@positronic/cli 0.0.56 → 0.0.57
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/src/cli.js +130 -0
- package/dist/src/commands/auth.js +98 -0
- package/dist/src/commands/helpers.js +48 -10
- package/dist/src/commands/project-config-manager.js +119 -0
- package/dist/src/commands/users.js +91 -0
- package/dist/src/components/agent-chat-view.js +125 -0
- package/dist/src/components/auth-list.js +56 -0
- package/dist/src/components/auth-login.js +209 -0
- package/dist/src/components/auth-logout.js +75 -0
- package/dist/src/components/auth-status.js +88 -0
- package/dist/src/components/brain-run.js +287 -254
- package/dist/src/components/brain-top-table.js +4 -0
- package/dist/src/components/event-detail.js +364 -0
- package/dist/src/components/events-view.js +221 -25
- package/dist/src/components/state-view.js +52 -0
- package/dist/src/components/top-navigator.js +80 -6
- package/dist/src/components/types.js +1 -0
- package/dist/src/components/users-create.js +293 -0
- package/dist/src/components/users-delete.js +294 -0
- package/dist/src/components/users-keys-add.js +156 -0
- package/dist/src/components/users-keys-list.js +119 -0
- package/dist/src/components/users-keys-remove.js +299 -0
- package/dist/src/components/users-list.js +109 -0
- package/dist/src/components/watch-keyboard.js +136 -0
- package/dist/src/components/watch-machine.js +573 -0
- package/dist/src/components/watch.js +357 -44
- package/dist/src/hooks/useApi.js +80 -42
- package/dist/src/lib/request-signer.js +208 -0
- package/dist/src/lib/ssh-key-utils.js +212 -0
- package/dist/src/utils/agent-utils.js +107 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/commands/auth.d.ts +36 -0
- package/dist/types/commands/auth.d.ts.map +1 -0
- package/dist/types/commands/helpers.d.ts.map +1 -1
- package/dist/types/commands/project-config-manager.d.ts +43 -0
- package/dist/types/commands/project-config-manager.d.ts.map +1 -1
- package/dist/types/commands/users.d.ts +33 -0
- package/dist/types/commands/users.d.ts.map +1 -0
- package/dist/types/components/agent-chat-view.d.ts +12 -0
- package/dist/types/components/agent-chat-view.d.ts.map +1 -0
- package/dist/types/components/auth-list.d.ts +7 -0
- package/dist/types/components/auth-list.d.ts.map +1 -0
- package/dist/types/components/auth-login.d.ts +9 -0
- package/dist/types/components/auth-login.d.ts.map +1 -0
- package/dist/types/components/auth-logout.d.ts +8 -0
- package/dist/types/components/auth-logout.d.ts.map +1 -0
- package/dist/types/components/auth-status.d.ts +7 -0
- package/dist/types/components/auth-status.d.ts.map +1 -0
- package/dist/types/components/brain-run.d.ts +11 -1
- package/dist/types/components/brain-run.d.ts.map +1 -1
- package/dist/types/components/brain-top-table.d.ts.map +1 -1
- package/dist/types/components/event-detail.d.ts +10 -0
- package/dist/types/components/event-detail.d.ts.map +1 -0
- package/dist/types/components/events-view.d.ts +9 -7
- package/dist/types/components/events-view.d.ts.map +1 -1
- package/dist/types/components/state-view.d.ts +13 -0
- package/dist/types/components/state-view.d.ts.map +1 -0
- package/dist/types/components/top-navigator.d.ts.map +1 -1
- package/dist/types/components/types.d.ts +11 -0
- package/dist/types/components/types.d.ts.map +1 -0
- package/dist/types/components/users-create.d.ts +6 -0
- package/dist/types/components/users-create.d.ts.map +1 -0
- package/dist/types/components/users-delete.d.ts +7 -0
- package/dist/types/components/users-delete.d.ts.map +1 -0
- package/dist/types/components/users-keys-add.d.ts +8 -0
- package/dist/types/components/users-keys-add.d.ts.map +1 -0
- package/dist/types/components/users-keys-list.d.ts +6 -0
- package/dist/types/components/users-keys-list.d.ts.map +1 -0
- package/dist/types/components/users-keys-remove.d.ts +8 -0
- package/dist/types/components/users-keys-remove.d.ts.map +1 -0
- package/dist/types/components/users-list.d.ts +2 -0
- package/dist/types/components/users-list.d.ts.map +1 -0
- package/dist/types/components/watch-keyboard.d.ts +56 -0
- package/dist/types/components/watch-keyboard.d.ts.map +1 -0
- package/dist/types/components/watch-machine.d.ts +171 -0
- package/dist/types/components/watch-machine.d.ts.map +1 -0
- package/dist/types/components/watch.d.ts.map +1 -1
- package/dist/types/hooks/useApi.d.ts.map +1 -1
- package/dist/types/hooks/useBrainMachine.d.ts +9 -3
- package/dist/types/hooks/useBrainMachine.d.ts.map +1 -1
- package/dist/types/lib/request-signer.d.ts +51 -0
- package/dist/types/lib/request-signer.d.ts.map +1 -0
- package/dist/types/lib/ssh-key-utils.d.ts +45 -0
- package/dist/types/lib/ssh-key-utils.d.ts.map +1 -0
- package/dist/types/utils/agent-utils.d.ts +20 -0
- package/dist/types/utils/agent-utils.d.ts.map +1 -0
- package/package.json +7 -4
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_without_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
8
|
+
}
|
|
9
|
+
function _iterable_to_array(iter) {
|
|
10
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
11
|
+
}
|
|
12
|
+
function _non_iterable_spread() {
|
|
13
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
14
|
+
}
|
|
15
|
+
function _to_consumable_array(arr) {
|
|
16
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
17
|
+
}
|
|
18
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
19
|
+
if (!o) return;
|
|
20
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
21
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
22
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
23
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
24
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
25
|
+
}
|
|
26
|
+
import React from 'react';
|
|
27
|
+
import { Text, Box, useStdout, useInput } from 'ink';
|
|
28
|
+
import { BRAIN_EVENTS } from '@positronic/core';
|
|
29
|
+
function formatFullTimestamp(timestamp) {
|
|
30
|
+
return timestamp.toLocaleTimeString('en-US', {
|
|
31
|
+
hour: '2-digit',
|
|
32
|
+
minute: '2-digit',
|
|
33
|
+
second: '2-digit',
|
|
34
|
+
hour12: false
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function formatValue(value) {
|
|
38
|
+
if (typeof value === 'string') return value;
|
|
39
|
+
return JSON.stringify(value, null, 2);
|
|
40
|
+
}
|
|
41
|
+
function getStatusIcon(status) {
|
|
42
|
+
switch(status){
|
|
43
|
+
case 'complete':
|
|
44
|
+
return '✓';
|
|
45
|
+
case 'running':
|
|
46
|
+
return '•';
|
|
47
|
+
case 'error':
|
|
48
|
+
return '✗';
|
|
49
|
+
default:
|
|
50
|
+
return '○';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function getEventSymbol(event) {
|
|
54
|
+
switch(event.type){
|
|
55
|
+
case BRAIN_EVENTS.START:
|
|
56
|
+
return {
|
|
57
|
+
symbol: '[>]',
|
|
58
|
+
color: 'yellow'
|
|
59
|
+
};
|
|
60
|
+
case BRAIN_EVENTS.COMPLETE:
|
|
61
|
+
return {
|
|
62
|
+
symbol: '[ok]',
|
|
63
|
+
color: 'green'
|
|
64
|
+
};
|
|
65
|
+
case BRAIN_EVENTS.ERROR:
|
|
66
|
+
return {
|
|
67
|
+
symbol: '[!!]',
|
|
68
|
+
color: 'red'
|
|
69
|
+
};
|
|
70
|
+
case BRAIN_EVENTS.CANCELLED:
|
|
71
|
+
return {
|
|
72
|
+
symbol: '[x]',
|
|
73
|
+
color: 'red'
|
|
74
|
+
};
|
|
75
|
+
case BRAIN_EVENTS.STEP_START:
|
|
76
|
+
return {
|
|
77
|
+
symbol: '[.]',
|
|
78
|
+
color: 'yellow'
|
|
79
|
+
};
|
|
80
|
+
case BRAIN_EVENTS.STEP_COMPLETE:
|
|
81
|
+
return {
|
|
82
|
+
symbol: '[+]',
|
|
83
|
+
color: 'green'
|
|
84
|
+
};
|
|
85
|
+
case BRAIN_EVENTS.STEP_RETRY:
|
|
86
|
+
return {
|
|
87
|
+
symbol: '[?]',
|
|
88
|
+
color: 'yellow'
|
|
89
|
+
};
|
|
90
|
+
case BRAIN_EVENTS.STEP_STATUS:
|
|
91
|
+
return {
|
|
92
|
+
symbol: '[-]',
|
|
93
|
+
color: 'gray'
|
|
94
|
+
};
|
|
95
|
+
case BRAIN_EVENTS.WEBHOOK:
|
|
96
|
+
return {
|
|
97
|
+
symbol: '[~]',
|
|
98
|
+
color: 'cyan'
|
|
99
|
+
};
|
|
100
|
+
case BRAIN_EVENTS.WEBHOOK_RESPONSE:
|
|
101
|
+
return {
|
|
102
|
+
symbol: '[<]',
|
|
103
|
+
color: 'cyan'
|
|
104
|
+
};
|
|
105
|
+
case BRAIN_EVENTS.AGENT_START:
|
|
106
|
+
return {
|
|
107
|
+
symbol: '[A]',
|
|
108
|
+
color: 'yellow'
|
|
109
|
+
};
|
|
110
|
+
case BRAIN_EVENTS.AGENT_ITERATION:
|
|
111
|
+
return {
|
|
112
|
+
symbol: '[#]',
|
|
113
|
+
color: 'gray'
|
|
114
|
+
};
|
|
115
|
+
case BRAIN_EVENTS.AGENT_TOOL_CALL:
|
|
116
|
+
return {
|
|
117
|
+
symbol: '[T]',
|
|
118
|
+
color: 'white'
|
|
119
|
+
};
|
|
120
|
+
case BRAIN_EVENTS.AGENT_TOOL_RESULT:
|
|
121
|
+
return {
|
|
122
|
+
symbol: '[R]',
|
|
123
|
+
color: 'white'
|
|
124
|
+
};
|
|
125
|
+
case BRAIN_EVENTS.AGENT_ASSISTANT_MESSAGE:
|
|
126
|
+
return {
|
|
127
|
+
symbol: '[M]',
|
|
128
|
+
color: 'white'
|
|
129
|
+
};
|
|
130
|
+
case BRAIN_EVENTS.AGENT_COMPLETE:
|
|
131
|
+
return {
|
|
132
|
+
symbol: '[A]',
|
|
133
|
+
color: 'green'
|
|
134
|
+
};
|
|
135
|
+
case BRAIN_EVENTS.AGENT_TOKEN_LIMIT:
|
|
136
|
+
return {
|
|
137
|
+
symbol: '[!]',
|
|
138
|
+
color: 'red'
|
|
139
|
+
};
|
|
140
|
+
case BRAIN_EVENTS.AGENT_ITERATION_LIMIT:
|
|
141
|
+
return {
|
|
142
|
+
symbol: '[!]',
|
|
143
|
+
color: 'red'
|
|
144
|
+
};
|
|
145
|
+
case BRAIN_EVENTS.AGENT_WEBHOOK:
|
|
146
|
+
return {
|
|
147
|
+
symbol: '[W]',
|
|
148
|
+
color: 'cyan'
|
|
149
|
+
};
|
|
150
|
+
default:
|
|
151
|
+
return {
|
|
152
|
+
symbol: '[?]',
|
|
153
|
+
color: 'gray'
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function getEventDetailContent(event) {
|
|
158
|
+
switch(event.type){
|
|
159
|
+
case BRAIN_EVENTS.AGENT_TOOL_CALL:
|
|
160
|
+
return [
|
|
161
|
+
"Tool: ".concat(event.toolName),
|
|
162
|
+
"Tool Call ID: ".concat(event.toolCallId),
|
|
163
|
+
"Step: ".concat(event.stepTitle),
|
|
164
|
+
'',
|
|
165
|
+
'Input:',
|
|
166
|
+
JSON.stringify(event.input, null, 2)
|
|
167
|
+
].join('\n');
|
|
168
|
+
case BRAIN_EVENTS.AGENT_TOOL_RESULT:
|
|
169
|
+
return [
|
|
170
|
+
"Tool: ".concat(event.toolName),
|
|
171
|
+
"Tool Call ID: ".concat(event.toolCallId),
|
|
172
|
+
"Step: ".concat(event.stepTitle),
|
|
173
|
+
'',
|
|
174
|
+
'Result:',
|
|
175
|
+
formatValue(event.result)
|
|
176
|
+
].join('\n');
|
|
177
|
+
case BRAIN_EVENTS.ERROR:
|
|
178
|
+
return [
|
|
179
|
+
"Brain: ".concat(event.brainTitle),
|
|
180
|
+
'',
|
|
181
|
+
"Error: ".concat(event.error.name),
|
|
182
|
+
"Message: ".concat(event.error.message),
|
|
183
|
+
'',
|
|
184
|
+
'Stack Trace:',
|
|
185
|
+
event.error.stack || '(no stack trace)'
|
|
186
|
+
].join('\n');
|
|
187
|
+
case BRAIN_EVENTS.AGENT_COMPLETE:
|
|
188
|
+
return [
|
|
189
|
+
"Step: ".concat(event.stepTitle),
|
|
190
|
+
"Terminal Tool: ".concat(event.terminalToolName),
|
|
191
|
+
"Total Iterations: ".concat(event.totalIterations),
|
|
192
|
+
"Total Tokens: ".concat(event.totalTokens.toLocaleString()),
|
|
193
|
+
'',
|
|
194
|
+
'Result:',
|
|
195
|
+
JSON.stringify(event.result, null, 2)
|
|
196
|
+
].join('\n');
|
|
197
|
+
case BRAIN_EVENTS.AGENT_ITERATION:
|
|
198
|
+
return [
|
|
199
|
+
"Step: ".concat(event.stepTitle),
|
|
200
|
+
"Iteration: ".concat(event.iteration),
|
|
201
|
+
"Tokens This Iteration: ".concat(event.tokensThisIteration.toLocaleString()),
|
|
202
|
+
"Total Tokens So Far: ".concat(event.totalTokens.toLocaleString())
|
|
203
|
+
].join('\n');
|
|
204
|
+
case BRAIN_EVENTS.STEP_COMPLETE:
|
|
205
|
+
return [
|
|
206
|
+
"Step: ".concat(event.stepTitle),
|
|
207
|
+
"Step ID: ".concat(event.stepId),
|
|
208
|
+
'',
|
|
209
|
+
'State Patch:',
|
|
210
|
+
JSON.stringify(event.patch, null, 2)
|
|
211
|
+
].join('\n');
|
|
212
|
+
case BRAIN_EVENTS.AGENT_START:
|
|
213
|
+
return [
|
|
214
|
+
"Step: ".concat(event.stepTitle),
|
|
215
|
+
"Step ID: ".concat(event.stepId),
|
|
216
|
+
'',
|
|
217
|
+
'Tools:'
|
|
218
|
+
].concat(_to_consumable_array(event.tools && event.tools.length > 0 ? event.tools.map(function(t) {
|
|
219
|
+
return " • ".concat(t);
|
|
220
|
+
}) : [
|
|
221
|
+
' (none)'
|
|
222
|
+
]), [
|
|
223
|
+
'',
|
|
224
|
+
'Prompt:',
|
|
225
|
+
event.prompt
|
|
226
|
+
], _to_consumable_array(event.system ? [
|
|
227
|
+
'',
|
|
228
|
+
'System Prompt:',
|
|
229
|
+
event.system
|
|
230
|
+
] : [])).join('\n');
|
|
231
|
+
case BRAIN_EVENTS.START:
|
|
232
|
+
return [
|
|
233
|
+
"Brain: ".concat(event.brainTitle)
|
|
234
|
+
].concat(_to_consumable_array(event.brainDescription ? [
|
|
235
|
+
"Description: ".concat(event.brainDescription)
|
|
236
|
+
] : []), [
|
|
237
|
+
"Run ID: ".concat(event.brainRunId),
|
|
238
|
+
'',
|
|
239
|
+
'Options:',
|
|
240
|
+
JSON.stringify(event.options, null, 2)
|
|
241
|
+
]).join('\n');
|
|
242
|
+
case BRAIN_EVENTS.AGENT_TOKEN_LIMIT:
|
|
243
|
+
return [
|
|
244
|
+
"Step: ".concat(event.stepTitle),
|
|
245
|
+
"Total Tokens: ".concat(event.totalTokens.toLocaleString()),
|
|
246
|
+
"Max Tokens: ".concat(event.maxTokens.toLocaleString()),
|
|
247
|
+
'',
|
|
248
|
+
'Token limit exceeded. Agent stopped.'
|
|
249
|
+
].join('\n');
|
|
250
|
+
case BRAIN_EVENTS.AGENT_ITERATION_LIMIT:
|
|
251
|
+
return [
|
|
252
|
+
"Step: ".concat(event.stepTitle),
|
|
253
|
+
"Iteration: ".concat(event.iteration),
|
|
254
|
+
"Max Iterations: ".concat(event.maxIterations),
|
|
255
|
+
"Total Tokens: ".concat(event.totalTokens.toLocaleString()),
|
|
256
|
+
'',
|
|
257
|
+
'Iteration limit reached. Agent stopped.'
|
|
258
|
+
].join('\n');
|
|
259
|
+
case BRAIN_EVENTS.STEP_STATUS:
|
|
260
|
+
return [
|
|
261
|
+
'Steps:'
|
|
262
|
+
].concat(_to_consumable_array(event.steps.map(function(s) {
|
|
263
|
+
return " ".concat(getStatusIcon(s.status), " ").concat(s.title);
|
|
264
|
+
}))).join('\n');
|
|
265
|
+
case BRAIN_EVENTS.AGENT_ASSISTANT_MESSAGE:
|
|
266
|
+
return [
|
|
267
|
+
"Step: ".concat(event.stepTitle),
|
|
268
|
+
'',
|
|
269
|
+
'Message:',
|
|
270
|
+
event.content
|
|
271
|
+
].join('\n');
|
|
272
|
+
case BRAIN_EVENTS.STEP_START:
|
|
273
|
+
return [
|
|
274
|
+
"Step: ".concat(event.stepTitle),
|
|
275
|
+
"Step ID: ".concat(event.stepId)
|
|
276
|
+
].join('\n');
|
|
277
|
+
case BRAIN_EVENTS.STEP_RETRY:
|
|
278
|
+
return [
|
|
279
|
+
"Step: ".concat(event.stepTitle),
|
|
280
|
+
"Step ID: ".concat(event.stepId),
|
|
281
|
+
"Attempt: ".concat(event.attempt)
|
|
282
|
+
].join('\n');
|
|
283
|
+
case BRAIN_EVENTS.COMPLETE:
|
|
284
|
+
return [
|
|
285
|
+
"Brain: ".concat(event.brainTitle),
|
|
286
|
+
'',
|
|
287
|
+
'Brain completed successfully.'
|
|
288
|
+
].join('\n');
|
|
289
|
+
case BRAIN_EVENTS.CANCELLED:
|
|
290
|
+
return [
|
|
291
|
+
"Brain: ".concat(event.brainTitle),
|
|
292
|
+
'',
|
|
293
|
+
'Brain was cancelled.'
|
|
294
|
+
].join('\n');
|
|
295
|
+
case BRAIN_EVENTS.WEBHOOK:
|
|
296
|
+
return [
|
|
297
|
+
'Waiting for webhook response...',
|
|
298
|
+
'',
|
|
299
|
+
'Wait For:',
|
|
300
|
+
JSON.stringify(event.waitFor, null, 2)
|
|
301
|
+
].join('\n');
|
|
302
|
+
case BRAIN_EVENTS.WEBHOOK_RESPONSE:
|
|
303
|
+
return [
|
|
304
|
+
'Webhook Response:',
|
|
305
|
+
JSON.stringify(event.response, null, 2)
|
|
306
|
+
].join('\n');
|
|
307
|
+
case BRAIN_EVENTS.AGENT_WEBHOOK:
|
|
308
|
+
return [
|
|
309
|
+
"Step: ".concat(event.stepTitle),
|
|
310
|
+
"Tool: ".concat(event.toolName),
|
|
311
|
+
"Tool Call ID: ".concat(event.toolCallId),
|
|
312
|
+
'',
|
|
313
|
+
'Agent waiting for webhook response...'
|
|
314
|
+
].join('\n');
|
|
315
|
+
default:
|
|
316
|
+
// Show all fields for any event type
|
|
317
|
+
return JSON.stringify(event, null, 2);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
export var EventDetail = function(param) {
|
|
321
|
+
var stored = param.stored, scrollOffset = param.scrollOffset, onScrollChange = param.onScrollChange, _param_isActive = param.isActive, isActive = _param_isActive === void 0 ? true : _param_isActive;
|
|
322
|
+
var stdout = useStdout().stdout;
|
|
323
|
+
var terminalHeight = (stdout === null || stdout === void 0 ? void 0 : stdout.rows) || 24;
|
|
324
|
+
var maxLines = Math.max(5, terminalHeight - 8);
|
|
325
|
+
var content = getEventDetailContent(stored.event);
|
|
326
|
+
var lines = content.split('\n');
|
|
327
|
+
var totalLines = lines.length;
|
|
328
|
+
var maxScroll = Math.max(0, totalLines - maxLines);
|
|
329
|
+
// Handle scrolling
|
|
330
|
+
useInput(function(input, key) {
|
|
331
|
+
if (!isActive) return;
|
|
332
|
+
if (key.upArrow || input === 'k') {
|
|
333
|
+
onScrollChange(Math.max(0, scrollOffset - 1));
|
|
334
|
+
} else if (key.downArrow || input === 'j') {
|
|
335
|
+
onScrollChange(Math.min(maxScroll, scrollOffset + 1));
|
|
336
|
+
}
|
|
337
|
+
}, {
|
|
338
|
+
isActive: isActive
|
|
339
|
+
});
|
|
340
|
+
var visibleLines = lines.slice(scrollOffset, scrollOffset + maxLines);
|
|
341
|
+
var _getEventSymbol = getEventSymbol(stored.event), symbol = _getEventSymbol.symbol, color = _getEventSymbol.color;
|
|
342
|
+
return /*#__PURE__*/ React.createElement(Box, {
|
|
343
|
+
flexDirection: "column"
|
|
344
|
+
}, /*#__PURE__*/ React.createElement(Box, {
|
|
345
|
+
marginBottom: 1
|
|
346
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
347
|
+
color: color
|
|
348
|
+
}, symbol, " "), /*#__PURE__*/ React.createElement(Text, {
|
|
349
|
+
bold: true
|
|
350
|
+
}, stored.event.type), /*#__PURE__*/ React.createElement(Text, {
|
|
351
|
+
dimColor: true
|
|
352
|
+
}, " • ", formatFullTimestamp(stored.timestamp))), /*#__PURE__*/ React.createElement(Box, {
|
|
353
|
+
flexDirection: "column",
|
|
354
|
+
marginLeft: 2
|
|
355
|
+
}, visibleLines.map(function(line, i) {
|
|
356
|
+
return /*#__PURE__*/ React.createElement(Text, {
|
|
357
|
+
key: scrollOffset + i
|
|
358
|
+
}, line);
|
|
359
|
+
})), totalLines > maxLines && /*#__PURE__*/ React.createElement(Box, {
|
|
360
|
+
marginTop: 1
|
|
361
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
362
|
+
dimColor: true
|
|
363
|
+
}, "Lines ", scrollOffset + 1, "-", Math.min(scrollOffset + maxLines, totalLines), " of ", totalLines)));
|
|
364
|
+
};
|
|
@@ -1,6 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
9
|
+
function _iterable_to_array_limit(arr, i) {
|
|
10
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
11
|
+
if (_i == null) return;
|
|
12
|
+
var _arr = [];
|
|
13
|
+
var _n = true;
|
|
14
|
+
var _d = false;
|
|
15
|
+
var _s, _e;
|
|
16
|
+
try {
|
|
17
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
18
|
+
_arr.push(_s.value);
|
|
19
|
+
if (i && _arr.length === i) break;
|
|
20
|
+
}
|
|
21
|
+
} catch (err) {
|
|
22
|
+
_d = true;
|
|
23
|
+
_e = err;
|
|
24
|
+
} finally{
|
|
25
|
+
try {
|
|
26
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
27
|
+
} finally{
|
|
28
|
+
if (_d) throw _e;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return _arr;
|
|
32
|
+
}
|
|
33
|
+
function _non_iterable_rest() {
|
|
34
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
35
|
+
}
|
|
36
|
+
function _sliced_to_array(arr, i) {
|
|
37
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
38
|
+
}
|
|
39
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
40
|
+
if (!o) return;
|
|
41
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
42
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
43
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
44
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
45
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
46
|
+
}
|
|
47
|
+
import React, { useState, useEffect } from 'react';
|
|
48
|
+
import { Text, Box, useStdout, useInput } from 'ink';
|
|
3
49
|
import { BRAIN_EVENTS } from '@positronic/core';
|
|
50
|
+
import { EventDetail } from './event-detail.js';
|
|
4
51
|
// Format relative timestamp
|
|
5
52
|
function formatTimestamp(timestamp) {
|
|
6
53
|
var now = Date.now();
|
|
@@ -32,12 +79,6 @@ function formatEvent(event) {
|
|
|
32
79
|
text: 'Brain started: "'.concat(event.brainTitle, '"'),
|
|
33
80
|
color: 'yellow'
|
|
34
81
|
};
|
|
35
|
-
case BRAIN_EVENTS.RESTART:
|
|
36
|
-
return {
|
|
37
|
-
symbol: '[>>]',
|
|
38
|
-
text: 'Brain restarted: "'.concat(event.brainTitle, '"'),
|
|
39
|
-
color: 'yellow'
|
|
40
|
-
};
|
|
41
82
|
case BRAIN_EVENTS.COMPLETE:
|
|
42
83
|
return {
|
|
43
84
|
symbol: '[ok]',
|
|
@@ -102,7 +143,8 @@ function formatEvent(event) {
|
|
|
102
143
|
return {
|
|
103
144
|
symbol: '[#]',
|
|
104
145
|
text: "Agent iteration ".concat(event.iteration),
|
|
105
|
-
color: 'gray'
|
|
146
|
+
color: 'gray',
|
|
147
|
+
tokens: event.tokensThisIteration
|
|
106
148
|
};
|
|
107
149
|
case BRAIN_EVENTS.AGENT_TOOL_CALL:
|
|
108
150
|
return {
|
|
@@ -125,14 +167,23 @@ function formatEvent(event) {
|
|
|
125
167
|
case BRAIN_EVENTS.AGENT_COMPLETE:
|
|
126
168
|
return {
|
|
127
169
|
symbol: '[A]',
|
|
128
|
-
text: 'Agent completed: "'.concat(event.terminalToolName, '" (').concat(event.totalIterations, "
|
|
129
|
-
color: 'green'
|
|
170
|
+
text: 'Agent completed: "'.concat(event.terminalToolName, '" (').concat(event.totalIterations, " iter)"),
|
|
171
|
+
color: 'green',
|
|
172
|
+
tokens: event.totalTokens
|
|
130
173
|
};
|
|
131
174
|
case BRAIN_EVENTS.AGENT_TOKEN_LIMIT:
|
|
132
175
|
return {
|
|
133
176
|
symbol: '[!]',
|
|
134
177
|
text: "Token limit reached: ".concat(event.totalTokens, "/").concat(event.maxTokens),
|
|
135
|
-
color: 'red'
|
|
178
|
+
color: 'red',
|
|
179
|
+
tokens: event.totalTokens
|
|
180
|
+
};
|
|
181
|
+
case BRAIN_EVENTS.AGENT_ITERATION_LIMIT:
|
|
182
|
+
return {
|
|
183
|
+
symbol: '[!]',
|
|
184
|
+
text: "Iteration limit reached: ".concat(event.iteration, "/").concat(event.maxIterations),
|
|
185
|
+
color: 'red',
|
|
186
|
+
tokens: event.totalTokens
|
|
136
187
|
};
|
|
137
188
|
case BRAIN_EVENTS.AGENT_WEBHOOK:
|
|
138
189
|
return {
|
|
@@ -140,6 +191,24 @@ function formatEvent(event) {
|
|
|
140
191
|
text: "Agent webhook: ".concat(event.toolName),
|
|
141
192
|
color: 'cyan'
|
|
142
193
|
};
|
|
194
|
+
case BRAIN_EVENTS.AGENT_RAW_RESPONSE_MESSAGE:
|
|
195
|
+
return {
|
|
196
|
+
symbol: '[~]',
|
|
197
|
+
text: "Agent response (iteration ".concat(event.iteration, ")"),
|
|
198
|
+
color: 'gray'
|
|
199
|
+
};
|
|
200
|
+
case BRAIN_EVENTS.PAUSED:
|
|
201
|
+
return {
|
|
202
|
+
symbol: '[||]',
|
|
203
|
+
text: 'Brain paused: "'.concat(event.brainTitle, '"'),
|
|
204
|
+
color: 'cyan'
|
|
205
|
+
};
|
|
206
|
+
case BRAIN_EVENTS.RESUMED:
|
|
207
|
+
return {
|
|
208
|
+
symbol: '[>]',
|
|
209
|
+
text: 'Brain resumed: "'.concat(event.brainTitle, '"'),
|
|
210
|
+
color: 'green'
|
|
211
|
+
};
|
|
143
212
|
default:
|
|
144
213
|
return {
|
|
145
214
|
symbol: '[?]',
|
|
@@ -148,36 +217,163 @@ function formatEvent(event) {
|
|
|
148
217
|
};
|
|
149
218
|
}
|
|
150
219
|
}
|
|
220
|
+
// Calculate visible window with selection support
|
|
221
|
+
function calculateVisibleWindow(eventsLength, selectedIndex, maxVisible) {
|
|
222
|
+
if (selectedIndex === null) {
|
|
223
|
+
// Auto-scroll: show most recent
|
|
224
|
+
return {
|
|
225
|
+
start: Math.max(0, eventsLength - maxVisible),
|
|
226
|
+
end: eventsLength
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
// Keep selection centered when possible
|
|
230
|
+
var half = Math.floor(maxVisible / 2);
|
|
231
|
+
var start = Math.max(0, selectedIndex - half);
|
|
232
|
+
var end = Math.min(eventsLength, start + maxVisible);
|
|
233
|
+
// Adjust if we hit the end
|
|
234
|
+
if (end === eventsLength) {
|
|
235
|
+
start = Math.max(0, end - maxVisible);
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
start: start,
|
|
239
|
+
end: end
|
|
240
|
+
};
|
|
241
|
+
}
|
|
151
242
|
var EventLine = function(param) {
|
|
152
|
-
var stored = param.stored;
|
|
153
|
-
var _formatEvent = formatEvent(stored.event), symbol = _formatEvent.symbol, text = _formatEvent.text, color = _formatEvent.color;
|
|
243
|
+
var stored = param.stored, isSelected = param.isSelected;
|
|
244
|
+
var _formatEvent = formatEvent(stored.event), symbol = _formatEvent.symbol, text = _formatEvent.text, color = _formatEvent.color, tokens = _formatEvent.tokens;
|
|
154
245
|
var timestamp = formatTimestamp(stored.timestamp);
|
|
155
246
|
return /*#__PURE__*/ React.createElement(Box, null, /*#__PURE__*/ React.createElement(Text, {
|
|
247
|
+
color: isSelected ? 'cyan' : undefined
|
|
248
|
+
}, isSelected ? '› ' : ' '), /*#__PURE__*/ React.createElement(Text, {
|
|
156
249
|
dimColor: true
|
|
157
250
|
}, timestamp.padEnd(12), " "), /*#__PURE__*/ React.createElement(Text, {
|
|
158
|
-
color: color
|
|
159
|
-
}, symbol, " "), /*#__PURE__*/ React.createElement(Text,
|
|
251
|
+
color: isSelected ? 'cyan' : color
|
|
252
|
+
}, symbol, " "), /*#__PURE__*/ React.createElement(Text, {
|
|
253
|
+
color: isSelected ? 'cyan' : undefined
|
|
254
|
+
}, text), tokens !== undefined && /*#__PURE__*/ React.createElement(Text, {
|
|
255
|
+
dimColor: true
|
|
256
|
+
}, " (", tokens.toLocaleString(), " tokens)"));
|
|
160
257
|
};
|
|
161
258
|
export var EventsView = function(param) {
|
|
162
|
-
var events = param.events;
|
|
259
|
+
var events = param.events, _param_totalTokens = param.totalTokens, totalTokens = _param_totalTokens === void 0 ? 0 : _param_totalTokens, _param_isActive = param.isActive, isActive = _param_isActive === void 0 ? true : _param_isActive, onModeChange = param.onModeChange, onViewState = param.onViewState, controlledSelectedIndex = param.selectedIndex, onSelectedIndexChange = param.onSelectedIndexChange;
|
|
163
260
|
var stdout = useStdout().stdout;
|
|
164
261
|
var terminalHeight = (stdout === null || stdout === void 0 ? void 0 : stdout.rows) || 24;
|
|
165
|
-
// Reserve lines for header, footer, margins
|
|
166
|
-
var maxVisible = Math.max(5, terminalHeight -
|
|
167
|
-
|
|
168
|
-
var
|
|
262
|
+
// Reserve lines for header, footer, margins, token total
|
|
263
|
+
var maxVisible = Math.max(5, terminalHeight - 8);
|
|
264
|
+
var _useState = _sliced_to_array(useState('list'), 2), mode = _useState[0], setMode = _useState[1];
|
|
265
|
+
var _useState1 = _sliced_to_array(useState(null), 2), internalSelectedIndex = _useState1[0], setInternalSelectedIndex = _useState1[1];
|
|
266
|
+
var _useState2 = _sliced_to_array(useState(0), 2), scrollOffset = _useState2[0], setScrollOffset = _useState2[1];
|
|
267
|
+
// Use controlled value if provided, otherwise use internal state
|
|
268
|
+
var isControlled = controlledSelectedIndex !== undefined;
|
|
269
|
+
var selectedIndex = isControlled ? controlledSelectedIndex : internalSelectedIndex;
|
|
270
|
+
var setSelectedIndex = function(index) {
|
|
271
|
+
if (isControlled) {
|
|
272
|
+
onSelectedIndexChange === null || onSelectedIndexChange === void 0 ? void 0 : onSelectedIndexChange(index);
|
|
273
|
+
} else {
|
|
274
|
+
setInternalSelectedIndex(index);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
// Notify parent of mode changes
|
|
278
|
+
useEffect(function() {
|
|
279
|
+
if (onModeChange) {
|
|
280
|
+
if (mode === 'detail') {
|
|
281
|
+
onModeChange('detail');
|
|
282
|
+
} else if (selectedIndex !== null) {
|
|
283
|
+
onModeChange('navigating');
|
|
284
|
+
} else {
|
|
285
|
+
onModeChange('auto');
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}, [
|
|
289
|
+
mode,
|
|
290
|
+
selectedIndex,
|
|
291
|
+
onModeChange
|
|
292
|
+
]);
|
|
293
|
+
// Keep selection valid when events change
|
|
294
|
+
useEffect(function() {
|
|
295
|
+
if (selectedIndex !== null && events.length > 0) {
|
|
296
|
+
if (selectedIndex >= events.length) {
|
|
297
|
+
setSelectedIndex(events.length - 1);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}, [
|
|
301
|
+
events.length,
|
|
302
|
+
selectedIndex
|
|
303
|
+
]);
|
|
304
|
+
// Keyboard handling
|
|
305
|
+
useInput(function(input, key) {
|
|
306
|
+
if (!isActive) return;
|
|
307
|
+
if (mode === 'list') {
|
|
308
|
+
if (key.upArrow || input === 'k') {
|
|
309
|
+
if (selectedIndex === null) {
|
|
310
|
+
// First navigation: start from last event
|
|
311
|
+
if (events.length > 0) {
|
|
312
|
+
setSelectedIndex(events.length - 1);
|
|
313
|
+
}
|
|
314
|
+
} else if (selectedIndex > 0) {
|
|
315
|
+
setSelectedIndex(selectedIndex - 1);
|
|
316
|
+
}
|
|
317
|
+
} else if (key.downArrow || input === 'j') {
|
|
318
|
+
if (selectedIndex === null) {
|
|
319
|
+
if (events.length > 0) {
|
|
320
|
+
setSelectedIndex(events.length - 1);
|
|
321
|
+
}
|
|
322
|
+
} else if (selectedIndex < events.length - 1) {
|
|
323
|
+
setSelectedIndex(selectedIndex + 1);
|
|
324
|
+
}
|
|
325
|
+
} else if (key.return && selectedIndex !== null && events.length > 0) {
|
|
326
|
+
setMode('detail');
|
|
327
|
+
setScrollOffset(0);
|
|
328
|
+
} else if (input === 's' && selectedIndex !== null && onViewState) {
|
|
329
|
+
// View state at selected event
|
|
330
|
+
onViewState(selectedIndex);
|
|
331
|
+
} else if (key.escape && selectedIndex !== null) {
|
|
332
|
+
// Return to auto-scroll mode
|
|
333
|
+
setSelectedIndex(null);
|
|
334
|
+
}
|
|
335
|
+
} else if (mode === 'detail') {
|
|
336
|
+
// Escape or 'b' to go back to list
|
|
337
|
+
if (key.escape || input === 'b') {
|
|
338
|
+
setMode('list');
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}, {
|
|
342
|
+
isActive: isActive
|
|
343
|
+
});
|
|
344
|
+
// Detail view
|
|
345
|
+
if (mode === 'detail' && selectedIndex !== null && events[selectedIndex]) {
|
|
346
|
+
return /*#__PURE__*/ React.createElement(EventDetail, {
|
|
347
|
+
stored: events[selectedIndex],
|
|
348
|
+
scrollOffset: scrollOffset,
|
|
349
|
+
onScrollChange: setScrollOffset,
|
|
350
|
+
isActive: isActive
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// List view
|
|
354
|
+
var _calculateVisibleWindow = calculateVisibleWindow(events.length, selectedIndex, maxVisible), start = _calculateVisibleWindow.start, end = _calculateVisibleWindow.end;
|
|
355
|
+
var visibleEvents = events.slice(start, end);
|
|
169
356
|
return /*#__PURE__*/ React.createElement(Box, {
|
|
170
357
|
flexDirection: "column"
|
|
171
358
|
}, /*#__PURE__*/ React.createElement(Box, {
|
|
172
359
|
marginBottom: 1
|
|
173
360
|
}, /*#__PURE__*/ React.createElement(Text, {
|
|
174
361
|
bold: true
|
|
175
|
-
}, "Events (", events.length, " total)")
|
|
362
|
+
}, "Events (", events.length, " total)"), selectedIndex !== null && /*#__PURE__*/ React.createElement(Text, {
|
|
363
|
+
dimColor: true
|
|
364
|
+
}, " • Selected: ", selectedIndex + 1)), visibleEvents.length === 0 ? /*#__PURE__*/ React.createElement(Text, {
|
|
176
365
|
dimColor: true
|
|
177
366
|
}, "Waiting for events...") : visibleEvents.map(function(stored, index) {
|
|
178
367
|
return /*#__PURE__*/ React.createElement(EventLine, {
|
|
179
|
-
key: index,
|
|
180
|
-
stored: stored
|
|
368
|
+
key: start + index,
|
|
369
|
+
stored: stored,
|
|
370
|
+
isSelected: selectedIndex === start + index
|
|
181
371
|
});
|
|
182
|
-
})
|
|
372
|
+
}), totalTokens > 0 && /*#__PURE__*/ React.createElement(Box, {
|
|
373
|
+
marginTop: 1
|
|
374
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
375
|
+
dimColor: true
|
|
376
|
+
}, "Total tokens: "), /*#__PURE__*/ React.createElement(Text, {
|
|
377
|
+
bold: true
|
|
378
|
+
}, totalTokens.toLocaleString())));
|
|
183
379
|
};
|