@capekai/core 1.0.0
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/README.md +12 -0
- package/package.json +105 -0
- package/src/adapters/ai-sdk.ts +84 -0
- package/src/compaction/contracts.ts +82 -0
- package/src/compaction/executor.ts +161 -0
- package/src/compaction/policy.ts +318 -0
- package/src/compaction/recovery.ts +139 -0
- package/src/compaction/task.ts +540 -0
- package/src/configuration/contracts.ts +58 -0
- package/src/configuration/defaults.ts +27 -0
- package/src/configuration/runtime.ts +42 -0
- package/src/configuration/single-model.ts +75 -0
- package/src/context/assembler.ts +112 -0
- package/src/context/index.ts +2 -0
- package/src/context/sources.ts +119 -0
- package/src/context/workspace.ts +63 -0
- package/src/core/agent.ts +401 -0
- package/src/core/build-tools.ts +139 -0
- package/src/core/chat-handler.ts +858 -0
- package/src/core/error-handling.ts +18 -0
- package/src/core/fork.ts +103 -0
- package/src/core/interrupt.ts +192 -0
- package/src/core/message-utils.ts +261 -0
- package/src/core/model-utils.ts +149 -0
- package/src/core/part-utils.ts +88 -0
- package/src/core/provider-utils.ts +67 -0
- package/src/core/revert.ts +46 -0
- package/src/core/step-handlers.ts +157 -0
- package/src/core/stream/finalization.ts +65 -0
- package/src/core/stream/stream-config.ts +82 -0
- package/src/core/stream-handlers.ts +242 -0
- package/src/core/structured-output.ts +68 -0
- package/src/core/tool-builders/agent-tools.ts +71 -0
- package/src/core/tool-builders/external-tools.ts +179 -0
- package/src/core/tool-builders/types.ts +16 -0
- package/src/core/tool-builders/workspace-tools.ts +293 -0
- package/src/core/tool-capabilities.ts +65 -0
- package/src/goals/evaluator.ts +171 -0
- package/src/goals/index.ts +3 -0
- package/src/goals/loop.ts +167 -0
- package/src/goals/service.ts +39 -0
- package/src/index.ts +10 -0
- package/src/internal/ask-authority.ts +29 -0
- package/src/internal/composition.ts +44 -0
- package/src/internal/configuration.ts +22 -0
- package/src/internal/execution.ts +108 -0
- package/src/internal/hosts.ts +64 -0
- package/src/internal/plugins.ts +71 -0
- package/src/internal/providers.ts +32 -0
- package/src/internal/sandbox.ts +19 -0
- package/src/internal/tools.ts +48 -0
- package/src/internal/workspace.ts +25 -0
- package/src/kernel/diagnostics.ts +249 -0
- package/src/kernel/errors.ts +120 -0
- package/src/kernel/events.ts +82 -0
- package/src/kernel/index.ts +72 -0
- package/src/kernel/kernel.ts +62 -0
- package/src/kernel/lifecycle.ts +72 -0
- package/src/kernel/plugin.ts +218 -0
- package/src/kernel/registry.ts +493 -0
- package/src/kernel/scope.ts +776 -0
- package/src/kernel/service-key.ts +19 -0
- package/src/kernel/types.ts +317 -0
- package/src/memory/index.ts +2 -0
- package/src/memory/memory-tool.ts +75 -0
- package/src/memory/registry.ts +172 -0
- package/src/permission/ask-user-api.ts +70 -0
- package/src/permission/contracts.ts +135 -0
- package/src/permission/permission-request-manager.ts +58 -0
- package/src/permission/policy.ts +277 -0
- package/src/permission/runtime.ts +612 -0
- package/src/plugins/compaction-policy.ts +46 -0
- package/src/plugins/compose.ts +171 -0
- package/src/plugins/context-sections.ts +246 -0
- package/src/plugins/default-agent-driver.ts +14 -0
- package/src/plugins/facade-plugins.ts +129 -0
- package/src/plugins/goal-domain.ts +82 -0
- package/src/plugins/legacy-system-message.ts +152 -0
- package/src/plugins/loaded-tools.ts +23 -0
- package/src/plugins/memory-domain.ts +264 -0
- package/src/plugins/orchestrator-session.ts +29 -0
- package/src/plugins/permission-policy.ts +49 -0
- package/src/plugins/retry-policy.ts +28 -0
- package/src/plugins/scheduler-domain.ts +192 -0
- package/src/plugins/service-keys.ts +294 -0
- package/src/plugins/session-search-domain.ts +238 -0
- package/src/plugins/skills-domain.ts +272 -0
- package/src/plugins/subagent-domain.ts +287 -0
- package/src/plugins/tool-catalog.ts +78 -0
- package/src/plugins/tool-output-policy.ts +52 -0
- package/src/plugins/value-plugins.ts +150 -0
- package/src/plugins/workflow-domain.ts +198 -0
- package/src/plugins/workspace-policy.ts +37 -0
- package/src/providers/registry.ts +63 -0
- package/src/providers/types.ts +44 -0
- package/src/retry/policy.ts +282 -0
- package/src/retry/stream-chat.ts +312 -0
- package/src/runtime/agent-runtime.ts +83 -0
- package/src/runtime/default-agent-driver.ts +23 -0
- package/src/runtime/domain-tool-source.ts +156 -0
- package/src/runtime/events.ts +61 -0
- package/src/runtime/host-dependencies.ts +71 -0
- package/src/runtime/host-guidance.ts +22 -0
- package/src/runtime/host-layout.ts +23 -0
- package/src/runtime/host.ts +129 -0
- package/src/runtime/standalone-host.ts +118 -0
- package/src/sandbox/controller.ts +204 -0
- package/src/sandbox/model.ts +305 -0
- package/src/sandbox/provider.ts +53 -0
- package/src/sandbox/types.ts +110 -0
- package/src/scheduler/host.ts +22 -0
- package/src/scheduler/scheduler-tool.ts +172 -0
- package/src/session-search/host.ts +56 -0
- package/src/session-search/index.ts +23 -0
- package/src/session-search/session-search-tool.ts +151 -0
- package/src/skills/index.ts +3 -0
- package/src/skills/registry.ts +63 -0
- package/src/skills/skill-manage-tool.ts +205 -0
- package/src/skills/skill-tool.ts +42 -0
- package/src/storage/contracts.ts +159 -0
- package/src/storage/memory.ts +321 -0
- package/src/storage/options.ts +75 -0
- package/src/storage/runtime.ts +115 -0
- package/src/storage/sqlite-tool-output-artifacts.ts +106 -0
- package/src/storage/sqlite.ts +321 -0
- package/src/storage/tool-output-artifacts.ts +75 -0
- package/src/storage.ts +31 -0
- package/src/subagent/child-session.ts +282 -0
- package/src/subagent/guidance.ts +8 -0
- package/src/subagent/policy.ts +198 -0
- package/src/subagent/task-tool.ts +584 -0
- package/src/tool-output/contracts.ts +111 -0
- package/src/tool-output/policy.ts +410 -0
- package/src/tool.ts +1 -0
- package/src/tools/executor.ts +258 -0
- package/src/tools/install-manifest.ts +40 -0
- package/src/tools/llm-api.ts +77 -0
- package/src/tools/registry.ts +206 -0
- package/src/tools/tool-artifact.ts +182 -0
- package/src/tools/tool-source.ts +53 -0
- package/src/utils/errors.ts +334 -0
- package/src/utils/strip-visualization.ts +50 -0
- package/src/workflow/decomposer.ts +139 -0
- package/src/workflow/execution.ts +523 -0
- package/src/workflow/orchestrator-session.ts +161 -0
- package/src/workflow/synthesizer.ts +130 -0
- package/src/workspace/contracts.ts +135 -0
- package/src/workspace/policy.ts +327 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import type { Preconfig } from '@capekai/types'
|
|
2
|
+
import type { ToolDefinition } from '@capekai/tool';
|
|
3
|
+
import { validateContextAssemblyData, type ContextAssemblyData } from '../context/assembler';
|
|
4
|
+
import { serviceKey } from '../kernel/service-key';
|
|
5
|
+
import type {
|
|
6
|
+
CapekPlugin,
|
|
7
|
+
ContextSectionContribution,
|
|
8
|
+
PluginContext,
|
|
9
|
+
ToolDefinition as KernelToolDefinition,
|
|
10
|
+
} from '../kernel/types';
|
|
11
|
+
import {
|
|
12
|
+
DOMAIN_TOOL_PAYLOAD_FIELD,
|
|
13
|
+
registerDomainToolFallback,
|
|
14
|
+
type DomainToolPayload,
|
|
15
|
+
} from '../runtime/domain-tool-source';
|
|
16
|
+
import type { RuntimeDelivery, RuntimeEvent } from '../runtime/events';
|
|
17
|
+
import type { BroadcastFn, RuntimeHost } from '../runtime/host';
|
|
18
|
+
import type { StorageBundle } from '../storage/contracts';
|
|
19
|
+
import { executeChildSession } from '../subagent/child-session';
|
|
20
|
+
import { selfDelegationGuidance } from '../subagent/guidance';
|
|
21
|
+
import {
|
|
22
|
+
resolveEffectiveSubagentTargets,
|
|
23
|
+
type ResolveSubagentTargetsOptions,
|
|
24
|
+
} from '../subagent/policy';
|
|
25
|
+
import {
|
|
26
|
+
buildTaskToolDefinition,
|
|
27
|
+
canSpawnSubagent,
|
|
28
|
+
canSpawnSubagentWithDeps,
|
|
29
|
+
executeSubagent,
|
|
30
|
+
executeSubagentWithDeps,
|
|
31
|
+
getSubagentToolDefinition,
|
|
32
|
+
type GetSubagentToolDefinitionOptions,
|
|
33
|
+
type SubagentInput,
|
|
34
|
+
type SubagentOutput,
|
|
35
|
+
type SubagentServiceBroadcasts,
|
|
36
|
+
type SubagentServiceDeps,
|
|
37
|
+
type SubagentServiceSessionAccess,
|
|
38
|
+
} from '../subagent/task-tool';
|
|
39
|
+
import { capekContextSourcesKey, capekRuntimeHostKey, capekStorageKey } from './service-keys';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* C5 subagent domain plugin. Owns the agent-scoped subagent service (depth
|
|
43
|
+
* and ancestry policy over the captured storage and preconfig sources), the
|
|
44
|
+
* `task` tool contribution through the generic contributed-domain-tool seam,
|
|
45
|
+
* and the `self-delegation` context section. Composed payloads never read
|
|
46
|
+
* module-level globals; the unscoped fallback keeps the pre-C5
|
|
47
|
+
* execute-time module accessors and is installed explicitly, never at
|
|
48
|
+
* module load.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
export const CURRENT_SUBAGENT_DOMAIN_PLUGIN_ID = 'current.subagent-domain';
|
|
52
|
+
export const SUBAGENT_TOOL_CONTRIBUTION_ID = 'subagent.task';
|
|
53
|
+
/** Before session-search (700) and scheduler (750) so the contributed tool
|
|
54
|
+
* order keeps `task` ahead of the workspace-gated domain tools, matching
|
|
55
|
+
* the pre-C5 buildAiSdkTools phase-1 placement. */
|
|
56
|
+
export const SUBAGENT_TOOL_CONTRIBUTION_ORDER = 650;
|
|
57
|
+
export const SELF_DELEGATION_SECTION_ID = 'self-delegation';
|
|
58
|
+
|
|
59
|
+
export interface SubagentDomainService {
|
|
60
|
+
readonly tools: readonly DomainToolPayload[];
|
|
61
|
+
/** Depth gate shared by the task tool payload. */
|
|
62
|
+
canSpawnSubagent(sessionId: string): Promise<boolean>;
|
|
63
|
+
resolveTargets(options: ResolveSubagentTargetsOptions): Promise<Preconfig[]>;
|
|
64
|
+
/** Composed leaf execution for other C5 domains (workflow): runs the task
|
|
65
|
+
* execution path over this domain's scope-captured deps, never module
|
|
66
|
+
* globals. */
|
|
67
|
+
execute(input: SubagentInput): Promise<SubagentOutput>;
|
|
68
|
+
/** Scope-captured subagent preconfig listing for other C5 domains
|
|
69
|
+
* (workflow decomposition). */
|
|
70
|
+
listSubagents(): Promise<Preconfig[]>;
|
|
71
|
+
/** Whether the current session may delegate to a fresh instance of its own
|
|
72
|
+
* preconfig: task tool visible + allowSelfAsSubagent + the resolved target
|
|
73
|
+
* list contains the current preconfig. Mirrors the pre-C5 agent.ts
|
|
74
|
+
* computation over the same domain policy. */
|
|
75
|
+
selfDelegationAvailable(
|
|
76
|
+
sessionId: string,
|
|
77
|
+
preconfigId: string,
|
|
78
|
+
allowSelfAsSubagent: boolean,
|
|
79
|
+
): Promise<boolean>;
|
|
80
|
+
guidance(preconfigId: string): string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const capekSubagentDomainKey = serviceKey<SubagentDomainService>(
|
|
84
|
+
'capek.subagent-domain',
|
|
85
|
+
'agent',
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
function deliver(host: RuntimeHost, delivery: RuntimeDelivery): void {
|
|
89
|
+
host.delivery.observe?.(delivery);
|
|
90
|
+
host.delivery.emit(delivery);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Runtime-host delivery projection shared by the C5 domain plugins
|
|
94
|
+
* (subagent, workflow) that route leaf events through the captured host. */
|
|
95
|
+
export function broadcastsFromHost(host: RuntimeHost): SubagentServiceBroadcasts {
|
|
96
|
+
return {
|
|
97
|
+
event: (event) => deliver(host, { event, audience: { scope: 'global' } }),
|
|
98
|
+
sessionCreated: (session) =>
|
|
99
|
+
deliver(host, { event: { kind: 'session', action: 'created', session }, audience: { scope: 'global' } }),
|
|
100
|
+
sessionUpdated: (session) =>
|
|
101
|
+
deliver(host, { event: { kind: 'session', action: 'updated', session }, audience: { scope: 'global' } }),
|
|
102
|
+
toSession: (sessionId: string, event: RuntimeEvent) =>
|
|
103
|
+
deliver(host, { event, audience: { scope: 'session', sessionId } }),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface TaskPayloadDeps {
|
|
108
|
+
canSpawn: (sessionId: string) => boolean | Promise<boolean>;
|
|
109
|
+
resolveDefinition: (
|
|
110
|
+
options: GetSubagentToolDefinitionOptions,
|
|
111
|
+
) => Promise<ToolDefinition | null>;
|
|
112
|
+
execute: (input: SubagentInput) => Promise<Record<string, unknown>>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function taskPayload(deps: TaskPayloadDeps): DomainToolPayload {
|
|
116
|
+
const placeholder = buildTaskToolDefinition([]);
|
|
117
|
+
return {
|
|
118
|
+
name: placeholder.name,
|
|
119
|
+
description: placeholder.description,
|
|
120
|
+
inputSchema: placeholder.inputSchema,
|
|
121
|
+
display: { summary: '{description}' },
|
|
122
|
+
visualize: (_input, result) => {
|
|
123
|
+
const taskId = typeof result.task_id === 'string' ? result.task_id : '';
|
|
124
|
+
const text = typeof result.result === 'string' ? result.result : '';
|
|
125
|
+
return {
|
|
126
|
+
type: 'none',
|
|
127
|
+
badge: taskId ? 'session ready' : undefined,
|
|
128
|
+
message: text.split('\n').filter((line) => line && !line.startsWith('task_id:'))
|
|
129
|
+
.join('\n').replace(/<\/?task_result>/g, '').replace(/<\/?structured_result>/g, '').trim().slice(0, 200) || 'Subagent completed',
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
isEnabled: async (workspaceId, sessionId) =>
|
|
133
|
+
typeof sessionId === 'string' && await deps.canSpawn(sessionId),
|
|
134
|
+
resolveDefinition: async (sessionId, options) => {
|
|
135
|
+
const definition = await deps.resolveDefinition({
|
|
136
|
+
sessionId,
|
|
137
|
+
canSpawnSubagents: options?.canSpawnSubagents as boolean | string[] | null | undefined,
|
|
138
|
+
allowSelfAsSubagent: options?.allowSelfAsSubagent as boolean | undefined,
|
|
139
|
+
});
|
|
140
|
+
if (!definition) return null;
|
|
141
|
+
return {
|
|
142
|
+
description: definition.description,
|
|
143
|
+
inputSchema: definition.inputSchema,
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
execute: async (input, context) => {
|
|
147
|
+
const subagentInput: SubagentInput = {
|
|
148
|
+
description: input.description as string,
|
|
149
|
+
prompt: input.prompt as string,
|
|
150
|
+
subagent_type: input.subagent_type as string,
|
|
151
|
+
task_id: input.task_id as string | undefined,
|
|
152
|
+
sessionId: context.sessionId,
|
|
153
|
+
workspaceId: typeof context.workspaceId === 'string' ? context.workspaceId : undefined,
|
|
154
|
+
workspacePath: typeof context.workspacePath === 'string' ? context.workspacePath : undefined,
|
|
155
|
+
abortSignal: context.abortSignal as AbortSignal | undefined,
|
|
156
|
+
onSessionCreated: context.onSessionCreated as ((childSessionId: string) => void | Promise<void>) | undefined,
|
|
157
|
+
allowedSubagentIds: context.allowedSubagentIds as string[] | undefined,
|
|
158
|
+
broadcast: context.broadcast as BroadcastFn | undefined,
|
|
159
|
+
...(input.outputSchema ? { outputSchema: input.outputSchema as Record<string, unknown> } : {}),
|
|
160
|
+
};
|
|
161
|
+
return deps.execute(subagentInput);
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Unscoped compatibility payload: keeps the pre-C5 execute-time module
|
|
167
|
+
* accessors. Installed through `installTaskToolFallback`, never at module
|
|
168
|
+
* load. */
|
|
169
|
+
export function createTaskToolFallbackPayload(): DomainToolPayload {
|
|
170
|
+
return taskPayload({
|
|
171
|
+
canSpawn: (sessionId) => canSpawnSubagent(sessionId),
|
|
172
|
+
resolveDefinition: (options) => getSubagentToolDefinition(options),
|
|
173
|
+
execute: async (input) => executeSubagent(input) as unknown as Record<string, unknown>,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Explicitly installs the unscoped legacy fallback. Called by the Jean2
|
|
178
|
+
* compatibility bindings installation (server bootstrap) and by focused
|
|
179
|
+
* tests; no module-load registration exists. */
|
|
180
|
+
export function installTaskToolFallback(): void {
|
|
181
|
+
registerDomainToolFallback('task', createTaskToolFallbackPayload());
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
type GuidanceSectionContribution = ContextSectionContribution<ContextAssemblyData>;
|
|
185
|
+
|
|
186
|
+
export function subagentDomainPlugin(id: string): CapekPlugin<unknown> {
|
|
187
|
+
return {
|
|
188
|
+
id,
|
|
189
|
+
scope: 'agent',
|
|
190
|
+
provides: [capekSubagentDomainKey],
|
|
191
|
+
requires: [capekStorageKey, capekContextSourcesKey, capekRuntimeHostKey],
|
|
192
|
+
setup(context: PluginContext) {
|
|
193
|
+
const storage: StorageBundle = context.require(capekStorageKey);
|
|
194
|
+
const contextSources = context.require(capekContextSourcesKey);
|
|
195
|
+
const host: RuntimeHost = context.require(capekRuntimeHostKey);
|
|
196
|
+
const preconfigSource = contextSources.preconfigs;
|
|
197
|
+
const getPreconfigOrAgentScoped = (preconfigId: string): Promise<Preconfig | null> =>
|
|
198
|
+
preconfigSource ? preconfigSource.getForAgent(preconfigId) : Promise.resolve(null);
|
|
199
|
+
const listSubagentPreconfigsScoped = (): Promise<Preconfig[]> =>
|
|
200
|
+
preconfigSource ? preconfigSource.listSubagents() : Promise.resolve([]);
|
|
201
|
+
|
|
202
|
+
const sessionAccess: SubagentServiceSessionAccess = {
|
|
203
|
+
getSession: async (sessionId) => storage.conversation.getSession(sessionId),
|
|
204
|
+
createSession: async (session) => storage.conversation.createSession(session),
|
|
205
|
+
updateSession: async (sessionId, updates) => storage.conversation.updateSession(sessionId, updates),
|
|
206
|
+
getWorkspaceAutoApproveSeverity: async (workspaceId) => storage.workspaces.getAutoApproveSeverity(workspaceId),
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const serviceDeps: SubagentServiceDeps = {
|
|
210
|
+
sessionAccess,
|
|
211
|
+
preconfigs: {
|
|
212
|
+
getPreconfigOrAgent: getPreconfigOrAgentScoped,
|
|
213
|
+
listSubagentPreconfigs: listSubagentPreconfigsScoped,
|
|
214
|
+
},
|
|
215
|
+
broadcasts: broadcastsFromHost(host),
|
|
216
|
+
executeChild: executeChildSession,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const service: SubagentDomainService = {
|
|
220
|
+
tools: [
|
|
221
|
+
taskPayload({
|
|
222
|
+
canSpawn: async (sessionId) => canSpawnSubagentWithDeps(sessionId, sessionAccess.getSession),
|
|
223
|
+
resolveDefinition: async (options) => {
|
|
224
|
+
// The composed path resolves targets through the scope-captured
|
|
225
|
+
// storage and preconfig sources; it never reads module globals.
|
|
226
|
+
const deps = {
|
|
227
|
+
getSession: sessionAccess.getSession,
|
|
228
|
+
listPreconfigs: listSubagentPreconfigsScoped,
|
|
229
|
+
};
|
|
230
|
+
const maximumDepthReached = !(await canSpawnSubagentWithDeps(options.sessionId, deps.getSession));
|
|
231
|
+
return resolveEffectiveSubagentTargets({
|
|
232
|
+
...options,
|
|
233
|
+
maximumDepthReached,
|
|
234
|
+
}, deps).then((targets) =>
|
|
235
|
+
targets.length === 0 ? null : buildTaskToolDefinition(targets));
|
|
236
|
+
},
|
|
237
|
+
execute: (input) => executeSubagentWithDeps(input, serviceDeps) as unknown as Promise<Record<string, unknown>>,
|
|
238
|
+
}),
|
|
239
|
+
],
|
|
240
|
+
canSpawnSubagent: async (sessionId) => canSpawnSubagentWithDeps(sessionId, sessionAccess.getSession),
|
|
241
|
+
execute: (input) => executeSubagentWithDeps(input, serviceDeps),
|
|
242
|
+
listSubagents: listSubagentPreconfigsScoped,
|
|
243
|
+
resolveTargets: (options) => resolveEffectiveSubagentTargets(options, {
|
|
244
|
+
getSession: sessionAccess.getSession,
|
|
245
|
+
listPreconfigs: listSubagentPreconfigsScoped,
|
|
246
|
+
}),
|
|
247
|
+
selfDelegationAvailable: async (sessionId, preconfigId, allowSelfAsSubagent) =>
|
|
248
|
+
resolveEffectiveSubagentTargets({
|
|
249
|
+
sessionId,
|
|
250
|
+
canSpawnSubagents: true,
|
|
251
|
+
allowSelfAsSubagent,
|
|
252
|
+
maximumDepthReached: !(await canSpawnSubagentWithDeps(sessionId, sessionAccess.getSession)),
|
|
253
|
+
}, {
|
|
254
|
+
getSession: sessionAccess.getSession,
|
|
255
|
+
listPreconfigs: listSubagentPreconfigsScoped,
|
|
256
|
+
}).then((targets) =>
|
|
257
|
+
allowSelfAsSubagent === true && targets.some((candidate) => candidate.id === preconfigId)),
|
|
258
|
+
guidance: selfDelegationGuidance,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const guidance: GuidanceSectionContribution = {
|
|
262
|
+
id: SELF_DELEGATION_SECTION_ID,
|
|
263
|
+
phase: 'identity',
|
|
264
|
+
order: 50,
|
|
265
|
+
provide: (build) => {
|
|
266
|
+
const data = validateContextAssemblyData(build.data);
|
|
267
|
+
return data.selfDelegationAvailable ? service.guidance(data.preconfig.id) : null;
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
context.provide(capekSubagentDomainKey, service);
|
|
272
|
+
context.contributeTool({
|
|
273
|
+
id: SUBAGENT_TOOL_CONTRIBUTION_ID,
|
|
274
|
+
order: SUBAGENT_TOOL_CONTRIBUTION_ORDER,
|
|
275
|
+
definition: {
|
|
276
|
+
name: service.tools[0].name,
|
|
277
|
+
description: service.tools[0].description,
|
|
278
|
+
inputSchema: service.tools[0].inputSchema,
|
|
279
|
+
timeout: 300000,
|
|
280
|
+
[DOMAIN_TOOL_PAYLOAD_FIELD]: service.tools[0],
|
|
281
|
+
} as KernelToolDefinition,
|
|
282
|
+
requiredCapabilities: [capekSubagentDomainKey],
|
|
283
|
+
});
|
|
284
|
+
context.contributeContext(guidance);
|
|
285
|
+
},
|
|
286
|
+
};
|
|
287
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contributed tool catalog.
|
|
3
|
+
*
|
|
4
|
+
* Joins the effective tool contributions of a scope with the payloads
|
|
5
|
+
* carried on those contributions (`ToolContribution.payload`). The resolver
|
|
6
|
+
* re-attaches each contributed definition to its executor and install path
|
|
7
|
+
* by identity, in the deterministic kernel tool order.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { LoadedTool } from '@capekai/tool';
|
|
11
|
+
import type { CapekPlugin, EffectiveTool, PluginContext, ServiceKey } from '../kernel/types';
|
|
12
|
+
import type { ToolRegistryResolver } from '../tools/registry';
|
|
13
|
+
import { capekToolResolverKey } from './service-keys';
|
|
14
|
+
|
|
15
|
+
/** The narrow surface a contributed resolver reads: effective tools plus
|
|
16
|
+
* optional service resolution. `ScopeHandle` and `PluginContext` both
|
|
17
|
+
* satisfy it. */
|
|
18
|
+
export interface ContributedToolScope {
|
|
19
|
+
listTools(): readonly EffectiveTool[];
|
|
20
|
+
optional<T>(key: ServiceKey<T>): T | undefined;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isLoadedToolPayload(value: unknown): value is LoadedTool {
|
|
24
|
+
if (typeof value !== 'object' || value === null) return false;
|
|
25
|
+
const candidate = value as { definition?: unknown; execute?: unknown };
|
|
26
|
+
return typeof candidate.definition === 'object' && candidate.definition !== null
|
|
27
|
+
&& typeof candidate.execute === 'function';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Builds a `ToolRegistryResolver` from the scope's effective visible tool
|
|
31
|
+
* contributions carrying payloads. Hidden tools are omitted, exactly like
|
|
32
|
+
* the kernel's effective visibility decision. Order follows the
|
|
33
|
+
* deterministic kernel tool order. The payload snapshot is taken lazily on
|
|
34
|
+
* first use, so plugin activation order (the resolver plugin id may sort
|
|
35
|
+
* before payload-contributing plugins) cannot drop contributions. */
|
|
36
|
+
export function createContributedToolResolver(
|
|
37
|
+
scope: ContributedToolScope,
|
|
38
|
+
): ToolRegistryResolver {
|
|
39
|
+
let loaded: LoadedTool[] | null = null;
|
|
40
|
+
const byName = new Map<string, LoadedTool>();
|
|
41
|
+
const ensureSnapshot = (): void => {
|
|
42
|
+
if (loaded !== null) return;
|
|
43
|
+
const collected: LoadedTool[] = [];
|
|
44
|
+
for (const tool of scope.listTools()) {
|
|
45
|
+
if (!tool.visible) continue;
|
|
46
|
+
const payload = tool.payload;
|
|
47
|
+
if (isLoadedToolPayload(payload) && payload.definition.name === tool.definition.name) {
|
|
48
|
+
collected.push(payload);
|
|
49
|
+
byName.set(payload.definition.name, payload);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
loaded = collected;
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
get(name: string): LoadedTool | null {
|
|
56
|
+
ensureSnapshot();
|
|
57
|
+
return byName.get(name) ?? null;
|
|
58
|
+
},
|
|
59
|
+
list(): LoadedTool[] {
|
|
60
|
+
ensureSnapshot();
|
|
61
|
+
return [...loaded!];
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Agent plugin that provides `capek.tool-resolver` with a resolver built
|
|
67
|
+
* from this scope's effective contributed tool payloads. The resolver stays
|
|
68
|
+
* bound to the owning scope. */
|
|
69
|
+
export function contributedToolResolverPlugin(id: string): CapekPlugin<unknown> {
|
|
70
|
+
return {
|
|
71
|
+
id,
|
|
72
|
+
scope: 'agent',
|
|
73
|
+
provides: [capekToolResolverKey],
|
|
74
|
+
setup(context: PluginContext) {
|
|
75
|
+
context.provide(capekToolResolverKey, createContributedToolResolver(context));
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getHostLayout } from '../runtime/host-layout';
|
|
2
|
+
import type { CapekPlugin, PluginContext, ToolDefinition as KernelToolDefinition } from '../kernel/types';
|
|
3
|
+
import {
|
|
4
|
+
createToolOutputService,
|
|
5
|
+
retrieveToolOutputStandardTool,
|
|
6
|
+
type ToolOutputPolicyOptions,
|
|
7
|
+
} from '../tool-output/policy';
|
|
8
|
+
import { capekToolOutputPolicyKey } from './service-keys';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* C6 provider for the agent-scoped tool-output policy service
|
|
12
|
+
* (`capek.tool-output-policy`). The bounding thresholds and legacy
|
|
13
|
+
* truncation constants translate into provider options here, at
|
|
14
|
+
* composition: there is no current environment source for them, so the
|
|
15
|
+
* exact pre-C6 constants freeze into the service options (the same
|
|
16
|
+
* documented pattern as the generic ask timeout in C6 step 3). The page
|
|
17
|
+
* limits (10k default, 20k max) are mandatory storage invariants and are
|
|
18
|
+
* NOT options. The default provider reproduces the exact envelope,
|
|
19
|
+
* fallback, retrieval, wrap, and truncation behavior; the strict ID
|
|
20
|
+
* validation and session-scoped retrieval invariants stay in the storage
|
|
21
|
+
* layer.
|
|
22
|
+
*/
|
|
23
|
+
export function toolOutputPolicyPlugin(id: string, tempRoot?: string): CapekPlugin<unknown> {
|
|
24
|
+
return {
|
|
25
|
+
id,
|
|
26
|
+
scope: 'agent',
|
|
27
|
+
provides: [capekToolOutputPolicyKey],
|
|
28
|
+
setup(context: PluginContext) {
|
|
29
|
+
const options: ToolOutputPolicyOptions = {
|
|
30
|
+
thresholdChars: 50_000,
|
|
31
|
+
previewChars: 10_000,
|
|
32
|
+
retrievalToolName: 'retrieve-tool-output',
|
|
33
|
+
truncationMaxChars: 50_000,
|
|
34
|
+
truncationPreviewChars: 10_000,
|
|
35
|
+
truncationTempDir: tempRoot ?? getHostLayout().toolOutputTempRoot(),
|
|
36
|
+
};
|
|
37
|
+
context.provide(
|
|
38
|
+
capekToolOutputPolicyKey,
|
|
39
|
+
createToolOutputService({ id, options }),
|
|
40
|
+
);
|
|
41
|
+
// The retrieval tool is the tool-output capability's own contribution:
|
|
42
|
+
// it enters the effective catalog through the service it depends on.
|
|
43
|
+
context.contributeTool({
|
|
44
|
+
id: 'tool-output.retrieve-tool-output',
|
|
45
|
+
order: 600,
|
|
46
|
+
definition: retrieveToolOutputStandardTool.definition as KernelToolDefinition,
|
|
47
|
+
payload: retrieveToolOutputStandardTool,
|
|
48
|
+
requiredCapabilities: [capekToolOutputPolicyKey],
|
|
49
|
+
});
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Value-bound provider plugin factories. Each factory produces one plugin
|
|
3
|
+
* that provides one C2 service key with the exact supplied value; the plugin
|
|
4
|
+
* declares the key in `provides` so kernel validation and diagnostics see the
|
|
5
|
+
* real ownership. Plugins carry no disposable resources: disposal never
|
|
6
|
+
* closes storage, controllers, or hosts.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { CapekPlugin, ServiceKey } from '../kernel/types';
|
|
10
|
+
import type { RuntimeConfiguration } from '../configuration/contracts';
|
|
11
|
+
import type { ContextSources } from '../context/sources';
|
|
12
|
+
import {
|
|
13
|
+
connectProvider,
|
|
14
|
+
createModelForProvider,
|
|
15
|
+
disconnectProvider,
|
|
16
|
+
getConnectableProviders,
|
|
17
|
+
getProvider,
|
|
18
|
+
getProviderStatus,
|
|
19
|
+
registerProvider,
|
|
20
|
+
} from '../providers/registry';
|
|
21
|
+
import type { ConnectableProvider } from '../providers/types';
|
|
22
|
+
import type { RuntimeHost } from '../runtime/host';
|
|
23
|
+
import type { SandboxController } from '../sandbox/controller';
|
|
24
|
+
import type { SchedulerHost } from '../scheduler/host';
|
|
25
|
+
import type { SessionSearchHost } from '../session-search/host';
|
|
26
|
+
import type { StorageBundle } from '../storage/contracts';
|
|
27
|
+
import {
|
|
28
|
+
clearCache,
|
|
29
|
+
configureToolsPath,
|
|
30
|
+
getTool,
|
|
31
|
+
listTools,
|
|
32
|
+
scanTools,
|
|
33
|
+
stopWatching,
|
|
34
|
+
watchTools,
|
|
35
|
+
type ToolRegistryResolver,
|
|
36
|
+
} from '../tools/registry';
|
|
37
|
+
import type { WorkspaceToolDiscovery } from '../tools/tool-source';
|
|
38
|
+
import {
|
|
39
|
+
capekContextSourcesKey,
|
|
40
|
+
capekInstalledToolRegistryKey,
|
|
41
|
+
capekProviderOverridesKey,
|
|
42
|
+
capekProviderRegistryKey,
|
|
43
|
+
capekRuntimeConfigurationKey,
|
|
44
|
+
capekRuntimeHostKey,
|
|
45
|
+
capekSandboxControllerKey,
|
|
46
|
+
capekSchedulerHostKey,
|
|
47
|
+
capekSessionSearchHostKey,
|
|
48
|
+
capekStorageKey,
|
|
49
|
+
capekToolResolverKey,
|
|
50
|
+
capekWorkspaceToolDiscoveryKey,
|
|
51
|
+
type InstalledToolRegistryContract,
|
|
52
|
+
type ProviderRegistryContract,
|
|
53
|
+
} from './service-keys';
|
|
54
|
+
|
|
55
|
+
function valuePlugin<T>(id: string, key: ServiceKey<T>, value: T): CapekPlugin<unknown> {
|
|
56
|
+
return {
|
|
57
|
+
id,
|
|
58
|
+
scope: key.scope,
|
|
59
|
+
provides: [key],
|
|
60
|
+
setup(context) {
|
|
61
|
+
context.provide(key, value);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function storageValuePlugin(id: string, storage: StorageBundle): CapekPlugin<unknown> {
|
|
67
|
+
return valuePlugin(id, capekStorageKey, storage);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function runtimeConfigurationValuePlugin(
|
|
71
|
+
id: string,
|
|
72
|
+
configuration: RuntimeConfiguration,
|
|
73
|
+
): CapekPlugin<unknown> {
|
|
74
|
+
return valuePlugin(id, capekRuntimeConfigurationKey, configuration);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function runtimeHostValuePlugin(id: string, host: RuntimeHost): CapekPlugin<unknown> {
|
|
78
|
+
return valuePlugin(id, capekRuntimeHostKey, host);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function contextSourcesValuePlugin(
|
|
82
|
+
id: string,
|
|
83
|
+
sources: Partial<ContextSources>,
|
|
84
|
+
): CapekPlugin<unknown> {
|
|
85
|
+
return valuePlugin(id, capekContextSourcesKey, sources);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function workspaceToolDiscoveryValuePlugin(
|
|
89
|
+
id: string,
|
|
90
|
+
discovery: WorkspaceToolDiscovery,
|
|
91
|
+
): CapekPlugin<unknown> {
|
|
92
|
+
return valuePlugin(id, capekWorkspaceToolDiscoveryKey, discovery);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function toolResolverValuePlugin(id: string, resolver: ToolRegistryResolver): CapekPlugin<unknown> {
|
|
96
|
+
return valuePlugin(id, capekToolResolverKey, resolver);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function sandboxControllerValuePlugin(
|
|
100
|
+
id: string,
|
|
101
|
+
controller: SandboxController,
|
|
102
|
+
): CapekPlugin<unknown> {
|
|
103
|
+
return valuePlugin(id, capekSandboxControllerKey, controller);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function providerOverridesValuePlugin(
|
|
107
|
+
id: string,
|
|
108
|
+
overrides: ReadonlyMap<string, ConnectableProvider>,
|
|
109
|
+
): CapekPlugin<unknown> {
|
|
110
|
+
return valuePlugin(id, capekProviderOverridesKey, overrides);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Process-scope registry provider. Delegates to the current module
|
|
114
|
+
* functions, which read the seeded per-agent overrides exactly like the
|
|
115
|
+
* runtime does today. */
|
|
116
|
+
export function providerRegistryValuePlugin(id: string): CapekPlugin<unknown> {
|
|
117
|
+
const registry: ProviderRegistryContract = {
|
|
118
|
+
registerProvider,
|
|
119
|
+
getProvider,
|
|
120
|
+
getConnectableProviders,
|
|
121
|
+
getProviderStatus,
|
|
122
|
+
connectProvider,
|
|
123
|
+
disconnectProvider,
|
|
124
|
+
createModelForProvider,
|
|
125
|
+
};
|
|
126
|
+
return valuePlugin(id, capekProviderRegistryKey, registry);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Process-scope installed tool registry provider. Delegates to the current
|
|
130
|
+
* module functions, which read the seeded resolver first. */
|
|
131
|
+
export function installedToolRegistryValuePlugin(id: string): CapekPlugin<unknown> {
|
|
132
|
+
const registry: InstalledToolRegistryContract = {
|
|
133
|
+
getTool,
|
|
134
|
+
listTools,
|
|
135
|
+
scanTools,
|
|
136
|
+
watchTools,
|
|
137
|
+
stopWatching,
|
|
138
|
+
clearCache,
|
|
139
|
+
configureToolsPath,
|
|
140
|
+
};
|
|
141
|
+
return valuePlugin(id, capekInstalledToolRegistryKey, registry);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function sessionSearchHostValuePlugin(id: string, host: SessionSearchHost): CapekPlugin<unknown> {
|
|
145
|
+
return valuePlugin(id, capekSessionSearchHostKey, host);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function schedulerHostValuePlugin(id: string, host: SchedulerHost): CapekPlugin<unknown> {
|
|
149
|
+
return valuePlugin(id, capekSchedulerHostKey, host);
|
|
150
|
+
}
|