@robota-sdk/agent-command 3.0.0-beta.70 → 3.0.0-beta.71
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/node/index.cjs +32 -32
- package/dist/node/index.js +33 -33
- package/dist/node/index.js.map +1 -1
- package/package.json +3 -3
- package/src/background/__tests__/background-command-module.test.ts +1 -0
- package/src/compact/__tests__/compact-command-module.test.ts +1 -0
- package/src/context/__tests__/context-command-module.test.ts +1 -0
- package/src/context/context-command.ts +92 -56
- package/src/help/__tests__/help-command-module.test.ts +1 -0
- package/src/help/__tests__/help-command.test.ts +1 -0
- package/src/plugin/__tests__/plugin-command-module.test.ts +1 -0
- package/src/session/__tests__/session-command-module.test.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-command",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.71",
|
|
4
4
|
"description": "Consolidated command module implementations for Robota SDK CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"src"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
28
|
-
"@robota-sdk/agent-framework": "3.0.0-beta.
|
|
27
|
+
"@robota-sdk/agent-core": "3.0.0-beta.71",
|
|
28
|
+
"@robota-sdk/agent-framework": "3.0.0-beta.71"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.14.0",
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
writeAutoCompactThresholdSetting,
|
|
13
13
|
} from '@robota-sdk/agent-framework';
|
|
14
14
|
|
|
15
|
-
import type { IHistoryEntry } from '@robota-sdk/agent-core';
|
|
15
|
+
import type { IHistoryEntry, TUniversalMessage } from '@robota-sdk/agent-core';
|
|
16
16
|
import type {
|
|
17
17
|
ICommandHostContext,
|
|
18
18
|
ICommandResult,
|
|
@@ -65,14 +65,14 @@ export async function executeContextCommand(
|
|
|
65
65
|
const autoCompactThreshold = readAutoCompactThreshold(context);
|
|
66
66
|
const autoCompactThresholdSource = readAutoCompactThresholdSource(context);
|
|
67
67
|
const history = context.getSession().getFullHistory();
|
|
68
|
-
const
|
|
68
|
+
const display = buildToolDisplayList(history);
|
|
69
69
|
const references = listCommandContextReferences(context);
|
|
70
70
|
return {
|
|
71
71
|
message: [
|
|
72
72
|
`Context: ${state.usedTokens.toLocaleString()} / ${state.maxTokens.toLocaleString()} tokens (${Math.round(state.usedPercentage)}%)`,
|
|
73
73
|
formatAutoCompactLine(autoCompactThreshold, autoCompactThresholdSource),
|
|
74
74
|
formatContextReferenceSummary(references),
|
|
75
|
-
`History: ${
|
|
75
|
+
`History: ${display.turnCount} turn${display.turnCount !== 1 ? 's' : ''}`,
|
|
76
76
|
].join('\n'),
|
|
77
77
|
success: true,
|
|
78
78
|
data: {
|
|
@@ -304,19 +304,25 @@ function formatContextReferenceLine(reference: IContextReferenceItem): string {
|
|
|
304
304
|
interface IToolResultSummary {
|
|
305
305
|
toolName: string;
|
|
306
306
|
displayArg: string;
|
|
307
|
-
tokens: number;
|
|
308
307
|
}
|
|
309
308
|
|
|
310
|
-
interface
|
|
311
|
-
|
|
312
|
-
userCount: number;
|
|
309
|
+
interface IMessageTokensByRole {
|
|
310
|
+
systemTokens: number;
|
|
313
311
|
userTokens: number;
|
|
314
|
-
|
|
312
|
+
userCount: number;
|
|
315
313
|
assistantTokens: number;
|
|
316
|
-
|
|
314
|
+
assistantCount: number;
|
|
315
|
+
toolTokens: number;
|
|
316
|
+
toolCallCount: number;
|
|
317
317
|
totalTokens: number;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
interface IToolDisplayList {
|
|
321
|
+
turnCount: number;
|
|
322
|
+
toolResults: IToolResultSummary[];
|
|
323
|
+
totalToolCallCount: number;
|
|
324
|
+
}
|
|
325
|
+
|
|
320
326
|
function parseToolCallArgs(argsJson: string): Record<string, unknown> | null {
|
|
321
327
|
try {
|
|
322
328
|
return JSON.parse(argsJson) as Record<string, unknown>;
|
|
@@ -334,7 +340,44 @@ function extractFirstToolArg(argsJson: string): string {
|
|
|
334
340
|
return raw.length > TOOL_ARG_MAX_LEN ? `${raw.slice(0, TOOL_ARG_MAX_LEN)}…` : raw;
|
|
335
341
|
}
|
|
336
342
|
|
|
337
|
-
function
|
|
343
|
+
function computeMessageTokensByRole(rawMessages: TUniversalMessage[]): IMessageTokensByRole {
|
|
344
|
+
let systemTokens = 0;
|
|
345
|
+
let userTokens = 0;
|
|
346
|
+
let userCount = 0;
|
|
347
|
+
let assistantTokens = 0;
|
|
348
|
+
let assistantCount = 0;
|
|
349
|
+
let toolTokens = 0;
|
|
350
|
+
let toolCallCount = 0;
|
|
351
|
+
|
|
352
|
+
for (const msg of rawMessages) {
|
|
353
|
+
const t = Math.ceil(JSON.stringify(msg).length / CHARS_PER_TOKEN);
|
|
354
|
+
if (msg.role === 'system') {
|
|
355
|
+
systemTokens += t;
|
|
356
|
+
} else if (msg.role === 'user') {
|
|
357
|
+
userTokens += t;
|
|
358
|
+
userCount++;
|
|
359
|
+
} else if (msg.role === 'assistant') {
|
|
360
|
+
assistantTokens += t;
|
|
361
|
+
assistantCount++;
|
|
362
|
+
} else if (msg.role === 'tool') {
|
|
363
|
+
toolTokens += t;
|
|
364
|
+
toolCallCount++;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return {
|
|
369
|
+
systemTokens,
|
|
370
|
+
userTokens,
|
|
371
|
+
userCount,
|
|
372
|
+
assistantTokens,
|
|
373
|
+
assistantCount,
|
|
374
|
+
toolTokens,
|
|
375
|
+
toolCallCount,
|
|
376
|
+
totalTokens: systemTokens + userTokens + assistantTokens + toolTokens,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function buildToolDisplayList(history: IHistoryEntry[]): IToolDisplayList {
|
|
338
381
|
type TToolCallEntry = { name: string; firstArg: string };
|
|
339
382
|
const toolCallMap = new Map<string, TToolCallEntry>();
|
|
340
383
|
|
|
@@ -351,44 +394,28 @@ function analyzeHistory(history: IHistoryEntry[]): IHistoryAnalysis {
|
|
|
351
394
|
}
|
|
352
395
|
}
|
|
353
396
|
|
|
354
|
-
let
|
|
355
|
-
let
|
|
356
|
-
|
|
357
|
-
let assistantTokens = 0;
|
|
358
|
-
const toolResultMap = new Map<string, IToolResultSummary>();
|
|
397
|
+
let turnCount = 0;
|
|
398
|
+
let totalToolCallCount = 0;
|
|
399
|
+
const toolDisplayMap = new Map<string, IToolResultSummary>();
|
|
359
400
|
|
|
360
401
|
for (const entry of history) {
|
|
361
402
|
if (entry.category !== 'chat') continue;
|
|
362
403
|
if (entry.type === 'user') {
|
|
363
|
-
|
|
364
|
-
userCount++;
|
|
365
|
-
userTokens += estimateTokens((data.content ?? '').length);
|
|
366
|
-
} else if (entry.type === 'assistant') {
|
|
367
|
-
const data = entry.data as { content?: string | null; toolCalls?: unknown[] };
|
|
368
|
-
assistantCount++;
|
|
369
|
-
assistantTokens += estimateTokens(
|
|
370
|
-
(data.content ?? '').length + (data.toolCalls ? JSON.stringify(data.toolCalls).length : 0),
|
|
371
|
-
);
|
|
404
|
+
turnCount++;
|
|
372
405
|
} else if (entry.type === 'tool') {
|
|
373
|
-
const data = entry.data as {
|
|
406
|
+
const data = entry.data as { toolCallId?: string };
|
|
374
407
|
const tc = toolCallMap.get(data.toolCallId ?? '');
|
|
375
408
|
const toolName = tc?.name ?? 'tool';
|
|
376
409
|
const displayArg = tc?.firstArg ?? '';
|
|
377
|
-
|
|
378
|
-
|
|
410
|
+
totalToolCallCount++;
|
|
411
|
+
toolDisplayMap.set(`${toolName}:${displayArg}`, { toolName, displayArg });
|
|
379
412
|
}
|
|
380
413
|
}
|
|
381
414
|
|
|
382
|
-
const toolResults = [...toolResultMap.values()];
|
|
383
|
-
const toolTokens = toolResults.reduce((s, t) => s + t.tokens, 0);
|
|
384
415
|
return {
|
|
385
|
-
turnCount
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
assistantCount,
|
|
389
|
-
assistantTokens,
|
|
390
|
-
toolResults,
|
|
391
|
-
totalTokens: userTokens + assistantTokens + toolTokens,
|
|
416
|
+
turnCount,
|
|
417
|
+
toolResults: [...toolDisplayMap.values()],
|
|
418
|
+
totalToolCallCount,
|
|
392
419
|
};
|
|
393
420
|
}
|
|
394
421
|
|
|
@@ -406,44 +433,53 @@ function formatFullContextBreakdown(context: ICommandHostContext): ICommandResul
|
|
|
406
433
|
const state = readCommandContextState(context);
|
|
407
434
|
const autoCompactThreshold = readAutoCompactThreshold(context);
|
|
408
435
|
const autoCompactThresholdSource = readAutoCompactThresholdSource(context);
|
|
409
|
-
const
|
|
410
|
-
const
|
|
436
|
+
const rawMessages = context.getSession().getHistory();
|
|
437
|
+
const msgTokens = computeMessageTokensByRole(rawMessages);
|
|
438
|
+
const display = buildToolDisplayList(context.getSession().getFullHistory());
|
|
411
439
|
const references = listCommandContextReferences(context);
|
|
412
440
|
|
|
413
441
|
const systemRefs = references.filter((r) => r.loadType === 'system');
|
|
414
442
|
const manualRefs = references.filter((r) => r.loadType === 'manual');
|
|
415
443
|
const promptRefs = references.filter((r) => r.loadType === 'prompt-reference');
|
|
416
444
|
|
|
417
|
-
const
|
|
445
|
+
const systemRefTokens = systemRefs.reduce((s, r) => s + estimateTokens(r.byteLength), 0);
|
|
418
446
|
const manualTokens = manualRefs.reduce((s, r) => s + estimateTokens(r.byteLength), 0);
|
|
419
447
|
const promptRefTokens = promptRefs.reduce((s, r) => s + estimateTokens(r.byteLength), 0);
|
|
420
448
|
|
|
421
449
|
const convTurnLabel =
|
|
422
|
-
|
|
450
|
+
display.turnCount === 0
|
|
423
451
|
? 'Conversation history — 0 turns'
|
|
424
|
-
: `Conversation history — ${
|
|
452
|
+
: `Conversation history — ${display.turnCount} turn${display.turnCount !== 1 ? 's' : ''} | ~${msgTokens.totalTokens.toLocaleString()} tokens`;
|
|
425
453
|
|
|
426
|
-
const toolResultLines =
|
|
427
|
-
(t) =>
|
|
428
|
-
`${t.toolName}${t.displayArg ? `: ${t.displayArg}` : ''} — ~${t.tokens.toLocaleString()} tokens`,
|
|
454
|
+
const toolResultLines = display.toolResults.map(
|
|
455
|
+
(t) => `${t.toolName}${t.displayArg ? `: ${t.displayArg}` : ''}`,
|
|
429
456
|
);
|
|
430
457
|
|
|
458
|
+
const uniqueToolCount = display.toolResults.length;
|
|
459
|
+
const totalToolCallCount = display.totalToolCallCount;
|
|
460
|
+
const toolResultsLabel =
|
|
461
|
+
totalToolCallCount === 0
|
|
462
|
+
? 'Tool results (0): (none)'
|
|
463
|
+
: uniqueToolCount < totalToolCallCount
|
|
464
|
+
? `Tool results (${uniqueToolCount} unique / ${totalToolCallCount} calls, ~${msgTokens.toolTokens.toLocaleString()} tokens):`
|
|
465
|
+
: `Tool results (${uniqueToolCount}, ~${msgTokens.toolTokens.toLocaleString()} tokens):`;
|
|
466
|
+
|
|
431
467
|
const conversationLines: string[] =
|
|
432
|
-
|
|
468
|
+
display.turnCount === 0
|
|
433
469
|
? []
|
|
434
470
|
: [
|
|
435
|
-
`User (${
|
|
436
|
-
`Assistant (${
|
|
437
|
-
|
|
438
|
-
? [
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
:
|
|
471
|
+
`User (${msgTokens.userCount}): ~${msgTokens.userTokens.toLocaleString()} tokens`,
|
|
472
|
+
`Assistant (${msgTokens.assistantCount}): ~${msgTokens.assistantTokens.toLocaleString()} tokens`,
|
|
473
|
+
...(msgTokens.systemTokens > 0
|
|
474
|
+
? [`System messages: ~${msgTokens.systemTokens.toLocaleString()} tokens`]
|
|
475
|
+
: []),
|
|
476
|
+
totalToolCallCount > 0
|
|
477
|
+
? [toolResultsLabel, ...toolResultLines.map((l) => ` ${l}`)].join('\n')
|
|
478
|
+
: toolResultsLabel,
|
|
443
479
|
];
|
|
444
480
|
|
|
445
481
|
const convSection =
|
|
446
|
-
|
|
482
|
+
display.turnCount === 0
|
|
447
483
|
? `${convTurnLabel}:\n (none)`
|
|
448
484
|
: [`${convTurnLabel}:`, ...conversationLines.map((l) => ` ${l}`)].join('\n');
|
|
449
485
|
|
|
@@ -453,7 +489,7 @@ function formatFullContextBreakdown(context: ICommandHostContext): ICommandResul
|
|
|
453
489
|
'',
|
|
454
490
|
formatSection(
|
|
455
491
|
'System prompt (active every turn)',
|
|
456
|
-
|
|
492
|
+
systemRefTokens,
|
|
457
493
|
systemRefs.map(formatContextReferenceLine),
|
|
458
494
|
),
|
|
459
495
|
'',
|
|
@@ -473,7 +509,7 @@ function formatFullContextBreakdown(context: ICommandHostContext): ICommandResul
|
|
|
473
509
|
message,
|
|
474
510
|
data: {
|
|
475
511
|
references,
|
|
476
|
-
history: { turnCount:
|
|
512
|
+
history: { turnCount: display.turnCount, toolResults: display.toolResults },
|
|
477
513
|
},
|
|
478
514
|
};
|
|
479
515
|
}
|