cognitive-core 0.0.1 → 0.1.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 +363 -2
- package/SKILL.md +193 -0
- package/dist/agents/index.d.ts +3 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/mock-provider.d.ts +23 -0
- package/dist/agents/mock-provider.d.ts.map +1 -0
- package/dist/agents/mock-provider.js +71 -0
- package/dist/agents/mock-provider.js.map +1 -0
- package/dist/agents/types.d.ts +98 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +44 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/atlas.d.ts +196 -0
- package/dist/atlas.d.ts.map +1 -0
- package/dist/atlas.js +373 -0
- package/dist/atlas.js.map +1 -0
- package/dist/bin/cognitive-core.d.ts +18 -0
- package/dist/bin/cognitive-core.d.ts.map +1 -0
- package/dist/bin/cognitive-core.js +419 -0
- package/dist/bin/cognitive-core.js.map +1 -0
- package/dist/embeddings/bm25.d.ts +104 -0
- package/dist/embeddings/bm25.d.ts.map +1 -0
- package/dist/embeddings/bm25.js +264 -0
- package/dist/embeddings/bm25.js.map +1 -0
- package/dist/embeddings/index.d.ts +12 -0
- package/dist/embeddings/index.d.ts.map +1 -0
- package/dist/embeddings/index.js +16 -0
- package/dist/embeddings/index.js.map +1 -0
- package/dist/embeddings/manager.d.ts +112 -0
- package/dist/embeddings/manager.d.ts.map +1 -0
- package/dist/embeddings/manager.js +215 -0
- package/dist/embeddings/manager.js.map +1 -0
- package/dist/embeddings/provider.d.ts +101 -0
- package/dist/embeddings/provider.d.ts.map +1 -0
- package/dist/embeddings/provider.js +232 -0
- package/dist/embeddings/provider.js.map +1 -0
- package/dist/embeddings/vector-store.d.ts +101 -0
- package/dist/embeddings/vector-store.d.ts.map +1 -0
- package/dist/embeddings/vector-store.js +256 -0
- package/dist/embeddings/vector-store.js.map +1 -0
- package/dist/factory.d.ts +193 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +109 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +84 -0
- package/dist/index.js.map +1 -0
- package/dist/learning/analyzer.d.ts +110 -0
- package/dist/learning/analyzer.d.ts.map +1 -0
- package/dist/learning/analyzer.js +213 -0
- package/dist/learning/analyzer.js.map +1 -0
- package/dist/learning/effectiveness.d.ts +158 -0
- package/dist/learning/effectiveness.d.ts.map +1 -0
- package/dist/learning/effectiveness.js +251 -0
- package/dist/learning/effectiveness.js.map +1 -0
- package/dist/learning/index.d.ts +8 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +11 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/llm-extractor.d.ts +88 -0
- package/dist/learning/llm-extractor.d.ts.map +1 -0
- package/dist/learning/llm-extractor.js +372 -0
- package/dist/learning/llm-extractor.js.map +1 -0
- package/dist/learning/meta-learner.d.ts +80 -0
- package/dist/learning/meta-learner.d.ts.map +1 -0
- package/dist/learning/meta-learner.js +355 -0
- package/dist/learning/meta-learner.js.map +1 -0
- package/dist/learning/pipeline.d.ts +65 -0
- package/dist/learning/pipeline.d.ts.map +1 -0
- package/dist/learning/pipeline.js +170 -0
- package/dist/learning/pipeline.js.map +1 -0
- package/dist/learning/playbook-extractor.d.ts +113 -0
- package/dist/learning/playbook-extractor.d.ts.map +1 -0
- package/dist/learning/playbook-extractor.js +523 -0
- package/dist/learning/playbook-extractor.js.map +1 -0
- package/dist/learning/usage-inference.d.ts +82 -0
- package/dist/learning/usage-inference.d.ts.map +1 -0
- package/dist/learning/usage-inference.js +261 -0
- package/dist/learning/usage-inference.js.map +1 -0
- package/dist/mcp/index.d.ts +6 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +6 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/playbook-server.d.ts +120 -0
- package/dist/mcp/playbook-server.d.ts.map +1 -0
- package/dist/mcp/playbook-server.js +427 -0
- package/dist/mcp/playbook-server.js.map +1 -0
- package/dist/memory/curated-loader.d.ts +62 -0
- package/dist/memory/curated-loader.d.ts.map +1 -0
- package/dist/memory/curated-loader.js +106 -0
- package/dist/memory/curated-loader.js.map +1 -0
- package/dist/memory/experience.d.ts +122 -0
- package/dist/memory/experience.d.ts.map +1 -0
- package/dist/memory/experience.js +392 -0
- package/dist/memory/experience.js.map +1 -0
- package/dist/memory/index.d.ts +6 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +9 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/meta.d.ts +90 -0
- package/dist/memory/meta.d.ts.map +1 -0
- package/dist/memory/meta.js +362 -0
- package/dist/memory/meta.js.map +1 -0
- package/dist/memory/playbook.d.ts +133 -0
- package/dist/memory/playbook.d.ts.map +1 -0
- package/dist/memory/playbook.js +357 -0
- package/dist/memory/playbook.js.map +1 -0
- package/dist/memory/system.d.ts +167 -0
- package/dist/memory/system.d.ts.map +1 -0
- package/dist/memory/system.js +383 -0
- package/dist/memory/system.js.map +1 -0
- package/dist/runtime/backends/acp.d.ts +67 -0
- package/dist/runtime/backends/acp.d.ts.map +1 -0
- package/dist/runtime/backends/acp.js +290 -0
- package/dist/runtime/backends/acp.js.map +1 -0
- package/dist/runtime/backends/index.d.ts +5 -0
- package/dist/runtime/backends/index.d.ts.map +1 -0
- package/dist/runtime/backends/index.js +6 -0
- package/dist/runtime/backends/index.js.map +1 -0
- package/dist/runtime/backends/mock.d.ts +67 -0
- package/dist/runtime/backends/mock.d.ts.map +1 -0
- package/dist/runtime/backends/mock.js +153 -0
- package/dist/runtime/backends/mock.js.map +1 -0
- package/dist/runtime/backends/subprocess.d.ts +56 -0
- package/dist/runtime/backends/subprocess.d.ts.map +1 -0
- package/dist/runtime/backends/subprocess.js +260 -0
- package/dist/runtime/backends/subprocess.js.map +1 -0
- package/dist/runtime/flows/learning.d.ts +73 -0
- package/dist/runtime/flows/learning.d.ts.map +1 -0
- package/dist/runtime/flows/learning.js +116 -0
- package/dist/runtime/flows/learning.js.map +1 -0
- package/dist/runtime/flows/validation.d.ts +122 -0
- package/dist/runtime/flows/validation.d.ts.map +1 -0
- package/dist/runtime/flows/validation.js +223 -0
- package/dist/runtime/flows/validation.js.map +1 -0
- package/dist/runtime/index.d.ts +6 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +8 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/manager.d.ts +116 -0
- package/dist/runtime/manager.d.ts.map +1 -0
- package/dist/runtime/manager.js +416 -0
- package/dist/runtime/manager.js.map +1 -0
- package/dist/runtime/types.d.ts +138 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/search/evaluator.d.ts +102 -0
- package/dist/search/evaluator.d.ts.map +1 -0
- package/dist/search/evaluator.js +352 -0
- package/dist/search/evaluator.js.map +1 -0
- package/dist/search/index.d.ts +7 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +11 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/refinement-loop.d.ts +73 -0
- package/dist/search/refinement-loop.d.ts.map +1 -0
- package/dist/search/refinement-loop.js +245 -0
- package/dist/search/refinement-loop.js.map +1 -0
- package/dist/search/refinement-types.d.ts +154 -0
- package/dist/search/refinement-types.d.ts.map +1 -0
- package/dist/search/refinement-types.js +99 -0
- package/dist/search/refinement-types.js.map +1 -0
- package/dist/search/router.d.ts +61 -0
- package/dist/search/router.d.ts.map +1 -0
- package/dist/search/router.js +197 -0
- package/dist/search/router.js.map +1 -0
- package/dist/search/solver.d.ts +75 -0
- package/dist/search/solver.d.ts.map +1 -0
- package/dist/search/solver.js +216 -0
- package/dist/search/solver.js.map +1 -0
- package/dist/search/verification-runner.d.ts +125 -0
- package/dist/search/verification-runner.d.ts.map +1 -0
- package/dist/search/verification-runner.js +440 -0
- package/dist/search/verification-runner.js.map +1 -0
- package/dist/surfacing/index.d.ts +2 -0
- package/dist/surfacing/index.d.ts.map +1 -0
- package/dist/surfacing/index.js +2 -0
- package/dist/surfacing/index.js.map +1 -0
- package/dist/surfacing/skill-library.d.ts +158 -0
- package/dist/surfacing/skill-library.d.ts.map +1 -0
- package/dist/surfacing/skill-library.js +429 -0
- package/dist/surfacing/skill-library.js.map +1 -0
- package/dist/types/config.d.ts +1113 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +274 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/memory.d.ts +339 -0
- package/dist/types/memory.d.ts.map +1 -0
- package/dist/types/memory.js +207 -0
- package/dist/types/memory.js.map +1 -0
- package/dist/types/meta.d.ts +146 -0
- package/dist/types/meta.d.ts.map +1 -0
- package/dist/types/meta.js +51 -0
- package/dist/types/meta.js.map +1 -0
- package/dist/types/outcome.d.ts +42 -0
- package/dist/types/outcome.d.ts.map +1 -0
- package/dist/types/outcome.js +50 -0
- package/dist/types/outcome.js.map +1 -0
- package/dist/types/playbook.d.ts +119 -0
- package/dist/types/playbook.d.ts.map +1 -0
- package/dist/types/playbook.js +71 -0
- package/dist/types/playbook.js.map +1 -0
- package/dist/types/step.d.ts +44 -0
- package/dist/types/step.d.ts.map +1 -0
- package/dist/types/step.js +32 -0
- package/dist/types/step.js.map +1 -0
- package/dist/types/task.d.ts +91 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +39 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/trajectory.d.ts +221 -0
- package/dist/types/trajectory.d.ts.map +1 -0
- package/dist/types/trajectory.js +60 -0
- package/dist/types/trajectory.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/similarity.d.ts +31 -0
- package/dist/utils/similarity.d.ts.map +1 -0
- package/dist/utils/similarity.js +107 -0
- package/dist/utils/similarity.js.map +1 -0
- package/dist/utils/storage.d.ts +106 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/dist/utils/storage.js +203 -0
- package/dist/utils/storage.js.map +1 -0
- package/dist/utils/validation.d.ts +129 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +171 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +61 -9
- package/scripts/migrate-to-playbooks.ts +307 -0
- package/src/agents/index.ts +14 -0
- package/src/agents/mock-provider.ts +93 -0
- package/src/agents/types.ts +137 -0
- package/src/atlas.ts +560 -0
- package/src/bin/cognitive-core.ts +470 -0
- package/src/embeddings/bm25.ts +337 -0
- package/src/embeddings/index.ts +39 -0
- package/src/embeddings/manager.ts +288 -0
- package/src/embeddings/provider.ts +311 -0
- package/src/embeddings/vector-store.ts +353 -0
- package/src/factory.ts +263 -0
- package/src/index.ts +246 -0
- package/src/learning/analyzer.ts +335 -0
- package/src/learning/effectiveness.ts +428 -0
- package/src/learning/index.ts +58 -0
- package/src/learning/llm-extractor.ts +542 -0
- package/src/learning/meta-learner.ts +516 -0
- package/src/learning/pipeline.ts +244 -0
- package/src/learning/playbook-extractor.ts +702 -0
- package/src/learning/usage-inference.ts +372 -0
- package/src/mcp/index.ts +12 -0
- package/src/mcp/playbook-server.ts +565 -0
- package/src/memory/curated-loader.ts +160 -0
- package/src/memory/experience.ts +515 -0
- package/src/memory/index.ts +27 -0
- package/src/memory/meta.ts +506 -0
- package/src/memory/playbook.ts +493 -0
- package/src/memory/system.ts +551 -0
- package/src/runtime/backends/acp.ts +378 -0
- package/src/runtime/backends/index.ts +24 -0
- package/src/runtime/backends/mock.ts +218 -0
- package/src/runtime/backends/subprocess.ts +356 -0
- package/src/runtime/flows/learning.ts +183 -0
- package/src/runtime/flows/validation.ts +381 -0
- package/src/runtime/index.ts +53 -0
- package/src/runtime/manager.ts +541 -0
- package/src/runtime/types.ts +157 -0
- package/src/search/evaluator.ts +474 -0
- package/src/search/index.ts +59 -0
- package/src/search/refinement-loop.ts +363 -0
- package/src/search/refinement-types.ts +159 -0
- package/src/search/router.ts +261 -0
- package/src/search/solver.ts +303 -0
- package/src/search/verification-runner.ts +570 -0
- package/src/surfacing/index.ts +6 -0
- package/src/surfacing/skill-library.ts +594 -0
- package/src/types/config.ts +333 -0
- package/src/types/index.ts +130 -0
- package/src/types/memory.ts +270 -0
- package/src/types/meta.ts +218 -0
- package/src/types/outcome.ts +66 -0
- package/src/types/playbook.ts +196 -0
- package/src/types/step.ts +40 -0
- package/src/types/task.ts +52 -0
- package/src/types/trajectory.ts +80 -0
- package/src/utils/index.ts +38 -0
- package/src/utils/similarity.ts +139 -0
- package/src/utils/storage.ts +249 -0
- package/src/utils/validation.ts +286 -0
- package/tests/embeddings/bm25.test.ts +130 -0
- package/tests/embeddings/manager.test.ts +205 -0
- package/tests/integration/atlas.test.ts +266 -0
- package/tests/integration/e2e.test.ts +929 -0
- package/tests/learning/analyzer.test.ts +426 -0
- package/tests/learning/effectiveness.test.ts +542 -0
- package/tests/learning/pipeline.test.ts +176 -0
- package/tests/learning/playbook-extractor-provenance.test.ts +114 -0
- package/tests/learning/usage-inference.test.ts +254 -0
- package/tests/mcp/playbook-server.test.ts +252 -0
- package/tests/memory/experience.test.ts +198 -0
- package/tests/memory/playbook.test.ts +338 -0
- package/tests/memory/provenance.test.ts +639 -0
- package/tests/memory/system.test.ts +325 -0
- package/tests/runtime/agent-manager.test.ts +512 -0
- package/tests/runtime/mock-backend.test.ts +248 -0
- package/tests/search/refinement-loop.test.ts +468 -0
- package/tests/search/refinement.test.ts +267 -0
- package/tests/search/router.test.ts +427 -0
- package/tests/surfacing/skill-library.test.ts +292 -0
- package/tests/types/outcome.test.ts +147 -0
- package/tests/types/step.test.ts +133 -0
- package/tests/types/task.test.ts +158 -0
- package/tests/types/trajectory.test.ts +253 -0
- package/tests/utils/similarity.test.ts +188 -0
- package/tests/utils/validation.test.ts +252 -0
- package/tsconfig.json +25 -0
- package/vitest.config.ts +22 -0
- package/index.d.ts +0 -4
- package/index.js +0 -4
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP Backend using acp-factory
|
|
3
|
+
*
|
|
4
|
+
* This backend uses the acp-factory package to spawn and manage ACP-compatible
|
|
5
|
+
* agents like Claude Code, providing a clean interface for Atlas integration.
|
|
6
|
+
*/
|
|
7
|
+
import {
|
|
8
|
+
AgentFactory,
|
|
9
|
+
AgentHandle,
|
|
10
|
+
Session,
|
|
11
|
+
type AgentConfig,
|
|
12
|
+
type SpawnOptions,
|
|
13
|
+
type ExtendedSessionUpdate,
|
|
14
|
+
} from 'acp-factory';
|
|
15
|
+
import type {
|
|
16
|
+
AgentBackend,
|
|
17
|
+
AgentSpawnConfig,
|
|
18
|
+
AgentSession,
|
|
19
|
+
AgentMessage,
|
|
20
|
+
ToolCall,
|
|
21
|
+
} from '../types.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* ACP agent configuration
|
|
25
|
+
*/
|
|
26
|
+
export interface ACPAgentConfig extends AgentConfig {
|
|
27
|
+
/** Display name for the agent */
|
|
28
|
+
displayName?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Active ACP session state
|
|
33
|
+
*/
|
|
34
|
+
interface ACPSessionState {
|
|
35
|
+
atlasSession: AgentSession;
|
|
36
|
+
agentHandle: AgentHandle;
|
|
37
|
+
acpSession: Session;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* ACP Backend
|
|
42
|
+
* Uses acp-factory to spawn and manage ACP-compatible agents
|
|
43
|
+
*/
|
|
44
|
+
export class ACPBackend implements AgentBackend {
|
|
45
|
+
readonly name = 'acp';
|
|
46
|
+
readonly supportedTypes: string[];
|
|
47
|
+
|
|
48
|
+
private sessions: Map<string, ACPSessionState> = new Map();
|
|
49
|
+
private handles: Map<string, AgentHandle> = new Map();
|
|
50
|
+
|
|
51
|
+
constructor(configs: Record<string, ACPAgentConfig>) {
|
|
52
|
+
this.supportedTypes = Object.keys(configs);
|
|
53
|
+
|
|
54
|
+
// Register all agent configs with AgentFactory
|
|
55
|
+
for (const [name, config] of Object.entries(configs)) {
|
|
56
|
+
AgentFactory.register(name, {
|
|
57
|
+
command: config.command,
|
|
58
|
+
args: config.args,
|
|
59
|
+
env: config.env,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async isAvailable(): Promise<boolean> {
|
|
65
|
+
return this.supportedTypes.length > 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async spawn(config: AgentSpawnConfig): Promise<AgentSession> {
|
|
69
|
+
const atlasSessionId = crypto.randomUUID();
|
|
70
|
+
|
|
71
|
+
// Create Atlas session tracking
|
|
72
|
+
const atlasSession: AgentSession = {
|
|
73
|
+
id: atlasSessionId,
|
|
74
|
+
agentType: config.agentType,
|
|
75
|
+
task: config.task,
|
|
76
|
+
state: 'running',
|
|
77
|
+
messages: [],
|
|
78
|
+
toolCalls: [],
|
|
79
|
+
startTime: new Date(),
|
|
80
|
+
metadata: {
|
|
81
|
+
injectedKnowledge: !!config.injectedKnowledge,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Spawn the agent
|
|
87
|
+
const spawnOptions: SpawnOptions = {
|
|
88
|
+
permissionMode: 'auto-approve', // Auto-approve for automated learning
|
|
89
|
+
env: config.env,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const agentHandle = await AgentFactory.spawn(config.agentType, spawnOptions);
|
|
93
|
+
this.handles.set(atlasSessionId, agentHandle);
|
|
94
|
+
|
|
95
|
+
// Store capabilities
|
|
96
|
+
atlasSession.metadata.capabilities = agentHandle.capabilities;
|
|
97
|
+
|
|
98
|
+
// Create a session with the agent
|
|
99
|
+
const cwd = config.cwd ?? process.cwd();
|
|
100
|
+
const acpSession = await agentHandle.createSession(cwd);
|
|
101
|
+
|
|
102
|
+
// Store session state
|
|
103
|
+
const state: ACPSessionState = {
|
|
104
|
+
atlasSession,
|
|
105
|
+
agentHandle,
|
|
106
|
+
acpSession,
|
|
107
|
+
};
|
|
108
|
+
this.sessions.set(atlasSessionId, state);
|
|
109
|
+
|
|
110
|
+
// Build prompt content with knowledge injection
|
|
111
|
+
let promptContent = config.task.description;
|
|
112
|
+
if (config.systemPromptAdditions) {
|
|
113
|
+
promptContent = `## Context from Atlas Memory\n\n${config.systemPromptAdditions}\n\n---\n\n${promptContent}`;
|
|
114
|
+
}
|
|
115
|
+
if (Object.keys(config.task.context).length > 0) {
|
|
116
|
+
promptContent += `\n\n## Additional Context\n\`\`\`json\n${JSON.stringify(config.task.context, null, 2)}\n\`\`\``;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Send prompt and collect updates
|
|
120
|
+
await this.runPrompt(state, promptContent, config);
|
|
121
|
+
|
|
122
|
+
return atlasSession;
|
|
123
|
+
} catch (error) {
|
|
124
|
+
atlasSession.state = 'failed';
|
|
125
|
+
atlasSession.error = error instanceof Error ? error.message : 'Unknown error';
|
|
126
|
+
atlasSession.endTime = new Date();
|
|
127
|
+
console.error(
|
|
128
|
+
`[ACPBackend] Session ${atlasSessionId} spawn failed:`,
|
|
129
|
+
error instanceof Error ? error.message : String(error)
|
|
130
|
+
);
|
|
131
|
+
return atlasSession;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Run a prompt and collect all updates
|
|
137
|
+
*/
|
|
138
|
+
private async runPrompt(
|
|
139
|
+
state: ACPSessionState,
|
|
140
|
+
promptContent: string,
|
|
141
|
+
config: AgentSpawnConfig
|
|
142
|
+
): Promise<void> {
|
|
143
|
+
const { atlasSession, acpSession } = state;
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
// Stream updates from the agent
|
|
147
|
+
for await (const update of acpSession.prompt(promptContent)) {
|
|
148
|
+
this.processUpdate(atlasSession, update, config);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Mark as completed
|
|
152
|
+
atlasSession.state = 'completed';
|
|
153
|
+
atlasSession.endTime = new Date();
|
|
154
|
+
} catch (error) {
|
|
155
|
+
atlasSession.state = 'failed';
|
|
156
|
+
atlasSession.error = error instanceof Error ? error.message : 'Unknown error';
|
|
157
|
+
atlasSession.endTime = new Date();
|
|
158
|
+
console.error(
|
|
159
|
+
`[ACPBackend] Session ${atlasSession.id} prompt execution failed:`,
|
|
160
|
+
error instanceof Error ? error.message : String(error)
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Process a session update from the agent
|
|
167
|
+
* Uses defensive typing since ACP types can vary
|
|
168
|
+
*/
|
|
169
|
+
private processUpdate(
|
|
170
|
+
session: AgentSession,
|
|
171
|
+
update: ExtendedSessionUpdate,
|
|
172
|
+
config: AgentSpawnConfig
|
|
173
|
+
): void {
|
|
174
|
+
// Cast to any for flexible property access since ACP types are complex unions
|
|
175
|
+
const u = update as Record<string, unknown>;
|
|
176
|
+
const updateType = u.sessionUpdate as string;
|
|
177
|
+
|
|
178
|
+
switch (updateType) {
|
|
179
|
+
case 'agent_message_chunk':
|
|
180
|
+
case 'user_message_chunk':
|
|
181
|
+
case 'agent_thought_chunk': {
|
|
182
|
+
// ContentChunk has a single 'content' field (ContentBlock)
|
|
183
|
+
const content = u.content as Record<string, unknown> | undefined;
|
|
184
|
+
if (content && content.type === 'text' && typeof content.text === 'string') {
|
|
185
|
+
const message: AgentMessage = {
|
|
186
|
+
role: updateType === 'user_message_chunk' ? 'user' : 'assistant',
|
|
187
|
+
content: content.text,
|
|
188
|
+
timestamp: new Date(),
|
|
189
|
+
};
|
|
190
|
+
session.messages.push(message);
|
|
191
|
+
config.onMessage?.(message);
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
case 'tool_call': {
|
|
197
|
+
// ToolCall has toolCallId, title, rawInput, status, content, etc.
|
|
198
|
+
const toolCallId = (u.toolCallId as string) ?? crypto.randomUUID();
|
|
199
|
+
const title = (u.title as string) ?? 'unknown';
|
|
200
|
+
const rawInput = u.rawInput;
|
|
201
|
+
|
|
202
|
+
const toolCall: ToolCall = {
|
|
203
|
+
id: toolCallId,
|
|
204
|
+
name: title,
|
|
205
|
+
input: rawInput,
|
|
206
|
+
startTime: new Date(),
|
|
207
|
+
};
|
|
208
|
+
session.toolCalls.push(toolCall);
|
|
209
|
+
config.onToolCall?.(toolCall);
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
case 'tool_call_update': {
|
|
214
|
+
// ToolCallUpdate has toolCallId, status, content, etc.
|
|
215
|
+
const toolCallId = u.toolCallId as string;
|
|
216
|
+
const status = u.status as string | undefined;
|
|
217
|
+
const content = u.content as Array<Record<string, unknown>> | undefined;
|
|
218
|
+
|
|
219
|
+
const existingTc = session.toolCalls.find((t) => t.id === toolCallId);
|
|
220
|
+
if (existingTc) {
|
|
221
|
+
if (status === 'completed' || status === 'failed') {
|
|
222
|
+
existingTc.endTime = new Date();
|
|
223
|
+
}
|
|
224
|
+
if (content && Array.isArray(content)) {
|
|
225
|
+
// Extract text from content blocks
|
|
226
|
+
const outputs: string[] = [];
|
|
227
|
+
for (const block of content) {
|
|
228
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
229
|
+
outputs.push(block.text);
|
|
230
|
+
} else if (block.type === 'diff' && typeof block.diff === 'string') {
|
|
231
|
+
outputs.push(block.diff);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (outputs.length > 0) {
|
|
235
|
+
existingTc.output = outputs.join('\n');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (status === 'failed') {
|
|
239
|
+
existingTc.error = 'Tool call failed';
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
case 'permission_request': {
|
|
246
|
+
// In auto-approve mode, this shouldn't happen, but log it
|
|
247
|
+
session.messages.push({
|
|
248
|
+
role: 'system',
|
|
249
|
+
content: `Permission requested: ${JSON.stringify(update)}`,
|
|
250
|
+
timestamp: new Date(),
|
|
251
|
+
});
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
case 'plan': {
|
|
256
|
+
// Agent shared its plan
|
|
257
|
+
const plan = u.plan;
|
|
258
|
+
session.messages.push({
|
|
259
|
+
role: 'assistant',
|
|
260
|
+
content: `[Plan] ${JSON.stringify(plan)}`,
|
|
261
|
+
timestamp: new Date(),
|
|
262
|
+
});
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
default:
|
|
267
|
+
// Log other updates for debugging
|
|
268
|
+
session.metadata.lastUpdate = update;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async getSession(sessionId: string): Promise<AgentSession | undefined> {
|
|
273
|
+
return this.sessions.get(sessionId)?.atlasSession;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async sendMessage(sessionId: string, message: string): Promise<void> {
|
|
277
|
+
const state = this.sessions.get(sessionId);
|
|
278
|
+
if (!state) {
|
|
279
|
+
throw new Error('Session not found');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Send additional prompt
|
|
283
|
+
for await (const update of state.acpSession.prompt(message)) {
|
|
284
|
+
this.processUpdate(state.atlasSession, update, {
|
|
285
|
+
agentType: state.atlasSession.agentType,
|
|
286
|
+
task: state.atlasSession.task,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
async terminate(sessionId: string): Promise<void> {
|
|
292
|
+
const state = this.sessions.get(sessionId);
|
|
293
|
+
if (!state) return;
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
// Cancel any running prompt
|
|
297
|
+
await state.acpSession.cancel();
|
|
298
|
+
} catch (error) {
|
|
299
|
+
// Log cancellation errors but don't throw
|
|
300
|
+
console.error(
|
|
301
|
+
`[ACPBackend] Session ${sessionId} cancel error:`,
|
|
302
|
+
error instanceof Error ? error.message : String(error)
|
|
303
|
+
);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
try {
|
|
307
|
+
// Close the agent handle
|
|
308
|
+
await state.agentHandle.close();
|
|
309
|
+
} catch (error) {
|
|
310
|
+
// Log close errors but don't throw
|
|
311
|
+
console.error(
|
|
312
|
+
`[ACPBackend] Session ${sessionId} close error:`,
|
|
313
|
+
error instanceof Error ? error.message : String(error)
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
state.atlasSession.state = 'failed';
|
|
318
|
+
state.atlasSession.error = 'Terminated';
|
|
319
|
+
state.atlasSession.endTime = new Date();
|
|
320
|
+
|
|
321
|
+
this.sessions.delete(sessionId);
|
|
322
|
+
this.handles.delete(sessionId);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async listSessions(): Promise<AgentSession[]> {
|
|
326
|
+
return Array.from(this.sessions.values()).map((s) => s.atlasSession);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get a raw ACP session for advanced usage
|
|
331
|
+
*/
|
|
332
|
+
getACPSession(sessionId: string): Session | undefined {
|
|
333
|
+
return this.sessions.get(sessionId)?.acpSession;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Get a raw agent handle for advanced usage
|
|
338
|
+
*/
|
|
339
|
+
getAgentHandle(sessionId: string): AgentHandle | undefined {
|
|
340
|
+
return this.sessions.get(sessionId)?.agentHandle;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Create an ACP backend with agent configurations
|
|
346
|
+
*/
|
|
347
|
+
export function createACPBackend(
|
|
348
|
+
configs: Record<string, ACPAgentConfig>
|
|
349
|
+
): ACPBackend {
|
|
350
|
+
return new ACPBackend(configs);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Pre-configured Claude Code agent via claude-code-acp
|
|
355
|
+
*/
|
|
356
|
+
export const claudeCodeACPConfig: ACPAgentConfig = {
|
|
357
|
+
command: 'npx',
|
|
358
|
+
args: ['claude-code-acp'],
|
|
359
|
+
displayName: 'Claude Code (ACP)',
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Pre-configured Claude direct (requires --print mode)
|
|
364
|
+
* Note: This may not support full ACP protocol
|
|
365
|
+
*/
|
|
366
|
+
export const claudeCodeDirectConfig: ACPAgentConfig = {
|
|
367
|
+
command: 'claude',
|
|
368
|
+
args: ['--print'],
|
|
369
|
+
displayName: 'Claude (Direct)',
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Helper to register common agents
|
|
374
|
+
*/
|
|
375
|
+
export function registerCommonAgents(): void {
|
|
376
|
+
AgentFactory.register('claude-code', claudeCodeACPConfig);
|
|
377
|
+
AgentFactory.register('claude-code-acp', claudeCodeACPConfig);
|
|
378
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export {
|
|
2
|
+
SubprocessBackend,
|
|
3
|
+
createSubprocessBackend,
|
|
4
|
+
claudeCodeConfig,
|
|
5
|
+
type SubprocessAgentConfig,
|
|
6
|
+
} from './subprocess.js';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
MockBackend,
|
|
10
|
+
createMockBackend,
|
|
11
|
+
type MockAgentBehavior,
|
|
12
|
+
} from './mock.js';
|
|
13
|
+
|
|
14
|
+
export {
|
|
15
|
+
ACPBackend,
|
|
16
|
+
createACPBackend,
|
|
17
|
+
claudeCodeACPConfig,
|
|
18
|
+
claudeCodeDirectConfig,
|
|
19
|
+
registerCommonAgents,
|
|
20
|
+
type ACPAgentConfig,
|
|
21
|
+
} from './acp.js';
|
|
22
|
+
|
|
23
|
+
// Re-export useful types from acp-factory
|
|
24
|
+
export { AgentFactory } from 'acp-factory';
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AgentBackend,
|
|
3
|
+
AgentSpawnConfig,
|
|
4
|
+
AgentSession,
|
|
5
|
+
AgentMessage,
|
|
6
|
+
ToolCall,
|
|
7
|
+
} from '../types.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Mock agent behavior definition
|
|
11
|
+
*/
|
|
12
|
+
export interface MockAgentBehavior {
|
|
13
|
+
/** Simulated tool calls */
|
|
14
|
+
toolCalls?: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
input: unknown;
|
|
17
|
+
output: unknown;
|
|
18
|
+
delayMs?: number;
|
|
19
|
+
}>;
|
|
20
|
+
/** Messages to emit */
|
|
21
|
+
messages?: Array<{
|
|
22
|
+
role: 'assistant' | 'user';
|
|
23
|
+
content: string;
|
|
24
|
+
delayMs?: number;
|
|
25
|
+
}>;
|
|
26
|
+
/** Final result */
|
|
27
|
+
result?: unknown;
|
|
28
|
+
/** Should the agent succeed? */
|
|
29
|
+
success?: boolean;
|
|
30
|
+
/** Error message if failing */
|
|
31
|
+
error?: string;
|
|
32
|
+
/** Total duration in ms */
|
|
33
|
+
durationMs?: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Mock backend for testing
|
|
38
|
+
*/
|
|
39
|
+
export class MockBackend implements AgentBackend {
|
|
40
|
+
readonly name = 'mock';
|
|
41
|
+
readonly supportedTypes = ['mock', 'test'];
|
|
42
|
+
|
|
43
|
+
private sessions: Map<string, AgentSession> = new Map();
|
|
44
|
+
private behaviors: Map<string, MockAgentBehavior> = new Map();
|
|
45
|
+
private defaultBehavior: MockAgentBehavior;
|
|
46
|
+
|
|
47
|
+
constructor(defaultBehavior?: MockAgentBehavior) {
|
|
48
|
+
this.defaultBehavior = defaultBehavior ?? {
|
|
49
|
+
success: true,
|
|
50
|
+
result: 'Mock result',
|
|
51
|
+
durationMs: 100,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Set behavior for a specific task description
|
|
57
|
+
*/
|
|
58
|
+
setBehavior(taskDescription: string, behavior: MockAgentBehavior): void {
|
|
59
|
+
this.behaviors.set(taskDescription, behavior);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Set default behavior for all tasks
|
|
64
|
+
*/
|
|
65
|
+
setDefaultBehavior(behavior: MockAgentBehavior): void {
|
|
66
|
+
this.defaultBehavior = behavior;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async isAvailable(): Promise<boolean> {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async spawn(config: AgentSpawnConfig): Promise<AgentSession> {
|
|
74
|
+
const sessionId = crypto.randomUUID();
|
|
75
|
+
const behavior =
|
|
76
|
+
this.behaviors.get(config.task.description) ?? this.defaultBehavior;
|
|
77
|
+
|
|
78
|
+
const session: AgentSession = {
|
|
79
|
+
id: sessionId,
|
|
80
|
+
agentType: config.agentType,
|
|
81
|
+
task: config.task,
|
|
82
|
+
state: 'running',
|
|
83
|
+
messages: [],
|
|
84
|
+
toolCalls: [],
|
|
85
|
+
startTime: new Date(),
|
|
86
|
+
metadata: {
|
|
87
|
+
injectedKnowledge: !!config.injectedKnowledge,
|
|
88
|
+
hasSystemPromptAdditions: !!config.systemPromptAdditions,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
this.sessions.set(sessionId, session);
|
|
93
|
+
|
|
94
|
+
// Simulate execution asynchronously
|
|
95
|
+
this.simulateExecution(session, behavior, config).catch((error) => {
|
|
96
|
+
session.state = 'failed';
|
|
97
|
+
session.error = error.message;
|
|
98
|
+
session.endTime = new Date();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return session;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private async simulateExecution(
|
|
105
|
+
session: AgentSession,
|
|
106
|
+
behavior: MockAgentBehavior,
|
|
107
|
+
config: AgentSpawnConfig
|
|
108
|
+
): Promise<void> {
|
|
109
|
+
const startTime = Date.now();
|
|
110
|
+
|
|
111
|
+
// Emit messages
|
|
112
|
+
if (behavior.messages) {
|
|
113
|
+
for (const msg of behavior.messages) {
|
|
114
|
+
if (msg.delayMs) {
|
|
115
|
+
await this.delay(msg.delayMs);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const message: AgentMessage = {
|
|
119
|
+
role: msg.role,
|
|
120
|
+
content: msg.content,
|
|
121
|
+
timestamp: new Date(),
|
|
122
|
+
};
|
|
123
|
+
session.messages.push(message);
|
|
124
|
+
config.onMessage?.(message);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Emit tool calls
|
|
129
|
+
if (behavior.toolCalls) {
|
|
130
|
+
for (const tc of behavior.toolCalls) {
|
|
131
|
+
if (tc.delayMs) {
|
|
132
|
+
await this.delay(tc.delayMs);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const toolCall: ToolCall = {
|
|
136
|
+
id: crypto.randomUUID(),
|
|
137
|
+
name: tc.name,
|
|
138
|
+
input: tc.input,
|
|
139
|
+
output: tc.output,
|
|
140
|
+
startTime: new Date(),
|
|
141
|
+
endTime: new Date(),
|
|
142
|
+
};
|
|
143
|
+
session.toolCalls.push(toolCall);
|
|
144
|
+
config.onToolCall?.(toolCall);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Wait for remaining duration
|
|
149
|
+
const elapsed = Date.now() - startTime;
|
|
150
|
+
const remaining = (behavior.durationMs ?? 100) - elapsed;
|
|
151
|
+
if (remaining > 0) {
|
|
152
|
+
await this.delay(remaining);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Complete
|
|
156
|
+
session.endTime = new Date();
|
|
157
|
+
if (behavior.success ?? true) {
|
|
158
|
+
session.state = 'completed';
|
|
159
|
+
session.result = behavior.result;
|
|
160
|
+
} else {
|
|
161
|
+
session.state = 'failed';
|
|
162
|
+
session.error = behavior.error ?? 'Mock failure';
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private delay(ms: number): Promise<void> {
|
|
167
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async getSession(sessionId: string): Promise<AgentSession | undefined> {
|
|
171
|
+
return this.sessions.get(sessionId);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async sendMessage(sessionId: string, _message: string): Promise<void> {
|
|
175
|
+
const session = this.sessions.get(sessionId);
|
|
176
|
+
if (!session) {
|
|
177
|
+
throw new Error('Session not found');
|
|
178
|
+
}
|
|
179
|
+
// Mock doesn't process additional messages
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async terminate(sessionId: string): Promise<void> {
|
|
183
|
+
const session = this.sessions.get(sessionId);
|
|
184
|
+
if (!session) return;
|
|
185
|
+
|
|
186
|
+
session.state = 'failed';
|
|
187
|
+
session.error = 'Terminated';
|
|
188
|
+
session.endTime = new Date();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async listSessions(): Promise<AgentSession[]> {
|
|
192
|
+
return Array.from(this.sessions.values());
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get all sessions (for testing assertions)
|
|
197
|
+
*/
|
|
198
|
+
getAllSessions(): AgentSession[] {
|
|
199
|
+
return Array.from(this.sessions.values());
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Clear all sessions
|
|
204
|
+
*/
|
|
205
|
+
clear(): void {
|
|
206
|
+
this.sessions.clear();
|
|
207
|
+
this.behaviors.clear();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Create a mock backend
|
|
213
|
+
*/
|
|
214
|
+
export function createMockBackend(
|
|
215
|
+
defaultBehavior?: MockAgentBehavior
|
|
216
|
+
): MockBackend {
|
|
217
|
+
return new MockBackend(defaultBehavior);
|
|
218
|
+
}
|