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

@@ -5,7 +5,10 @@ import type { PluginPolicyClientState } from '../../electron/services/plugin-pol
import {
CodingCapabilityRegistryImpl,
} from '../../electron/coding-plugins/registry';
import type { CodingPluginAdapter } from '../../electron/coding-plugins/registry';
import type {
AdapterInvocationResult,
CodingPluginAdapter,
} from '../../electron/coding-plugins/registry';
import { createDataServicePluginAdapter } from '../../electron/coding-plugins/adapters/data-service';
import {
createDataServiceOperations,
@@ -277,14 +280,28 @@ describe('CodingCapabilityRegistry', () => {
getPolicyState: vi.fn(() => hostedPolicy),
getInstalledDefinition: vi.fn(async () => hostedDefinition),
} as unknown as EffectivePluginResolver;
const invoke = vi.fn(async () => ({
success: true as const, status: 202, code: null, error: null, retryable: false as const,
payload_schema: 'game-resource.v1', data: { executionId: 'execution-a', status: 'accepted' },
billing: {
mode: 'platform_metered' as const, status: 'dispatched' as const,
reserved_points: '2.00', usage_amount: 1, unit: 'generation',
},
}));
const dispatchedBilling = {
mode: 'platform_metered' as const, status: 'dispatched' as const,
reserved_points: '2.00', usage_amount: 1, unit: 'generation',
};
const invoke = vi.fn(async (
_context: unknown,
_tool: unknown,
_value: unknown,
onProgress?: (result: AdapterInvocationResult) => void,
) => {
onProgress?.({
success: true, status: 202, code: null, error: null, retryable: false,
payload_schema: 'game-resource.v1',
data: { phase: 'generating', executionId: 'execution-a' },
billing: dispatchedBilling,
});
return {
success: true as const, status: 202, code: null, error: null, retryable: false as const,
payload_schema: 'game-resource.v1', data: { executionId: 'execution-a', status: 'accepted' },
billing: dispatchedBilling,
};
});
const capabilityRegistry = registry({
definitions: [], effectiveResolver,
adapters: [{ pluginId: hostedDefinition.id, inspect: async () => ({ status: 'ready' }), invoke }],
@@ -292,10 +309,12 @@ describe('CodingCapabilityRegistry', () => {
getEnabledPluginIds: async () => [hostedDefinition.id],
});
const onUpdate = vi.fn();
const result = await capabilityRegistry.invoke({
toolName: 'game_resource_generate',
context: { ...context, skillIds: ['game-resource'], effectiveSnapshot: frozenSnapshot },
workerRole: 'parent', effectiveSkillIds: ['game-resource'], value: { kind: 'pixel' },
onUpdate,
});
expect(effectiveResolver.getInstalledDefinition).toHaveBeenCalledWith(
@@ -305,7 +324,17 @@ describe('CodingCapabilityRegistry', () => {
expect(invoke).toHaveBeenCalledWith(expect.objectContaining({
requestId: 'pi:run-a:resource-a', workerRole: 'parent', effectiveSkillIds: ['game-resource'],
pluginReleaseId: hostedDefinition.releaseId,
}), hostedDefinition.tools[0], { kind: 'pixel' });
}), hostedDefinition.tools[0], { kind: 'pixel' }, expect.any(Function));
expect(onUpdate).toHaveBeenCalledWith(expect.objectContaining({
details: expect.objectContaining({
schema: 'makelore-capability.v1',
plugin_id: hostedDefinition.id,
operation: 'generate',
status: 202,
data: { phase: 'generating', executionId: 'execution-a' },
billing: dispatchedBilling,
}),
}));
expect(result.details).toMatchObject({
schema: 'makelore-capability.v1', plugin_id: hostedDefinition.id,
capability_id: 'game-resource.generate', operation: 'generate',