osdy-pi 1.11.8 → 1.11.9
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/README.md
CHANGED
|
@@ -492,14 +492,14 @@ While work is active, Osdy Pi centers an activity label and compact animated gly
|
|
|
492
492
|
|
|
493
493
|
| Source | Example | Meaning |
|
|
494
494
|
| --- | --- | --- |
|
|
495
|
-
| Validated public `agent` argument | `
|
|
496
|
-
| Public foreground progress from Joker (`pi-subagents-j0k3r`) | `
|
|
495
|
+
| Validated public `agent` argument | `Working...` | Generic fallback, not measured progress or a claimed editing operation. This provider-neutral fallback works with Gentle Agents, which currently emits no live child progress. |
|
|
496
|
+
| Public foreground progress from Joker (`pi-subagents-j0k3r`) | `Exploring...` | Named `read` activity selects both the Exploring label and its existing glyph frames, overriding fallback. |
|
|
497
497
|
|
|
498
|
-
Live child activity uses the same six states and corresponding animated glyphs listed above,
|
|
498
|
+
Live child activity uses the same six states and corresponding animated glyphs listed above, without agent names: `Thinking...`, `Exploring...`, `Verifying...`, `Working...`, `Delegating...`, or `Executing...`. Both public thinking and response streaming select Thinking; model labels, reasoning and response text are never read. Named reads/searches/direct documentation tools select Exploring, `lens_diagnostics` selects Verifying, edits/writes select Working, and `subagent_run` selects Delegating. Only named checks qualify: public tool metadata lacks arguments, so `bash`, wrappers needing selectors, and unknown tool names select Executing. Tool completion/failure events classify the reported operation while the child is running; they do not claim whole-task completion.
|
|
499
499
|
|
|
500
|
-
The fallback is
|
|
500
|
+
The fallback is `Working...` **with the Working glyph**, regardless of optional `label` metadata. Missing or empty tool names supply no usable operation; named unknown tools instead select Executing. A continuation with an absent agent validates the generic `Subagent` identity without displaying it, never inferring an identity; missing/invalid run identity or explicitly invalid continuation identity fails closed to ordinary parent activity unless a live snapshot supplies its own validated public agent. Full tasks, prompts, context, content, trails and transcripts are never read or displayed.
|
|
501
501
|
|
|
502
|
-
For multiple running children, the indicator uses the first child in snapshot order with a compact additional-child count. Missing, malformed, terminal or no-running-child progress restores both the
|
|
502
|
+
For multiple running children, the indicator uses the first child in snapshot order with a compact additional-child count (`(+N)`). Missing, malformed, terminal or no-running-child progress restores both the generic `Working...` fallback text and Working glyph, or ordinary parent activity when validated agent identity is unavailable. Labels are bounded, control-safe and clipped to terminal width. Matching tool end, agent/session end and reload cleanup discard per-call state.
|
|
503
503
|
|
|
504
504
|
**Background limitation:** agent fallbacks appear only while their parent call is active. There is no persistent background live feed, polling or task cache.
|
|
505
505
|
|
|
@@ -9,24 +9,24 @@ registerHooks({ resolve(specifier, context, nextResolve) {
|
|
|
9
9
|
return nextResolve(specifier, context);
|
|
10
10
|
} });
|
|
11
11
|
const { childActivityState: activity, childAssignmentState: assignment } = await import("./working-child-activity.js");
|
|
12
|
-
const working = (
|
|
12
|
+
const working = () => ({ activity: "working", label: "Working..." });
|
|
13
13
|
|
|
14
14
|
void test("fallback uses only validated public agent identity regardless of optional label", () => {
|
|
15
|
-
assert.deepEqual(assignment("subagent_run", { agent: "explore", label: "map footer data" }), working(
|
|
15
|
+
assert.deepEqual(assignment("subagent_run", { agent: "explore", label: "map footer data" }), working());
|
|
16
16
|
for (const args of [undefined, null, [], "scout", {}, { agent: 1 }, { agent: "\u0000\n" }, { agent: "a".repeat(4097) }, { label: "secret" }])
|
|
17
17
|
assert.equal(assignment("subagent_run", args), undefined);
|
|
18
18
|
for (const label of [undefined, null, 1, [], "", "\u0000", "x".repeat(4097)])
|
|
19
|
-
assert.deepEqual(assignment("subagent_run", { agent: "scout", label, task: "SECRET", prompt: "SECRET", context: "SECRET" }), working(
|
|
19
|
+
assert.deepEqual(assignment("subagent_run", { agent: "scout", label, task: "SECRET", prompt: "SECRET", context: "SECRET" }), working());
|
|
20
20
|
const metadata = { agent: "scout", get label() { throw new Error("label must not be read"); },
|
|
21
21
|
get task() { throw new Error("task must not be read"); }, get prompt() { throw new Error("prompt must not be read"); },
|
|
22
22
|
get context() { throw new Error("context must not be read"); } };
|
|
23
|
-
assert.deepEqual(assignment("subagent_run", metadata), working(
|
|
23
|
+
assert.deepEqual(assignment("subagent_run", metadata), working());
|
|
24
24
|
assert.equal(assignment("read", { agent: "scout" }), undefined);
|
|
25
|
-
assert.deepEqual(assignment("subagent_continue", { id: "scout" }), working(
|
|
25
|
+
assert.deepEqual(assignment("subagent_continue", { id: "scout" }), working());
|
|
26
26
|
for (const agent of [42, null, "", "\u0000"])
|
|
27
27
|
assert.equal(assignment("subagent_continue", { agent }), undefined);
|
|
28
|
-
assert.deepEqual(assignment("subagent_run", { agent: "\u001b[31m探索\u001b[0m\n\u202eagent" }), working(
|
|
29
|
-
assert.deepEqual(assignment("subagent_run", { agent: "🙂".repeat(1000) }), working(
|
|
28
|
+
assert.deepEqual(assignment("subagent_run", { agent: "\u001b[31m探索\u001b[0m\n\u202eagent" }), working());
|
|
29
|
+
assert.deepEqual(assignment("subagent_run", { agent: "🙂".repeat(1000) }), working());
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
function task(agent = "scout", kind = "tool_running", tool_names: unknown = ["read"]) {
|
|
@@ -54,18 +54,18 @@ void test("public operations return structured six-state activity and label", ()
|
|
|
54
54
|
];
|
|
55
55
|
for (const kind of ["tool_running", "tool_completed", "tool_failed"])
|
|
56
56
|
for (const [tool, state, label] of cases)
|
|
57
|
-
assert.deepEqual(activity(progress(task("scout", kind, [tool]))), { activity: state, label
|
|
57
|
+
assert.deepEqual(activity(progress(task("scout", kind, [tool]))), { activity: state, label });
|
|
58
58
|
for (const kind of ["thinking", "streaming_response"])
|
|
59
|
-
assert.deepEqual(activity(progress(task("scout", kind))), { activity: "thinking", label: "
|
|
59
|
+
assert.deepEqual(activity(progress(task("scout", kind))), { activity: "thinking", label: "Thinking..." });
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
void test("multiple children select first running snapshot child and validate all children", () => {
|
|
63
63
|
assert.deepEqual(activity(progress({ agent: "old", status: "completed" }, task("first"), task("second"), task("third"))),
|
|
64
|
-
{ activity: "exploring", label: "
|
|
65
|
-
assert.deepEqual(activity(progress(task("first", "tool_running", ["read", "write"]))), { activity: "exploring", label: "
|
|
64
|
+
{ activity: "exploring", label: "Exploring... (+2)" });
|
|
65
|
+
assert.deepEqual(activity(progress(task("first", "tool_running", ["read", "write"]))), { activity: "exploring", label: "Exploring..." });
|
|
66
66
|
assert.equal(activity(progress(task(), task("bad", "tool_running", ["read", 1]))), undefined);
|
|
67
67
|
assert.equal(activity(progress(...Array.from({ length: 65 }, () => task()))), undefined);
|
|
68
|
-
assert.equal(activity(progress(...Array.from({ length: 64 }, () => task())))?.label, "
|
|
68
|
+
assert.equal(activity(progress(...Array.from({ length: 64 }, () => task())))?.label, "Exploring... (+63)");
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
void test("terminal, missing, malformed and unsupported progress has no usable activity", () => {
|
|
@@ -90,16 +90,16 @@ void test("oversized snapshot agent is rejected despite otherwise valid live act
|
|
|
90
90
|
assert.equal(activity(progress(task("a".repeat(4097)))), undefined);
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
void test("snapshot agent at the input bound remains valid
|
|
93
|
+
void test("snapshot agent at the input bound remains valid without appearing in the label", () => {
|
|
94
94
|
assert.deepEqual(activity(progress(task("a".repeat(4096)))),
|
|
95
|
-
{ activity: "exploring", label:
|
|
95
|
+
{ activity: "exploring", label: "Exploring..." });
|
|
96
96
|
});
|
|
97
97
|
|
|
98
98
|
void test("external names are single-line, control-free and bounded before classification", () => {
|
|
99
99
|
const dirty = "\u001b[31mAgent\u001b[0m\n\t\u202eName\u0007";
|
|
100
100
|
assert.deepEqual(activity(progress(task(dirty, "tool_running", ["\u001b]0;title\u0007read\nfile"]))),
|
|
101
|
-
{ activity: "executing", label: "
|
|
101
|
+
{ activity: "executing", label: "Executing..." });
|
|
102
102
|
assert.deepEqual(activity(progress(task("a".repeat(1000), "tool_running", ["b".repeat(1000)]))),
|
|
103
|
-
{ activity: "executing", label:
|
|
103
|
+
{ activity: "executing", label: "Executing..." });
|
|
104
104
|
assert.equal(activity(progress(task("\u0000\n"))), undefined);
|
|
105
105
|
});
|
|
@@ -4,8 +4,8 @@ import { classifyWorkingActivity, WORKING_ACTIVITY_LABELS } from "./working-acti
|
|
|
4
4
|
|
|
5
5
|
export type ChildWorkingState = { activity: WorkingActivity; label: string };
|
|
6
6
|
|
|
7
|
-
function childState(
|
|
8
|
-
return { activity, label:
|
|
7
|
+
function childState(activity: WorkingActivity): ChildWorkingState {
|
|
8
|
+
return { activity, label: WORKING_ACTIVITY_LABELS[activity] };
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function record(value: unknown): value is Record<string, unknown> {
|
|
@@ -27,7 +27,7 @@ export function childAssignmentState(toolName: string, args: unknown): ChildWork
|
|
|
27
27
|
if (!record(args)) return undefined;
|
|
28
28
|
const agent = args.agent === undefined && toolName === "subagent_continue" ? "Subagent" : safeLabel(args.agent, 32);
|
|
29
29
|
if (!agent) return undefined;
|
|
30
|
-
return childState(
|
|
30
|
+
return childState("working");
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
function observableActivity(value: unknown): WorkingActivity | undefined {
|
|
@@ -63,7 +63,7 @@ export function childActivityState(partialResult: unknown): ChildWorkingState |
|
|
|
63
63
|
const agent = safeLabel(task.agent, 32);
|
|
64
64
|
const activity = record(task.live_activity) ? observableActivity(task.live_activity.current) : undefined;
|
|
65
65
|
if (!agent || !activity) return undefined;
|
|
66
|
-
first ??= childState(
|
|
66
|
+
first ??= childState(activity);
|
|
67
67
|
running++;
|
|
68
68
|
}
|
|
69
69
|
if (!first) return undefined;
|
|
@@ -122,7 +122,7 @@ void test("child states select matching text and every existing glyph frame", (t
|
|
|
122
122
|
t.mock.timers.enable({ apis: ["setInterval"] });
|
|
123
123
|
const { working, controller: c } = fixture();
|
|
124
124
|
c.onToolStart("subagent_run", "child", { agent: "scout" });
|
|
125
|
-
assertDisplay(working, "working", "
|
|
125
|
+
assertDisplay(working, "working", "Working...");
|
|
126
126
|
const cases: Array<[string, string | undefined, WorkingActivity, string]> = [
|
|
127
127
|
["thinking", undefined, "thinking", "Thinking..."],
|
|
128
128
|
["streaming_response", undefined, "thinking", "Thinking..."],
|
|
@@ -135,7 +135,7 @@ void test("child states select matching text and every existing glyph frame", (t
|
|
|
135
135
|
for (const [kind, tool, activity, label] of cases) {
|
|
136
136
|
c.onToolUpdate("subagent_run", "child", { details: { tasks: [{ agent: "scout", status: "running",
|
|
137
137
|
live_activity: { current: { kind, label: "IGNORED", tool_names: tool ? [tool] : undefined } } }] } });
|
|
138
|
-
assertDisplay(working, activity,
|
|
138
|
+
assertDisplay(working, activity, label);
|
|
139
139
|
}
|
|
140
140
|
c.onShutdown();
|
|
141
141
|
});
|
|
@@ -145,21 +145,21 @@ void test("child updates respect tool identity and latest remaining tool ownersh
|
|
|
145
145
|
const { working, controller: c } = fixture();
|
|
146
146
|
c.onToolStart("subagent_run", "a");
|
|
147
147
|
c.onToolUpdate("subagent_run", "a", childProgress("scout"));
|
|
148
|
-
assertDisplay(working, "exploring", "
|
|
148
|
+
assertDisplay(working, "exploring", "Exploring...");
|
|
149
149
|
c.onToolStart("subagent_run", "b");
|
|
150
150
|
c.onToolUpdate("subagent_run", "b", childProgress("writer", "edit"));
|
|
151
151
|
c.onToolUpdate("subagent_run", "a", childProgress("scout", "grep"));
|
|
152
152
|
c.onToolUpdate("read", "b", childProgress("wrong"));
|
|
153
153
|
c.onToolUpdate("subagent_run", "missing", childProgress("late"));
|
|
154
154
|
c.onToolEnd("missing");
|
|
155
|
-
assertDisplay(working, "working", "
|
|
155
|
+
assertDisplay(working, "working", "Working...");
|
|
156
156
|
c.onToolStart("read", "ordinary");
|
|
157
157
|
c.onToolUpdate("subagent_run", "ordinary", childProgress("wrong"));
|
|
158
158
|
assert.equal(working.label, "Exploring...");
|
|
159
|
-
c.onToolEnd("ordinary"); assertDisplay(working, "working", "
|
|
160
|
-
c.onToolEnd("b"); assertDisplay(working, "exploring", "
|
|
159
|
+
c.onToolEnd("ordinary"); assertDisplay(working, "working", "Working...");
|
|
160
|
+
c.onToolEnd("b"); assertDisplay(working, "exploring", "Exploring...");
|
|
161
161
|
c.onToolUpdate("subagent_run", "b", childProgress("late"));
|
|
162
|
-
assertDisplay(working, "exploring", "
|
|
162
|
+
assertDisplay(working, "exploring", "Exploring...");
|
|
163
163
|
c.onToolUpdate("subagent_run", "a", childProgress("scout", "read", "completed"));
|
|
164
164
|
assert.equal(working.label, "Delegating...");
|
|
165
165
|
c.onToolUpdate("subagent_run", "a", childProgress("scout"));
|
|
@@ -187,16 +187,16 @@ void test("agent fallback appears at start and resets after unavailable, malform
|
|
|
187
187
|
t.mock.timers.enable({ apis: ["setInterval"] });
|
|
188
188
|
const { working, controller: c } = fixture();
|
|
189
189
|
c.onToolStart("subagent_run", "a", { agent: "explore", label: "map footer data", task: "SECRET TASK", prompt: "SECRET PROMPT" });
|
|
190
|
-
assertDisplay(working, "working", "
|
|
190
|
+
assertDisplay(working, "working", "Working...");
|
|
191
191
|
c.onToolUpdate("subagent_run", "a", childProgress("explore"));
|
|
192
|
-
assertDisplay(working, "exploring", "
|
|
192
|
+
assertDisplay(working, "exploring", "Exploring...");
|
|
193
193
|
for (const update of [undefined, {}, { details: { tasks: null } }, { details: { tasks: [{ agent: "explore", status: "running" }] } }, childProgress("explore", "read", "completed"), childProgress("explore", ""),
|
|
194
194
|
{ details: { tasks: [{ agent: "explore", status: "running", live_activity: { current: { kind: "tool_running", tool_names: [] } } }] } },
|
|
195
195
|
{ details: { tasks: [{ agent: "explore", status: "running", live_activity: { current: { kind: "tool_running" } } }] } }]) {
|
|
196
196
|
c.onToolUpdate("subagent_run", "a", childProgress("explore"));
|
|
197
|
-
assertDisplay(working, "exploring", "
|
|
197
|
+
assertDisplay(working, "exploring", "Exploring...");
|
|
198
198
|
c.onToolUpdate("subagent_run", "a", update);
|
|
199
|
-
assertDisplay(working, "working", "
|
|
199
|
+
assertDisplay(working, "working", "Working...");
|
|
200
200
|
}
|
|
201
201
|
c.onToolEnd("a"); assert.equal(working.label, "Thinking...");
|
|
202
202
|
});
|
|
@@ -205,28 +205,28 @@ void test("continuations use generic identity without guessing and preserve call
|
|
|
205
205
|
t.mock.timers.enable({ apis: ["setInterval"] });
|
|
206
206
|
const { working, controller: c } = fixture();
|
|
207
207
|
c.onToolStart("subagent_run", "a", { agent: "scout" });
|
|
208
|
-
assert.equal(working.label, "
|
|
208
|
+
assert.equal(working.label, "Working...");
|
|
209
209
|
c.onToolStart("subagent_continue", "b", { id: "a", label: "check footer" });
|
|
210
|
-
assert.equal(working.label, "
|
|
210
|
+
assert.equal(working.label, "Working...");
|
|
211
211
|
c.onToolStart("subagent_continue", "a", { agent: "wrong", label: "wrong" });
|
|
212
212
|
c.onToolUpdate("subagent_run", "b", childProgress("wrong"));
|
|
213
213
|
c.onToolUpdate("subagent_continue", "missing", childProgress("wrong"));
|
|
214
|
-
assert.equal(working.label, "
|
|
214
|
+
assert.equal(working.label, "Working...");
|
|
215
215
|
c.onToolUpdate("subagent_continue", "b", childProgress("writer", "edit"));
|
|
216
|
-
assertDisplay(working, "working", "
|
|
216
|
+
assertDisplay(working, "working", "Working...");
|
|
217
217
|
c.onToolUpdate("subagent_run", "a", childProgress("scout"));
|
|
218
|
-
assertDisplay(working, "working", "
|
|
218
|
+
assertDisplay(working, "working", "Working...");
|
|
219
219
|
c.onToolUpdate("subagent_continue", "b", {});
|
|
220
|
-
assert.equal(working.label, "
|
|
221
|
-
c.onToolEnd("b"); assertDisplay(working, "exploring", "
|
|
220
|
+
assert.equal(working.label, "Working...");
|
|
221
|
+
c.onToolEnd("b"); assertDisplay(working, "exploring", "Exploring...");
|
|
222
222
|
c.onToolUpdate("subagent_continue", "b", childProgress("late"));
|
|
223
|
-
c.onToolUpdate("subagent_run", "a", {}); assert.equal(working.label, "
|
|
223
|
+
c.onToolUpdate("subagent_run", "a", {}); assert.equal(working.label, "Working...");
|
|
224
224
|
c.onToolEnd("a");
|
|
225
225
|
c.onToolStart("subagent_continue", "c", { agent: "writer", label: "finish" });
|
|
226
|
-
assert.equal(working.label, "
|
|
226
|
+
assert.equal(working.label, "Working...");
|
|
227
227
|
c.onToolEnd("c");
|
|
228
228
|
c.onToolStart("subagent_continue", "d", { id: "c", task: "SECRET" });
|
|
229
|
-
assert.equal(working.label, "
|
|
229
|
+
assert.equal(working.label, "Working...");
|
|
230
230
|
c.onToolEnd("d");
|
|
231
231
|
});
|
|
232
232
|
|
|
@@ -237,7 +237,7 @@ void test("identity failures stay parent-owned and live snapshots retain validat
|
|
|
237
237
|
c.onToolStart("subagent_run", "run", args);
|
|
238
238
|
assertDisplay(working, "delegating", "Delegating...");
|
|
239
239
|
c.onToolUpdate("subagent_run", "run", childProgress("public"));
|
|
240
|
-
assertDisplay(working, "exploring", "
|
|
240
|
+
assertDisplay(working, "exploring", "Exploring...");
|
|
241
241
|
c.onToolUpdate("subagent_run", "run", {});
|
|
242
242
|
assertDisplay(working, "delegating", "Delegating...");
|
|
243
243
|
c.onToolEnd("run");
|
|
@@ -246,17 +246,17 @@ void test("identity failures stay parent-owned and live snapshots retain validat
|
|
|
246
246
|
assertDisplay(working, "executing", "Executing...");
|
|
247
247
|
c.onToolEnd("continue");
|
|
248
248
|
c.onToolStart("subagent_continue", "continue", {});
|
|
249
|
-
assertDisplay(working, "working", "
|
|
249
|
+
assertDisplay(working, "working", "Working...");
|
|
250
250
|
c.onToolUpdate("subagent_continue", "continue", { details: { tasks: [
|
|
251
251
|
{ agent: "first", status: "running", live_activity: { current: { kind: "tool_running", tool_names: ["read"] } } },
|
|
252
252
|
{ agent: "second", status: "running", live_activity: { current: { kind: "thinking" } } },
|
|
253
253
|
] } });
|
|
254
|
-
assertDisplay(working, "exploring", "
|
|
254
|
+
assertDisplay(working, "exploring", "Exploring... (+1)");
|
|
255
255
|
c.onToolStart("subagent_run", "continue", { agent: "wrong" });
|
|
256
256
|
c.onToolUpdate("subagent_run", "continue", childProgress("wrong"));
|
|
257
|
-
assertDisplay(working, "exploring", "
|
|
257
|
+
assertDisplay(working, "exploring", "Exploring... (+1)");
|
|
258
258
|
c.onToolUpdate("subagent_continue", "continue", {});
|
|
259
|
-
assertDisplay(working, "working", "
|
|
259
|
+
assertDisplay(working, "working", "Working...");
|
|
260
260
|
c.onShutdown();
|
|
261
261
|
});
|
|
262
262
|
|
|
@@ -265,7 +265,7 @@ void test("assignment metadata is cleared on agent and session cleanup", (t) =>
|
|
|
265
265
|
const { working, controller: c } = fixture();
|
|
266
266
|
for (const cleanup of [() => c.onAgentEnd(), () => c.onShutdown()]) {
|
|
267
267
|
c.onToolStart("subagent_run", "a", { agent: "scout", label: "map" });
|
|
268
|
-
assert.equal(working.label, "
|
|
268
|
+
assert.equal(working.label, "Working...");
|
|
269
269
|
cleanup(); c.onToolUpdate("subagent_run", "a", childProgress("late"));
|
|
270
270
|
c.refreshWorking(); assert.equal(working.label, "Thinking...");
|
|
271
271
|
assert.equal(working.active, false); assert.equal(working.timer, undefined);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osdy-pi",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.9",
|
|
4
4
|
"description": "Osdy Pi package: themes, header, and custom editor for Pi.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"typescript": "^5.9.3",
|
|
84
84
|
"typescript-eslint": "^8.46.3"
|
|
85
85
|
},
|
|
86
|
-
"releaseSource": "
|
|
86
|
+
"releaseSource": "5e7c5215302d92dc19cf7aedea5d8b767cebd76a",
|
|
87
87
|
"repository": {
|
|
88
88
|
"type": "git",
|
|
89
89
|
"url": "git+https://github.com/OsdyOrtiz/Osdy-Pi.git"
|