@howaboua/pi-ask 0.0.7 → 0.0.8
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 +4 -0
- package/ask/coordinator.ts +25 -14
- package/ask/tool.ts +14 -14
- package/index.ts +29 -9
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @howaboua/pi-ask
|
|
2
2
|
|
|
3
|
+
## 0.0.8
|
|
4
|
+
|
|
5
|
+
- Shepherdr now discovers and answers waiting questions invoked inside Code and Notebook Mode.
|
|
6
|
+
|
|
3
7
|
## 0.0.7
|
|
4
8
|
|
|
5
9
|
- The `ask` tool now supports steering questions that return immediately, preserve the full response panel, and deliver answers at the next safe boundary using the developer role under active Pi Codex Responses.
|
package/ask/coordinator.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface AskCoordinatorOptions {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
interface PresentAskOptions {
|
|
20
|
+
onActiveChange?: (active: boolean) => void;
|
|
20
21
|
handoff?: boolean;
|
|
21
22
|
steering?: boolean;
|
|
22
23
|
signal?: AbortSignal;
|
|
@@ -42,23 +43,33 @@ export function createAskCoordinator({
|
|
|
42
43
|
const present = (
|
|
43
44
|
ctx: ExtensionContext,
|
|
44
45
|
prompts: AskPrompt[],
|
|
45
|
-
{
|
|
46
|
+
{
|
|
47
|
+
handoff = false,
|
|
48
|
+
steering = false,
|
|
49
|
+
signal,
|
|
50
|
+
onActiveChange,
|
|
51
|
+
}: PresentAskOptions = {},
|
|
46
52
|
): Promise<unknown> => {
|
|
47
53
|
const run = async () => {
|
|
48
54
|
if (signal?.aborted) return null;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
? await
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
try {
|
|
56
|
+
onActiveChange?.(true);
|
|
57
|
+
return askInComposer
|
|
58
|
+
? await askInComposer(prompts, signal)
|
|
59
|
+
: ctx.mode === "tui"
|
|
60
|
+
? await askInTui(ctx, prompts, {
|
|
61
|
+
handoff,
|
|
62
|
+
steering,
|
|
63
|
+
...(signal ? { signal } : {}),
|
|
64
|
+
})
|
|
65
|
+
: await askWithPiUi(ctx, prompts, {
|
|
66
|
+
handoff,
|
|
67
|
+
steering,
|
|
68
|
+
...(signal ? { signal } : {}),
|
|
69
|
+
});
|
|
70
|
+
} finally {
|
|
71
|
+
onActiveChange?.(false);
|
|
72
|
+
}
|
|
62
73
|
};
|
|
63
74
|
const result = presentationTail.then(run, run);
|
|
64
75
|
presentationTail = result.then(
|
package/ask/tool.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineTool } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Text } from "@earendil-works/pi-tui";
|
|
3
|
-
import { AskParameters } from "./contracts.js";
|
|
3
|
+
import { AskParameters, type AskPrompt } from "./contracts.js";
|
|
4
4
|
import {
|
|
5
5
|
type AskCoordinatorOptions,
|
|
6
6
|
createAskCoordinator,
|
|
@@ -18,6 +18,8 @@ interface BlockedState {
|
|
|
18
18
|
active: boolean;
|
|
19
19
|
label: string;
|
|
20
20
|
prompt: string;
|
|
21
|
+
handoff: boolean;
|
|
22
|
+
prompts: AskPrompt[];
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
type OnBlockedChange = (state: BlockedState) => void;
|
|
@@ -79,24 +81,22 @@ export function createAskRuntime({
|
|
|
79
81
|
const blockedState = {
|
|
80
82
|
id: toolCallId,
|
|
81
83
|
active: true,
|
|
84
|
+
handoff,
|
|
85
|
+
prompts,
|
|
82
86
|
label: handoff ? "Human action needed" : "Waiting for input",
|
|
83
87
|
prompt: handoff
|
|
84
88
|
? "The user needs to complete an action before the active work can continue. Please announce this briefly in your natural voice."
|
|
85
89
|
: "User input is required before the active work can continue. Please announce this briefly in your natural voice.",
|
|
86
90
|
};
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
} finally {
|
|
98
|
-
onBlockedChange?.({ ...blockedState, active: false });
|
|
99
|
-
}
|
|
91
|
+
const presentationSignal = signal
|
|
92
|
+
? AbortSignal.any([signal, coordinator.sessionSignal])
|
|
93
|
+
: coordinator.sessionSignal;
|
|
94
|
+
const rawResponses = await coordinator.present(ctx, prompts, {
|
|
95
|
+
handoff,
|
|
96
|
+
signal: presentationSignal,
|
|
97
|
+
onActiveChange: (active) =>
|
|
98
|
+
onBlockedChange?.({ ...blockedState, active }),
|
|
99
|
+
});
|
|
100
100
|
const responses = normalizeResponses(prompts, rawResponses);
|
|
101
101
|
if (!responses) {
|
|
102
102
|
return {
|
package/index.ts
CHANGED
|
@@ -29,15 +29,35 @@ export default async function humanInTheLoop(pi: ExtensionAPI): Promise<void> {
|
|
|
29
29
|
const askRuntime = createAskRuntime({
|
|
30
30
|
deliverSteer: createSteerDelivery(pi, trySendCodexDeveloperMessage),
|
|
31
31
|
onBlockedChange: (state) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
const notify = () => {
|
|
33
|
+
pi.events.emit(REALTIME_VOICE_PROMPT_CHANNEL, {
|
|
34
|
+
id: state.id,
|
|
35
|
+
active: state.active,
|
|
36
|
+
prompt: state.prompt,
|
|
37
|
+
});
|
|
38
|
+
pi.events.emit("herdr:blocked", {
|
|
39
|
+
active: state.active,
|
|
40
|
+
label: state.label,
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
// Publish before Herdr reports blocked, including calls nested inside exec.
|
|
44
|
+
try {
|
|
45
|
+
pi.appendEntry(
|
|
46
|
+
"pi-ask-active",
|
|
47
|
+
state.active
|
|
48
|
+
? {
|
|
49
|
+
version: 1,
|
|
50
|
+
state: "active",
|
|
51
|
+
id: state.id,
|
|
52
|
+
handoff: state.handoff,
|
|
53
|
+
prompts: state.prompts,
|
|
54
|
+
}
|
|
55
|
+
: { version: 1, state: "closed", id: state.id },
|
|
56
|
+
);
|
|
57
|
+
} finally {
|
|
58
|
+
if (!state.active) notify();
|
|
59
|
+
}
|
|
60
|
+
if (state.active) notify();
|
|
41
61
|
},
|
|
42
62
|
onPendingChange: (update) => {
|
|
43
63
|
pi.appendEntry(PENDING_ASK_ENTRY_TYPE, update);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@howaboua/pi-ask",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Interactive decisions, review triage, and human handoffs for Pi.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
]
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@howaboua/pi-codex-conversion": ">=3.0.
|
|
48
|
+
"@howaboua/pi-codex-conversion": ">=3.0.30",
|
|
49
49
|
"@earendil-works/pi-ai": ">=0.84.3",
|
|
50
50
|
"@earendil-works/pi-coding-agent": ">=0.84.3",
|
|
51
51
|
"@earendil-works/pi-tui": ">=0.84.3",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
}
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@howaboua/pi-codex-conversion": "3.0.
|
|
60
|
+
"@howaboua/pi-codex-conversion": "3.0.30",
|
|
61
61
|
"@biomejs/biome": "^2.5.10",
|
|
62
|
-
"@earendil-works/pi-ai": "0.85.
|
|
63
|
-
"@earendil-works/pi-coding-agent": "0.85.
|
|
64
|
-
"@earendil-works/pi-tui": "0.85.
|
|
62
|
+
"@earendil-works/pi-ai": "0.85.1",
|
|
63
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
64
|
+
"@earendil-works/pi-tui": "0.85.1",
|
|
65
65
|
"typebox": "1.3.18",
|
|
66
66
|
"typescript": "^7.0.2"
|
|
67
67
|
},
|