feat: integrate marketplace plugins with coding runtime

This commit is contained in:
2026-08-28 18:02:51 +08:00
parent 1d64b89499
commit 05917a789a
21 changed files with 1921 additions and 29 deletions

View File

@@ -141,6 +141,8 @@ export interface PiManagedWorkerOpenerOptions {
cliPath: string;
userDataDir: string;
bundledSkillsDir: string;
getSkillRoots?(): readonly string[] | Promise<readonly string[]>;
registerActivePluginReleases?(releaseIds: readonly string[]): () => void;
loadProviderInput(): Promise<PiManagedProviderInput>;
resolveCredential(account: ProviderAccount): Promise<string | null>;
getLocalProxyCredential?(): Promise<string | undefined>;
@@ -246,6 +248,7 @@ export function createPiManagedWorkerOpener(
const workerResources = options.capabilityRegistry
? await options.capabilityRegistry.resolveWorkerResources({
projectPath: registered.projectPath,
projectId: input.conversation.projectId,
assignedSkillIds: registered.agent.skillIds,
role: 'parent',
})
@@ -258,6 +261,12 @@ export function createPiManagedWorkerOpener(
skillEntries: workerResources.skillEntries,
catalogRevision: workerResources.catalogRevision,
bundledSkillsDir: options.bundledSkillsDir,
...(workerResources.skillRoots
? { skillRoots: workerResources.skillRoots }
: options.getSkillRoots ? { skillRoots: await options.getSkillRoots() } : {}),
...(workerResources.effectiveSnapshot
? { effectiveSnapshot: workerResources.effectiveSnapshot }
: {}),
revision: input.revision,
});
const credential = await buildPiWorkerCredentialProjection({
@@ -276,6 +285,9 @@ export function createPiManagedWorkerOpener(
skillEntries: workerResources.skillEntries,
catalogRevision: workerResources.catalogRevision,
tools: workerResources.tools,
...(workerResources.effectiveSnapshot
? { effectiveSnapshot: workerResources.effectiveSnapshot }
: {}),
extensionsDir: managedPaths.extensionsDir,
});
recordManagedMilestone(
@@ -313,8 +325,21 @@ export function createPiManagedWorkerOpener(
conversationId: input.conversation.conversationId,
workerGeneration: input.generation,
});
const releaseActivePluginReleases = workerResources.effectiveSnapshot
? options.registerActivePluginReleases?.(workerResources.effectiveSnapshot.pluginReleaseIds)
: undefined;
let managedResourcesDisposed = false;
const disposeManagedResources = async (): Promise<void> => {
if (managedResourcesDisposed) return;
managedResourcesDisposed = true;
try {
await extension.dispose();
} finally {
releaseActivePluginReleases?.();
}
};
let unsubscribeExtensionInvalidation = process.subscribeInvalidation(() => {
void extension.dispose();
void disposeManagedResources();
});
try {
const spawnStartedAt = now();
@@ -389,7 +414,7 @@ export function createPiManagedWorkerOpener(
`${input.conversation.conversationId}:${input.generation}`,
input.generation,
process,
extension.dispose,
disposeManagedResources,
() => {
unsubscribeExtensionInvalidation();
unsubscribeExtensionInvalidation = () => undefined;
@@ -400,7 +425,7 @@ export function createPiManagedWorkerOpener(
} catch (error) {
unsubscribeExtensionInvalidation();
await process.stop('open_failure').catch(() => undefined);
await extension.dispose();
await disposeManagedResources();
throw error;
}
};