@apolloyh/apollo-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.
Files changed (103) hide show
  1. package/.apollo/config.example.json +37 -0
  2. package/.env.example +17 -0
  3. package/README.md +62 -0
  4. package/dist/brand.d.ts +17 -0
  5. package/dist/brand.d.ts.map +1 -0
  6. package/dist/brand.js +23 -0
  7. package/dist/cli-args.d.ts +13 -0
  8. package/dist/cli-args.d.ts.map +1 -0
  9. package/dist/cli-args.js +50 -0
  10. package/dist/config.d.ts +13 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +190 -0
  13. package/dist/constants/spinner-verbs.d.ts +7 -0
  14. package/dist/constants/spinner-verbs.d.ts.map +1 -0
  15. package/dist/constants/spinner-verbs.js +21 -0
  16. package/dist/coordinator/workflow.d.ts +20 -0
  17. package/dist/coordinator/workflow.d.ts.map +1 -0
  18. package/dist/coordinator/workflow.js +120 -0
  19. package/dist/goal/goal-mode.d.ts +26 -0
  20. package/dist/goal/goal-mode.d.ts.map +1 -0
  21. package/dist/goal/goal-mode.js +141 -0
  22. package/dist/hooks/runner.d.ts +43 -0
  23. package/dist/hooks/runner.d.ts.map +1 -0
  24. package/dist/hooks/runner.js +94 -0
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +1716 -0
  28. package/dist/llm/anthropic.d.ts +46 -0
  29. package/dist/llm/anthropic.d.ts.map +1 -0
  30. package/dist/llm/anthropic.js +278 -0
  31. package/dist/mcp/manager.d.ts +14 -0
  32. package/dist/mcp/manager.d.ts.map +1 -0
  33. package/dist/mcp/manager.js +93 -0
  34. package/dist/memory/memdir.d.ts +19 -0
  35. package/dist/memory/memdir.d.ts.map +1 -0
  36. package/dist/memory/memdir.js +96 -0
  37. package/dist/plan/plan-mode.d.ts +14 -0
  38. package/dist/plan/plan-mode.d.ts.map +1 -0
  39. package/dist/plan/plan-mode.js +90 -0
  40. package/dist/project-instructions.d.ts +8 -0
  41. package/dist/project-instructions.d.ts.map +1 -0
  42. package/dist/project-instructions.js +33 -0
  43. package/dist/runtime/compaction.d.ts +5 -0
  44. package/dist/runtime/compaction.d.ts.map +1 -0
  45. package/dist/runtime/compaction.js +37 -0
  46. package/dist/runtime/context.d.ts +25 -0
  47. package/dist/runtime/context.d.ts.map +1 -0
  48. package/dist/runtime/context.js +75 -0
  49. package/dist/runtime/permissions.d.ts +11 -0
  50. package/dist/runtime/permissions.d.ts.map +1 -0
  51. package/dist/runtime/permissions.js +119 -0
  52. package/dist/runtime/prompt-builder.d.ts +27 -0
  53. package/dist/runtime/prompt-builder.d.ts.map +1 -0
  54. package/dist/runtime/prompt-builder.js +112 -0
  55. package/dist/runtime/query-engine.d.ts +136 -0
  56. package/dist/runtime/query-engine.d.ts.map +1 -0
  57. package/dist/runtime/query-engine.js +1182 -0
  58. package/dist/runtime/tool-policy.d.ts +13 -0
  59. package/dist/runtime/tool-policy.d.ts.map +1 -0
  60. package/dist/runtime/tool-policy.js +106 -0
  61. package/dist/sdk.d.ts +33 -0
  62. package/dist/sdk.d.ts.map +1 -0
  63. package/dist/sdk.js +41 -0
  64. package/dist/session/resume-ui.d.ts +17 -0
  65. package/dist/session/resume-ui.d.ts.map +1 -0
  66. package/dist/session/resume-ui.js +64 -0
  67. package/dist/session/store.d.ts +66 -0
  68. package/dist/session/store.d.ts.map +1 -0
  69. package/dist/session/store.js +120 -0
  70. package/dist/skillify/skillify.d.ts +12 -0
  71. package/dist/skillify/skillify.d.ts.map +1 -0
  72. package/dist/skillify/skillify.js +52 -0
  73. package/dist/skills/skills.d.ts +26 -0
  74. package/dist/skills/skills.d.ts.map +1 -0
  75. package/dist/skills/skills.js +195 -0
  76. package/dist/status-ui.d.ts +37 -0
  77. package/dist/status-ui.d.ts.map +1 -0
  78. package/dist/status-ui.js +130 -0
  79. package/dist/thought-fold.d.ts +48 -0
  80. package/dist/thought-fold.d.ts.map +1 -0
  81. package/dist/thought-fold.js +156 -0
  82. package/dist/tools/builtin.d.ts +27 -0
  83. package/dist/tools/builtin.d.ts.map +1 -0
  84. package/dist/tools/builtin.js +898 -0
  85. package/dist/tools/registry.d.ts +17 -0
  86. package/dist/tools/registry.d.ts.map +1 -0
  87. package/dist/tools/registry.js +86 -0
  88. package/dist/trace.d.ts +68 -0
  89. package/dist/trace.d.ts.map +1 -0
  90. package/dist/trace.js +600 -0
  91. package/dist/types.d.ts +202 -0
  92. package/dist/types.d.ts.map +1 -0
  93. package/dist/types.js +1 -0
  94. package/dist/utils.d.ts +8 -0
  95. package/dist/utils.d.ts.map +1 -0
  96. package/dist/utils.js +78 -0
  97. package/docs/sdk.md +259 -0
  98. package/package.json +53 -0
  99. package/src/skills/tech-research-skill/SKILL.md +200 -0
  100. package/src/skills/tech-research-skill/agents/openai.yaml +4 -0
  101. package/src/skills/tech-research-skill/repo-analyze +435 -0
  102. package/src/skills/tech-research-skill/repo-fetch +310 -0
  103. package/src/skills/tech-research-skill/report-generate +254 -0
@@ -0,0 +1,202 @@
1
+ export type JsonObject = Record<string, unknown>;
2
+ export type ContentBlock = {
3
+ type: "text";
4
+ text: string;
5
+ } | {
6
+ type: "tool_use";
7
+ id: string;
8
+ name: string;
9
+ input: JsonObject;
10
+ } | {
11
+ type: "tool_result";
12
+ tool_use_id: string;
13
+ content: string;
14
+ is_error?: boolean;
15
+ };
16
+ export type Message = {
17
+ role: "user" | "assistant";
18
+ content: string | ContentBlock[];
19
+ };
20
+ export type AnthropicTool = {
21
+ name: string;
22
+ description: string;
23
+ input_schema: JsonObject;
24
+ };
25
+ export type ToolRisk = "low" | "medium" | "high";
26
+ export type ToolDefinition = AnthropicTool & {
27
+ risk: ToolRisk;
28
+ execute(input: JsonObject, context: ToolExecutionContext): Promise<ToolResult>;
29
+ };
30
+ export type ToolResult = {
31
+ content: string;
32
+ isError?: boolean;
33
+ fileChange?: FileChangeDisplay;
34
+ };
35
+ export type FileChangeDisplay = {
36
+ path: string;
37
+ kind: "create" | "update";
38
+ added: number;
39
+ removed: number;
40
+ lines: string[];
41
+ omitted: number;
42
+ };
43
+ /** Claude Code–style Task / subagent lifecycle events. */
44
+ export type TraceEvent = {
45
+ type: "llm_request";
46
+ turn: number;
47
+ toolCount: number;
48
+ } | {
49
+ type: "llm_retry";
50
+ attempt: number;
51
+ reason: string;
52
+ mode: "same-request" | "non-stream" | "after-compaction" | "continue";
53
+ delayMs?: number;
54
+ } | {
55
+ type: "llm_response";
56
+ turn: number;
57
+ stopReason?: string;
58
+ text?: string;
59
+ } | {
60
+ type: "assistant_delta";
61
+ text: string;
62
+ } | {
63
+ type: "llm_tool_delta";
64
+ bytes: number;
65
+ tool?: string;
66
+ detail?: string;
67
+ } | {
68
+ type: "tool_call";
69
+ tool: string;
70
+ input: JsonObject;
71
+ risk: ToolRisk;
72
+ } | {
73
+ type: "tool_result";
74
+ tool: string;
75
+ input?: JsonObject;
76
+ isError?: boolean;
77
+ content: string;
78
+ fileChange?: FileChangeDisplay;
79
+ } | {
80
+ type: "approval_required";
81
+ tool: string;
82
+ risk: ToolRisk;
83
+ reason: string;
84
+ } | {
85
+ type: "approval_result";
86
+ tool: string;
87
+ approved: boolean;
88
+ } | {
89
+ type: "context_compaction_start";
90
+ beforeChars: number;
91
+ } | {
92
+ type: "context_compacted";
93
+ beforeChars: number;
94
+ afterChars: number;
95
+ } | {
96
+ type: "context_compaction_failed";
97
+ reason: string;
98
+ } | {
99
+ type: "task_start";
100
+ id: string;
101
+ subagentType: string;
102
+ description: string;
103
+ } | {
104
+ type: "task_progress";
105
+ id: string;
106
+ subagentType: string;
107
+ message: string;
108
+ } | {
109
+ type: "task_finish";
110
+ id: string;
111
+ subagentType: string;
112
+ description: string;
113
+ result: string;
114
+ durationMs: number;
115
+ } | {
116
+ type: "workflow_status";
117
+ goal: string;
118
+ phases: Array<{
119
+ name: string;
120
+ label: string;
121
+ status: string;
122
+ summary?: string;
123
+ }>;
124
+ } | {
125
+ type: "plan_mode";
126
+ active: boolean;
127
+ approved?: boolean;
128
+ path?: string;
129
+ } | {
130
+ type: "user_question";
131
+ question: string;
132
+ options?: string[];
133
+ } | {
134
+ type: "user_answer";
135
+ answer: string;
136
+ } | {
137
+ type: "goal_status";
138
+ goal: string;
139
+ status: string;
140
+ iteration: number;
141
+ maxIterations: number;
142
+ progress: string[];
143
+ };
144
+ export type TraceSink = (event: TraceEvent) => void;
145
+ export type ApprovalRequest = {
146
+ toolName: string;
147
+ risk: ToolRisk;
148
+ reason: string;
149
+ input: JsonObject;
150
+ };
151
+ export type ApprovalProvider = (request: ApprovalRequest) => Promise<boolean>;
152
+ export type AskUserFn = (question: string, options?: string[]) => Promise<string>;
153
+ export type ToolExecutionContext = {
154
+ workspaceRoot: string;
155
+ emit: TraceSink;
156
+ requestApproval: ApprovalProvider;
157
+ signal?: AbortSignal;
158
+ /** Structured user question (AskUserQuestion) */
159
+ askUser?: AskUserFn;
160
+ /** When true, write tools are restricted (plan mode) */
161
+ planMode?: boolean;
162
+ };
163
+ export type LlmConfig = {
164
+ authToken: string;
165
+ baseUrl: string;
166
+ model: string;
167
+ maxTokens: number;
168
+ timeoutMs?: number;
169
+ cacheTtl?: "5m" | "1h";
170
+ };
171
+ export type McpServerConfig = {
172
+ command: string;
173
+ args?: string[];
174
+ env?: Record<string, string>;
175
+ cwd?: string;
176
+ };
177
+ export type SubagentConfig = {
178
+ name: string;
179
+ description: string;
180
+ tools?: string[];
181
+ prompt: string;
182
+ };
183
+ export type AgentConfig = {
184
+ workspaceRoot: string;
185
+ maxTurns: number;
186
+ systemPrompt?: string;
187
+ modeInstructions?: string;
188
+ context: {
189
+ maxChars: number;
190
+ summaryChars: number;
191
+ };
192
+ permissions: {
193
+ mode: "ask" | "readonly" | "unrestricted";
194
+ autoApproveReadOnly: boolean;
195
+ };
196
+ skills: {
197
+ directories: string[];
198
+ };
199
+ mcpServers: Record<string, McpServerConfig>;
200
+ agents: SubagentConfig[];
201
+ };
202
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export declare function truncate(value: string, max?: number): string;
2
+ export declare function truncateMiddle(value: string, max?: number): string;
3
+ export declare function stringify(value: unknown, max?: number): string;
4
+ export declare function safeResolve(root: string, target: string): string;
5
+ export declare function safeRealResolve(root: string, target: string): Promise<string>;
6
+ export declare function messageText(content: unknown): string;
7
+ export declare function estimateChars(value: unknown): number;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CAG1D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAQ,GAAG,MAAM,CAQjE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,SAAO,GAAG,MAAM,CAG5D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAOhE;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BnF;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAQpD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD"}
package/dist/utils.js ADDED
@@ -0,0 +1,78 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export function truncate(value, max = 4000) {
4
+ if (value.length <= max)
5
+ return value;
6
+ return `${value.slice(0, max)}\n...[truncated ${value.length - max} chars]`;
7
+ }
8
+ export function truncateMiddle(value, max = 30000) {
9
+ if (value.length <= max)
10
+ return value;
11
+ const marker = "\n...[tool result truncated]...\n";
12
+ if (max <= marker.length)
13
+ return value.slice(0, max);
14
+ const available = max - marker.length;
15
+ const headLength = Math.ceil(available * 0.6);
16
+ const tailLength = available - headLength;
17
+ return `${value.slice(0, headLength)}${marker}${tailLength > 0 ? value.slice(-tailLength) : ""}`;
18
+ }
19
+ export function stringify(value, max = 6000) {
20
+ const text = typeof value === "string" ? value : JSON.stringify(value, null, 2);
21
+ return truncate(text, max);
22
+ }
23
+ export function safeResolve(root, target) {
24
+ const resolved = path.resolve(root, target);
25
+ const normalizedRoot = path.resolve(root);
26
+ if (resolved !== normalizedRoot && !resolved.startsWith(`${normalizedRoot}${path.sep}`)) {
27
+ throw new Error(`Path escapes workspace: ${target}`);
28
+ }
29
+ return resolved;
30
+ }
31
+ export async function safeRealResolve(root, target) {
32
+ const resolved = safeResolve(root, target);
33
+ const realRoot = await fs.realpath(path.resolve(root));
34
+ const missingSegments = [];
35
+ let probe = resolved;
36
+ for (;;) {
37
+ try {
38
+ const realProbe = await fs.realpath(probe);
39
+ const relative = path.relative(realRoot, realProbe);
40
+ if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
41
+ throw new Error(`Path escapes workspace: ${target} -> ${realProbe}`);
42
+ }
43
+ return path.join(realProbe, ...missingSegments);
44
+ }
45
+ catch (error) {
46
+ if (error.code !== "ENOENT")
47
+ throw error;
48
+ try {
49
+ if ((await fs.lstat(probe)).isSymbolicLink()) {
50
+ throw new Error(`Path escapes workspace: ${target}`);
51
+ }
52
+ }
53
+ catch (lstatError) {
54
+ if (lstatError.code !== "ENOENT")
55
+ throw lstatError;
56
+ }
57
+ const parent = path.dirname(probe);
58
+ if (parent === probe)
59
+ throw error;
60
+ missingSegments.unshift(path.basename(probe));
61
+ probe = parent;
62
+ }
63
+ }
64
+ }
65
+ export function messageText(content) {
66
+ if (typeof content === "string")
67
+ return content;
68
+ if (!Array.isArray(content))
69
+ return "";
70
+ return content
71
+ .filter((block) => block && typeof block === "object" && block.type === "text")
72
+ .map((block) => block.text)
73
+ .filter((text) => typeof text === "string")
74
+ .join("\n");
75
+ }
76
+ export function estimateChars(value) {
77
+ return JSON.stringify(value).length;
78
+ }
package/docs/sdk.md ADDED
@@ -0,0 +1,259 @@
1
+ # Apollo SDK 接入指南
2
+
3
+ Apollo SDK 用于把 Agent 能力嵌入 Node.js / TypeScript 系统。CLI 只是终端界面;SDK 与 CLI 使用同一个 `QueryEngine`、工具、权限、会话、记忆和 Prompt Cache 机制。
4
+
5
+ ## 运行要求
6
+
7
+ - Node.js 20 或更高版本
8
+ - ESM 项目(`import`,不提供 CommonJS `require`)
9
+ - Anthropic Messages API 兼容模型服务
10
+
11
+ ## 安装
12
+
13
+ 当前使用本地 tarball:
14
+
15
+ ```bash
16
+ npm install /Users/apollo/Code-YH/web-agent/agent/apolloyh-apollo-agent-0.1.0.tgz
17
+ ```
18
+
19
+ 发布到 npm 后可改为:
20
+
21
+ ```bash
22
+ npm install @apolloyh/apollo-agent
23
+ ```
24
+
25
+ ## 长期对话
26
+
27
+ 一个 `QueryEngine` 对应一个对话。重复调用 `submitMessage()` 会保留历史、会话状态和缓存稳定前缀。
28
+
29
+ ```ts
30
+ import { createQueryEngine } from "@apolloyh/apollo-agent";
31
+
32
+ const engine = await createQueryEngine({
33
+ configPath: ".apollo/config.json",
34
+ envPath: ".apollo/.env",
35
+ onEvent(event) {
36
+ if (event.type === "assistant_delta") {
37
+ process.stdout.write(event.text);
38
+ }
39
+ },
40
+ });
41
+
42
+ try {
43
+ await engine.submitMessage("分析这个项目");
44
+ await engine.submitMessage("继续修复发现的问题");
45
+ } finally {
46
+ await engine.close();
47
+ }
48
+ ```
49
+
50
+ 必须调用 `close()`,它会关闭当前 Engine 持有的 MCP 连接。不要并发调用同一个 Engine 的 `submitMessage()`;每个独立对话使用独立 Engine。
51
+
52
+ ## 一次性调用
53
+
54
+ `runAgentTurn()` 创建临时 Engine,执行一次用户请求并自动关闭。一次请求内部仍可包含多轮模型与工具调用。
55
+
56
+ ```ts
57
+ import { runAgentTurn } from "@apolloyh/apollo-agent";
58
+
59
+ const result = await runAgentTurn({
60
+ input: "审查这个项目",
61
+ configPath: ".apollo/config.json",
62
+ envPath: ".apollo/.env",
63
+ });
64
+
65
+ console.log(result.text);
66
+ ```
67
+
68
+ ## 服务端推荐配置
69
+
70
+ `envPath` 会把文件内容加载到进程级 `process.env`。单用户应用可以使用;多租户服务应直接传入每个 Engine 的 `llmConfig`,避免不同租户共享环境变量。
71
+
72
+ ```ts
73
+ const engine = await createQueryEngine({
74
+ configPath: tenant.configPath,
75
+ llmConfig: {
76
+ authToken: tenant.modelApiKey,
77
+ baseUrl: "https://open.bigmodel.cn/api/anthropic",
78
+ model: "glm-5.2",
79
+ maxTokens: 4096,
80
+ timeoutMs: 300_000,
81
+ cacheTtl: "5m",
82
+ },
83
+ });
84
+ ```
85
+
86
+ 不要把 API Key 写入 `.apollo/config.json`、日志或会话消息。
87
+
88
+ ## `createQueryEngine()` 参数
89
+
90
+ | 参数 | 类型 | 说明 |
91
+ |---|---|---|
92
+ | `configPath` | `string` | Agent 配置路径;默认发现 `.apollo/config.json`,兼容旧 `agent.config.json` |
93
+ | `envPath` | `string` | 可选环境变量文件;未提供模型配置时默认发现 `.apollo/.env`,然后 `.env` |
94
+ | `agentConfig` | `AgentConfig` | 直接传入完整 Agent 配置;优先于 `configPath` |
95
+ | `llmConfig` | `LlmConfig` | 直接传入模型配置;优先于环境变量 |
96
+ | `onEvent` | `(event) => void` | 接收流式文本、工具、审批、子 Agent 和压缩事件 |
97
+ | `approvalProvider` | `async (request) => boolean` | 接入宿主系统权限审批 |
98
+ | `askUser` | `async (question, options?) => string` | 接入宿主系统问答 UI |
99
+ | `assumeYes` | `boolean \| (() => boolean)` | 使用默认审批器时自动批准;服务端不建议启用 |
100
+ | `stream` | `boolean \| (() => boolean)` | 是否使用模型流式响应,默认开启 |
101
+ | `sessionId` | `string` | 创建后立即恢复指定会话 |
102
+
103
+ 如果同时传入 `agentConfig` 和 `configPath`,使用 `agentConfig`;如果同时传入 `llmConfig` 和环境变量,使用 `llmConfig`。
104
+
105
+ ## 系统提示词与缓存
106
+
107
+ `.apollo/config.json` 可以配置:
108
+
109
+ ```json
110
+ {
111
+ "systemPrompt": "你是当前产品的项目 Agent。始终使用中文回答。"
112
+ }
113
+ ```
114
+
115
+ Engine 创建时读取配置,首次请求时拼接 System Prompt 和工具定义,随后在该 Engine 生命周期内冻结。修改配置文件不会影响已经存在的 Engine,必须关闭并创建新 Engine。
116
+
117
+ 运行中主要变化的是 `messages`,接近上下文上限时会执行语义压缩;稳定的 `system` 和 `tools` 有利于命中模型厂商的 Prompt Cache。
118
+
119
+ ## 流式事件
120
+
121
+ ```ts
122
+ const engine = await createQueryEngine({
123
+ configPath: ".apollo/config.json",
124
+ llmConfig,
125
+ onEvent(event) {
126
+ switch (event.type) {
127
+ case "assistant_delta":
128
+ websocket.send(JSON.stringify({ type: "text", text: event.text }));
129
+ break;
130
+ case "tool_call":
131
+ websocket.send(JSON.stringify({ type: "tool", name: event.tool, risk: event.risk }));
132
+ break;
133
+ case "task_progress":
134
+ websocket.send(JSON.stringify({ type: "task", message: event.message }));
135
+ break;
136
+ }
137
+ },
138
+ });
139
+ ```
140
+
141
+ 常用事件:
142
+
143
+ | 事件 | 用途 |
144
+ |---|---|
145
+ | `assistant_delta` | 流式回答文本 |
146
+ | `llm_request` / `llm_response` | 模型请求生命周期 |
147
+ | `llm_retry` | 自动重试或流式降级 |
148
+ | `tool_call` / `tool_result` | 工具执行状态 |
149
+ | `approval_required` / `approval_result` | 默认审批器状态 |
150
+ | `task_start` / `task_progress` / `task_finish` | 子 Agent 状态 |
151
+ | `context_compaction_start` / `context_compacted` | 上下文压缩状态 |
152
+ | `goal_status` / `workflow_status` / `plan_mode` | 运行模式状态 |
153
+
154
+ `onEvent` 可能包含工具参数或结果。转发到日志和前端前,应按宿主系统的数据策略脱敏。
155
+ 成功的 `write_file` 事件还会携带 `fileChange`,用于渲染新文件预览或彩色 diff;该字段不会发送给模型。
156
+
157
+ ## 权限审批
158
+
159
+ 自定义 `approvalProvider` 会接收每次工具调用。宿主系统应根据用户、工作区、工具和风险等级决定是否允许。
160
+
161
+ ```ts
162
+ const engine = await createQueryEngine({
163
+ configPath: ".apollo/config.json",
164
+ llmConfig,
165
+ approvalProvider: async (request) => {
166
+ if (request.risk === "low") return true;
167
+ return await permissions.askCurrentUser({
168
+ tool: request.toolName,
169
+ risk: request.risk,
170
+ reason: request.reason,
171
+ input: request.input,
172
+ });
173
+ },
174
+ });
175
+ ```
176
+
177
+ SDK 的权限边界属于应用层,不是操作系统沙箱。允许 `shell_exec` 或 MCP 后,进程仍拥有当前操作系统用户的权限。多租户或不可信用户场景需要额外使用容器或独立进程隔离。
178
+
179
+ ## 用户提问
180
+
181
+ ```ts
182
+ const engine = await createQueryEngine({
183
+ configPath: ".apollo/config.json",
184
+ llmConfig,
185
+ askUser: async (question, options) => {
186
+ return await ui.waitForAnswer({ question, options });
187
+ },
188
+ });
189
+ ```
190
+
191
+ 没有提供 `askUser` 时,Agent 会收到当前环境无法进行交互式提问的错误结果,并改为在最终回答中询问。
192
+
193
+ ## 会话恢复
194
+
195
+ CLI 与 CC 一样支持 `apollo -c` 继续当前项目最近会话,以及 `apollo -r [session-id]` 选择或恢复指定会话。交互模式也可以使用 `/sessions` 和 `/resume [session-id]`。省略 ID 时可用 ↑/↓ 选择会话、Enter 恢复;恢复后终端会重新显示可读的历史对话。
196
+
197
+ ```ts
198
+ const first = await createQueryEngine({ configPath, llmConfig });
199
+ await first.submitMessage("分析项目");
200
+ const sessionId = first.getSessionId();
201
+ await first.close();
202
+
203
+ const resumed = await createQueryEngine({
204
+ configPath,
205
+ llmConfig,
206
+ sessionId: sessionId!,
207
+ });
208
+
209
+ try {
210
+ await resumed.submitMessage("继续");
211
+ } finally {
212
+ await resumed.close();
213
+ }
214
+ ```
215
+
216
+ 会话默认保存在项目的 `.apollo/sessions/`。会话内容没有加密,不应保存秘密。
217
+
218
+ ## 常用 Engine 方法
219
+
220
+ | 方法 | 说明 |
221
+ |---|---|
222
+ | `submitMessage(input)` | 提交一条用户消息 |
223
+ | `close()` | 关闭 MCP 等运行资源 |
224
+ | `getSessionId()` | 获取当前会话 ID |
225
+ | `saveCurrentSession()` | 立即保存会话 |
226
+ | `resumeSession(id?)` | 恢复指定或最近会话 |
227
+ | `clearConversation()` | 清空当前对话,不删除长期记忆 |
228
+ | `getMessages()` | 获取当前消息数组;不要在请求执行期间修改 |
229
+ | `getUsageStats()` | 获取 Token、缓存和分类用量 |
230
+ | `compactConversation(force?)` | 主动执行语义压缩 |
231
+ | `enterPlanMode()` / `approvePlan()` | 控制计划模式 |
232
+ | `startGoal()` / `stopGoal()` | 控制目标模式 |
233
+ | `startWorkflow()` / `stopWorkflow()` | 控制工作流模式 |
234
+
235
+ ## 记忆与会话工具
236
+
237
+ SDK 还导出以下项目级函数:
238
+
239
+ ```ts
240
+ import {
241
+ saveMemory,
242
+ searchMemories,
243
+ listMemories,
244
+ listSessions,
245
+ loadSession,
246
+ loadLatestSession,
247
+ } from "@apolloyh/apollo-agent";
248
+ ```
249
+
250
+ 记忆保存在 `.apollo/memory/`,会话保存在 `.apollo/sessions/`。路径参数应使用对应项目的 `workspaceRoot`。
251
+
252
+ ## 集成原则
253
+
254
+ - 每个对话一个 Engine。
255
+ - 同一个 Engine 串行提交消息。
256
+ - 每个用户或租户使用独立 `workspaceRoot` 和 `llmConfig`。
257
+ - 应用退出、对话销毁或异常时始终调用 `close()`。
258
+ - 服务端使用 `approvalProvider`,不要启用 `assumeYes`。
259
+ - Node.js 之外的系统可在 SDK 外增加一层薄 HTTP/SSE 服务;Apollo SDK 本身不内置服务器。
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@apolloyh/apollo-agent",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Apollo — your personal agent. Answer first, act when needed. Claude Code–style Task subagents.",
6
+ "bin": {
7
+ "apollo": "./dist/index.js"
8
+ },
9
+ "main": "./dist/sdk.js",
10
+ "types": "./dist/sdk.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/sdk.d.ts",
14
+ "import": "./dist/sdk.js"
15
+ },
16
+ "./cli": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "src/skills/tech-research-skill",
24
+ "README.md",
25
+ "docs/sdk.md",
26
+ ".apollo/config.example.json",
27
+ ".env.example"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "prebuild": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
34
+ "build": "tsc -p tsconfig.json && node -e \"require('node:fs').chmodSync('dist/index.js', 0o755)\"",
35
+ "dev": "tsx src/index.ts",
36
+ "prepack": "npm run build",
37
+ "start": "node dist/index.js",
38
+ "test": "npm run build && node --test test/*.test.mjs",
39
+ "typecheck": "tsc -p tsconfig.json --noEmit"
40
+ },
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.29.0",
43
+ "diff": "^9.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^24.10.1",
47
+ "tsx": "^4.21.0",
48
+ "typescript": "^5.9.3"
49
+ },
50
+ "engines": {
51
+ "node": ">=20"
52
+ }
53
+ }