@mcoda/mswarm 0.1.56 → 0.1.60
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 +20 -1
- package/dist/codali-executor.d.ts +266 -0
- package/dist/codali-executor.d.ts.map +1 -0
- package/dist/codali-executor.js +227 -0
- package/dist/codali-executor.js.map +1 -0
- package/dist/runtime.d.ts +47 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +248 -30
- package/dist/runtime.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +83 -3
- package/dist/server.js.map +1 -1
- package/dist/vendor/codali/agents/AgentProtocol.d.ts +287 -0
- package/dist/vendor/codali/agents/AgentProtocol.d.ts.map +1 -0
- package/dist/vendor/codali/agents/AgentProtocol.js +365 -0
- package/dist/vendor/codali/agents/AgentResolver.d.ts +23 -0
- package/dist/vendor/codali/agents/AgentResolver.d.ts.map +1 -0
- package/dist/vendor/codali/agents/AgentResolver.js +77 -0
- package/dist/vendor/codali/agents/PhaseAgentSelector.d.ts +23 -0
- package/dist/vendor/codali/agents/PhaseAgentSelector.d.ts.map +1 -0
- package/dist/vendor/codali/agents/PhaseAgentSelector.js +287 -0
- package/dist/vendor/codali/cli/EvalCommand.d.ts +37 -0
- package/dist/vendor/codali/cli/EvalCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/EvalCommand.js +333 -0
- package/dist/vendor/codali/cli/FeedbackCommand.d.ts +22 -0
- package/dist/vendor/codali/cli/FeedbackCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/FeedbackCommand.js +163 -0
- package/dist/vendor/codali/cli/RunCommand.d.ts +78 -0
- package/dist/vendor/codali/cli/RunCommand.d.ts.map +1 -0
- package/dist/vendor/codali/cli/RunCommand.js +2261 -0
- package/dist/vendor/codali/cli.d.ts +3 -0
- package/dist/vendor/codali/cli.d.ts.map +1 -0
- package/dist/vendor/codali/cli.js +109 -0
- package/dist/vendor/codali/cognitive/ArchitectPlanner.d.ts +107 -0
- package/dist/vendor/codali/cognitive/ArchitectPlanner.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ArchitectPlanner.js +1726 -0
- package/dist/vendor/codali/cognitive/BuilderOutputParser.d.ts +25 -0
- package/dist/vendor/codali/cognitive/BuilderOutputParser.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/BuilderOutputParser.js +164 -0
- package/dist/vendor/codali/cognitive/BuilderRunner.d.ts +76 -0
- package/dist/vendor/codali/cognitive/BuilderRunner.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/BuilderRunner.js +1159 -0
- package/dist/vendor/codali/cognitive/ContextAssembler.d.ts +91 -0
- package/dist/vendor/codali/cognitive/ContextAssembler.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextAssembler.js +4547 -0
- package/dist/vendor/codali/cognitive/ContextBudget.d.ts +19 -0
- package/dist/vendor/codali/cognitive/ContextBudget.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextBudget.js +35 -0
- package/dist/vendor/codali/cognitive/ContextFileLoader.d.ts +30 -0
- package/dist/vendor/codali/cognitive/ContextFileLoader.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextFileLoader.js +307 -0
- package/dist/vendor/codali/cognitive/ContextManager.d.ts +47 -0
- package/dist/vendor/codali/cognitive/ContextManager.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextManager.js +272 -0
- package/dist/vendor/codali/cognitive/ContextRedactor.d.ts +18 -0
- package/dist/vendor/codali/cognitive/ContextRedactor.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextRedactor.js +53 -0
- package/dist/vendor/codali/cognitive/ContextSelector.d.ts +22 -0
- package/dist/vendor/codali/cognitive/ContextSelector.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextSelector.js +431 -0
- package/dist/vendor/codali/cognitive/ContextSerializer.d.ts +8 -0
- package/dist/vendor/codali/cognitive/ContextSerializer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextSerializer.js +882 -0
- package/dist/vendor/codali/cognitive/ContextStore.d.ts +27 -0
- package/dist/vendor/codali/cognitive/ContextStore.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextStore.js +79 -0
- package/dist/vendor/codali/cognitive/ContextSummarizer.d.ts +16 -0
- package/dist/vendor/codali/cognitive/ContextSummarizer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ContextSummarizer.js +45 -0
- package/dist/vendor/codali/cognitive/CostEstimator.d.ts +31 -0
- package/dist/vendor/codali/cognitive/CostEstimator.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/CostEstimator.js +66 -0
- package/dist/vendor/codali/cognitive/CriticEvaluator.d.ts +32 -0
- package/dist/vendor/codali/cognitive/CriticEvaluator.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/CriticEvaluator.js +297 -0
- package/dist/vendor/codali/cognitive/EvidenceGate.d.ts +9 -0
- package/dist/vendor/codali/cognitive/EvidenceGate.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/EvidenceGate.js +75 -0
- package/dist/vendor/codali/cognitive/GoldenExampleIndexer.d.ts +12 -0
- package/dist/vendor/codali/cognitive/GoldenExampleIndexer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/GoldenExampleIndexer.js +34 -0
- package/dist/vendor/codali/cognitive/GoldenSetStore.d.ts +33 -0
- package/dist/vendor/codali/cognitive/GoldenSetStore.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/GoldenSetStore.js +159 -0
- package/dist/vendor/codali/cognitive/IntentSignals.d.ts +7 -0
- package/dist/vendor/codali/cognitive/IntentSignals.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/IntentSignals.js +285 -0
- package/dist/vendor/codali/cognitive/LearningGovernance.d.ts +100 -0
- package/dist/vendor/codali/cognitive/LearningGovernance.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/LearningGovernance.js +276 -0
- package/dist/vendor/codali/cognitive/MemoryWriteback.d.ts +64 -0
- package/dist/vendor/codali/cognitive/MemoryWriteback.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/MemoryWriteback.js +287 -0
- package/dist/vendor/codali/cognitive/PatchApplier.d.ts +49 -0
- package/dist/vendor/codali/cognitive/PatchApplier.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/PatchApplier.js +199 -0
- package/dist/vendor/codali/cognitive/PatchInterpreter.d.ts +35 -0
- package/dist/vendor/codali/cognitive/PatchInterpreter.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/PatchInterpreter.js +100 -0
- package/dist/vendor/codali/cognitive/PatchOutputNormalizer.d.ts +7 -0
- package/dist/vendor/codali/cognitive/PatchOutputNormalizer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/PatchOutputNormalizer.js +59 -0
- package/dist/vendor/codali/cognitive/PostMortemAnalyzer.d.ts +17 -0
- package/dist/vendor/codali/cognitive/PostMortemAnalyzer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/PostMortemAnalyzer.js +131 -0
- package/dist/vendor/codali/cognitive/PreferenceExtraction.d.ts +3 -0
- package/dist/vendor/codali/cognitive/PreferenceExtraction.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/PreferenceExtraction.js +85 -0
- package/dist/vendor/codali/cognitive/Prompts.d.ts +15 -0
- package/dist/vendor/codali/cognitive/Prompts.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/Prompts.js +326 -0
- package/dist/vendor/codali/cognitive/ProviderRouting.d.ts +16 -0
- package/dist/vendor/codali/cognitive/ProviderRouting.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ProviderRouting.js +24 -0
- package/dist/vendor/codali/cognitive/QueryExtraction.d.ts +12 -0
- package/dist/vendor/codali/cognitive/QueryExtraction.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/QueryExtraction.js +262 -0
- package/dist/vendor/codali/cognitive/RunHistoryIndexer.d.ts +13 -0
- package/dist/vendor/codali/cognitive/RunHistoryIndexer.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/RunHistoryIndexer.js +125 -0
- package/dist/vendor/codali/cognitive/SmartPipeline.d.ts +92 -0
- package/dist/vendor/codali/cognitive/SmartPipeline.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/SmartPipeline.js +4804 -0
- package/dist/vendor/codali/cognitive/Types.d.ts +474 -0
- package/dist/vendor/codali/cognitive/Types.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/Types.js +7 -0
- package/dist/vendor/codali/cognitive/ValidationRunner.d.ts +57 -0
- package/dist/vendor/codali/cognitive/ValidationRunner.d.ts.map +1 -0
- package/dist/vendor/codali/cognitive/ValidationRunner.js +515 -0
- package/dist/vendor/codali/config/Config.d.ts +249 -0
- package/dist/vendor/codali/config/Config.d.ts.map +1 -0
- package/dist/vendor/codali/config/Config.js +200 -0
- package/dist/vendor/codali/config/ConfigLoader.d.ts +56 -0
- package/dist/vendor/codali/config/ConfigLoader.d.ts.map +1 -0
- package/dist/vendor/codali/config/ConfigLoader.js +1246 -0
- package/dist/vendor/codali/docdex/DocdexClient.d.ts +113 -0
- package/dist/vendor/codali/docdex/DocdexClient.d.ts.map +1 -0
- package/dist/vendor/codali/docdex/DocdexClient.js +524 -0
- package/dist/vendor/codali/eval/EvalRunner.d.ts +35 -0
- package/dist/vendor/codali/eval/EvalRunner.d.ts.map +1 -0
- package/dist/vendor/codali/eval/EvalRunner.js +38 -0
- package/dist/vendor/codali/eval/EvalTaskExecutor.d.ts +81 -0
- package/dist/vendor/codali/eval/EvalTaskExecutor.d.ts.map +1 -0
- package/dist/vendor/codali/eval/EvalTaskExecutor.js +371 -0
- package/dist/vendor/codali/eval/GateEvaluator.d.ts +31 -0
- package/dist/vendor/codali/eval/GateEvaluator.d.ts.map +1 -0
- package/dist/vendor/codali/eval/GateEvaluator.js +134 -0
- package/dist/vendor/codali/eval/MetricTypes.d.ts +28 -0
- package/dist/vendor/codali/eval/MetricTypes.d.ts.map +1 -0
- package/dist/vendor/codali/eval/MetricTypes.js +1 -0
- package/dist/vendor/codali/eval/MetricsAggregator.d.ts +4 -0
- package/dist/vendor/codali/eval/MetricsAggregator.d.ts.map +1 -0
- package/dist/vendor/codali/eval/MetricsAggregator.js +97 -0
- package/dist/vendor/codali/eval/RegressionComparator.d.ts +29 -0
- package/dist/vendor/codali/eval/RegressionComparator.d.ts.map +1 -0
- package/dist/vendor/codali/eval/RegressionComparator.js +155 -0
- package/dist/vendor/codali/eval/ReportInputAdapter.d.ts +52 -0
- package/dist/vendor/codali/eval/ReportInputAdapter.d.ts.map +1 -0
- package/dist/vendor/codali/eval/ReportInputAdapter.js +229 -0
- package/dist/vendor/codali/eval/ReportSerializer.d.ts +32 -0
- package/dist/vendor/codali/eval/ReportSerializer.d.ts.map +1 -0
- package/dist/vendor/codali/eval/ReportSerializer.js +33 -0
- package/dist/vendor/codali/eval/ReportStore.d.ts +18 -0
- package/dist/vendor/codali/eval/ReportStore.d.ts.map +1 -0
- package/dist/vendor/codali/eval/ReportStore.js +96 -0
- package/dist/vendor/codali/eval/SuiteLoader.d.ts +12 -0
- package/dist/vendor/codali/eval/SuiteLoader.d.ts.map +1 -0
- package/dist/vendor/codali/eval/SuiteLoader.js +51 -0
- package/dist/vendor/codali/eval/SuiteSchema.d.ts +56 -0
- package/dist/vendor/codali/eval/SuiteSchema.d.ts.map +1 -0
- package/dist/vendor/codali/eval/SuiteSchema.js +357 -0
- package/dist/vendor/codali/index.d.ts +11 -0
- package/dist/vendor/codali/index.d.ts.map +1 -0
- package/dist/vendor/codali/index.js +5 -0
- package/dist/vendor/codali/providers/CodexCliProvider.d.ts +8 -0
- package/dist/vendor/codali/providers/CodexCliProvider.d.ts.map +1 -0
- package/dist/vendor/codali/providers/CodexCliProvider.js +282 -0
- package/dist/vendor/codali/providers/OllamaRemoteProvider.d.ts +8 -0
- package/dist/vendor/codali/providers/OllamaRemoteProvider.d.ts.map +1 -0
- package/dist/vendor/codali/providers/OllamaRemoteProvider.js +300 -0
- package/dist/vendor/codali/providers/OpenAiCompatibleProvider.d.ts +8 -0
- package/dist/vendor/codali/providers/OpenAiCompatibleProvider.d.ts.map +1 -0
- package/dist/vendor/codali/providers/OpenAiCompatibleProvider.js +192 -0
- package/dist/vendor/codali/providers/ProviderRegistry.d.ts +12 -0
- package/dist/vendor/codali/providers/ProviderRegistry.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ProviderRegistry.js +28 -0
- package/dist/vendor/codali/providers/ProviderTypes.d.ts +81 -0
- package/dist/vendor/codali/providers/ProviderTypes.d.ts.map +1 -0
- package/dist/vendor/codali/providers/ProviderTypes.js +1 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts +183 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/CodaliRuntime.js +1363 -0
- package/dist/vendor/codali/runtime/DeepInvestigationErrors.d.ts +39 -0
- package/dist/vendor/codali/runtime/DeepInvestigationErrors.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/DeepInvestigationErrors.js +57 -0
- package/dist/vendor/codali/runtime/RunContext.d.ts +27 -0
- package/dist/vendor/codali/runtime/RunContext.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RunContext.js +51 -0
- package/dist/vendor/codali/runtime/RunLogQuery.d.ts +48 -0
- package/dist/vendor/codali/runtime/RunLogQuery.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RunLogQuery.js +36 -0
- package/dist/vendor/codali/runtime/RunLogReader.d.ts +19 -0
- package/dist/vendor/codali/runtime/RunLogReader.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RunLogReader.js +361 -0
- package/dist/vendor/codali/runtime/RunLogger.d.ts +71 -0
- package/dist/vendor/codali/runtime/RunLogger.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RunLogger.js +100 -0
- package/dist/vendor/codali/runtime/RunTelemetryTypes.d.ts +117 -0
- package/dist/vendor/codali/runtime/RunTelemetryTypes.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/RunTelemetryTypes.js +299 -0
- package/dist/vendor/codali/runtime/Runner.d.ts +66 -0
- package/dist/vendor/codali/runtime/Runner.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/Runner.js +215 -0
- package/dist/vendor/codali/runtime/StoragePaths.d.ts +3 -0
- package/dist/vendor/codali/runtime/StoragePaths.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/StoragePaths.js +19 -0
- package/dist/vendor/codali/runtime/WorkspaceLock.d.ts +30 -0
- package/dist/vendor/codali/runtime/WorkspaceLock.d.ts.map +1 -0
- package/dist/vendor/codali/runtime/WorkspaceLock.js +141 -0
- package/dist/vendor/codali/session/InstructionLoader.d.ts +14 -0
- package/dist/vendor/codali/session/InstructionLoader.d.ts.map +1 -0
- package/dist/vendor/codali/session/InstructionLoader.js +107 -0
- package/dist/vendor/codali/session/SessionStore.d.ts +81 -0
- package/dist/vendor/codali/session/SessionStore.d.ts.map +1 -0
- package/dist/vendor/codali/session/SessionStore.js +244 -0
- package/dist/vendor/codali/subagents/SubagentOrchestrator.d.ts +68 -0
- package/dist/vendor/codali/subagents/SubagentOrchestrator.d.ts.map +1 -0
- package/dist/vendor/codali/subagents/SubagentOrchestrator.js +150 -0
- package/dist/vendor/codali/tools/ToolRegistry.d.ts +9 -0
- package/dist/vendor/codali/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/vendor/codali/tools/ToolRegistry.js +263 -0
- package/dist/vendor/codali/tools/ToolTypes.d.ts +66 -0
- package/dist/vendor/codali/tools/ToolTypes.d.ts.map +1 -0
- package/dist/vendor/codali/tools/ToolTypes.js +32 -0
- package/dist/vendor/codali/tools/diff/DiffTool.d.ts +3 -0
- package/dist/vendor/codali/tools/diff/DiffTool.d.ts.map +1 -0
- package/dist/vendor/codali/tools/diff/DiffTool.js +34 -0
- package/dist/vendor/codali/tools/docdex/DocdexTools.d.ts +4 -0
- package/dist/vendor/codali/tools/docdex/DocdexTools.d.ts.map +1 -0
- package/dist/vendor/codali/tools/docdex/DocdexTools.js +453 -0
- package/dist/vendor/codali/tools/filesystem/FileTools.d.ts +3 -0
- package/dist/vendor/codali/tools/filesystem/FileTools.d.ts.map +1 -0
- package/dist/vendor/codali/tools/filesystem/FileTools.js +141 -0
- package/dist/vendor/codali/tools/search/SearchTool.d.ts +3 -0
- package/dist/vendor/codali/tools/search/SearchTool.d.ts.map +1 -0
- package/dist/vendor/codali/tools/search/SearchTool.js +46 -0
- package/dist/vendor/codali/tools/shell/ShellTool.d.ts +3 -0
- package/dist/vendor/codali/tools/shell/ShellTool.d.ts.map +1 -0
- package/dist/vendor/codali/tools/shell/ShellTool.js +104 -0
- package/package.json +5 -3
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const DEFAULT_SESSION_STORAGE_DIR = ".mcoda/codali/sessions";
|
|
5
|
+
const safeId = (value) => {
|
|
6
|
+
const safe = value.replace(/[^a-zA-Z0-9._-]+/g, "_").slice(0, 120);
|
|
7
|
+
if (!safe)
|
|
8
|
+
throw new Error("Session id must contain at least one safe character");
|
|
9
|
+
return safe;
|
|
10
|
+
};
|
|
11
|
+
const parseJsonLines = (content) => {
|
|
12
|
+
if (!content.trim())
|
|
13
|
+
return [];
|
|
14
|
+
return content
|
|
15
|
+
.split("\n")
|
|
16
|
+
.map((line) => line.trim())
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.map((line) => JSON.parse(line));
|
|
19
|
+
};
|
|
20
|
+
const nowIso = () => new Date().toISOString();
|
|
21
|
+
const shortJson = (value, maxLength = 400) => {
|
|
22
|
+
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
23
|
+
if (!text)
|
|
24
|
+
return "";
|
|
25
|
+
return text.length > maxLength ? `${text.slice(0, maxLength)}...` : text;
|
|
26
|
+
};
|
|
27
|
+
const summarizeEvents = (metadata, events) => {
|
|
28
|
+
const counts = new Map();
|
|
29
|
+
for (const event of events)
|
|
30
|
+
counts.set(event.type, (counts.get(event.type) ?? 0) + 1);
|
|
31
|
+
const highlights = [];
|
|
32
|
+
for (const event of events.slice(-20)) {
|
|
33
|
+
if (event.type === "final" && typeof event.data.content === "string") {
|
|
34
|
+
highlights.push(`Final: ${shortJson(event.data.content, 240)}`);
|
|
35
|
+
}
|
|
36
|
+
else if (event.type === "tool_result") {
|
|
37
|
+
highlights.push(`Tool ${String(event.data.name ?? "unknown")}: ${String(event.data.ok ?? "unknown")}`);
|
|
38
|
+
}
|
|
39
|
+
else if (event.type === "subagent_result") {
|
|
40
|
+
highlights.push(`Subagent ${String(event.data.role ?? "unknown")}: ${String(event.data.status ?? "unknown")}`);
|
|
41
|
+
}
|
|
42
|
+
else if (event.type === "error") {
|
|
43
|
+
highlights.push(`Error: ${shortJson(event.data.message, 240)}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const countText = Array.from(counts.entries())
|
|
47
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
48
|
+
.map(([type, count]) => `${type}=${count}`)
|
|
49
|
+
.join(", ");
|
|
50
|
+
return {
|
|
51
|
+
summary: [
|
|
52
|
+
`Task: ${metadata.task}`,
|
|
53
|
+
`Status: ${metadata.status}`,
|
|
54
|
+
`Runs: ${metadata.runIds.join(", ") || "none"}`,
|
|
55
|
+
`Events: ${countText || "none"}`,
|
|
56
|
+
highlights.length ? `Recent highlights: ${highlights.join(" | ")}` : "Recent highlights: none",
|
|
57
|
+
].join("\n"),
|
|
58
|
+
highlights,
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export class SessionStore {
|
|
62
|
+
constructor(options) {
|
|
63
|
+
this.lastTimestampMs = 0;
|
|
64
|
+
this.workspaceRoot = path.resolve(options.workspaceRoot);
|
|
65
|
+
this.storageDir = options.storageDir ?? DEFAULT_SESSION_STORAGE_DIR;
|
|
66
|
+
}
|
|
67
|
+
rootDir() {
|
|
68
|
+
const resolved = path.resolve(this.workspaceRoot, this.storageDir);
|
|
69
|
+
const relative = path.relative(this.workspaceRoot, resolved);
|
|
70
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
71
|
+
throw new Error("Session storage path is outside workspace root");
|
|
72
|
+
}
|
|
73
|
+
return resolved;
|
|
74
|
+
}
|
|
75
|
+
sessionDir(sessionId) {
|
|
76
|
+
return path.join(this.rootDir(), safeId(sessionId));
|
|
77
|
+
}
|
|
78
|
+
metadataPath(sessionId) {
|
|
79
|
+
return path.join(this.sessionDir(sessionId), "metadata.json");
|
|
80
|
+
}
|
|
81
|
+
transcriptPath(sessionId) {
|
|
82
|
+
return path.join(this.sessionDir(sessionId), "transcript.jsonl");
|
|
83
|
+
}
|
|
84
|
+
summariesDir(sessionId) {
|
|
85
|
+
return path.join(this.sessionDir(sessionId), "summaries");
|
|
86
|
+
}
|
|
87
|
+
nextTimestampIso(after) {
|
|
88
|
+
const afterMs = after ? Date.parse(after) : Number.NaN;
|
|
89
|
+
const timestampMs = Math.max(Date.now(), this.lastTimestampMs + 1, Number.isFinite(afterMs) ? afterMs + 1 : 0);
|
|
90
|
+
this.lastTimestampMs = timestampMs;
|
|
91
|
+
return new Date(timestampMs).toISOString();
|
|
92
|
+
}
|
|
93
|
+
async createSession(input) {
|
|
94
|
+
const sessionId = input.sessionId ? safeId(input.sessionId) : randomUUID();
|
|
95
|
+
const createdAt = this.nextTimestampIso();
|
|
96
|
+
const metadata = {
|
|
97
|
+
schemaVersion: 1,
|
|
98
|
+
sessionId,
|
|
99
|
+
repoRoot: input.repoRoot,
|
|
100
|
+
task: input.task,
|
|
101
|
+
status: input.status ?? "active",
|
|
102
|
+
branch: input.branch,
|
|
103
|
+
parentSessionId: input.parentSessionId,
|
|
104
|
+
runIds: [],
|
|
105
|
+
transcriptRefs: ["transcript.jsonl"],
|
|
106
|
+
summaryRefs: [],
|
|
107
|
+
contextLaneRefs: input.contextLaneRefs ?? [],
|
|
108
|
+
instructionSources: input.instructionSources ?? [],
|
|
109
|
+
createdAt,
|
|
110
|
+
updatedAt: createdAt,
|
|
111
|
+
};
|
|
112
|
+
await fs.mkdir(this.sessionDir(sessionId), { recursive: true });
|
|
113
|
+
await fs.writeFile(this.metadataPath(sessionId), `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
|
|
114
|
+
return metadata;
|
|
115
|
+
}
|
|
116
|
+
async readSession(sessionId) {
|
|
117
|
+
const content = await fs.readFile(this.metadataPath(sessionId), "utf8");
|
|
118
|
+
return JSON.parse(content);
|
|
119
|
+
}
|
|
120
|
+
async getOrCreateSession(input) {
|
|
121
|
+
if (input.sessionId) {
|
|
122
|
+
try {
|
|
123
|
+
return await this.readSession(input.sessionId);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "ENOENT") {
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return this.createSession(input);
|
|
132
|
+
}
|
|
133
|
+
async updateSession(sessionId, patch) {
|
|
134
|
+
const current = await this.readSession(sessionId);
|
|
135
|
+
const next = {
|
|
136
|
+
...current,
|
|
137
|
+
...patch,
|
|
138
|
+
runIds: patch.runIds ?? current.runIds,
|
|
139
|
+
transcriptRefs: patch.transcriptRefs ?? current.transcriptRefs,
|
|
140
|
+
summaryRefs: patch.summaryRefs ?? current.summaryRefs,
|
|
141
|
+
contextLaneRefs: patch.contextLaneRefs ?? current.contextLaneRefs,
|
|
142
|
+
instructionSources: patch.instructionSources ?? current.instructionSources,
|
|
143
|
+
updatedAt: this.nextTimestampIso(current.updatedAt),
|
|
144
|
+
};
|
|
145
|
+
await fs.writeFile(this.metadataPath(sessionId), `${JSON.stringify(next, null, 2)}\n`, "utf8");
|
|
146
|
+
return next;
|
|
147
|
+
}
|
|
148
|
+
async addRun(sessionId, runId) {
|
|
149
|
+
const current = await this.readSession(sessionId);
|
|
150
|
+
if (current.runIds.includes(runId))
|
|
151
|
+
return current;
|
|
152
|
+
return this.updateSession(sessionId, { runIds: [...current.runIds, runId] });
|
|
153
|
+
}
|
|
154
|
+
async appendTranscript(sessionId, event) {
|
|
155
|
+
const record = {
|
|
156
|
+
schemaVersion: 1,
|
|
157
|
+
sessionId,
|
|
158
|
+
type: event.type,
|
|
159
|
+
timestamp: event.timestamp ?? nowIso(),
|
|
160
|
+
runId: event.runId,
|
|
161
|
+
data: event.data,
|
|
162
|
+
};
|
|
163
|
+
const transcriptPath = this.transcriptPath(sessionId);
|
|
164
|
+
await fs.mkdir(path.dirname(transcriptPath), { recursive: true });
|
|
165
|
+
await fs.appendFile(transcriptPath, `${JSON.stringify(record)}\n`, "utf8");
|
|
166
|
+
await this.updateSession(sessionId, {});
|
|
167
|
+
return record;
|
|
168
|
+
}
|
|
169
|
+
async readTranscript(sessionId) {
|
|
170
|
+
try {
|
|
171
|
+
const content = await fs.readFile(this.transcriptPath(sessionId), "utf8");
|
|
172
|
+
return parseJsonLines(content);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
throw error;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async listSessions() {
|
|
182
|
+
let entries;
|
|
183
|
+
try {
|
|
184
|
+
entries = await fs.readdir(this.rootDir());
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
188
|
+
return [];
|
|
189
|
+
}
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
192
|
+
const sessions = [];
|
|
193
|
+
for (const entry of entries) {
|
|
194
|
+
try {
|
|
195
|
+
sessions.push(await this.readSession(entry));
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Ignore incomplete session directories.
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
202
|
+
}
|
|
203
|
+
async compactSession(sessionId) {
|
|
204
|
+
const metadata = await this.readSession(sessionId);
|
|
205
|
+
const events = await this.readTranscript(sessionId);
|
|
206
|
+
const createdAt = nowIso();
|
|
207
|
+
const compacted = summarizeEvents(metadata, events);
|
|
208
|
+
const summary = {
|
|
209
|
+
schemaVersion: 1,
|
|
210
|
+
sessionId,
|
|
211
|
+
createdAt,
|
|
212
|
+
eventCount: events.length,
|
|
213
|
+
...compacted,
|
|
214
|
+
};
|
|
215
|
+
const summariesDir = this.summariesDir(sessionId);
|
|
216
|
+
await fs.mkdir(summariesDir, { recursive: true });
|
|
217
|
+
const fileName = `${createdAt.replace(/[^0-9T]/g, "").slice(0, 15)}-${events.length}.json`;
|
|
218
|
+
const filePath = path.join(summariesDir, fileName);
|
|
219
|
+
await fs.writeFile(filePath, `${JSON.stringify(summary, null, 2)}\n`, "utf8");
|
|
220
|
+
const relativeRef = path.relative(this.sessionDir(sessionId), filePath);
|
|
221
|
+
await this.updateSession(sessionId, {
|
|
222
|
+
summaryRefs: [...metadata.summaryRefs, relativeRef],
|
|
223
|
+
});
|
|
224
|
+
return summary;
|
|
225
|
+
}
|
|
226
|
+
async readLatestSummary(sessionId) {
|
|
227
|
+
const metadata = await this.readSession(sessionId);
|
|
228
|
+
const latest = metadata.summaryRefs.at(-1);
|
|
229
|
+
if (!latest)
|
|
230
|
+
return undefined;
|
|
231
|
+
const content = await fs.readFile(path.join(this.sessionDir(sessionId), latest), "utf8");
|
|
232
|
+
return JSON.parse(content);
|
|
233
|
+
}
|
|
234
|
+
async buildResumeBundle(sessionId, options = {}) {
|
|
235
|
+
const metadata = await this.readSession(sessionId);
|
|
236
|
+
const transcript = await this.readTranscript(sessionId);
|
|
237
|
+
const recentCount = Math.max(0, options.recentEvents ?? 20);
|
|
238
|
+
return {
|
|
239
|
+
metadata,
|
|
240
|
+
latestSummary: await this.readLatestSummary(sessionId),
|
|
241
|
+
recentEvents: recentCount ? transcript.slice(-recentCount) : [],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export type SubagentRole = "explorer" | "reviewer" | "worker" | "verifier" | "custom";
|
|
2
|
+
export type SubagentStatus = "completed" | "failed" | "timed_out";
|
|
3
|
+
export interface SubagentPermissions {
|
|
4
|
+
readOnly?: boolean;
|
|
5
|
+
allowedPaths?: string[];
|
|
6
|
+
writePaths?: string[];
|
|
7
|
+
allowNetwork?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface SubagentSpec {
|
|
10
|
+
id?: string;
|
|
11
|
+
role: SubagentRole;
|
|
12
|
+
goal: string;
|
|
13
|
+
agentRef?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
tools?: string[];
|
|
16
|
+
permissions?: SubagentPermissions;
|
|
17
|
+
maxSteps?: number;
|
|
18
|
+
maxToolCalls?: number;
|
|
19
|
+
timeoutMs?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SubagentResult {
|
|
22
|
+
id: string;
|
|
23
|
+
role: SubagentRole;
|
|
24
|
+
goal: string;
|
|
25
|
+
status: SubagentStatus;
|
|
26
|
+
summary: string;
|
|
27
|
+
output: string;
|
|
28
|
+
toolCallsExecuted: number;
|
|
29
|
+
touchedFiles: string[];
|
|
30
|
+
warnings: string[];
|
|
31
|
+
startedAt: string;
|
|
32
|
+
endedAt: string;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
error?: string;
|
|
35
|
+
metadata?: Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface SubagentRunnerInput {
|
|
38
|
+
spec: Required<Pick<SubagentSpec, "id" | "role" | "goal">> & SubagentSpec;
|
|
39
|
+
parentRunId: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SubagentRunnerResult {
|
|
42
|
+
output: string;
|
|
43
|
+
toolCallsExecuted?: number;
|
|
44
|
+
touchedFiles?: string[];
|
|
45
|
+
warnings?: string[];
|
|
46
|
+
metadata?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
export type SubagentRunner = (input: SubagentRunnerInput) => Promise<SubagentRunnerResult>;
|
|
49
|
+
export interface SubagentOrchestratorOptions {
|
|
50
|
+
parentRunId: string;
|
|
51
|
+
maxParallel?: number;
|
|
52
|
+
maxSubagents?: number;
|
|
53
|
+
defaultTimeoutMs?: number;
|
|
54
|
+
runner: SubagentRunner;
|
|
55
|
+
onEvent?: (event: {
|
|
56
|
+
type: "subagent_start" | "subagent_result";
|
|
57
|
+
result?: SubagentResult;
|
|
58
|
+
spec?: SubagentSpec;
|
|
59
|
+
}) => void;
|
|
60
|
+
}
|
|
61
|
+
export declare const normalizeSubagentSpec: (spec: SubagentSpec, index: number) => SubagentRunnerInput["spec"];
|
|
62
|
+
export declare const assertNoOverlappingWriteScopes: (specs: SubagentSpec[]) => void;
|
|
63
|
+
export declare class SubagentOrchestrator {
|
|
64
|
+
private options;
|
|
65
|
+
constructor(options: SubagentOrchestratorOptions);
|
|
66
|
+
run(specs: SubagentSpec[]): Promise<SubagentResult[]>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=SubagentOrchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubagentOrchestrator.d.ts","sourceRoot":"","sources":["../../src/subagents/SubagentOrchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
const normalizeScopePath = (value) => {
|
|
3
|
+
const normalized = path.posix.normalize(value.replace(/\\/g, "/")).replace(/^\/+/, "");
|
|
4
|
+
if (!normalized || normalized === ".")
|
|
5
|
+
return ".";
|
|
6
|
+
if (normalized === ".." || normalized.startsWith("../")) {
|
|
7
|
+
throw new Error(`Subagent scope path is outside workspace: ${value}`);
|
|
8
|
+
}
|
|
9
|
+
return normalized;
|
|
10
|
+
};
|
|
11
|
+
const scopeContains = (outer, inner) => {
|
|
12
|
+
if (outer === ".")
|
|
13
|
+
return true;
|
|
14
|
+
return inner === outer || inner.startsWith(`${outer}/`);
|
|
15
|
+
};
|
|
16
|
+
const scopesOverlap = (a, b) => scopeContains(a, b) || scopeContains(b, a);
|
|
17
|
+
const stableSpecId = (spec, index) => {
|
|
18
|
+
if (spec.id?.trim())
|
|
19
|
+
return spec.id.trim().replace(/[^a-zA-Z0-9._-]+/g, "_");
|
|
20
|
+
return `${spec.role}-${index + 1}`;
|
|
21
|
+
};
|
|
22
|
+
const summarizeOutput = (output) => {
|
|
23
|
+
const trimmed = output.trim().replace(/\s+/g, " ");
|
|
24
|
+
if (!trimmed)
|
|
25
|
+
return "No output.";
|
|
26
|
+
return trimmed.length > 240 ? `${trimmed.slice(0, 240)}...` : trimmed;
|
|
27
|
+
};
|
|
28
|
+
const withTimeout = async (promise, timeoutMs) => {
|
|
29
|
+
if (!timeoutMs || timeoutMs <= 0)
|
|
30
|
+
return promise;
|
|
31
|
+
let timeoutId;
|
|
32
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
33
|
+
timeoutId = setTimeout(() => reject(new Error("subagent_timeout")), timeoutMs);
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
if (timeoutId)
|
|
40
|
+
clearTimeout(timeoutId);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export const normalizeSubagentSpec = (spec, index) => {
|
|
44
|
+
if (!spec.goal.trim())
|
|
45
|
+
throw new Error("Subagent goal is required");
|
|
46
|
+
const readOnly = spec.permissions?.readOnly ?? spec.role !== "worker";
|
|
47
|
+
const allowedPaths = spec.permissions?.allowedPaths?.map(normalizeScopePath);
|
|
48
|
+
const writePaths = spec.permissions?.writePaths?.map(normalizeScopePath);
|
|
49
|
+
if (readOnly && writePaths?.length) {
|
|
50
|
+
throw new Error(`Read-only subagent ${spec.id ?? spec.role} cannot declare write paths`);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
...spec,
|
|
54
|
+
id: stableSpecId(spec, index),
|
|
55
|
+
role: spec.role,
|
|
56
|
+
goal: spec.goal.trim(),
|
|
57
|
+
permissions: {
|
|
58
|
+
...spec.permissions,
|
|
59
|
+
readOnly,
|
|
60
|
+
allowedPaths,
|
|
61
|
+
writePaths,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export const assertNoOverlappingWriteScopes = (specs) => {
|
|
66
|
+
const writers = specs
|
|
67
|
+
.map((spec, index) => normalizeSubagentSpec(spec, index))
|
|
68
|
+
.filter((spec) => !spec.permissions?.readOnly && (spec.permissions?.writePaths?.length ?? 0) > 0);
|
|
69
|
+
for (let left = 0; left < writers.length; left += 1) {
|
|
70
|
+
for (let right = left + 1; right < writers.length; right += 1) {
|
|
71
|
+
for (const leftScope of writers[left].permissions?.writePaths ?? []) {
|
|
72
|
+
for (const rightScope of writers[right].permissions?.writePaths ?? []) {
|
|
73
|
+
if (scopesOverlap(leftScope, rightScope)) {
|
|
74
|
+
throw new Error(`Subagent write scopes overlap: ${writers[left].id}:${leftScope} and ${writers[right].id}:${rightScope}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
export class SubagentOrchestrator {
|
|
82
|
+
constructor(options) {
|
|
83
|
+
this.options = options;
|
|
84
|
+
}
|
|
85
|
+
async run(specs) {
|
|
86
|
+
const maxSubagents = Math.max(1, this.options.maxSubagents ?? 8);
|
|
87
|
+
if (specs.length > maxSubagents) {
|
|
88
|
+
throw new Error(`Too many subagents requested: ${specs.length} > ${maxSubagents}`);
|
|
89
|
+
}
|
|
90
|
+
assertNoOverlappingWriteScopes(specs);
|
|
91
|
+
const normalized = specs.map(normalizeSubagentSpec);
|
|
92
|
+
const maxParallel = Math.max(1, this.options.maxParallel ?? 2);
|
|
93
|
+
const results = new Array(normalized.length);
|
|
94
|
+
let nextIndex = 0;
|
|
95
|
+
const runOne = async (index) => {
|
|
96
|
+
const spec = normalized[index];
|
|
97
|
+
const started = Date.now();
|
|
98
|
+
const startedAt = new Date(started).toISOString();
|
|
99
|
+
this.options.onEvent?.({ type: "subagent_start", spec });
|
|
100
|
+
try {
|
|
101
|
+
const runnerResult = await withTimeout(this.options.runner({ spec, parentRunId: this.options.parentRunId }), spec.timeoutMs ?? this.options.defaultTimeoutMs);
|
|
102
|
+
const ended = Date.now();
|
|
103
|
+
results[index] = {
|
|
104
|
+
id: spec.id,
|
|
105
|
+
role: spec.role,
|
|
106
|
+
goal: spec.goal,
|
|
107
|
+
status: "completed",
|
|
108
|
+
summary: summarizeOutput(runnerResult.output),
|
|
109
|
+
output: runnerResult.output,
|
|
110
|
+
toolCallsExecuted: runnerResult.toolCallsExecuted ?? 0,
|
|
111
|
+
touchedFiles: runnerResult.touchedFiles ?? [],
|
|
112
|
+
warnings: runnerResult.warnings ?? [],
|
|
113
|
+
startedAt,
|
|
114
|
+
endedAt: new Date(ended).toISOString(),
|
|
115
|
+
durationMs: ended - started,
|
|
116
|
+
metadata: runnerResult.metadata,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
const ended = Date.now();
|
|
121
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
122
|
+
results[index] = {
|
|
123
|
+
id: spec.id,
|
|
124
|
+
role: spec.role,
|
|
125
|
+
goal: spec.goal,
|
|
126
|
+
status: message === "subagent_timeout" ? "timed_out" : "failed",
|
|
127
|
+
summary: message,
|
|
128
|
+
output: "",
|
|
129
|
+
toolCallsExecuted: 0,
|
|
130
|
+
touchedFiles: [],
|
|
131
|
+
warnings: [],
|
|
132
|
+
startedAt,
|
|
133
|
+
endedAt: new Date(ended).toISOString(),
|
|
134
|
+
durationMs: ended - started,
|
|
135
|
+
error: message,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
this.options.onEvent?.({ type: "subagent_result", result: results[index] });
|
|
139
|
+
};
|
|
140
|
+
const workers = Array.from({ length: Math.min(maxParallel, normalized.length) }, async () => {
|
|
141
|
+
while (nextIndex < normalized.length) {
|
|
142
|
+
const index = nextIndex;
|
|
143
|
+
nextIndex += 1;
|
|
144
|
+
await runOne(index);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
await Promise.all(workers);
|
|
148
|
+
return results;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ToolContext, type ToolDefinition, type ToolExecutionResult } from "./ToolTypes.js";
|
|
2
|
+
export declare class ToolRegistry {
|
|
3
|
+
private tools;
|
|
4
|
+
register(tool: ToolDefinition): void;
|
|
5
|
+
list(): ToolDefinition[];
|
|
6
|
+
describe(): Array<Pick<ToolDefinition, "name" | "description" | "inputSchema">>;
|
|
7
|
+
execute(name: string, args: unknown, context: ToolContext): Promise<ToolExecutionResult>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ToolRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../src/tools/ToolRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,cAAc,EAGnB,KAAK,mBAAmB,EAGzB,MAAM,gBAAgB,CAAC;AAyOxB,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAqC;IAElD,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAOpC,IAAI,IAAI,cAAc,EAAE;IAIxB,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,CAAC,CAAC;IAQzE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAkC/F"}
|