maka-agent 0.2.0-dev.26.20260909 → 0.2.0-dev.28.20260911
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +106 -0
- package/dist/cli-core.js +28 -0
- package/dist/runtime-host-cli.js +43 -3
- package/dist/runtime-host-handoff-surface.js +10 -8
- package/dist/runtime-host-lifecycle-transaction.js +28 -3
- package/dist/runtime-host-local-source-retirement.js +1 -1
- package/dist/runtime-host-run-command.js +15 -7
- package/dist/runtime-host-setup-command.js +29 -6
- package/dist/runtime-host-update-command.js +49 -5
- package/dist/session-export-command.js +72 -0
- package/dist/session-import-command.js +69 -0
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-windows-task-launcher/prebuilds/win32-x64/maka-runtime-host-task-launcher.exe +0 -0
- package/node_modules/@earendil-works/pi-tui/dist/components/editor.js +9 -4
- package/node_modules/@maka/core/dist/diagnostic-log.js +18 -7
- package/node_modules/@maka/core/dist/text-sanitize.js +8 -2
- package/node_modules/@maka/core/dist/usage-stats/types.js +2 -0
- package/node_modules/@maka/core/dist/workhub-routing.js +126 -0
- package/node_modules/@maka/core/package.json +2 -1
- package/node_modules/@maka/runtime/dist/ai-sdk-turn.js +15 -11
- package/node_modules/@maka/runtime/dist/archive-read-tool.js +3 -1
- package/node_modules/@maka/runtime/dist/bots/bot-test.js +2 -1
- package/node_modules/@maka/runtime/dist/bots/feishu-bridge.js +24 -20
- package/node_modules/@maka/runtime/dist/bots/slack-bridge.js +5 -3
- package/node_modules/@maka/runtime/dist/bots/wechat-bridge.js +87 -29
- package/node_modules/@maka/runtime/dist/bots/wecom-bridge.js +40 -36
- package/node_modules/@maka/runtime/dist/builtin-tools.js +21 -2
- package/node_modules/@maka/runtime/dist/computer-use-tools.js +4 -1
- package/node_modules/@maka/runtime/dist/deep-research-tools.js +11 -5
- package/node_modules/@maka/runtime/dist/edit-replace.js +2 -2
- package/node_modules/@maka/runtime/dist/filesystem-worker/operations.js +5 -6
- package/node_modules/@maka/runtime/dist/memory-extraction-evidence.js +7 -1
- package/node_modules/@maka/runtime/dist/memory-extraction.js +12 -7
- package/node_modules/@maka/runtime/dist/openai-responses-websocket.js +2 -5
- package/node_modules/@maka/runtime/dist/plugin-agent-service.js +131 -0
- package/node_modules/@maka/runtime/dist/plugin-approval-service.js +33 -0
- package/node_modules/@maka/runtime/dist/plugin-attachment-service.js +53 -0
- package/node_modules/@maka/runtime/dist/plugin-command-service.js +100 -0
- package/node_modules/@maka/runtime/dist/plugin-composition-loader.js +11 -2
- package/node_modules/@maka/runtime/dist/plugin-data-services.js +332 -0
- package/node_modules/@maka/runtime/dist/plugin-fs-service.js +62 -0
- package/node_modules/@maka/runtime/dist/plugin-goal-service.js +61 -0
- package/node_modules/@maka/runtime/dist/plugin-invocation-signal.js +24 -0
- package/node_modules/@maka/runtime/dist/plugin-llm-service.js +85 -0
- package/node_modules/@maka/runtime/dist/plugin-lsp-service.js +94 -0
- package/node_modules/@maka/runtime/dist/plugin-scope-registry.js +91 -0
- package/node_modules/@maka/runtime/dist/plugin-session-query-service.js +71 -0
- package/node_modules/@maka/runtime/dist/plugin-shell-env-service.js +87 -0
- package/node_modules/@maka/runtime/dist/plugin-shell-service.js +74 -0
- package/node_modules/@maka/runtime/dist/plugin-skill-service.js +93 -0
- package/node_modules/@maka/runtime/dist/plugin-system-prompt-service.js +346 -0
- package/node_modules/@maka/runtime/dist/plugin-tool-service.js +18 -52
- package/node_modules/@maka/runtime/dist/plugin-user-question-service.js +43 -0
- package/node_modules/@maka/runtime/dist/plugin-web-service.js +69 -0
- package/node_modules/@maka/runtime/dist/request-customization-fetch.js +14 -7
- package/node_modules/@maka/runtime/dist/session-export.js +178 -0
- package/node_modules/@maka/runtime/dist/session-import.js +100 -0
- package/node_modules/@maka/runtime/dist/session-manager.js +6 -1
- package/node_modules/@maka/runtime/dist/shell-run-manager.js +9 -6
- package/node_modules/@maka/runtime/dist/shell-run-tool-result.js +13 -6
- package/node_modules/@maka/runtime/dist/stream-graph-coordinator.js +43 -10
- package/node_modules/@maka/runtime/dist/stream-graph-handoff.js +6 -1
- package/node_modules/@maka/runtime/dist/subscription-model-fetch.js +1 -4
- package/node_modules/@maka/runtime/dist/system-prompt/workspace-instructions.js +11 -6
- package/node_modules/@maka/runtime/dist/tavily-search.js +8 -2
- package/node_modules/@maka/runtime/dist/text-line-window.js +49 -0
- package/node_modules/@maka/runtime/dist/tool-output.js +35 -12
- package/node_modules/@maka/runtime/dist/unified-diff.js +40 -10
- package/node_modules/@maka/runtime/dist/web-fetch-tool.js +4 -2
- package/node_modules/@maka/runtime/dist/workers/filesystem-worker.js +82 -33
- package/node_modules/@maka/runtime/dist/workspace-executor.js +2 -6
- package/node_modules/@maka/runtime/package.json +20 -1
- package/node_modules/@maka/runtime-host/dist/client/host-handoff-copy.js +73 -24
- package/node_modules/@maka/runtime-host/dist/client/host-handoff.js +46 -12
- package/node_modules/@maka/runtime-host/dist/operator/setup-frame.js +31 -21
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +7 -4
- package/node_modules/@maka/runtime-host/dist/protocol/artifact.js +2 -2
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +10 -1
- package/node_modules/@maka/runtime-host/dist/protocol/plugin-platform.js +30 -5
- package/node_modules/@maka/runtime-host/dist/protocol/session-transcript.js +3 -2
- package/node_modules/@maka/runtime-host/dist/protocol/skill-catalog.js +2 -1
- package/node_modules/@maka/runtime-host/dist/protocol/workhub-coordination.js +25 -23
- package/node_modules/@maka/runtime-host/dist/server/artifact-coordinator.js +2 -0
- package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +62 -4
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +481 -11
- package/node_modules/@maka/runtime-host/dist/server/execution-model-authority.js +74 -0
- package/node_modules/@maka/runtime-host/dist/server/goal-coordinator.js +6 -1
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-recovery.js +2 -2
- package/node_modules/@maka/runtime-host/dist/server/hosted-execution-tool-profile.js +30 -0
- package/node_modules/@maka/runtime-host/dist/server/interactive-run-composer.js +114 -20
- package/node_modules/@maka/runtime-host/dist/server/message-coordinator.js +49 -12
- package/node_modules/@maka/runtime-host/dist/server/plugin-data-runtime.js +234 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform-coordinator.js +6 -0
- package/node_modules/@maka/runtime-host/dist/server/plugin-platform.js +12 -0
- package/node_modules/@maka/runtime-host/dist/server/root-admission-owner.js +17 -8
- package/node_modules/@maka/runtime-host/dist/server/root-turn-coordinator.js +189 -92
- package/node_modules/@maka/runtime-host/dist/server/runtime-resource-projection.js +3 -9
- package/node_modules/@maka/runtime-host/dist/server/session-continuity-coordinator.js +20 -21
- package/node_modules/@maka/runtime-host/dist/server/session-transcript-pager.js +24 -2
- package/node_modules/@maka/runtime-host/dist/server/skill-catalog-coordinator.js +18 -2
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-action-gate.js +44 -35
- package/node_modules/@maka/runtime-host/dist/server/workhub-coordination-coordinator.js +92 -10
- package/node_modules/@maka/runtime-host/dist/transport/framed-byte-stream-transport.js +4 -1
- package/node_modules/@maka/runtime-host/dist/transport/local-ipc-framing.js +4 -2
- package/node_modules/@maka/runtime-host/dist/transport/peer-native.js +9 -8
- package/node_modules/@maka/runtime-host/dist/transport/resumable-peer-stream.js +14 -9
- package/node_modules/@maka/storage/dist/agent-run-store.js +54 -10
- package/node_modules/@maka/storage/dist/context-offload-snapshot.js +32 -10
- package/node_modules/@maka/storage/dist/context-value-mutation-gate.js +59 -0
- package/node_modules/@maka/storage/dist/execution-stores.js +1 -1
- package/node_modules/@maka/storage/dist/session-bundle-policy.js +909 -34
- package/node_modules/@maka/storage/dist/session-message-projection.js +8 -4
- package/node_modules/@maka/storage/dist/session-store.js +2 -2
- package/node_modules/@maka/storage/dist/sqlite-context-offload-store.js +18 -4
- package/node_modules/@maka/storage/dist/sqlite-session-metadata-store.js +12 -5
- package/node_modules/@maka/storage/dist/stable-storage.js +2 -1
- package/node_modules/@maka/storage/package.json +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-D_zzAWoS.mjs +22 -5
- package/node_modules/@modelcontextprotocol/client/dist/src-NAgB4Mp8.cjs +22 -5
- package/node_modules/zod/v4/core/memoizer.cjs +12 -16
- package/node_modules/zod/v4/core/memoizer.js +12 -16
- package/package.json +1 -1
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { copyWorkHubAttachmentsToTarget } from './workhub-message-attachments.js';
|
|
20
20
|
import { createHash, randomUUID } from 'node:crypto';
|
|
21
|
-
import { MAX_READ_IMAGE_BYTES } from '@maka/core/attachments';
|
|
21
|
+
import { attachmentKindFromMimeType, MAX_READ_IMAGE_BYTES } from '@maka/core/attachments';
|
|
22
22
|
import { messageContentDigest, normalizeMessageContent } from '@maka/core/events';
|
|
23
23
|
import { NO_REAL_CONNECTION_CODE } from '@maka/core/connection-error-copy';
|
|
24
24
|
import { generalizedErrorMessage } from '@maka/core/redaction';
|
|
@@ -26,11 +26,12 @@ import { emptyPlanSessionState } from '@maka/core/plan';
|
|
|
26
26
|
import { readLogicalRuntimeExecutionForRun } from '@maka/core/runtime-logical-execution';
|
|
27
27
|
import { runtimeInvocationOutcome, } from '@maka/core/runtime-invocation';
|
|
28
28
|
import { isDeepResearchSession, WORKHUB_COORDINATION_SESSION_ID, WORKHUB_COORDINATION_REPLACEMENT_SCHEMA_VERSION, } from '@maka/core/session';
|
|
29
|
-
import { AgentGraphCoordinator } from '@maka/runtime/stream-graph-coordinator';
|
|
29
|
+
import { AgentGraphClientOperationError, AgentGraphCoordinator, } from '@maka/runtime/stream-graph-coordinator';
|
|
30
30
|
import { AgentGraphSupervisorWakeCoordinator } from '@maka/runtime/agent-graph-supervisor-wake';
|
|
31
31
|
import { BackendRegistry, SessionManager, workHubDirectStopAbortSource, } from '@maka/runtime/session-manager';
|
|
32
32
|
import { buildToolsForAgentDefinition } from '@maka/runtime/agent-catalog';
|
|
33
33
|
import { buildHistoryTools } from '@maka/runtime/history-tools';
|
|
34
|
+
import { buildBuiltinTools } from '@maka/runtime/builtin-tools';
|
|
34
35
|
import { createLocalContinuationSafetyInspector } from '@maka/runtime/continuation-safety';
|
|
35
36
|
import { createConfiguredSubagentCatalog } from '@maka/runtime/configured-subagent-catalog';
|
|
36
37
|
import { buildHostCapabilitiesFromBinding } from '@maka/runtime/skills';
|
|
@@ -45,8 +46,24 @@ import { SessionActivityRegistry } from '@maka/runtime/goal-turn-lifecycle';
|
|
|
45
46
|
import { ShellRunProcessManager } from '@maka/runtime/shell-run-manager';
|
|
46
47
|
import { resolveShellPlan, resolveTurnShellPlan, validateShellPreference, } from '@maka/runtime/shell-detect';
|
|
47
48
|
import { Context } from '@maka/runtime/plugin-kernel';
|
|
49
|
+
import { PluginAgentService } from '@maka/runtime/plugin-agent-service';
|
|
50
|
+
import { PluginAttachmentService } from '@maka/runtime/plugin-attachment-service';
|
|
51
|
+
import { PluginApprovalService } from '@maka/runtime/plugin-approval-service';
|
|
52
|
+
import { PluginFilesystemService } from '@maka/runtime/plugin-fs-service';
|
|
53
|
+
import { PluginLlmService } from '@maka/runtime/plugin-llm-service';
|
|
54
|
+
import { PluginShellService } from '@maka/runtime/plugin-shell-service';
|
|
55
|
+
import { PluginUserQuestionService } from '@maka/runtime/plugin-user-question-service';
|
|
56
|
+
import { PluginWebService } from '@maka/runtime/plugin-web-service';
|
|
48
57
|
import { MakaCompositionLoader } from '@maka/runtime/plugin-composition-loader';
|
|
49
58
|
import { PluginToolService } from '@maka/runtime/plugin-tool-service';
|
|
59
|
+
import { PluginSystemPromptService } from '@maka/runtime/plugin-system-prompt-service';
|
|
60
|
+
import { PluginCommandService } from '@maka/runtime/plugin-command-service';
|
|
61
|
+
import { PluginAuthorizationService, PluginCredentialService, PluginSettingsService, PluginStorageService, } from '@maka/runtime/plugin-data-services';
|
|
62
|
+
import { PluginGoalService } from '@maka/runtime/plugin-goal-service';
|
|
63
|
+
import { PluginLspService } from '@maka/runtime/plugin-lsp-service';
|
|
64
|
+
import { PluginSessionQueryService } from '@maka/runtime/plugin-session-query-service';
|
|
65
|
+
import { PluginShellEnvService } from '@maka/runtime/plugin-shell-env-service';
|
|
66
|
+
import { PluginSkillService } from '@maka/runtime/plugin-skill-service';
|
|
50
67
|
import { isHostedExecutionTerminal } from './hosted-execution-authority.js';
|
|
51
68
|
import { createAgentGraphControlStore } from '@maka/storage/agent-graph-control-store';
|
|
52
69
|
import { createArtifactAttachmentResourceReader } from '@maka/storage/artifact-stores';
|
|
@@ -59,6 +76,7 @@ import { createInteractiveContextOffloadReader } from '@maka/storage/context-off
|
|
|
59
76
|
import { openStorageWriterComposition } from '@maka/storage/storage-writer-composition';
|
|
60
77
|
import { resolveWorkspaceIdentity } from '@maka/storage/workspace-identity';
|
|
61
78
|
import { CanonicalSessionProjectionReader } from './canonical-session-projection.js';
|
|
79
|
+
import { HostPluginDataRuntime } from './plugin-data-runtime.js';
|
|
62
80
|
import { bindHostChildAgentBackend, createHostChildAgentToolComposition, } from './child-agent-composition.js';
|
|
63
81
|
import { HostCanonicalPermissionOutcomeReader } from './canonical-permission-outcome-reader.js';
|
|
64
82
|
import { HostArtifactCoordinator } from './artifact-coordinator.js';
|
|
@@ -75,7 +93,7 @@ import { HostDeepResearchCoordinator } from './deep-research-coordinator.js';
|
|
|
75
93
|
import { HostDailyReviewCoordinator } from './daily-review-coordinator.js';
|
|
76
94
|
import { prepareHostAiSdkBackend } from './execution-model-composition.js';
|
|
77
95
|
import { createInteractiveRunComposer, createInteractiveRunComposerFactory, routeInteractiveRunToolSurface, } from './interactive-run-composer.js';
|
|
78
|
-
import { createHostGoalEvaluator, createHostDailyReviewModel, createHostMemoryExtractionModel, createHostSessionEffectModel, } from './execution-model-authority.js';
|
|
96
|
+
import { createHostGoalEvaluator, createHostDailyReviewModel, createHostMemoryExtractionModel, createHostPluginModel, createHostSessionEffectModel, } from './execution-model-authority.js';
|
|
79
97
|
import { HostExecutionInspectCoordinator } from './execution-inspect-coordinator.js';
|
|
80
98
|
import { HostExternalSessionCoordinator } from './external-session-coordinator.js';
|
|
81
99
|
import { HostGoalCoordinator } from './goal-coordinator.js';
|
|
@@ -88,7 +106,7 @@ import { HostInteractionCoordinator } from './interaction-coordinator.js';
|
|
|
88
106
|
import { HostInteractiveTurnCoordinator } from './interactive-turn-coordinator.js';
|
|
89
107
|
import { SessionTurnAccessRequestCoordinator } from './session-turn-access-request-coordinator.js';
|
|
90
108
|
import { ensureBootstrapRuntimePolicy } from './bootstrap-runtime-policy.js';
|
|
91
|
-
import { hostedExecutionRunProfile } from './hosted-execution-tool-profile.js';
|
|
109
|
+
import { bindWorkHubRoutingDecisionPrompt, hostedExecutionRunProfile, } from './hosted-execution-tool-profile.js';
|
|
92
110
|
import { HostMemoryCoordinator } from './memory-coordinator.js';
|
|
93
111
|
import { HostMemoryExtractionCoordinator } from './memory-extraction-coordinator.js';
|
|
94
112
|
import { MemoryExtractionSessionLane } from './memory-extraction-session-lane.js';
|
|
@@ -118,7 +136,7 @@ import { HostSessionRevisionCoordinator } from './session-revision-coordinator.j
|
|
|
118
136
|
import { HostSessionEffectCoordinator } from './session-effect-coordinator.js';
|
|
119
137
|
import { SessionContinuityCoordinator } from './session-continuity-coordinator.js';
|
|
120
138
|
import { createSessionTranscriptReader, } from './session-transcript-reader.js';
|
|
121
|
-
import { HostSkillCatalogCoordinator } from './skill-catalog-coordinator.js';
|
|
139
|
+
import { HostSkillCatalogCoordinator, SkillCatalogInvocableContextError, } from './skill-catalog-coordinator.js';
|
|
122
140
|
import { SkillCatalogRepository } from './skill-catalog-repository.js';
|
|
123
141
|
import { HostSessionTodoCoordinator } from './session-todo-coordinator.js';
|
|
124
142
|
import { HostTurnControlCoordinator } from './turn-control-coordinator.js';
|
|
@@ -177,10 +195,35 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
177
195
|
let archiveEvidence;
|
|
178
196
|
try {
|
|
179
197
|
const pluginRoot = new Context();
|
|
180
|
-
const
|
|
198
|
+
const pluginAgents = new PluginAgentService(pluginRoot);
|
|
199
|
+
const pluginAttachments = new PluginAttachmentService(pluginRoot, pluginAgents);
|
|
200
|
+
new PluginApprovalService(pluginRoot, pluginAgents);
|
|
201
|
+
new PluginUserQuestionService(pluginRoot, pluginAgents);
|
|
202
|
+
const pluginFilesystem = new PluginFilesystemService(pluginRoot, pluginAgents);
|
|
203
|
+
const pluginLlm = new PluginLlmService(pluginRoot, pluginAgents);
|
|
204
|
+
const pluginShellEnv = new PluginShellEnvService(pluginRoot);
|
|
205
|
+
const pluginShell = new PluginShellService(pluginRoot, pluginAgents, pluginShellEnv);
|
|
206
|
+
const pluginWeb = new PluginWebService(pluginRoot, pluginAgents);
|
|
207
|
+
const pluginSessionQuery = new PluginSessionQueryService(pluginRoot, pluginAgents);
|
|
208
|
+
const pluginGoals = new PluginGoalService(pluginRoot, pluginAgents);
|
|
209
|
+
const pluginSkills = new PluginSkillService(pluginRoot);
|
|
210
|
+
const pluginCommands = new PluginCommandService(pluginRoot);
|
|
211
|
+
new PluginLspService(pluginRoot);
|
|
212
|
+
const pluginSettings = new PluginSettingsService(pluginRoot);
|
|
213
|
+
const pluginStorage = new PluginStorageService(pluginRoot);
|
|
214
|
+
const pluginCredentials = new PluginCredentialService(pluginRoot);
|
|
215
|
+
new PluginAuthorizationService(pluginRoot, pluginCredentials);
|
|
216
|
+
const pluginData = new HostPluginDataRuntime(context.owner.controlDirectory);
|
|
217
|
+
pluginSettings.bindRuntime(pluginData);
|
|
218
|
+
pluginStorage.bindRuntime(pluginData);
|
|
219
|
+
pluginCredentials.bindRuntime(pluginData);
|
|
220
|
+
const pluginTools = new PluginToolService(pluginRoot, { agents: pluginAgents });
|
|
221
|
+
const pluginSystemPrompt = new PluginSystemPromptService(pluginRoot);
|
|
181
222
|
pluginPlatform = new HostPluginPlatform(context.owner.controlDirectory, {
|
|
182
223
|
composition: new MakaCompositionLoader({ root: pluginRoot }),
|
|
183
224
|
tools: pluginTools,
|
|
225
|
+
systemPrompt: pluginSystemPrompt,
|
|
226
|
+
commands: pluginCommands,
|
|
184
227
|
});
|
|
185
228
|
const pluginPlatformCoordinator = new HostPluginPlatformCoordinator(pluginPlatform);
|
|
186
229
|
const openedProjectCatalog = storage.projectCatalog;
|
|
@@ -323,12 +366,94 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
323
366
|
...(sandboxManager ? { sandboxManager } : {}),
|
|
324
367
|
...(filesystemWorker ? { filesystemWorker } : {}),
|
|
325
368
|
};
|
|
369
|
+
const invokeBuiltin = async (name, args, invocation, shellEnvironment) => {
|
|
370
|
+
if (!invocation.toolContext)
|
|
371
|
+
throw new Error(`${name} requires an active Tool invocation`);
|
|
372
|
+
const policy = await runtimePolicyStores.runtimePolicy.getSnapshot();
|
|
373
|
+
const tool = buildBuiltinTools({
|
|
374
|
+
...builtinTools,
|
|
375
|
+
shell: resolveTurnShellPlan(policy.policy.shell),
|
|
376
|
+
...(shellEnvironment ? { shellEnvironment } : {}),
|
|
377
|
+
}).find((candidate) => candidate.name === name);
|
|
378
|
+
if (!tool)
|
|
379
|
+
throw new Error(`Builtin capability is unavailable: ${name}`);
|
|
380
|
+
return tool.impl(args, invocation.toolContext);
|
|
381
|
+
};
|
|
382
|
+
pluginFilesystem.bindRuntime({
|
|
383
|
+
execute: (operation, invocation) => {
|
|
384
|
+
switch (operation.kind) {
|
|
385
|
+
case 'read':
|
|
386
|
+
return invokeBuiltin('Read', operation, invocation);
|
|
387
|
+
case 'write':
|
|
388
|
+
return invokeBuiltin('Write', operation, invocation);
|
|
389
|
+
case 'edit':
|
|
390
|
+
return invokeBuiltin('Edit', {
|
|
391
|
+
path: operation.path,
|
|
392
|
+
old_string: operation.oldString,
|
|
393
|
+
new_string: operation.newString,
|
|
394
|
+
}, invocation);
|
|
395
|
+
case 'glob':
|
|
396
|
+
return invokeBuiltin('Glob', { pattern: operation.pattern, cwd: operation.path }, invocation);
|
|
397
|
+
case 'grep':
|
|
398
|
+
return invokeBuiltin('Grep', { pattern: operation.pattern, path: operation.path, glob: operation.glob }, invocation);
|
|
399
|
+
case 'apply_patch':
|
|
400
|
+
return invokeBuiltin('apply_patch', operation.patch, invocation);
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
pluginShell.bindRuntime({
|
|
405
|
+
run: (options, invocation) => invokeBuiltin('Bash', {
|
|
406
|
+
command: options.command,
|
|
407
|
+
timeout_ms: options.timeoutMs,
|
|
408
|
+
run_in_background: options.background,
|
|
409
|
+
pty: options.pty,
|
|
410
|
+
}, invocation, options.environment),
|
|
411
|
+
read: (ref, invocation) => runtimeResources.readRuntimeResource(invocation.sessionId, ref, invocation.abortSignal),
|
|
412
|
+
write: (ref, input, invocation) => runtimeResources.writeStdin({
|
|
413
|
+
sessionId: invocation.sessionId,
|
|
414
|
+
ref,
|
|
415
|
+
input,
|
|
416
|
+
abortSignal: invocation.abortSignal,
|
|
417
|
+
caller: 'model',
|
|
418
|
+
}),
|
|
419
|
+
stop: (ref, invocation) => runtimeResources.stopBackgroundTask(invocation.sessionId, ref, invocation.abortSignal),
|
|
420
|
+
});
|
|
421
|
+
pluginAttachments.bindRuntime({
|
|
422
|
+
create: async (input, invocation) => {
|
|
423
|
+
const record = await openedArtifactStore.create({
|
|
424
|
+
sessionId: invocation.sessionId,
|
|
425
|
+
turnId: invocation.turnId,
|
|
426
|
+
name: input.name,
|
|
427
|
+
kind: pluginAttachmentArtifactKind(input.mimeType, input.name),
|
|
428
|
+
content: input.content,
|
|
429
|
+
mimeType: input.mimeType,
|
|
430
|
+
source: 'tool_result',
|
|
431
|
+
...(input.summary ? { summary: input.summary } : {}),
|
|
432
|
+
});
|
|
433
|
+
return pluginAttachmentRef(record);
|
|
434
|
+
},
|
|
435
|
+
read: async (attachment, invocation) => {
|
|
436
|
+
if (attachment.ref.kind !== 'session_file' ||
|
|
437
|
+
attachment.ref.sessionId !== invocation.sessionId) {
|
|
438
|
+
throw new Error('Attachment is outside the current Session');
|
|
439
|
+
}
|
|
440
|
+
const result = await openedArtifactStore.readBinaryInSession(invocation.sessionId, attachment.ref.relativePath);
|
|
441
|
+
if (!result.ok)
|
|
442
|
+
throw new Error(`Attachment read failed: ${result.reason}`);
|
|
443
|
+
return Uint8Array.from(Buffer.from(result.base64, 'base64'));
|
|
444
|
+
},
|
|
445
|
+
list: async (invocation) => (await openedArtifactStore.listTurnArtifacts(invocation.sessionId, invocation.turnId)).map(pluginAttachmentRef),
|
|
446
|
+
});
|
|
326
447
|
const webSearchService = createHostWebSearchService({
|
|
327
448
|
policy: runtimePolicyStores.operations,
|
|
328
449
|
});
|
|
329
450
|
const webFetchService = createHostWebFetchService({
|
|
330
451
|
policy: runtimePolicyStores.operations,
|
|
331
452
|
});
|
|
453
|
+
pluginWeb.bindRuntime({
|
|
454
|
+
search: ({ query, limit, abortSignal }) => webSearchService.search({ query, limit, ...(abortSignal ? { abortSignal } : {}) }),
|
|
455
|
+
fetch: (input) => webFetchService.fetch(input),
|
|
456
|
+
});
|
|
332
457
|
const historyTools = buildHistoryTools({
|
|
333
458
|
listSessions: () => requireSessionManager(manager).listSessions(),
|
|
334
459
|
readMessages: async (sessionId, abortSignal) => {
|
|
@@ -375,8 +500,33 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
375
500
|
}), workspaceResolver, async (input, connection) => {
|
|
376
501
|
if (input.target.kind === 'session') {
|
|
377
502
|
const sessionId = input.target.sessionId;
|
|
378
|
-
|
|
379
|
-
|
|
503
|
+
let header;
|
|
504
|
+
try {
|
|
505
|
+
header = await stores.sessionStore.readHeaderSnapshot(sessionId);
|
|
506
|
+
}
|
|
507
|
+
catch (error) {
|
|
508
|
+
if (isSessionNotFoundError(error)) {
|
|
509
|
+
throw new SkillCatalogInvocableContextError('not_found', 'Session does not exist');
|
|
510
|
+
}
|
|
511
|
+
throw error;
|
|
512
|
+
}
|
|
513
|
+
if (header.isArchived) {
|
|
514
|
+
throw new SkillCatalogInvocableContextError('session_archived', 'Session is archived');
|
|
515
|
+
}
|
|
516
|
+
let preview;
|
|
517
|
+
try {
|
|
518
|
+
preview = await requireClientCapabilities(clientCapabilities).runWithSessionBindingPreview(sessionId, connection.connectionId, () => requireToolNameResolver(resolveAvailableToolNames)(sessionId));
|
|
519
|
+
}
|
|
520
|
+
catch (error) {
|
|
521
|
+
if (isSessionNotFoundError(error)) {
|
|
522
|
+
throw new SkillCatalogInvocableContextError('not_found', 'Session does not exist');
|
|
523
|
+
}
|
|
524
|
+
if (error instanceof AgentGraphClientOperationError &&
|
|
525
|
+
error.code === 'session_archived') {
|
|
526
|
+
throw new SkillCatalogInvocableContextError('session_archived', 'Session is archived');
|
|
527
|
+
}
|
|
528
|
+
throw error;
|
|
529
|
+
}
|
|
380
530
|
if (!preview.ok)
|
|
381
531
|
throw new Error(preview.message);
|
|
382
532
|
return {
|
|
@@ -394,6 +544,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
394
544
|
publish: (sessionId) => hostChanges.publishSessionCatalog(sessionId),
|
|
395
545
|
}, projectMembership, context.requestDrain, new HostProjectDirectoryAuthority(options.projectDirectoryRoots));
|
|
396
546
|
let rootCoordinator;
|
|
547
|
+
let workHubCoordination;
|
|
397
548
|
let canonicalProjection;
|
|
398
549
|
let memory;
|
|
399
550
|
let clientCapabilities;
|
|
@@ -473,6 +624,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
473
624
|
let recoveryTask;
|
|
474
625
|
let rootCloseTask;
|
|
475
626
|
let rootRecoveryCompleted = false;
|
|
627
|
+
let clientBoundRecovery = Promise.resolve();
|
|
476
628
|
let closeTask;
|
|
477
629
|
let backendInvalidationPoisoned = false;
|
|
478
630
|
let domainModules;
|
|
@@ -539,6 +691,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
539
691
|
oauthCredentials,
|
|
540
692
|
createRunComposer: createInteractiveRunComposerFactory({
|
|
541
693
|
skills,
|
|
694
|
+
pluginSkills,
|
|
542
695
|
memory: requireMemory(memory),
|
|
543
696
|
sessionTodo,
|
|
544
697
|
clientCapabilities: requireClientCapabilities(clientCapabilities),
|
|
@@ -551,9 +704,29 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
551
704
|
hostTools,
|
|
552
705
|
resolveRootTools: (sessionId) => requireGraphCoordinator(graphCoordinator).toolsForSession(sessionId),
|
|
553
706
|
resolvePluginTools: (sessionId, coreTools) => pluginTools.resolveContributions(sessionId, coreTools),
|
|
707
|
+
resolvePluginSystemPrompt: async (sessionId, promptContext, baseText) => {
|
|
708
|
+
const assembly = await pluginSystemPrompt.assemble({
|
|
709
|
+
sessionId,
|
|
710
|
+
turnId: promptContext.turnId,
|
|
711
|
+
cwd: promptContext.cwd,
|
|
712
|
+
}, baseText);
|
|
713
|
+
return {
|
|
714
|
+
text: assembly.text,
|
|
715
|
+
contexts: assembly.contexts,
|
|
716
|
+
sourceRevisions: assembly.sourceRevision ? [assembly.sourceRevision] : [],
|
|
717
|
+
};
|
|
718
|
+
},
|
|
554
719
|
parentAgentTools: childAgentTools.parentTools,
|
|
555
720
|
childTools: childAgentTools.childTools,
|
|
556
721
|
worktreePatchWriteBackAvailable: true,
|
|
722
|
+
resolveProfileSystemPrompt: async (promptContext, basePrompt) => {
|
|
723
|
+
if (promptContext.sessionId !== WORKHUB_COORDINATION_SESSION_ID)
|
|
724
|
+
return basePrompt;
|
|
725
|
+
const admission = await stores.agentRunStore.readRootTurnAdmission(promptContext.sessionId, promptContext.turnId);
|
|
726
|
+
return bindWorkHubRoutingDecisionPrompt(basePrompt, admission?.execution.kind === 'workhub_coordination'
|
|
727
|
+
? admission.execution.routingDecision
|
|
728
|
+
: undefined);
|
|
729
|
+
},
|
|
557
730
|
}),
|
|
558
731
|
...(hostedExecutionRunProfile(backendContext.header.toolProfile)?.memoryExtraction === false
|
|
559
732
|
? {}
|
|
@@ -927,8 +1100,229 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
927
1100
|
}, {
|
|
928
1101
|
currentGraphId: (rootSessionId) => requireGraphCoordinator(graphCoordinator).currentGraphId(rootSessionId),
|
|
929
1102
|
beginNextGraphEpoch: async (rootSessionId) => (await requireGraphCoordinator(graphCoordinator).beginNextGraphEpoch(rootSessionId, (operation) => requireGraphSupervisorWake(graphSupervisorWake).runWithSessionWakesSuppressed(rootSessionId, operation, 'agent_graph_epoch_advanced'))).graphId,
|
|
930
|
-
}, (input) => sessionEffectCoordinator.nameSessionFromRootMessage(input), context.owner.capability.rootId
|
|
1103
|
+
}, (input) => sessionEffectCoordinator.nameSessionFromRootMessage(input), context.owner.capability.rootId, dependencies.workHubRoutingModel
|
|
1104
|
+
? (input) => workHubCoordination.prepareRoutingDecision(input)
|
|
1105
|
+
: undefined);
|
|
931
1106
|
const coordinator = rootCoordinator;
|
|
1107
|
+
const pluginModel = createHostPluginModel({
|
|
1108
|
+
runtimePolicy: runtimePolicyStores,
|
|
1109
|
+
oauthCredentials,
|
|
1110
|
+
usage: openedUsageStores,
|
|
1111
|
+
requestDrain: context.requestDrain,
|
|
1112
|
+
readSessionHeader: (sessionId) => stores.sessionStore.readHeaderSnapshot(sessionId),
|
|
1113
|
+
});
|
|
1114
|
+
pluginLlm.bindRuntime({
|
|
1115
|
+
generate: (input, invocation) => pluginModel.generate({
|
|
1116
|
+
sessionId: invocation.sessionId,
|
|
1117
|
+
prompt: input.prompt,
|
|
1118
|
+
...(input.system ? { system: input.system } : {}),
|
|
1119
|
+
...(input.maxOutputTokens ? { maxOutputTokens: input.maxOutputTokens } : {}),
|
|
1120
|
+
abortSignal: input.signal ?? invocation.abortSignal,
|
|
1121
|
+
}),
|
|
1122
|
+
});
|
|
1123
|
+
const visibleAgentSessions = async (initiator) => {
|
|
1124
|
+
const sessions = await manager.listSessions();
|
|
1125
|
+
if (!initiator)
|
|
1126
|
+
return [];
|
|
1127
|
+
const visible = new Set([initiator.sessionId]);
|
|
1128
|
+
let changed = true;
|
|
1129
|
+
while (changed) {
|
|
1130
|
+
changed = false;
|
|
1131
|
+
for (const session of sessions) {
|
|
1132
|
+
if (!session.parentSessionId ||
|
|
1133
|
+
!visible.has(session.parentSessionId) ||
|
|
1134
|
+
visible.has(session.id))
|
|
1135
|
+
continue;
|
|
1136
|
+
visible.add(session.id);
|
|
1137
|
+
changed = true;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return sessions.filter((session) => visible.has(session.id));
|
|
1141
|
+
};
|
|
1142
|
+
const pluginSessionSummary = (session) => Object.freeze({
|
|
1143
|
+
id: session.id,
|
|
1144
|
+
...(session.name ? { title: session.name } : {}),
|
|
1145
|
+
...(session.cwd ? { cwd: session.cwd } : {}),
|
|
1146
|
+
...(session.status ? { status: session.status } : {}),
|
|
1147
|
+
...(session.parentSessionId ? { parentSessionId: session.parentSessionId } : {}),
|
|
1148
|
+
...(session.statusUpdatedAt || session.lastMessageAt
|
|
1149
|
+
? { updatedAt: session.statusUpdatedAt ?? session.lastMessageAt }
|
|
1150
|
+
: {}),
|
|
1151
|
+
});
|
|
1152
|
+
const sessionQueryInitiator = (caller) => caller.invocation ??
|
|
1153
|
+
(caller.scopeSessionId ? Object.freeze({ sessionId: caller.scopeSessionId }) : undefined);
|
|
1154
|
+
pluginSessionQuery.bindRuntime({
|
|
1155
|
+
list: async (caller) => Object.freeze((await visibleAgentSessions(sessionQueryInitiator(caller))).map(pluginSessionSummary)),
|
|
1156
|
+
read: async (sessionId, caller) => {
|
|
1157
|
+
const session = (await visibleAgentSessions(sessionQueryInitiator(caller))).find(({ id }) => id === sessionId);
|
|
1158
|
+
if (!session)
|
|
1159
|
+
return undefined;
|
|
1160
|
+
return Object.freeze({
|
|
1161
|
+
session: pluginSessionSummary(session),
|
|
1162
|
+
messages: Object.freeze([
|
|
1163
|
+
...(await requireSessionManager(manager).getMessages(sessionId)),
|
|
1164
|
+
]),
|
|
1165
|
+
});
|
|
1166
|
+
},
|
|
1167
|
+
search: async (request, caller) => {
|
|
1168
|
+
const query = request.query.toLocaleLowerCase();
|
|
1169
|
+
const sessions = await visibleAgentSessions(sessionQueryInitiator(caller));
|
|
1170
|
+
const matches = [];
|
|
1171
|
+
for (const session of sessions) {
|
|
1172
|
+
const headerText = `${session.name}\n${session.cwd ?? ''}`.toLocaleLowerCase();
|
|
1173
|
+
if (headerText.includes(query)) {
|
|
1174
|
+
matches.push(session);
|
|
1175
|
+
continue;
|
|
1176
|
+
}
|
|
1177
|
+
const messages = await requireSessionManager(manager).getMessages(session.id);
|
|
1178
|
+
if (messages.some((message) => JSON.stringify(message).toLocaleLowerCase().includes(query))) {
|
|
1179
|
+
matches.push(session);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
const offset = request.cursor ? Number.parseInt(request.cursor, 10) : 0;
|
|
1183
|
+
if (!Number.isSafeInteger(offset) || offset < 0)
|
|
1184
|
+
throw new TypeError('Invalid Session query cursor');
|
|
1185
|
+
const limit = request.limit ?? 20;
|
|
1186
|
+
const page = matches.slice(offset, offset + limit);
|
|
1187
|
+
return Object.freeze({
|
|
1188
|
+
items: Object.freeze(page.map(pluginSessionSummary)),
|
|
1189
|
+
...(offset + page.length < matches.length
|
|
1190
|
+
? { cursor: String(offset + page.length) }
|
|
1191
|
+
: {}),
|
|
1192
|
+
});
|
|
1193
|
+
},
|
|
1194
|
+
});
|
|
1195
|
+
const describeAgent = (session) => ({
|
|
1196
|
+
id: session.id,
|
|
1197
|
+
sessionId: session.id,
|
|
1198
|
+
root: !session.parentSessionId,
|
|
1199
|
+
status: session.runningTurnIds?.length ? 'running' : session.status,
|
|
1200
|
+
...(session.parentSessionId ? { ownerId: session.parentSessionId } : {}),
|
|
1201
|
+
});
|
|
1202
|
+
const submitAgentMessage = async (id, message, placement, initiator) => {
|
|
1203
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id)) {
|
|
1204
|
+
throw new Error('Agent is outside the current ownership tree');
|
|
1205
|
+
}
|
|
1206
|
+
const content = normalizeMessageContent(typeof message === 'string' ? { text: message } : message);
|
|
1207
|
+
const result = await messages.handlers['turn.message.submit']({
|
|
1208
|
+
originHostEpoch: context.hostEpoch,
|
|
1209
|
+
sessionId: id,
|
|
1210
|
+
messageId: randomUUID(),
|
|
1211
|
+
content,
|
|
1212
|
+
placement,
|
|
1213
|
+
}, {
|
|
1214
|
+
hostEpoch: context.hostEpoch,
|
|
1215
|
+
connectionId: 'plugin-agent',
|
|
1216
|
+
principal: 'runtime_host',
|
|
1217
|
+
acquireResidency: () => context.acquireResidency('plugin-agent'),
|
|
1218
|
+
});
|
|
1219
|
+
if (!result.ok)
|
|
1220
|
+
throw new Error(result.error.message);
|
|
1221
|
+
return result.result;
|
|
1222
|
+
};
|
|
1223
|
+
pluginAgents.bindRuntime({
|
|
1224
|
+
create: async (options, initiator) => {
|
|
1225
|
+
const spawn = initiator.toolContext?.spawnChildSession;
|
|
1226
|
+
if (!spawn)
|
|
1227
|
+
throw new Error('Agent creation requires an active Tool invocation');
|
|
1228
|
+
if (!options.prompt?.trim())
|
|
1229
|
+
throw new Error('Agent creation requires a prompt');
|
|
1230
|
+
return new Promise((resolve, reject) => {
|
|
1231
|
+
void spawn({
|
|
1232
|
+
agentProfile: options.agentProfile ?? 'implementation',
|
|
1233
|
+
prompt: options.prompt,
|
|
1234
|
+
...(options.signal ? { abortSignal: options.signal } : {}),
|
|
1235
|
+
onReady: (ready) => resolve({
|
|
1236
|
+
id: ready.childSessionId,
|
|
1237
|
+
sessionId: ready.childSessionId,
|
|
1238
|
+
root: false,
|
|
1239
|
+
status: 'running',
|
|
1240
|
+
ownerId: initiator.sessionId,
|
|
1241
|
+
}),
|
|
1242
|
+
}).catch(reject);
|
|
1243
|
+
});
|
|
1244
|
+
},
|
|
1245
|
+
resume: async (options, initiator) => {
|
|
1246
|
+
if (options.prompt)
|
|
1247
|
+
await submitAgentMessage(options.sessionId, options.prompt, 'next_turn', initiator);
|
|
1248
|
+
const session = (await visibleAgentSessions(initiator)).find((item) => item.id === options.sessionId);
|
|
1249
|
+
if (!session)
|
|
1250
|
+
throw new Error('Agent was not found');
|
|
1251
|
+
return describeAgent(session);
|
|
1252
|
+
},
|
|
1253
|
+
get: async (id, initiator) => {
|
|
1254
|
+
const session = (await visibleAgentSessions(initiator)).find((item) => item.id === id);
|
|
1255
|
+
return session ? describeAgent(session) : undefined;
|
|
1256
|
+
},
|
|
1257
|
+
list: async (initiator) => (await visibleAgentSessions(initiator)).map(describeAgent),
|
|
1258
|
+
roots: async (initiator) => (await visibleAgentSessions(initiator))
|
|
1259
|
+
.filter((session) => !session.parentSessionId)
|
|
1260
|
+
.map(describeAgent),
|
|
1261
|
+
followup: (id, message, initiator) => submitAgentMessage(id, message, 'next_turn', initiator),
|
|
1262
|
+
steer: (id, message, initiator) => submitAgentMessage(id, message, 'current_turn', initiator),
|
|
1263
|
+
inject: (id, message, initiator) => submitAgentMessage(id, message, 'current_turn', initiator),
|
|
1264
|
+
cancel: async (id, initiator) => {
|
|
1265
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id)) {
|
|
1266
|
+
throw new Error('Agent is outside the current ownership tree');
|
|
1267
|
+
}
|
|
1268
|
+
await coordinator.stopSession(id, { source: 'stop_button' });
|
|
1269
|
+
},
|
|
1270
|
+
whenIdle: async (id, signal, initiator) => {
|
|
1271
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id)) {
|
|
1272
|
+
throw new Error('Agent is outside the current ownership tree');
|
|
1273
|
+
}
|
|
1274
|
+
const wait = coordinator.whenIdle(id);
|
|
1275
|
+
if (!wait)
|
|
1276
|
+
return;
|
|
1277
|
+
if (!signal)
|
|
1278
|
+
return wait;
|
|
1279
|
+
if (signal.aborted)
|
|
1280
|
+
throw signal.reason;
|
|
1281
|
+
let rejectAbort;
|
|
1282
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
1283
|
+
rejectAbort = reject;
|
|
1284
|
+
});
|
|
1285
|
+
const onAbort = () => rejectAbort?.(signal.reason);
|
|
1286
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
1287
|
+
try {
|
|
1288
|
+
await Promise.race([wait, aborted]);
|
|
1289
|
+
}
|
|
1290
|
+
finally {
|
|
1291
|
+
signal.removeEventListener('abort', onAbort);
|
|
1292
|
+
}
|
|
1293
|
+
},
|
|
1294
|
+
snapshot: async (id, initiator) => {
|
|
1295
|
+
const session = (await visibleAgentSessions(initiator)).find((item) => item.id === id);
|
|
1296
|
+
if (!session)
|
|
1297
|
+
throw new Error('Agent was not found');
|
|
1298
|
+
return { agent: describeAgent(session), root: coordinator.readRootState(id) };
|
|
1299
|
+
},
|
|
1300
|
+
inbox: async (id, initiator) => {
|
|
1301
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id))
|
|
1302
|
+
throw new Error('Agent was not found');
|
|
1303
|
+
return coordinator.readRootState(id);
|
|
1304
|
+
},
|
|
1305
|
+
result: async (id, initiator) => {
|
|
1306
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id))
|
|
1307
|
+
throw new Error('Agent was not found');
|
|
1308
|
+
return (await manager.getMessages(id)).at(-1);
|
|
1309
|
+
},
|
|
1310
|
+
artifacts: async (id, initiator) => {
|
|
1311
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id))
|
|
1312
|
+
throw new Error('Agent was not found');
|
|
1313
|
+
return (await openedArtifactStore.listPage(id, { offset: 0, limit: 100 })).records;
|
|
1314
|
+
},
|
|
1315
|
+
transcript: async (id, initiator) => {
|
|
1316
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id))
|
|
1317
|
+
throw new Error('Agent was not found');
|
|
1318
|
+
return manager.getMessages(id);
|
|
1319
|
+
},
|
|
1320
|
+
dispose: async (id, initiator) => {
|
|
1321
|
+
if (!(await visibleAgentSessions(initiator)).some((session) => session.id === id))
|
|
1322
|
+
throw new Error('Agent was not found');
|
|
1323
|
+
await coordinator.stopSession(id, { source: 'stop_button' });
|
|
1324
|
+
},
|
|
1325
|
+
});
|
|
932
1326
|
const contextOperations = new HostContextCoordinator({
|
|
933
1327
|
runtime: manager,
|
|
934
1328
|
executions: coordinator,
|
|
@@ -1032,6 +1426,34 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1032
1426
|
onProjectionChanged: (sessionId) => continuityCoordinator.enqueueCanonicalRefresh(sessionId),
|
|
1033
1427
|
requestDrain: context.requestDrain,
|
|
1034
1428
|
});
|
|
1429
|
+
pluginGoals.bindRuntime({
|
|
1430
|
+
execute: async (operation, invocation) => {
|
|
1431
|
+
const coordinator = requireGoal(goal);
|
|
1432
|
+
if (operation.kind === 'get')
|
|
1433
|
+
return coordinator.readProjection(invocation.sessionId);
|
|
1434
|
+
if (!invocation.toolContext)
|
|
1435
|
+
throw new Error('Goal mutation requires an active Tool invocation');
|
|
1436
|
+
const toolName = operation.kind === 'create'
|
|
1437
|
+
? 'GoalSet'
|
|
1438
|
+
: operation.kind === 'clear'
|
|
1439
|
+
? 'GoalClear'
|
|
1440
|
+
: operation.kind === 'pause'
|
|
1441
|
+
? 'GoalPause'
|
|
1442
|
+
: 'GoalResume';
|
|
1443
|
+
const tool = coordinator.tools.find(({ name }) => name === toolName);
|
|
1444
|
+
if (!tool)
|
|
1445
|
+
throw new Error(`Goal capability is unavailable: ${toolName}`);
|
|
1446
|
+
const args = operation.kind === 'create'
|
|
1447
|
+
? {
|
|
1448
|
+
condition: operation.objective,
|
|
1449
|
+
...(operation.maxIterations ? { max_iterations: operation.maxIterations } : {}),
|
|
1450
|
+
...(operation.blockCap ? { block_cap: operation.blockCap } : {}),
|
|
1451
|
+
...(operation.tokenBudget ? { token_budget: operation.tokenBudget } : {}),
|
|
1452
|
+
}
|
|
1453
|
+
: {};
|
|
1454
|
+
return await tool.impl(args, invocation.toolContext);
|
|
1455
|
+
},
|
|
1456
|
+
});
|
|
1035
1457
|
async function applyRuntimePolicyMutationEffects() {
|
|
1036
1458
|
try {
|
|
1037
1459
|
await requireMemory(memory).refreshAfterPolicyMutation();
|
|
@@ -1061,7 +1483,8 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1061
1483
|
? { sessionAccessAuthority: context.sessionAccessAuthority }
|
|
1062
1484
|
: {}),
|
|
1063
1485
|
});
|
|
1064
|
-
|
|
1486
|
+
workHubCoordination = new HostWorkHubCoordinationCoordinator({
|
|
1487
|
+
routingModel: dependencies.workHubRoutingModel,
|
|
1065
1488
|
configureModel: (input) => sessionCatalog.configureWorkHubModel(input),
|
|
1066
1489
|
transitionConfiguration: (input) => requireSessionManager(manager).transitionSessionConfiguration(WORKHUB_COORDINATION_SESSION_ID, input),
|
|
1067
1490
|
stateRoot: context.owner.capability.canonicalPath,
|
|
@@ -1556,7 +1979,35 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1556
1979
|
}),
|
|
1557
1980
|
createRuntimeHostDomainModule({
|
|
1558
1981
|
id: 'client-capability',
|
|
1559
|
-
handlers: [
|
|
1982
|
+
handlers: [
|
|
1983
|
+
{
|
|
1984
|
+
...clientCapabilities.handlers,
|
|
1985
|
+
'client.capability.replace': async (input, operationContext) => {
|
|
1986
|
+
const outcome = await clientCapabilities.handlers['client.capability.replace'](input, operationContext);
|
|
1987
|
+
if (outcome.ok && rootRecoveryCompleted && !draining) {
|
|
1988
|
+
// Registration completes outside the policy mutation gate before
|
|
1989
|
+
// recovery selects bindings or composes a backend. Serialize
|
|
1990
|
+
// reconnects and retain the task for the shutdown barrier.
|
|
1991
|
+
clientBoundRecovery = clientBoundRecovery.then(async () => {
|
|
1992
|
+
if (draining)
|
|
1993
|
+
return;
|
|
1994
|
+
await coordinator.recover();
|
|
1995
|
+
await messages.consumePendingAdmissions(recoverySessions
|
|
1996
|
+
.filter((session) => session.toolProfile === 'workhub-coordination-v2')
|
|
1997
|
+
.map((session) => session.id));
|
|
1998
|
+
});
|
|
1999
|
+
try {
|
|
2000
|
+
await clientBoundRecovery;
|
|
2001
|
+
}
|
|
2002
|
+
catch (error) {
|
|
2003
|
+
context.requestDrain();
|
|
2004
|
+
throw error;
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
return outcome;
|
|
2008
|
+
},
|
|
2009
|
+
},
|
|
2010
|
+
],
|
|
1560
2011
|
recovery: {
|
|
1561
2012
|
resources: async () => {
|
|
1562
2013
|
await recoverClientCapabilityOutcomes(stores.runtimeEventStore, recoverySessions.map((session) => session.id));
|
|
@@ -1630,6 +2081,7 @@ export async function createExecutionRuntimeHostComposition(context, options = {
|
|
|
1630
2081
|
async () => {
|
|
1631
2082
|
if (!rootRecoveryCompleted || poisonFailure)
|
|
1632
2083
|
return;
|
|
2084
|
+
await clientBoundRecovery.catch(() => undefined);
|
|
1633
2085
|
rootCloseTask ??= coordinator.close();
|
|
1634
2086
|
await rootCloseTask;
|
|
1635
2087
|
},
|
|
@@ -2028,6 +2480,24 @@ function requireGoal(coordinator) {
|
|
|
2028
2480
|
throw new Error('Runtime Host Goal coordinator is not composed');
|
|
2029
2481
|
return coordinator;
|
|
2030
2482
|
}
|
|
2483
|
+
function pluginAttachmentArtifactKind(mimeType, name) {
|
|
2484
|
+
const kind = attachmentKindFromMimeType(mimeType, name);
|
|
2485
|
+
return kind === 'image' || kind === 'pdf' ? kind : 'file';
|
|
2486
|
+
}
|
|
2487
|
+
function pluginAttachmentRef(record) {
|
|
2488
|
+
const mimeType = record.mimeType ?? 'application/octet-stream';
|
|
2489
|
+
return {
|
|
2490
|
+
kind: attachmentKindFromMimeType(mimeType, record.name),
|
|
2491
|
+
name: record.name,
|
|
2492
|
+
mimeType,
|
|
2493
|
+
bytes: record.sizeBytes,
|
|
2494
|
+
ref: {
|
|
2495
|
+
kind: 'session_file',
|
|
2496
|
+
sessionId: record.sessionId,
|
|
2497
|
+
relativePath: record.relativePath,
|
|
2498
|
+
},
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2031
2501
|
/** Every run this Session has opened, named by the event spine that defines it. */
|
|
2032
2502
|
async function sessionRunIds(runtimeEventStore, sessionId) {
|
|
2033
2503
|
return (await runtimeEventStore.listSessionInvocations(sessionId)).map((invocation) => invocation.runId);
|