feat(coding): add model tools and device packages

This commit is contained in:
2026-09-02 18:35:26 +08:00
parent 841273b433
commit 664b8823a0
60 changed files with 3847 additions and 2068 deletions

View File

@@ -46,8 +46,6 @@ import {
import { createDataServicePluginAdapter } from '../coding-plugins/adapters/data-service';
import { createGameResourcePluginAdapter } from '../coding-plugins/adapters/game-resource';
import { GameResourceClient } from '../services/game-resource-client';
import { createWebSearchPluginAdapter } from '../coding-plugins/adapters/web-search';
import { WebSearchClient } from '../services/web-search-client';
import { AccountPluginCache } from '../coding-plugins/account-plugin-cache';
import {
createMarketplaceClient,
@@ -74,11 +72,15 @@ import {
type CodingPluginMarketplaceService,
} from './coding-product-services';
import { CODE_OWNED_OPTIONAL_BUNDLED_RELEASES } from '../../shared/coding-plugins';
import { ModelToolRegistry } from '../coding-runtime/pi/model-tools/model-tool-registry';
import { DevicePackageManager } from '../coding-packages/device-package-manager';
import { DevicePackageTools } from '../coding-packages/device-package-tools';
export interface CodingCompositionPaths {
executablePath: string;
cliPath: string;
serverPath: string;
npmCliPath?: string;
userDataDir: string;
bundledSkillsDir: string;
}
@@ -139,7 +141,7 @@ export function resolveCodingPiRuntimePaths(input: {
resourcesPath: string;
appPath: string;
executablePath: string;
}): Pick<CodingCompositionPaths, 'executablePath' | 'cliPath' | 'serverPath'> {
}): Pick<CodingCompositionPaths, 'executablePath' | 'cliPath' | 'serverPath' | 'npmCliPath'> {
return {
executablePath: resolvePiWorkerExecutablePath(input.executablePath),
cliPath: input.isPackaged
@@ -155,6 +157,9 @@ export function resolveCodingPiRuntimePaths(input: {
serverPath: input.isPackaged
? path.join(input.resourcesPath, 'resources', 'pi-agent-server.mjs')
: path.join(input.appPath, 'resources', 'pi-agent-server.mjs'),
npmCliPath: input.isPackaged
? path.join(input.resourcesPath, 'publish-runtime', 'bin', 'npm-cli.js')
: path.join(input.appPath, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
};
}
@@ -210,14 +215,26 @@ export function createCodingComposition(
};
};
let effectiveResolver: EffectivePluginResolver | undefined;
let invalidateDeviceResources = async (): Promise<void> => undefined;
const projectStore = options.projectStore ?? createCodingProjectStore(options.storage);
const attachments = new CodingAttachmentStore(
path.join(options.paths.userDataDir, 'coding-runtime', 'attachments'),
);
const modelToolRegistry = new ModelToolRegistry();
const devicePackageManager = new DevicePackageManager({
rootDir: path.join(options.paths.userDataDir, 'coding-runtime', 'device-packages'),
executablePath: options.paths.executablePath,
cliPath: options.paths.cliPath,
...(options.paths.npmCliPath ? { npmCliPath: options.paths.npmCliPath } : {}),
onGenerationChanged: async () => await invalidateDeviceResources(),
});
const devicePackageTools = new DevicePackageTools(devicePackageManager);
const productTools = new PiProductTools({
browser: options.browser,
attachments,
bundledSkillsDir: options.paths.bundledSkillsDir,
modelToolRegistry,
devicePackageTools,
pluginSkillSources,
getPluginSkillSources: async () => effectiveResolver
? (await effectiveResolver.getSkillSources()).map((source) => ({
@@ -292,13 +309,6 @@ export function createCodingComposition(
makeloreVersion: options.clientVersion ?? '2.0.0',
bundledReleases: CODE_OWNED_OPTIONAL_BUNDLED_RELEASES,
});
const webSearchAdapter = createWebSearchPluginAdapter({
client: new WebSearchClient(),
marketplace: marketplaceClient,
packageStore,
makeloreVersion: options.clientVersion ?? '2.0.0',
bundledReleases: CODE_OWNED_OPTIONAL_BUNDLED_RELEASES,
});
const policyClient = options.policyClient ?? new PluginPolicyClient();
const knownPluginIds = new Set(pluginDefinitions.map(({ id }) => id));
// Existing user Releases are discovered from the device index at startup;
@@ -334,7 +344,7 @@ export function createCodingComposition(
const capabilityRegistry = createCodingCapabilityRegistry({
policyClient,
projectPlugins,
adapters: [dataServiceAdapter, gameResourceAdapter, webSearchAdapter],
adapters: [dataServiceAdapter, gameResourceAdapter],
definitions: pluginDefinitions,
effectiveResolver,
getDurableProjectId: async (projectPath, localProjectId) => {
@@ -350,7 +360,7 @@ export function createCodingComposition(
projects,
projectPlugins,
policyClient,
adapters: [dataServiceAdapter, gameResourceAdapter, webSearchAdapter],
adapters: [dataServiceAdapter, gameResourceAdapter],
definitions: pluginDefinitions,
effectiveResolver,
getDefinitions: async () => {
@@ -385,6 +395,9 @@ export function createCodingComposition(
: {}),
extensionHost,
capabilityRegistry,
modelToolRegistry,
devicePackageManager,
devicePackageTools: devicePackageTools.tools,
}),
});
const childOpener = createPiManagedSubagentChildOpener({
@@ -442,7 +455,7 @@ export function createCodingComposition(
},
});
const invalidateManagedResources = async (): Promise<void> => {
runtime?.markResourcesStale();
await runtime?.refreshResources();
const projectPaths = [...conversationStores.entries()];
for (const [, store] of projectPaths) {
const conversationsInProject = await store.read()
@@ -451,6 +464,7 @@ export function createCodingComposition(
for (const conversation of conversationsInProject) registry.forget(conversation.id);
}
};
invalidateDeviceResources = invalidateManagedResources;
const pluginMarketplace: CodingPluginMarketplaceService = createCodingPluginMarketplaceService({
marketplace: marketplaceClient,
packageStore,
@@ -482,6 +496,7 @@ export function createCodingComposition(
return {
attachments,
dataService,
devicePackages: devicePackageManager,
plugins,
pluginMarketplace,
marketplace: pluginMarketplace,