pi-compact-tools 0.6.3 → 0.7.7
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 +151 -183
- package/examples/compact-tools-2.json +1 -4
- package/examples/compact-tools.json +1 -4
- package/extensions/compact-tools-color.ts +65 -0
- package/extensions/compact-tools-config.ts +7 -42
- package/extensions/compact-tools-core.ts +26 -0
- package/extensions/compact-tools-invocation.ts +228 -117
- package/extensions/compact-tools-layout.ts +23 -22
- package/extensions/compact-tools-progress.ts +158 -0
- package/extensions/compact-tools-runtime.ts +44 -70
- package/extensions/compact-tools-thinking.ts +280 -337
- package/extensions/compact-tools-types.ts +9 -8
- package/extensions/compact-tools.ts +350 -322
- package/package.json +64 -64
- package/schemas/compact-tools.schema.json +8 -24
- package/scripts/check-resources.mjs +13 -16
- package/extensions/compact-tools-input.ts +0 -8
|
@@ -9,32 +9,26 @@ import type {
|
|
|
9
9
|
} from "./compact-tools-types.ts";
|
|
10
10
|
|
|
11
11
|
const MAX_TRACKED_ROWS = 2_000;
|
|
12
|
-
const
|
|
12
|
+
const INDICATOR_INTERVAL_MS = 45;
|
|
13
13
|
const EXECUTION_TIMINGS_KEY = Symbol.for("pi.compact-tools.execution-timings");
|
|
14
14
|
|
|
15
15
|
type ExecutionTiming = { startedAt: number; endedAt?: number };
|
|
16
|
-
type TrackedRow = { state: RowState; name: CompactToolName; invalidate: () => void };
|
|
17
16
|
type TimedExecute = (...args: any[]) => Promise<AgentToolResult<unknown>>;
|
|
18
17
|
type SharedState = typeof globalThis & {
|
|
19
|
-
[SPINNING_ROWS_KEY]?: Set<RowState>;
|
|
20
18
|
[EXECUTION_TIMINGS_KEY]?: Map<string, ExecutionTiming>;
|
|
21
19
|
};
|
|
22
20
|
|
|
23
21
|
export class ToolRuntime {
|
|
24
22
|
private configValue = DEFAULT_CONFIG;
|
|
25
23
|
private configRevision: object = {};
|
|
26
|
-
private animateRows = false;
|
|
27
|
-
private readonly spinningRows = new Set<RowState>();
|
|
28
24
|
private readonly executionTimings: Map<string, ExecutionTiming>;
|
|
29
|
-
private readonly
|
|
25
|
+
private readonly indicatorInvalidators = new Map<string, () => void>();
|
|
26
|
+
private indicatorFrame = 0;
|
|
27
|
+
private indicatorTimer: ReturnType<typeof setInterval> | undefined;
|
|
30
28
|
|
|
31
29
|
constructor() {
|
|
32
30
|
const shared = globalThis as SharedState;
|
|
33
|
-
for (const state of shared[SPINNING_ROWS_KEY] ?? []) {
|
|
34
|
-
if (state.timer) clearInterval(state.timer);
|
|
35
|
-
}
|
|
36
31
|
this.executionTimings = shared[EXECUTION_TIMINGS_KEY] ?? new Map<string, ExecutionTiming>();
|
|
37
|
-
shared[SPINNING_ROWS_KEY] = this.spinningRows;
|
|
38
32
|
shared[EXECUTION_TIMINGS_KEY] = this.executionTimings;
|
|
39
33
|
}
|
|
40
34
|
|
|
@@ -42,14 +36,8 @@ export class ToolRuntime {
|
|
|
42
36
|
return this.configValue;
|
|
43
37
|
}
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
return this.animateRows;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
configure(config: CompactToolsConfig, animateRows: boolean): void {
|
|
50
|
-
this.reset(false);
|
|
39
|
+
configure(config: CompactToolsConfig): void {
|
|
51
40
|
this.configValue = config;
|
|
52
|
-
this.animateRows = animateRows;
|
|
53
41
|
this.configRevision = {};
|
|
54
42
|
}
|
|
55
43
|
|
|
@@ -58,40 +46,35 @@ export class ToolRuntime {
|
|
|
58
46
|
}
|
|
59
47
|
|
|
60
48
|
reset(clearTimings: boolean): void {
|
|
61
|
-
|
|
62
|
-
this.trackedRows.clear();
|
|
49
|
+
this.stopIndicators();
|
|
63
50
|
if (clearTimings) this.clearTimings();
|
|
64
51
|
}
|
|
65
52
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const oldest = this.trackedRows.keys().next().value;
|
|
71
|
-
if (oldest !== undefined) this.trackedRows.delete(oldest);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
toggleTrackedRows(): "expanded" | "collapsed" | undefined {
|
|
75
|
-
const rows: TrackedRow[] = [];
|
|
76
|
-
for (const row of this.trackedRows.values()) {
|
|
77
|
-
if (this.configValue.auto_compact[row.name] && row.state.hasResult) rows.push(row);
|
|
53
|
+
syncIndicator(toolCallId: string, running: boolean, invalidate: () => void): number {
|
|
54
|
+
if (!running) {
|
|
55
|
+
this.removeIndicator(toolCallId);
|
|
56
|
+
return 0;
|
|
78
57
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
58
|
+
this.indicatorInvalidators.set(toolCallId, invalidate);
|
|
59
|
+
if (!this.indicatorTimer) {
|
|
60
|
+
this.indicatorTimer = setInterval(() => {
|
|
61
|
+
this.indicatorFrame++;
|
|
62
|
+
for (const requestRender of this.indicatorInvalidators.values()) requestRender();
|
|
63
|
+
}, INDICATOR_INTERVAL_MS);
|
|
64
|
+
this.indicatorTimer.unref?.();
|
|
84
65
|
}
|
|
85
|
-
return
|
|
66
|
+
return this.indicatorFrame;
|
|
86
67
|
}
|
|
87
68
|
|
|
88
69
|
syncExpansion(state: RowState, hostExpanded: boolean, name: CompactToolName): boolean {
|
|
89
|
-
const initialized = this.initializeExpansion(state, name);
|
|
90
|
-
if (initialized
|
|
91
|
-
state.lastHostExpanded = hostExpanded;
|
|
92
|
-
} else if (state.lastHostExpanded !== hostExpanded) {
|
|
70
|
+
const initialized = this.initializeExpansion(state, name, hostExpanded);
|
|
71
|
+
if (!initialized && state.lastHostExpanded !== hostExpanded) {
|
|
93
72
|
state.lastHostExpanded = hostExpanded;
|
|
94
|
-
state.expanded =
|
|
73
|
+
state.expanded = hostExpanded;
|
|
74
|
+
// A non-auto-compacted row collapses back to its bounded preview. Hiding it
|
|
75
|
+
// here removes the clicked row from under the pointer, so the next click can
|
|
76
|
+
// accidentally hit the Thinking block that moved into the same coordinates.
|
|
77
|
+
state.preview = !hostExpanded && !this.configValue.auto_compact[name];
|
|
95
78
|
}
|
|
96
79
|
return state.expanded ?? false;
|
|
97
80
|
}
|
|
@@ -111,8 +94,8 @@ export class ToolRuntime {
|
|
|
111
94
|
const started = !ctx.argsComplete || ctx.executionStarted || running;
|
|
112
95
|
if (started && state.startedAt === undefined) state.startedAt = Date.now();
|
|
113
96
|
if (finished && state.startedAt !== undefined && state.endedAt === undefined) state.endedAt = Date.now();
|
|
97
|
+
if (finished) this.removeIndicator(ctx.toolCallId);
|
|
114
98
|
this.persistTiming(state, ctx.toolCallId);
|
|
115
|
-
this.syncSpinner(state, running, ctx.invalidate);
|
|
116
99
|
return state;
|
|
117
100
|
}
|
|
118
101
|
|
|
@@ -133,37 +116,28 @@ export class ToolRuntime {
|
|
|
133
116
|
};
|
|
134
117
|
}
|
|
135
118
|
|
|
136
|
-
private
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
119
|
+
private removeIndicator(toolCallId: string): void {
|
|
120
|
+
this.indicatorInvalidators.delete(toolCallId);
|
|
121
|
+
if (this.indicatorInvalidators.size > 0 || !this.indicatorTimer) return;
|
|
122
|
+
clearInterval(this.indicatorTimer);
|
|
123
|
+
this.indicatorTimer = undefined;
|
|
124
|
+
this.indicatorFrame = 0;
|
|
141
125
|
}
|
|
142
126
|
|
|
143
|
-
private
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
this.
|
|
127
|
+
private stopIndicators(): void {
|
|
128
|
+
if (this.indicatorTimer) clearInterval(this.indicatorTimer);
|
|
129
|
+
this.indicatorTimer = undefined;
|
|
130
|
+
this.indicatorInvalidators.clear();
|
|
131
|
+
this.indicatorFrame = 0;
|
|
147
132
|
}
|
|
148
133
|
|
|
149
|
-
private
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
state.frame ??= 0;
|
|
157
|
-
state.timer = setInterval(() => {
|
|
158
|
-
state.frame = ((state.frame ?? 0) + 1) % spinner.frames.length;
|
|
159
|
-
try {
|
|
160
|
-
invalidate();
|
|
161
|
-
} catch {
|
|
162
|
-
this.stopSpinner(state);
|
|
163
|
-
}
|
|
164
|
-
}, spinner.intervalMs);
|
|
165
|
-
state.timer.unref?.();
|
|
166
|
-
this.spinningRows.add(state);
|
|
134
|
+
private initializeExpansion(state: RowState, name: CompactToolName, hostExpanded = false): boolean {
|
|
135
|
+
if (state.configRevision === this.configRevision) return false;
|
|
136
|
+
state.configRevision = this.configRevision;
|
|
137
|
+
state.lastHostExpanded = hostExpanded;
|
|
138
|
+
state.expanded = hostExpanded;
|
|
139
|
+
state.preview = !hostExpanded && !this.configValue.auto_compact[name];
|
|
140
|
+
return true;
|
|
167
141
|
}
|
|
168
142
|
|
|
169
143
|
private restoreTiming(state: RowState, toolCallId: string): boolean {
|