klaus-agent 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 +685 -0
- package/dist/approval/approval.d.ts +18 -0
- package/dist/approval/approval.js +93 -0
- package/dist/approval/approval.js.map +1 -0
- package/dist/approval/types.d.ts +21 -0
- package/dist/approval/types.js +3 -0
- package/dist/approval/types.js.map +1 -0
- package/dist/background/task-manager.d.ts +14 -0
- package/dist/background/task-manager.js +89 -0
- package/dist/background/task-manager.js.map +1 -0
- package/dist/background/tools.d.ts +4 -0
- package/dist/background/tools.js +74 -0
- package/dist/background/tools.js.map +1 -0
- package/dist/background/types.d.ts +31 -0
- package/dist/background/types.js +3 -0
- package/dist/background/types.js.map +1 -0
- package/dist/checkpoint/checkpoint-manager.d.ts +19 -0
- package/dist/checkpoint/checkpoint-manager.js +49 -0
- package/dist/checkpoint/checkpoint-manager.js.map +1 -0
- package/dist/checkpoint/dmail.d.ts +10 -0
- package/dist/checkpoint/dmail.js +26 -0
- package/dist/checkpoint/dmail.js.map +1 -0
- package/dist/checkpoint/types.d.ts +12 -0
- package/dist/checkpoint/types.js +3 -0
- package/dist/checkpoint/types.js.map +1 -0
- package/dist/compaction/compaction.d.ts +6 -0
- package/dist/compaction/compaction.js +104 -0
- package/dist/compaction/compaction.js.map +1 -0
- package/dist/compaction/summarizer.d.ts +10 -0
- package/dist/compaction/summarizer.js +75 -0
- package/dist/compaction/summarizer.js.map +1 -0
- package/dist/compaction/types.d.ts +23 -0
- package/dist/compaction/types.js +3 -0
- package/dist/compaction/types.js.map +1 -0
- package/dist/core/agent-loop.d.ts +37 -0
- package/dist/core/agent-loop.js +337 -0
- package/dist/core/agent-loop.js.map +1 -0
- package/dist/core/agent.d.ts +97 -0
- package/dist/core/agent.js +335 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/extensions/runner.d.ts +19 -0
- package/dist/extensions/runner.js +88 -0
- package/dist/extensions/runner.js.map +1 -0
- package/dist/extensions/types.d.ts +179 -0
- package/dist/extensions/types.js +3 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/injection/history-normalizer.d.ts +2 -0
- package/dist/injection/history-normalizer.js +34 -0
- package/dist/injection/history-normalizer.js.map +1 -0
- package/dist/injection/injection-manager.d.ts +8 -0
- package/dist/injection/injection-manager.js +28 -0
- package/dist/injection/injection-manager.js.map +1 -0
- package/dist/injection/types.d.ts +8 -0
- package/dist/injection/types.js +3 -0
- package/dist/injection/types.js.map +1 -0
- package/dist/llm/provider.d.ts +16 -0
- package/dist/llm/provider.js +233 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/types.d.ts +110 -0
- package/dist/llm/types.js +3 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/multi-agent/labor-market.d.ts +16 -0
- package/dist/multi-agent/labor-market.js +40 -0
- package/dist/multi-agent/labor-market.js.map +1 -0
- package/dist/multi-agent/task-executor.d.ts +12 -0
- package/dist/multi-agent/task-executor.js +38 -0
- package/dist/multi-agent/task-executor.js.map +1 -0
- package/dist/multi-agent/task-tool.d.ts +4 -0
- package/dist/multi-agent/task-tool.js +46 -0
- package/dist/multi-agent/task-tool.js.map +1 -0
- package/dist/multi-agent/types.d.ts +7 -0
- package/dist/multi-agent/types.js +3 -0
- package/dist/multi-agent/types.js.map +1 -0
- package/dist/session/session-context-builder.d.ts +2 -0
- package/dist/session/session-context-builder.js +52 -0
- package/dist/session/session-context-builder.js.map +1 -0
- package/dist/session/session-manager.d.ts +30 -0
- package/dist/session/session-manager.js +209 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/types.d.ts +61 -0
- package/dist/session/types.js +3 -0
- package/dist/session/types.js.map +1 -0
- package/dist/skills/discovery.d.ts +2 -0
- package/dist/skills/discovery.js +29 -0
- package/dist/skills/discovery.js.map +1 -0
- package/dist/skills/loader.d.ts +3 -0
- package/dist/skills/loader.js +46 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/skill-tool.d.ts +3 -0
- package/dist/skills/skill-tool.js +38 -0
- package/dist/skills/skill-tool.js.map +1 -0
- package/dist/skills/types.d.ts +14 -0
- package/dist/skills/types.js +3 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/tools/executor.d.ts +37 -0
- package/dist/tools/executor.js +131 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/mcp-adapter.d.ts +57 -0
- package/dist/tools/mcp-adapter.js +113 -0
- package/dist/tools/mcp-adapter.js.map +1 -0
- package/dist/tools/types.d.ts +43 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/types.d.ts +96 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/id.d.ts +1 -0
- package/dist/utils/id.js +9 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/jsonl.d.ts +3 -0
- package/dist/utils/jsonl.js +17 -0
- package/dist/utils/jsonl.js.map +1 -0
- package/dist/wire/types.d.ts +10 -0
- package/dist/wire/types.js +3 -0
- package/dist/wire/types.js.map +1 -0
- package/dist/wire/wire.d.ts +20 -0
- package/dist/wire/wire.js +71 -0
- package/dist/wire/wire.js.map +1 -0
- package/package.json +26 -0
- package/src/approval/approval.ts +108 -0
- package/src/approval/types.ts +26 -0
- package/src/background/task-manager.ts +112 -0
- package/src/background/tools.ts +84 -0
- package/src/background/types.ts +29 -0
- package/src/checkpoint/checkpoint-manager.ts +60 -0
- package/src/checkpoint/dmail.ts +35 -0
- package/src/checkpoint/types.ts +16 -0
- package/src/compaction/compaction.ts +119 -0
- package/src/compaction/summarizer.ts +83 -0
- package/src/compaction/types.ts +29 -0
- package/src/core/agent-loop.ts +427 -0
- package/src/core/agent.ts +430 -0
- package/src/extensions/runner.ts +138 -0
- package/src/extensions/types.ts +177 -0
- package/src/index.ts +221 -0
- package/src/injection/history-normalizer.ts +44 -0
- package/src/injection/injection-manager.ts +34 -0
- package/src/injection/types.ts +12 -0
- package/src/llm/provider.ts +254 -0
- package/src/llm/types.ts +146 -0
- package/src/multi-agent/labor-market.ts +54 -0
- package/src/multi-agent/task-executor.ts +49 -0
- package/src/multi-agent/task-tool.ts +58 -0
- package/src/multi-agent/types.ts +10 -0
- package/src/session/session-context-builder.ts +65 -0
- package/src/session/session-manager.ts +258 -0
- package/src/session/types.ts +93 -0
- package/src/skills/discovery.ts +32 -0
- package/src/skills/loader.ts +54 -0
- package/src/skills/skill-tool.ts +50 -0
- package/src/skills/types.ts +18 -0
- package/src/tools/executor.ts +196 -0
- package/src/tools/mcp-adapter.ts +185 -0
- package/src/tools/types.ts +64 -0
- package/src/types.ts +96 -0
- package/src/utils/id.ts +8 -0
- package/src/utils/jsonl.ts +19 -0
- package/src/wire/types.ts +14 -0
- package/src/wire/wire.ts +79 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// LaborMarket — fixed + dynamic subagent registry
|
|
2
|
+
export class LaborMarket {
|
|
3
|
+
_fixed = new Map();
|
|
4
|
+
_dynamic = new Map();
|
|
5
|
+
addFixed(name, agent, description) {
|
|
6
|
+
if (this._fixed.has(name) || this._dynamic.has(name)) {
|
|
7
|
+
throw new Error(`Subagent "${name}" already exists`);
|
|
8
|
+
}
|
|
9
|
+
this._fixed.set(name, { agent, description });
|
|
10
|
+
}
|
|
11
|
+
addDynamic(name, agent, description) {
|
|
12
|
+
if (this._fixed.has(name) || this._dynamic.has(name)) {
|
|
13
|
+
throw new Error(`Subagent "${name}" already exists`);
|
|
14
|
+
}
|
|
15
|
+
this._dynamic.set(name, { agent, description });
|
|
16
|
+
}
|
|
17
|
+
get(name) {
|
|
18
|
+
return this._fixed.get(name)?.agent ?? this._dynamic.get(name)?.agent;
|
|
19
|
+
}
|
|
20
|
+
getDescription(name) {
|
|
21
|
+
return this._fixed.get(name)?.description ?? this._dynamic.get(name)?.description;
|
|
22
|
+
}
|
|
23
|
+
listAll() {
|
|
24
|
+
const result = [];
|
|
25
|
+
for (const [name, entry] of this._fixed) {
|
|
26
|
+
result.push({ name, description: entry.description, type: "fixed" });
|
|
27
|
+
}
|
|
28
|
+
for (const [name, entry] of this._dynamic) {
|
|
29
|
+
result.push({ name, description: entry.description, type: "dynamic" });
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
removeDynamic(name) {
|
|
34
|
+
return this._dynamic.delete(name);
|
|
35
|
+
}
|
|
36
|
+
has(name) {
|
|
37
|
+
return this._fixed.has(name) || this._dynamic.has(name);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=labor-market.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"labor-market.js","sourceRoot":"","sources":["../../src/multi-agent/labor-market.ts"],"names":[],"mappings":"AAAA,kDAAkD;AASlD,MAAM,OAAO,WAAW;IACd,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC1C,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEpD,QAAQ,CAAC,IAAY,EAAE,KAAY,EAAE,WAAmB;QACtD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,kBAAkB,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,UAAU,CAAC,IAAY,EAAE,KAAY,EAAE,WAAmB;QACxD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,kBAAkB,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC;IACxE,CAAC;IAED,cAAc,CAAC,IAAY;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IACpF,CAAC;IAED,OAAO;QACL,MAAM,MAAM,GAAuE,EAAE,CAAC;QACtF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LaborMarket } from "./labor-market.js";
|
|
2
|
+
import type { AgentMessage, AgentEvent, AssistantMessage } from "../types.js";
|
|
3
|
+
export interface TaskResult {
|
|
4
|
+
messages: AgentMessage[];
|
|
5
|
+
lastAssistantMessage?: AssistantMessage;
|
|
6
|
+
}
|
|
7
|
+
export declare class TaskExecutor {
|
|
8
|
+
private _laborMarket;
|
|
9
|
+
private _onEvent?;
|
|
10
|
+
constructor(_laborMarket: LaborMarket, _onEvent?: ((subagentName: string, event: AgentEvent) => void) | undefined);
|
|
11
|
+
execute(subagentName: string, prompt: string): Promise<TaskResult>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// TaskExecutor — run subagent with isolated context, pipe approval back
|
|
2
|
+
export class TaskExecutor {
|
|
3
|
+
_laborMarket;
|
|
4
|
+
_onEvent;
|
|
5
|
+
constructor(_laborMarket, _onEvent) {
|
|
6
|
+
this._laborMarket = _laborMarket;
|
|
7
|
+
this._onEvent = _onEvent;
|
|
8
|
+
}
|
|
9
|
+
async execute(subagentName, prompt) {
|
|
10
|
+
const agent = this._laborMarket.get(subagentName);
|
|
11
|
+
if (!agent) {
|
|
12
|
+
throw new Error(`Subagent "${subagentName}" not found`);
|
|
13
|
+
}
|
|
14
|
+
// Subscribe to subagent events and forward them
|
|
15
|
+
let unsubscribe;
|
|
16
|
+
if (this._onEvent) {
|
|
17
|
+
const handler = this._onEvent;
|
|
18
|
+
unsubscribe = agent.subscribe((event) => handler(subagentName, event));
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const messages = await agent.prompt(prompt);
|
|
22
|
+
// Extract last assistant message as the "result"
|
|
23
|
+
let lastAssistantMessage;
|
|
24
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
25
|
+
const msg = messages[i];
|
|
26
|
+
if (msg && typeof msg === "object" && "role" in msg && msg.role === "assistant") {
|
|
27
|
+
lastAssistantMessage = msg;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { messages, lastAssistantMessage };
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
unsubscribe?.();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=task-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-executor.js","sourceRoot":"","sources":["../../src/multi-agent/task-executor.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAWxE,MAAM,OAAO,YAAY;IAEb;IACA;IAFV,YACU,YAAyB,EACzB,QAA4D;QAD5D,iBAAY,GAAZ,YAAY,CAAa;QACzB,aAAQ,GAAR,QAAQ,CAAoD;IACnE,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,YAAoB,EAAE,MAAc;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,aAAa,CAAC,CAAC;QAC1D,CAAC;QAED,gDAAgD;QAChD,IAAI,WAAqC,CAAC;QAC1C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC9B,WAAW,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAE5C,iDAAiD;YACjD,IAAI,oBAAkD,CAAC;YACvD,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACxB,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAK,GAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBACzF,oBAAoB,GAAG,GAAuB,CAAC;oBAC/C,MAAM;gBACR,CAAC;YACH,CAAC;YAED,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC;QAC5C,CAAC;gBAAS,CAAC;YACT,WAAW,EAAE,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Built-in TaskTool — allows LLM to delegate work to subagents
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
export function createTaskTool(laborMarket, taskExecutor) {
|
|
4
|
+
return {
|
|
5
|
+
name: "delegate_task",
|
|
6
|
+
label: "Delegate Task",
|
|
7
|
+
description: buildTaskToolDescription(laborMarket),
|
|
8
|
+
parameters: Type.Object({
|
|
9
|
+
subagent: Type.String({ description: "Name of the subagent to delegate to" }),
|
|
10
|
+
prompt: Type.String({ description: "The task prompt for the subagent" }),
|
|
11
|
+
}),
|
|
12
|
+
async execute(toolCallId, params, context) {
|
|
13
|
+
const { subagent, prompt } = params;
|
|
14
|
+
if (!laborMarket.has(subagent)) {
|
|
15
|
+
const available = laborMarket.listAll().map((s) => s.name).join(", ");
|
|
16
|
+
return {
|
|
17
|
+
content: [{ type: "text", text: `Unknown subagent: "${subagent}". Available: ${available || "none"}` }],
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const result = await taskExecutor.execute(subagent, prompt);
|
|
22
|
+
const responseText = result.lastAssistantMessage?.content
|
|
23
|
+
.filter((b) => b.type === "text")
|
|
24
|
+
.map((b) => b.text)
|
|
25
|
+
.join("\n") ?? "(no response)";
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text: responseText }],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
return {
|
|
32
|
+
content: [{ type: "text", text: `Subagent error: ${err instanceof Error ? err.message : String(err)}` }],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function buildTaskToolDescription(laborMarket) {
|
|
39
|
+
const agents = laborMarket.listAll();
|
|
40
|
+
if (agents.length === 0) {
|
|
41
|
+
return "Delegate a task to a subagent.";
|
|
42
|
+
}
|
|
43
|
+
const list = agents.map((a) => `- ${a.name}: ${a.description}`).join("\n");
|
|
44
|
+
return `Delegate a task to a subagent. Available subagents:\n${list}`;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=task-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-tool.js","sourceRoot":"","sources":["../../src/multi-agent/task-tool.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D,OAAO,EAAE,IAAI,EAAgB,MAAM,mBAAmB,CAAC;AAKvD,MAAM,UAAU,cAAc,CAAC,WAAwB,EAAE,YAA0B;IACjF,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE,wBAAwB,CAAC,WAAW,CAAC;QAClD,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC;YACtB,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;YAC7E,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kCAAkC,EAAE,CAAC;SACzE,CAAC;QAEF,KAAK,CAAC,OAAO,CACX,UAAkB,EAClB,MAA4C,EAC5C,OAA6B;YAE7B,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;YAEpC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtE,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,QAAQ,iBAAiB,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC;iBACxG,CAAC;YACJ,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;gBAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,oBAAoB,EAAE,OAAO;qBACtD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;qBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAAsB,CAAC,IAAI,CAAC;qBACxC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;gBAEjC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;iBAChD,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;iBACzG,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,WAAwB;IACxD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,OAAO,wDAAwD,IAAI,EAAE,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/multi-agent/types.ts"],"names":[],"mappings":"AAAA,oBAAoB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Build session context by walking the branch from root to leaf
|
|
2
|
+
export function buildSessionContext(branch) {
|
|
3
|
+
const messages = [];
|
|
4
|
+
let compactionSummary;
|
|
5
|
+
let compactionFirstKeptId = null;
|
|
6
|
+
let pastCompactionCutoff = false;
|
|
7
|
+
// First pass: find the latest compaction entry
|
|
8
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
9
|
+
const entry = branch[i];
|
|
10
|
+
if (entry.type === "compaction") {
|
|
11
|
+
compactionSummary = entry.summary;
|
|
12
|
+
compactionFirstKeptId = entry.firstKeptEntryId;
|
|
13
|
+
break;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// If no compaction, include all messages
|
|
17
|
+
if (!compactionFirstKeptId) {
|
|
18
|
+
pastCompactionCutoff = true;
|
|
19
|
+
}
|
|
20
|
+
// Second pass: build messages
|
|
21
|
+
for (const entry of branch) {
|
|
22
|
+
// If we have a compaction, skip entries before the kept point
|
|
23
|
+
if (!pastCompactionCutoff) {
|
|
24
|
+
if (entry.type === "compaction" && entry.firstKeptEntryId === compactionFirstKeptId) {
|
|
25
|
+
// This is the compaction entry — inject summary and start keeping
|
|
26
|
+
pastCompactionCutoff = true;
|
|
27
|
+
if (compactionSummary) {
|
|
28
|
+
const summaryMsg = {
|
|
29
|
+
role: "user",
|
|
30
|
+
content: `<compaction-summary>${compactionSummary}</compaction-summary>`,
|
|
31
|
+
};
|
|
32
|
+
messages.push(summaryMsg);
|
|
33
|
+
}
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
continue; // Skip pre-compaction entries
|
|
37
|
+
}
|
|
38
|
+
if (entry.type === "message") {
|
|
39
|
+
messages.push(entry.message);
|
|
40
|
+
}
|
|
41
|
+
else if (entry.type === "branch_summary") {
|
|
42
|
+
const summaryMsg = {
|
|
43
|
+
role: "user",
|
|
44
|
+
content: `[Branch summary] ${entry.summary}`,
|
|
45
|
+
};
|
|
46
|
+
messages.push(summaryMsg);
|
|
47
|
+
}
|
|
48
|
+
// checkpoint, model_change, thinking_level_change, custom — not included in LLM context
|
|
49
|
+
}
|
|
50
|
+
return { messages, compactionSummary };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=session-context-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-context-builder.js","sourceRoot":"","sources":["../../src/session/session-context-builder.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAWhE,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,IAAI,iBAAqC,CAAC;IAC1C,IAAI,qBAAqB,GAAkB,IAAI,CAAC;IAChD,IAAI,oBAAoB,GAAG,KAAK,CAAC;IAEjC,+CAA+C;IAC/C,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAChC,iBAAiB,GAAI,KAAyB,CAAC,OAAO,CAAC;YACvD,qBAAqB,GAAI,KAAyB,CAAC,gBAAgB,CAAC;YACpE,MAAM;QACR,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,oBAAoB,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,8BAA8B;IAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,8DAA8D;QAC9D,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAK,KAAyB,CAAC,gBAAgB,KAAK,qBAAqB,EAAE,CAAC;gBACzG,kEAAkE;gBAClE,oBAAoB,GAAG,IAAI,CAAC;gBAC5B,IAAI,iBAAiB,EAAE,CAAC;oBACtB,MAAM,UAAU,GAAgB;wBAC9B,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,uBAAuB,iBAAiB,uBAAuB;qBACzE,CAAC;oBACF,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC5B,CAAC;gBACD,SAAS;YACX,CAAC;YACD,SAAS,CAAC,8BAA8B;QAC1C,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CAAE,KAA6B,CAAC,OAAO,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAgB;gBAC9B,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,oBAAqB,KAA4B,CAAC,OAAO,EAAE;aACrE,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QACD,wFAAwF;IAC1F,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SessionEntry, SessionTreeNode, SessionContext, SessionConfig } from "./types.js";
|
|
2
|
+
import type { AgentMessage } from "../types.js";
|
|
3
|
+
export declare class SessionManager {
|
|
4
|
+
private _entries;
|
|
5
|
+
private _entriesById;
|
|
6
|
+
private _leafId;
|
|
7
|
+
private _sessionId;
|
|
8
|
+
private _filePath;
|
|
9
|
+
private _persist;
|
|
10
|
+
constructor(config?: SessionConfig);
|
|
11
|
+
private _initialized;
|
|
12
|
+
init(): Promise<void>;
|
|
13
|
+
appendMessage(message: AgentMessage): Promise<string>;
|
|
14
|
+
appendCompaction(summary: string, firstKeptEntryId: string, tokensBefore: number): Promise<string>;
|
|
15
|
+
appendBranchSummary(fromId: string, summary: string): Promise<string>;
|
|
16
|
+
appendModelChange(provider: string, modelId: string): Promise<string>;
|
|
17
|
+
appendThinkingLevelChange(thinkingLevel: string): Promise<string>;
|
|
18
|
+
appendCheckpoint(checkpointId: number): Promise<string>;
|
|
19
|
+
appendCustomEntry(customType: string, data?: unknown): Promise<string>;
|
|
20
|
+
getLeafId(): string | null;
|
|
21
|
+
getEntry(id: string): SessionEntry | undefined;
|
|
22
|
+
getEntries(): SessionEntry[];
|
|
23
|
+
getBranch(fromId?: string | null): SessionEntry[];
|
|
24
|
+
getTree(): SessionTreeNode[];
|
|
25
|
+
branch(branchFromId: string): void;
|
|
26
|
+
buildSessionContext(): SessionContext;
|
|
27
|
+
getSessionId(): string;
|
|
28
|
+
private _append;
|
|
29
|
+
private _load;
|
|
30
|
+
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// Session manager — JSONL tree with append, branch, navigate
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { mkdirSync, existsSync } from "node:fs";
|
|
4
|
+
import { generateId } from "../utils/id.js";
|
|
5
|
+
import { readJSONL, appendJSONL, writeJSONLHeader } from "../utils/jsonl.js";
|
|
6
|
+
import { buildSessionContext } from "./session-context-builder.js";
|
|
7
|
+
const SESSION_VERSION = 1;
|
|
8
|
+
export class SessionManager {
|
|
9
|
+
_entries = [];
|
|
10
|
+
_entriesById = new Map();
|
|
11
|
+
_leafId = null;
|
|
12
|
+
_sessionId;
|
|
13
|
+
_filePath;
|
|
14
|
+
_persist;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this._persist = config?.persist ?? false;
|
|
17
|
+
this._sessionId = config?.sessionId ?? generateId();
|
|
18
|
+
if (this._persist && config?.directory) {
|
|
19
|
+
mkdirSync(config.directory, { recursive: true });
|
|
20
|
+
this._filePath = join(config.directory, `${this._sessionId}.jsonl`);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this._filePath = null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// --- Init ---
|
|
27
|
+
_initialized = false;
|
|
28
|
+
async init() {
|
|
29
|
+
if (this._initialized)
|
|
30
|
+
return;
|
|
31
|
+
this._initialized = true;
|
|
32
|
+
if (this._filePath && existsSync(this._filePath)) {
|
|
33
|
+
await this._load();
|
|
34
|
+
}
|
|
35
|
+
else if (this._filePath) {
|
|
36
|
+
const header = {
|
|
37
|
+
type: "session",
|
|
38
|
+
version: SESSION_VERSION,
|
|
39
|
+
id: this._sessionId,
|
|
40
|
+
timestamp: new Date().toISOString(),
|
|
41
|
+
};
|
|
42
|
+
await writeJSONLHeader(this._filePath, header);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// --- Append operations ---
|
|
46
|
+
async appendMessage(message) {
|
|
47
|
+
const entry = {
|
|
48
|
+
type: "message",
|
|
49
|
+
id: generateId(),
|
|
50
|
+
parentId: this._leafId,
|
|
51
|
+
timestamp: new Date().toISOString(),
|
|
52
|
+
message,
|
|
53
|
+
};
|
|
54
|
+
return this._append(entry);
|
|
55
|
+
}
|
|
56
|
+
async appendCompaction(summary, firstKeptEntryId, tokensBefore) {
|
|
57
|
+
const entry = {
|
|
58
|
+
type: "compaction",
|
|
59
|
+
id: generateId(),
|
|
60
|
+
parentId: this._leafId,
|
|
61
|
+
timestamp: new Date().toISOString(),
|
|
62
|
+
summary,
|
|
63
|
+
firstKeptEntryId,
|
|
64
|
+
tokensBefore,
|
|
65
|
+
};
|
|
66
|
+
return this._append(entry);
|
|
67
|
+
}
|
|
68
|
+
async appendBranchSummary(fromId, summary) {
|
|
69
|
+
const entry = {
|
|
70
|
+
type: "branch_summary",
|
|
71
|
+
id: generateId(),
|
|
72
|
+
parentId: this._leafId,
|
|
73
|
+
timestamp: new Date().toISOString(),
|
|
74
|
+
fromId,
|
|
75
|
+
summary,
|
|
76
|
+
};
|
|
77
|
+
return this._append(entry);
|
|
78
|
+
}
|
|
79
|
+
async appendModelChange(provider, modelId) {
|
|
80
|
+
const entry = {
|
|
81
|
+
type: "model_change",
|
|
82
|
+
id: generateId(),
|
|
83
|
+
parentId: this._leafId,
|
|
84
|
+
timestamp: new Date().toISOString(),
|
|
85
|
+
provider,
|
|
86
|
+
modelId,
|
|
87
|
+
};
|
|
88
|
+
return this._append(entry);
|
|
89
|
+
}
|
|
90
|
+
async appendThinkingLevelChange(thinkingLevel) {
|
|
91
|
+
const entry = {
|
|
92
|
+
type: "thinking_level_change",
|
|
93
|
+
id: generateId(),
|
|
94
|
+
parentId: this._leafId,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
thinkingLevel,
|
|
97
|
+
};
|
|
98
|
+
return this._append(entry);
|
|
99
|
+
}
|
|
100
|
+
async appendCheckpoint(checkpointId) {
|
|
101
|
+
const entry = {
|
|
102
|
+
type: "checkpoint",
|
|
103
|
+
id: generateId(),
|
|
104
|
+
parentId: this._leafId,
|
|
105
|
+
timestamp: new Date().toISOString(),
|
|
106
|
+
checkpointId,
|
|
107
|
+
};
|
|
108
|
+
return this._append(entry);
|
|
109
|
+
}
|
|
110
|
+
async appendCustomEntry(customType, data) {
|
|
111
|
+
const entry = {
|
|
112
|
+
type: "custom",
|
|
113
|
+
id: generateId(),
|
|
114
|
+
parentId: this._leafId,
|
|
115
|
+
timestamp: new Date().toISOString(),
|
|
116
|
+
customType,
|
|
117
|
+
data,
|
|
118
|
+
};
|
|
119
|
+
return this._append(entry);
|
|
120
|
+
}
|
|
121
|
+
// --- Tree navigation ---
|
|
122
|
+
getLeafId() {
|
|
123
|
+
return this._leafId;
|
|
124
|
+
}
|
|
125
|
+
getEntry(id) {
|
|
126
|
+
return this._entriesById.get(id);
|
|
127
|
+
}
|
|
128
|
+
getEntries() {
|
|
129
|
+
return [...this._entries];
|
|
130
|
+
}
|
|
131
|
+
getBranch(fromId) {
|
|
132
|
+
const leafId = fromId ?? this._leafId;
|
|
133
|
+
if (!leafId)
|
|
134
|
+
return [];
|
|
135
|
+
const branch = [];
|
|
136
|
+
let currentId = leafId;
|
|
137
|
+
while (currentId) {
|
|
138
|
+
const entry = this._entriesById.get(currentId);
|
|
139
|
+
if (!entry)
|
|
140
|
+
break;
|
|
141
|
+
branch.unshift(entry);
|
|
142
|
+
currentId = entry.parentId;
|
|
143
|
+
}
|
|
144
|
+
return branch;
|
|
145
|
+
}
|
|
146
|
+
getTree() {
|
|
147
|
+
// Build tree from entries
|
|
148
|
+
const childrenMap = new Map();
|
|
149
|
+
for (const entry of this._entries) {
|
|
150
|
+
const parentId = entry.parentId;
|
|
151
|
+
if (!childrenMap.has(parentId)) {
|
|
152
|
+
childrenMap.set(parentId, []);
|
|
153
|
+
}
|
|
154
|
+
childrenMap.get(parentId).push(entry);
|
|
155
|
+
}
|
|
156
|
+
function buildNode(entry) {
|
|
157
|
+
const children = (childrenMap.get(entry.id) ?? []).map(buildNode);
|
|
158
|
+
return { entry, children };
|
|
159
|
+
}
|
|
160
|
+
// Root entries have parentId === null
|
|
161
|
+
const roots = childrenMap.get(null) ?? [];
|
|
162
|
+
return roots.map(buildNode);
|
|
163
|
+
}
|
|
164
|
+
branch(branchFromId) {
|
|
165
|
+
if (!this._entriesById.has(branchFromId)) {
|
|
166
|
+
throw new Error(`Entry ${branchFromId} not found`);
|
|
167
|
+
}
|
|
168
|
+
this._leafId = branchFromId;
|
|
169
|
+
}
|
|
170
|
+
// --- Context building ---
|
|
171
|
+
buildSessionContext() {
|
|
172
|
+
const branch = this.getBranch();
|
|
173
|
+
return buildSessionContext(branch);
|
|
174
|
+
}
|
|
175
|
+
// --- Accessors ---
|
|
176
|
+
getSessionId() {
|
|
177
|
+
return this._sessionId;
|
|
178
|
+
}
|
|
179
|
+
// --- Internal ---
|
|
180
|
+
async _append(entry) {
|
|
181
|
+
this._entries.push(entry);
|
|
182
|
+
this._entriesById.set(entry.id, entry);
|
|
183
|
+
this._leafId = entry.id;
|
|
184
|
+
if (this._filePath) {
|
|
185
|
+
await appendJSONL(this._filePath, entry);
|
|
186
|
+
}
|
|
187
|
+
return entry.id;
|
|
188
|
+
}
|
|
189
|
+
async _load() {
|
|
190
|
+
if (!this._filePath)
|
|
191
|
+
return;
|
|
192
|
+
const records = await readJSONL(this._filePath);
|
|
193
|
+
if (records.length === 0)
|
|
194
|
+
return;
|
|
195
|
+
// First record is header
|
|
196
|
+
const header = records[0];
|
|
197
|
+
if (header.type === "session") {
|
|
198
|
+
this._sessionId = header.id;
|
|
199
|
+
}
|
|
200
|
+
// Rest are entries
|
|
201
|
+
for (let i = 1; i < records.length; i++) {
|
|
202
|
+
const entry = records[i];
|
|
203
|
+
this._entries.push(entry);
|
|
204
|
+
this._entriesById.set(entry.id, entry);
|
|
205
|
+
this._leafId = entry.id;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=session-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AgentMessage } from "../types.js";
|
|
2
|
+
export interface SessionEntryBase {
|
|
3
|
+
type: string;
|
|
4
|
+
id: string;
|
|
5
|
+
parentId: string | null;
|
|
6
|
+
timestamp: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SessionHeader {
|
|
9
|
+
type: "session";
|
|
10
|
+
version: number;
|
|
11
|
+
id: string;
|
|
12
|
+
timestamp: string;
|
|
13
|
+
cwd?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SessionMessageEntry extends SessionEntryBase {
|
|
16
|
+
type: "message";
|
|
17
|
+
message: AgentMessage;
|
|
18
|
+
}
|
|
19
|
+
export interface CompactionEntry extends SessionEntryBase {
|
|
20
|
+
type: "compaction";
|
|
21
|
+
summary: string;
|
|
22
|
+
firstKeptEntryId: string;
|
|
23
|
+
tokensBefore: number;
|
|
24
|
+
}
|
|
25
|
+
export interface BranchSummaryEntry extends SessionEntryBase {
|
|
26
|
+
type: "branch_summary";
|
|
27
|
+
fromId: string;
|
|
28
|
+
summary: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ModelChangeEntry extends SessionEntryBase {
|
|
31
|
+
type: "model_change";
|
|
32
|
+
provider: string;
|
|
33
|
+
modelId: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ThinkingLevelChangeEntry extends SessionEntryBase {
|
|
36
|
+
type: "thinking_level_change";
|
|
37
|
+
thinkingLevel: string;
|
|
38
|
+
}
|
|
39
|
+
export interface CheckpointEntry extends SessionEntryBase {
|
|
40
|
+
type: "checkpoint";
|
|
41
|
+
checkpointId: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CustomEntry extends SessionEntryBase {
|
|
44
|
+
type: "custom";
|
|
45
|
+
customType: string;
|
|
46
|
+
data?: unknown;
|
|
47
|
+
}
|
|
48
|
+
export type SessionEntry = SessionMessageEntry | CompactionEntry | BranchSummaryEntry | ModelChangeEntry | ThinkingLevelChangeEntry | CheckpointEntry | CustomEntry;
|
|
49
|
+
export interface SessionTreeNode {
|
|
50
|
+
entry: SessionEntry;
|
|
51
|
+
children: SessionTreeNode[];
|
|
52
|
+
}
|
|
53
|
+
export interface SessionContext {
|
|
54
|
+
messages: AgentMessage[];
|
|
55
|
+
compactionSummary?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface SessionConfig {
|
|
58
|
+
persist?: boolean;
|
|
59
|
+
directory?: string;
|
|
60
|
+
sessionId?: string;
|
|
61
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/session/types.ts"],"names":[],"mappings":"AAAA,+CAA+C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Skill discovery — scan directories, parse frontmatter from markdown
|
|
2
|
+
import { readdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { loadSkill } from "./loader.js";
|
|
6
|
+
export async function discoverSkills(sources) {
|
|
7
|
+
const skills = [];
|
|
8
|
+
for (const source of sources) {
|
|
9
|
+
if (!existsSync(source.directory))
|
|
10
|
+
continue;
|
|
11
|
+
const pattern = source.pattern ?? ".md";
|
|
12
|
+
const files = await readdir(source.directory);
|
|
13
|
+
for (const file of files) {
|
|
14
|
+
if (!file.endsWith(pattern))
|
|
15
|
+
continue;
|
|
16
|
+
const filePath = join(source.directory, file);
|
|
17
|
+
try {
|
|
18
|
+
const skill = await loadSkill(filePath);
|
|
19
|
+
if (skill)
|
|
20
|
+
skills.push(skill);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
// Skip invalid skill files
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return skills;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/skills/discovery.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAW,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAsB;IACzD,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;YAAE,SAAS;QAE5C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAE9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YAEtC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC9C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;gBACxC,IAAI,KAAK;oBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,2BAA2B;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Skill loader — read markdown, parse frontmatter, render templates
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { basename } from "node:path";
|
|
4
|
+
const FRONTMATTER_REGEX = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
5
|
+
export async function loadSkill(filePath) {
|
|
6
|
+
const raw = await readFile(filePath, "utf-8");
|
|
7
|
+
const match = raw.match(FRONTMATTER_REGEX);
|
|
8
|
+
let frontmatter;
|
|
9
|
+
let content;
|
|
10
|
+
if (match) {
|
|
11
|
+
frontmatter = parseFrontmatter(match[1]);
|
|
12
|
+
content = match[2].trim();
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
// No frontmatter — use filename as name
|
|
16
|
+
frontmatter = { name: basename(filePath, ".md") };
|
|
17
|
+
content = raw.trim();
|
|
18
|
+
}
|
|
19
|
+
if (!content)
|
|
20
|
+
return null;
|
|
21
|
+
return {
|
|
22
|
+
name: frontmatter.name,
|
|
23
|
+
description: frontmatter.description ?? "",
|
|
24
|
+
content,
|
|
25
|
+
source: filePath,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function parseFrontmatter(raw) {
|
|
29
|
+
const result = {};
|
|
30
|
+
for (const line of raw.split("\n")) {
|
|
31
|
+
const colonIdx = line.indexOf(":");
|
|
32
|
+
if (colonIdx < 0)
|
|
33
|
+
continue;
|
|
34
|
+
const key = line.slice(0, colonIdx).trim();
|
|
35
|
+
const value = line.slice(colonIdx + 1).trim().replace(/^["']|["']$/g, "");
|
|
36
|
+
result[key] = value;
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
name: result.name ?? "unnamed",
|
|
40
|
+
description: result.description,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function renderSkillTemplate(content, vars) {
|
|
44
|
+
return content.replace(/\{\{\s*(\w+)\s*\}\}/g, (_, key) => vars[key] ?? `{{${key}}}`);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=loader.js.map
|