pi-ptc-subagents 6.2.0 → 7.0.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/dist/worker.js +115 -76
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -1,66 +1,76 @@
|
|
|
1
1
|
import { stripTypeScriptTypes } from "node:module";
|
|
2
|
-
import { inspect } from "node:util";
|
|
3
2
|
import { parentPort, workerData } from "node:worker_threads";
|
|
3
|
+
import vm from "node:vm";
|
|
4
4
|
// ../ptc/src/compile.ts
|
|
5
5
|
function compileProgram(source) {
|
|
6
|
-
|
|
7
|
-
return new Function(`"use strict";\n${stripped}\nreturn __ptcProgram;`)();
|
|
8
|
-
}
|
|
9
|
-
// ../ptc/src/workflow-helpers.ts
|
|
10
|
-
function createWorkflowHelpers(emit) {
|
|
11
|
-
return {
|
|
12
|
-
log: (...args) => emit(args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")),
|
|
13
|
-
phase: (name) => emit(`— phase: ${name} —`),
|
|
14
|
-
parallel: (items) => Promise.allSettled(items.map((run) => run())),
|
|
15
|
-
pipeline: (items, step) => {
|
|
16
|
-
const results = [];
|
|
17
|
-
return items.reduce((chain, item, index) => chain.then(async () => {
|
|
18
|
-
results.push(await step(item, index));
|
|
19
|
-
}), Promise.resolve()).then(() => results);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
6
|
+
return `"use strict";\n${stripTypeScriptTypes(`async function __ptcProgram() {\n${source}\n}`, { mode: "strip" })}\n;globalThis.__ptcProgram = __ptcProgram;`;
|
|
22
7
|
}
|
|
23
8
|
// ../ptc/src/worker-main.ts
|
|
9
|
+
const CELL_PREAMBLE = `"use strict";
|
|
10
|
+
(function () {
|
|
11
|
+
var __bridge = globalThis.__ptcCall;
|
|
12
|
+
var __emit = globalThis.__ptcConsole;
|
|
13
|
+
var __args = JSON.parse(globalThis.__ptcArgsJson);
|
|
14
|
+
// contextified 全局属性不可 delete(vm 限制)但可写——置 undefined 即脱手,桥只剩序言闭包可达
|
|
15
|
+
globalThis.__ptcCall = undefined;
|
|
16
|
+
globalThis.__ptcConsole = undefined;
|
|
17
|
+
globalThis.__ptcArgsJson = undefined;
|
|
18
|
+
function __ptcFmt(v) {
|
|
19
|
+
if (typeof v === "string") return v;
|
|
20
|
+
try { var s = JSON.stringify(v); return s === undefined ? String(v) : s; } catch (e) { return String(v); }
|
|
21
|
+
}
|
|
22
|
+
function __ptcJoin(values) {
|
|
23
|
+
var out = [];
|
|
24
|
+
for (var i = 0; i < values.length; i++) out.push(__ptcFmt(values[i]));
|
|
25
|
+
return out.join(" ");
|
|
26
|
+
}
|
|
27
|
+
var __ptcTools = {};
|
|
28
|
+
__PTC_NAMES__.forEach(function (name) {
|
|
29
|
+
__ptcTools[name] = function (args) {
|
|
30
|
+
return new Promise(function (resolve, reject) {
|
|
31
|
+
__bridge(name, JSON.stringify(args === undefined ? null : args)).then(function (json) {
|
|
32
|
+
var value;
|
|
33
|
+
try { value = JSON.parse(json); } catch (e) { reject(e); return; }
|
|
34
|
+
resolve(value);
|
|
35
|
+
}, reject);
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
globalThis.tools = Object.freeze(__ptcTools);
|
|
40
|
+
globalThis.console = Object.freeze({
|
|
41
|
+
log: function () { __emit("log", __ptcJoin(arguments)); },
|
|
42
|
+
info: function () { __emit("info", __ptcJoin(arguments)); },
|
|
43
|
+
warn: function () { __emit("warn", __ptcJoin(arguments)); },
|
|
44
|
+
error: function () { __emit("error", __ptcJoin(arguments)); },
|
|
45
|
+
debug: function () { __emit("debug", __ptcJoin(arguments)); }
|
|
46
|
+
});
|
|
47
|
+
globalThis.args = Object.freeze(__args);
|
|
48
|
+
if (__PTC_WORKFLOW__) {
|
|
49
|
+
globalThis.workflow = Object.freeze({
|
|
50
|
+
log: function () { __emit("log", __ptcJoin(arguments)); },
|
|
51
|
+
phase: function (name) { __emit("log", "— phase: " + name + " —"); },
|
|
52
|
+
parallel: function (items) { return Promise.allSettled(items.map(function (run) { return run(); })); },
|
|
53
|
+
pipeline: function (items, step) {
|
|
54
|
+
var results = [];
|
|
55
|
+
return items.reduce(function (chain, item, index) {
|
|
56
|
+
return chain.then(function () { return Promise.resolve(step(item, index)).then(function (r) { results.push(r); }); });
|
|
57
|
+
}, Promise.resolve()).then(function () { return results; });
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
`;
|
|
24
63
|
function workerMain(deps) {
|
|
25
|
-
let
|
|
64
|
+
let bindingNames = [];
|
|
65
|
+
let surface = "run_code";
|
|
26
66
|
let pending = /* @__PURE__ */ new Map();
|
|
27
67
|
let nextCallId = 1;
|
|
28
68
|
let currentRunId = null;
|
|
29
69
|
let logs = [];
|
|
30
|
-
const globalBaseline = /* @__PURE__ */ new Set();
|
|
31
|
-
const consoleBaseline = { ...console };
|
|
32
70
|
deps.onFrame((frame) => {
|
|
33
71
|
if (frame.kind === "init") {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (currentRunId === null) return Promise.reject(/* @__PURE__ */ new Error("run 已结束:reset 后不再接受工具调用"));
|
|
37
|
-
const call = new Promise((resolve, reject) => {
|
|
38
|
-
const callId = nextCallId++;
|
|
39
|
-
pending.set(callId, {
|
|
40
|
-
resolve,
|
|
41
|
-
reject
|
|
42
|
-
});
|
|
43
|
-
deps.post({
|
|
44
|
-
kind: "call",
|
|
45
|
-
runId: currentRunId ?? "",
|
|
46
|
-
callId,
|
|
47
|
-
name,
|
|
48
|
-
args
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
call.catch(() => {});
|
|
52
|
-
return call;
|
|
53
|
-
}])));
|
|
54
|
-
defineGlobal("tools", tools);
|
|
55
|
-
if (frame.surface === "workflow") defineGlobal("workflow", createWorkflowHelpers((text) => {
|
|
56
|
-
logs.push(text);
|
|
57
|
-
deps.post({
|
|
58
|
-
kind: "log",
|
|
59
|
-
runId: currentRunId ?? "",
|
|
60
|
-
level: "log",
|
|
61
|
-
text
|
|
62
|
-
});
|
|
63
|
-
}));
|
|
72
|
+
bindingNames = frame.bindingNames;
|
|
73
|
+
surface = frame.surface;
|
|
64
74
|
deps.post({ kind: "ready" });
|
|
65
75
|
return;
|
|
66
76
|
}
|
|
@@ -68,8 +78,6 @@ function workerMain(deps) {
|
|
|
68
78
|
currentRunId = null;
|
|
69
79
|
for (const { reject } of pending.values()) reject(/* @__PURE__ */ new Error("run reset:worker 被复用"));
|
|
70
80
|
pending = /* @__PURE__ */ new Map();
|
|
71
|
-
for (const name of Object.getOwnPropertyNames(globalThis)) if (!globalBaseline.has(name)) delete globalThis[name];
|
|
72
|
-
Object.assign(console, consoleBaseline);
|
|
73
81
|
deps.post({ kind: "ready" });
|
|
74
82
|
return;
|
|
75
83
|
}
|
|
@@ -77,25 +85,28 @@ function workerMain(deps) {
|
|
|
77
85
|
const entry = pending.get(frame.callId);
|
|
78
86
|
if (!entry) return;
|
|
79
87
|
pending.delete(frame.callId);
|
|
80
|
-
if (frame.ok)
|
|
81
|
-
|
|
88
|
+
if (frame.ok) {
|
|
89
|
+
let json;
|
|
90
|
+
try {
|
|
91
|
+
json = JSON.stringify(frame.value ?? null);
|
|
92
|
+
} catch {
|
|
93
|
+
json = void 0;
|
|
94
|
+
}
|
|
95
|
+
if (json === void 0) entry.reject(/* @__PURE__ */ new Error("binding 返回值不可 JSON 序列化(如循环引用)"));
|
|
96
|
+
else entry.resolve(json);
|
|
97
|
+
} else entry.reject(new Error(frame.error));
|
|
82
98
|
return;
|
|
83
99
|
}
|
|
84
100
|
if (frame.kind === "cancel") return;
|
|
85
101
|
run(frame.code, frame.id, frame.args);
|
|
86
102
|
});
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
value,
|
|
90
|
-
writable: false,
|
|
91
|
-
configurable: true
|
|
92
|
-
});
|
|
103
|
+
function preamble() {
|
|
104
|
+
return CELL_PREAMBLE.replace(/__PTC_NAMES__/g, () => JSON.stringify(bindingNames)).replace(/__PTC_WORKFLOW__/g, () => surface === "workflow" ? "true" : "false");
|
|
93
105
|
}
|
|
94
106
|
async function run(code, runId, args) {
|
|
95
107
|
currentRunId = runId;
|
|
96
108
|
logs = [];
|
|
97
|
-
|
|
98
|
-
installConsole((level, text) => {
|
|
109
|
+
const postLog = (level, text) => {
|
|
99
110
|
logs.push(text);
|
|
100
111
|
deps.post({
|
|
101
112
|
kind: "log",
|
|
@@ -103,17 +114,54 @@ function workerMain(deps) {
|
|
|
103
114
|
level,
|
|
104
115
|
text
|
|
105
116
|
});
|
|
106
|
-
}
|
|
107
|
-
const outcome = await execute(code
|
|
117
|
+
};
|
|
118
|
+
const outcome = await execute(code, vm.createContext({
|
|
119
|
+
__ptcArgsJson: JSON.stringify(args ?? {}),
|
|
120
|
+
__ptcCall(name, argsJson) {
|
|
121
|
+
if (currentRunId === null) return Promise.reject(/* @__PURE__ */ new Error("run 已结束:reset 后不再接受工具调用"));
|
|
122
|
+
let parsed = null;
|
|
123
|
+
try {
|
|
124
|
+
parsed = JSON.parse(argsJson);
|
|
125
|
+
} catch {
|
|
126
|
+
return Promise.reject(/* @__PURE__ */ new Error("工具参数不是合法 JSON"));
|
|
127
|
+
}
|
|
128
|
+
const call = new Promise((resolve, reject) => {
|
|
129
|
+
const callId = nextCallId++;
|
|
130
|
+
pending.set(callId, {
|
|
131
|
+
resolve,
|
|
132
|
+
reject
|
|
133
|
+
});
|
|
134
|
+
deps.post({
|
|
135
|
+
kind: "call",
|
|
136
|
+
runId: currentRunId ?? "",
|
|
137
|
+
callId,
|
|
138
|
+
name,
|
|
139
|
+
args: parsed
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
call.catch(() => {});
|
|
143
|
+
return call;
|
|
144
|
+
},
|
|
145
|
+
__ptcConsole(level, text) {
|
|
146
|
+
postLog(level, String(text));
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
108
149
|
deps.post({
|
|
109
150
|
kind: "settled",
|
|
110
151
|
runId,
|
|
111
152
|
outcome
|
|
112
153
|
});
|
|
113
154
|
}
|
|
114
|
-
|
|
155
|
+
function errorMessage(error) {
|
|
156
|
+
if (error instanceof Error) return error.message;
|
|
157
|
+
if (error && typeof error === "object" && typeof error.message === "string") return error.message;
|
|
158
|
+
return String(error);
|
|
159
|
+
}
|
|
160
|
+
async function execute(code, context) {
|
|
115
161
|
try {
|
|
116
|
-
|
|
162
|
+
vm.runInContext(preamble(), context, { filename: "ptc_preamble.js" });
|
|
163
|
+
vm.runInContext(compileProgram(code), context, { filename: "run_code.js" });
|
|
164
|
+
const value = await context.__ptcProgram.call(context);
|
|
117
165
|
if (value === void 0) return {
|
|
118
166
|
status: "fulfilled",
|
|
119
167
|
value: { $void: true },
|
|
@@ -133,21 +181,12 @@ function workerMain(deps) {
|
|
|
133
181
|
} catch (error) {
|
|
134
182
|
return {
|
|
135
183
|
status: "rejected",
|
|
136
|
-
error:
|
|
184
|
+
error: errorMessage(error),
|
|
137
185
|
logs
|
|
138
186
|
};
|
|
139
187
|
}
|
|
140
188
|
}
|
|
141
189
|
}
|
|
142
|
-
function installConsole(emit) {
|
|
143
|
-
for (const level of [
|
|
144
|
-
"log",
|
|
145
|
-
"info",
|
|
146
|
-
"warn",
|
|
147
|
-
"error",
|
|
148
|
-
"debug"
|
|
149
|
-
]) console[level] = (...args) => emit(level, args.map((a) => typeof a === "string" ? a : inspect(a)).join(" "));
|
|
150
|
-
}
|
|
151
190
|
// ../ptc/src/worker-entry.ts
|
|
152
191
|
if (!parentPort) throw new Error("worker-entry 只能在 worker 线程里加载");
|
|
153
192
|
Object.freeze(workerData);
|