@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,152 @@
1
+ import type { Preconfig } from '@capekai/types';
2
+ import { loadMemoryInstructions } from '../memory';
3
+ import { selfDelegationGuidance } from '../subagent/guidance';
4
+ import {
5
+ buildWorkspaceSystemPrompt,
6
+ formatInstructions,
7
+ getAgentDirectory,
8
+ loadInstructions,
9
+ readAgentMemoryFile,
10
+ } from '../context';
11
+ import { getWorkspace } from '../storage/runtime';
12
+ import { getHostGuidance } from '../runtime/host-guidance';
13
+ import { getHostLayout } from '../runtime/host-layout';
14
+ import {
15
+ validateContextAssemblyData,
16
+ type ContextAssembler,
17
+ type ContextAssemblyData,
18
+ } from '../context/assembler';
19
+ import type { ContextSectionContribution } from '../kernel/types';
20
+
21
+ /**
22
+ * Fixed system-message builder, byte-frozen as the C3 legacy adapter.
23
+ *
24
+ * C3 replaced this builder with ordered context contributions, but the fixed
25
+ * implementation stays available through `internal/execution` for migration
26
+ * and serves as the reference against which ordered assembly is verified
27
+ * byte-for-byte. The section guidance constants below are shared with the
28
+ * ordered contributions so both paths emit identical bytes.
29
+ */
30
+
31
+ export interface SystemMessageOptions {
32
+ preconfig: Preconfig;
33
+ workspacePath?: string;
34
+ workspaceId?: string;
35
+ additionalPaths?: string[];
36
+ selfDelegationAvailable?: boolean;
37
+ }
38
+
39
+ /** The fixed builder behind the ContextAssembler contract. Installed as the
40
+ * default assembler so consumers that run outside a composed agent scope
41
+ * (the current Jean2 server path) keep the exact pre-C3 behavior until they
42
+ * adopt the ordered composition. */
43
+ export const fixedBuilderContextAssembler: ContextAssembler = {
44
+ id: 'fixed-legacy-adapter',
45
+ build: (data) => buildSystemMessage(data),
46
+ };
47
+
48
+ /** The legacy session-search guidance contribution, kept for facade and
49
+ * legacy compositions that reproduce the fixed builder byte-for-byte. The
50
+ * C5 domain plugin owns this section in the current Jean2 composition;
51
+ * `createContextSectionsPlugin` includes it only when its
52
+ * `includeSessionSearchGuidance` option stays at the legacy default. */
53
+ export const legacySessionSearchGuidanceSection: ContextSectionContribution<ContextAssemblyData> = {
54
+ id: 'session-search-guidance',
55
+ phase: 'workspace',
56
+ order: 50,
57
+ provide: async (context) => {
58
+ const data = validateContextAssemblyData(context.data);
59
+ if (!data.workspaceId) return null;
60
+ return (await getWorkspace(data.workspaceId))?.settings?.sessionSearch?.enabled
61
+ ? getHostGuidance().sessionSearch
62
+ : null;
63
+ },
64
+ };
65
+
66
+ export const AGENT_MEMORY_SKILLS_GUIDANCE = `You have personal memory and skills that travel with you across all workspaces.
67
+
68
+ MEMORY:
69
+ - Use "memory" (workspace) for facts about THIS project (repo conventions, build commands, project-specific patterns).
70
+ - Use "agent_memory" (personal) for cross-project knowledge: reusable patterns, techniques, pitfalls, and user preferences that apply everywhere.
71
+ - Save to agent_memory when: you complete a complex multi-step task, the user corrects your approach, you discover a pattern useful beyond this project, or you debug through errors.
72
+
73
+ SKILLS:
74
+ - Use "skill_manage" for procedures specific to THIS workspace.
75
+ - Use "agent_skill_manage" for personal workflows you've refined across projects.
76
+
77
+ Before saving, use list to check existing entries and avoid duplicates.`;
78
+
79
+ /** The legacy self-delegation guidance contribution, kept for facade and
80
+ * legacy compositions that reproduce the fixed builder byte-for-byte. The
81
+ * C5 subagent domain plugin owns this section in the current Jean2 and
82
+ * facade compositions; `createContextSectionsPlugin` includes it only when
83
+ * its `includeSelfDelegationGuidance` option stays at the legacy default. */
84
+ export const legacySelfDelegationGuidanceSection: ContextSectionContribution<ContextAssemblyData> = {
85
+ id: 'self-delegation',
86
+ phase: 'identity',
87
+ order: 50,
88
+ provide: (context) => {
89
+ const data = validateContextAssemblyData(context.data);
90
+ return data.selfDelegationAvailable ? selfDelegationGuidance(data.preconfig.id) : null;
91
+ },
92
+ };
93
+
94
+ export async function buildSystemMessage(options: SystemMessageOptions): Promise<string> {
95
+ const { preconfig, workspacePath, workspaceId, additionalPaths } = options;
96
+
97
+ let systemMessage = preconfig.systemPrompt || '';
98
+
99
+ // Inject agent memory layers if this is an agent
100
+ const agentDir = await getAgentDirectory(preconfig.id);
101
+ if (agentDir) {
102
+ const agentUserMemory = await readAgentMemoryFile(preconfig.id, 'USER.md');
103
+ if (agentUserMemory) {
104
+ systemMessage = `<agent_user_preferences>\n${agentUserMemory}\n</agent_user_preferences>\n\n` + systemMessage;
105
+ }
106
+ const agentMemory = await readAgentMemoryFile(preconfig.id, 'MEMORY.md');
107
+ if (agentMemory) {
108
+ systemMessage = `<agent_memory>\n${agentMemory}\n</agent_memory>\n\n` + systemMessage;
109
+ }
110
+
111
+ systemMessage = systemMessage + '\n\n' + getHostGuidance().agentMemorySkills;
112
+ }
113
+
114
+ if (options.selfDelegationAvailable) {
115
+ systemMessage = systemMessage + '\n\n' + selfDelegationGuidance(preconfig.id);
116
+ }
117
+
118
+ // Add instructions (global first, then project)
119
+ const instructions = await loadInstructions(workspacePath);
120
+ const instructionsSection = formatInstructions(instructions);
121
+ if (instructionsSection) {
122
+ systemMessage = systemMessage + '\n\n' + instructionsSection;
123
+ }
124
+
125
+ // Add workspace context
126
+ if (workspacePath) {
127
+ const workspaceContext = buildWorkspaceSystemPrompt(workspacePath, additionalPaths);
128
+ systemMessage = systemMessage + '\n\n' + workspaceContext;
129
+ }
130
+
131
+ // Add workspace-gated guidance sections
132
+ if (workspaceId) {
133
+ const workspace = await getWorkspace(workspaceId);
134
+ if (workspace?.settings?.memory?.enabled && workspacePath) {
135
+ const memorySection = await loadMemoryInstructions(getHostLayout().workspaceMemoryDir(workspacePath));
136
+ if (memorySection) {
137
+ systemMessage = systemMessage + '\n\n' + memorySection;
138
+ }
139
+ systemMessage = systemMessage + '\n\n' + getHostGuidance().memory;
140
+ }
141
+
142
+ if (workspace?.settings?.skills?.managementEnabled) {
143
+ systemMessage = systemMessage + '\n\n' + getHostGuidance().skillManage;
144
+ }
145
+
146
+ if (workspace?.settings?.sessionSearch?.enabled) {
147
+ systemMessage = systemMessage + '\n\n' + getHostGuidance().sessionSearch;
148
+ }
149
+ }
150
+
151
+ return systemMessage;
152
+ }
@@ -0,0 +1,23 @@
1
+ import type { LoadedTool } from '@capekai/tool';
2
+ import type { CapekPlugin, ToolDefinition } from '../kernel/types';
3
+
4
+ /** One agent plugin contributing the given loaded tools as visible tool
5
+ * contributions carrying their execution payloads, in array order. This is
6
+ * the plugin behind the former `createAgent({ tools })` option; compose it
7
+ * directly into your agent scope's plugin list. */
8
+ export function loadedToolsPlugin(id: string, tools: readonly LoadedTool[]): CapekPlugin<unknown> {
9
+ return {
10
+ id,
11
+ scope: 'agent',
12
+ setup(context) {
13
+ tools.forEach((loaded, index) => {
14
+ context.contributeTool({
15
+ id: `${id}.${loaded.definition.name}`,
16
+ order: 1000 + index,
17
+ definition: loaded.definition as unknown as ToolDefinition,
18
+ payload: loaded,
19
+ });
20
+ });
21
+ },
22
+ };
23
+ }
@@ -0,0 +1,264 @@
1
+ import type { PermissionRiskLevel } from '@capekai/tool';
2
+ import { serviceKey } from '../kernel/service-key';
3
+ import type {
4
+ CapekPlugin,
5
+ ContextSectionContribution,
6
+ PluginContext,
7
+ ToolDefinition as KernelToolDefinition,
8
+ } from '../kernel/types';
9
+ import {
10
+ DOMAIN_TOOL_PAYLOAD_FIELD,
11
+ registerDomainToolFallback,
12
+ type DomainToolPayload,
13
+ } from '../runtime/domain-tool-source';
14
+ import { validateContextAssemblyData, type ContextAssemblyData } from '../context/assembler';
15
+ import type { ContextSources } from '../context/sources';
16
+ import {
17
+ executeMemoryTool,
18
+ memoryToolDefinition,
19
+ loadMemoryInstructions,
20
+ } from '../memory';
21
+ import type { StorageBundle } from '../storage/contracts';
22
+ import { getHostGuidance } from '../runtime/host-guidance';
23
+ import { getHostLayout } from '../runtime/host-layout';
24
+ import { capekContextSourcesKey, capekStorageKey } from './service-keys';
25
+
26
+ /**
27
+ * C5 memory domain plugin. Owns the agent-scoped memory service: the
28
+ * workspace `memory` tool payload, the agent `agent_memory` tool payload,
29
+ * and the memory context sections (agent-memory, agent-user-preferences,
30
+ * memory-skills-guidance, workspace-memory, memory-guidance). Tool building
31
+ * stays in the core tool builders over the generic contributed-domain-tool
32
+ * seam; the payloads read only the build context the builders capture
33
+ * (workspace path, permission risk, agent directory), never module globals.
34
+ * The unscoped fallback installs explicitly, never at module load.
35
+ */
36
+
37
+ export const CURRENT_MEMORY_DOMAIN_PLUGIN_ID = 'current.memory-domain';
38
+ export const MEMORY_TOOL_CONTRIBUTION_ID = 'memory.memory';
39
+ export const MEMORY_TOOL_CONTRIBUTION_ORDER = 665;
40
+ export const AGENT_MEMORY_TOOL_CONTRIBUTION_ID = 'memory.agent_memory';
41
+ export const AGENT_MEMORY_TOOL_CONTRIBUTION_ORDER = 800;
42
+
43
+ export interface MemoryDomainService {
44
+ readonly tools: readonly DomainToolPayload[];
45
+ }
46
+
47
+ export const capekMemoryDomainKey = serviceKey<MemoryDomainService>(
48
+ 'capek.memory-domain',
49
+ 'agent',
50
+ );
51
+
52
+ export function createMemoryToolPayload(): DomainToolPayload {
53
+ return {
54
+ name: memoryToolDefinition.name,
55
+ description: memoryToolDefinition.description,
56
+ inputSchema: memoryToolDefinition.inputSchema,
57
+ display: { summary: '{action} {target}' },
58
+ visualize: (_input, result) => {
59
+ const r = result as { action?: string; target?: string; usage?: { chars?: number; limit?: number }; entries?: string[] };
60
+ if (r.action === 'list') {
61
+ const count = Array.isArray(r.entries) ? r.entries.length : 0;
62
+ const usage = r.usage ? `${r.usage.chars ?? 0}/${r.usage.limit ?? 0} chars` : '';
63
+ return {
64
+ type: 'none',
65
+ badge: [`${count} entr${count === 1 ? 'y' : 'ies'}`, usage].filter(Boolean).join(' · '),
66
+ message: `Memory (${r.target ?? 'memory'})`,
67
+ };
68
+ }
69
+ return { type: 'none', message: String(result.title ?? 'Memory updated') };
70
+ },
71
+ execute: async (input, context) => {
72
+ const workspacePath = context.workspacePath as string;
73
+ const risk = (context.permissionRisk ?? 'none') as PermissionRiskLevel;
74
+ const result = await executeMemoryTool(
75
+ input,
76
+ getHostLayout().workspaceMemoryDir(workspacePath),
77
+ risk,
78
+ context.ask,
79
+ );
80
+ if (!result.success) {
81
+ return {
82
+ error: result.error ?? 'Memory operation failed',
83
+ ...(result.entries ? { entries: result.entries } : {}),
84
+ ...(result.usage ? { usage: result.usage } : {}),
85
+ };
86
+ }
87
+ const r = result.result!;
88
+ return {
89
+ title: r.action === 'list' ? `Memory list (${r.target})` : 'Memory updated',
90
+ ...r,
91
+ };
92
+ },
93
+ };
94
+ }
95
+
96
+ export function createAgentMemoryToolPayload(): DomainToolPayload {
97
+ return {
98
+ name: 'agent_memory',
99
+ description: `Persist YOUR personal knowledge that travels with you across all workspaces.
100
+
101
+ Use target="user" for cross-workspace user preferences (how this person likes to work).
102
+ Use target="memory" for accumulated work knowledge (lessons, patterns, techniques from any project).
103
+
104
+ This is YOUR personal memory. It is separate from the workspace memory tool.
105
+ - Use "memory" (workspace) for project-specific facts about the current codebase.
106
+ - Use "agent_memory" (this tool) for cross-project knowledge that applies everywhere.
107
+
108
+ Actions:
109
+ - list: Read current entries and char usage. Requires target only.
110
+ - add: Append a new bullet entry. Requires content.
111
+ - replace: Find an entry by oldText substring and replace it.
112
+ - remove: Find an entry by oldText substring and remove it.
113
+
114
+ Character limits: user=1500, memory=2500. Keep entries compact.`,
115
+ inputSchema: memoryToolDefinition.inputSchema,
116
+ display: { summary: '{action} {target}' },
117
+ visualize: (_input, result) => {
118
+ const r = result as { action?: string; target?: string; entries?: string[] };
119
+ if (r.action === 'list') {
120
+ const count = Array.isArray(r.entries) ? r.entries.length : 0;
121
+ return {
122
+ type: 'none',
123
+ badge: `${count} entr${count === 1 ? 'y' : 'ies'}`,
124
+ message: `Agent memory (${r.target ?? 'memory'})`,
125
+ };
126
+ }
127
+ return { type: 'none', message: String(result.title ?? 'Agent memory updated') };
128
+ },
129
+ execute: async (input, context) => {
130
+ const result = await executeMemoryTool(input, context.agentDir as string, 'none');
131
+ if (!result.success) {
132
+ return { error: result.error ?? 'Agent memory operation failed' };
133
+ }
134
+ const r = result.result!;
135
+ return {
136
+ title: r.action === 'list' ? `Agent memory list (${r.target})` : 'Agent memory updated',
137
+ ...r,
138
+ };
139
+ },
140
+ };
141
+ }
142
+
143
+ /** Explicitly installs the unscoped legacy fallbacks. Called by the Jean2
144
+ * compatibility bindings installation (server bootstrap) and by focused
145
+ * tests; no module-load registration exists. */
146
+ export function installMemoryToolFallback(): void {
147
+ registerDomainToolFallback('memory', createMemoryToolPayload());
148
+ registerDomainToolFallback('agent_memory', createAgentMemoryToolPayload());
149
+ }
150
+
151
+ type MemorySectionContribution = ContextSectionContribution<ContextAssemblyData>;
152
+
153
+ function agentMemorySections(
154
+ sources: Partial<ContextSources>,
155
+ guidance: string,
156
+ ): readonly MemorySectionContribution[] {
157
+ return [
158
+ {
159
+ id: 'agent-memory',
160
+ phase: 'identity',
161
+ order: 10,
162
+ provide: async (build) => {
163
+ const data = validateContextAssemblyData(build.data);
164
+ const agentDir = await sources.agents?.getDirectory(data.preconfig.id);
165
+ if (!agentDir) return null;
166
+ const memory = await sources.agents?.readMemoryFile(data.preconfig.id, 'MEMORY.md');
167
+ return memory ? `<agent_memory>\n${memory}\n</agent_memory>` : null;
168
+ },
169
+ },
170
+ {
171
+ id: 'agent-user-preferences',
172
+ phase: 'identity',
173
+ order: 20,
174
+ provide: async (build) => {
175
+ const data = validateContextAssemblyData(build.data);
176
+ const agentDir = await sources.agents?.getDirectory(data.preconfig.id);
177
+ if (!agentDir) return null;
178
+ const memory = await sources.agents?.readMemoryFile(data.preconfig.id, 'USER.md');
179
+ return memory ? `<agent_user_preferences>\n${memory}\n</agent_user_preferences>` : null;
180
+ },
181
+ },
182
+ {
183
+ id: 'memory-skills-guidance',
184
+ phase: 'identity',
185
+ order: 40,
186
+ provide: async (build) => {
187
+ const data = validateContextAssemblyData(build.data);
188
+ const agentDir = await sources.agents?.getDirectory(data.preconfig.id);
189
+ return agentDir ? guidance : null;
190
+ },
191
+ },
192
+ ];
193
+ }
194
+
195
+ function workspaceMemorySections(storage: StorageBundle): readonly MemorySectionContribution[] {
196
+ return [
197
+ {
198
+ id: 'workspace-memory',
199
+ phase: 'workspace',
200
+ order: 20,
201
+ provide: async (build) => {
202
+ const data = validateContextAssemblyData(build.data);
203
+ if (!data.workspaceId) return null;
204
+ const workspace = await storage.workspaces.get(data.workspaceId);
205
+ if (!workspace?.settings?.memory?.enabled || !data.workspacePath) return null;
206
+ return loadMemoryInstructions(getHostLayout().workspaceMemoryDir(data.workspacePath));
207
+ },
208
+ },
209
+ {
210
+ id: 'memory-guidance',
211
+ phase: 'workspace',
212
+ order: 30,
213
+ provide: async (build) => {
214
+ const data = validateContextAssemblyData(build.data);
215
+ if (!data.workspaceId) return null;
216
+ const workspace = await storage.workspaces.get(data.workspaceId);
217
+ return workspace?.settings?.memory?.enabled && data.workspacePath ? getHostGuidance().memory : null;
218
+ },
219
+ },
220
+ ];
221
+ }
222
+
223
+ export function memoryDomainPlugin(id: string): CapekPlugin<unknown> {
224
+ return {
225
+ id,
226
+ scope: 'agent',
227
+ provides: [capekMemoryDomainKey],
228
+ requires: [capekStorageKey, capekContextSourcesKey],
229
+ setup(context: PluginContext) {
230
+ const storage: StorageBundle = context.require(capekStorageKey);
231
+ const sources: Partial<ContextSources> = context.require(capekContextSourcesKey);
232
+
233
+ const service: MemoryDomainService = {
234
+ tools: [createMemoryToolPayload(), createAgentMemoryToolPayload()],
235
+ };
236
+
237
+ context.provide(capekMemoryDomainKey, service);
238
+ for (const payload of service.tools) {
239
+ context.contributeTool({
240
+ id: payload.name === 'memory'
241
+ ? MEMORY_TOOL_CONTRIBUTION_ID
242
+ : AGENT_MEMORY_TOOL_CONTRIBUTION_ID,
243
+ order: payload.name === 'memory'
244
+ ? MEMORY_TOOL_CONTRIBUTION_ORDER
245
+ : AGENT_MEMORY_TOOL_CONTRIBUTION_ORDER,
246
+ definition: {
247
+ name: payload.name,
248
+ description: payload.description,
249
+ inputSchema: payload.inputSchema,
250
+ timeout: 10000,
251
+ [DOMAIN_TOOL_PAYLOAD_FIELD]: payload,
252
+ } as KernelToolDefinition,
253
+ requiredCapabilities: [capekMemoryDomainKey],
254
+ });
255
+ }
256
+ for (const section of agentMemorySections(sources, getHostGuidance().agentMemorySkills)) {
257
+ context.contributeContext(section);
258
+ }
259
+ for (const section of workspaceMemorySections(storage)) {
260
+ context.contributeContext(section);
261
+ }
262
+ },
263
+ };
264
+ }
@@ -0,0 +1,29 @@
1
+ import type { CapekPlugin, PluginContext } from '../kernel/types';
2
+ import { runOrchestratorSession } from '../workflow/orchestrator-session';
3
+ import {
4
+ capekOrchestratorSessionKey,
5
+ type OrchestratorSessionContract,
6
+ } from './service-keys';
7
+
8
+ /**
9
+ * C5 provider for the shared workflow/goals orchestrator model-turn
10
+ * contract (`capek.orchestrator-session`). Wraps the current implementation
11
+ * at `workflow/orchestrator-session.ts` with its exact function identity, so
12
+ * the workflow domain plugin and, next slice, the goals domain plugin
13
+ * consume the same named service without owning workflow code. The provider
14
+ * is a composition bridge; its workflow-domain import is pinned by the
15
+ * `plugins-no-workflow-ownership` boundary rule.
16
+ */
17
+ export function orchestratorSessionProviderPlugin(id: string): CapekPlugin<unknown> {
18
+ return {
19
+ id,
20
+ scope: 'agent',
21
+ provides: [capekOrchestratorSessionKey],
22
+ setup(context: PluginContext) {
23
+ const contract: OrchestratorSessionContract = {
24
+ run: runOrchestratorSession,
25
+ };
26
+ context.provide(capekOrchestratorSessionKey, contract);
27
+ },
28
+ };
29
+ }
@@ -0,0 +1,49 @@
1
+ import type { CapekPlugin, PluginContext } from '../kernel/types';
2
+ import {
3
+ createAskPermissionService,
4
+ type AskPermissionServiceCreateOptions,
5
+ } from '../permission/policy';
6
+ import { createPermissionRuntimeService } from '../permission/runtime';
7
+ import {
8
+ capekPermissionPolicyKey,
9
+ capekPermissionRuntimeKey,
10
+ capekRuntimeHostKey,
11
+ } from './service-keys';
12
+
13
+ /**
14
+ * C6 providers for the permission surface:
15
+ *
16
+ * - `capek.permission-policy` (REPLACEABLE advice/config): the permission
17
+ * timeout translates into provider options here, at composition. The
18
+ * generic ask timeout has no current configuration source and stays the
19
+ * fixed 5-minute constant.
20
+ * - `capek.permission-runtime` (NON-REPLACEABLE lifecycle): request-id
21
+ * routing, waiters, validation enforcement, raw-audit denial, and
22
+ * canonical grant construction/persistence. A replacement policy can
23
+ * change advice only; it can never approve malformed responses or create
24
+ * grants outside the canonical allowed scopes.
25
+ */
26
+ export function permissionPolicyPlugin(id: string): CapekPlugin<unknown> {
27
+ return {
28
+ id,
29
+ scope: 'agent',
30
+ provides: [capekPermissionPolicyKey, capekPermissionRuntimeKey],
31
+ requires: [capekRuntimeHostKey],
32
+ setup(context: PluginContext) {
33
+ const host = context.require(capekRuntimeHostKey);
34
+ const createOptions: AskPermissionServiceCreateOptions = {
35
+ id,
36
+ options: {
37
+ askTimeoutMs: 5 * 60 * 1000,
38
+ permissionTimeoutMs: host.interaction.getPermissionTimeoutMs(),
39
+ },
40
+ };
41
+ const policy = createAskPermissionService(createOptions);
42
+ context.provide(capekPermissionPolicyKey, policy);
43
+ context.provide(
44
+ capekPermissionRuntimeKey,
45
+ createPermissionRuntimeService({ id: `${id}.runtime`, provider: policy }),
46
+ );
47
+ },
48
+ };
49
+ }
@@ -0,0 +1,28 @@
1
+ import type { CapekPlugin, PluginContext } from '../kernel/types';
2
+ import {
3
+ createRetryPolicy,
4
+ type RetryPolicy,
5
+ } from '../retry/policy';
6
+ import { capekRetryPolicyKey } from './service-keys';
7
+
8
+ /**
9
+ * C6 provider for the agent-scoped retry policy contract
10
+ * (`capek.retry-policy`). Wraps the exact current behavior through
11
+ * `createRetryPolicy()`: classification, exponential jittered backoff with
12
+ * Retry-After as a minimum, circuit state owned by this policy instance, and
13
+ * the no-retry-after-tool-activity side-effect barrier. Every composed agent
14
+ * scope gets its own policy instance, so circuit state is isolated per
15
+ * agent; the facade's pre-C6 per-agent `withRetryCircuitState` wrap is
16
+ * replaced by this scope-owned provider.
17
+ */
18
+ export function retryPolicyPlugin(id: string): CapekPlugin<unknown> {
19
+ return {
20
+ id,
21
+ scope: 'agent',
22
+ provides: [capekRetryPolicyKey],
23
+ setup(context: PluginContext) {
24
+ const policy: RetryPolicy = createRetryPolicy({ id });
25
+ context.provide(capekRetryPolicyKey, policy);
26
+ },
27
+ };
28
+ }