@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.
Files changed (148) hide show
  1. package/README.md +12 -0
  2. package/package.json +105 -0
  3. package/src/adapters/ai-sdk.ts +84 -0
  4. package/src/compaction/contracts.ts +82 -0
  5. package/src/compaction/executor.ts +161 -0
  6. package/src/compaction/policy.ts +318 -0
  7. package/src/compaction/recovery.ts +139 -0
  8. package/src/compaction/task.ts +540 -0
  9. package/src/configuration/contracts.ts +58 -0
  10. package/src/configuration/defaults.ts +27 -0
  11. package/src/configuration/runtime.ts +42 -0
  12. package/src/configuration/single-model.ts +75 -0
  13. package/src/context/assembler.ts +112 -0
  14. package/src/context/index.ts +2 -0
  15. package/src/context/sources.ts +119 -0
  16. package/src/context/workspace.ts +63 -0
  17. package/src/core/agent.ts +401 -0
  18. package/src/core/build-tools.ts +139 -0
  19. package/src/core/chat-handler.ts +858 -0
  20. package/src/core/error-handling.ts +18 -0
  21. package/src/core/fork.ts +103 -0
  22. package/src/core/interrupt.ts +192 -0
  23. package/src/core/message-utils.ts +261 -0
  24. package/src/core/model-utils.ts +149 -0
  25. package/src/core/part-utils.ts +88 -0
  26. package/src/core/provider-utils.ts +67 -0
  27. package/src/core/revert.ts +46 -0
  28. package/src/core/step-handlers.ts +157 -0
  29. package/src/core/stream/finalization.ts +65 -0
  30. package/src/core/stream/stream-config.ts +82 -0
  31. package/src/core/stream-handlers.ts +242 -0
  32. package/src/core/structured-output.ts +68 -0
  33. package/src/core/tool-builders/agent-tools.ts +71 -0
  34. package/src/core/tool-builders/external-tools.ts +179 -0
  35. package/src/core/tool-builders/types.ts +16 -0
  36. package/src/core/tool-builders/workspace-tools.ts +293 -0
  37. package/src/core/tool-capabilities.ts +65 -0
  38. package/src/goals/evaluator.ts +171 -0
  39. package/src/goals/index.ts +3 -0
  40. package/src/goals/loop.ts +167 -0
  41. package/src/goals/service.ts +39 -0
  42. package/src/index.ts +10 -0
  43. package/src/internal/ask-authority.ts +29 -0
  44. package/src/internal/composition.ts +44 -0
  45. package/src/internal/configuration.ts +22 -0
  46. package/src/internal/execution.ts +108 -0
  47. package/src/internal/hosts.ts +64 -0
  48. package/src/internal/plugins.ts +71 -0
  49. package/src/internal/providers.ts +32 -0
  50. package/src/internal/sandbox.ts +19 -0
  51. package/src/internal/tools.ts +48 -0
  52. package/src/internal/workspace.ts +25 -0
  53. package/src/kernel/diagnostics.ts +249 -0
  54. package/src/kernel/errors.ts +120 -0
  55. package/src/kernel/events.ts +82 -0
  56. package/src/kernel/index.ts +72 -0
  57. package/src/kernel/kernel.ts +62 -0
  58. package/src/kernel/lifecycle.ts +72 -0
  59. package/src/kernel/plugin.ts +218 -0
  60. package/src/kernel/registry.ts +493 -0
  61. package/src/kernel/scope.ts +776 -0
  62. package/src/kernel/service-key.ts +19 -0
  63. package/src/kernel/types.ts +317 -0
  64. package/src/memory/index.ts +2 -0
  65. package/src/memory/memory-tool.ts +75 -0
  66. package/src/memory/registry.ts +172 -0
  67. package/src/permission/ask-user-api.ts +70 -0
  68. package/src/permission/contracts.ts +135 -0
  69. package/src/permission/permission-request-manager.ts +58 -0
  70. package/src/permission/policy.ts +277 -0
  71. package/src/permission/runtime.ts +612 -0
  72. package/src/plugins/compaction-policy.ts +46 -0
  73. package/src/plugins/compose.ts +171 -0
  74. package/src/plugins/context-sections.ts +246 -0
  75. package/src/plugins/default-agent-driver.ts +14 -0
  76. package/src/plugins/facade-plugins.ts +129 -0
  77. package/src/plugins/goal-domain.ts +82 -0
  78. package/src/plugins/legacy-system-message.ts +152 -0
  79. package/src/plugins/loaded-tools.ts +23 -0
  80. package/src/plugins/memory-domain.ts +264 -0
  81. package/src/plugins/orchestrator-session.ts +29 -0
  82. package/src/plugins/permission-policy.ts +49 -0
  83. package/src/plugins/retry-policy.ts +28 -0
  84. package/src/plugins/scheduler-domain.ts +192 -0
  85. package/src/plugins/service-keys.ts +294 -0
  86. package/src/plugins/session-search-domain.ts +238 -0
  87. package/src/plugins/skills-domain.ts +272 -0
  88. package/src/plugins/subagent-domain.ts +287 -0
  89. package/src/plugins/tool-catalog.ts +78 -0
  90. package/src/plugins/tool-output-policy.ts +52 -0
  91. package/src/plugins/value-plugins.ts +150 -0
  92. package/src/plugins/workflow-domain.ts +198 -0
  93. package/src/plugins/workspace-policy.ts +37 -0
  94. package/src/providers/registry.ts +63 -0
  95. package/src/providers/types.ts +44 -0
  96. package/src/retry/policy.ts +282 -0
  97. package/src/retry/stream-chat.ts +312 -0
  98. package/src/runtime/agent-runtime.ts +83 -0
  99. package/src/runtime/default-agent-driver.ts +23 -0
  100. package/src/runtime/domain-tool-source.ts +156 -0
  101. package/src/runtime/events.ts +61 -0
  102. package/src/runtime/host-dependencies.ts +71 -0
  103. package/src/runtime/host-guidance.ts +22 -0
  104. package/src/runtime/host-layout.ts +23 -0
  105. package/src/runtime/host.ts +129 -0
  106. package/src/runtime/standalone-host.ts +118 -0
  107. package/src/sandbox/controller.ts +204 -0
  108. package/src/sandbox/model.ts +305 -0
  109. package/src/sandbox/provider.ts +53 -0
  110. package/src/sandbox/types.ts +110 -0
  111. package/src/scheduler/host.ts +22 -0
  112. package/src/scheduler/scheduler-tool.ts +172 -0
  113. package/src/session-search/host.ts +56 -0
  114. package/src/session-search/index.ts +23 -0
  115. package/src/session-search/session-search-tool.ts +151 -0
  116. package/src/skills/index.ts +3 -0
  117. package/src/skills/registry.ts +63 -0
  118. package/src/skills/skill-manage-tool.ts +205 -0
  119. package/src/skills/skill-tool.ts +42 -0
  120. package/src/storage/contracts.ts +159 -0
  121. package/src/storage/memory.ts +321 -0
  122. package/src/storage/options.ts +75 -0
  123. package/src/storage/runtime.ts +115 -0
  124. package/src/storage/sqlite-tool-output-artifacts.ts +106 -0
  125. package/src/storage/sqlite.ts +321 -0
  126. package/src/storage/tool-output-artifacts.ts +75 -0
  127. package/src/storage.ts +31 -0
  128. package/src/subagent/child-session.ts +282 -0
  129. package/src/subagent/guidance.ts +8 -0
  130. package/src/subagent/policy.ts +198 -0
  131. package/src/subagent/task-tool.ts +584 -0
  132. package/src/tool-output/contracts.ts +111 -0
  133. package/src/tool-output/policy.ts +410 -0
  134. package/src/tool.ts +1 -0
  135. package/src/tools/executor.ts +258 -0
  136. package/src/tools/install-manifest.ts +40 -0
  137. package/src/tools/llm-api.ts +77 -0
  138. package/src/tools/registry.ts +206 -0
  139. package/src/tools/tool-artifact.ts +182 -0
  140. package/src/tools/tool-source.ts +53 -0
  141. package/src/utils/errors.ts +334 -0
  142. package/src/utils/strip-visualization.ts +50 -0
  143. package/src/workflow/decomposer.ts +139 -0
  144. package/src/workflow/execution.ts +523 -0
  145. package/src/workflow/orchestrator-session.ts +161 -0
  146. package/src/workflow/synthesizer.ts +130 -0
  147. package/src/workspace/contracts.ts +135 -0
  148. package/src/workspace/policy.ts +327 -0
@@ -0,0 +1,192 @@
1
+ import type { PermissionRiskLevel } from '@capekai/tool'
2
+ import type { Session, WorkspaceSchedulingSettings } from '@capekai/types';
3
+ import { serviceKey } from '../kernel/service-key';
4
+ import type {
5
+ CapekPlugin,
6
+ PluginContext,
7
+ ToolDefinition as KernelToolDefinition,
8
+ } from '../kernel/types';
9
+ import {
10
+ DOMAIN_TOOL_PAYLOAD_FIELD,
11
+ registerDomainToolFallback,
12
+ type DomainToolExecuteContext,
13
+ type DomainToolPayload,
14
+ } from '../runtime/domain-tool-source';
15
+ import type { SchedulerHost } from '../scheduler/host';
16
+ import {
17
+ executeSchedulerTool,
18
+ executeSchedulerToolWithHost,
19
+ schedulerToolDefinition,
20
+ type SchedulerToolResult,
21
+ } from '../scheduler/scheduler-tool';
22
+ import type { StorageBundle } from '../storage/contracts';
23
+ import { getSession, getWorkspace } from '../storage/runtime';
24
+ import { capekSchedulerHostKey, capekStorageKey } from './service-keys';
25
+
26
+ /**
27
+ * C5 scheduler domain plugin. Owns the domain service (agent scope) and the
28
+ * `scheduler` tool contribution. Composed payloads execute through the
29
+ * scope-captured host; the unscoped fallback keeps the pre-C5 execute-time
30
+ * module host. No scheduler context contribution exists today.
31
+ */
32
+
33
+ export const CURRENT_SCHEDULER_DOMAIN_PLUGIN_ID = 'current.scheduler-domain';
34
+ export const SCHEDULER_TOOL_CONTRIBUTION_ID = 'scheduler.scheduler';
35
+ /** After the session-search domain contribution (700) so the effective
36
+ * contributed tool order keeps `scheduler` after `session_search`. */
37
+ export const SCHEDULER_TOOL_CONTRIBUTION_ORDER = 750;
38
+
39
+ export interface SchedulerDomainService {
40
+ readonly tools: readonly DomainToolPayload[];
41
+ /** Single availability predicate: workspace settings gate plus the
42
+ * current-session scheduled-job recursion gate, shared by the tool
43
+ * payload. */
44
+ isEnabled(workspaceId: string, sessionId?: string): boolean | Promise<boolean>;
45
+ }
46
+
47
+ export const capekSchedulerDomainKey = serviceKey<SchedulerDomainService>(
48
+ 'capek.scheduler-domain',
49
+ 'agent',
50
+ );
51
+
52
+ /** Pre-C5 gate body shared by the composed and the unscoped path: the
53
+ * workspace must enable scheduling and the current session's
54
+ * `metadata.scheduledJobId` must be falsy (Boolean coercion, no ancestry
55
+ * walk). Any ancestry or typed-string semantics are a C6 decision. */
56
+ function schedulingGate(
57
+ settings: WorkspaceSchedulingSettings | undefined,
58
+ session: Session | null | undefined,
59
+ ): boolean {
60
+ if (settings?.enabled !== true) return false;
61
+ return !session?.metadata?.scheduledJobId;
62
+ }
63
+
64
+ interface SchedulerPayloadDeps {
65
+ readonly isEnabled: (workspaceId: string, sessionId?: string) => boolean | Promise<boolean>;
66
+ readonly run: (
67
+ input: Record<string, unknown>,
68
+ context: DomainToolExecuteContext,
69
+ risk: PermissionRiskLevel,
70
+ ) => Promise<SchedulerToolResult>;
71
+ }
72
+
73
+ function shapeSchedulerResult(result: SchedulerToolResult): Record<string, unknown> {
74
+ if (!result.success) {
75
+ return { error: result.error ?? 'Scheduler operation failed' };
76
+ }
77
+ return {
78
+ action: result.action,
79
+ title: result.title,
80
+ ...(result.job && { job: result.job }),
81
+ ...(result.jobs && { jobs: result.jobs }),
82
+ ...(result.jobId && { jobId: result.jobId }),
83
+ };
84
+ }
85
+
86
+ function schedulerPayload(deps: SchedulerPayloadDeps): DomainToolPayload {
87
+ return {
88
+ name: schedulerToolDefinition.name,
89
+ description: schedulerToolDefinition.description,
90
+ inputSchema: schedulerToolDefinition.inputSchema as Readonly<Record<string, unknown>>,
91
+ display: { summary: '{action} {name}' },
92
+ isEnabled: deps.isEnabled,
93
+ visualize: (_input, result) => {
94
+ const jobs = Array.isArray(result.jobs) ? result.jobs.length : undefined;
95
+ if (jobs !== undefined) {
96
+ return {
97
+ type: 'none',
98
+ badge: `${jobs} job${jobs === 1 ? '' : 's'}`,
99
+ message: String(result.title ?? ''),
100
+ };
101
+ }
102
+ return {
103
+ type: 'none',
104
+ message: String(result.title ?? 'Scheduler action completed'),
105
+ };
106
+ },
107
+ execute: async (input, context) => {
108
+ // workspace-tools captures the settings at build time exactly like
109
+ // pre-C5 and passes the value through the execution context; the
110
+ // payload never re-reads workspace settings at execution time.
111
+ const risk = context.permissionRisk as PermissionRiskLevel;
112
+ const result = await deps.run(input, context, risk);
113
+ return shapeSchedulerResult(result);
114
+ },
115
+ };
116
+ }
117
+
118
+ /** Unscoped compatibility payload: keeps the pre-C5 execute-time module host
119
+ * and storage reads. Installed through `installSchedulerToolFallback`, never
120
+ * at module load. */
121
+ export function createSchedulerToolFallbackPayload(): DomainToolPayload {
122
+ return schedulerPayload({
123
+ isEnabled: async (workspaceId, sessionId) => schedulingGate(
124
+ (await getWorkspace(workspaceId))?.settings?.scheduling,
125
+ typeof sessionId === 'string' ? await getSession(sessionId) : null,
126
+ ),
127
+ run: (input, context, risk) => executeSchedulerTool(
128
+ input,
129
+ context.workspaceId,
130
+ context.sessionId,
131
+ risk,
132
+ context.ask,
133
+ ),
134
+ });
135
+ }
136
+
137
+ /** Explicitly installs the unscoped legacy fallback. Called by the Jean2
138
+ * compatibility bindings installation (server bootstrap) and by focused
139
+ * tests; no module-load registration exists. */
140
+ export function installSchedulerToolFallback(): void {
141
+ registerDomainToolFallback(
142
+ schedulerToolDefinition.name,
143
+ createSchedulerToolFallbackPayload(),
144
+ );
145
+ }
146
+
147
+ export function schedulerDomainPlugin(id: string): CapekPlugin<unknown> {
148
+ return {
149
+ id,
150
+ scope: 'agent',
151
+ provides: [capekSchedulerDomainKey],
152
+ requires: [capekStorageKey, capekSchedulerHostKey],
153
+ setup(context: PluginContext) {
154
+ const storage: StorageBundle = context.require(capekStorageKey);
155
+ const host: SchedulerHost = context.require(capekSchedulerHostKey);
156
+ const isEnabled = async (workspaceId: string, sessionId?: string): Promise<boolean> =>
157
+ schedulingGate(
158
+ (await storage.workspaces.get(workspaceId))?.settings?.scheduling,
159
+ typeof sessionId === 'string' ? await storage.conversation.getSession(sessionId) : null,
160
+ );
161
+ const payload = schedulerPayload({
162
+ isEnabled,
163
+ run: (input, executionContext, risk) => executeSchedulerToolWithHost(
164
+ host,
165
+ input,
166
+ executionContext.workspaceId,
167
+ executionContext.sessionId,
168
+ risk,
169
+ executionContext.ask,
170
+ ),
171
+ });
172
+ const service: SchedulerDomainService = {
173
+ tools: [payload],
174
+ isEnabled,
175
+ };
176
+
177
+ context.provide(capekSchedulerDomainKey, service);
178
+ context.contributeTool({
179
+ id: SCHEDULER_TOOL_CONTRIBUTION_ID,
180
+ order: SCHEDULER_TOOL_CONTRIBUTION_ORDER,
181
+ definition: {
182
+ name: payload.name,
183
+ description: payload.description,
184
+ inputSchema: payload.inputSchema,
185
+ timeout: schedulerToolDefinition.timeout,
186
+ [DOMAIN_TOOL_PAYLOAD_FIELD]: payload,
187
+ } as KernelToolDefinition,
188
+ requiredCapabilities: [capekSchedulerDomainKey],
189
+ });
190
+ },
191
+ };
192
+ }
@@ -0,0 +1,294 @@
1
+ /**
2
+ * C2 service keys for the current configurable seams. Each key wraps the
3
+ * existing contract without inventing a new abstraction: the contract types
4
+ * below are the current module surfaces, and the ownership record lives in
5
+ * .architecture-v2/10-current-inventory.md ("C2 provider ownership and scope
6
+ * record"). Ownership rules:
7
+ *
8
+ * - Values that differ across simultaneous facade agents are agent-scoped.
9
+ * - Values that are process-global today (registries, host-installed search
10
+ * and scheduler) are process-scoped.
11
+ * - No current seam is run-scoped; run services belong to C7.
12
+ */
13
+
14
+ import { serviceKey } from '../kernel/service-key';
15
+ import type { ProviderStatus } from '@capekai/types';
16
+ import type { LoadedTool, ToolDefinition } from '@capekai/tool';
17
+ import type { RuntimeConfiguration } from '../configuration/contracts';
18
+ import type { ContextSources } from '../context/sources';
19
+ import type { ContextAssembler } from '../context/assembler';
20
+ export type { ContextAssembler, ContextAssemblyData } from '../context/assembler';
21
+ import type { RetryPolicy } from '../retry/policy';
22
+ import type { CompactionService } from '../compaction/policy';
23
+ import type { AskPermissionPolicyService } from '../permission/contracts';
24
+ import type { PermissionRuntimeService } from '../permission/contracts';
25
+ import type { WorkspaceService } from '../workspace/contracts';
26
+ import type { ToolOutputArtifactService } from '../tool-output/contracts';
27
+ import type { ConnectableProvider, ConnectOptions, ConnectResult, ModelFactoryOptions, ModelFactoryResult } from '../providers/types';
28
+ import type { BroadcastFn, BroadcastSessionFn, RuntimeHost } from '../runtime/host';
29
+ import type { SandboxController } from '../sandbox/controller';
30
+ import type { SchedulerHost } from '../scheduler/host';
31
+ import type { SessionSearchHost } from '../session-search/host';
32
+ import type { StorageBundle } from '../storage/contracts';
33
+ import type { ToolRegistryResolver } from '../tools/registry';
34
+ import type { WorkspaceToolDiscovery } from '../tools/tool-source';
35
+ import type { AgentDriver } from '../runtime/agent-runtime';
36
+ import type { DefaultDriverInput } from '../runtime/default-agent-driver';
37
+
38
+ /** Current `providers/registry.ts` surface. `createModelForProvider` is the
39
+ * model factory seam; a separate model-service contract is a C7 concern. */
40
+ export interface ProviderRegistryContract {
41
+ registerProvider(provider: ConnectableProvider): void;
42
+ getProvider(id: string): ConnectableProvider | undefined;
43
+ getConnectableProviders(): ConnectableProvider[];
44
+ getProviderStatus(id: string): ProviderStatus;
45
+ connectProvider(id: string, options?: ConnectOptions): Promise<ConnectResult>;
46
+ disconnectProvider(id: string): Promise<void>;
47
+ createModelForProvider(options: ModelFactoryOptions): Promise<ModelFactoryResult>;
48
+ }
49
+
50
+ /** Current `tools/registry.ts` surface. `getTool` and `listTools` read the
51
+ * seeded resolver first, exactly like the module functions they delegate to. */
52
+ export interface InstalledToolRegistryContract {
53
+ getTool(name: string): Promise<LoadedTool | null>;
54
+ listTools(): Promise<ToolDefinition[]>;
55
+ scanTools(toolsPath?: string | null): Promise<LoadedTool[]>;
56
+ watchTools(toolsPath?: string | null): void;
57
+ stopWatching(): void;
58
+ clearCache(): void;
59
+ configureToolsPath(path?: string): void;
60
+ }
61
+
62
+ // Process scope: process-global registries and hosts.
63
+
64
+ export const capekProviderRegistryKey = serviceKey<ProviderRegistryContract>(
65
+ 'capek.provider-registry',
66
+ 'process',
67
+ );
68
+
69
+ export const capekInstalledToolRegistryKey = serviceKey<InstalledToolRegistryContract>(
70
+ 'capek.installed-tool-registry',
71
+ 'process',
72
+ );
73
+
74
+ export const capekSessionSearchHostKey = serviceKey<SessionSearchHost>(
75
+ 'capek.session-search-host',
76
+ 'process',
77
+ );
78
+
79
+ export const capekSchedulerHostKey = serviceKey<SchedulerHost>(
80
+ 'capek.scheduler-host',
81
+ 'process',
82
+ );
83
+
84
+ // Agent scope: per-agent values. A facade agent and a host agent must be able
85
+ // to run simultaneously with different values, so none of these may be
86
+ // process-scoped.
87
+
88
+ export const capekStorageKey = serviceKey<StorageBundle>('capek.storage', 'agent');
89
+
90
+ export const capekRuntimeConfigurationKey = serviceKey<RuntimeConfiguration>(
91
+ 'capek.runtime-configuration',
92
+ 'agent',
93
+ );
94
+
95
+ export const capekRuntimeHostKey = serviceKey<RuntimeHost>('capek.runtime-host', 'agent');
96
+
97
+ /** The facade passes `{}` (module defaults) exactly as today; the current
98
+ * composition passes the full active source set. */
99
+ export const capekContextSourcesKey = serviceKey<Partial<ContextSources>>(
100
+ 'capek.context-sources',
101
+ 'agent',
102
+ );
103
+
104
+ export const capekWorkspaceToolDiscoveryKey = serviceKey<WorkspaceToolDiscovery>(
105
+ 'capek.workspace-tool-discovery',
106
+ 'agent',
107
+ );
108
+
109
+ /** Optional by design: only the facade composition provides it. The current
110
+ * composition omits it so installed-tool cache resolution runs unchanged. */
111
+ export const capekToolResolverKey = serviceKey<ToolRegistryResolver>(
112
+ 'capek.tool-resolver',
113
+ 'agent',
114
+ );
115
+
116
+ export const capekSandboxControllerKey = serviceKey<SandboxController>(
117
+ 'capek.sandbox-controller',
118
+ 'agent',
119
+ );
120
+
121
+ /** Seeding an empty map is behaviorally identical to today's unseeded host
122
+ * path: both fall through to the process-wide provider registry. */
123
+ export const capekProviderOverridesKey = serviceKey<ReadonlyMap<string, ConnectableProvider>>(
124
+ 'capek.provider-overrides',
125
+ 'agent',
126
+ );
127
+
128
+ /** Ordered context assembly is a required agent service in C3. The facade and
129
+ * current compositions both provide it through their context-sections plugin;
130
+ * the runtime core resolves it through `getContextAssembler()`. */
131
+ export const capekContextAssemblerKey = serviceKey<ContextAssembler>(
132
+ 'capek.context-assembler',
133
+ 'agent',
134
+ );
135
+
136
+ export const capekAgentDriverKey = serviceKey<AgentDriver<DefaultDriverInput<unknown>, unknown>>(
137
+ 'capek.agent-driver',
138
+ 'agent',
139
+ );
140
+
141
+ /**
142
+ * C5 shared optional-domain model-turn service contract. The workflow and
143
+ * goals slices both run short visible model turns (decomposer, synthesizer,
144
+ * goal evaluator) through this contract; the workflow slice named it and
145
+ * `plugins/orchestrator-session.ts` provides the current implementation
146
+ * (`workflow/orchestrator-session.ts`), so the goals slice consumes the
147
+ * same service without owning workflow code.
148
+ */
149
+ export interface OrchestratorSessionContractOptions {
150
+ parentSessionId: string;
151
+ title: string;
152
+ agentName: string;
153
+ systemPrompt: string;
154
+ userPrompt: string;
155
+ maxTokens?: number;
156
+ abortSignal?: AbortSignal;
157
+ broadcast?: BroadcastFn;
158
+ broadcastSessionCreated?: BroadcastSessionFn;
159
+ broadcastSessionUpdated?: BroadcastSessionFn;
160
+ }
161
+
162
+ export interface OrchestratorSessionContractResult {
163
+ text: string;
164
+ json: Record<string, unknown> | null;
165
+ sessionId: string;
166
+ }
167
+
168
+ export interface OrchestratorSessionContract {
169
+ run(options: OrchestratorSessionContractOptions): Promise<OrchestratorSessionContractResult>;
170
+ }
171
+
172
+ export const capekOrchestratorSessionKey = serviceKey<OrchestratorSessionContract>(
173
+ 'capek.orchestrator-session',
174
+ 'agent',
175
+ );
176
+
177
+ /**
178
+ * C6 retry policy service. Agent-scoped because circuit state must be
179
+ * isolated per composed agent: two facade agents must never share circuit
180
+ * failures. The contract and default provider live in `retry/policy.ts`;
181
+ * the stream loop resolves the active policy through `getRetryPolicy()`.
182
+ * Unscoped consumers keep the process-default fallback.
183
+ */
184
+ export const capekRetryPolicyKey = serviceKey<RetryPolicy>(
185
+ 'capek.retry-policy',
186
+ 'agent',
187
+ );
188
+
189
+ /**
190
+ * C6 compaction service. Agent-scoped because policy options are translated
191
+ * from the composed runtime configuration at composition time, and the
192
+ * failure cooldown plus the concurrency guard must be isolated per composed
193
+ * agent. The contract and default provider live in `compaction/policy.ts`;
194
+ * the executor and chat handler resolve the active service through
195
+ * `getCompactionService()`. Unscoped consumers keep the process-default
196
+ * fallback with live configuration reads.
197
+ */
198
+ export const capekCompactionServiceKey = serviceKey<CompactionService>(
199
+ 'capek.compaction-service',
200
+ 'agent',
201
+ );
202
+
203
+ /**
204
+ * C6 permission policy service. Agent-scoped because pending asks, waiters,
205
+ * timers, and the frozen timeout options must be isolated per composed
206
+ * agent. The contract and default provider live in `permission/`;
207
+ * `tools/ask-user-api.ts` and `tools/permission-request-manager.ts` are the
208
+ * pinned compatibility forwarders. Unscoped consumers keep the
209
+ * process-default fallback with live timeout reads.
210
+ */
211
+ export const capekPermissionPolicyKey = serviceKey<AskPermissionPolicyService>(
212
+ 'capek.permission-policy',
213
+ 'agent',
214
+ );
215
+
216
+ /**
217
+ * C6 permission runtime service. Agent-scoped because the pending-ask and
218
+ * waiter registries plus their timers must be isolated per composed agent.
219
+ * NON-REPLACEABLE: the runtime owns request-id routing, validation
220
+ * enforcement, raw-audit denial, and canonical grant construction; the
221
+ * replaceable `capek.permission-policy` advice provider sits behind it.
222
+ */
223
+ export const capekPermissionRuntimeKey = serviceKey<PermissionRuntimeService>(
224
+ 'capek.permission-runtime',
225
+ 'agent',
226
+ );
227
+
228
+ /**
229
+ * C6 workspace policy service. Agent-scoped because the frozen path inputs
230
+ * (blocked paths, sensitive patterns, home directory) belong to the
231
+ * composed profile. The contract and default provider live in `workspace/`;
232
+ * `tools/workspace-capability.ts` is the pinned compatibility forwarder and
233
+ * the Jean2 server fulfills the inward-facing workspace path port through
234
+ * the compat barrel. Unscoped consumers keep the process-default fallback.
235
+ */
236
+ export const capekWorkspacePolicyKey = serviceKey<WorkspaceService>(
237
+ 'capek.workspace-policy',
238
+ 'agent',
239
+ );
240
+
241
+ /**
242
+ * C6 tool-output policy service. Agent-scoped because the frozen bounding
243
+ * and truncation thresholds plus the wrap WeakSet belong to the composed
244
+ * profile. The contract and default provider live in `tool-output/`;
245
+ * `tools/tool-output-artifacts.ts` and `utils/truncate-tool-result.ts` are
246
+ * the pinned compatibility forwarders. Unscoped consumers keep the
247
+ * process-default fallback.
248
+ */
249
+ export const capekToolOutputPolicyKey = serviceKey<ToolOutputArtifactService>(
250
+ 'capek.tool-output-policy',
251
+ 'agent',
252
+ );
253
+
254
+ /** Every required service key in the C2 inventory. */
255
+ export const C2_SERVICE_KEYS = [
256
+ capekStorageKey,
257
+ capekRuntimeConfigurationKey,
258
+ capekRuntimeHostKey,
259
+ capekContextSourcesKey,
260
+ capekWorkspaceToolDiscoveryKey,
261
+ capekToolResolverKey,
262
+ capekSandboxControllerKey,
263
+ capekProviderOverridesKey,
264
+ capekContextAssemblerKey,
265
+ capekProviderRegistryKey,
266
+ capekInstalledToolRegistryKey,
267
+ capekSessionSearchHostKey,
268
+ capekSchedulerHostKey,
269
+ ] as const;
270
+
271
+ /** Keys a composed agent scope must resolve before seeding accessors. */
272
+ export const C2_REQUIRED_AGENT_KEYS = [
273
+ capekStorageKey,
274
+ capekRuntimeConfigurationKey,
275
+ capekRuntimeHostKey,
276
+ capekContextSourcesKey,
277
+ capekWorkspaceToolDiscoveryKey,
278
+ capekSandboxControllerKey,
279
+ capekProviderOverridesKey,
280
+ capekContextAssemblerKey,
281
+ capekRetryPolicyKey,
282
+ capekCompactionServiceKey,
283
+ capekPermissionPolicyKey,
284
+ capekPermissionRuntimeKey,
285
+ capekWorkspacePolicyKey,
286
+ capekToolOutputPolicyKey,
287
+ ] as const;
288
+
289
+ export const C2_PROCESS_KEYS = [
290
+ capekProviderRegistryKey,
291
+ capekInstalledToolRegistryKey,
292
+ capekSessionSearchHostKey,
293
+ capekSchedulerHostKey,
294
+ ] as const;