@akagilnc/pi-workflow-roles 0.1.2471 → 0.1.2477
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { ENGINE_DETOUR_TOOL_NAME, engineDetourFailureDiagnostic, engineNameFromEnv, isEngineDetourFailure, runEngineDetourOnce, } from "./engine-detour.js";
|
|
3
3
|
const engineDetourArgsSchema = Type.Object({
|
|
4
4
|
argv: Type.Array(Type.String({ minLength: 1 }), {
|
|
5
5
|
minItems: 1,
|
|
@@ -18,26 +18,20 @@ function isCallerCancellation(error, signal) {
|
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Build one
|
|
22
|
-
* `latch` is shared so parent registration can reset between activations.
|
|
21
|
+
* Build one detour tool definition for a configured engine name.
|
|
23
22
|
* `fail` owns host abort (parent) vs throw (evidence child) for tool misuse only.
|
|
24
23
|
* Engine process failures (nonzero/empty/spawn) stop via `fail` with their cause.
|
|
25
24
|
* Caller AbortSignal cancellation propagates unchanged.
|
|
26
25
|
*/
|
|
27
26
|
export function createEngineDetourToolDefinition(input) {
|
|
28
|
-
const latch = input.latch ?? { used: false };
|
|
29
27
|
const engineName = input.engineName;
|
|
30
28
|
return {
|
|
31
29
|
name: ENGINE_DETOUR_TOOL_NAME,
|
|
32
30
|
label: "劳务引擎",
|
|
33
|
-
description: `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session
|
|
31
|
+
description: `运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session。`,
|
|
34
32
|
promptSnippet: "运行配置的劳务引擎一次并返回 stdout",
|
|
35
33
|
parameters: engineDetourArgsSchema,
|
|
36
34
|
async execute(toolCallId, params, signal, _onUpdate, ctx) {
|
|
37
|
-
if (latch.used) {
|
|
38
|
-
input.fail(new Error(ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC), toolCallId, ctx);
|
|
39
|
-
}
|
|
40
|
-
latch.used = true;
|
|
41
35
|
const args = params;
|
|
42
36
|
const argv = Array.isArray(args.argv) ? args.argv : [];
|
|
43
37
|
if (argv.length === 0 || argv.some((part) => typeof part !== "string" || part.length === 0)) {
|
|
@@ -67,6 +61,7 @@ export function createEngineDetourToolDefinition(input) {
|
|
|
67
61
|
details: {
|
|
68
62
|
tool: ENGINE_DETOUR_TOOL_NAME,
|
|
69
63
|
code: result.code,
|
|
64
|
+
stderr: result.stderr,
|
|
70
65
|
},
|
|
71
66
|
};
|
|
72
67
|
},
|
|
@@ -75,31 +70,18 @@ export function createEngineDetourToolDefinition(input) {
|
|
|
75
70
|
/**
|
|
76
71
|
* Register the engine-generic detour tool once for this process when any role has
|
|
77
72
|
* an engine activation signal. Returns whether registration occurred.
|
|
78
|
-
* Once-latch is activation-scoped via the returned reset handle.
|
|
79
73
|
*/
|
|
80
74
|
export function registerEngineDetourTool(pi, hostActions) {
|
|
81
75
|
const engineName = engineNameFromEnv();
|
|
82
76
|
if (engineName === undefined) {
|
|
83
|
-
return
|
|
84
|
-
registered: false,
|
|
85
|
-
resetLatch() {
|
|
86
|
-
/* no-op when unregistered */
|
|
87
|
-
},
|
|
88
|
-
};
|
|
77
|
+
return false;
|
|
89
78
|
}
|
|
90
|
-
const latch = { used: false };
|
|
91
79
|
const definition = createEngineDetourToolDefinition({
|
|
92
80
|
engineName,
|
|
93
|
-
latch,
|
|
94
81
|
fail(error, toolCallId, ctx) {
|
|
95
82
|
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
96
83
|
},
|
|
97
84
|
});
|
|
98
85
|
pi.registerTool(definition);
|
|
99
|
-
return
|
|
100
|
-
registered: true,
|
|
101
|
-
resetLatch() {
|
|
102
|
-
latch.used = false;
|
|
103
|
-
},
|
|
104
|
-
};
|
|
86
|
+
return true;
|
|
105
87
|
}
|
package/dist/engine-detour.js
CHANGED
|
@@ -22,7 +22,6 @@ export function applyEngineChildEnv(childEnv, engine) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
export const ENGINE_DETOUR_EMPTY_STDOUT_DIAGNOSTIC = "劳务引擎 stdout 为空";
|
|
25
|
-
export const ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC = "本激活内劳务引擎已使用";
|
|
26
25
|
function abortReasonError(signal) {
|
|
27
26
|
const reason = signal.reason;
|
|
28
27
|
if (reason instanceof Error)
|
package/package.json
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# zcode engine method material
|
|
2
|
+
|
|
3
|
+
This file is packaged technical material for the optional `zcode` labor engine
|
|
4
|
+
(Z.AI ZCode agent runtime on the host, GLM Coding Plan models).
|
|
5
|
+
|
|
6
|
+
Before invoking the engine, read `../engine-dispatch.md`, resolving that path
|
|
7
|
+
relative to this note. This note only covers this engine's CLI technical
|
|
8
|
+
parameters.
|
|
9
|
+
|
|
10
|
+
## Invocation (host-verified 2026-08-29)
|
|
11
|
+
|
|
12
|
+
The machine entrypoint is `zcode` (npm `zcode-app-cli`, wraps the official
|
|
13
|
+
ZCode runtime; host has 3.10.1-17 / runtime 0.16.5). Non-interactive labor:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
zcode --prompt 'YOUR_LABOR_PROMPT' --cwd /path/to/worktree
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`--prompt` defaults to permission mode `yolo` (no TTY permission stalls).
|
|
20
|
+
Useful extras measured from `zcode --help`: `--attach <path>` (repeatable),
|
|
21
|
+
`--mode build|edit|plan|yolo`, `--resume <sess_...>`, `--json` where
|
|
22
|
+
supported. Prefer `zcode --help` on the host over any remembered flag set.
|
|
23
|
+
|
|
24
|
+
## Realm and model traps (host-verified 2026-08-29, all three hit in sequence)
|
|
25
|
+
|
|
26
|
+
- Missing `~/.zcode/cli/config.json` → hard error `Model config is missing`.
|
|
27
|
+
The desktop app's login is NOT shared with the CLI.
|
|
28
|
+
- `zcode login` signs into the **overseas Z.AI realm only**. An account on the
|
|
29
|
+
mainland BigModel realm then fails with
|
|
30
|
+
`[1113][Insufficient balance or no resource package]`.
|
|
31
|
+
- The scaffolded config defaults `model.main` to `zai/glm-5.2`, which is not
|
|
32
|
+
in the coding plan — same 1113 failure even with a valid plan.
|
|
33
|
+
|
|
34
|
+
Working mainland configuration (per official docs
|
|
35
|
+
`docs.bigmodel.cn/cn/coding-plan/quick-start`): in
|
|
36
|
+
`~/.zcode/cli/config.json`, provider kind `anthropic` with
|
|
37
|
+
`baseURL: https://open.bigmodel.cn/api/anthropic`, `options.apiKey` = the
|
|
38
|
+
coding-plan key (host keychain: service `glm-key`, account `akagilnc`), and
|
|
39
|
+
`model.main: zai/glm-5.3`, `model.lite: zai/glm-5.3-flash`. With that config
|
|
40
|
+
the smoke prompt returns normally.
|
|
41
|
+
|
|
42
|
+
## Quota facts (owner-provided, 2026-08-28)
|
|
43
|
+
|
|
44
|
+
Plan quotas are daily and per-model (GLM-5.3 3M/day, Flash 5M/day on the
|
|
45
|
+
current plan; a weekend event granted a larger temporary pool). Whether cached
|
|
46
|
+
tokens count toward quota is unverified.
|
|
@@ -14,7 +14,6 @@ import type {
|
|
|
14
14
|
import { Type, type Static } from "typebox";
|
|
15
15
|
|
|
16
16
|
import {
|
|
17
|
-
ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC,
|
|
18
17
|
ENGINE_DETOUR_TOOL_NAME,
|
|
19
18
|
engineDetourFailureDiagnostic,
|
|
20
19
|
engineNameFromEnv,
|
|
@@ -42,13 +41,6 @@ export type EngineDetourHostActions = {
|
|
|
42
41
|
): never;
|
|
43
42
|
};
|
|
44
43
|
|
|
45
|
-
export type EngineDetourToolRegistration = {
|
|
46
|
-
/** True when the tool definition was installed on this ExtensionAPI. */
|
|
47
|
-
readonly registered: boolean;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
type EngineDetourLatch = { used: boolean };
|
|
51
|
-
|
|
52
44
|
/** Caller/upper-layer cancellation must propagate unchanged. */
|
|
53
45
|
function isCallerCancellation(
|
|
54
46
|
error: unknown,
|
|
@@ -66,24 +58,21 @@ function isCallerCancellation(
|
|
|
66
58
|
}
|
|
67
59
|
|
|
68
60
|
/**
|
|
69
|
-
* Build one
|
|
70
|
-
* `latch` is shared so parent registration can reset between activations.
|
|
61
|
+
* Build one detour tool definition for a configured engine name.
|
|
71
62
|
* `fail` owns host abort (parent) vs throw (evidence child) for tool misuse only.
|
|
72
63
|
* Engine process failures (nonzero/empty/spawn) stop via `fail` with their cause.
|
|
73
64
|
* Caller AbortSignal cancellation propagates unchanged.
|
|
74
65
|
*/
|
|
75
66
|
export function createEngineDetourToolDefinition(input: {
|
|
76
67
|
engineName: string;
|
|
77
|
-
latch?: EngineDetourLatch;
|
|
78
68
|
fail: (error: Error, toolCallId: string, ctx: ExtensionContext) => never;
|
|
79
69
|
}): ToolDefinition {
|
|
80
|
-
const latch = input.latch ?? { used: false };
|
|
81
70
|
const engineName = input.engineName;
|
|
82
71
|
return {
|
|
83
72
|
name: ENGINE_DETOUR_TOOL_NAME,
|
|
84
73
|
label: "劳务引擎",
|
|
85
74
|
description:
|
|
86
|
-
`运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session
|
|
75
|
+
`运行一次劳务引擎子进程(engine=${engineName}),stdout 返回本 session。`,
|
|
87
76
|
promptSnippet: "运行配置的劳务引擎一次并返回 stdout",
|
|
88
77
|
parameters: engineDetourArgsSchema,
|
|
89
78
|
async execute(
|
|
@@ -93,15 +82,6 @@ export function createEngineDetourToolDefinition(input: {
|
|
|
93
82
|
_onUpdate,
|
|
94
83
|
ctx,
|
|
95
84
|
): Promise<AgentToolResult<unknown>> {
|
|
96
|
-
if (latch.used) {
|
|
97
|
-
input.fail(
|
|
98
|
-
new Error(ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC),
|
|
99
|
-
toolCallId,
|
|
100
|
-
ctx,
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
latch.used = true;
|
|
104
|
-
|
|
105
85
|
const args = params as EngineDetourArgs;
|
|
106
86
|
const argv = Array.isArray(args.argv) ? args.argv : [];
|
|
107
87
|
if (argv.length === 0 || argv.some((part) => typeof part !== "string" || part.length === 0)) {
|
|
@@ -140,6 +120,7 @@ export function createEngineDetourToolDefinition(input: {
|
|
|
140
120
|
details: {
|
|
141
121
|
tool: ENGINE_DETOUR_TOOL_NAME,
|
|
142
122
|
code: result.code,
|
|
123
|
+
stderr: result.stderr,
|
|
143
124
|
},
|
|
144
125
|
};
|
|
145
126
|
},
|
|
@@ -149,36 +130,23 @@ export function createEngineDetourToolDefinition(input: {
|
|
|
149
130
|
/**
|
|
150
131
|
* Register the engine-generic detour tool once for this process when any role has
|
|
151
132
|
* an engine activation signal. Returns whether registration occurred.
|
|
152
|
-
* Once-latch is activation-scoped via the returned reset handle.
|
|
153
133
|
*/
|
|
154
134
|
export function registerEngineDetourTool(
|
|
155
135
|
pi: ExtensionAPI,
|
|
156
136
|
hostActions: EngineDetourHostActions,
|
|
157
|
-
):
|
|
137
|
+
): boolean {
|
|
158
138
|
const engineName = engineNameFromEnv();
|
|
159
139
|
if (engineName === undefined) {
|
|
160
|
-
return
|
|
161
|
-
registered: false,
|
|
162
|
-
resetLatch() {
|
|
163
|
-
/* no-op when unregistered */
|
|
164
|
-
},
|
|
165
|
-
};
|
|
140
|
+
return false;
|
|
166
141
|
}
|
|
167
142
|
|
|
168
|
-
const latch: EngineDetourLatch = { used: false };
|
|
169
143
|
const definition = createEngineDetourToolDefinition({
|
|
170
144
|
engineName,
|
|
171
|
-
latch,
|
|
172
145
|
fail(error, toolCallId, ctx) {
|
|
173
146
|
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
174
147
|
},
|
|
175
148
|
});
|
|
176
149
|
pi.registerTool(definition);
|
|
177
150
|
|
|
178
|
-
return
|
|
179
|
-
registered: true,
|
|
180
|
-
resetLatch() {
|
|
181
|
-
latch.used = false;
|
|
182
|
-
},
|
|
183
|
-
};
|
|
151
|
+
return true;
|
|
184
152
|
}
|
package/src/engine-detour.ts
CHANGED
|
@@ -30,9 +30,6 @@ export function applyEngineChildEnv(
|
|
|
30
30
|
export const ENGINE_DETOUR_EMPTY_STDOUT_DIAGNOSTIC =
|
|
31
31
|
"劳务引擎 stdout 为空" as const;
|
|
32
32
|
|
|
33
|
-
export const ENGINE_DETOUR_ALREADY_USED_DIAGNOSTIC =
|
|
34
|
-
"本激活内劳务引擎已使用" as const;
|
|
35
|
-
|
|
36
33
|
export type EngineDetourResult = Readonly<{
|
|
37
34
|
code: number;
|
|
38
35
|
stdout: string;
|
package/src/role-runtime.ts
CHANGED
|
@@ -629,7 +629,7 @@ export function createRoleRuntimeExtension(
|
|
|
629
629
|
const pendingInfrastructureFailures = new Map<string, PendingInfrastructureFailure>();
|
|
630
630
|
// Envelope-owned execute→tool_result bridge for Gatekeeper non-pass (ADR 0018).
|
|
631
631
|
const pendingGatekeeperNonPassByToolCallId = new Map<string, GatekeeperNonPassResult>();
|
|
632
|
-
let
|
|
632
|
+
let engineDetourRegistered = false;
|
|
633
633
|
// #288 primary-session thin adapter. The policy is the sole budget owner;
|
|
634
634
|
// terminating-tool rejections and mechanical delivery requests share two turns.
|
|
635
635
|
let receiptDelivery = createReceiptDeliveryPolicy();
|
|
@@ -1109,7 +1109,6 @@ export function createRoleRuntimeExtension(
|
|
|
1109
1109
|
pendingNavigatorSettlement = undefined;
|
|
1110
1110
|
pendingInfrastructureFailures.clear();
|
|
1111
1111
|
pendingGatekeeperNonPassByToolCallId.clear();
|
|
1112
|
-
engineDetourRegistration?.resetLatch();
|
|
1113
1112
|
navigatorWorkContext = undefined;
|
|
1114
1113
|
// #351: OAuth keepalive is orthogonal to --ak-role; start before role early-return
|
|
1115
1114
|
// so role-less sessions (and reload after shutdown stop) still keep tokens alive.
|
|
@@ -1224,11 +1223,8 @@ export function createRoleRuntimeExtension(
|
|
|
1224
1223
|
await executeActivationStage(entry.role, activationStage(entry.role, runtime), { clock, writeTrace });
|
|
1225
1224
|
// #357 T2 / #378 / #380 / #391: any role+engine activation registers the package detour tool once.
|
|
1226
1225
|
// Gate is env presence only — no per-engine execute branch; no role-module spawn.
|
|
1227
|
-
if (
|
|
1228
|
-
|
|
1229
|
-
if (!engineDetourRegistration.registered) {
|
|
1230
|
-
engineDetourRegistration = undefined;
|
|
1231
|
-
}
|
|
1226
|
+
if (!engineDetourRegistered) {
|
|
1227
|
+
engineDetourRegistered = registerEngineDetourTool(pi, hostActions);
|
|
1232
1228
|
}
|
|
1233
1229
|
// Worker gates ①②: arm records baseline and runs private one-shot hook uninstall (ADR 0070).
|
|
1234
1230
|
// Parent session feeds #216 createRecordSession so baseline/bounce survive resume.
|