@maplezzk/pi-dynamic-workflows 1.2.2 → 1.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 +2 -2
- package/src/extension.ts +14 -7
- package/src/notice.ts +13 -0
- package/src/subagent-agent.ts +29 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maplezzk/pi-dynamic-workflows",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Claude-Code-style dynamic workflow orchestration for Pi. Fork of michaelliv/pi-dynamic-workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
],
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"acorn": "^8.16.0",
|
|
63
|
-
"pi-extensions-i18n": "^0.
|
|
63
|
+
"pi-extensions-i18n": "^0.5.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@earendil-works/pi-ai": ">=0.80.0",
|
package/src/extension.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineTool, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Box, Text } from "@earendil-works/pi-tui";
|
|
3
|
-
import { createTranslator, loadCatalog } from "pi-extensions-i18n";
|
|
3
|
+
import { createTranslator, loadCatalog, notifyWithSource } from "pi-extensions-i18n";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { loadConfig, saveConfig } from "./config.ts";
|
|
6
6
|
import { cancelRunningWorkflow, createWorkflowTool, renderWorkflowThemed } from "./index.ts";
|
|
7
|
+
import { NOTICE_SOURCE } from "./notice.ts";
|
|
7
8
|
|
|
8
9
|
const i18n = createTranslator(loadCatalog(new URL("../locales/index.json", import.meta.url)));
|
|
9
|
-
const LOG_PREFIX = "[pi-dynamic-workflows]";
|
|
10
10
|
|
|
11
11
|
export default function extension(pi: ExtensionAPI) {
|
|
12
12
|
// Subagent session 不注册 workflow 工具:subagent 是 workflow 的执行节点,
|
|
@@ -122,13 +122,20 @@ function registerConfigCommand(pi: ExtensionAPI) {
|
|
|
122
122
|
|
|
123
123
|
if (choice === choices[0]) {
|
|
124
124
|
const saved = saveConfig({ backend: cfg.backend === "subagent" ? "workflow" : "subagent" });
|
|
125
|
-
|
|
125
|
+
notifyWithSource({
|
|
126
|
+
ctx,
|
|
127
|
+
source: NOTICE_SOURCE,
|
|
128
|
+
level: "info",
|
|
129
|
+
message: i18n.t("savedBackend", { value: saved.backend }),
|
|
130
|
+
});
|
|
126
131
|
} else if (choice === choices[1]) {
|
|
127
132
|
const saved = saveConfig({ async: !cfg.async });
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
notifyWithSource({
|
|
134
|
+
ctx,
|
|
135
|
+
source: NOTICE_SOURCE,
|
|
136
|
+
level: "info",
|
|
137
|
+
message: `${i18n.t("savedAsync", { value: saved.async ? on : off })} ${i18n.t("reloadHint")}`,
|
|
138
|
+
});
|
|
132
139
|
}
|
|
133
140
|
}
|
|
134
141
|
},
|
package/src/notice.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 本扩展统一的提示来源定义。
|
|
3
|
+
* 所有 notifyWithSource 调用共用同一份标签与颜色,避免多个入口不一致。
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { NoticeColor, NoticeSource } from "pi-extensions-i18n";
|
|
7
|
+
|
|
8
|
+
/** 本扩展的提示标签;短且唯一,便于在会话里定位来源。 */
|
|
9
|
+
export const NOTICE_TAG = "workflow";
|
|
10
|
+
/** 提示标签颜色;与其它扩展错开,避免看起来像同一条消息。 */
|
|
11
|
+
export const NOTICE_COLOR: NoticeColor = "accent";
|
|
12
|
+
/** 本扩展的提示来源。 */
|
|
13
|
+
export const NOTICE_SOURCE: NoticeSource = { tag: NOTICE_TAG, color: NOTICE_COLOR };
|
package/src/subagent-agent.ts
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
// sentinel)导致的"子 agent 根本没启动就被判定完成"。herdr-split.log 9:01 失败批次
|
|
13
13
|
// 模式:pane run 6ms 后 close,subagentSessionFile.jsonl 永远不存在。
|
|
14
14
|
import { existsSync, statSync } from "node:fs";
|
|
15
|
-
import { createTranslator, loadCatalog } from "pi-extensions-i18n";
|
|
15
|
+
import { createTranslator, loadCatalog, notifyWithSource, type NoticeColor } from "pi-extensions-i18n";
|
|
16
|
+
import { NOTICE_SOURCE } from "./notice.ts";
|
|
16
17
|
|
|
17
18
|
const i18n = createTranslator(loadCatalog(new URL("../locales/index.json", import.meta.url)));
|
|
18
19
|
|
|
@@ -39,7 +40,13 @@ interface SubagentCtx {
|
|
|
39
40
|
cwd: string;
|
|
40
41
|
model?: unknown;
|
|
41
42
|
modelRegistry?: unknown;
|
|
42
|
-
|
|
43
|
+
/** Pi 运行模式;只有 tui 能给来源标签上色。 */
|
|
44
|
+
mode?: string;
|
|
45
|
+
ui?: {
|
|
46
|
+
notify?(message: string, level: "info" | "warning" | "error"): void;
|
|
47
|
+
/** 主题;缺失时来源标签输出纯文本。 */
|
|
48
|
+
theme?: { fg(color: NoticeColor, text: string): string };
|
|
49
|
+
};
|
|
43
50
|
[key: string]: unknown;
|
|
44
51
|
}
|
|
45
52
|
|
|
@@ -117,6 +124,19 @@ export class SubagentWorkflowAgent {
|
|
|
117
124
|
this.instructions = options.instructions;
|
|
118
125
|
}
|
|
119
126
|
|
|
127
|
+
/** 统一提示出口:加上来源标签;ui 缺失时跳过提示,不影响流程。 */
|
|
128
|
+
private notify(message: string, level: "info" | "warning" | "error"): void {
|
|
129
|
+
const ui = this.launchCtx.ui;
|
|
130
|
+
if (!ui?.notify) return;
|
|
131
|
+
const notify = ui.notify.bind(ui);
|
|
132
|
+
notifyWithSource({
|
|
133
|
+
ctx: { mode: this.launchCtx.mode, ui: { notify, theme: ui.theme } },
|
|
134
|
+
source: NOTICE_SOURCE,
|
|
135
|
+
level,
|
|
136
|
+
message,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
120
140
|
async run(prompt: string, options: AgentRunOptions = {}): Promise<AgentRunResult> {
|
|
121
141
|
const api = getSubagentApi();
|
|
122
142
|
|
|
@@ -139,7 +159,7 @@ export class SubagentWorkflowAgent {
|
|
|
139
159
|
},
|
|
140
160
|
this.launchCtx,
|
|
141
161
|
);
|
|
142
|
-
this.
|
|
162
|
+
this.notify(`"${options.label ?? "workflow-agent"}" launched (${Date.now() - launchedAt}ms)`, "info");
|
|
143
163
|
|
|
144
164
|
// Create abort signal that combines caller's signal with module-level abort
|
|
145
165
|
const abortController = new AbortController();
|
|
@@ -157,8 +177,8 @@ export class SubagentWorkflowAgent {
|
|
|
157
177
|
const watchStartedAt = Date.now();
|
|
158
178
|
const result = await api.watchSubagent(running, abortController.signal);
|
|
159
179
|
const watchTookMs = Date.now() - watchStartedAt;
|
|
160
|
-
this.
|
|
161
|
-
`
|
|
180
|
+
this.notify(
|
|
181
|
+
`"${options.label ?? "workflow-agent"}" done (${watchTookMs}ms) → ` +
|
|
162
182
|
`exitCode=${result.exitCode} hasOutput=${result.structuredOutput !== undefined}`,
|
|
163
183
|
"info",
|
|
164
184
|
);
|
|
@@ -171,8 +191,8 @@ export class SubagentWorkflowAgent {
|
|
|
171
191
|
// 这种"假成功"比"明确失败"更危险——workflow 会把空数据当成结果继续往下走。
|
|
172
192
|
const jsonlCheck = sessionFileLooksValid(running.sessionFile);
|
|
173
193
|
if (!jsonlCheck.ok) {
|
|
174
|
-
this.
|
|
175
|
-
`
|
|
194
|
+
this.notify(
|
|
195
|
+
`"${options.label ?? "workflow-agent"}" SESSION FILE ${jsonlCheck.reason} ` +
|
|
176
196
|
`(${watchTookMs}ms, session ${running.sessionFile}) — ` +
|
|
177
197
|
`subagent never actually started, likely pollForExit false positive`,
|
|
178
198
|
"error",
|
|
@@ -188,8 +208,8 @@ export class SubagentWorkflowAgent {
|
|
|
188
208
|
|
|
189
209
|
if (options.schema) {
|
|
190
210
|
if (result.structuredOutput === undefined) {
|
|
191
|
-
this.
|
|
192
|
-
`
|
|
211
|
+
this.notify(
|
|
212
|
+
`"${options.label ?? "workflow-agent"}" ${watchTookMs}ms exitCode=${result.exitCode} ` +
|
|
193
213
|
`— finished without calling structured_output`,
|
|
194
214
|
"warning",
|
|
195
215
|
);
|