feat: integrate automatic game resource delivery

This commit is contained in:
2026-09-06 09:50:49 +08:00
parent f721966f3c
commit 4df4bc9624
20 changed files with 1667 additions and 191 deletions

View File

@@ -93,7 +93,7 @@ interface SubagentBridgeRequest {
}
interface ProductToolBridgeRequest {
action: 'product.invoke';
action: 'product.invoke' | 'product.invoke.stream';
conversationId: string;
workerGeneration: number;
runId: string;
@@ -142,7 +142,7 @@ function bridgeRequest(value: unknown): value is BridgeRequest {
&& typeof value.resourceId === 'string';
if (!common) return false;
if (value.action === 'subagent.dispatch') return 'request' in value;
if (value.action === 'product.invoke') {
if (value.action === 'product.invoke' || value.action === 'product.invoke.stream') {
return typeof value.toolName === 'string'
&& PRODUCT_TOOL_NAME_PATTERN.test(value.toolName)
&& 'input' in value;
@@ -417,7 +417,7 @@ export class PiManagedExtensionHost {
this.respond(response, 200, { recorded: true });
return;
}
if (value.action === 'product.invoke') {
if (value.action === 'product.invoke' || value.action === 'product.invoke.stream') {
if (record.role !== 'parent') {
this.respond(response, 403, { error: 'Child workers cannot invoke parent product tools' });
return;
@@ -431,7 +431,7 @@ export class PiManagedExtensionHost {
this.respond(response, 503, { error: 'Product tools are unavailable' });
return;
}
const productResult = await this.productTools.execute(value.toolName, {
const context = {
conversationId: record.conversationId,
workerGeneration: record.generation,
runId: value.runId,
@@ -440,7 +440,38 @@ export class PiManagedExtensionHost {
projectPath: record.projectPath,
skillIds: record.skillIds,
...(record.effectiveSnapshot ? { effectiveSnapshot: record.effectiveSnapshot } : {}),
}, value.input);
};
if (value.action === 'product.invoke.stream') {
response.writeHead(200, {
'content-type': 'application/x-ndjson; charset=utf-8',
...(this.closing ? { connection: 'close' } : {}),
});
try {
const productResult = await this.productTools.execute(
value.toolName,
context,
value.input,
(result) => {
if (!response.writableEnded && !response.destroyed) {
response.write(`${JSON.stringify({ result })}\n`);
}
},
);
if (!response.writableEnded && !response.destroyed) {
response.end(`${JSON.stringify({ result: productResult, done: true })}\n`);
}
} catch {
if (!response.writableEnded && !response.destroyed) {
response.end(`${JSON.stringify({ error: 'Product tool invocation failed' })}\n`);
}
}
return;
}
const productResult = await this.productTools.execute(
value.toolName,
context,
value.input,
);
this.respond(response, 200, { result: productResult });
return;
}