@roarpeng/graphflow 0.6.5
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/AGENTS.md +58 -0
- package/CHANGELOG.md +205 -0
- package/CLAUDE.md +39 -0
- package/LICENSE +17 -0
- package/README.md +434 -0
- package/dist/agents/brainstormer.d.ts +5 -0
- package/dist/agents/brainstormer.d.ts.map +1 -0
- package/dist/agents/brainstormer.js +61 -0
- package/dist/agents/brainstormer.js.map +1 -0
- package/dist/agents/planner.d.ts +14 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +166 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/validator.d.ts +6 -0
- package/dist/agents/validator.d.ts.map +1 -0
- package/dist/agents/validator.js +133 -0
- package/dist/agents/validator.js.map +1 -0
- package/dist/agents/worker.d.ts +18 -0
- package/dist/agents/worker.d.ts.map +1 -0
- package/dist/agents/worker.js +34 -0
- package/dist/agents/worker.js.map +1 -0
- package/dist/config/defaults.d.ts +16 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +85 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/embedding-factory.d.ts +4 -0
- package/dist/config/embedding-factory.d.ts.map +1 -0
- package/dist/config/embedding-factory.js +37 -0
- package/dist/config/embedding-factory.js.map +1 -0
- package/dist/config/loader.d.ts +4 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +194 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +6 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +130 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/paths.d.ts +6 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +32 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/resolve.d.ts +4 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/resolve.js +45 -0
- package/dist/config/resolve.js.map +1 -0
- package/dist/config/scaffold.d.ts +11 -0
- package/dist/config/scaffold.d.ts.map +1 -0
- package/dist/config/scaffold.js +42 -0
- package/dist/config/scaffold.js.map +1 -0
- package/dist/config/schema.d.ts +102 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +3 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/secrets.d.ts +9 -0
- package/dist/config/secrets.d.ts.map +1 -0
- package/dist/config/secrets.js +55 -0
- package/dist/config/secrets.js.map +1 -0
- package/dist/core/dag-engine.d.ts +14 -0
- package/dist/core/dag-engine.d.ts.map +1 -0
- package/dist/core/dag-engine.js +97 -0
- package/dist/core/dag-engine.js.map +1 -0
- package/dist/core/errors.d.ts +15 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +29 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/orchestrator.d.ts +31 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +321 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/state-machine.d.ts +14 -0
- package/dist/core/state-machine.d.ts.map +1 -0
- package/dist/core/state-machine.js +77 -0
- package/dist/core/state-machine.js.map +1 -0
- package/dist/core/triage.d.ts +6 -0
- package/dist/core/triage.d.ts.map +1 -0
- package/dist/core/triage.js +58 -0
- package/dist/core/triage.js.map +1 -0
- package/dist/core/types.d.ts +61 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/graph/client-factory.d.ts +22 -0
- package/dist/graph/client-factory.d.ts.map +1 -0
- package/dist/graph/client-factory.js +60 -0
- package/dist/graph/client-factory.js.map +1 -0
- package/dist/graph/context-slicer.d.ts +47 -0
- package/dist/graph/context-slicer.d.ts.map +1 -0
- package/dist/graph/context-slicer.js +246 -0
- package/dist/graph/context-slicer.js.map +1 -0
- package/dist/graph/file-indexer.d.ts +15 -0
- package/dist/graph/file-indexer.d.ts.map +1 -0
- package/dist/graph/file-indexer.js +343 -0
- package/dist/graph/file-indexer.js.map +1 -0
- package/dist/graph/graph-indexer.d.ts +7 -0
- package/dist/graph/graph-indexer.d.ts.map +1 -0
- package/dist/graph/graph-indexer.js +32 -0
- package/dist/graph/graph-indexer.js.map +1 -0
- package/dist/graph/graphify-client.d.ts +30 -0
- package/dist/graph/graphify-client.d.ts.map +1 -0
- package/dist/graph/graphify-client.js +186 -0
- package/dist/graph/graphify-client.js.map +1 -0
- package/dist/graph/graphify-file-client.d.ts +26 -0
- package/dist/graph/graphify-file-client.d.ts.map +1 -0
- package/dist/graph/graphify-file-client.js +140 -0
- package/dist/graph/graphify-file-client.js.map +1 -0
- package/dist/graph/graphify-mcp-client.d.ts +18 -0
- package/dist/graph/graphify-mcp-client.d.ts.map +1 -0
- package/dist/graph/graphify-mcp-client.js +73 -0
- package/dist/graph/graphify-mcp-client.js.map +1 -0
- package/dist/graph/language-indexers/c-cpp.d.ts +3 -0
- package/dist/graph/language-indexers/c-cpp.d.ts.map +1 -0
- package/dist/graph/language-indexers/c-cpp.js +121 -0
- package/dist/graph/language-indexers/c-cpp.js.map +1 -0
- package/dist/graph/language-indexers/go.d.ts +3 -0
- package/dist/graph/language-indexers/go.d.ts.map +1 -0
- package/dist/graph/language-indexers/go.js +97 -0
- package/dist/graph/language-indexers/go.js.map +1 -0
- package/dist/graph/language-indexers/index.d.ts +29 -0
- package/dist/graph/language-indexers/index.d.ts.map +1 -0
- package/dist/graph/language-indexers/index.js +27 -0
- package/dist/graph/language-indexers/index.js.map +1 -0
- package/dist/graph/language-indexers/python.d.ts +3 -0
- package/dist/graph/language-indexers/python.d.ts.map +1 -0
- package/dist/graph/language-indexers/python.js +91 -0
- package/dist/graph/language-indexers/python.js.map +1 -0
- package/dist/graph/language-indexers/rust.d.ts +3 -0
- package/dist/graph/language-indexers/rust.d.ts.map +1 -0
- package/dist/graph/language-indexers/rust.js +99 -0
- package/dist/graph/language-indexers/rust.js.map +1 -0
- package/dist/graph/language-indexers/tree-sitter-loader.d.ts +18 -0
- package/dist/graph/language-indexers/tree-sitter-loader.d.ts.map +1 -0
- package/dist/graph/language-indexers/tree-sitter-loader.js +34 -0
- package/dist/graph/language-indexers/tree-sitter-loader.js.map +1 -0
- package/dist/graph/language-indexers/typescript.d.ts +3 -0
- package/dist/graph/language-indexers/typescript.d.ts.map +1 -0
- package/dist/graph/language-indexers/typescript.js +194 -0
- package/dist/graph/language-indexers/typescript.js.map +1 -0
- package/dist/graph/semantic-enricher.d.ts +17 -0
- package/dist/graph/semantic-enricher.d.ts.map +1 -0
- package/dist/graph/semantic-enricher.js +97 -0
- package/dist/graph/semantic-enricher.js.map +1 -0
- package/dist/graph/sqlite-client.d.ts +24 -0
- package/dist/graph/sqlite-client.d.ts.map +1 -0
- package/dist/graph/sqlite-client.js +215 -0
- package/dist/graph/sqlite-client.js.map +1 -0
- package/dist/hooks/post-run-sync.d.ts +7 -0
- package/dist/hooks/post-run-sync.d.ts.map +1 -0
- package/dist/hooks/post-run-sync.js +26 -0
- package/dist/hooks/post-run-sync.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/agent-mcp-installer.d.ts +50 -0
- package/dist/integrations/agent-mcp-installer.d.ts.map +1 -0
- package/dist/integrations/agent-mcp-installer.js +414 -0
- package/dist/integrations/agent-mcp-installer.js.map +1 -0
- package/dist/learning/canary-gate.d.ts +6 -0
- package/dist/learning/canary-gate.d.ts.map +1 -0
- package/dist/learning/canary-gate.js +13 -0
- package/dist/learning/canary-gate.js.map +1 -0
- package/dist/learning/embeddings.d.ts +19 -0
- package/dist/learning/embeddings.d.ts.map +1 -0
- package/dist/learning/embeddings.js +160 -0
- package/dist/learning/embeddings.js.map +1 -0
- package/dist/learning/episodic-memory.d.ts +36 -0
- package/dist/learning/episodic-memory.d.ts.map +1 -0
- package/dist/learning/episodic-memory.js +228 -0
- package/dist/learning/episodic-memory.js.map +1 -0
- package/dist/learning/exporter.d.ts +10 -0
- package/dist/learning/exporter.d.ts.map +1 -0
- package/dist/learning/exporter.js +25 -0
- package/dist/learning/exporter.js.map +1 -0
- package/dist/learning/feedback-collector.d.ts +12 -0
- package/dist/learning/feedback-collector.d.ts.map +1 -0
- package/dist/learning/feedback-collector.js +14 -0
- package/dist/learning/feedback-collector.js.map +1 -0
- package/dist/learning/learning-events.d.ts +4 -0
- package/dist/learning/learning-events.d.ts.map +1 -0
- package/dist/learning/learning-events.js +35 -0
- package/dist/learning/learning-events.js.map +1 -0
- package/dist/learning/local-embedding.d.ts +3 -0
- package/dist/learning/local-embedding.d.ts.map +1 -0
- package/dist/learning/local-embedding.js +21 -0
- package/dist/learning/local-embedding.js.map +1 -0
- package/dist/learning/nightly-trainer.d.ts +14 -0
- package/dist/learning/nightly-trainer.d.ts.map +1 -0
- package/dist/learning/nightly-trainer.js +56 -0
- package/dist/learning/nightly-trainer.js.map +1 -0
- package/dist/learning/reflector.d.ts +19 -0
- package/dist/learning/reflector.d.ts.map +1 -0
- package/dist/learning/reflector.js +130 -0
- package/dist/learning/reflector.js.map +1 -0
- package/dist/learning/sample-builder.d.ts +7 -0
- package/dist/learning/sample-builder.d.ts.map +1 -0
- package/dist/learning/sample-builder.js +10 -0
- package/dist/learning/sample-builder.js.map +1 -0
- package/dist/learning/skill-flywheel.d.ts +52 -0
- package/dist/learning/skill-flywheel.d.ts.map +1 -0
- package/dist/learning/skill-flywheel.js +533 -0
- package/dist/learning/skill-flywheel.js.map +1 -0
- package/dist/learning/vector-store.d.ts +18 -0
- package/dist/learning/vector-store.d.ts.map +1 -0
- package/dist/learning/vector-store.js +73 -0
- package/dist/learning/vector-store.js.map +1 -0
- package/dist/routing/model-router.d.ts +13 -0
- package/dist/routing/model-router.d.ts.map +1 -0
- package/dist/routing/model-router.js +113 -0
- package/dist/routing/model-router.js.map +1 -0
- package/dist/routing/provider-adapters/anthropic.d.ts +3 -0
- package/dist/routing/provider-adapters/anthropic.d.ts.map +1 -0
- package/dist/routing/provider-adapters/anthropic.js +57 -0
- package/dist/routing/provider-adapters/anthropic.js.map +1 -0
- package/dist/routing/provider-adapters/bailian.d.ts +3 -0
- package/dist/routing/provider-adapters/bailian.d.ts.map +1 -0
- package/dist/routing/provider-adapters/bailian.js +56 -0
- package/dist/routing/provider-adapters/bailian.js.map +1 -0
- package/dist/routing/provider-adapters/doubao.d.ts +3 -0
- package/dist/routing/provider-adapters/doubao.d.ts.map +1 -0
- package/dist/routing/provider-adapters/doubao.js +56 -0
- package/dist/routing/provider-adapters/doubao.js.map +1 -0
- package/dist/routing/provider-adapters/openai.d.ts +6 -0
- package/dist/routing/provider-adapters/openai.d.ts.map +1 -0
- package/dist/routing/provider-adapters/openai.js +80 -0
- package/dist/routing/provider-adapters/openai.js.map +1 -0
- package/dist/routing/provider-adapters/openbmb.d.ts +16 -0
- package/dist/routing/provider-adapters/openbmb.d.ts.map +1 -0
- package/dist/routing/provider-adapters/openbmb.js +368 -0
- package/dist/routing/provider-adapters/openbmb.js.map +1 -0
- package/dist/routing/provider-executor.d.ts +21 -0
- package/dist/routing/provider-executor.d.ts.map +1 -0
- package/dist/routing/provider-executor.js +260 -0
- package/dist/routing/provider-executor.js.map +1 -0
- package/dist/routing/provider-health.d.ts +9 -0
- package/dist/routing/provider-health.d.ts.map +1 -0
- package/dist/routing/provider-health.js +66 -0
- package/dist/routing/provider-health.js.map +1 -0
- package/dist/surfaces/cli/index.d.ts +3 -0
- package/dist/surfaces/cli/index.d.ts.map +1 -0
- package/dist/surfaces/cli/index.js +200 -0
- package/dist/surfaces/cli/index.js.map +1 -0
- package/dist/surfaces/cli/init.d.ts +2 -0
- package/dist/surfaces/cli/init.d.ts.map +1 -0
- package/dist/surfaces/cli/init.js +121 -0
- package/dist/surfaces/cli/init.js.map +1 -0
- package/dist/surfaces/cli/output.d.ts +16 -0
- package/dist/surfaces/cli/output.d.ts.map +1 -0
- package/dist/surfaces/cli/output.js +74 -0
- package/dist/surfaces/cli/output.js.map +1 -0
- package/dist/surfaces/cli/runtime.d.ts +218 -0
- package/dist/surfaces/cli/runtime.d.ts.map +1 -0
- package/dist/surfaces/cli/runtime.js +1130 -0
- package/dist/surfaces/cli/runtime.js.map +1 -0
- package/dist/surfaces/mcp/server.d.ts +60 -0
- package/dist/surfaces/mcp/server.d.ts.map +1 -0
- package/dist/surfaces/mcp/server.js +425 -0
- package/dist/surfaces/mcp/server.js.map +1 -0
- package/dist/surfaces/vscode/extension.d.ts +17 -0
- package/dist/surfaces/vscode/extension.d.ts.map +1 -0
- package/dist/surfaces/vscode/extension.js +35 -0
- package/dist/surfaces/vscode/extension.js.map +1 -0
- package/dist/utils/file-lock.d.ts +9 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +90 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +36 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +89 -0
- package/scripts/safe-postinstall.cjs +14 -0
package/README.md
ADDED
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
# GraphFlow
|
|
2
|
+
|
|
3
|
+
A Context-Aware Multi-Agent Orchestration Engine.
|
|
4
|
+
|
|
5
|
+
GraphFlow 是一个基于 TypeScript/Node.js 的多智能体编排引擎,当前版本聚焦于工程可用性:任务分流、DAG 执行、结果校验、图谱索引、近无损上下文压缩、CLI 与 VS Code 扩展联动。
|
|
6
|
+
|
|
7
|
+
## 当前进度(v0.6.5)
|
|
8
|
+
|
|
9
|
+
GraphFlow 已演进为面向多 agent 协作的工程级编排 + 上下文引擎,覆盖 **任务编排 / 路由 / 图谱 / 检索 / 学习 / Agent 接入** 全链路。
|
|
10
|
+
|
|
11
|
+
### 一句话总结
|
|
12
|
+
|
|
13
|
+
> 从 task 描述出发,自动规划 → 路由模型 → 压缩图谱上下文(含向量召回)→ 执行/校验/重试,并把经验沉淀回知识图谱。
|
|
14
|
+
|
|
15
|
+
### v0.6.5 本轮重点
|
|
16
|
+
|
|
17
|
+
1. **Settings 可观测性**:图谱规模、上次索引、配置覆盖层 diff、面板内路由诊断。
|
|
18
|
+
2. **保存即索引(可选)**:`autoIndexOnSave` 在文件保存后 debounce 增量索引。
|
|
19
|
+
3. **发布流水线**:main 推送自动构建 VSIX 并发布 GitHub Release;`v*` tag 额外触发 npm publish(需 `NPM_TOKEN`)。
|
|
20
|
+
4. **推送前门禁**:Husky + lint-staged 在 `git push` 前运行 ESLint,避免 CI 才发现语法错误。
|
|
21
|
+
|
|
22
|
+
### 工程质量
|
|
23
|
+
|
|
24
|
+
- 测试:**39 文件** 全绿(`npm run ci` 含 extension build + bundled runtime smoke)。
|
|
25
|
+
- 类型:TypeScript 6 strict + exactOptionalPropertyTypes + NodeNext。
|
|
26
|
+
- License:Apache-2.0。
|
|
27
|
+
|
|
28
|
+
发布信息:
|
|
29
|
+
|
|
30
|
+
1. 最新版本:`v0.6.5`(root + vscode-extension)
|
|
31
|
+
2. **GitHub Release**:push 到 `main` 且 CI 通过后自动发布 VSIX(见 [Actions](https://github.com/Roarpeng/GraphFlow/actions))
|
|
32
|
+
3. 变更日志:`CHANGELOG.md`
|
|
33
|
+
|
|
34
|
+
## 环境要求
|
|
35
|
+
|
|
36
|
+
1. Node.js >= 20
|
|
37
|
+
2. npm >= 10
|
|
38
|
+
3. Windows / macOS / Linux 均可
|
|
39
|
+
|
|
40
|
+
## 5 分钟本地试跑(推荐)
|
|
41
|
+
|
|
42
|
+
在仓库根目录执行:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm install
|
|
46
|
+
npm run lint
|
|
47
|
+
npm run build
|
|
48
|
+
npm test
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
预期结果:
|
|
52
|
+
|
|
53
|
+
1. `lint` 无错误
|
|
54
|
+
2. `build` 成功
|
|
55
|
+
3. `vitest` 全量通过(当前应为 146 tests / 33 files passed)
|
|
56
|
+
|
|
57
|
+
可选一键 CI 本地校验:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm run ci
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Agent 工具接入
|
|
64
|
+
|
|
65
|
+
GraphFlow 已支持两种对外接入方式:
|
|
66
|
+
|
|
67
|
+
1. CLI 机器输出:所有核心命令支持 `--json`
|
|
68
|
+
2. MCP stdio server:可被 Cursor、Claude Code 等支持 MCP 的 agent 直接调用
|
|
69
|
+
|
|
70
|
+
本仓库内直接启动 MCP server:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm run start:mcp
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
CLI 结构化输出示例:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm run start -- plan "refactor planner and add tests" --json
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
CLI 标准帮助与版本:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run start -- --help
|
|
86
|
+
npm run start -- --version
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
外部 agent 约定文件:
|
|
90
|
+
|
|
91
|
+
1. `AGENTS.md`
|
|
92
|
+
2. `CLAUDE.md`
|
|
93
|
+
3. `.cursor/rules/graphflow.mdc`
|
|
94
|
+
4. `docs/integrations/cursor.mcp.json`
|
|
95
|
+
5. `docs/integrations/claude-code.mcp.json`
|
|
96
|
+
6. `docs/integrations/claude-desktop-config.json`
|
|
97
|
+
|
|
98
|
+
## 本地功能验证(CLI)
|
|
99
|
+
|
|
100
|
+
### 1) 图谱索引
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm run start -- graph index .
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
预期输出示例:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
indexedFiles=52; indexedSymbols=98
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### 2) 上下文压缩预览
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm run start -- context preview "orchestrator"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
预期输出示例:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
summary=6; anchors=6; tokens=98; truncated=false; L1=3; L2=2; L3=1
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 3) 执行任务
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
npm run start -- run "update readme and add tests"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
说明:该命令会根据任务复杂度自动走 simple 或 complex 工作流。
|
|
131
|
+
|
|
132
|
+
### 4) 规划与头脑风暴
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
npm run start -- plan "update readme and add tests and refactor architecture module"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
预期输出示例:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
mode=complex; ideas=...; plan=task-1... | task-2... | task-3...
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 5) 动态路由诊断
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run start -- route diagnose
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
预期输出示例:
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
dynamicRouting=on; health=openai:true,...; planner=openai/...; worker=openai/...
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 6) 学习夜跑
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npm run start -- learn nightly
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
预期输出示例:
|
|
163
|
+
|
|
164
|
+
```text
|
|
165
|
+
events=12; passRate=0.833; avgTokens=118.0; canary=allow; dataset=tmp/learning-dataset.jsonl
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### 7) 图谱快照洞察
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
npm run start -- graph inspect
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
预期输出示例:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
nodes=120; edges=184; types=File:20,Symbol:54,...; relations=defines:44,imports:20,...
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 8) 技能洞察
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npm run start -- skill insights
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
预期输出示例:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
source=graph-store; transport=file; count=8; top=add tests:4/6,refactor planner:3/4
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## v0.4 新能力使用指南
|
|
193
|
+
|
|
194
|
+
### 1) 切换到 SQLite/FTS5 图谱后端
|
|
195
|
+
|
|
196
|
+
将 `graphflow.config.json` 的 `graphPolicy` 改为:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"graphPolicy": {
|
|
201
|
+
"enableAutoBuild": true,
|
|
202
|
+
"transport": "sqlite",
|
|
203
|
+
"graphStorePath": "tmp/graphflow-graph.sqlite",
|
|
204
|
+
"maxContextTokens": 1200
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
特点:
|
|
210
|
+
|
|
211
|
+
1. WAL 模式 + FTS5 全文索引,关键词查询 O(log n)
|
|
212
|
+
2. 边表三索引(from / to / relation),`getNeighbors` O(度)
|
|
213
|
+
3. 与 `file` / `memory` transport 接口完全一致,零业务代码改动
|
|
214
|
+
|
|
215
|
+
### 2) 启用向量召回 + RRF 双路融合
|
|
216
|
+
|
|
217
|
+
代码侧(`buildLayeredContextPackage` 调用方)打开:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { createHashEmbeddingProvider } from "graphflow/dist/learning/embeddings";
|
|
221
|
+
|
|
222
|
+
const pkg = await buildLayeredContextPackage(client, query, {
|
|
223
|
+
enableVectorRecall: true,
|
|
224
|
+
embeddingProvider: createHashEmbeddingProvider(),
|
|
225
|
+
vectorTopK: 8,
|
|
226
|
+
vectorMinSimilarity: 0.2,
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
切换到 OpenAI 真向量:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { createOpenAiEmbeddingProvider } from "graphflow/dist/learning/embeddings";
|
|
234
|
+
|
|
235
|
+
const provider = createOpenAiEmbeddingProvider({
|
|
236
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
237
|
+
model: "text-embedding-3-small",
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
关键词命中 + 向量相似度通过 RRF(k=60)融合排序,对自然语言任务描述召回更稳。
|
|
242
|
+
|
|
243
|
+
### 3) Episodic Memory + Reflection
|
|
244
|
+
|
|
245
|
+
在 `orchestrate(...)` 选项里打开:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const run = await orchestrate(
|
|
249
|
+
{ task: "refactor planner module and add tests" },
|
|
250
|
+
{
|
|
251
|
+
graphClient,
|
|
252
|
+
enableEpisodicMemory: true,
|
|
253
|
+
enableGraphContextInPrompt: true,
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
|
|
257
|
+
console.log(run.episodeId); // "episode:xxx"
|
|
258
|
+
console.log(run.similarEpisodes); // 历史相似 task 的 keyDecisions
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
行为:
|
|
262
|
+
|
|
263
|
+
1. 每次 task 结束写入一个 `Episode` 节点(含 plan / outcome / keyDecisions / attempts)
|
|
264
|
+
2. 复现相似 task 时,Top-K 历史决策自动注入 PromptContext.extraInstructions
|
|
265
|
+
3. `learn nightly` 调用 reflector:将多次成功 episode 聚类合成 `Lesson` 节点 + `improves` 边,可被技能提示复用
|
|
266
|
+
|
|
267
|
+
### 4) 跨语言 AST 索引
|
|
268
|
+
|
|
269
|
+
无需额外配置。`graph index` 会自动识别并解析:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
npm run start -- graph index .
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
支持的语言/扩展:
|
|
276
|
+
|
|
277
|
+
| 语言 | 扩展 | 解析方式 |
|
|
278
|
+
| --- | --- | --- |
|
|
279
|
+
| TypeScript / JavaScript | `.ts .tsx .js .jsx` | TS Compiler API |
|
|
280
|
+
| Python | `.py` | 语言专用 indexer |
|
|
281
|
+
| Rust | `.rs` | 语言专用 indexer |
|
|
282
|
+
| Go | `.go` | 语言专用 indexer |
|
|
283
|
+
| C / C++ | `.c .h .cc .cpp .cxx .hpp .hxx` | 语言专用 indexer |
|
|
284
|
+
|
|
285
|
+
统一输出 `Symbol` / `Module` 节点 + `defines` / `imports` / `references` 边,下游图谱检索、prompt 注入、episode 召回完全透明复用。
|
|
286
|
+
|
|
287
|
+
如需限制扫描语言,调整 `graphPolicy.includeExtensions` 即可。
|
|
288
|
+
|
|
289
|
+
## 配置文件
|
|
290
|
+
|
|
291
|
+
默认使用根目录 `graphflow.config.json`。
|
|
292
|
+
|
|
293
|
+
首次使用建议从模板复制:
|
|
294
|
+
|
|
295
|
+
Windows CMD:
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
copy graphflow.config.example.json graphflow.config.json
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
PowerShell / macOS / Linux:
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
cp graphflow.config.example.json graphflow.config.json
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
关键配置:
|
|
308
|
+
|
|
309
|
+
1. `graphPolicy.transport`
|
|
310
|
+
- `file`:本地持久化图谱(JSON,默认,适合正式使用测试)
|
|
311
|
+
- `memory`:本地内存图谱(适合轻量调试)
|
|
312
|
+
- `sqlite`:SQLite + FTS5 后端(v0.4 新增,适合大型工作区与跨会话持久化)
|
|
313
|
+
- `mcp-http`:连接 Graphify MCP HTTP 服务
|
|
314
|
+
2. `graphPolicy.graphStorePath`
|
|
315
|
+
- `file` transport 的 JSON 路径,或 `sqlite` transport 的 `.sqlite` 路径
|
|
316
|
+
2. `graphPolicy.enableNearLosslessMode`
|
|
317
|
+
- 开启后启用近无损上下文打包
|
|
318
|
+
3. `graphPolicy.autoIndexOnPreview`
|
|
319
|
+
- `context preview` 前自动索引工作区
|
|
320
|
+
4. `graphPolicy.autoIndexOnRun`
|
|
321
|
+
- `run` 前自动索引工作区
|
|
322
|
+
5. `graphPolicy.layerQuota`
|
|
323
|
+
- 控制 L1/L2/L3 锚点配额
|
|
324
|
+
6. `learningPolicy.exportPath`
|
|
325
|
+
- 学习样本导出路径
|
|
326
|
+
7. `learningPolicy.eventsPath`
|
|
327
|
+
- 运行反馈事件日志路径(用于 nightly 学习)
|
|
328
|
+
8. `learningPolicy.summaryPath`
|
|
329
|
+
- 学习汇总指标路径
|
|
330
|
+
9. `routingPolicy.enableDynamicRouting`
|
|
331
|
+
- 启用按 provider 健康状态的自动路由
|
|
332
|
+
10. `routingPolicy.requireApiKeyForHealthy`
|
|
333
|
+
- 若开启,缺少 apiKey 的 provider 会被标记为不健康并触发 fallback
|
|
334
|
+
11. `routingPolicy.providerPriority`
|
|
335
|
+
- 设置 fallback 优先级,例如 `["anthropic", "openai", "bailian", "doubao"]`
|
|
336
|
+
12. `skillPolicy.enableSkillFlywheel`
|
|
337
|
+
- 开启技能飞轮(技能抽取、技能连接、技能提示复用)
|
|
338
|
+
13. `skillPolicy.maxSkillHints`
|
|
339
|
+
- 每次规划注入的技能提示上限
|
|
340
|
+
|
|
341
|
+
## 本地测试验收清单
|
|
342
|
+
|
|
343
|
+
你可以按下面清单判断“本地可用”:
|
|
344
|
+
|
|
345
|
+
1. 质量门禁通过:`npm run lint && npm run build && npm test`
|
|
346
|
+
2. `graph index` 返回 `indexedFiles > 0`
|
|
347
|
+
3. `context preview` 返回 `summary > 0` 且 `anchors > 0`
|
|
348
|
+
4. `run "..."` 能返回正常执行输出
|
|
349
|
+
5. `plan "..."` 返回 `mode=...; ideas=...; plan=...`
|
|
350
|
+
|
|
351
|
+
## 正式使用测试
|
|
352
|
+
|
|
353
|
+
正式使用测试脚本(含通过标准)见:
|
|
354
|
+
|
|
355
|
+
1. `docs/testing/2026-05-28-formal-usage-test-plan.md`
|
|
356
|
+
2. `docs/testing/2026-05-28-formal-usage-test-report.md`
|
|
357
|
+
|
|
358
|
+
## VS Code 扩展本地试用
|
|
359
|
+
|
|
360
|
+
### 方式 A:安装已打包 VSIX
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
code --install-extension artifacts/graphflow-vscode-0.5.0.vsix
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
安装后可在命令面板执行:
|
|
367
|
+
|
|
368
|
+
1. `GraphFlow: Run Task`
|
|
369
|
+
2. `GraphFlow: Show Runs`
|
|
370
|
+
3. `GraphFlow: Plan & Brainstorm`
|
|
371
|
+
4. `GraphFlow: Graph Snapshot`
|
|
372
|
+
5. `GraphFlow: Skill Insights`
|
|
373
|
+
|
|
374
|
+
并可在 Agent 对话框通过 `@graphflow` 使用:
|
|
375
|
+
|
|
376
|
+
1. `/run <task>`
|
|
377
|
+
2. `/plan <task>`
|
|
378
|
+
3. `/history`
|
|
379
|
+
4. `/diagnose`
|
|
380
|
+
5. `/learn`
|
|
381
|
+
6. `/graph`
|
|
382
|
+
7. `/skills`
|
|
383
|
+
|
|
384
|
+
分发给同事:
|
|
385
|
+
|
|
386
|
+
1. 直接发送 `artifacts/graphflow-vscode-0.5.0.vsix`
|
|
387
|
+
2. 同事执行 `code --install-extension artifacts/graphflow-vscode-0.5.0.vsix`
|
|
388
|
+
3. 不需要克隆 GraphFlow 仓库即可使用插件核心能力
|
|
389
|
+
|
|
390
|
+
### 方式 B:开发模式运行扩展
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
cd vscode-extension
|
|
394
|
+
npm install
|
|
395
|
+
npm run build
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
然后在 VS Code 中按 `F5` 启动 Extension Development Host 进行联调。
|
|
399
|
+
|
|
400
|
+
## 常见问题
|
|
401
|
+
|
|
402
|
+
1. `context preview` 返回 0 anchors
|
|
403
|
+
- 先执行 `npm run start -- graph index .`
|
|
404
|
+
- 检查查询词是否命中现有代码符号(例如 `orchestrator`, `runtime`, `planner`)
|
|
405
|
+
|
|
406
|
+
2. 扩展打包产物不存在
|
|
407
|
+
- 确认目录 `artifacts/` 已存在
|
|
408
|
+
- 在 `vscode-extension` 目录执行 `npm run package`
|
|
409
|
+
|
|
410
|
+
3. API Key 未配置导致模型调用失败
|
|
411
|
+
- 在 `graphflow.config.json` 中配置对应 provider 的 `apiKey`
|
|
412
|
+
- `graphflow.config.json` 与示例模板支持 `${ENV_VAR}` 环境变量占位写法
|
|
413
|
+
|
|
414
|
+
## 项目结构(简版)
|
|
415
|
+
|
|
416
|
+
```text
|
|
417
|
+
GraphFlow/
|
|
418
|
+
├── src/
|
|
419
|
+
│ ├── core/
|
|
420
|
+
│ ├── graph/
|
|
421
|
+
│ ├── routing/
|
|
422
|
+
│ ├── learning/
|
|
423
|
+
│ └── surfaces/cli/
|
|
424
|
+
├── tests/
|
|
425
|
+
├── docs/releases/
|
|
426
|
+
├── vscode-extension/
|
|
427
|
+
└── artifacts/
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## 版本与变更
|
|
431
|
+
|
|
432
|
+
1. 变更日志:`CHANGELOG.md`
|
|
433
|
+
2. 发布文档:`docs/releases/v0.3.0.md`
|
|
434
|
+
3. License:`LICENSE`
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ModelSelection } from "../routing/model-router";
|
|
2
|
+
import { type PromptContext } from "../routing/provider-executor";
|
|
3
|
+
export declare function brainstormTask(task: string): string[];
|
|
4
|
+
export declare function brainstormTaskLlm(task: string, selection: ModelSelection, context?: PromptContext): Promise<string[]>;
|
|
5
|
+
//# sourceMappingURL=brainstormer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brainstormer.d.ts","sourceRoot":"","sources":["../../src/agents/brainstormer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAErF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAmBrD;AAID,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,cAAc,EACzB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,MAAM,EAAE,CAAC,CA2BnB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.brainstormTask = brainstormTask;
|
|
4
|
+
exports.brainstormTaskLlm = brainstormTaskLlm;
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
const provider_executor_1 = require("../routing/provider-executor");
|
|
7
|
+
function brainstormTask(task) {
|
|
8
|
+
const normalized = task.trim();
|
|
9
|
+
if (!normalized) {
|
|
10
|
+
return ["澄清目标: 任务描述不能为空"];
|
|
11
|
+
}
|
|
12
|
+
const clauses = normalized
|
|
13
|
+
.split(/\band\b|,|;/i)
|
|
14
|
+
.map((part) => part.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
const focus = clauses.slice(0, 3);
|
|
17
|
+
const ideas = [
|
|
18
|
+
`目标澄清: 明确要完成 ${focus.join("、")}`,
|
|
19
|
+
`实现路径: 先拆分子任务并并行推进,再做集成校验`,
|
|
20
|
+
`风险提示: 重点关注跨文件依赖和回归影响`,
|
|
21
|
+
];
|
|
22
|
+
return ideas;
|
|
23
|
+
}
|
|
24
|
+
const MAX_BRAINSTORM_IDEAS = 6;
|
|
25
|
+
async function brainstormTaskLlm(task, selection, context) {
|
|
26
|
+
const normalized = task.trim();
|
|
27
|
+
if (!normalized) {
|
|
28
|
+
return brainstormTask(task);
|
|
29
|
+
}
|
|
30
|
+
const prompt = [
|
|
31
|
+
"Brainstorm 3 short ideas in Chinese for the following task.",
|
|
32
|
+
"Cover: 1) 目标澄清, 2) 实现路径, 3) 风险提示.",
|
|
33
|
+
"Return each idea on its own line, no extra commentary.",
|
|
34
|
+
`Task: ${normalized}`,
|
|
35
|
+
].join("\n");
|
|
36
|
+
let raw = "";
|
|
37
|
+
try {
|
|
38
|
+
raw = await (0, provider_executor_1.executeRolePrompt)("planner", prompt, selection, context);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
logger_1.logger.error({ error }, "Caught error");
|
|
42
|
+
return brainstormTask(task);
|
|
43
|
+
}
|
|
44
|
+
const ideas = parseBrainstormIdeas(raw);
|
|
45
|
+
if (ideas.length === 0) {
|
|
46
|
+
return brainstormTask(task);
|
|
47
|
+
}
|
|
48
|
+
return ideas.slice(0, MAX_BRAINSTORM_IDEAS);
|
|
49
|
+
}
|
|
50
|
+
function parseBrainstormIdeas(raw) {
|
|
51
|
+
if (!raw) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
return raw
|
|
55
|
+
.split(/\r?\n/)
|
|
56
|
+
.map((line) => line.trim())
|
|
57
|
+
.filter((line) => line.length > 0)
|
|
58
|
+
.map((line) => line.replace(/^[-*•]\s*/, "").replace(/^\d+[\.\)、::]\s*/, "").trim())
|
|
59
|
+
.filter((line) => line.length > 0);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=brainstormer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brainstormer.js","sourceRoot":"","sources":["../../src/agents/brainstormer.ts"],"names":[],"mappings":";;AAIA,wCAmBC;AAID,8CA+BC;AA1DD,4CAAyC;AAEzC,oEAAqF;AAErF,SAAgB,cAAc,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,OAAO,GAAG,UAAU;SACvB,KAAK,CAAC,cAAc,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG;QACZ,eAAe,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;QAChC,0BAA0B;QAC1B,sBAAsB;KACvB,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAExB,KAAK,UAAU,iBAAiB,CACrC,IAAY,EACZ,SAAyB,EACzB,OAAuB;IAEvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG;QACb,6DAA6D;QAC7D,mCAAmC;QACnC,wDAAwD;QACxD,SAAS,UAAU,EAAE;KACtB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,IAAA,qCAAiB,EAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,eAAM,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,cAAc,CAAC,CAAC;QACxC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,KAAK,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,GAAG;SACP,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;SACnF,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TaskNode } from "../core/types";
|
|
2
|
+
import type { ModelSelection } from "../routing/model-router";
|
|
3
|
+
import { type PromptContext } from "../routing/provider-executor";
|
|
4
|
+
export declare function planTasks(task: string, skillHints?: string[]): TaskNode[];
|
|
5
|
+
export interface PlanTasksLlmOptions {
|
|
6
|
+
selection: ModelSelection;
|
|
7
|
+
skillHints?: string[];
|
|
8
|
+
brainstormIdeas?: string[];
|
|
9
|
+
previousPlan?: TaskNode[];
|
|
10
|
+
failureFeedback?: string;
|
|
11
|
+
context?: PromptContext;
|
|
12
|
+
}
|
|
13
|
+
export declare function planTasksLlm(task: string, options: PlanTasksLlmOptions): Promise<TaskNode[]>;
|
|
14
|
+
//# sourceMappingURL=planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.d.ts","sourceRoot":"","sources":["../../src/agents/planner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAarF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAoBzE;AAUD,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAkBlG"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planTasks = planTasks;
|
|
4
|
+
exports.planTasksLlm = planTasksLlm;
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
const provider_executor_1 = require("../routing/provider-executor");
|
|
7
|
+
function toNode(id, description, dependencies) {
|
|
8
|
+
return {
|
|
9
|
+
id,
|
|
10
|
+
description,
|
|
11
|
+
dependencies,
|
|
12
|
+
status: "PENDING",
|
|
13
|
+
contextQuery: description,
|
|
14
|
+
retryCount: 0,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function planTasks(task, skillHints) {
|
|
18
|
+
const parts = task
|
|
19
|
+
.split(/\band\b|,|;/i)
|
|
20
|
+
.map((item) => item.trim())
|
|
21
|
+
.filter((item) => item.length > 0);
|
|
22
|
+
if (parts.length <= 1) {
|
|
23
|
+
return [toNode("task-1", withSkillHints(task.trim(), skillHints), [])];
|
|
24
|
+
}
|
|
25
|
+
const parallelTasks = parts.map((part, index) => toNode(`task-${index + 1}`, withSkillHints(part, skillHints), []));
|
|
26
|
+
const finalTask = toNode(`task-${parts.length + 1}`, withSkillHints(`integrate and verify: ${parts.join("; ")}`, skillHints), parallelTasks.map((item) => item.id));
|
|
27
|
+
return [...parallelTasks, finalTask];
|
|
28
|
+
}
|
|
29
|
+
function withSkillHints(task, skillHints) {
|
|
30
|
+
if (!skillHints || skillHints.length === 0) {
|
|
31
|
+
return task;
|
|
32
|
+
}
|
|
33
|
+
return `${task} | use skills: ${skillHints.join(", ")}`;
|
|
34
|
+
}
|
|
35
|
+
const MAX_PLAN_NODES = 8;
|
|
36
|
+
async function planTasksLlm(task, options) {
|
|
37
|
+
const prompt = buildPlannerPrompt(task, options);
|
|
38
|
+
let raw = "";
|
|
39
|
+
try {
|
|
40
|
+
raw = await (0, provider_executor_1.executeRolePrompt)("planner", prompt, options.selection, options.context);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
logger_1.logger.error({ error }, "Caught error");
|
|
44
|
+
return planTasks(task, options.skillHints);
|
|
45
|
+
}
|
|
46
|
+
const parsed = parsePlannerJson(raw);
|
|
47
|
+
if (!parsed || parsed.length === 0) {
|
|
48
|
+
return planTasks(task, options.skillHints);
|
|
49
|
+
}
|
|
50
|
+
return parsed.slice(0, MAX_PLAN_NODES).map((item) => toNode(item.id, withSkillHints(item.description, options.skillHints), item.dependencies));
|
|
51
|
+
}
|
|
52
|
+
function buildPlannerPrompt(task, options) {
|
|
53
|
+
const lines = [];
|
|
54
|
+
lines.push("You are a task planner. Decompose the task into a small DAG.");
|
|
55
|
+
lines.push("Return ONLY a JSON array of items shaped as {id, description, dependencies}.");
|
|
56
|
+
lines.push("- id: short string like task-1");
|
|
57
|
+
lines.push("- description: concrete actionable subtask");
|
|
58
|
+
lines.push("- dependencies: array of ids this task depends on (may be empty)");
|
|
59
|
+
lines.push(`Task: ${task}`);
|
|
60
|
+
if (options.skillHints && options.skillHints.length > 0) {
|
|
61
|
+
lines.push(`Skill hints: ${options.skillHints.join(", ")}`);
|
|
62
|
+
}
|
|
63
|
+
if (options.brainstormIdeas && options.brainstormIdeas.length > 0) {
|
|
64
|
+
lines.push(`Brainstorm ideas: ${options.brainstormIdeas.join(" | ")}`);
|
|
65
|
+
}
|
|
66
|
+
if (options.previousPlan && options.previousPlan.length > 0) {
|
|
67
|
+
const projection = options.previousPlan.map((node) => ({
|
|
68
|
+
id: node.id,
|
|
69
|
+
description: node.description,
|
|
70
|
+
dependencies: node.dependencies,
|
|
71
|
+
}));
|
|
72
|
+
lines.push(`Previous plan: ${JSON.stringify(projection)}`);
|
|
73
|
+
}
|
|
74
|
+
if (options.failureFeedback) {
|
|
75
|
+
lines.push(`Previous failure feedback: ${options.failureFeedback}`);
|
|
76
|
+
lines.push("Revise the plan to address the failures. Avoid repeating failing steps verbatim.");
|
|
77
|
+
}
|
|
78
|
+
return lines.join("\n");
|
|
79
|
+
}
|
|
80
|
+
function parsePlannerJson(raw) {
|
|
81
|
+
if (!raw) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
let text = raw.trim();
|
|
85
|
+
text = stripCodeFences(text);
|
|
86
|
+
const jsonBlock = extractFirstJsonArray(text);
|
|
87
|
+
if (!jsonBlock) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
let parsed;
|
|
91
|
+
try {
|
|
92
|
+
parsed = JSON.parse(jsonBlock);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
logger_1.logger.error({ error }, "Caught error");
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
if (!Array.isArray(parsed)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const items = [];
|
|
102
|
+
for (let index = 0; index < parsed.length; index += 1) {
|
|
103
|
+
const entry = parsed[index];
|
|
104
|
+
if (!entry || typeof entry !== "object") {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const record = entry;
|
|
108
|
+
const id = typeof record.id === "string" && record.id.trim().length > 0 ? record.id.trim() : `task-${index + 1}`;
|
|
109
|
+
const description = typeof record.description === "string" ? record.description.trim() : "";
|
|
110
|
+
if (!description) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const dependenciesRaw = record.dependencies;
|
|
114
|
+
const dependencies = Array.isArray(dependenciesRaw)
|
|
115
|
+
? dependenciesRaw.filter((dep) => typeof dep === "string")
|
|
116
|
+
: [];
|
|
117
|
+
items.push({ id, description, dependencies });
|
|
118
|
+
}
|
|
119
|
+
return items.length > 0 ? items : null;
|
|
120
|
+
}
|
|
121
|
+
function stripCodeFences(text) {
|
|
122
|
+
const fenceMatch = text.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
|
|
123
|
+
if (fenceMatch && fenceMatch[1]) {
|
|
124
|
+
return fenceMatch[1].trim();
|
|
125
|
+
}
|
|
126
|
+
return text;
|
|
127
|
+
}
|
|
128
|
+
function extractFirstJsonArray(text) {
|
|
129
|
+
const start = text.indexOf("[");
|
|
130
|
+
if (start === -1) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
let depth = 0;
|
|
134
|
+
let inString = false;
|
|
135
|
+
let escape = false;
|
|
136
|
+
for (let index = start; index < text.length; index += 1) {
|
|
137
|
+
const ch = text[index];
|
|
138
|
+
if (inString) {
|
|
139
|
+
if (escape) {
|
|
140
|
+
escape = false;
|
|
141
|
+
}
|
|
142
|
+
else if (ch === "\\") {
|
|
143
|
+
escape = true;
|
|
144
|
+
}
|
|
145
|
+
else if (ch === '"') {
|
|
146
|
+
inString = false;
|
|
147
|
+
}
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (ch === '"') {
|
|
151
|
+
inString = true;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (ch === "[") {
|
|
155
|
+
depth += 1;
|
|
156
|
+
}
|
|
157
|
+
else if (ch === "]") {
|
|
158
|
+
depth -= 1;
|
|
159
|
+
if (depth === 0) {
|
|
160
|
+
return text.slice(start, index + 1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=planner.js.map
|