@zhushanwen/pi-session-manager 0.2.4 → 0.3.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhushanwen/pi-session-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pi extension for managing agent-managed sessions — create, send, read history, list, status, abort via ctx.ui.select channel.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
"README.md"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@zhushanwen/extension-protocol": "0.
|
|
34
|
-
"@zhushanwen/pi-
|
|
35
|
-
"@zhushanwen/
|
|
36
|
-
"@zhushanwen/pi-
|
|
37
|
-
"@zhushanwen/
|
|
33
|
+
"@zhushanwen/extension-protocol": "0.18.0",
|
|
34
|
+
"@zhushanwen/pi-notify-ledger-host": "0.3.0",
|
|
35
|
+
"@zhushanwen/subagent-core": "1.3.0",
|
|
36
|
+
"@zhushanwen/pi-ext-guards": "0.4.3",
|
|
37
|
+
"@zhushanwen/pi-extension-logger": "0.6.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^24.0.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@earendil-works/pi-coding-agent": "*",
|
|
46
|
-
"typebox": "
|
|
46
|
+
"typebox": "1.3.27"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"@earendil-works/pi-coding-agent": {
|
|
@@ -11,7 +11,7 @@ describe("U5-A4 tool-error-handling", () => {
|
|
|
11
11
|
vi.clearAllMocks();
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
it("select returning undefined (user cancel/
|
|
14
|
+
it("select returning undefined (user cancel/channel error) → cancelled throw(W4 范式:错误路径 throw)", async () => {
|
|
15
15
|
await expectToolRejects(
|
|
16
16
|
createToolHarness(vi.fn().mockResolvedValue(undefined)),
|
|
17
17
|
"create_managed_session",
|
|
@@ -53,8 +53,8 @@ describe("U5-A2 tool-execute", () => {
|
|
|
53
53
|
expect(options).toHaveLength(1);
|
|
54
54
|
const payload = JSON.parse(options[0]);
|
|
55
55
|
expect(payload.action).toBe(expectedAction);
|
|
56
|
-
// third arg
|
|
57
|
-
expect(opts).toHaveProperty("timeout");
|
|
56
|
+
// third arg: timeout 不传(ADR-0122 无包内挂死兜底,全 action 无 timer 长挂)
|
|
57
|
+
expect(opts).toHaveProperty("timeout", undefined);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it("create_managed_session includes cwd and label in payload.params", async () => {
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type {
|
|
5
5
|
ExtensionAPI,
|
|
6
6
|
ExtensionContext,
|
|
7
|
+
ExtensionToolContext,
|
|
7
8
|
SessionCompactEvent,
|
|
8
9
|
SessionStartEvent,
|
|
9
10
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -55,27 +56,19 @@ const AbortSessionParams = Type.Object({
|
|
|
55
56
|
|
|
56
57
|
// ── select 通道辅助 ──
|
|
57
58
|
|
|
58
|
-
/** select 超时(ms):工具等待 runtime handler respond 的最大时间(create/history 走长链路放宽)。
|
|
59
|
-
* watch 刻意缺席(notify-once D2:不传 timeout、fire-and-forget 长挂——P1 实测 `if
|
|
60
|
-
* (opts?.timeout)` 才设 timer)。形制 = `Exclude<SessionManagerAction, "watch">`:
|
|
61
|
-
* 协议 action 集 6→7 后漏配键即编译期红(计划 blocker #1 的修复形态)。 */
|
|
62
|
-
const SELECT_TIMEOUT_MS: Record<Exclude<SessionManagerAction, "watch">, number> = {
|
|
63
|
-
create: 60_000,
|
|
64
|
-
send: 30_000,
|
|
65
|
-
history: 60_000,
|
|
66
|
-
status: 30_000,
|
|
67
|
-
list: 30_000,
|
|
68
|
-
abort: 30_000,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
59
|
/**
|
|
72
60
|
* 通过 select 通道向 runtime handler 发送 session 管理请求(传输核走 protocol 的
|
|
73
61
|
* callMarkerRpc 原语,D8)。回包为 handler respond 的 JSON 字符串(value 恒 raw);
|
|
74
|
-
*
|
|
75
|
-
* pi agent-loop
|
|
76
|
-
*
|
|
77
|
-
*
|
|
62
|
+
* 失败态(cancelled/channel-error/non-json)由 executeTool 统一 throw——
|
|
63
|
+
* execute throw → pi agent-loop catch 置 isError:true(pi-agent-core dist/agent-loop.js
|
|
64
|
+
* executePreparedToolCall,1.0.0 实读 catch :581-588);1.0.0 起返回值 isError:true 也被
|
|
65
|
+
* 尊重(同文件 :579 `isError: result.isError === true`,0.84.4 时返回值会被丢弃)——
|
|
66
|
+
* 本工具失败恒走 throw,两版语义等价(语义登记 PS-56)。
|
|
78
67
|
* 通道异常与非 JSON 回包的留痕由原语经注入的 log 承担。
|
|
68
|
+
*
|
|
69
|
+
* 不传 timeout(ADR-0122:无包内挂死兜底,handler 不回包时工具调用长挂、失败直报;
|
|
70
|
+
* 原 SELECT_TIMEOUT_MS per-action 表已删——原 watch 通道 D2/P1 的无 timer 长挂形态
|
|
71
|
+
* 现为全部 action 统一形态:任意晚的 respond 按 id 精确 resolve)。
|
|
79
72
|
*/
|
|
80
73
|
function callSessionManager(
|
|
81
74
|
ctx: ExtensionContext,
|
|
@@ -95,8 +88,7 @@ function callSessionManager(
|
|
|
95
88
|
ui: { select: ctx.ui.select.bind(ctx.ui) },
|
|
96
89
|
};
|
|
97
90
|
return callMarkerRpc(guiCtx, SESSION_MANAGER_MARKER, payload, {
|
|
98
|
-
//
|
|
99
|
-
timeout: action === "watch" ? undefined : SELECT_TIMEOUT_MS[action],
|
|
91
|
+
// 全 action 不传 timeout(ADR-0122:无包内挂死兜底;无 timer 长挂,任意晚的 respond 按 id 精确 resolve)
|
|
100
92
|
log: (msg, detail) => logger.error(`[session-manager] ${msg}`, detail),
|
|
101
93
|
});
|
|
102
94
|
}
|
|
@@ -117,10 +109,13 @@ function asResultRecord(v: unknown): Record<string, unknown> | undefined {
|
|
|
117
109
|
/**
|
|
118
110
|
* 统一的 execute 包装:调用 select 通道并解析结果。
|
|
119
111
|
* 返回标准 AgentToolResult 形状;select 取消/超时/异常/非 JSON 回包是错误路径,
|
|
120
|
-
* 必须 throw(extension-conventions「禁止错误成功模式」——
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
112
|
+
* 必须 throw(extension-conventions「禁止错误成功模式」——execute throw → pi
|
|
113
|
+
* agent-loop catch 置 isError:true(pi-agent-core dist/agent-loop.js
|
|
114
|
+
* executePreparedToolCall,1.0.0 实读 catch :581-588);1.0.0 起返回值 isError:true
|
|
115
|
+
* 也被尊重(同文件 :579 `isError: result.isError === true`,0.84.4 时返回值会被
|
|
116
|
+
* 丢弃)——本工具失败恒走 throw,两版语义等价(语义登记 PS-56);
|
|
117
|
+
* ask-user/scheduler/session-reader 的 W4 throw 范式同款,调用方 agent 需能区分
|
|
118
|
+
* 成功与失败以决定重试/放弃)。
|
|
124
119
|
*/
|
|
125
120
|
async function executeTool(
|
|
126
121
|
ctx: ExtensionContext,
|
|
@@ -130,13 +125,13 @@ async function executeTool(
|
|
|
130
125
|
): Promise<{ content: Array<{ type: "text"; text: string }>; details: undefined }> {
|
|
131
126
|
const result = await callSessionManager(ctx, action, params);
|
|
132
127
|
if (!result.ok) {
|
|
133
|
-
// 行为微变①(D8
|
|
128
|
+
// 行为微变①(D8,有意):非 JSON 回包从「catch 后
|
|
134
129
|
// parsed=undefined 静默当成功文本返回」改为 throw + 提示文本(留痕由原语
|
|
135
|
-
// 经注入的 logger.error
|
|
130
|
+
// 经注入的 logger.error 承担);不传 timeout 后剩余 cancelled/channel-error 两态折叠。
|
|
136
131
|
const text =
|
|
137
132
|
result.reason === "non-json"
|
|
138
133
|
? `Session manager ${action}: non-JSON response from runtime (protocol mismatch — redeploy same-version runtime + extension; see extension logs).`
|
|
139
|
-
: `Session manager ${action}: cancelled or
|
|
134
|
+
: `Session manager ${action}: cancelled or channel error.`;
|
|
140
135
|
throw new Error(text);
|
|
141
136
|
}
|
|
142
137
|
const raw = result.value;
|
|
@@ -189,7 +184,8 @@ function registerSessionTool<S extends TObject>(pi: ExtensionAPI, cfg: SessionTo
|
|
|
189
184
|
params: Static<S>,
|
|
190
185
|
_signal: AbortSignal | undefined,
|
|
191
186
|
_onUpdate: unknown,
|
|
192
|
-
ctx
|
|
187
|
+
// pi 1.0.0:ToolDefinition.execute 第 5 参 ctx 收窄为 ExtensionToolContext
|
|
188
|
+
ctx: ExtensionToolContext,
|
|
193
189
|
) {
|
|
194
190
|
return executeTool(ctx, cfg.action, cfg.toParams(params), cfg.onResult);
|
|
195
191
|
},
|