@whispering233/ai-editor-agent 0.0.30 → 0.0.33
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/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -9
- package/dist/index.js.map +1 -1
- package/dist/runtime/events.d.ts +21 -0
- package/dist/runtime/events.d.ts.map +1 -0
- package/dist/runtime/events.js +235 -0
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/index.d.ts +11 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +12 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/message-projection.d.ts +57 -0
- package/dist/runtime/message-projection.d.ts.map +1 -0
- package/dist/runtime/message-projection.js +94 -0
- package/dist/runtime/message-projection.js.map +1 -0
- package/dist/runtime/paths.d.ts +11 -0
- package/dist/runtime/paths.d.ts.map +1 -0
- package/dist/runtime/paths.js +23 -0
- package/dist/runtime/paths.js.map +1 -0
- package/dist/runtime/project-runtime.d.ts +57 -0
- package/dist/runtime/project-runtime.d.ts.map +1 -0
- package/dist/runtime/project-runtime.js +78 -0
- package/dist/runtime/project-runtime.js.map +1 -0
- package/dist/runtime/proposals.d.ts +85 -0
- package/dist/runtime/proposals.d.ts.map +1 -0
- package/dist/runtime/proposals.js +173 -0
- package/dist/runtime/proposals.js.map +1 -0
- package/dist/runtime/resources.d.ts +14 -0
- package/dist/runtime/resources.d.ts.map +1 -0
- package/dist/runtime/resources.js +39 -0
- package/dist/runtime/resources.js.map +1 -0
- package/dist/runtime/sessions.d.ts +35 -0
- package/dist/runtime/sessions.d.ts.map +1 -0
- package/dist/runtime/sessions.js +89 -0
- package/dist/runtime/sessions.js.map +1 -0
- package/dist/{prompts.d.ts → runtime/system-prompt.d.ts} +4 -12
- package/dist/runtime/system-prompt.d.ts.map +1 -0
- package/dist/runtime/system-prompt.js +22 -0
- package/dist/runtime/system-prompt.js.map +1 -0
- package/dist/runtime/tool-result.d.ts +12 -0
- package/dist/runtime/tool-result.d.ts.map +1 -0
- package/dist/runtime/tool-result.js +53 -0
- package/dist/runtime/tool-result.js.map +1 -0
- package/dist/runtime/tools.d.ts +28 -0
- package/dist/runtime/tools.d.ts.map +1 -0
- package/dist/runtime/tools.js +54 -0
- package/dist/runtime/tools.js.map +1 -0
- package/package.json +5 -4
- package/dist/context.d.ts +0 -96
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -149
- package/dist/context.js.map +0 -1
- package/dist/executor.d.ts +0 -86
- package/dist/executor.d.ts.map +0 -1
- package/dist/executor.js +0 -259
- package/dist/executor.js.map +0 -1
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -29
- package/dist/prompts.js.map +0 -1
- package/dist/run.d.ts +0 -182
- package/dist/run.d.ts.map +0 -1
- package/dist/run.js +0 -430
- package/dist/run.js.map +0 -1
- package/dist/session.d.ts +0 -60
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -204
- package/dist/session.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/runtime/system-prompt.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,kEAAkE;AAClE,+CAA+C;AAC/C,EAAE;AACF,0CAA0C;AAE1C,gEAAgE;AAChE,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;gBAWb,CAAC;AAEjB,+CAA+C;AAC/C,MAAM,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** 单条工具结果 token 上限(不可配——失控保护常量,见 docs/design/config.md) */
|
|
2
|
+
export declare const TOOL_RESULT_MAX_TOKENS = 8000;
|
|
3
|
+
/**
|
|
4
|
+
* 保守 token 估算:ASCII 按 4 字符 ≈ 1 token,非 ASCII(CJK 等)按 1 字符 ≈ 1 token。
|
|
5
|
+
* 中文真实密度约 1 字 ≈ 0.6 token——**故意高估**:预算宁可保守(截断偏早优于超窗)。
|
|
6
|
+
*/
|
|
7
|
+
export declare function estimateTokens(text: string): number;
|
|
8
|
+
/** 工具返回值 → 回填文本(字符串原样;其余 JSON 序列化;不可序列化 → String()) */
|
|
9
|
+
export declare function stringifyToolResult(result: unknown): string;
|
|
10
|
+
/** 超上限 → 截断 + 结构化提示(未超限原样返回) */
|
|
11
|
+
export declare function truncateToolResultText(text: string, maxTokens?: number): string;
|
|
12
|
+
//# sourceMappingURL=tool-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result.d.ts","sourceRoot":"","sources":["../../src/runtime/tool-result.ts"],"names":[],"mappings":"AAMA,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,uDAAuD;AACvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAQ3D;AAYD,gCAAgC;AAChC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,GAAE,MAA+B,GAAG,MAAM,CAKvG"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// pi 运行时:工具结果文本化与截断
|
|
2
|
+
//
|
|
3
|
+
// pi 只对内置工具做输出截断;自定义工具必须自己控制回填给模型的文本量,
|
|
4
|
+
// 否则 `get_outline` 整树 / `query_relationships` depth=3 会撑爆上下文。
|
|
5
|
+
// 契约(docs/design/20-context.md §2):超上限即截断 + **显式告知**(模型必须知道数据不完整)。
|
|
6
|
+
/** 单条工具结果 token 上限(不可配——失控保护常量,见 docs/design/config.md) */
|
|
7
|
+
export const TOOL_RESULT_MAX_TOKENS = 8000;
|
|
8
|
+
/**
|
|
9
|
+
* 保守 token 估算:ASCII 按 4 字符 ≈ 1 token,非 ASCII(CJK 等)按 1 字符 ≈ 1 token。
|
|
10
|
+
* 中文真实密度约 1 字 ≈ 0.6 token——**故意高估**:预算宁可保守(截断偏早优于超窗)。
|
|
11
|
+
*/
|
|
12
|
+
export function estimateTokens(text) {
|
|
13
|
+
let ascii = 0;
|
|
14
|
+
let wide = 0;
|
|
15
|
+
for (let i = 0; i < text.length; i++) {
|
|
16
|
+
if (text.charCodeAt(i) < 128)
|
|
17
|
+
ascii++;
|
|
18
|
+
else
|
|
19
|
+
wide++;
|
|
20
|
+
}
|
|
21
|
+
return Math.ceil(ascii / 4) + wide;
|
|
22
|
+
}
|
|
23
|
+
/** 工具返回值 → 回填文本(字符串原样;其余 JSON 序列化;不可序列化 → String()) */
|
|
24
|
+
export function stringifyToolResult(result) {
|
|
25
|
+
if (typeof result === "string")
|
|
26
|
+
return result;
|
|
27
|
+
try {
|
|
28
|
+
const json = JSON.stringify(result);
|
|
29
|
+
return json === undefined ? String(result) : json;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return String(result);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** 按 token 预算截断前缀(宽字符按 1 token 计,逐字符累计) */
|
|
36
|
+
function cutToTokenBudget(text, maxTokens) {
|
|
37
|
+
let tokens = 0;
|
|
38
|
+
for (let i = 0; i < text.length; i++) {
|
|
39
|
+
tokens += text.charCodeAt(i) < 128 ? 0.25 : 1;
|
|
40
|
+
if (tokens > maxTokens)
|
|
41
|
+
return text.slice(0, i);
|
|
42
|
+
}
|
|
43
|
+
return text;
|
|
44
|
+
}
|
|
45
|
+
/** 超上限 → 截断 + 结构化提示(未超限原样返回) */
|
|
46
|
+
export function truncateToolResultText(text, maxTokens = TOOL_RESULT_MAX_TOKENS) {
|
|
47
|
+
const tokens = estimateTokens(text);
|
|
48
|
+
if (tokens <= maxTokens)
|
|
49
|
+
return text;
|
|
50
|
+
const head = cutToTokenBudget(text, maxTokens);
|
|
51
|
+
return `${head}\n\n[工具结果已截断:原始约 ${tokens} tokens,超出单条上限 ${maxTokens} tokens,当前数据不完整。请缩小查询范围或分页获取后重试。]`;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tool-result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result.js","sourceRoot":"","sources":["../../src/runtime/tool-result.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,EAAE;AACF,uCAAuC;AACvC,8DAA8D;AAC9D,mEAAmE;AAEnE,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG;YAAE,KAAK,EAAE,CAAC;;YACjC,IAAI,EAAE,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;AACrC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED,2CAA2C;AAC3C,SAAS,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IACvD,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,MAAM,GAAG,SAAS;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,YAAoB,sBAAsB;IAC7F,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,OAAO,GAAG,IAAI,oBAAoB,MAAM,kBAAkB,SAAS,mCAAmC,CAAC;AACzG,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ToolDefinition as PiToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type ToolContext } from "@whispering233/ai-editor-tools";
|
|
3
|
+
/** 提案载荷(`propose_*` 工具的 details;推送前端的形态见 docs/api/80-api-chat.md) */
|
|
4
|
+
export interface ProposalPayload {
|
|
5
|
+
proposal_id: string;
|
|
6
|
+
type: string;
|
|
7
|
+
preview: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/** 提案登记入参(K3 的提案仓消费:可据此重建完整 Proposal 并入仓;未接线返回 undefined) */
|
|
10
|
+
export interface ProposalSinkInput {
|
|
11
|
+
toolName: string;
|
|
12
|
+
toolCallId: string;
|
|
13
|
+
/** 校验/coerce 后的工具参数(重建 Proposal 需要,与 run 内部同源) */
|
|
14
|
+
params: unknown;
|
|
15
|
+
/** run 的返回值(propose_* 为 `{ proposal_id, summary }`,不含预览细节) */
|
|
16
|
+
result: unknown;
|
|
17
|
+
toolContext: ToolContext;
|
|
18
|
+
}
|
|
19
|
+
/** 提案登记回调(K2 只留接线点,缺省 no-op;K3 接提案仓) */
|
|
20
|
+
export type ProposalSink = (input: ProposalSinkInput) => ProposalPayload | undefined;
|
|
21
|
+
export interface CreateCustomToolsOptions {
|
|
22
|
+
toolContext: ToolContext;
|
|
23
|
+
proposalSink?: ProposalSink;
|
|
24
|
+
}
|
|
25
|
+
/** registry 全部工具 → pi 工具定义(顺序 = listTools 的稳定序) */
|
|
26
|
+
export declare function createCustomTools(options: CreateCustomToolsOptions): PiToolDefinition[];
|
|
27
|
+
/** 工具参数 schema 类型(测试/调用方按需引用) */
|
|
28
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/runtime/tools.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,IAAI,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAE1F,OAAO,EAAa,KAAK,WAAW,EAA+C,MAAM,gCAAgC,CAAC;AAG1H,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,6DAA6D;AAC7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wCAAwC;AACxC,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,iBAAiB,KAAK,eAAe,GAAG,SAAS,CAAC;AAErF,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AA4CD,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,gBAAgB,EAAE,CAEvF;AAED,iCAAiC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// pi 运行时:领域工具 → pi 工具定义(TypeBox 直通,不转换)
|
|
2
|
+
//
|
|
3
|
+
// 适配面很薄:name/label/description/parameters 直通;execute 注入 ToolContext(db/outlineDir/projectId),
|
|
4
|
+
// 把 tools 包的返回值文本化回填并做截断;PROPOSAL 权限工具的提案载荷走 `details`(K3 接提案仓)。
|
|
5
|
+
//
|
|
6
|
+
// 契约见 docs/api/tool-calling.md:抛错即失败(不把失败编码进 content);提案 content 只给
|
|
7
|
+
// 「提案已发出」提示,预览细节在 details 里随 SSE 推给 GUI。
|
|
8
|
+
import { TOOL_PERMISSION } from "@whispering233/ai-editor-shared";
|
|
9
|
+
import { listTools } from "@whispering233/ai-editor-tools";
|
|
10
|
+
import { stringifyToolResult, truncateToolResultText } from "./tool-result.js";
|
|
11
|
+
/** 提案已发出提示(content 不含预览细节——避免模型误以为提案已生效)
|
|
12
|
+
* 一句话摘要取自 preview.summary(结构化 preview 的提案没有该字段,则只给 id) */
|
|
13
|
+
function proposalAckText(payload) {
|
|
14
|
+
const summary = payload.preview.summary;
|
|
15
|
+
const summaryText = typeof summary === "string" && summary !== "" ? `${summary};` : "";
|
|
16
|
+
return `提案已发出(proposal_id=${payload.proposal_id}):${summaryText}需用户确认后才会生效;确认前不要假设任何修改已发生。`;
|
|
17
|
+
}
|
|
18
|
+
/** 单个领域工具 → pi 工具定义 */
|
|
19
|
+
function toPiTool(tool, options) {
|
|
20
|
+
return {
|
|
21
|
+
name: tool.name,
|
|
22
|
+
label: tool.name,
|
|
23
|
+
description: tool.description,
|
|
24
|
+
parameters: tool.parameters,
|
|
25
|
+
execute: async (toolCallId, params, signal) => {
|
|
26
|
+
const result = await tool.run(options.toolContext, params, signal);
|
|
27
|
+
if (tool.permission === TOOL_PERMISSION.PROPOSAL) {
|
|
28
|
+
const proposal = options.proposalSink?.({
|
|
29
|
+
toolName: tool.name,
|
|
30
|
+
toolCallId,
|
|
31
|
+
params,
|
|
32
|
+
result,
|
|
33
|
+
toolContext: options.toolContext,
|
|
34
|
+
});
|
|
35
|
+
if (proposal !== undefined) {
|
|
36
|
+
return {
|
|
37
|
+
content: [{ type: "text", text: proposalAckText(proposal) }],
|
|
38
|
+
details: proposal,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: "text", text: truncateToolResultText(stringifyToolResult(result)) }],
|
|
44
|
+
details: result,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** registry 全部工具 → pi 工具定义(顺序 = listTools 的稳定序) */
|
|
50
|
+
export function createCustomTools(options) {
|
|
51
|
+
return listTools().map((tool) => toPiTool(tool, options));
|
|
52
|
+
}
|
|
53
|
+
/** 工具参数 schema 类型(测试/调用方按需引用) */
|
|
54
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/runtime/tools.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,EAAE;AACF,8FAA8F;AAC9F,iEAAiE;AACjE,EAAE;AACF,oEAAoE;AACpE,yCAAyC;AAGzC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAiE,MAAM,gCAAgC,CAAC;AAC1H,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AA4B/E;0DAC0D;AAC1D,SAAS,eAAe,CAAC,OAAwB;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;IACxC,MAAM,WAAW,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,OAAO,qBAAqB,OAAO,CAAC,WAAW,KAAK,WAAW,4BAA4B,CAAC;AAC9F,CAAC;AAED,uBAAuB;AACvB,SAAS,QAAQ,CAAC,IAA0B,EAAE,OAAiC;IAC7E,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,IAAI;QAChB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC5C,MAAM,MAAM,GAAY,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAe,EAAE,MAAM,CAAC,CAAC;YAErF,IAAI,IAAI,CAAC,UAAU,KAAK,eAAe,CAAC,QAAQ,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;oBACtC,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,UAAU;oBACV,MAAM;oBACN,MAAM;oBACN,WAAW,EAAE,OAAO,CAAC,WAAW;iBACjC,CAAC,CAAC;gBACH,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,OAAO;wBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACrE,OAAO,EAAE,QAAQ;qBAClB,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBAC/F,OAAO,EAAE,MAAM;aAChB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,iBAAiB,CAAC,OAAiC;IACjE,OAAO,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,iCAAiC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whispering233/ai-editor-agent",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.33",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "AI 对话循环:会话管理 / 上下文组装 / 工具调度",
|
|
6
6
|
"type": "module",
|
|
@@ -26,9 +26,10 @@
|
|
|
26
26
|
"postpack": "node ../../scripts/restore-package-json.mjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@whispering233/ai-editor-
|
|
29
|
+
"@earendil-works/pi-ai": "0.85.1",
|
|
30
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
31
|
+
"@whispering233/ai-editor-shared": "0.0.33",
|
|
32
|
+
"@whispering233/ai-editor-tools": "0.0.33"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"typescript": "^5.8.0"
|
package/dist/context.d.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { LLMMessage, LLMUsage } from "@whispering233/ai-editor-llm";
|
|
2
|
-
import { type ToolDefinition } from "@whispering233/ai-editor-tools";
|
|
3
|
-
import { type SessionMessage } from "./session.js";
|
|
4
|
-
/** 分层 token 预算(系统 ~500 / 聚焦 ~3000 / 历史 ~6000;可整体或单项覆盖)。
|
|
5
|
-
* 分层合计约 11.5K,远低于 DeepSeek 64K 窗口——各层独立校验、不设总预算校验(YAGNI:
|
|
6
|
-
* 分层裁剪已保证各层在其预算内,窗口余量充足) */
|
|
7
|
-
export interface ContextBudgets {
|
|
8
|
-
/** 基础 system 层:内核 + 项目提示词 + 临时指令(~500;超限仅记录不裁剪——用户内容不可裁) */
|
|
9
|
-
system: number;
|
|
10
|
-
/** 聚焦上下文层(~3000;超限截断并显式告知) */
|
|
11
|
-
focus: number;
|
|
12
|
-
/** 对话历史层(~6000;超限走 session 成对裁剪——同裁同留不拆对) */
|
|
13
|
-
history: number;
|
|
14
|
-
}
|
|
15
|
-
export declare const DEFAULT_CONTEXT_BUDGETS: ContextBudgets;
|
|
16
|
-
/** 工具清单注入所需的工具形态(仅消费 name/description,不依赖 registry 全量定义) */
|
|
17
|
-
export type ToolListEntry = Pick<ToolDefinition, "name" | "description">;
|
|
18
|
-
/** buildContext 输入:除 history 外全部可空(无聚焦 / 无项目提示词 / 无临时指令均为合法态) */
|
|
19
|
-
export interface BuildContextInput {
|
|
20
|
-
/**
|
|
21
|
-
* 会话历史(session 状态;本层负责超预算成对裁剪 + 末条约束收尾)。
|
|
22
|
-
* **前置条件**:必须含至少一条 user/tool 消息(末条约束);空历史属调用方错误——
|
|
23
|
-
* S7.3 应在 history 为空时走引导分支(不发请求),勿传入空数组(buildPayload 空数组
|
|
24
|
-
* 语义同源:空历史 = 无有效上下文,两者互相印证)
|
|
25
|
-
*/
|
|
26
|
-
history: SessionMessage[];
|
|
27
|
-
/** 内核提示词(默认 KERNEL_PROMPT;测试可覆盖) */
|
|
28
|
-
kernelPrompt?: string;
|
|
29
|
-
/** 项目提示词(项目层;起数据源 = 项目目录 文件内容,调用方读取后传入;可空) */
|
|
30
|
-
projectPrompt?: string;
|
|
31
|
-
/** 临时指令(临时层,即时输入不持久化;可空) */
|
|
32
|
-
instruction?: string;
|
|
33
|
-
/** 聚焦上下文文本(聚焦层,调用方查询实体/大纲节点后拼好传入;空/缺省 = 无聚焦) */
|
|
34
|
-
focus?: string;
|
|
35
|
-
/** 工具清单(默认内部 listTools();测试可注入 mock) */
|
|
36
|
-
tools?: ToolListEntry[];
|
|
37
|
-
/**
|
|
38
|
-
* 最近一次成功响应的 usage 基线(本层触发裁剪后重置为 null)。
|
|
39
|
-
* **口径**(ora S7.3 审核 S1,与 run.ts toHistoryBaseline / llm token.ts 三处等价表述):
|
|
40
|
-
* 调用方(S7.3)须换算为「历史段」真实分量传入——以 usage.prompt_tokens 为起点减
|
|
41
|
-
* system + toolList + focus 估算(completion 属输出、不占 prompt_tokens,无需扣除);
|
|
42
|
-
* 若以 total_tokens 为起点则再减 completion(两式等价)。meta.tokens 已提供
|
|
43
|
-
* system/toolList/focus 各层估算可供换算;直接传原始 total_tokens 会与非历史层重复计费
|
|
44
|
-
*/
|
|
45
|
-
lastUsage?: LLMUsage | null;
|
|
46
|
-
/** 分层预算覆盖(缺省用 常量) */
|
|
47
|
-
budgets?: Partial<ContextBudgets>;
|
|
48
|
-
}
|
|
49
|
-
/** buildContext 输出:完整喂回 messages + 各层估算 + 裁剪/截断/基线记录 */
|
|
50
|
-
export interface AssembledContext {
|
|
51
|
-
/** 完整喂回数组:[system(基础+工具清单), (system(聚焦) 若有), ...历史];末条恒 user/tool 或为空 */
|
|
52
|
-
messages: LLMMessage[];
|
|
53
|
-
/** 各层估算 token(history 为裁剪后、无基线重置后的估算) */
|
|
54
|
-
tokens: {
|
|
55
|
-
/** 基础 system(内核+项目+临时) */
|
|
56
|
-
system: number;
|
|
57
|
-
/** 工具清单(独立于 system 层计,不参与裁剪——LLM 需完整工具表) */
|
|
58
|
-
toolList: number;
|
|
59
|
-
/** 聚焦层(截断后;无聚焦为 0) */
|
|
60
|
-
focus: number;
|
|
61
|
-
/** 历史层(裁剪后) */
|
|
62
|
-
history: number;
|
|
63
|
-
/** 四层合计 */
|
|
64
|
-
total: number;
|
|
65
|
-
};
|
|
66
|
-
meta: {
|
|
67
|
-
/** 基础 system 超限(仅记录不裁剪——用户内容不可裁) */
|
|
68
|
-
systemOverBudget: boolean;
|
|
69
|
-
/** 聚焦被截断(含截断提示) */
|
|
70
|
-
focusTruncated: boolean;
|
|
71
|
-
/** 历史被成对裁剪(同裁同留不拆对) */
|
|
72
|
-
historyTrimmed: boolean;
|
|
73
|
-
/** 裁剪后历史条数 */
|
|
74
|
-
historyMessageCount: number;
|
|
75
|
-
/** 基线被重置(触发裁剪/重排后旧 usage 不再可信—— 防预算漂移) */
|
|
76
|
-
lastUsageReset: boolean;
|
|
77
|
-
/**
|
|
78
|
-
* 生效基线:未触发裁剪时保留换算后的 lastUsage;触发后为 null。
|
|
79
|
-
* **回写(S7.3 接线)**:本层消费的 lastUsage 是「历史段」口径(见
|
|
80
|
-
* BuildContextInput.lastUsage);effectiveLastUsage 仅回写「是否重置」这一决策,
|
|
81
|
-
* S7.3 下一轮组装时仍须按换算公式从最新 usage 重新计算历史段分量传入
|
|
82
|
-
*/
|
|
83
|
-
effectiveLastUsage: LLMUsage | null;
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* 组装完整喂回上下文:
|
|
88
|
-
* 1. 基础 system = 内核 + 项目提示词 + 临时指令 + 工具清单(超 system 预算仅记录不裁剪)
|
|
89
|
-
* 2. 聚焦注入 = 独立 system 消息(有 focus 时;超预算截断并显式告知)
|
|
90
|
-
* 3. 历史 = 超预算成对裁剪(同裁同留)+ 末条约束收尾(buildPayload——输出末条恒 user/tool)
|
|
91
|
-
* 4. usage 基线:未触发裁剪时保留 lastUsage(真实用量优先);一旦触发裁剪即重置为
|
|
92
|
-
* null(旧 usage 描述裁剪前前缀,沿用会导致预算漂移)——meta.effectiveLastUsage 反映
|
|
93
|
-
* 生效基线,S7.3 应回写该值作为下一轮输入
|
|
94
|
-
*/
|
|
95
|
-
export declare function buildContext(input: BuildContextInput): AssembledContext;
|
|
96
|
-
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAEzE,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAShF,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9E;;4BAE4B;AAC5B,MAAM,WAAW,cAAc;IAC9B,4DAA4D;IAC3D,MAAM,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC5C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,uBAAuB,EAAE,cAIrC,CAAC;AAIF,4DAA4D;AAC5D,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC;AAEzE,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IACjC;;;;;MAKE;IACD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC3B,oCAAoC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;IACxB,4BAA4B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACvC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACzB;;;;;;;MAOE;IACD,SAAS,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC7B,qBAAqB;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;CACnC;AAED,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACxE,QAAQ,EAAE,UAAU,EAAE,CAAC;IACxB,yCAAyC;IACxC,MAAM,EAAE;QACT,0BAA0B;QACvB,MAAM,EAAE,MAAM,CAAC;QAClB,4CAA4C;QACzC,QAAQ,EAAE,MAAM,CAAC;QACpB,sBAAsB;QACnB,KAAK,EAAE,MAAM,CAAC;QACjB,eAAe;QACZ,OAAO,EAAE,MAAM,CAAC;QACnB,WAAW;QACR,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,IAAI,EAAE;QACP,oCAAoC;QACjC,gBAAgB,EAAE,OAAO,CAAC;QAC7B,mBAAmB;QAChB,cAAc,EAAE,OAAO,CAAC;QAC3B,uBAAuB;QACpB,cAAc,EAAE,OAAO,CAAC;QAC3B,cAAc;QACX,mBAAmB,EAAE,MAAM,CAAC;QAC/B,0CAA0C;QACvC,cAAc,EAAE,OAAO,CAAC;QAC3B;;;;;UAKE;QACC,kBAAkB,EAAE,QAAQ,GAAG,IAAI,CAAC;KACrC,CAAC;CACH;AAsED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,gBAAgB,CA2DvE"}
|
package/dist/context.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
// @whispering233/ai-editor-agent 上下文组装(S7.2)
|
|
2
|
-
//
|
|
3
|
-
// 历史 ~6000;usage 基线——优先最近真实 usage,裁剪历史后重置基线防预算漂移)、
|
|
4
|
-
// (提示词三层注入:内核 + 项目 + 临时)、(POST /api/v1/chat 的
|
|
5
|
-
// context 字段 focus_entity_type/focus_entity_id/focus_node_id——聚焦数据由调用方查询后
|
|
6
|
-
// 以文本传入)、packages/llm/src/token.ts(estimateTokens / estimateMessagesTokens)、
|
|
7
|
-
// packages/tools/src/registry.ts(listTools 工具清单)。
|
|
8
|
-
//
|
|
9
|
-
// 架构边界:本模块**不依赖 db**——聚焦上下文文本与项目提示词均由调用方(S7.6 server 层)
|
|
10
|
-
// 查询后传入,context.ts 只做组装与预算控制;工具列表默认内部取 registry(agent 依赖 tools ✓)。
|
|
11
|
-
//
|
|
12
|
-
// 消费链(S7.3 主循环):SessionState → buildContext(本层成对裁剪 + 基线重置)→
|
|
13
|
-
// 输出 LLMMessage[](system + 可选聚焦 system + 历史)直接喂给模型。
|
|
14
|
-
import { estimateMessagesTokens, estimateTokens } from "@whispering233/ai-editor-llm";
|
|
15
|
-
import { listTools } from "@whispering233/ai-editor-tools";
|
|
16
|
-
import { FOCUS_TITLE, FOCUS_TRUNCATION_NOTICE, INSTRUCTION_TITLE, KERNEL_PROMPT, PROJECT_PROMPT_TITLE, TOOL_LIST_TITLE, } from "./prompts.js";
|
|
17
|
-
import { buildPayload, trimSession } from "./session.js";
|
|
18
|
-
export const DEFAULT_CONTEXT_BUDGETS = {
|
|
19
|
-
system: 500,
|
|
20
|
-
focus: 3000,
|
|
21
|
-
history: 6000,
|
|
22
|
-
};
|
|
23
|
-
// ============ 内部组装辅助(纯函数) ============
|
|
24
|
-
/** 基础 system 文本:内核 + 项目提示词 + 临时指令(三层注入,空层跳过) */
|
|
25
|
-
function buildSystemBase(kernel, project, instruction) {
|
|
26
|
-
const parts = [kernel];
|
|
27
|
-
if (project !== undefined && project.trim() !== "") {
|
|
28
|
-
parts.push(`${PROJECT_PROMPT_TITLE}\n${project}`);
|
|
29
|
-
}
|
|
30
|
-
if (instruction !== undefined && instruction.trim() !== "") {
|
|
31
|
-
parts.push(`${INSTRUCTION_TITLE}\n${instruction}`);
|
|
32
|
-
}
|
|
33
|
-
return parts.join("\n\n");
|
|
34
|
-
}
|
|
35
|
-
/** 工具清单文本:name + description 一行(registry listTools 形态;空清单返回空串) */
|
|
36
|
-
function buildToolListText(tools) {
|
|
37
|
-
if (tools.length === 0)
|
|
38
|
-
return "";
|
|
39
|
-
const lines = tools.map((t) => `- ${t.name}:${t.description}`);
|
|
40
|
-
return `${TOOL_LIST_TITLE}\n${lines.join("\n")}`;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* 聚焦文本按预算截断(显式告知,不静默丢数据):
|
|
44
|
-
* 按 chars/4 反推可保留字符数(预留截断提示空间),保留前缀 + 截断提示。
|
|
45
|
-
*/
|
|
46
|
-
function trimFocus(focus, maxTokens) {
|
|
47
|
-
if (estimateTokens(focus) <= maxTokens) {
|
|
48
|
-
return { text: focus, truncated: false };
|
|
49
|
-
}
|
|
50
|
-
const maxChars = Math.max(0, Math.floor(maxTokens * 4));
|
|
51
|
-
const keptChars = Math.max(0, maxChars - FOCUS_TRUNCATION_NOTICE.length);
|
|
52
|
-
return { text: focus.slice(0, keptChars) + FOCUS_TRUNCATION_NOTICE, truncated: true };
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* 历史按 token 预算成对裁剪:
|
|
56
|
-
* 用 trimSession 以「配对块」为单位裁剪(同裁同留不拆对),二分找预算内尽量多保留的
|
|
57
|
-
* 最大条数。裁剪后的估算**一律不带 usage 基线**——旧基线描述裁剪前前缀,沿用即预算漂移。
|
|
58
|
-
* 返回 { messages, trimmed }:trimmed=true 表示至少裁掉一条消息。
|
|
59
|
-
*/
|
|
60
|
-
function trimHistoryToBudget(history, maxTokens) {
|
|
61
|
-
if (estimateMessagesTokens(history) <= maxTokens) {
|
|
62
|
-
return { messages: history, trimmed: false };
|
|
63
|
-
}
|
|
64
|
-
// 二分最大可行条数 n:f(n) = estimate(trimSession(history, n)),f(0)=0 ≤ 预算。
|
|
65
|
-
// 单调性论证:n 增大时原放不下的块可能变得可放(swap)——新纳入块的条数严格大于
|
|
66
|
-
// 被其挤出的更早块(否则此前不会被拒),保留**条数**单调不减;条数分布均匀时
|
|
67
|
-
// f(n) 即近似单调不减,二分求最大可行 n 正确。
|
|
68
|
-
// 兜底:即使极端大小构造破坏 token 单调性,lo 不变式(f(lo) ≤ 预算恒成立)保证
|
|
69
|
-
// 二分终止时输出不超预算——最坏只是保留条数略少于最优,绝无超预算风险。
|
|
70
|
-
let lo = 0;
|
|
71
|
-
let hi = history.length;
|
|
72
|
-
while (lo < hi) {
|
|
73
|
-
const mid = Math.ceil((lo + hi) / 2);
|
|
74
|
-
if (estimateMessagesTokens(trimSession(history, mid)) <= maxTokens) {
|
|
75
|
-
lo = mid;
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
hi = mid - 1;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return { messages: trimSession(history, lo), trimmed: lo < history.length };
|
|
82
|
-
}
|
|
83
|
-
// ============ 主组装 ============
|
|
84
|
-
/**
|
|
85
|
-
* 组装完整喂回上下文:
|
|
86
|
-
* 1. 基础 system = 内核 + 项目提示词 + 临时指令 + 工具清单(超 system 预算仅记录不裁剪)
|
|
87
|
-
* 2. 聚焦注入 = 独立 system 消息(有 focus 时;超预算截断并显式告知)
|
|
88
|
-
* 3. 历史 = 超预算成对裁剪(同裁同留)+ 末条约束收尾(buildPayload——输出末条恒 user/tool)
|
|
89
|
-
* 4. usage 基线:未触发裁剪时保留 lastUsage(真实用量优先);一旦触发裁剪即重置为
|
|
90
|
-
* null(旧 usage 描述裁剪前前缀,沿用会导致预算漂移)——meta.effectiveLastUsage 反映
|
|
91
|
-
* 生效基线,S7.3 应回写该值作为下一轮输入
|
|
92
|
-
*/
|
|
93
|
-
export function buildContext(input) {
|
|
94
|
-
const budgets = { ...DEFAULT_CONTEXT_BUDGETS, ...input.budgets };
|
|
95
|
-
const kernel = input.kernelPrompt ?? KERNEL_PROMPT;
|
|
96
|
-
const tools = input.tools ?? listTools();
|
|
97
|
-
// ---- 1. 基础 system 层(内核 + 项目 + 临时 + 工具清单) ----
|
|
98
|
-
const baseText = buildSystemBase(kernel, input.projectPrompt, input.instruction);
|
|
99
|
-
const toolListText = buildToolListText(tools);
|
|
100
|
-
const systemContent = toolListText === "" ? baseText : `${baseText}\n\n${toolListText}`;
|
|
101
|
-
const systemTokens = estimateTokens(baseText);
|
|
102
|
-
const toolListTokens = estimateTokens(toolListText);
|
|
103
|
-
const systemOverBudget = systemTokens > budgets.system;
|
|
104
|
-
// ---- 2. 聚焦层(独立 system 消息;超预算截断) ----
|
|
105
|
-
let focusMessage = null;
|
|
106
|
-
let focusTokens = 0;
|
|
107
|
-
let focusTruncated = false;
|
|
108
|
-
if (input.focus !== undefined && input.focus !== "") {
|
|
109
|
-
const trimmed = trimFocus(input.focus, budgets.focus);
|
|
110
|
-
focusTruncated = trimmed.truncated;
|
|
111
|
-
focusTokens = estimateTokens(`${FOCUS_TITLE}\n${trimmed.text}`);
|
|
112
|
-
focusMessage = { role: "system", content: `${FOCUS_TITLE}\n${trimmed.text}` };
|
|
113
|
-
}
|
|
114
|
-
// ---- 3. 历史层(超预算成对裁剪 + 末条约束收尾) ----
|
|
115
|
-
// 预算判定优先真实 usage 基线;一旦判定超限触发裁剪,基线即重置
|
|
116
|
-
const withBaseline = estimateMessagesTokens(input.history, {
|
|
117
|
-
lastUsage: input.lastUsage ?? null,
|
|
118
|
-
});
|
|
119
|
-
const lastUsageReset = withBaseline > budgets.history;
|
|
120
|
-
const trimmedHistory = lastUsageReset
|
|
121
|
-
? trimHistoryToBudget(input.history, budgets.history)
|
|
122
|
-
: { messages: input.history, trimmed: false };
|
|
123
|
-
const historyPayload = buildPayload(trimmedHistory.messages);
|
|
124
|
-
const historyTokens = estimateMessagesTokens(historyPayload);
|
|
125
|
-
// ---- 4. 汇总 ----
|
|
126
|
-
const messages = [{ role: "system", content: systemContent }];
|
|
127
|
-
if (focusMessage !== null)
|
|
128
|
-
messages.push(focusMessage);
|
|
129
|
-
messages.push(...historyPayload);
|
|
130
|
-
return {
|
|
131
|
-
messages,
|
|
132
|
-
tokens: {
|
|
133
|
-
system: systemTokens,
|
|
134
|
-
toolList: toolListTokens,
|
|
135
|
-
focus: focusTokens,
|
|
136
|
-
history: historyTokens,
|
|
137
|
-
total: systemTokens + toolListTokens + focusTokens + historyTokens,
|
|
138
|
-
},
|
|
139
|
-
meta: {
|
|
140
|
-
systemOverBudget,
|
|
141
|
-
focusTruncated,
|
|
142
|
-
historyTrimmed: trimmedHistory.trimmed,
|
|
143
|
-
historyMessageCount: historyPayload.length,
|
|
144
|
-
lastUsageReset,
|
|
145
|
-
effectiveLastUsage: lastUsageReset ? null : (input.lastUsage ?? null),
|
|
146
|
-
},
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
package/dist/executor.d.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { type Proposal, type ToolContext } from "@whispering233/ai-editor-tools";
|
|
2
|
-
import type { ToolDispatcher } from "./run.js";
|
|
3
|
-
/** 提案 TTL(10 分钟;S7.5 confirm/reject 引用——超期按不存在处理) */
|
|
4
|
-
export declare const PROPOSAL_TTL_MS: number;
|
|
5
|
-
/**
|
|
6
|
-
* 提案条数上限(超限淘汰 createdAt 最旧)。
|
|
7
|
-
* 决策原文未定数——取 200 为数量级防御:正常会话一轮最多 15 个提案、挂卡不确认的
|
|
8
|
-
* 残留按 TTL 自动过期,200 足以覆盖极端多轮场景且内存占用可忽略(防无限增长)。
|
|
9
|
-
*/
|
|
10
|
-
export declare const PROPOSAL_MAX_COUNT = 200;
|
|
11
|
-
/** 提案仓接口(S7.5 路由消费:confirm/reject 经 get/peek;S7.6 切换项目调 clear) */
|
|
12
|
-
export interface ProposalStore {
|
|
13
|
-
/** 存入提案(TTL 从 createdAt 起算;先清过期、超限淘汰最旧) */
|
|
14
|
-
set(proposal: Proposal): void;
|
|
15
|
-
/**
|
|
16
|
-
* 按 id + 项目取:不存在 / 过期 / **跨项目** → null。
|
|
17
|
-
* 跨项目返回 null 即防御 PROPOSAL_PROJECT_MISMATCH 语义(
|
|
18
|
-
* 提案绑定 project_id,确认时校验与当前项目一致)。
|
|
19
|
-
*/
|
|
20
|
-
get(proposalId: string, projectId: string): Proposal | null;
|
|
21
|
-
/**
|
|
22
|
-
* 仅按 id 取(不校验项目):S7.5 区分「404 PROPOSAL_NOT_FOUND」与
|
|
23
|
-
* 「409 PROPOSAL_PROJECT_MISMATCH」用——get 返回 null 后 peek 仍可见 ⇒ 跨项目误操作。
|
|
24
|
-
* 过期条目同样视为不存在(惰性清理)。
|
|
25
|
-
*/
|
|
26
|
-
peek(proposalId: string): Proposal | null;
|
|
27
|
-
/**
|
|
28
|
-
* 按 id 移除单条(S7.5 一次性消费:confirm/reject 终态后移除—— 瞬态交互对象,
|
|
29
|
-
* 确认/拒绝动作即消费,残留只会让重复 confirm 产生重复执行或反复 409)。
|
|
30
|
-
* 与 clear 的区别:clear 清空全部(S7.6 切换项目用),remove 只移除指定提案。
|
|
31
|
-
*/
|
|
32
|
-
remove(proposalId: string): void;
|
|
33
|
-
/** 清空全部项目提案(create/open/close 切换项目时由 S7.6 调用) */
|
|
34
|
-
clear(): void;
|
|
35
|
-
/** 当前仓内提案数(测试/诊断) */
|
|
36
|
-
size(): number;
|
|
37
|
-
}
|
|
38
|
-
/** createProposalStore 选项(测试覆盖 TTL/上限用;缺省取导出的常量) */
|
|
39
|
-
export interface ProposalStoreOptions {
|
|
40
|
-
/** TTL 覆盖 ms(缺省 PROPOSAL_TTL_MS) */
|
|
41
|
-
ttlMs?: number;
|
|
42
|
-
/** 条数上限覆盖(缺省 PROPOSAL_MAX_COUNT) */
|
|
43
|
-
maxCount?: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 创建提案仓实例。
|
|
47
|
-
* 过期策略:**惰性过期 + 按需清理**(「超期自动清除」落地)——get/peek 只清理命中的
|
|
48
|
-
* 单条,set 前扫全仓清理;无定时器(定时器引入时钟耦合且小仓无必要,测试用假时钟直接断言)。
|
|
49
|
-
* 淘汰策略:条数超限时淘汰 createdAt **最旧**的提案(sweep 过期后仍满则循环淘汰最旧)。
|
|
50
|
-
*/
|
|
51
|
-
export declare function createProposalStore(options?: ProposalStoreOptions): ProposalStore;
|
|
52
|
-
/** 默认提案仓单例(S7.5 confirm/reject 与 S7.6 切换项目 clear 直接引用;测试用 createProposalStore 独立实例) */
|
|
53
|
-
export declare const defaultProposalStore: ProposalStore;
|
|
54
|
-
/**
|
|
55
|
-
* 提案 build 层入口签名(args 已过 argsSchema 校验——执行前 safeParse 的 parsed.data)。
|
|
56
|
-
* run 层裁剪只返回 { proposal_id, summary }(「提案类」2026-08 修订),
|
|
57
|
-
* 完整 Proposal 对象须经 build 层重建(与 run 内部产出同源确定:同 ctx + 同 args 结果一致)。
|
|
58
|
-
*/
|
|
59
|
-
type ProposalBuilder = (ctx: ToolContext, args: unknown) => Proposal;
|
|
60
|
-
/**
|
|
61
|
-
* 15 个 propose_* 工具名 → build 层函数。
|
|
62
|
-
* 运行时查表缺失(非 propose 工具)走普通结果路径;完整性由测试断言覆盖
|
|
63
|
-
* (Object.keys(PROPOSAL_BUILDERS) === PROPOSAL_TOOLS)——S6.6 后续新增提案工具须同步登记。
|
|
64
|
-
* 导出仅为完整性测试断言;业务侧经 createToolDispatcher 间接使用。
|
|
65
|
-
*/
|
|
66
|
-
export declare const PROPOSAL_BUILDERS: Record<string, ProposalBuilder>;
|
|
67
|
-
/** createToolDispatcher 选项 */
|
|
68
|
-
export interface CreateToolDispatcherOptions {
|
|
69
|
-
/** 提案仓(缺省 defaultProposalStore 单例——S7.5 confirm/reject 与调度同仓消费) */
|
|
70
|
-
store?: ProposalStore;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* 创建工具调度器(run.ts ToolDispatcher 真实现):
|
|
74
|
-
* 1. **批量校验 fail fast**(「工具执行」):先全部 getTool(name).argsSchema
|
|
75
|
-
* safeParse——工具不存在 / 参数非法 → 该调用合成 isError 结果(**不中断其他调用**,
|
|
76
|
-
* 「fail fast」指校验先于执行,错误编码进 isError 喂回 LLM 自纠);全部校验完再逐个执行
|
|
77
|
-
* 2. **执行中检查 signal**:调度前 + 每个工具执行前 throwIfAborted,run 调用
|
|
78
|
-
* 透传 signal(长分析工具内部周期检查);命中取消抛 AbortedError **按取消语义传播**
|
|
79
|
-
* (原样抛穿,run.ts 识别后按用户取消终止——不喂回、不视为工具失败)
|
|
80
|
-
* 3. 工具执行抛错(非 AbortedError)→ 统一 isError 结构化(工具名+参数+错误信息)
|
|
81
|
-
* 4. propose_* 执行成功 → build 层重建完整 Proposal 入仓 + 构造 preview(S7.6 推 GUI)→
|
|
82
|
-
* DispatchResult.proposal 透传 run.ts(proposal 事件在 tool_result 后、循环继续前——run.ts 保证)
|
|
83
|
-
*/
|
|
84
|
-
export declare function createToolDispatcher(ctx: ToolContext, options?: CreateToolDispatcherOptions): ToolDispatcher;
|
|
85
|
-
export {};
|
|
86
|
-
//# sourceMappingURL=executor.d.ts.map
|
package/dist/executor.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAwBA,OAAO,EAoBL,KAAK,QAAQ,EACb,KAAK,WAAW,EAEjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAoC,cAAc,EAAE,MAAM,UAAU,CAAC;AAIjF,qDAAqD;AACrD,eAAO,MAAM,eAAe,QAAc,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC7B,2CAA2C;IAC1C,GAAG,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC/B;;;;MAIE;IACD,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC7D;;;;MAIE;IACD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC3C;;;;MAIE;IACD,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iDAAiD;IAChD,KAAK,IAAI,IAAI,CAAC;IACf,qBAAqB;IACpB,IAAI,IAAI,MAAM,CAAC;CAChB;AAED,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACpC,oCAAoC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA+DrF;AAED,uFAAuF;AACvF,eAAO,MAAM,oBAAoB,EAAE,aAAqC,CAAC;AAIzE;;;;GAIG;AACH,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,KAAK,QAAQ,CAAC;AAErE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAiB7D,CAAC;AAEF,8BAA8B;AAC9B,MAAM,WAAW,2BAA2B;IAC3C,mEAAmE;IAClE,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAwGhH"}
|