@abdwhb-png/pi-test-harness 0.7.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/CHANGELOG.md +161 -0
- package/LICENSE +21 -0
- package/README.md +673 -0
- package/dist/diagnostics.d.ts +11 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +61 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/events.d.ts +6 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +33 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/mock-pi-script.mjs +176 -0
- package/dist/mock-pi.d.ts +32 -0
- package/dist/mock-pi.d.ts.map +1 -0
- package/dist/mock-pi.js +150 -0
- package/dist/mock-pi.js.map +1 -0
- package/dist/mock-tools.d.ts +51 -0
- package/dist/mock-tools.d.ts.map +1 -0
- package/dist/mock-tools.js +192 -0
- package/dist/mock-tools.js.map +1 -0
- package/dist/mock-ui.d.ts +13 -0
- package/dist/mock-ui.d.ts.map +1 -0
- package/dist/mock-ui.js +159 -0
- package/dist/mock-ui.js.map +1 -0
- package/dist/pi-loader-parity.d.ts +36 -0
- package/dist/pi-loader-parity.d.ts.map +1 -0
- package/dist/pi-loader-parity.js +60 -0
- package/dist/pi-loader-parity.js.map +1 -0
- package/dist/playbook.d.ts +44 -0
- package/dist/playbook.d.ts.map +1 -0
- package/dist/playbook.js +143 -0
- package/dist/playbook.js.map +1 -0
- package/dist/sandbox.d.ts +27 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +269 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/session.d.ts +13 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +187 -0
- package/dist/session.js.map +1 -0
- package/dist/types.d.ts +171 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +46 -0
- package/dist/utils.js.map +1 -0
- package/package.json +84 -0
- package/skills/pi-test-harness/SKILL.md +451 -0
- package/skills/pi-test-harness/evals/evals.json +26 -0
- package/skills/pi-test-harness/references/api-reference.md +480 -0
- package/skills/pi-test-harness/references/mock-pi-cli.md +135 -0
- package/skills/pi-test-harness/references/mock-tools.md +176 -0
- package/skills/pi-test-harness/references/mock-ui.md +170 -0
- package/skills/pi-test-harness/references/playbook-dsl.md +209 -0
- package/skills/pi-test-harness/references/sandbox-install.md +113 -0
- package/src/diagnostics.ts +90 -0
- package/src/events.ts +43 -0
- package/src/index.ts +42 -0
- package/src/mock-pi-script.mjs +176 -0
- package/src/mock-pi.ts +169 -0
- package/src/mock-tools.ts +252 -0
- package/src/mock-ui.ts +196 -0
- package/src/pi-loader-parity.ts +61 -0
- package/src/playbook.ts +189 -0
- package/src/sandbox.ts +334 -0
- package/src/session.ts +249 -0
- package/src/types.ts +203 -0
- package/src/utils.ts +46 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool execution interceptor — wraps tool.execute() for tools in mockTools.
|
|
3
|
+
*
|
|
4
|
+
* For mocked tools, the mock replaces tool.execute() and returns controlled
|
|
5
|
+
* values. Extension hooks (tool_call / tool_result) are handled by
|
|
6
|
+
* AgentSession 0.83's internal beforeToolCall/afterToolCall — the mock
|
|
7
|
+
* must NOT re-emit them.
|
|
8
|
+
*
|
|
9
|
+
* For non-mocked tools, the real execute() is called and results are
|
|
10
|
+
* collected for event queries.
|
|
11
|
+
*/
|
|
12
|
+
import { formatToolError } from "./diagnostics.js";
|
|
13
|
+
/**
|
|
14
|
+
* Thrown when an extension hook blocks a tool call.
|
|
15
|
+
* Exported for test assertions — no longer thrown by the mock itself since
|
|
16
|
+
* AgentSession 0.83's beforeToolCall handles blocking before execute().
|
|
17
|
+
*/
|
|
18
|
+
export class ToolBlockedError extends Error {
|
|
19
|
+
toolBlocked = true;
|
|
20
|
+
constructor(reason) {
|
|
21
|
+
super(reason);
|
|
22
|
+
this.name = "ToolBlockedError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns true if `err` represents a hook-based tool block.
|
|
27
|
+
*
|
|
28
|
+
* Kept for consumers that catch errors from tool execution flows, though
|
|
29
|
+
* AgentSession 0.83's beforeToolCall blocks before execute() is reached.
|
|
30
|
+
*/
|
|
31
|
+
export function isBlockedError(err) {
|
|
32
|
+
if (err instanceof ToolBlockedError)
|
|
33
|
+
return true;
|
|
34
|
+
if (err instanceof Error) {
|
|
35
|
+
const msg = err.message;
|
|
36
|
+
return (msg.includes("blocked") ||
|
|
37
|
+
msg.includes("Plan mode") ||
|
|
38
|
+
msg.includes("WRITE operation"));
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function normalizeMockResult(handler, params) {
|
|
43
|
+
let raw;
|
|
44
|
+
if (typeof handler === "string") {
|
|
45
|
+
raw = handler;
|
|
46
|
+
}
|
|
47
|
+
else if (typeof handler === "function") {
|
|
48
|
+
raw = handler(params);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
raw = handler;
|
|
52
|
+
}
|
|
53
|
+
if (typeof raw === "string") {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: "text", text: raw }],
|
|
56
|
+
details: {},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return raw;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Intercept tool execution for mocked tools.
|
|
63
|
+
*
|
|
64
|
+
* Unlike the old approach, this does NOT emit tool_call/tool_result hooks
|
|
65
|
+
* manually — AgentSession 0.83's beforeToolCall/afterToolCall handles that.
|
|
66
|
+
* The mock only replaces execute() to return controlled values. Result
|
|
67
|
+
* recording is handled by the session subscriber from tool_execution_end
|
|
68
|
+
* events (which carry the final afterToolCall-modified result).
|
|
69
|
+
*
|
|
70
|
+
* Returns a Set of mocked tool names for the session subscriber to set the
|
|
71
|
+
* mocked flag on recorded results, plus a Set of toolCallIds whose mock
|
|
72
|
+
* returned a ToolResult with isError:true. Pi 0.84's agent loop hardcodes
|
|
73
|
+
* successful execute() as non-error (isError:false), so the subscriber must
|
|
74
|
+
* consult this set to preserve the mock's error intent in collected records.
|
|
75
|
+
*/
|
|
76
|
+
export function interceptToolExecution(tools, mockTools, playbookState, propagateErrors) {
|
|
77
|
+
const mockedNames = new Set(Object.keys(mockTools));
|
|
78
|
+
const mockedErrorToolCallIds = new Set();
|
|
79
|
+
const wrapped = tools.map((tool) => {
|
|
80
|
+
const mockHandler = mockTools[tool.name];
|
|
81
|
+
if (!mockHandler) {
|
|
82
|
+
return wrapForCollection(tool, playbookState, propagateErrors);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
...tool,
|
|
86
|
+
execute: async (toolCallId, params, _signal, _onUpdate) => {
|
|
87
|
+
const result = normalizeMockResult(mockHandler, params);
|
|
88
|
+
const text = result.content
|
|
89
|
+
.filter((c) => c.type === "text")
|
|
90
|
+
.map((c) => c.text)
|
|
91
|
+
.join("\n");
|
|
92
|
+
if (result.isError) {
|
|
93
|
+
// Pi 0.84 hardcodes successful execute() as non-error; remember the
|
|
94
|
+
// toolCallId so the session subscriber can flag the record.
|
|
95
|
+
mockedErrorToolCallIds.add(toolCallId);
|
|
96
|
+
}
|
|
97
|
+
// fireThenCallback fires synchronously so .then() sees real data
|
|
98
|
+
fireThenCallback(playbookState, toolCallId, {
|
|
99
|
+
step: playbookState.consumed,
|
|
100
|
+
toolName: tool.name,
|
|
101
|
+
toolCallId,
|
|
102
|
+
text,
|
|
103
|
+
content: result.content,
|
|
104
|
+
isError: result.isError ?? false,
|
|
105
|
+
details: result.details,
|
|
106
|
+
mocked: true,
|
|
107
|
+
});
|
|
108
|
+
return {
|
|
109
|
+
content: result.content,
|
|
110
|
+
details: result.details ?? {},
|
|
111
|
+
};
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
return { tools: wrapped, mockedNames, mockedErrorToolCallIds };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Wrap a real tool for event collection (non-mocked tools).
|
|
119
|
+
* Does not push to toolResults — the session subscriber handles recording
|
|
120
|
+
* from tool_execution_end events.
|
|
121
|
+
*/
|
|
122
|
+
function wrapForCollection(tool, playbookState, propagateErrors) {
|
|
123
|
+
const originalExecute = tool.execute;
|
|
124
|
+
return {
|
|
125
|
+
...tool,
|
|
126
|
+
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
127
|
+
const step = playbookState.consumed;
|
|
128
|
+
try {
|
|
129
|
+
const result = await originalExecute.call(tool, toolCallId, params, signal, onUpdate);
|
|
130
|
+
const text = (result.content ?? [])
|
|
131
|
+
.filter((c) => c.type === "text")
|
|
132
|
+
.map((c) => c.text)
|
|
133
|
+
.join("\n");
|
|
134
|
+
fireThenCallback(playbookState, toolCallId, {
|
|
135
|
+
step,
|
|
136
|
+
toolName: tool.name,
|
|
137
|
+
toolCallId,
|
|
138
|
+
text,
|
|
139
|
+
content: result.content ?? [],
|
|
140
|
+
isError: !!result.isError,
|
|
141
|
+
details: result.details,
|
|
142
|
+
mocked: false,
|
|
143
|
+
});
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
148
|
+
try {
|
|
149
|
+
fireThenCallback(playbookState, toolCallId, {
|
|
150
|
+
step,
|
|
151
|
+
toolName: tool.name,
|
|
152
|
+
toolCallId,
|
|
153
|
+
text: errMsg,
|
|
154
|
+
content: [{ type: "text", text: errMsg }],
|
|
155
|
+
isError: true,
|
|
156
|
+
details: undefined,
|
|
157
|
+
mocked: false,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
/* best-effort callback */
|
|
162
|
+
}
|
|
163
|
+
if (propagateErrors) {
|
|
164
|
+
const diagnostic = formatToolError(step, tool.name, err);
|
|
165
|
+
throw new Error(diagnostic, { cause: err });
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: "text", text: errMsg }],
|
|
169
|
+
details: {},
|
|
170
|
+
isError: true,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function fireThenCallback(state, toolCallId, record) {
|
|
177
|
+
const callback = state.pendingCallbacks.get(toolCallId) ??
|
|
178
|
+
state.pendingCallbacks.get(record.toolName);
|
|
179
|
+
const key = state.pendingCallbacks.has(toolCallId)
|
|
180
|
+
? toolCallId
|
|
181
|
+
: record.toolName;
|
|
182
|
+
if (callback) {
|
|
183
|
+
state.pendingCallbacks.delete(key);
|
|
184
|
+
try {
|
|
185
|
+
callback(record);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
console.warn(`[pi-test-harness] .then() callback error for ${record.toolName}: ${err}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=mock-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-tools.js","sourceRoot":"","sources":["../src/mock-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock UI context — intercepts ctx.ui.* calls from extensions.
|
|
3
|
+
* All calls are collected for assertions. Interactive methods return
|
|
4
|
+
* configured mock responses.
|
|
5
|
+
*/
|
|
6
|
+
import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import type { MockUIConfig, UICallRecord } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Create a mock ExtensionUIContext that records all calls and returns
|
|
10
|
+
* configured responses.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createMockUIContext(config: MockUIConfig | undefined, uiLog: UICallRecord[]): ExtensionUIContext;
|
|
13
|
+
//# sourceMappingURL=mock-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-ui.d.ts","sourceRoot":"","sources":["../src/mock-ui.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE7D;;;GAGG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,YAAY,YAAK,EACzB,KAAK,EAAE,YAAY,EAAE,GACnB,kBAAkB,CAmLpB"}
|
package/dist/mock-ui.js
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock UI context — intercepts ctx.ui.* calls from extensions.
|
|
3
|
+
* All calls are collected for assertions. Interactive methods return
|
|
4
|
+
* configured mock responses.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Create a mock ExtensionUIContext that records all calls and returns
|
|
8
|
+
* configured responses.
|
|
9
|
+
*/
|
|
10
|
+
export function createMockUIContext(config = {}, uiLog) {
|
|
11
|
+
function record(method, args, returnValue) {
|
|
12
|
+
uiLog.push({ method, args, returnValue });
|
|
13
|
+
}
|
|
14
|
+
const mockUI = {
|
|
15
|
+
async select(title, options, _opts) {
|
|
16
|
+
let result;
|
|
17
|
+
const handler = config.select;
|
|
18
|
+
if (handler === undefined || handler === null) {
|
|
19
|
+
result = options[0]; // default: first item
|
|
20
|
+
}
|
|
21
|
+
else if (typeof handler === "number") {
|
|
22
|
+
result = options[handler];
|
|
23
|
+
}
|
|
24
|
+
else if (typeof handler === "string") {
|
|
25
|
+
result = options.find((o) => o === handler) ?? options[0];
|
|
26
|
+
}
|
|
27
|
+
else if (typeof handler === "function") {
|
|
28
|
+
result = handler(title, options);
|
|
29
|
+
}
|
|
30
|
+
record("select", [title, options], result);
|
|
31
|
+
return result;
|
|
32
|
+
},
|
|
33
|
+
async confirm(title, message, _opts) {
|
|
34
|
+
let result;
|
|
35
|
+
const handler = config.confirm;
|
|
36
|
+
if (handler === undefined || handler === null) {
|
|
37
|
+
result = true; // default: approve
|
|
38
|
+
}
|
|
39
|
+
else if (typeof handler === "boolean") {
|
|
40
|
+
result = handler;
|
|
41
|
+
}
|
|
42
|
+
else if (typeof handler === "function") {
|
|
43
|
+
result = handler(title, message);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
result = true;
|
|
47
|
+
}
|
|
48
|
+
record("confirm", [title, message], result);
|
|
49
|
+
return result;
|
|
50
|
+
},
|
|
51
|
+
async input(title, placeholder, _opts) {
|
|
52
|
+
let result;
|
|
53
|
+
const handler = config.input;
|
|
54
|
+
if (handler === undefined || handler === null) {
|
|
55
|
+
result = "";
|
|
56
|
+
}
|
|
57
|
+
else if (typeof handler === "string") {
|
|
58
|
+
result = handler;
|
|
59
|
+
}
|
|
60
|
+
else if (typeof handler === "function") {
|
|
61
|
+
result = handler(title, placeholder);
|
|
62
|
+
}
|
|
63
|
+
record("input", [title, placeholder], result);
|
|
64
|
+
return result;
|
|
65
|
+
},
|
|
66
|
+
async editor(title, prefill) {
|
|
67
|
+
let result;
|
|
68
|
+
const handler = config.editor;
|
|
69
|
+
if (handler === undefined || handler === null) {
|
|
70
|
+
result = "";
|
|
71
|
+
}
|
|
72
|
+
else if (typeof handler === "string") {
|
|
73
|
+
result = handler;
|
|
74
|
+
}
|
|
75
|
+
else if (typeof handler === "function") {
|
|
76
|
+
result = handler(title, prefill);
|
|
77
|
+
}
|
|
78
|
+
record("editor", [title, prefill], result);
|
|
79
|
+
return result;
|
|
80
|
+
},
|
|
81
|
+
notify(message, type) {
|
|
82
|
+
record("notify", [message, type]);
|
|
83
|
+
},
|
|
84
|
+
onTerminalInput() {
|
|
85
|
+
return () => { };
|
|
86
|
+
},
|
|
87
|
+
setStatus(key, text) {
|
|
88
|
+
record("setStatus", [key, text]);
|
|
89
|
+
},
|
|
90
|
+
setWorkingMessage(message) {
|
|
91
|
+
record("setWorkingMessage", [message]);
|
|
92
|
+
},
|
|
93
|
+
setWorkingVisible(visible) {
|
|
94
|
+
record("setWorkingVisible", [visible]);
|
|
95
|
+
},
|
|
96
|
+
setWorkingIndicator(options) {
|
|
97
|
+
record("setWorkingIndicator", [options]);
|
|
98
|
+
},
|
|
99
|
+
setHiddenThinkingLabel(label) {
|
|
100
|
+
record("setHiddenThinkingLabel", [label]);
|
|
101
|
+
},
|
|
102
|
+
setWidget(key, content, _options) {
|
|
103
|
+
record("setWidget", [key, content]);
|
|
104
|
+
},
|
|
105
|
+
setFooter(...args) {
|
|
106
|
+
record("setFooter", args);
|
|
107
|
+
},
|
|
108
|
+
setHeader(...args) {
|
|
109
|
+
record("setHeader", args);
|
|
110
|
+
},
|
|
111
|
+
setTitle(title) {
|
|
112
|
+
record("setTitle", [title]);
|
|
113
|
+
},
|
|
114
|
+
async custom() {
|
|
115
|
+
return undefined;
|
|
116
|
+
},
|
|
117
|
+
pasteToEditor(text) {
|
|
118
|
+
record("pasteToEditor", [text]);
|
|
119
|
+
},
|
|
120
|
+
setEditorText(text) {
|
|
121
|
+
record("setEditorText", [text]);
|
|
122
|
+
},
|
|
123
|
+
getEditorText() {
|
|
124
|
+
return "";
|
|
125
|
+
},
|
|
126
|
+
setEditorComponent(factory) {
|
|
127
|
+
record("setEditorComponent", [factory]);
|
|
128
|
+
},
|
|
129
|
+
addAutocompleteProvider(factory) {
|
|
130
|
+
record("addAutocompleteProvider", [factory]);
|
|
131
|
+
},
|
|
132
|
+
getEditorComponent() {
|
|
133
|
+
return undefined;
|
|
134
|
+
},
|
|
135
|
+
get theme() {
|
|
136
|
+
return {
|
|
137
|
+
fg: (_color, text) => text,
|
|
138
|
+
bold: (text) => text,
|
|
139
|
+
italic: (text) => text,
|
|
140
|
+
strikethrough: (text) => text,
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
getAllThemes() {
|
|
144
|
+
return [];
|
|
145
|
+
},
|
|
146
|
+
getTheme() {
|
|
147
|
+
return undefined;
|
|
148
|
+
},
|
|
149
|
+
setTheme() {
|
|
150
|
+
return { success: false, error: "Test mode" };
|
|
151
|
+
},
|
|
152
|
+
getToolsExpanded() {
|
|
153
|
+
return false;
|
|
154
|
+
},
|
|
155
|
+
setToolsExpanded() { },
|
|
156
|
+
};
|
|
157
|
+
return mockUI;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=mock-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-ui.js","sourceRoot":"","sources":["../src/mock-ui.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAClC,SAAuB,EAAE,EACzB,KAAqB;IAErB,SAAS,MAAM,CACd,MAAc,EACd,IAAe,EACf,WAAqB;QAErB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAuB;QAClC,KAAK,CAAC,MAAM,CACX,KAAa,EACb,OAAiB,EACjB,KAAW;YAEX,IAAI,MAA0B,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;YAC9B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/C,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,sBAAsB;YAC5C,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC1C,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC;QACf,CAAC;QAED,KAAK,CAAC,OAAO,CACZ,KAAa,EACb,OAAe,EACf,KAAW;YAEX,IAAI,MAAe,CAAC;YACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YAC/B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/C,MAAM,GAAG,IAAI,CAAC,CAAC,mBAAmB;YACnC,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,SAAS,EAAE,CAAC;gBACzC,MAAM,GAAG,OAAO,CAAC;YAClB,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC1C,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACP,MAAM,GAAG,IAAI,CAAC;YACf,CAAC;YACD,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YAC5C,OAAO,MAAM,CAAC;QACf,CAAC;QAED,KAAK,CAAC,KAAK,CACV,KAAa,EACb,WAAoB,EACpB,KAAW;YAEX,IAAI,MAA0B,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;YAC7B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/C,MAAM,GAAG,EAAE,CAAC;YACb,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,GAAG,OAAO,CAAC;YAClB,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC1C,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACtC,CAAC;YACD,MAAM,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9C,OAAO,MAAM,CAAC;QACf,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAgB;YAC3C,IAAI,MAA0B,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;YAC9B,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC/C,MAAM,GAAG,EAAE,CAAC;YACb,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,MAAM,GAAG,OAAO,CAAC;YAClB,CAAC;iBAAM,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAC1C,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;YAC3C,OAAO,MAAM,CAAC;QACf,CAAC;QAED,MAAM,CAAC,OAAe,EAAE,IAAmC;YAC1D,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnC,CAAC;QAED,eAAe;YACd,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;QACjB,CAAC;QAED,SAAS,CAAC,GAAW,EAAE,IAAwB;YAC9C,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;QAClC,CAAC;QAED,iBAAiB,CAAC,OAAgB;YACjC,MAAM,CAAC,mBAAmB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,iBAAiB,CAAC,OAAgB;YACjC,MAAM,CAAC,mBAAmB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,mBAAmB,CAAC,OAGnB;YACA,MAAM,CAAC,qBAAqB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1C,CAAC;QAED,sBAAsB,CAAC,KAAc;YACpC,MAAM,CAAC,wBAAwB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,SAAS,CAAC,GAAW,EAAE,OAAY,EAAE,QAAc;YAClD,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;QACrC,CAAC;QAED,SAAS,CAAC,GAAG,IAAe;YAC3B,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,SAAS,CAAC,GAAG,IAAe;YAC3B,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC3B,CAAC;QAED,QAAQ,CAAC,KAAa;YACrB,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7B,CAAC;QAED,KAAK,CAAC,MAAM;YACX,OAAO,SAAkB,CAAC;QAC3B,CAAC;QAED,aAAa,CAAC,IAAY;YACzB,MAAM,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,aAAa,CAAC,IAAY;YACzB,MAAM,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,aAAa;YACZ,OAAO,EAAE,CAAC;QACX,CAAC;QAED,kBAAkB,CAAC,OAAY;YAC9B,MAAM,CAAC,oBAAoB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACzC,CAAC;QAED,uBAAuB,CAAC,OAAY;YACnC,MAAM,CAAC,yBAAyB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,kBAAkB;YACjB,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,IAAI,KAAK;YACR,OAAO;gBACN,EAAE,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI;gBAC1C,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI;gBAC5B,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI;gBAC9B,aAAa,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI;aACrC,CAAC;QACH,CAAC;QAED,YAAY;YACX,OAAO,EAAE,CAAC;QACX,CAAC;QACD,QAAQ;YACP,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,QAAQ;YACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;QAC/C,CAAC;QACD,gBAAgB;YACf,OAAO,KAAK,CAAC;QACd,CAAC;QACD,gBAAgB,KAAU,CAAC;KAC3B,CAAC;IAEF,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension-loader parity with Pi's shipped runtimes.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Run `fn` with jiti's native import/require fast-path disabled.
|
|
6
|
+
*
|
|
7
|
+
* **Why this exists**: Pi loads every extension entrypoint through jiti
|
|
8
|
+
* (`loadExtensionModule` in `core/extensions/loader.ts`). Which jiti options it
|
|
9
|
+
* passes depends on how Pi itself is running:
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* isBunBinary || isNodeSeaBinary || isBundledNode
|
|
13
|
+
* ? { virtualModules, tryNative: false } // compiled binary / bundled Node
|
|
14
|
+
* : isTypeScriptSourceRuntime
|
|
15
|
+
* ? { virtualModules, tsconfigPaths: true }
|
|
16
|
+
* : { alias: getAliases() } // unbundled Node build
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* The last branch — the one an in-process harness always takes, because it
|
|
20
|
+
* imports the package's compiled entrypoint — leaves `tryNative` at jiti's
|
|
21
|
+
* default, and that default is "enabled if Bun is detected". Under a Bun test
|
|
22
|
+
* runner this combination hands Pi a factory for a module whose body has not
|
|
23
|
+
* finished evaluating: an entrypoint with a module-level `await import(...)`
|
|
24
|
+
* reports as loaded before its top-level `const` is initialized, so the hoisted
|
|
25
|
+
* default export Pi calls throws `Cannot access 'x' before initialization`.
|
|
26
|
+
*
|
|
27
|
+
* Pi's shipped runtimes never take that path, so the harness pins the choice
|
|
28
|
+
* they make (`tryNative: false`) for the duration of the load. This keeps
|
|
29
|
+
* `extensionFactories`-style and path-loaded extensions in exactly the loader
|
|
30
|
+
* configuration the real CLI uses, instead of one that varies by test runner.
|
|
31
|
+
*
|
|
32
|
+
* Nesting is reference-counted so two sessions loading concurrently in one
|
|
33
|
+
* process cannot have one restore the variable while the other is mid-load.
|
|
34
|
+
*/
|
|
35
|
+
export declare function withoutJitiNativeImport<T>(fn: () => Promise<T>): Promise<T>;
|
|
36
|
+
//# sourceMappingURL=pi-loader-parity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-loader-parity.d.ts","sourceRoot":"","sources":["../src/pi-loader-parity.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,EAC9C,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,CAAC,CAAC,CAaZ"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extension-loader parity with Pi's shipped runtimes.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Environment variable jiti reads when it decides whether to try the runtime's
|
|
6
|
+
* native require/import before applying its own transform.
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
const JITI_TRY_NATIVE = "JITI_TRY_NATIVE";
|
|
10
|
+
/** Nesting depth of `withoutJitiNativeImport` calls in this process. */
|
|
11
|
+
let suppressionDepth = 0;
|
|
12
|
+
/**
|
|
13
|
+
* Run `fn` with jiti's native import/require fast-path disabled.
|
|
14
|
+
*
|
|
15
|
+
* **Why this exists**: Pi loads every extension entrypoint through jiti
|
|
16
|
+
* (`loadExtensionModule` in `core/extensions/loader.ts`). Which jiti options it
|
|
17
|
+
* passes depends on how Pi itself is running:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* isBunBinary || isNodeSeaBinary || isBundledNode
|
|
21
|
+
* ? { virtualModules, tryNative: false } // compiled binary / bundled Node
|
|
22
|
+
* : isTypeScriptSourceRuntime
|
|
23
|
+
* ? { virtualModules, tsconfigPaths: true }
|
|
24
|
+
* : { alias: getAliases() } // unbundled Node build
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* The last branch — the one an in-process harness always takes, because it
|
|
28
|
+
* imports the package's compiled entrypoint — leaves `tryNative` at jiti's
|
|
29
|
+
* default, and that default is "enabled if Bun is detected". Under a Bun test
|
|
30
|
+
* runner this combination hands Pi a factory for a module whose body has not
|
|
31
|
+
* finished evaluating: an entrypoint with a module-level `await import(...)`
|
|
32
|
+
* reports as loaded before its top-level `const` is initialized, so the hoisted
|
|
33
|
+
* default export Pi calls throws `Cannot access 'x' before initialization`.
|
|
34
|
+
*
|
|
35
|
+
* Pi's shipped runtimes never take that path, so the harness pins the choice
|
|
36
|
+
* they make (`tryNative: false`) for the duration of the load. This keeps
|
|
37
|
+
* `extensionFactories`-style and path-loaded extensions in exactly the loader
|
|
38
|
+
* configuration the real CLI uses, instead of one that varies by test runner.
|
|
39
|
+
*
|
|
40
|
+
* Nesting is reference-counted so two sessions loading concurrently in one
|
|
41
|
+
* process cannot have one restore the variable while the other is mid-load.
|
|
42
|
+
*/
|
|
43
|
+
export async function withoutJitiNativeImport(fn) {
|
|
44
|
+
const previous = process.env[JITI_TRY_NATIVE];
|
|
45
|
+
suppressionDepth += 1;
|
|
46
|
+
process.env[JITI_TRY_NATIVE] = "0";
|
|
47
|
+
try {
|
|
48
|
+
return await fn();
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
suppressionDepth -= 1;
|
|
52
|
+
if (suppressionDepth === 0) {
|
|
53
|
+
if (previous === undefined)
|
|
54
|
+
delete process.env[JITI_TRY_NATIVE];
|
|
55
|
+
else
|
|
56
|
+
process.env[JITI_TRY_NATIVE] = previous;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=pi-loader-parity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-loader-parity.js","sourceRoot":"","sources":["../src/pi-loader-parity.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C,wEAAwE;AACxE,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAEzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC5C,EAAoB;IAEpB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC9C,gBAAgB,IAAI,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC;IACnC,IAAI,CAAC;QACJ,OAAO,MAAM,EAAE,EAAE,CAAC;IACnB,CAAC;YAAS,CAAC;QACV,gBAAgB,IAAI,CAAC,CAAC;QACtB,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;;gBAC3D,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC;QAC9C,CAAC;IACF,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlaybookStreamFn — replaces the model with scripted responses.
|
|
3
|
+
*
|
|
4
|
+
* The playbook is a queue of actions. Each streamFn call dequeues the next
|
|
5
|
+
* action and returns it as an AssistantMessageEventStream.
|
|
6
|
+
*/
|
|
7
|
+
import { type AssistantMessageEventStream, type Context, type Model, type SimpleStreamOptions } from "@earendil-works/pi-ai";
|
|
8
|
+
import type { PlaybookAction, Turn, ToolResultRecord } from "./types.js";
|
|
9
|
+
/** Chainable call action builder */
|
|
10
|
+
declare class CallAction {
|
|
11
|
+
readonly action: PlaybookAction;
|
|
12
|
+
constructor(toolName: string, params: Record<string, unknown> | (() => Record<string, unknown>));
|
|
13
|
+
then(callback: (result: ToolResultRecord) => void): CallAction;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The model calls a tool.
|
|
17
|
+
* @param toolName Tool to call
|
|
18
|
+
* @param params Static params or function for late binding
|
|
19
|
+
*/
|
|
20
|
+
export declare function calls(toolName: string, params?: Record<string, unknown> | (() => Record<string, unknown>)): CallAction;
|
|
21
|
+
/**
|
|
22
|
+
* The model emits text. Agent loop ends for this turn.
|
|
23
|
+
*/
|
|
24
|
+
export declare function says(text: string): PlaybookAction;
|
|
25
|
+
/**
|
|
26
|
+
* Define one user→model turn.
|
|
27
|
+
* @param prompt The actual user prompt text
|
|
28
|
+
* @param actions What the model does in response (call/say sequence)
|
|
29
|
+
*/
|
|
30
|
+
export declare function when(prompt: string, actions: Array<CallAction | PlaybookAction>): Turn;
|
|
31
|
+
export interface PlaybookState {
|
|
32
|
+
consumed: number;
|
|
33
|
+
remaining: number;
|
|
34
|
+
/** The action objects for each consumed step (for diagnostics) */
|
|
35
|
+
consumedActions: PlaybookAction[];
|
|
36
|
+
/** Callbacks pending for completed tool calls */
|
|
37
|
+
pendingCallbacks: Map<string, (result: ToolResultRecord) => void>;
|
|
38
|
+
}
|
|
39
|
+
export declare function createPlaybookStreamFn(turns: Turn[]): {
|
|
40
|
+
streamFn: (model: Model<any>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
|
|
41
|
+
state: PlaybookState;
|
|
42
|
+
};
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=playbook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playbook.d.ts","sourceRoot":"","sources":["../src/playbook.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGN,KAAK,2BAA2B,EAChC,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,mBAAmB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKzE,oCAAoC;AACpC,cAAM,UAAU;IACf,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBAEpB,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAI/F,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,GAAG,UAAU;CAI9D;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GACpE,UAAU,CAEZ;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAEjD;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,UAAU,GAAG,cAAc,CAAC,GAAG,IAAI,CAKtF;AA4CD,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,iDAAiD;IACjD,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC,CAAC;CAClE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG;IACtD,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,KAAK,2BAA2B,CAAC;IAC9G,KAAK,EAAE,aAAa,CAAC;CACrB,CAqEA"}
|