@coralai/sps-cli 0.89.19 → 0.89.21
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/dist/commands/memoryCommand.d.ts.map +1 -1
- package/dist/commands/memoryCommand.js +4 -6
- package/dist/commands/memoryCommand.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +1 -3
- package/dist/commands/setup.js.map +1 -1
- package/dist/console/index.d.ts.map +1 -1
- package/dist/console/index.js +0 -31
- package/dist/console/index.js.map +1 -1
- package/dist/console/routes/memory.d.ts.map +1 -1
- package/dist/console/routes/memory.js +0 -2
- package/dist/console/routes/memory.js.map +1 -1
- package/dist/console-assets/assets/{ShowcasePage-DjCtHHhI.js → ShowcasePage-DzgwRKax.js} +1 -1
- package/dist/console-assets/assets/{index-BzFo1jUx.js → index-B-uWfam_.js} +52 -52
- package/dist/console-assets/assets/{index-VWQXhVIx.css → index-BhH2rLIM.css} +1 -1
- package/dist/console-assets/index.html +2 -2
- package/dist/core/agents/ClaudeSdkBackend.d.ts.map +1 -1
- package/dist/core/agents/ClaudeSdkBackend.js +5 -0
- package/dist/core/agents/ClaudeSdkBackend.js.map +1 -1
- package/dist/core/memory2/capture.d.ts.map +1 -1
- package/dist/core/memory2/capture.js +1 -3
- package/dist/core/memory2/capture.js.map +1 -1
- package/dist/core/memory2/recallResult.d.ts +19 -0
- package/dist/core/memory2/recallResult.d.ts.map +1 -0
- package/dist/core/memory2/recallResult.js +33 -0
- package/dist/core/memory2/recallResult.js.map +1 -0
- package/dist/manager/worker-manager-impl.d.ts.map +1 -1
- package/dist/manager/worker-manager-impl.js +0 -15
- package/dist/manager/worker-manager-impl.js.map +1 -1
- package/dist/providers/RuntimeSessionRuntime.d.ts.map +1 -1
- package/dist/providers/RuntimeSessionRuntime.js +0 -1
- package/dist/providers/RuntimeSessionRuntime.js.map +1 -1
- package/dist/providers/mcp/spsMcpServer.d.ts.map +1 -1
- package/dist/providers/mcp/spsMcpServer.js +4 -36
- package/dist/providers/mcp/spsMcpServer.js.map +1 -1
- package/dist/runtime/backends/claude/ClaudeBackend.d.ts.map +1 -1
- package/dist/runtime/backends/claude/ClaudeBackend.js +4 -2
- package/dist/runtime/backends/claude/ClaudeBackend.js.map +1 -1
- package/dist/seams/memory-local/client.js +2 -2
- package/dist/services/MemoryService.d.ts +2 -7
- package/dist/services/MemoryService.d.ts.map +1 -1
- package/dist/services/MemoryService.js +3 -14
- package/dist/services/MemoryService.js.map +1 -1
- package/dist/services/SystemService.d.ts +1 -1
- package/dist/services/SystemService.d.ts.map +1 -1
- package/dist/services/SystemService.js +15 -16
- package/dist/services/SystemService.js.map +1 -1
- package/docs/help/02-commands.md +2 -2
- package/docs/help/05-api.md +2 -4
- package/package.json +2 -1
- package/dist/core/memory2/external/agentMemory.d.ts +0 -35
- package/dist/core/memory2/external/agentMemory.d.ts.map +0 -1
- package/dist/core/memory2/external/agentMemory.js +0 -127
- package/dist/core/memory2/external/agentMemory.js.map +0 -1
- package/dist/core/memory2/external/federate.d.ts +0 -23
- package/dist/core/memory2/external/federate.d.ts.map +0 -1
- package/dist/core/memory2/external/federate.js +0 -43
- package/dist/core/memory2/external/federate.js.map +0 -1
- package/dist/core/memory2/external/importTranscript.d.ts +0 -7
- package/dist/core/memory2/external/importTranscript.d.ts.map +0 -1
- package/dist/core/memory2/external/importTranscript.js +0 -44
- package/dist/core/memory2/external/importTranscript.js.map +0 -1
package/docs/help/05-api.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: 开放 API
|
|
3
3
|
generated: true
|
|
4
4
|
source: src/console/routes/*.ts
|
|
5
|
-
version: 0.89.
|
|
5
|
+
version: 0.89.21
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# 开放 API
|
|
@@ -10,7 +10,7 @@ version: 0.89.19
|
|
|
10
10
|
> ⚠️ **本页由 `scripts/gen-help-api.mjs` 从路由代码扫出,不要手改。**
|
|
11
11
|
> 门禁 `check:help` 会在代码与本页不一致时报红。
|
|
12
12
|
|
|
13
|
-
共 **
|
|
13
|
+
共 **175** 条路由(其中 110 条尚无说明)。版本 `0.89.21`。
|
|
14
14
|
|
|
15
15
|
> ℹ️ 口径:这里**逐条列**(同一路径的不同方法算两条)。门禁 `check:api-docs` 报的是
|
|
16
16
|
> **归一去重后的唯一路径数**,两个数字不相等是正常的 —— 别拿它们互相"对账"。
|
|
@@ -173,7 +173,6 @@ version: 0.89.19
|
|
|
173
173
|
| `GET` | `/api/memory/entries` | — |
|
|
174
174
|
| `GET` | `/api/memory/recall` | — |
|
|
175
175
|
| `GET` | `/api/memory/digest` | — |
|
|
176
|
-
| `GET` | `/api/memory/external` | 外部派生智能(agentmemory profile + graph);external 未启用返 {profile:null,graph:null}。 |
|
|
177
176
|
| `GET` | `/api/memory/entries/:id` | — |
|
|
178
177
|
| `POST` | `/api/memory/entries` | — |
|
|
179
178
|
| `DELETE` | `/api/memory/entries/:id` | — |
|
|
@@ -378,7 +377,6 @@ version: 0.89.19
|
|
|
378
377
|
|
|
379
378
|
| 方法 | 路径 | 说明 |
|
|
380
379
|
|---|---|---|
|
|
381
|
-
| `GET` | `/api/memory-cfg` | 记忆 viewer 配置:设了 SPS_CONSOLE_MEMORY_VIEWER_URL(如 https://mem.coralbot.top,反代 agentmemory 仪表板 :3113)→ 前端 iframe 内嵌该仪表板;没设 |
|
|
382
380
|
| `GET` | `/docs` | — |
|
|
383
381
|
| `GET` | `/docs/*` | 命不中静态文件 → 回 docs 的 404 页(而不是落到 console SPA)。 |
|
|
384
382
|
| `GET` | `/` | — |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coralai/sps-cli",
|
|
3
|
-
"version": "0.89.
|
|
3
|
+
"version": "0.89.21",
|
|
4
4
|
"description": "SPS CLI — AI-driven development pipeline orchestrator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"build:packages": "for d in packages/*/; do (cd \"$d\" && npx tsc -p tsconfig.json) || exit 1; done",
|
|
28
28
|
"build:seam-clients": "node scripts/build-seam-clients.mjs",
|
|
29
29
|
"gen:help": "node scripts/gen-help-commands.mjs && node scripts/gen-help-api.mjs",
|
|
30
|
+
"version": "npm run gen:help && git add docs/help",
|
|
30
31
|
"check:help": "node scripts/gen-help-commands.mjs --check && node scripts/gen-help-api.mjs --check"
|
|
31
32
|
},
|
|
32
33
|
"engines": {
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/** external 是否启用:mode 含 external + 配了 URL。 */
|
|
2
|
-
export declare function externalEnabled(): boolean;
|
|
3
|
-
export interface ExternalHit {
|
|
4
|
-
id: string;
|
|
5
|
-
title: string;
|
|
6
|
-
score: number;
|
|
7
|
-
type?: string;
|
|
8
|
-
timestamp?: string;
|
|
9
|
-
}
|
|
10
|
-
/** 相关性检索 agentmemory(POST /smart-search)。不可用/失败 → 返 []。 */
|
|
11
|
-
export declare function externalRecall(query: string, limit?: number): Promise<ExternalHit[]>;
|
|
12
|
-
/** 尽力把一条记忆镜像进 agentmemory(POST /remember)。project 让其 per-project profile/graph 能按项目归类。
|
|
13
|
-
* fire-and-forget,返回是否成功(仅日志用)。注:线上实例 type/tags 不认,只可靠 content+project+title。 */
|
|
14
|
-
export declare function externalRemember(content: string, opts?: {
|
|
15
|
-
title?: string;
|
|
16
|
-
project?: string;
|
|
17
|
-
}): Promise<boolean>;
|
|
18
|
-
/** 转发一条 worker 工具观测到 agentmemory(POST /observe),喂它的 profile/graph 长出跨会话智能。
|
|
19
|
-
* 红线:只送归一化事件里有的 toolName/detail,不碰 jsonl(无 tool 完整 input/output)。best-effort。 */
|
|
20
|
-
export declare function externalObserve(o: {
|
|
21
|
-
sessionId: string;
|
|
22
|
-
project: string;
|
|
23
|
-
cwd: string;
|
|
24
|
-
toolName: string;
|
|
25
|
-
output?: string;
|
|
26
|
-
}): Promise<boolean>;
|
|
27
|
-
/** 项目画像:top 概念/文件/惯例/常见错。null=不可用。 */
|
|
28
|
-
export declare function externalProfile(project: string): Promise<unknown | null>;
|
|
29
|
-
/** 知识图谱查询(BFS 遍历)。返回 {edges,depth} 或 null。 */
|
|
30
|
-
export declare function externalGraph(query?: Record<string, unknown>): Promise<unknown | null>;
|
|
31
|
-
/** 抽取的实体关系。 */
|
|
32
|
-
export declare function externalRelations(limit?: number): Promise<unknown | null>;
|
|
33
|
-
/** 识别的重复模式(按 project)。 */
|
|
34
|
-
export declare function externalPatterns(project: string): Promise<unknown | null>;
|
|
35
|
-
//# sourceMappingURL=agentMemory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agentMemory.d.ts","sourceRoot":"","sources":["../../../../src/core/memory2/external/agentMemory.ts"],"names":[],"mappings":"AAWA,8CAA8C;AAC9C,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AA6BD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2DAA2D;AAC3D,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CASrF;AAED;kFACkF;AAClF,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAOzH;AAED;kFACkF;AAClF,wBAAsB,eAAe,CAAC,CAAC,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACpF,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnB;AAoBD,sCAAsC;AACtC,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAI9E;AAED,8CAA8C;AAC9C,wBAAsB,aAAa,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAGhG;AAED,eAAe;AACf,wBAAsB,iBAAiB,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAI3E;AAED,0BAA0B;AAC1B,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAI/E"}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/external/agentMemory
|
|
3
|
-
* @description external 后端适配器:agentmemory(设计 §8 的 external/local+external)。
|
|
4
|
-
* 读 = POST /smart-search;写 = POST /remember(content 必填)。**本地始终真源**,
|
|
5
|
-
* 此适配器是可选增补:读做候选合并、写做尽力镜像,**任何失败/超时都静默降级、绝不阻断**
|
|
6
|
-
* (agentmemory 后端本身可能抖动)。URL 取 SPS_MEMORY_EXTERNAL_URL;mode 含 external 才启用。
|
|
7
|
-
* @layer core
|
|
8
|
-
* @boundedContext memory
|
|
9
|
-
*/
|
|
10
|
-
import { memoryEnv, memoryMode } from '../config.js';
|
|
11
|
-
/** external 是否启用:mode 含 external + 配了 URL。 */
|
|
12
|
-
export function externalEnabled() {
|
|
13
|
-
const m = memoryMode();
|
|
14
|
-
return (m === 'external' || m === 'local+external') && !!externalUrl();
|
|
15
|
-
}
|
|
16
|
-
function externalUrl() {
|
|
17
|
-
return (memoryEnv('SPS_MEMORY_EXTERNAL_URL') ?? '').replace(/\/+$/, '');
|
|
18
|
-
}
|
|
19
|
-
const RECALL_TIMEOUT_MS = 2500;
|
|
20
|
-
const WRITE_TIMEOUT_MS = 3000;
|
|
21
|
-
async function postJson(path, body, timeoutMs) {
|
|
22
|
-
const url = externalUrl();
|
|
23
|
-
if (!url)
|
|
24
|
-
return null;
|
|
25
|
-
const ac = new AbortController();
|
|
26
|
-
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
|
27
|
-
try {
|
|
28
|
-
const r = await fetch(`${url}${path}`, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: { 'content-type': 'application/json' },
|
|
31
|
-
body: JSON.stringify(body),
|
|
32
|
-
signal: ac.signal,
|
|
33
|
-
});
|
|
34
|
-
if (!r.ok)
|
|
35
|
-
return null;
|
|
36
|
-
return await r.json();
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return null; // 超时 / 网络 / 解析失败 → 静默降级
|
|
40
|
-
}
|
|
41
|
-
finally {
|
|
42
|
-
clearTimeout(timer);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
/** 相关性检索 agentmemory(POST /smart-search)。不可用/失败 → 返 []。 */
|
|
46
|
-
export async function externalRecall(query, limit = 6) {
|
|
47
|
-
if (!externalEnabled() || !query.trim())
|
|
48
|
-
return [];
|
|
49
|
-
const data = await postJson('/smart-search', { query, limit }, RECALL_TIMEOUT_MS);
|
|
50
|
-
if (!data?.results)
|
|
51
|
-
return [];
|
|
52
|
-
return data.results
|
|
53
|
-
.filter((r) => r.obsId && r.title)
|
|
54
|
-
.map((r) => ({ id: `ext:${r.obsId}`, title: String(r.title), score: Number(r.score ?? 0), type: r.type, timestamp: r.timestamp }));
|
|
55
|
-
}
|
|
56
|
-
/** 尽力把一条记忆镜像进 agentmemory(POST /remember)。project 让其 per-project profile/graph 能按项目归类。
|
|
57
|
-
* fire-and-forget,返回是否成功(仅日志用)。注:线上实例 type/tags 不认,只可靠 content+project+title。 */
|
|
58
|
-
export async function externalRemember(content, opts = {}) {
|
|
59
|
-
if (!externalEnabled() || !content.trim())
|
|
60
|
-
return false;
|
|
61
|
-
const body = { content };
|
|
62
|
-
if (opts.title)
|
|
63
|
-
body.title = opts.title;
|
|
64
|
-
if (opts.project)
|
|
65
|
-
body.project = opts.project;
|
|
66
|
-
const data = await postJson('/remember', body, WRITE_TIMEOUT_MS);
|
|
67
|
-
return data != null;
|
|
68
|
-
}
|
|
69
|
-
/** 转发一条 worker 工具观测到 agentmemory(POST /observe),喂它的 profile/graph 长出跨会话智能。
|
|
70
|
-
* 红线:只送归一化事件里有的 toolName/detail,不碰 jsonl(无 tool 完整 input/output)。best-effort。 */
|
|
71
|
-
export async function externalObserve(o) {
|
|
72
|
-
if (!externalEnabled())
|
|
73
|
-
return false;
|
|
74
|
-
const data = await postJson('/observe', {
|
|
75
|
-
hookType: 'PostToolUse', sessionId: o.sessionId, project: o.project, cwd: o.cwd,
|
|
76
|
-
timestamp: `${Date.now()}`, toolName: o.toolName, output: o.output ?? '',
|
|
77
|
-
}, WRITE_TIMEOUT_MS);
|
|
78
|
-
return data != null;
|
|
79
|
-
}
|
|
80
|
-
async function getJson(path, timeoutMs = RECALL_TIMEOUT_MS) {
|
|
81
|
-
const url = externalUrl();
|
|
82
|
-
if (!url)
|
|
83
|
-
return null;
|
|
84
|
-
const ac = new AbortController();
|
|
85
|
-
const timer = setTimeout(() => ac.abort(), timeoutMs);
|
|
86
|
-
try {
|
|
87
|
-
const r = await fetch(`${url}${path}`, { signal: ac.signal });
|
|
88
|
-
if (!r.ok)
|
|
89
|
-
return null;
|
|
90
|
-
return await r.json();
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
finally {
|
|
96
|
-
clearTimeout(timer);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// ─── 派生智能(agentmemory 跨会话算出、本地产不出的)——只读,external 启用才有 ───
|
|
100
|
-
/** 项目画像:top 概念/文件/惯例/常见错。null=不可用。 */
|
|
101
|
-
export async function externalProfile(project) {
|
|
102
|
-
if (!externalEnabled() || !project)
|
|
103
|
-
return null;
|
|
104
|
-
const d = await getJson(`/profile?project=${encodeURIComponent(project)}`);
|
|
105
|
-
return d?.profile ?? null;
|
|
106
|
-
}
|
|
107
|
-
/** 知识图谱查询(BFS 遍历)。返回 {edges,depth} 或 null。 */
|
|
108
|
-
export async function externalGraph(query = {}) {
|
|
109
|
-
if (!externalEnabled())
|
|
110
|
-
return null;
|
|
111
|
-
return postJson('/graph/query', query, RECALL_TIMEOUT_MS);
|
|
112
|
-
}
|
|
113
|
-
/** 抽取的实体关系。 */
|
|
114
|
-
export async function externalRelations(limit = 20) {
|
|
115
|
-
if (!externalEnabled())
|
|
116
|
-
return null;
|
|
117
|
-
const d = await getJson(`/relations?limit=${limit}`);
|
|
118
|
-
return d?.relations ?? null;
|
|
119
|
-
}
|
|
120
|
-
/** 识别的重复模式(按 project)。 */
|
|
121
|
-
export async function externalPatterns(project) {
|
|
122
|
-
if (!externalEnabled() || !project)
|
|
123
|
-
return null;
|
|
124
|
-
const d = await postJson('/patterns', { project }, RECALL_TIMEOUT_MS);
|
|
125
|
-
return d?.patterns ?? null;
|
|
126
|
-
}
|
|
127
|
-
//# sourceMappingURL=agentMemory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agentMemory.js","sourceRoot":"","sources":["../../../../src/core/memory2/external/agentMemory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { ScopeRef } from '../types.js';
|
|
2
|
-
export interface FederatedHit {
|
|
3
|
-
id: string;
|
|
4
|
-
source: 'local' | 'external';
|
|
5
|
-
title: string;
|
|
6
|
-
snippet: string;
|
|
7
|
-
score: number;
|
|
8
|
-
scope?: string;
|
|
9
|
-
project?: string;
|
|
10
|
-
category?: string;
|
|
11
|
-
tags?: string[];
|
|
12
|
-
type?: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* 融合召回:本地(含 FTS)+ agentmemory,RRF 交错。mode 决定权重:
|
|
16
|
-
* - local:纯本地;external:纯外部;local+external:两者 RRF 合并。
|
|
17
|
-
* external 关或不可用时自动只出本地。
|
|
18
|
-
*/
|
|
19
|
-
export declare function recallFederated(refs: ScopeRef[], query: string, opts?: {
|
|
20
|
-
tags?: string[];
|
|
21
|
-
limit?: number;
|
|
22
|
-
}): Promise<FederatedHit[]>;
|
|
23
|
-
//# sourceMappingURL=federate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"federate.d.ts","sourceRoot":"","sources":["../../../../src/core/memory2/external/federate.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,YAAY,EAAE,CAAC,CA0BzB"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/external/federate
|
|
3
|
-
* @description local+external 召回融合(设计 §8)。本地 BM25 分与 agentmemory cosine 分**不可比**,
|
|
4
|
-
* 用 RRF(Reciprocal Rank Fusion)只按各自排名交错,天然归一。external 未启用 → 纯本地。
|
|
5
|
-
* external 失败/超时 → 静默退化为纯本地(externalRecall 内部已兜底返 [])。
|
|
6
|
-
* @layer core
|
|
7
|
-
* @boundedContext memory
|
|
8
|
-
*/
|
|
9
|
-
import { recall } from '../retrieve.js';
|
|
10
|
-
import { externalEnabled, externalRecall } from './agentMemory.js';
|
|
11
|
-
const RRF_K = 60;
|
|
12
|
-
/**
|
|
13
|
-
* 融合召回:本地(含 FTS)+ agentmemory,RRF 交错。mode 决定权重:
|
|
14
|
-
* - local:纯本地;external:纯外部;local+external:两者 RRF 合并。
|
|
15
|
-
* external 关或不可用时自动只出本地。
|
|
16
|
-
*/
|
|
17
|
-
export async function recallFederated(refs, query, opts = {}) {
|
|
18
|
-
const limit = opts.limit ?? 6;
|
|
19
|
-
const mode = externalEnabled();
|
|
20
|
-
const local = recall(refs, query, { tags: opts.tags, limit: limit * 2 });
|
|
21
|
-
const localHits = local.map((h, i) => ({
|
|
22
|
-
id: `local:${h.entry.id}`, source: 'local', title: h.entry.title,
|
|
23
|
-
snippet: h.entry.body.slice(0, 200), score: 1 / (RRF_K + i),
|
|
24
|
-
scope: h.entry.scope, project: h.entry.project, category: h.entry.category, tags: h.entry.tags,
|
|
25
|
-
}));
|
|
26
|
-
if (!mode)
|
|
27
|
-
return localHits.slice(0, limit).map((h, i) => ({ ...h, score: 1 / (RRF_K + i) }));
|
|
28
|
-
const ext = await externalRecall(query, limit * 2);
|
|
29
|
-
const extHits = ext.map((e, i) => ({
|
|
30
|
-
id: e.id, source: 'external', title: e.title, snippet: e.title, score: 1 / (RRF_K + i), type: e.type,
|
|
31
|
-
}));
|
|
32
|
-
// RRF 合并:两列表各自 1/(k+rank),同 id 相加(此处两列 id 空间不交,等于公平交错)。
|
|
33
|
-
const merged = new Map();
|
|
34
|
-
for (const h of [...localHits, ...extHits]) {
|
|
35
|
-
const prev = merged.get(h.id);
|
|
36
|
-
if (prev)
|
|
37
|
-
prev.score += h.score;
|
|
38
|
-
else
|
|
39
|
-
merged.set(h.id, { ...h });
|
|
40
|
-
}
|
|
41
|
-
return [...merged.values()].sort((a, b) => b.score - a.score).slice(0, limit);
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=federate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"federate.js","sourceRoot":"","sources":["../../../../src/core/memory2/external/federate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* best-effort 把某会话 transcript 导入 agentmemory。异步 spawn,立即返回,失败静默。
|
|
3
|
-
* @param cwd worker 的工作目录(游戏 repo)——用于定位 claude transcript 目录。
|
|
4
|
-
* @param sessionId 该 worker 的 claude sessionId。
|
|
5
|
-
*/
|
|
6
|
-
export declare function importSessionToExternal(cwd: string, sessionId: string | null | undefined): void;
|
|
7
|
-
//# sourceMappingURL=importTranscript.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importTranscript.d.ts","sourceRoot":"","sources":["../../../../src/core/memory2/external/importTranscript.ts"],"names":[],"mappings":"AAwBA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAY/F"}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module core/memory2/external/importTranscript
|
|
3
|
-
* @description 方案 C:卡/会话完成时,把该 worker 会话的**完整 claude transcript** 交给
|
|
4
|
-
* `agentmemory import-jsonl` 导入 → agentmemory 用它自己的 LLM 压成全 I/O 观测、按项目归类
|
|
5
|
-
* (补齐 agentmemory 的 session/timeline/profile/graph)。
|
|
6
|
-
* 🔴 红线:sps **不解析 jsonl**,只用现成 sanctioned helper(runtimePaths.claudeJsonlFile)定位路径,
|
|
7
|
-
* 把路径交给 agentmemory 自己读。best-effort、异步、失败静默、不阻断流水线。
|
|
8
|
-
* 门控:external 启用 + SPS_MEMORY_IMPORT=on + `agentmemory` CLI 存在。import-jsonl 自带 dedup,重导安全。
|
|
9
|
-
* @layer core
|
|
10
|
-
* @boundedContext memory
|
|
11
|
-
*/
|
|
12
|
-
import { execFile } from 'node:child_process';
|
|
13
|
-
import { existsSync } from 'node:fs';
|
|
14
|
-
import { claudeJsonlFile } from '../../../shared/runtimePaths.js';
|
|
15
|
-
import { memoryEnv } from '../config.js';
|
|
16
|
-
import { externalEnabled } from './agentMemory.js';
|
|
17
|
-
/** 是否启用完成时导入(SPS_MEMORY_IMPORT=on 且 external 启用)。 */
|
|
18
|
-
function importEnabled() {
|
|
19
|
-
return externalEnabled() && (memoryEnv('SPS_MEMORY_IMPORT') ?? '').toLowerCase() === 'on';
|
|
20
|
-
}
|
|
21
|
-
let cliMissing = false; // 探测过一次 agentmemory 不存在就不再试
|
|
22
|
-
/**
|
|
23
|
-
* best-effort 把某会话 transcript 导入 agentmemory。异步 spawn,立即返回,失败静默。
|
|
24
|
-
* @param cwd worker 的工作目录(游戏 repo)——用于定位 claude transcript 目录。
|
|
25
|
-
* @param sessionId 该 worker 的 claude sessionId。
|
|
26
|
-
*/
|
|
27
|
-
export function importSessionToExternal(cwd, sessionId) {
|
|
28
|
-
if (cliMissing || !importEnabled() || !sessionId || !cwd)
|
|
29
|
-
return;
|
|
30
|
-
const file = claudeJsonlFile(cwd, sessionId); // 现成 helper,不自算编码
|
|
31
|
-
if (!existsSync(file))
|
|
32
|
-
return;
|
|
33
|
-
try {
|
|
34
|
-
execFile('agentmemory', ['import-jsonl', file], { timeout: 180000 }, (err) => {
|
|
35
|
-
// ENOENT = 没装 agentmemory CLI → 标记,后续不再试。其余失败静默(best-effort)。
|
|
36
|
-
if (err && err.code === 'ENOENT')
|
|
37
|
-
cliMissing = true;
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
/* spawn 失败也静默 */
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=importTranscript.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importTranscript.js","sourceRoot":"","sources":["../../../../src/core/memory2/external/importTranscript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qDAAqD;AACrD,SAAS,aAAa;IACpB,OAAO,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC;AAC5F,CAAC;AAED,IAAI,UAAU,GAAG,KAAK,CAAC,CAAC,4BAA4B;AAEpD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW,EAAE,SAAoC;IACvF,IAAI,UAAU,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG;QAAE,OAAO;IACjE,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,kBAAkB;IAChE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO;IAC9B,IAAI,CAAC;QACH,QAAQ,CAAC,aAAa,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;YAC3E,8DAA8D;YAC9D,IAAI,GAAG,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,UAAU,GAAG,IAAI,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC"}
|