ycodium-acp-executor 0.2.3072 → 0.2.3076

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.
@@ -6,7 +6,7 @@ export type AcpDispatchedPrompt = {
6
6
  /**
7
7
  * 发一轮 prompt,在 `session/prompt` 写进对端 stdin 时就返回,不等整轮跑完:插件的 `sendTurn`
8
8
  * 据此交出投递确认(规则 13 的判据),整轮结果走 `turn.completed`。写入之前就失败(会话已关、
9
- * 换模型失败)照旧 reject;写入之前就被取消,按执行器给的 cancelled 结果返回。
9
+ * 换模型失败)照旧 reject;插话未写出就被取消,必须拒收,不能确认投递。普通 prompt 保留取消结果。
10
10
  *
11
11
  * 会话忙闲以 `executor.status` 为准;写入之后的失败由执行器以 failed 收尾并记日志。
12
12
  */
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-dispatch.d.ts","sourceRoot":"","sources":["../src/prompt-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACrC,OAAO,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,KAC1C,OAAO,CAAC,mBAAmB,CAQ7B,CAAC"}
1
+ {"version":3,"file":"prompt-dispatch.d.ts","sourceRoot":"","sources":["../src/prompt-dispatch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EACrC,OAAO,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,KAC1C,OAAO,CAAC,mBAAmB,CAuB7B,CAAC"}
@@ -1,17 +1,31 @@
1
+ import { AcpExecutorTurnEndedError } from "./errors.js";
1
2
  /**
2
3
  * 发一轮 prompt,在 `session/prompt` 写进对端 stdin 时就返回,不等整轮跑完:插件的 `sendTurn`
3
4
  * 据此交出投递确认(规则 13 的判据),整轮结果走 `turn.completed`。写入之前就失败(会话已关、
4
- * 换模型失败)照旧 reject;写入之前就被取消,按执行器给的 cancelled 结果返回。
5
+ * 换模型失败)照旧 reject;插话未写出就被取消,必须拒收,不能确认投递。普通 prompt 保留取消结果。
5
6
  *
6
7
  * 会话忙闲以 `executor.status` 为准;写入之后的失败由执行器以 failed 收尾并记日志。
7
8
  */
8
9
  export const dispatchAcpPrompt = (executor, input) => {
9
10
  const { promise: dispatched, resolve } = Promise.withResolvers();
10
- const finished = executor.prompt({ ...input, onDispatched: resolve });
11
+ let written = false;
12
+ const finished = executor.prompt({
13
+ ...input,
14
+ onDispatched: (turnId) => {
15
+ written = true;
16
+ resolve(turnId);
17
+ },
18
+ });
11
19
  return Promise.race([
12
20
  dispatched.then((turnId) => ({ turnId })),
13
- // 写入之前就落定:成功(写入前被取消)带 turnId;拒绝原样交给调用方,那是起轮失败。
14
- finished.then((result) => ({ turnId: result.turnId })),
21
+ finished.then((result) => {
22
+ if (!written &&
23
+ input.expectedActiveTurnId !== undefined &&
24
+ result.stopReason === "cancelled") {
25
+ throw new AcpExecutorTurnEndedError();
26
+ }
27
+ return { turnId: result.turnId };
28
+ }),
15
29
  ]);
16
30
  };
17
31
  //# sourceMappingURL=prompt-dispatch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-dispatch.js","sourceRoot":"","sources":["../src/prompt-dispatch.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAqC,EACrC,KAA2C,EACb,EAAE;IAChC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,EAAU,CAAC;IACzE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,+CAA+C;QAC/C,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;KACvD,CAAC,CAAC;AACL,CAAC,CAAC"}
1
+ {"version":3,"file":"prompt-dispatch.js","sourceRoot":"","sources":["../src/prompt-dispatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAQxD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,QAAqC,EACrC,KAA2C,EACb,EAAE;IAChC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,aAAa,EAAU,CAAC;IACzE,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,GAAG,KAAK;QACR,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE;YACvB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC;KACF,CAAC,CAAC;IACH,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;YACvB,IACE,CAAC,OAAO;gBACR,KAAK,CAAC,oBAAoB,KAAK,SAAS;gBACxC,MAAM,CAAC,UAAU,KAAK,WAAW,EACjC,CAAC;gBACD,MAAM,IAAI,yBAAyB,EAAE,CAAC;YACxC,CAAC;YACD,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACnC,CAAC,CAAC;KACH,CAAC,CAAC;AACL,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ycodium-acp-executor",
3
- "version": "0.2.3072",
3
+ "version": "0.2.3076",
4
4
  "description": "Agent Client Protocol client and executor state machine for Ycodium agent plugins. Speaks ACP over stdio and emits Ycodium executor events.",
5
5
  "keywords": [
6
6
  "acp",
@@ -29,7 +29,8 @@
29
29
  "devDependencies": {
30
30
  "@types/node": "24.12.4",
31
31
  "typescript": "~6.0.3",
32
- "vite-plus": "0.2.2"
32
+ "vite-plus": "0.2.2",
33
+ "ycodium-executor-testing": "0.0.0"
33
34
  },
34
35
  "scripts": {
35
36
  "build": "tsc -p tsconfig.build.json",
@@ -1,29 +0,0 @@
1
- import * as NodeStream from "node:stream";
2
- export type HeldPromptFrame = {
3
- readonly id?: number | string;
4
- readonly method?: string;
5
- readonly params?: Record<string, unknown>;
6
- };
7
- export declare class HeldPromptAgent {
8
- readonly clientReadable: NodeStream.PassThrough;
9
- readonly clientWritable: NodeStream.PassThrough;
10
- readonly frames: HeldPromptFrame[];
11
- /** 最近一条 `session/prompt`;每条新的覆盖上一条。 */
12
- promptFrame: HeldPromptFrame | undefined;
13
- /** false 时收到 prompt 立即以空结果应答(不挂起)。 */
14
- holdPrompt: boolean;
15
- /** true 时不回答 initialize,用来造握手还没完成连接就断。 */
16
- hangInitialize: boolean;
17
- /** 收到 `session/cancel` 时以 cancelled 应答挂着的 prompt。 */
18
- answerCancel: boolean;
19
- /** 并进 `session/new` 应答的字段(比如 `models`)。别的请求(换模型等)不自动应答。 */
20
- sessionExtras: Record<string, unknown>;
21
- constructor();
22
- write(obj: unknown): void;
23
- reply(text: string): void;
24
- answer(stopReason?: string): void;
25
- fail(message: string): void;
26
- }
27
- /** 逐个 setImmediate 轮询直到条件成立;5 秒后报出等的是什么。 */
28
- export declare const waitFor: (isDone: () => boolean, label: string) => Promise<void>;
29
- //# sourceMappingURL=heldPromptAgent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"heldPromptAgent.d.ts","sourceRoot":"","sources":["../../src/testing/heldPromptAgent.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C,CAAC;AAEF,qBAAa,eAAe;IAC1B,QAAQ,CAAC,cAAc,yBAAgC;IACvD,QAAQ,CAAC,cAAc,yBAAgC;IACvD,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAM;IACxC,uCAAuC;IACvC,WAAW,EAAE,eAAe,GAAG,SAAS,CAAC;IACzC,sCAAsC;IACtC,UAAU,UAAQ;IAClB,0CAA0C;IAC1C,cAAc,UAAS;IACvB,qDAAqD;IACrD,YAAY,UAAS;IACrB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM;;IAiC5C,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAIzB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWzB,MAAM,CAAC,UAAU,SAAa,GAAG,IAAI;IAKrC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAI5B;AAED,4CAA4C;AAC5C,eAAO,MAAM,OAAO,GAAU,QAAQ,MAAM,OAAO,EAAE,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAMhF,CAAC"}
@@ -1,93 +0,0 @@
1
- // @effect-diagnostics nodeBuiltinImport:off globalDate:off - 测试用的进程内假 ACP agent;waitFor 的截止用 Date.now()。
2
- /**
3
- * 测试用的进程内假 ACP agent:答 initialize 与 session/new(会话 `sess-1`),收到
4
- * `session/prompt` 默认只记下、不应答,由用例决定何时推回复、应答或报错。厂商私有的帧
5
- * (提前收口通知等)由各用例经 `write` 自己写。
6
- */
7
- import * as NodeReadline from "node:readline";
8
- import * as NodeStream from "node:stream";
9
- export class HeldPromptAgent {
10
- clientReadable = new NodeStream.PassThrough();
11
- clientWritable = new NodeStream.PassThrough();
12
- frames = [];
13
- /** 最近一条 `session/prompt`;每条新的覆盖上一条。 */
14
- promptFrame;
15
- /** false 时收到 prompt 立即以空结果应答(不挂起)。 */
16
- holdPrompt = true;
17
- /** true 时不回答 initialize,用来造握手还没完成连接就断。 */
18
- hangInitialize = false;
19
- /** 收到 `session/cancel` 时以 cancelled 应答挂着的 prompt。 */
20
- answerCancel = false;
21
- /** 并进 `session/new` 应答的字段(比如 `models`)。别的请求(换模型等)不自动应答。 */
22
- sessionExtras = {};
23
- constructor() {
24
- NodeReadline.createInterface({ input: this.clientWritable }).on("line", (line) => {
25
- let frame;
26
- try {
27
- frame = JSON.parse(line);
28
- }
29
- catch {
30
- return;
31
- }
32
- this.frames.push(frame);
33
- if (frame.method === "initialize") {
34
- if (this.hangInitialize)
35
- return;
36
- this.write({
37
- jsonrpc: "2.0",
38
- id: frame.id,
39
- result: { protocolVersion: 1, agentCapabilities: {}, agentInfo: { name: "fake" } },
40
- });
41
- }
42
- else if (frame.method === "session/new") {
43
- this.write({
44
- jsonrpc: "2.0",
45
- id: frame.id,
46
- result: { sessionId: "sess-1", ...this.sessionExtras },
47
- });
48
- }
49
- else if (frame.method === "session/prompt") {
50
- this.promptFrame = frame;
51
- if (!this.holdPrompt)
52
- this.write({ jsonrpc: "2.0", id: frame.id, result: {} });
53
- }
54
- else if (frame.method === "session/cancel" && this.answerCancel) {
55
- this.answer("cancelled");
56
- }
57
- });
58
- }
59
- write(obj) {
60
- if (this.clientReadable.writable)
61
- this.clientReadable.write(`${JSON.stringify(obj)}\n`);
62
- }
63
- reply(text) {
64
- this.write({
65
- jsonrpc: "2.0",
66
- method: "session/update",
67
- params: {
68
- sessionId: "sess-1",
69
- update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text } },
70
- },
71
- });
72
- }
73
- answer(stopReason = "end_turn") {
74
- if (this.promptFrame === undefined)
75
- throw new Error("prompt was not received");
76
- this.write({ jsonrpc: "2.0", id: this.promptFrame.id, result: { stopReason } });
77
- }
78
- fail(message) {
79
- if (this.promptFrame === undefined)
80
- throw new Error("prompt was not received");
81
- this.write({ jsonrpc: "2.0", id: this.promptFrame.id, error: { code: -32603, message } });
82
- }
83
- }
84
- /** 逐个 setImmediate 轮询直到条件成立;5 秒后报出等的是什么。 */
85
- export const waitFor = async (isDone, label) => {
86
- const deadline = Date.now() + 5_000;
87
- while (!isDone()) {
88
- if (Date.now() > deadline)
89
- throw new Error(`timed out waiting for ${label}`);
90
- await new Promise((resolve) => setImmediate(resolve));
91
- }
92
- };
93
- //# sourceMappingURL=heldPromptAgent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"heldPromptAgent.js","sourceRoot":"","sources":["../../src/testing/heldPromptAgent.ts"],"names":[],"mappings":"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"}