@ai-setting/roy-agent-cli 1.7.19 → 1.7.21
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/bin/roy-agent.js +988 -115
- package/dist/index.js +988 -115
- package/dist/roy-agent-linux-x64/bin/roy-agent +2 -2
- package/package.json +1 -1
package/dist/bin/roy-agent.js
CHANGED
|
@@ -360,6 +360,97 @@ var init_markdown_renderer = __esm(() => {
|
|
|
360
360
|
], MarkdownRenderer.prototype, "push", null);
|
|
361
361
|
});
|
|
362
362
|
|
|
363
|
+
// src/services/stdout-batcher.ts
|
|
364
|
+
function createStdoutBatcher(options = {}) {
|
|
365
|
+
const flushIntervalMs = options.flushIntervalMs ?? 16;
|
|
366
|
+
const maxBufferBytes = options.maxBufferBytes ?? 4096;
|
|
367
|
+
const writeFn = options.writeFn ?? ((chunk) => {
|
|
368
|
+
process.stdout.write(chunk);
|
|
369
|
+
return true;
|
|
370
|
+
});
|
|
371
|
+
const onFlush = options.onFlush;
|
|
372
|
+
let buffer = "";
|
|
373
|
+
let queuedWrites = 0;
|
|
374
|
+
let timer = null;
|
|
375
|
+
let totalBatches = 0;
|
|
376
|
+
let totalWrites = 0;
|
|
377
|
+
let totalBytes = 0;
|
|
378
|
+
let lastBatchWrites = 0;
|
|
379
|
+
function performFlush() {
|
|
380
|
+
if (buffer.length === 0)
|
|
381
|
+
return;
|
|
382
|
+
const chunk = buffer;
|
|
383
|
+
buffer = "";
|
|
384
|
+
lastBatchWrites = queuedWrites;
|
|
385
|
+
queuedWrites = 0;
|
|
386
|
+
totalBatches += 1;
|
|
387
|
+
totalBytes += chunk.length;
|
|
388
|
+
writeFn(chunk);
|
|
389
|
+
if (onFlush) {
|
|
390
|
+
onFlush({
|
|
391
|
+
writesInLastBatch: lastBatchWrites,
|
|
392
|
+
totalBatches,
|
|
393
|
+
totalBytes
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
function scheduleFlush() {
|
|
398
|
+
if (timer !== null)
|
|
399
|
+
return;
|
|
400
|
+
timer = setTimeout(() => {
|
|
401
|
+
timer = null;
|
|
402
|
+
performFlush();
|
|
403
|
+
}, flushIntervalMs);
|
|
404
|
+
}
|
|
405
|
+
function maybeForceFlush() {
|
|
406
|
+
if (buffer.length >= maxBufferBytes) {
|
|
407
|
+
if (timer !== null) {
|
|
408
|
+
clearTimeout(timer);
|
|
409
|
+
timer = null;
|
|
410
|
+
}
|
|
411
|
+
performFlush();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function write(chunk) {
|
|
415
|
+
if (chunk.length === 0)
|
|
416
|
+
return;
|
|
417
|
+
buffer += chunk;
|
|
418
|
+
queuedWrites += 1;
|
|
419
|
+
totalWrites += 1;
|
|
420
|
+
scheduleFlush();
|
|
421
|
+
maybeForceFlush();
|
|
422
|
+
}
|
|
423
|
+
function flushNow() {
|
|
424
|
+
if (timer !== null) {
|
|
425
|
+
clearTimeout(timer);
|
|
426
|
+
timer = null;
|
|
427
|
+
}
|
|
428
|
+
performFlush();
|
|
429
|
+
}
|
|
430
|
+
function cancel() {
|
|
431
|
+
if (timer !== null) {
|
|
432
|
+
clearTimeout(timer);
|
|
433
|
+
timer = null;
|
|
434
|
+
}
|
|
435
|
+
buffer = "";
|
|
436
|
+
queuedWrites = 0;
|
|
437
|
+
}
|
|
438
|
+
function getStats() {
|
|
439
|
+
return {
|
|
440
|
+
batches: totalBatches,
|
|
441
|
+
queuedWrites: totalWrites,
|
|
442
|
+
totalBytes,
|
|
443
|
+
writesInLastBatch: lastBatchWrites
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
write,
|
|
448
|
+
flushNow,
|
|
449
|
+
cancel,
|
|
450
|
+
getStats
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
363
454
|
// src/services/stream-output.service.ts
|
|
364
455
|
var exports_stream_output_service = {};
|
|
365
456
|
__export(exports_stream_output_service, {
|
|
@@ -370,14 +461,26 @@ __export(exports_stream_output_service, {
|
|
|
370
461
|
COLORS: () => COLORS
|
|
371
462
|
});
|
|
372
463
|
import chalk2 from "chalk";
|
|
373
|
-
import {
|
|
464
|
+
import {
|
|
465
|
+
createLogger as createLogger2,
|
|
466
|
+
TracedAs as TracedAs2,
|
|
467
|
+
wrapFunction
|
|
468
|
+
} from "@ai-setting/roy-agent-core";
|
|
469
|
+
function isStdoutBatchEnabled() {
|
|
470
|
+
const v = process.env.ROY_AGENT_BATCH_STDOUT;
|
|
471
|
+
if (v === undefined)
|
|
472
|
+
return true;
|
|
473
|
+
if (v === "0" || v === "false" || v === "no")
|
|
474
|
+
return false;
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
374
477
|
function resetStreamAbort() {
|
|
375
478
|
streamAbortSignal.aborted = false;
|
|
376
479
|
}
|
|
377
480
|
function abortStream() {
|
|
378
481
|
streamAbortSignal.aborted = true;
|
|
379
482
|
}
|
|
380
|
-
var logger2, COLORS, streamAbortSignal, StreamOutputService;
|
|
483
|
+
var logger2, COLORS, emitBatchFlushSpanImpl = (stats) => {}, emitBatchFlushSpan, emitSilentModeSkippedSpanImpl = (textLength) => {}, emitSilentModeSkippedSpan, streamAbortSignal, StreamOutputService;
|
|
381
484
|
var init_stream_output_service = __esm(() => {
|
|
382
485
|
init_markdown_renderer();
|
|
383
486
|
logger2 = createLogger2("stream-output");
|
|
@@ -397,6 +500,28 @@ var init_stream_output_service = __esm(() => {
|
|
|
397
500
|
error: chalk2.red,
|
|
398
501
|
progress: chalk2.dim
|
|
399
502
|
};
|
|
503
|
+
emitBatchFlushSpan = wrapFunction(emitBatchFlushSpanImpl, "cli.stream-output.writeStdout-batched", {
|
|
504
|
+
recordParams: true,
|
|
505
|
+
recordResult: false,
|
|
506
|
+
log: false,
|
|
507
|
+
paramFilter: (args) => {
|
|
508
|
+
const s = args[0] ?? {};
|
|
509
|
+
return {
|
|
510
|
+
writesInLastBatch: s.writesInLastBatch ?? 0,
|
|
511
|
+
totalBatches: s.batches ?? 0,
|
|
512
|
+
totalBytes: s.totalBytes ?? 0
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
emitSilentModeSkippedSpan = wrapFunction(emitSilentModeSkippedSpanImpl, "stream-output.silent-mode-skipped", {
|
|
517
|
+
recordParams: true,
|
|
518
|
+
recordResult: false,
|
|
519
|
+
log: false,
|
|
520
|
+
paramFilter: (args) => ({
|
|
521
|
+
"text.length": typeof args[0] === "number" ? args[0] : 0,
|
|
522
|
+
reason: "silent=true (Ink mode)"
|
|
523
|
+
})
|
|
524
|
+
});
|
|
400
525
|
streamAbortSignal = {
|
|
401
526
|
aborted: false
|
|
402
527
|
};
|
|
@@ -415,6 +540,7 @@ var init_stream_output_service = __esm(() => {
|
|
|
415
540
|
reasoningClosedByText = false;
|
|
416
541
|
chunkCallback = undefined;
|
|
417
542
|
silent = false;
|
|
543
|
+
stdoutBatcher = null;
|
|
418
544
|
constructor(options = {}) {
|
|
419
545
|
this.options = options;
|
|
420
546
|
this.silent = options.silent ?? false;
|
|
@@ -439,9 +565,33 @@ var init_stream_output_service = __esm(() => {
|
|
|
439
565
|
}
|
|
440
566
|
}
|
|
441
567
|
writeStdout(text) {
|
|
442
|
-
if (this.silent)
|
|
568
|
+
if (this.silent) {
|
|
569
|
+
emitSilentModeSkippedSpan(text.length);
|
|
443
570
|
return;
|
|
444
|
-
|
|
571
|
+
}
|
|
572
|
+
if (!isStdoutBatchEnabled()) {
|
|
573
|
+
process.stdout.write(text);
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
if (this.stdoutBatcher === null) {
|
|
577
|
+
this.stdoutBatcher = createStdoutBatcher({
|
|
578
|
+
flushIntervalMs: 16,
|
|
579
|
+
onFlush: (stats) => {
|
|
580
|
+
emitBatchFlushSpan(stats);
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
this.stdoutBatcher.write(text);
|
|
585
|
+
}
|
|
586
|
+
flushStdout() {
|
|
587
|
+
if (this.stdoutBatcher !== null) {
|
|
588
|
+
this.stdoutBatcher.flushNow();
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
cancelStdout() {
|
|
592
|
+
if (this.stdoutBatcher !== null) {
|
|
593
|
+
this.stdoutBatcher.cancel();
|
|
594
|
+
}
|
|
445
595
|
}
|
|
446
596
|
logStdout(message) {
|
|
447
597
|
if (this.silent)
|
|
@@ -686,8 +836,60 @@ ${COLORS.system("[已中断]")}
|
|
|
686
836
|
this.reasoningStarted = false;
|
|
687
837
|
this.reasoningClosedByText = false;
|
|
688
838
|
this.thinkingPrinted = false;
|
|
839
|
+
this.flushStdout();
|
|
689
840
|
}
|
|
690
841
|
};
|
|
842
|
+
__legacyDecorateClassTS([
|
|
843
|
+
TracedAs2("cli.stream-output.writeStdout", {
|
|
844
|
+
recordParams: true,
|
|
845
|
+
recordResult: false,
|
|
846
|
+
log: false,
|
|
847
|
+
paramFilter: (args) => ({
|
|
848
|
+
"text.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
849
|
+
"text.head": typeof args[0] === "string" ? args[0].slice(0, 32) : "",
|
|
850
|
+
"text.tail": typeof args[0] === "string" ? args[0].slice(-32) : "",
|
|
851
|
+
"batch.enabled": isStdoutBatchEnabled() ? 1 : 0
|
|
852
|
+
})
|
|
853
|
+
}),
|
|
854
|
+
__legacyMetadataTS("design:type", Function),
|
|
855
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
856
|
+
String
|
|
857
|
+
]),
|
|
858
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
859
|
+
], StreamOutputService.prototype, "writeStdout", null);
|
|
860
|
+
__legacyDecorateClassTS([
|
|
861
|
+
TracedAs2("stream.handle-event", {
|
|
862
|
+
recordParams: true,
|
|
863
|
+
recordResult: false,
|
|
864
|
+
paramFilter: (args) => {
|
|
865
|
+
const e = args[0] ?? {};
|
|
866
|
+
const payload = e.payload ?? {};
|
|
867
|
+
return {
|
|
868
|
+
"event.type": e.type ?? "unknown",
|
|
869
|
+
"event.payload.kind": payload && typeof payload === "object" ? Object.keys(payload).join(",") : ""
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
}),
|
|
873
|
+
__legacyMetadataTS("design:type", Function),
|
|
874
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
875
|
+
typeof EnvEvent === "undefined" ? Object : EnvEvent
|
|
876
|
+
]),
|
|
877
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
878
|
+
], StreamOutputService.prototype, "handleEvent", null);
|
|
879
|
+
__legacyDecorateClassTS([
|
|
880
|
+
TracedAs2("stream.handle-start", {
|
|
881
|
+
recordParams: true,
|
|
882
|
+
recordResult: false,
|
|
883
|
+
paramFilter: (args) => ({
|
|
884
|
+
model: args[0]?.metadata?.model ?? ""
|
|
885
|
+
})
|
|
886
|
+
}),
|
|
887
|
+
__legacyMetadataTS("design:type", Function),
|
|
888
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
889
|
+
Object
|
|
890
|
+
]),
|
|
891
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
892
|
+
], StreamOutputService.prototype, "handleStart", null);
|
|
691
893
|
__legacyDecorateClassTS([
|
|
692
894
|
TracedAs2("stream.handle-text", {
|
|
693
895
|
recordParams: true,
|
|
@@ -703,6 +905,102 @@ ${COLORS.system("[已中断]")}
|
|
|
703
905
|
]),
|
|
704
906
|
__legacyMetadataTS("design:returntype", undefined)
|
|
705
907
|
], StreamOutputService.prototype, "handleText", null);
|
|
908
|
+
__legacyDecorateClassTS([
|
|
909
|
+
TracedAs2("stream.handle-reasoning", {
|
|
910
|
+
recordParams: true,
|
|
911
|
+
recordResult: false,
|
|
912
|
+
paramFilter: (args) => ({
|
|
913
|
+
"delta.length": args[0]?.delta?.length ?? 0,
|
|
914
|
+
"content.length": args[0]?.content?.length ?? 0,
|
|
915
|
+
phase: args[0]?.phase ?? ""
|
|
916
|
+
})
|
|
917
|
+
}),
|
|
918
|
+
__legacyMetadataTS("design:type", Function),
|
|
919
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
920
|
+
Object
|
|
921
|
+
]),
|
|
922
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
923
|
+
], StreamOutputService.prototype, "handleReasoning", null);
|
|
924
|
+
__legacyDecorateClassTS([
|
|
925
|
+
TracedAs2("stream.handle-tool-call", {
|
|
926
|
+
recordParams: true,
|
|
927
|
+
recordResult: false,
|
|
928
|
+
log: true,
|
|
929
|
+
paramFilter: (args) => {
|
|
930
|
+
const p = args[0] ?? {};
|
|
931
|
+
return {
|
|
932
|
+
"tool.name": p.name ?? "unknown",
|
|
933
|
+
"tool.id": p.id ?? "",
|
|
934
|
+
"tool.args.keys": p.arguments ? Object.keys(p.arguments).join(",") : ""
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
}),
|
|
938
|
+
__legacyMetadataTS("design:type", Function),
|
|
939
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
940
|
+
Object
|
|
941
|
+
]),
|
|
942
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
943
|
+
], StreamOutputService.prototype, "handleToolCall", null);
|
|
944
|
+
__legacyDecorateClassTS([
|
|
945
|
+
TracedAs2("stream.handle-tool-result", {
|
|
946
|
+
recordParams: true,
|
|
947
|
+
recordResult: false,
|
|
948
|
+
log: true,
|
|
949
|
+
paramFilter: (args) => {
|
|
950
|
+
const p = args[0] ?? {};
|
|
951
|
+
const result = p.result?.output ?? p.result?.error;
|
|
952
|
+
return {
|
|
953
|
+
"tool.name": p.name ?? "unknown",
|
|
954
|
+
"tool.result.kind": result !== undefined ? typeof result : "none",
|
|
955
|
+
"tool.result.preview": typeof result === "string" ? result.substring(0, 80) : typeof result === "object" && result !== null ? JSON.stringify(result).substring(0, 80) : ""
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
}),
|
|
959
|
+
__legacyMetadataTS("design:type", Function),
|
|
960
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
961
|
+
Object
|
|
962
|
+
]),
|
|
963
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
964
|
+
], StreamOutputService.prototype, "handleToolResult", null);
|
|
965
|
+
__legacyDecorateClassTS([
|
|
966
|
+
TracedAs2("stream.handle-tool-error", {
|
|
967
|
+
recordParams: true,
|
|
968
|
+
recordResult: false,
|
|
969
|
+
log: true,
|
|
970
|
+
paramFilter: (args) => {
|
|
971
|
+
const p = args[0] ?? {};
|
|
972
|
+
return {
|
|
973
|
+
"tool.name": p.toolName ?? "unknown",
|
|
974
|
+
"tool.error.preview": typeof p.error === "string" ? p.error.substring(0, 120) : ""
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
}),
|
|
978
|
+
__legacyMetadataTS("design:type", Function),
|
|
979
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
980
|
+
Object
|
|
981
|
+
]),
|
|
982
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
983
|
+
], StreamOutputService.prototype, "handleToolError", null);
|
|
984
|
+
__legacyDecorateClassTS([
|
|
985
|
+
TracedAs2("stream.handle-completed", {
|
|
986
|
+
recordParams: true,
|
|
987
|
+
recordResult: false,
|
|
988
|
+
paramFilter: (args) => {
|
|
989
|
+
const meta = args[0]?.metadata;
|
|
990
|
+
return {
|
|
991
|
+
model: meta?.model ?? "",
|
|
992
|
+
"usage.promptTokens": meta?.usage?.promptTokens ?? 0,
|
|
993
|
+
"usage.completionTokens": meta?.usage?.completionTokens ?? 0,
|
|
994
|
+
"usage.totalTokens": meta?.usage?.totalTokens ?? 0
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
}),
|
|
998
|
+
__legacyMetadataTS("design:type", Function),
|
|
999
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
1000
|
+
Object
|
|
1001
|
+
]),
|
|
1002
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
1003
|
+
], StreamOutputService.prototype, "handleCompleted", null);
|
|
706
1004
|
});
|
|
707
1005
|
|
|
708
1006
|
// src/commands/ui/mascot/glasses-girl.ts
|
|
@@ -1091,6 +1389,7 @@ var init_slash_command_popup = __esm(() => {
|
|
|
1091
1389
|
// src/render/markdown.ts
|
|
1092
1390
|
import { Marked } from "marked";
|
|
1093
1391
|
import { highlight } from "cli-highlight";
|
|
1392
|
+
import { wrapFunction as wrapFunction2 } from "@ai-setting/roy-agent-core";
|
|
1094
1393
|
function setMarkdownEnabled(enabled) {
|
|
1095
1394
|
markdownEnabled = enabled;
|
|
1096
1395
|
}
|
|
@@ -1333,7 +1632,50 @@ function wrapLine(line, width) {
|
|
|
1333
1632
|
return out.join(`
|
|
1334
1633
|
`);
|
|
1335
1634
|
}
|
|
1336
|
-
function
|
|
1635
|
+
function cacheLookup(key) {
|
|
1636
|
+
for (let i = 0;i < renderCache.length; i++) {
|
|
1637
|
+
if (renderCache[i].key === key) {
|
|
1638
|
+
const entry = renderCache[i];
|
|
1639
|
+
if (i > 0) {
|
|
1640
|
+
renderCache.splice(i, 1);
|
|
1641
|
+
renderCache.unshift(entry);
|
|
1642
|
+
}
|
|
1643
|
+
return entry.value;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
function cacheInsert(key, value, text, width) {
|
|
1649
|
+
if (renderCache.length >= MAX_CACHE_ENTRIES) {
|
|
1650
|
+
renderCache.pop();
|
|
1651
|
+
}
|
|
1652
|
+
renderCache.unshift({ key, value, text, width });
|
|
1653
|
+
renderCacheStats.size = renderCache.length;
|
|
1654
|
+
}
|
|
1655
|
+
function findPrefixCacheEntry(text, width) {
|
|
1656
|
+
let best;
|
|
1657
|
+
let bestLen = -1;
|
|
1658
|
+
for (let i = 0;i < renderCache.length; i++) {
|
|
1659
|
+
const e = renderCache[i];
|
|
1660
|
+
if (e.width !== width)
|
|
1661
|
+
continue;
|
|
1662
|
+
if (e.text.length === 0)
|
|
1663
|
+
continue;
|
|
1664
|
+
if (text.startsWith(e.text) && e.text.length > bestLen) {
|
|
1665
|
+
best = e;
|
|
1666
|
+
bestLen = e.text.length;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
return best;
|
|
1670
|
+
}
|
|
1671
|
+
function isSuffixSafeToLexIndependently(suffix) {
|
|
1672
|
+
if (suffix.length === 0)
|
|
1673
|
+
return true;
|
|
1674
|
+
if (suffix.charCodeAt(0) !== 10)
|
|
1675
|
+
return true;
|
|
1676
|
+
return false;
|
|
1677
|
+
}
|
|
1678
|
+
function renderMarkdownImpl(text, options = {}) {
|
|
1337
1679
|
const width = options.width ?? 80;
|
|
1338
1680
|
if (!markdownEnabled) {
|
|
1339
1681
|
return wrapLine(text, width);
|
|
@@ -1341,6 +1683,28 @@ function renderMarkdown(text, options = {}) {
|
|
|
1341
1683
|
if (!text || text.trim() === "") {
|
|
1342
1684
|
return "";
|
|
1343
1685
|
}
|
|
1686
|
+
const key = text + "\x00" + width;
|
|
1687
|
+
const cached = cacheLookup(key);
|
|
1688
|
+
if (cached !== undefined) {
|
|
1689
|
+
renderCacheStats.hits++;
|
|
1690
|
+
renderCacheStats.cachedHits++;
|
|
1691
|
+
return cached;
|
|
1692
|
+
}
|
|
1693
|
+
const prefixEntry = findPrefixCacheEntry(text, width);
|
|
1694
|
+
if (prefixEntry !== undefined) {
|
|
1695
|
+
const suffix = text.slice(prefixEntry.text.length);
|
|
1696
|
+
if (isSuffixSafeToLexIndependently(suffix)) {
|
|
1697
|
+
const suffixRender = renderMarkdownImpl(suffix, { width });
|
|
1698
|
+
const combined = prefixEntry.value + suffixRender;
|
|
1699
|
+
cacheInsert(key, combined, text, width);
|
|
1700
|
+
renderCacheStats.hits++;
|
|
1701
|
+
renderCacheStats.prefixHits++;
|
|
1702
|
+
renderCacheStats.partialParses++;
|
|
1703
|
+
return combined;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
renderCacheStats.misses++;
|
|
1707
|
+
renderCacheStats.partialParses++;
|
|
1344
1708
|
let tokens;
|
|
1345
1709
|
try {
|
|
1346
1710
|
tokens = marked.lexer(text);
|
|
@@ -1354,9 +1718,11 @@ function renderMarkdown(text, options = {}) {
|
|
|
1354
1718
|
lines.push(block);
|
|
1355
1719
|
}
|
|
1356
1720
|
}
|
|
1357
|
-
|
|
1721
|
+
const result = lines.join(`
|
|
1358
1722
|
|
|
1359
1723
|
`);
|
|
1724
|
+
cacheInsert(key, result, text, width);
|
|
1725
|
+
return result;
|
|
1360
1726
|
}
|
|
1361
1727
|
function truncateForTerminal(text, maxLines) {
|
|
1362
1728
|
if (maxLines <= 0) {
|
|
@@ -1452,7 +1818,7 @@ function tailTruncateToRows(line, rows, width) {
|
|
|
1452
1818
|
const tail = segments.join("");
|
|
1453
1819
|
return tail + ANSI2.reset;
|
|
1454
1820
|
}
|
|
1455
|
-
var ANSI2, DEFAULT_THEME, markdownEnabled = true, marked, ANSI_CSI_RE;
|
|
1821
|
+
var ANSI2, DEFAULT_THEME, markdownEnabled = true, marked, MAX_CACHE_ENTRIES = 32, renderCache, renderCacheStats, renderMarkdown, ANSI_CSI_RE;
|
|
1456
1822
|
var init_markdown = __esm(() => {
|
|
1457
1823
|
ANSI2 = {
|
|
1458
1824
|
reset: "\x1B[0m",
|
|
@@ -1494,6 +1860,32 @@ var init_markdown = __esm(() => {
|
|
|
1494
1860
|
breaks: false,
|
|
1495
1861
|
pedantic: false
|
|
1496
1862
|
});
|
|
1863
|
+
renderCache = [];
|
|
1864
|
+
renderCacheStats = {
|
|
1865
|
+
hits: 0,
|
|
1866
|
+
prefixHits: 0,
|
|
1867
|
+
misses: 0,
|
|
1868
|
+
partialParses: 0,
|
|
1869
|
+
cachedHits: 0,
|
|
1870
|
+
size: 0
|
|
1871
|
+
};
|
|
1872
|
+
renderMarkdown = wrapFunction2(renderMarkdownImpl, "markdown.render", {
|
|
1873
|
+
recordParams: true,
|
|
1874
|
+
recordResult: true,
|
|
1875
|
+
paramFilter: (args) => ({
|
|
1876
|
+
"input.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
1877
|
+
"options.width": typeof args[1]?.width === "number" ? args[1].width : 0
|
|
1878
|
+
}),
|
|
1879
|
+
resultFilter: (result) => ({
|
|
1880
|
+
"output.length": typeof result === "string" ? result.length : 0,
|
|
1881
|
+
"cache.hits": renderCacheStats.hits,
|
|
1882
|
+
"cache.prefixHits": renderCacheStats.prefixHits,
|
|
1883
|
+
"cache.misses": renderCacheStats.misses,
|
|
1884
|
+
"cache.partialParses": renderCacheStats.partialParses,
|
|
1885
|
+
"cache.size": renderCacheStats.size
|
|
1886
|
+
}),
|
|
1887
|
+
log: false
|
|
1888
|
+
});
|
|
1497
1889
|
ANSI_CSI_RE = /\u001b\[[0-9;?]*[ -/]*[@-~]/g;
|
|
1498
1890
|
});
|
|
1499
1891
|
|
|
@@ -9461,7 +9853,7 @@ class CliQuietModeService {
|
|
|
9461
9853
|
// package.json
|
|
9462
9854
|
var package_default = {
|
|
9463
9855
|
name: "@ai-setting/roy-agent-cli",
|
|
9464
|
-
version: "1.7.
|
|
9856
|
+
version: "1.7.21",
|
|
9465
9857
|
type: "module",
|
|
9466
9858
|
description: "CLI for roy-agent - Non-interactive command execution",
|
|
9467
9859
|
main: "./dist/index.js",
|
|
@@ -10616,6 +11008,21 @@ function finalizeActStdout(args) {
|
|
|
10616
11008
|
output.log(result);
|
|
10617
11009
|
}
|
|
10618
11010
|
|
|
11011
|
+
// src/commands/shared/debug-trace.ts
|
|
11012
|
+
function printTraceIdAfterResponse(traceId, options) {
|
|
11013
|
+
const enabled = typeof options === "boolean" ? options : options.enabled;
|
|
11014
|
+
if (!enabled)
|
|
11015
|
+
return;
|
|
11016
|
+
const writer = typeof options === "object" && options.write ? options.write : (chunk) => process.stderr.write(chunk);
|
|
11017
|
+
writer(`[Trace] ${traceId}
|
|
11018
|
+
`);
|
|
11019
|
+
if (typeof options === "object" && typeof options.tuiSink === "function") {
|
|
11020
|
+
try {
|
|
11021
|
+
options.tuiSink(traceId);
|
|
11022
|
+
} catch (_tuiErr) {}
|
|
11023
|
+
}
|
|
11024
|
+
}
|
|
11025
|
+
|
|
10619
11026
|
// src/commands/act.ts
|
|
10620
11027
|
function detectWorkspaceRoot(cwd = process.cwd(), runGit = execFileSync) {
|
|
10621
11028
|
try {
|
|
@@ -10683,6 +11090,10 @@ function createActCommand(externalEnvService) {
|
|
|
10683
11090
|
describe: "附加图片到消息(可多次传入;支持本地路径 / http(s) URL / data:base64)",
|
|
10684
11091
|
type: "array",
|
|
10685
11092
|
string: true
|
|
11093
|
+
}).option("debug-on", {
|
|
11094
|
+
describe: "调试模式:响应结束后输出 [Trace] <traceId>(stderr),便于追踪调用 trace",
|
|
11095
|
+
type: "boolean",
|
|
11096
|
+
default: false
|
|
10686
11097
|
}),
|
|
10687
11098
|
async handler(args) {
|
|
10688
11099
|
const quiet = args.quiet ?? true;
|
|
@@ -10919,9 +11330,6 @@ function createActCommand(externalEnvService) {
|
|
|
10919
11330
|
}
|
|
10920
11331
|
});
|
|
10921
11332
|
const traceId = rootSpan.spanContext.traceId;
|
|
10922
|
-
if (!quiet) {
|
|
10923
|
-
output.info(`[Trace] ${traceId}`);
|
|
10924
|
-
}
|
|
10925
11333
|
provider.setGlobalContext(rootSpan.spanContext);
|
|
10926
11334
|
const contextHandler = new ContextHandlerService(env, sessionComponent, { maxRetries: 1, autoCompact: true });
|
|
10927
11335
|
const context = {
|
|
@@ -10956,6 +11364,7 @@ function createActCommand(externalEnvService) {
|
|
|
10956
11364
|
streamService,
|
|
10957
11365
|
output
|
|
10958
11366
|
});
|
|
11367
|
+
printTraceIdAfterResponse(traceId, args.debugOn ?? false);
|
|
10959
11368
|
if (!quiet) {
|
|
10960
11369
|
if (isWorkflowPausedActResult(result)) {
|
|
10961
11370
|
output.warn("工作流已暂停,等待用户输入(见上方 resume 提示)");
|
|
@@ -11274,6 +11683,35 @@ class QueryExecutor {
|
|
|
11274
11683
|
}
|
|
11275
11684
|
}
|
|
11276
11685
|
}
|
|
11686
|
+
__legacyDecorateClassTS([
|
|
11687
|
+
TracedAs4("cli.query-executor.setChunkCallback", {
|
|
11688
|
+
recordParams: true,
|
|
11689
|
+
recordResult: false,
|
|
11690
|
+
log: true,
|
|
11691
|
+
paramFilter: (args) => ({
|
|
11692
|
+
"cb.isFunction": typeof args[0] === "function"
|
|
11693
|
+
})
|
|
11694
|
+
}),
|
|
11695
|
+
__legacyMetadataTS("design:type", Function),
|
|
11696
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
11697
|
+
typeof StreamChunkCallback === "undefined" ? Object : StreamChunkCallback
|
|
11698
|
+
]),
|
|
11699
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
11700
|
+
], QueryExecutor.prototype, "setChunkCallback", null);
|
|
11701
|
+
__legacyDecorateClassTS([
|
|
11702
|
+
TracedAs4("cli.query-executor.handleEvent", {
|
|
11703
|
+
recordParams: true,
|
|
11704
|
+
recordResult: false,
|
|
11705
|
+
paramFilter: (args) => ({
|
|
11706
|
+
"event.type": args[0]?.type ?? "unknown"
|
|
11707
|
+
})
|
|
11708
|
+
}),
|
|
11709
|
+
__legacyMetadataTS("design:type", Function),
|
|
11710
|
+
__legacyMetadataTS("design:paramtypes", [
|
|
11711
|
+
Object
|
|
11712
|
+
]),
|
|
11713
|
+
__legacyMetadataTS("design:returntype", undefined)
|
|
11714
|
+
], QueryExecutor.prototype, "handleEvent", null);
|
|
11277
11715
|
__legacyDecorateClassTS([
|
|
11278
11716
|
TracedAs4("cli.query-executor.execute", { recordParams: true, log: true }),
|
|
11279
11717
|
__legacyMetadataTS("design:type", Function),
|
|
@@ -11700,6 +12138,16 @@ class EventHandler {
|
|
|
11700
12138
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
11701
12139
|
}
|
|
11702
12140
|
}
|
|
12141
|
+
__legacyDecorateClassTS([
|
|
12142
|
+
TracedAs5("cli.event-handler.start", {
|
|
12143
|
+
recordParams: false,
|
|
12144
|
+
recordResult: false,
|
|
12145
|
+
log: true
|
|
12146
|
+
}),
|
|
12147
|
+
__legacyMetadataTS("design:type", Function),
|
|
12148
|
+
__legacyMetadataTS("design:paramtypes", []),
|
|
12149
|
+
__legacyMetadataTS("design:returntype", Function)
|
|
12150
|
+
], EventHandler.prototype, "start", null);
|
|
11703
12151
|
__legacyDecorateClassTS([
|
|
11704
12152
|
TracedAs5("cli.event-handler.handleEvent", { recordParams: true }),
|
|
11705
12153
|
__legacyMetadataTS("design:type", Function),
|
|
@@ -11708,6 +12156,16 @@ __legacyDecorateClassTS([
|
|
|
11708
12156
|
]),
|
|
11709
12157
|
__legacyMetadataTS("design:returntype", undefined)
|
|
11710
12158
|
], EventHandler.prototype, "handleEvent", null);
|
|
12159
|
+
__legacyDecorateClassTS([
|
|
12160
|
+
TracedAs5("cli.event-handler.processQueue", {
|
|
12161
|
+
recordParams: false,
|
|
12162
|
+
recordResult: false,
|
|
12163
|
+
log: true
|
|
12164
|
+
}),
|
|
12165
|
+
__legacyMetadataTS("design:type", Function),
|
|
12166
|
+
__legacyMetadataTS("design:paramtypes", []),
|
|
12167
|
+
__legacyMetadataTS("design:returntype", typeof Promise === "undefined" ? Object : Promise)
|
|
12168
|
+
], EventHandler.prototype, "processQueue", null);
|
|
11711
12169
|
|
|
11712
12170
|
// src/commands/shared/esc-active-descendant.ts
|
|
11713
12171
|
function hasActiveDescendants(env, parentSessionId) {
|
|
@@ -12654,8 +13112,23 @@ ${COLORS.system("[没有正在执行的请求]")}`);
|
|
|
12654
13112
|
onSubmit: async (input) => {
|
|
12655
13113
|
this.isExecuting = true;
|
|
12656
13114
|
inkApiRef?.setMode("executing");
|
|
13115
|
+
const inkTracerProvider = getTracerProvider3();
|
|
13116
|
+
const inkTracer = inkTracerProvider.getTracer("roy-tracer");
|
|
13117
|
+
const inkExistingContext = inkTracerProvider.getGlobalContext();
|
|
13118
|
+
let inkRootSpan;
|
|
13119
|
+
let inkTurnTraceId;
|
|
13120
|
+
if (inkExistingContext) {
|
|
13121
|
+
inkRootSpan = inkTracer.startSpan("interactive.execute", {
|
|
13122
|
+
parent: inkExistingContext
|
|
13123
|
+
});
|
|
13124
|
+
inkTurnTraceId = inkExistingContext.traceId;
|
|
13125
|
+
} else {
|
|
13126
|
+
inkRootSpan = inkTracer.startSpan("interactive.execute");
|
|
13127
|
+
inkTurnTraceId = inkRootSpan.spanContext.traceId;
|
|
13128
|
+
inkTracerProvider.setGlobalContext(inkRootSpan.spanContext);
|
|
13129
|
+
}
|
|
12657
13130
|
try {
|
|
12658
|
-
await this.options.onExecute(input);
|
|
13131
|
+
await this.options.onExecute(input, inkTurnTraceId, undefined);
|
|
12659
13132
|
inkApiRef?.setMode("ready");
|
|
12660
13133
|
if (this.options.onAfterExecute) {
|
|
12661
13134
|
try {
|
|
@@ -12670,6 +13143,26 @@ ${COLORS.system("[没有正在执行的请求]")}`);
|
|
|
12670
13143
|
inkApiRef?.appendMessage({ role: "system", content: `[Error] ${msg}` });
|
|
12671
13144
|
throw err;
|
|
12672
13145
|
} finally {
|
|
13146
|
+
try {
|
|
13147
|
+
printTraceIdAfterResponse(inkTurnTraceId, {
|
|
13148
|
+
enabled: this.options.debugOn ?? false,
|
|
13149
|
+
tuiSink: (traceId) => {
|
|
13150
|
+
inkApiRef?.appendMessage({
|
|
13151
|
+
role: "system",
|
|
13152
|
+
content: `\uD83D\uDD0D [Trace] ${traceId}`
|
|
13153
|
+
});
|
|
13154
|
+
}
|
|
13155
|
+
});
|
|
13156
|
+
} catch (traceErr) {
|
|
13157
|
+
logger5.warn("printTraceIdAfterResponse failed (ink path)", {
|
|
13158
|
+
error: String(traceErr)
|
|
13159
|
+
});
|
|
13160
|
+
}
|
|
13161
|
+
try {
|
|
13162
|
+
inkRootSpan.end();
|
|
13163
|
+
} catch (spanErr) {
|
|
13164
|
+
logger5.warn("inkRootSpan.end failed", { error: String(spanErr) });
|
|
13165
|
+
}
|
|
12673
13166
|
this.isExecuting = false;
|
|
12674
13167
|
}
|
|
12675
13168
|
},
|
|
@@ -12939,7 +13432,6 @@ ${COLORS.system("[通知2] ❯ " + message.replace(/\n/g, `
|
|
|
12939
13432
|
traceId = rootSpan.spanContext.traceId;
|
|
12940
13433
|
provider.setGlobalContext(rootSpan.spanContext);
|
|
12941
13434
|
}
|
|
12942
|
-
console.log(`${COLORS.system("[Trace] " + traceId)}`);
|
|
12943
13435
|
console.log(`${COLORS.progress("[thinking...]")}`);
|
|
12944
13436
|
try {
|
|
12945
13437
|
await this.options.onExecute(message, traceId, agentContext);
|
|
@@ -12962,6 +13454,7 @@ ${COLORS.error("❌ 执行失败: " + error)}
|
|
|
12962
13454
|
}
|
|
12963
13455
|
} finally {
|
|
12964
13456
|
rootSpan.end();
|
|
13457
|
+
printTraceIdAfterResponse(traceId, this.options.debugOn ?? false);
|
|
12965
13458
|
if (existingContext) {
|
|
12966
13459
|
provider.setGlobalContext(existingContext);
|
|
12967
13460
|
} else {
|
|
@@ -13302,6 +13795,10 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13302
13795
|
describe: "Default agent 名字(默认 Roy,可被覆盖)",
|
|
13303
13796
|
type: "string",
|
|
13304
13797
|
default: "Roy"
|
|
13798
|
+
}).option("debug-on", {
|
|
13799
|
+
describe: "调试模式:每次 turn 结束后输出 [Trace] <traceId>(stderr),便于追踪调用 trace",
|
|
13800
|
+
type: "boolean",
|
|
13801
|
+
default: false
|
|
13305
13802
|
}),
|
|
13306
13803
|
async handler(args) {
|
|
13307
13804
|
CliQuietModeService.getInstance().setQuiet(true);
|
|
@@ -13468,6 +13965,7 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13468
13965
|
model: args.model,
|
|
13469
13966
|
version: getPackageVersion(),
|
|
13470
13967
|
useInk,
|
|
13968
|
+
debugOn: args.debugOn ?? false,
|
|
13471
13969
|
onExecute: async (message, traceId, agentContext) => {
|
|
13472
13970
|
resetStreamAbort();
|
|
13473
13971
|
const preloadedPrompts = eventSourceSystemPrompts;
|
|
@@ -13642,15 +14140,16 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13642
14140
|
var InteractiveCommand = createInteractiveCommand();
|
|
13643
14141
|
|
|
13644
14142
|
// src/commands/run.ts
|
|
13645
|
-
import
|
|
14143
|
+
import React8 from "react";
|
|
13646
14144
|
import { render } from "ink";
|
|
13647
14145
|
|
|
13648
14146
|
// src/RunTui.tsx
|
|
13649
|
-
import { useState as useState6, useCallback as useCallback4, useRef as
|
|
13650
|
-
import { Box as
|
|
14147
|
+
import { useState as useState6, useCallback as useCallback4, useRef as useRef5, useEffect as useEffect7, useMemo as useMemo3 } from "react";
|
|
14148
|
+
import { Box as Box7, Text as Text9, useApp as useApp2 } from "ink";
|
|
13651
14149
|
|
|
13652
14150
|
// src/tui/App.tsx
|
|
13653
14151
|
init_Markdown();
|
|
14152
|
+
import React4, { useEffect as useEffect4, useRef as useRef2 } from "react";
|
|
13654
14153
|
import { Box as Box4, Static as Static2, Text as Text6 } from "ink";
|
|
13655
14154
|
|
|
13656
14155
|
// src/tui/Spinner.tsx
|
|
@@ -13689,12 +14188,45 @@ var Spinner = ({
|
|
|
13689
14188
|
// src/tui/App.tsx
|
|
13690
14189
|
init_StatusBar();
|
|
13691
14190
|
init_theme();
|
|
14191
|
+
import { wrapFunction as wrapFunction3 } from "@ai-setting/roy-agent-core";
|
|
13692
14192
|
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
13693
14193
|
var ROLE_PREFIX = {
|
|
13694
14194
|
user: "\uD83D\uDC64 You",
|
|
13695
14195
|
assistant: "\uD83E\uDD16 Agent",
|
|
13696
14196
|
tool: "\uD83D\uDD27 Tool"
|
|
13697
14197
|
};
|
|
14198
|
+
var emitAppRenderSpanImpl = (snapshot) => {};
|
|
14199
|
+
var emitAppRenderSpan = wrapFunction3(emitAppRenderSpanImpl, "tui.app.render", {
|
|
14200
|
+
recordParams: true,
|
|
14201
|
+
recordResult: false,
|
|
14202
|
+
log: true,
|
|
14203
|
+
paramFilter: (args) => {
|
|
14204
|
+
const s = args[0] ?? {};
|
|
14205
|
+
return {
|
|
14206
|
+
renderCount: s.renderCount ?? 0,
|
|
14207
|
+
historyLength: s.historyLength ?? 0,
|
|
14208
|
+
status: s.status ?? "unknown"
|
|
14209
|
+
};
|
|
14210
|
+
}
|
|
14211
|
+
});
|
|
14212
|
+
var emitRenderScheduledSpanImpl = (parentRenderCount) => {};
|
|
14213
|
+
var emitRenderScheduledSpan = wrapFunction3(emitRenderScheduledSpanImpl, "tui.app.render-scheduled", {
|
|
14214
|
+
recordParams: true,
|
|
14215
|
+
recordResult: false,
|
|
14216
|
+
log: false,
|
|
14217
|
+
paramFilter: (args) => ({
|
|
14218
|
+
parentRenderCount: args[0] ?? 0
|
|
14219
|
+
})
|
|
14220
|
+
});
|
|
14221
|
+
var emitRenderThrottledSpanImpl = (parentRenderCount) => {};
|
|
14222
|
+
var emitRenderThrottledSpan = wrapFunction3(emitRenderThrottledSpanImpl, "tui.app.render-throttled", {
|
|
14223
|
+
recordParams: true,
|
|
14224
|
+
recordResult: false,
|
|
14225
|
+
log: false,
|
|
14226
|
+
paramFilter: (args) => ({
|
|
14227
|
+
parentRenderCount: args[0] ?? 0
|
|
14228
|
+
})
|
|
14229
|
+
});
|
|
13698
14230
|
var RoleLabel = ({ role }) => {
|
|
13699
14231
|
const theme = getTheme();
|
|
13700
14232
|
const roleColor = role === "user" ? theme.user : role === "assistant" ? theme.assistant : theme.tool;
|
|
@@ -13762,10 +14294,18 @@ var App = ({
|
|
|
13762
14294
|
status,
|
|
13763
14295
|
model,
|
|
13764
14296
|
workdir,
|
|
13765
|
-
streamingText,
|
|
13766
14297
|
tokenCount
|
|
13767
14298
|
}) => {
|
|
13768
14299
|
const theme = getTheme();
|
|
14300
|
+
const renderCountRef = useRef2(0);
|
|
14301
|
+
renderCountRef.current += 1;
|
|
14302
|
+
useEffect4(() => {
|
|
14303
|
+
emitAppRenderSpan({
|
|
14304
|
+
renderCount: renderCountRef.current,
|
|
14305
|
+
historyLength: history.length,
|
|
14306
|
+
status
|
|
14307
|
+
});
|
|
14308
|
+
});
|
|
13769
14309
|
return /* @__PURE__ */ jsxDEV6(Box4, {
|
|
13770
14310
|
flexDirection: "column",
|
|
13771
14311
|
minHeight: 20,
|
|
@@ -13799,21 +14339,7 @@ var App = ({
|
|
|
13799
14339
|
label: "Agent is thinking..."
|
|
13800
14340
|
}, undefined, false, undefined, this)
|
|
13801
14341
|
}, undefined, false, undefined, this) : null,
|
|
13802
|
-
status === "streaming"
|
|
13803
|
-
flexDirection: "column",
|
|
13804
|
-
marginBottom: 1,
|
|
13805
|
-
children: [
|
|
13806
|
-
/* @__PURE__ */ jsxDEV6(RoleLabel, {
|
|
13807
|
-
role: "assistant"
|
|
13808
|
-
}, undefined, false, undefined, this),
|
|
13809
|
-
/* @__PURE__ */ jsxDEV6(Box4, {
|
|
13810
|
-
marginLeft: 2,
|
|
13811
|
-
children: /* @__PURE__ */ jsxDEV6(Markdown, {
|
|
13812
|
-
text: streamingText
|
|
13813
|
-
}, undefined, false, undefined, this)
|
|
13814
|
-
}, undefined, false, undefined, this)
|
|
13815
|
-
]
|
|
13816
|
-
}, undefined, true, undefined, this) : status === "streaming" ? /* @__PURE__ */ jsxDEV6(Box4, {
|
|
14342
|
+
status === "streaming" ? /* @__PURE__ */ jsxDEV6(Box4, {
|
|
13817
14343
|
marginBottom: 1,
|
|
13818
14344
|
children: /* @__PURE__ */ jsxDEV6(Spinner, {
|
|
13819
14345
|
label: "Generating response..."
|
|
@@ -13830,15 +14356,144 @@ var App = ({
|
|
|
13830
14356
|
]
|
|
13831
14357
|
}, undefined, true, undefined, this);
|
|
13832
14358
|
};
|
|
14359
|
+
function areAppPropsEqual(prev, next) {
|
|
14360
|
+
if (prev.status !== next.status)
|
|
14361
|
+
return false;
|
|
14362
|
+
if (prev.model !== next.model)
|
|
14363
|
+
return false;
|
|
14364
|
+
if (prev.workdir !== next.workdir)
|
|
14365
|
+
return false;
|
|
14366
|
+
if (prev.tokenCount !== next.tokenCount)
|
|
14367
|
+
return false;
|
|
14368
|
+
if (prev.history !== next.history)
|
|
14369
|
+
return false;
|
|
14370
|
+
return true;
|
|
14371
|
+
}
|
|
14372
|
+
var parentRenderCountRef = { current: 0 };
|
|
14373
|
+
var AppThrottledImpl = (props) => {
|
|
14374
|
+
parentRenderCountRef.current += 1;
|
|
14375
|
+
emitRenderScheduledSpan(parentRenderCountRef.current);
|
|
14376
|
+
return /* @__PURE__ */ jsxDEV6(App, {
|
|
14377
|
+
...props
|
|
14378
|
+
}, undefined, false, undefined, this);
|
|
14379
|
+
};
|
|
14380
|
+
var AppThrottled = React4.memo(AppThrottledImpl, areAppPropsEqual);
|
|
14381
|
+
AppThrottled.displayName = "App(throttled)";
|
|
14382
|
+
var lastMemoResult = null;
|
|
14383
|
+
var instrumentedAreEqual = (prev, next) => {
|
|
14384
|
+
const equal = areAppPropsEqual(prev, next);
|
|
14385
|
+
if (equal && lastMemoResult !== true) {
|
|
14386
|
+
emitRenderThrottledSpan(parentRenderCountRef.current);
|
|
14387
|
+
}
|
|
14388
|
+
lastMemoResult = equal;
|
|
14389
|
+
return equal;
|
|
14390
|
+
};
|
|
14391
|
+
var AppMemo = React4.memo(AppThrottledImpl, instrumentedAreEqual);
|
|
14392
|
+
AppMemo.displayName = "App(memo-throttled)";
|
|
14393
|
+
// src/tui/StreamingOverlay.tsx
|
|
14394
|
+
init_Markdown();
|
|
14395
|
+
import { useEffect as useEffect5, useRef as useRef3 } from "react";
|
|
14396
|
+
import { Box as Box5, Text as Text7 } from "ink";
|
|
14397
|
+
import { wrapFunction as wrapFunction4 } from "@ai-setting/roy-agent-core";
|
|
14398
|
+
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
14399
|
+
var emitOverlayRenderSpanImpl = (snapshot) => {};
|
|
14400
|
+
var emitOverlayRenderSpan = wrapFunction4(emitOverlayRenderSpanImpl, "streaming-overlay.render", {
|
|
14401
|
+
recordParams: true,
|
|
14402
|
+
recordResult: false,
|
|
14403
|
+
log: false,
|
|
14404
|
+
paramFilter: (args) => {
|
|
14405
|
+
const s = args[0] ?? {};
|
|
14406
|
+
return {
|
|
14407
|
+
renderCount: s.renderCount ?? 0,
|
|
14408
|
+
streamingTextLength: s.streamingTextLength ?? 0,
|
|
14409
|
+
status: s.status ?? "unknown"
|
|
14410
|
+
};
|
|
14411
|
+
}
|
|
14412
|
+
});
|
|
14413
|
+
var emitOverlayMarkdownSpanImpl = (snapshot) => {};
|
|
14414
|
+
var emitOverlayMarkdownSpan = wrapFunction4(emitOverlayMarkdownSpanImpl, "streaming-overlay.markdown-render", {
|
|
14415
|
+
recordParams: true,
|
|
14416
|
+
recordResult: false,
|
|
14417
|
+
log: false,
|
|
14418
|
+
paramFilter: (args) => {
|
|
14419
|
+
const s = args[0] ?? {};
|
|
14420
|
+
return {
|
|
14421
|
+
inputLength: s.inputLength ?? 0,
|
|
14422
|
+
renderCount: s.renderCount ?? 0
|
|
14423
|
+
};
|
|
14424
|
+
}
|
|
14425
|
+
});
|
|
14426
|
+
var StreamingOverlay = ({
|
|
14427
|
+
streamingText,
|
|
14428
|
+
status,
|
|
14429
|
+
markdownEnabled: markdownEnabled2,
|
|
14430
|
+
width
|
|
14431
|
+
}) => {
|
|
14432
|
+
const renderCountRef = useRef3(0);
|
|
14433
|
+
renderCountRef.current += 1;
|
|
14434
|
+
useEffect5(() => {
|
|
14435
|
+
emitOverlayRenderSpan({
|
|
14436
|
+
renderCount: renderCountRef.current,
|
|
14437
|
+
streamingTextLength: streamingText.length,
|
|
14438
|
+
status
|
|
14439
|
+
});
|
|
14440
|
+
});
|
|
14441
|
+
if (status === "thinking") {
|
|
14442
|
+
return /* @__PURE__ */ jsxDEV7(Box5, {
|
|
14443
|
+
marginBottom: 1,
|
|
14444
|
+
children: /* @__PURE__ */ jsxDEV7(Text7, {
|
|
14445
|
+
dimColor: true,
|
|
14446
|
+
children: "\uD83E\uDD14 thinking..."
|
|
14447
|
+
}, undefined, false, undefined, this)
|
|
14448
|
+
}, undefined, false, undefined, this);
|
|
14449
|
+
}
|
|
14450
|
+
if (status === "idle") {
|
|
14451
|
+
return null;
|
|
14452
|
+
}
|
|
14453
|
+
if (!streamingText) {
|
|
14454
|
+
return /* @__PURE__ */ jsxDEV7(Box5, {
|
|
14455
|
+
marginBottom: 1,
|
|
14456
|
+
children: /* @__PURE__ */ jsxDEV7(Text7, {
|
|
14457
|
+
dimColor: true,
|
|
14458
|
+
children: "⏳ generating response..."
|
|
14459
|
+
}, undefined, false, undefined, this)
|
|
14460
|
+
}, undefined, false, undefined, this);
|
|
14461
|
+
}
|
|
14462
|
+
const effectiveWidth = width ?? process.stdout.columns ?? 80;
|
|
14463
|
+
emitOverlayMarkdownSpan({
|
|
14464
|
+
inputLength: streamingText.length,
|
|
14465
|
+
renderCount: renderCountRef.current
|
|
14466
|
+
});
|
|
14467
|
+
return /* @__PURE__ */ jsxDEV7(Box5, {
|
|
14468
|
+
flexDirection: "column",
|
|
14469
|
+
marginBottom: 1,
|
|
14470
|
+
children: [
|
|
14471
|
+
/* @__PURE__ */ jsxDEV7(Text7, {
|
|
14472
|
+
bold: true,
|
|
14473
|
+
color: "cyan",
|
|
14474
|
+
children: "\uD83E\uDD16 Agent"
|
|
14475
|
+
}, undefined, false, undefined, this),
|
|
14476
|
+
/* @__PURE__ */ jsxDEV7(Box5, {
|
|
14477
|
+
marginLeft: 2,
|
|
14478
|
+
children: markdownEnabled2 ? /* @__PURE__ */ jsxDEV7(Markdown, {
|
|
14479
|
+
text: streamingText,
|
|
14480
|
+
width: effectiveWidth
|
|
14481
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV7(Text7, {
|
|
14482
|
+
children: streamingText
|
|
14483
|
+
}, undefined, false, undefined, this)
|
|
14484
|
+
}, undefined, false, undefined, this)
|
|
14485
|
+
]
|
|
14486
|
+
}, undefined, true, undefined, this);
|
|
14487
|
+
};
|
|
13833
14488
|
|
|
13834
14489
|
// src/tui/index.ts
|
|
13835
14490
|
init_Markdown();
|
|
13836
14491
|
init_StatusBar();
|
|
13837
14492
|
|
|
13838
14493
|
// src/tui/TextInput.tsx
|
|
13839
|
-
import { useEffect as
|
|
13840
|
-
import { Box as
|
|
13841
|
-
import { jsxDEV as
|
|
14494
|
+
import { useEffect as useEffect6, useState as useState4 } from "react";
|
|
14495
|
+
import { Box as Box6, Text as Text8, useInput as useInput3 } from "ink";
|
|
14496
|
+
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
13842
14497
|
var TextInput = ({
|
|
13843
14498
|
label,
|
|
13844
14499
|
prefix,
|
|
@@ -13850,7 +14505,7 @@ var TextInput = ({
|
|
|
13850
14505
|
const [value, setValue] = useState4("");
|
|
13851
14506
|
const [historyIndex, setHistoryIndex] = useState4(-1);
|
|
13852
14507
|
const [draft, setDraft] = useState4("");
|
|
13853
|
-
|
|
14508
|
+
useEffect6(() => {
|
|
13854
14509
|
setHistoryIndex(-1);
|
|
13855
14510
|
}, [history.length]);
|
|
13856
14511
|
useInput3((input, key) => {
|
|
@@ -13904,9 +14559,9 @@ var TextInput = ({
|
|
|
13904
14559
|
setValue((v) => v + input);
|
|
13905
14560
|
}
|
|
13906
14561
|
});
|
|
13907
|
-
return /* @__PURE__ */
|
|
14562
|
+
return /* @__PURE__ */ jsxDEV8(Box6, {
|
|
13908
14563
|
children: [
|
|
13909
|
-
/* @__PURE__ */
|
|
14564
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
13910
14565
|
bold: true,
|
|
13911
14566
|
color: "green",
|
|
13912
14567
|
children: [
|
|
@@ -13914,21 +14569,21 @@ var TextInput = ({
|
|
|
13914
14569
|
" "
|
|
13915
14570
|
]
|
|
13916
14571
|
}, undefined, true, undefined, this),
|
|
13917
|
-
/* @__PURE__ */
|
|
14572
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
13918
14573
|
bold: true,
|
|
13919
14574
|
children: [
|
|
13920
14575
|
label,
|
|
13921
14576
|
": "
|
|
13922
14577
|
]
|
|
13923
14578
|
}, undefined, true, undefined, this),
|
|
13924
|
-
/* @__PURE__ */
|
|
14579
|
+
/* @__PURE__ */ jsxDEV8(Text8, {
|
|
13925
14580
|
children: value
|
|
13926
14581
|
}, undefined, false, undefined, this),
|
|
13927
|
-
!value && placeholder ? /* @__PURE__ */
|
|
14582
|
+
!value && placeholder ? /* @__PURE__ */ jsxDEV8(Text8, {
|
|
13928
14583
|
dimColor: true,
|
|
13929
14584
|
children: placeholder
|
|
13930
14585
|
}, undefined, false, undefined, this) : null,
|
|
13931
|
-
historyIndex !== -1 ? /* @__PURE__ */
|
|
14586
|
+
historyIndex !== -1 ? /* @__PURE__ */ jsxDEV8(Text8, {
|
|
13932
14587
|
dimColor: true,
|
|
13933
14588
|
children: " (history)"
|
|
13934
14589
|
}, undefined, false, undefined, this) : null
|
|
@@ -13941,36 +14596,98 @@ init_theme();
|
|
|
13941
14596
|
init_welcome_card2();
|
|
13942
14597
|
|
|
13943
14598
|
// src/tui/use-streaming-accumulator.ts
|
|
13944
|
-
import { useCallback as useCallback3, useState as useState5 } from "react";
|
|
14599
|
+
import { useCallback as useCallback3, useRef as useRef4, useState as useState5 } from "react";
|
|
14600
|
+
import { wrapFunction as wrapFunction5 } from "@ai-setting/roy-agent-core";
|
|
13945
14601
|
function useStreamingAccumulator() {
|
|
13946
14602
|
const [status, setStatus] = useState5("idle");
|
|
13947
14603
|
const [streamingText, setStreamingText] = useState5("");
|
|
13948
|
-
const
|
|
14604
|
+
const appendCountRef = useRef4(0);
|
|
14605
|
+
const pendingBufferRef = useRef4("");
|
|
14606
|
+
const flushScheduledRef = useRef4(false);
|
|
14607
|
+
const flushBuffer = useCallback3(() => {
|
|
14608
|
+
flushScheduledRef.current = false;
|
|
14609
|
+
const buf = pendingBufferRef.current;
|
|
14610
|
+
if (buf.length === 0)
|
|
14611
|
+
return;
|
|
14612
|
+
pendingBufferRef.current = "";
|
|
14613
|
+
setStreamingText((prev) => prev + buf);
|
|
14614
|
+
}, []);
|
|
14615
|
+
const lastStatusRef = useRef4("idle");
|
|
14616
|
+
const startImpl = useCallback3(() => {
|
|
13949
14617
|
setStreamingText("");
|
|
13950
14618
|
setStatus("thinking");
|
|
14619
|
+
lastStatusRef.current = "thinking";
|
|
14620
|
+
appendCountRef.current = 0;
|
|
13951
14621
|
}, []);
|
|
13952
|
-
const
|
|
13953
|
-
|
|
13954
|
-
|
|
13955
|
-
|
|
13956
|
-
|
|
13957
|
-
|
|
14622
|
+
const appendImpl = useCallback3((chunk) => {
|
|
14623
|
+
pendingBufferRef.current += chunk;
|
|
14624
|
+
if (!flushScheduledRef.current) {
|
|
14625
|
+
flushScheduledRef.current = true;
|
|
14626
|
+
queueMicrotask(flushBuffer);
|
|
14627
|
+
}
|
|
14628
|
+
if (lastStatusRef.current !== "streaming") {
|
|
14629
|
+
setStatus("streaming");
|
|
14630
|
+
lastStatusRef.current = "streaming";
|
|
14631
|
+
}
|
|
14632
|
+
appendCountRef.current += 1;
|
|
14633
|
+
}, [flushBuffer]);
|
|
14634
|
+
const finishImpl = useCallback3(() => {
|
|
14635
|
+
if (pendingBufferRef.current.length > 0) {
|
|
14636
|
+
flushBuffer();
|
|
14637
|
+
}
|
|
13958
14638
|
let snapshot = "";
|
|
13959
14639
|
setStreamingText((prev) => {
|
|
13960
14640
|
snapshot = prev;
|
|
13961
14641
|
return "";
|
|
13962
14642
|
});
|
|
13963
|
-
return snapshot;
|
|
13964
|
-
}, []);
|
|
13965
|
-
const fail = useCallback3((_err) => {
|
|
13966
14643
|
setStatus("idle");
|
|
14644
|
+
lastStatusRef.current = "idle";
|
|
14645
|
+
return snapshot;
|
|
14646
|
+
}, [flushBuffer]);
|
|
14647
|
+
const failImpl = useCallback3((_err) => {
|
|
14648
|
+
if (pendingBufferRef.current.length > 0) {
|
|
14649
|
+
flushBuffer();
|
|
14650
|
+
}
|
|
13967
14651
|
let snapshot = "";
|
|
13968
14652
|
setStreamingText((prev) => {
|
|
13969
14653
|
snapshot = prev;
|
|
13970
14654
|
return "";
|
|
13971
14655
|
});
|
|
14656
|
+
setStatus("idle");
|
|
14657
|
+
lastStatusRef.current = "idle";
|
|
13972
14658
|
return snapshot;
|
|
13973
|
-
}, []);
|
|
14659
|
+
}, [flushBuffer]);
|
|
14660
|
+
const start = wrapFunction5(startImpl, "streaming.start", {
|
|
14661
|
+
recordParams: false,
|
|
14662
|
+
recordResult: false,
|
|
14663
|
+
log: true
|
|
14664
|
+
});
|
|
14665
|
+
const append = wrapFunction5(appendImpl, "streaming.append", {
|
|
14666
|
+
recordParams: true,
|
|
14667
|
+
recordResult: false,
|
|
14668
|
+
log: true,
|
|
14669
|
+
paramFilter: (args) => ({
|
|
14670
|
+
"chunk.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
14671
|
+
"chunk.head": typeof args[0] === "string" ? args[0].slice(0, 32) : "",
|
|
14672
|
+
"chunk.tail": typeof args[0] === "string" ? args[0].slice(-32) : ""
|
|
14673
|
+
})
|
|
14674
|
+
});
|
|
14675
|
+
const finish = wrapFunction5(finishImpl, "streaming.finish", {
|
|
14676
|
+
recordParams: false,
|
|
14677
|
+
recordResult: true,
|
|
14678
|
+
log: true,
|
|
14679
|
+
resultFilter: (result) => ({
|
|
14680
|
+
"snapshot.length": typeof result === "string" ? result.length : 0
|
|
14681
|
+
})
|
|
14682
|
+
});
|
|
14683
|
+
const fail = wrapFunction5(failImpl, "streaming.fail", {
|
|
14684
|
+
recordParams: true,
|
|
14685
|
+
recordResult: false,
|
|
14686
|
+
log: true,
|
|
14687
|
+
paramFilter: (args) => ({
|
|
14688
|
+
"err.message": args[0] instanceof Error ? args[0].message : String(args[0])
|
|
14689
|
+
})
|
|
14690
|
+
});
|
|
13974
14691
|
return { status, streamingText, start, append, finish, fail };
|
|
13975
14692
|
}
|
|
13976
14693
|
|
|
@@ -14050,7 +14767,8 @@ function dispatchSlashCommand(raw, ctx) {
|
|
|
14050
14767
|
}
|
|
14051
14768
|
|
|
14052
14769
|
// src/RunTui.tsx
|
|
14053
|
-
import {
|
|
14770
|
+
import { wrapFunction as wrapFunction6 } from "@ai-setting/roy-agent-core";
|
|
14771
|
+
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
14054
14772
|
var RunScreen = ({
|
|
14055
14773
|
handleQuery,
|
|
14056
14774
|
streamHandleQuery,
|
|
@@ -14068,17 +14786,17 @@ var RunScreen = ({
|
|
|
14068
14786
|
const stream = useStreamingAccumulator();
|
|
14069
14787
|
const status = stream.status;
|
|
14070
14788
|
const { exit } = useApp2();
|
|
14071
|
-
const userTurnCountRef =
|
|
14072
|
-
const assistantTurnCountRef =
|
|
14073
|
-
const isProcessingRef =
|
|
14074
|
-
const executeQueryRef =
|
|
14075
|
-
const historyIdRef =
|
|
14789
|
+
const userTurnCountRef = useRef5(0);
|
|
14790
|
+
const assistantTurnCountRef = useRef5(0);
|
|
14791
|
+
const isProcessingRef = useRef5(0);
|
|
14792
|
+
const executeQueryRef = useRef5(null);
|
|
14793
|
+
const historyIdRef = useRef5(0);
|
|
14076
14794
|
const width = process.stdout.columns ?? 80;
|
|
14077
14795
|
const doExit = useCallback4(() => {
|
|
14078
14796
|
onExit?.();
|
|
14079
14797
|
exit();
|
|
14080
14798
|
}, [onExit, exit]);
|
|
14081
|
-
const
|
|
14799
|
+
const executeQueryImpl = useCallback4(async (message) => {
|
|
14082
14800
|
isProcessingRef.current += 1;
|
|
14083
14801
|
stream.start();
|
|
14084
14802
|
try {
|
|
@@ -14110,13 +14828,24 @@ var RunScreen = ({
|
|
|
14110
14828
|
isProcessingRef.current -= 1;
|
|
14111
14829
|
}
|
|
14112
14830
|
}, [handleQuery, markdownEnabled2, maxLines, stream, streamHandleQuery, width]);
|
|
14113
|
-
|
|
14831
|
+
const executeQuery = useMemo3(() => wrapFunction6(executeQueryImpl, "tui.run-tui.executeQuery", {
|
|
14832
|
+
recordParams: true,
|
|
14833
|
+
recordResult: false,
|
|
14834
|
+
log: true,
|
|
14835
|
+
paramFilter: (args) => ({
|
|
14836
|
+
"message.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
14837
|
+
"message.head": typeof args[0] === "string" ? args[0].slice(0, 60) : "",
|
|
14838
|
+
"isProcessingRef.before": (isProcessingRef.current ?? 0) + 1,
|
|
14839
|
+
streaming: !!streamHandleQuery
|
|
14840
|
+
})
|
|
14841
|
+
}), [executeQueryImpl, streamHandleQuery]);
|
|
14842
|
+
useEffect7(() => {
|
|
14114
14843
|
executeQueryRef.current = executeQuery;
|
|
14115
14844
|
}, [executeQuery]);
|
|
14116
|
-
|
|
14845
|
+
useEffect7(() => {
|
|
14117
14846
|
if (!onRegisterHandlers)
|
|
14118
14847
|
return;
|
|
14119
|
-
const
|
|
14848
|
+
const handleNotificationImpl = async (message, _envEvent) => {
|
|
14120
14849
|
const notifId = `h${++historyIdRef.current}`;
|
|
14121
14850
|
setHistory((h) => [
|
|
14122
14851
|
...h,
|
|
@@ -14126,10 +14855,31 @@ var RunScreen = ({
|
|
|
14126
14855
|
await executeQueryRef.current(message);
|
|
14127
14856
|
}
|
|
14128
14857
|
};
|
|
14858
|
+
const handleNotification = wrapFunction6(handleNotificationImpl, "tui.run-tui.handleNotification", {
|
|
14859
|
+
recordParams: true,
|
|
14860
|
+
recordResult: false,
|
|
14861
|
+
log: true,
|
|
14862
|
+
paramFilter: (args) => ({
|
|
14863
|
+
"message.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
14864
|
+
"message.head": typeof args[0] === "string" ? args[0].slice(0, 60) : "",
|
|
14865
|
+
isProcessingRef: isProcessingRef.current ?? 0
|
|
14866
|
+
})
|
|
14867
|
+
});
|
|
14129
14868
|
const isIdle = () => {
|
|
14130
14869
|
return isProcessingRef.current === 0;
|
|
14131
14870
|
};
|
|
14132
|
-
|
|
14871
|
+
const appendTraceId = (traceId) => {
|
|
14872
|
+
const traceIdItemId = `h${++historyIdRef.current}`;
|
|
14873
|
+
setHistory((h) => [
|
|
14874
|
+
...h,
|
|
14875
|
+
{ role: "tool", content: `\uD83D\uDD0D [Trace] ${traceId}`, id: traceIdItemId }
|
|
14876
|
+
]);
|
|
14877
|
+
};
|
|
14878
|
+
onRegisterHandlers({
|
|
14879
|
+
onNotification: handleNotification,
|
|
14880
|
+
isIdle,
|
|
14881
|
+
appendTraceId
|
|
14882
|
+
});
|
|
14133
14883
|
}, [onRegisterHandlers]);
|
|
14134
14884
|
const handleSubmit = useCallback4(async (raw) => {
|
|
14135
14885
|
const trimmed = raw.trim();
|
|
@@ -14217,19 +14967,24 @@ var RunScreen = ({
|
|
|
14217
14967
|
const handleCancel = useCallback4(() => {
|
|
14218
14968
|
doExit();
|
|
14219
14969
|
}, [doExit]);
|
|
14220
|
-
return /* @__PURE__ */
|
|
14970
|
+
return /* @__PURE__ */ jsxDEV9(Box7, {
|
|
14221
14971
|
flexDirection: "column",
|
|
14222
14972
|
children: [
|
|
14223
|
-
/* @__PURE__ */
|
|
14973
|
+
/* @__PURE__ */ jsxDEV9(AppMemo, {
|
|
14224
14974
|
history,
|
|
14225
14975
|
status,
|
|
14226
14976
|
model,
|
|
14227
|
-
workdir
|
|
14228
|
-
streamingText: stream.streamingText
|
|
14977
|
+
workdir
|
|
14229
14978
|
}, undefined, false, undefined, this),
|
|
14230
|
-
status
|
|
14979
|
+
status !== "idle" ? /* @__PURE__ */ jsxDEV9(StreamingOverlay, {
|
|
14980
|
+
streamingText: stream.streamingText,
|
|
14981
|
+
status,
|
|
14982
|
+
markdownEnabled: markdownEnabled2,
|
|
14983
|
+
width
|
|
14984
|
+
}, undefined, false, undefined, this) : null,
|
|
14985
|
+
status === "idle" ? /* @__PURE__ */ jsxDEV9(Box7, {
|
|
14231
14986
|
marginTop: 1,
|
|
14232
|
-
children: /* @__PURE__ */
|
|
14987
|
+
children: /* @__PURE__ */ jsxDEV9(TextInput, {
|
|
14233
14988
|
label: "You",
|
|
14234
14989
|
prefix: "\uD83D\uDC64",
|
|
14235
14990
|
placeholder: 'Type a message, "/help", or "exit"',
|
|
@@ -14238,9 +14993,9 @@ var RunScreen = ({
|
|
|
14238
14993
|
history: userHistory
|
|
14239
14994
|
}, undefined, false, undefined, this)
|
|
14240
14995
|
}, undefined, false, undefined, this) : null,
|
|
14241
|
-
errorMessage ? /* @__PURE__ */
|
|
14996
|
+
errorMessage ? /* @__PURE__ */ jsxDEV9(Box7, {
|
|
14242
14997
|
marginTop: 1,
|
|
14243
|
-
children: /* @__PURE__ */
|
|
14998
|
+
children: /* @__PURE__ */ jsxDEV9(Text9, {
|
|
14244
14999
|
color: "red",
|
|
14245
15000
|
children: [
|
|
14246
15001
|
"⚠ ",
|
|
@@ -14338,7 +15093,11 @@ async function shutdownRunSteps(deps) {
|
|
|
14338
15093
|
}
|
|
14339
15094
|
|
|
14340
15095
|
// src/commands/run.ts
|
|
14341
|
-
|
|
15096
|
+
import {
|
|
15097
|
+
wrapFunction as wrapFunction7,
|
|
15098
|
+
getTracerProvider as getTracerProvider4
|
|
15099
|
+
} from "@ai-setting/roy-agent-core";
|
|
15100
|
+
async function loadHandleQueryImpl(options, hooks) {
|
|
14342
15101
|
const quiet = CliQuietModeService.getInstance().isQuiet();
|
|
14343
15102
|
const output = new OutputService2;
|
|
14344
15103
|
output.configure({ quiet });
|
|
@@ -14403,7 +15162,7 @@ async function loadHandleQuery(options, hooks) {
|
|
|
14403
15162
|
}
|
|
14404
15163
|
const llmComponent = envService.getLLM();
|
|
14405
15164
|
queryExecutor.initStreamOutput(llmComponent ?? null);
|
|
14406
|
-
const
|
|
15165
|
+
const handleQueryImpl = async (message) => {
|
|
14407
15166
|
const mergedContext = {
|
|
14408
15167
|
...agentContext,
|
|
14409
15168
|
model: options.model,
|
|
@@ -14420,6 +15179,14 @@ async function loadHandleQuery(options, hooks) {
|
|
|
14420
15179
|
}, undefined, mergedContext);
|
|
14421
15180
|
return String(result ?? "");
|
|
14422
15181
|
};
|
|
15182
|
+
const handleQuery = wrapFunction7(handleQueryImpl, "cli.run.handleQuery", {
|
|
15183
|
+
recordParams: true,
|
|
15184
|
+
recordResult: false,
|
|
15185
|
+
log: true,
|
|
15186
|
+
paramFilter: (args) => ({
|
|
15187
|
+
"message.length": typeof args[0] === "string" ? args[0].length : 0
|
|
15188
|
+
})
|
|
15189
|
+
});
|
|
14423
15190
|
const taskEventHandler = new TaskEventHandler({
|
|
14424
15191
|
env,
|
|
14425
15192
|
enabled: true
|
|
@@ -14451,17 +15218,80 @@ async function loadHandleQuery(options, hooks) {
|
|
|
14451
15218
|
sessionManager
|
|
14452
15219
|
};
|
|
14453
15220
|
}
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
15221
|
+
var loadHandleQuery = wrapFunction7(loadHandleQueryImpl, "cli.run.loadHandleQuery", {
|
|
15222
|
+
recordParams: true,
|
|
15223
|
+
recordResult: false,
|
|
15224
|
+
log: true,
|
|
15225
|
+
paramFilter: (args) => {
|
|
15226
|
+
const opts = args[0] ?? {};
|
|
15227
|
+
return {
|
|
15228
|
+
"options.model": opts.model ?? "",
|
|
15229
|
+
"options.workdir": opts.workdir ?? "",
|
|
15230
|
+
"options.session": opts.session ?? "",
|
|
15231
|
+
"options.eventSource": Array.isArray(opts.eventSource) ? opts.eventSource.join(",") : opts.eventSource ?? "",
|
|
15232
|
+
"has.onNotification": !!args[1]?.onNotification
|
|
15233
|
+
};
|
|
15234
|
+
}
|
|
15235
|
+
});
|
|
15236
|
+
function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext, eventSourceSystemPrompt, onTraceId) {
|
|
15237
|
+
const innerStreamHandler = async (message, onChunk) => {
|
|
15238
|
+
const onChunkInstrumented = wrapFunction7((chunk) => {
|
|
15239
|
+
onChunk(chunk);
|
|
15240
|
+
}, "cli.run.chunkCallbackImpl.onChunk-called", {
|
|
15241
|
+
recordParams: true,
|
|
15242
|
+
recordResult: false,
|
|
15243
|
+
log: false,
|
|
15244
|
+
paramFilter: (args) => ({
|
|
15245
|
+
"chunk.length": typeof args[0] === "string" ? args[0].length : 0,
|
|
15246
|
+
"chunk.head": typeof args[0] === "string" ? args[0].slice(0, 32) : ""
|
|
15247
|
+
})
|
|
15248
|
+
});
|
|
15249
|
+
const chunkCallbackImpl = (event) => {
|
|
14457
15250
|
if (event.type === "llm.text") {
|
|
14458
15251
|
if (event.delta) {
|
|
14459
|
-
|
|
15252
|
+
onChunkInstrumented(event.delta);
|
|
14460
15253
|
} else if (event.content) {
|
|
14461
|
-
|
|
15254
|
+
onChunkInstrumented(event.content);
|
|
14462
15255
|
}
|
|
15256
|
+
return;
|
|
14463
15257
|
}
|
|
14464
|
-
|
|
15258
|
+
if (event.type === "tool.call") {
|
|
15259
|
+
const toolName = event.toolName || "unknown";
|
|
15260
|
+
const toolId = event.toolId || "";
|
|
15261
|
+
onChunkInstrumented(`
|
|
15262
|
+
\uD83D\uDD27 tool: ${toolName} (${toolId})
|
|
15263
|
+
`);
|
|
15264
|
+
return;
|
|
15265
|
+
}
|
|
15266
|
+
if (event.type === "tool.result") {
|
|
15267
|
+
onChunkInstrumented(`
|
|
15268
|
+
✓ done
|
|
15269
|
+
`);
|
|
15270
|
+
return;
|
|
15271
|
+
}
|
|
15272
|
+
if (event.type === "tool.error") {
|
|
15273
|
+
const msg = event.toolError || "error";
|
|
15274
|
+
onChunkInstrumented(`
|
|
15275
|
+
✗ ${msg}
|
|
15276
|
+
`);
|
|
15277
|
+
return;
|
|
15278
|
+
}
|
|
15279
|
+
};
|
|
15280
|
+
queryExecutor.setChunkCallback(wrapFunction7(chunkCallbackImpl, "cli.run.chunkCallback", {
|
|
15281
|
+
recordParams: true,
|
|
15282
|
+
recordResult: false,
|
|
15283
|
+
log: true,
|
|
15284
|
+
paramFilter: (args) => {
|
|
15285
|
+
const e = args[0] ?? {};
|
|
15286
|
+
return {
|
|
15287
|
+
"event.type": e.type ?? "unknown",
|
|
15288
|
+
"event.delta.length": typeof e.delta === "string" ? e.delta.length : 0,
|
|
15289
|
+
"event.content.length": typeof e.content === "string" ? e.content.length : 0,
|
|
15290
|
+
"event.toolName": e.toolName ?? "",
|
|
15291
|
+
"event.toolId": e.toolId ?? ""
|
|
15292
|
+
};
|
|
15293
|
+
}
|
|
15294
|
+
}));
|
|
14465
15295
|
const mergedContext = {
|
|
14466
15296
|
...agentContext,
|
|
14467
15297
|
model: options.model,
|
|
@@ -14471,13 +15301,37 @@ function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext
|
|
|
14471
15301
|
defaultAgentName: options.defaultAgentName
|
|
14472
15302
|
}
|
|
14473
15303
|
};
|
|
14474
|
-
const
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
15304
|
+
const turnSpan = getTracerProvider4().getTracer("roy-tracer").startSpan("cli.run.turn");
|
|
15305
|
+
const turnTraceId = turnSpan.spanContext.traceId;
|
|
15306
|
+
let result;
|
|
15307
|
+
try {
|
|
15308
|
+
result = await queryExecutor.execute(message, sessionId, {
|
|
15309
|
+
showReasoning: options.reasoning ?? true,
|
|
15310
|
+
showToolCalls: options.toolCalls ?? true,
|
|
15311
|
+
showToolResults: options.toolResults ?? false
|
|
15312
|
+
}, undefined, mergedContext);
|
|
15313
|
+
turnSpan.end(result);
|
|
15314
|
+
} catch (error) {
|
|
15315
|
+
turnSpan.setAttribute("error", String(error));
|
|
15316
|
+
turnSpan.end(undefined, error instanceof Error ? error : new Error(String(error)));
|
|
15317
|
+
throw error;
|
|
15318
|
+
} finally {
|
|
15319
|
+
try {
|
|
15320
|
+
onTraceId?.(turnTraceId);
|
|
15321
|
+
} catch (cbErr) {
|
|
15322
|
+
console.warn(`[Trace] sink failed: ${cbErr instanceof Error ? cbErr.message : String(cbErr)}`);
|
|
15323
|
+
}
|
|
15324
|
+
}
|
|
14479
15325
|
return String(result ?? "");
|
|
14480
15326
|
};
|
|
15327
|
+
return wrapFunction7(innerStreamHandler, "cli.run.createStreamHandleQuery", {
|
|
15328
|
+
recordParams: true,
|
|
15329
|
+
recordResult: false,
|
|
15330
|
+
log: true,
|
|
15331
|
+
paramFilter: (args) => ({
|
|
15332
|
+
"message.length": typeof args[0] === "string" ? args[0].length : 0
|
|
15333
|
+
})
|
|
15334
|
+
});
|
|
14481
15335
|
}
|
|
14482
15336
|
function createRunCommand() {
|
|
14483
15337
|
return {
|
|
@@ -14550,6 +15404,10 @@ function createRunCommand() {
|
|
|
14550
15404
|
type: "string",
|
|
14551
15405
|
describe: "Default agent 名字(默认 Roy,可被覆盖)",
|
|
14552
15406
|
default: "Roy"
|
|
15407
|
+
}).option("debug-on", {
|
|
15408
|
+
type: "boolean",
|
|
15409
|
+
describe: "调试模式:每次 turn 结束后输出 [Trace] <traceId>(stderr),便于追踪调用 trace",
|
|
15410
|
+
default: false
|
|
14553
15411
|
}),
|
|
14554
15412
|
handler: async (argv) => {
|
|
14555
15413
|
if (argv.markdown === false) {
|
|
@@ -14591,10 +15449,17 @@ function createRunCommand() {
|
|
|
14591
15449
|
logger: undefined
|
|
14592
15450
|
});
|
|
14593
15451
|
});
|
|
14594
|
-
const
|
|
15452
|
+
const debugOn = argv.debugOn ?? false;
|
|
15453
|
+
let appendTraceIdTui;
|
|
15454
|
+
const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt, (traceId) => {
|
|
15455
|
+
printTraceIdAfterResponse(traceId, {
|
|
15456
|
+
enabled: debugOn,
|
|
15457
|
+
tuiSink: appendTraceIdTui
|
|
15458
|
+
});
|
|
15459
|
+
});
|
|
14595
15460
|
const stopEventHandler = eventHandler.start();
|
|
14596
15461
|
const stopTaskEventHandler = taskEventHandler.start();
|
|
14597
|
-
const { waitUntilExit } = render(
|
|
15462
|
+
const { waitUntilExit } = render(React8.createElement(RunTui_default, {
|
|
14598
15463
|
handleQuery,
|
|
14599
15464
|
streamHandleQuery,
|
|
14600
15465
|
model: argv.model,
|
|
@@ -14604,6 +15469,7 @@ function createRunCommand() {
|
|
|
14604
15469
|
onRegisterHandlers: (handlers) => {
|
|
14605
15470
|
runState.onNotification = handlers.onNotification;
|
|
14606
15471
|
runState.isIdle = handlers.isIdle;
|
|
15472
|
+
appendTraceIdTui = handlers.appendTraceId;
|
|
14607
15473
|
},
|
|
14608
15474
|
onExit: () => {}
|
|
14609
15475
|
}), { exitOnCtrlC: true });
|
|
@@ -14631,14 +15497,14 @@ function createRunCommand() {
|
|
|
14631
15497
|
var RunCommand = createRunCommand();
|
|
14632
15498
|
|
|
14633
15499
|
// src/commands/chat.ts
|
|
14634
|
-
import
|
|
15500
|
+
import React10 from "react";
|
|
14635
15501
|
import { render as render2 } from "ink";
|
|
14636
15502
|
|
|
14637
15503
|
// src/ChatTui.tsx
|
|
14638
|
-
import { useEffect as
|
|
14639
|
-
import { Box as
|
|
15504
|
+
import { useEffect as useEffect8, useRef as useRef6, useState as useState7 } from "react";
|
|
15505
|
+
import { Box as Box8, useApp as useApp3 } from "ink";
|
|
14640
15506
|
init_markdown();
|
|
14641
|
-
import { jsxDEV as
|
|
15507
|
+
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
14642
15508
|
var ChatScreen = ({
|
|
14643
15509
|
handleQuery,
|
|
14644
15510
|
streamHandleQuery,
|
|
@@ -14651,11 +15517,11 @@ var ChatScreen = ({
|
|
|
14651
15517
|
const [history, setHistory] = useState7([
|
|
14652
15518
|
{ role: "user", content: message, id: "h-init-1" }
|
|
14653
15519
|
]);
|
|
14654
|
-
const historyIdRef =
|
|
15520
|
+
const historyIdRef = useRef6(1);
|
|
14655
15521
|
const stream = useStreamingAccumulator();
|
|
14656
15522
|
const { exit } = useApp3();
|
|
14657
15523
|
const width = process.stdout.columns ?? 80;
|
|
14658
|
-
|
|
15524
|
+
useEffect8(() => {
|
|
14659
15525
|
let cancelled = false;
|
|
14660
15526
|
stream.start();
|
|
14661
15527
|
(async () => {
|
|
@@ -14694,16 +15560,23 @@ var ChatScreen = ({
|
|
|
14694
15560
|
cancelled = true;
|
|
14695
15561
|
};
|
|
14696
15562
|
}, [handleQuery, streamHandleQuery, message, maxLines, markdownEnabled2, exit, width, stream]);
|
|
14697
|
-
return /* @__PURE__ */
|
|
15563
|
+
return /* @__PURE__ */ jsxDEV10(Box8, {
|
|
14698
15564
|
flexDirection: "column",
|
|
14699
|
-
children:
|
|
14700
|
-
|
|
14701
|
-
|
|
14702
|
-
|
|
14703
|
-
|
|
14704
|
-
|
|
14705
|
-
|
|
14706
|
-
|
|
15565
|
+
children: [
|
|
15566
|
+
/* @__PURE__ */ jsxDEV10(AppMemo, {
|
|
15567
|
+
history,
|
|
15568
|
+
status: stream.status,
|
|
15569
|
+
model,
|
|
15570
|
+
workdir
|
|
15571
|
+
}, undefined, false, undefined, this),
|
|
15572
|
+
stream.status !== "idle" ? /* @__PURE__ */ jsxDEV10(StreamingOverlay, {
|
|
15573
|
+
streamingText: stream.streamingText,
|
|
15574
|
+
status: stream.status,
|
|
15575
|
+
markdownEnabled: markdownEnabled2,
|
|
15576
|
+
width
|
|
15577
|
+
}, undefined, false, undefined, this) : null
|
|
15578
|
+
]
|
|
15579
|
+
}, undefined, true, undefined, this);
|
|
14707
15580
|
};
|
|
14708
15581
|
var ChatTui_default = ChatScreen;
|
|
14709
15582
|
|
|
@@ -14782,7 +15655,7 @@ function createChatCommand() {
|
|
|
14782
15655
|
}
|
|
14783
15656
|
const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
|
|
14784
15657
|
const handleQuery = await loadHandleQuery2(argv);
|
|
14785
|
-
const { waitUntilExit } = render2(
|
|
15658
|
+
const { waitUntilExit } = render2(React10.createElement(ChatTui_default, {
|
|
14786
15659
|
handleQuery,
|
|
14787
15660
|
message: argv.message,
|
|
14788
15661
|
model: argv.model,
|
|
@@ -23739,7 +24612,7 @@ var WorkflowAddCommand = {
|
|
|
23739
24612
|
process.exit(1);
|
|
23740
24613
|
}
|
|
23741
24614
|
if (!agentComponent.getAgent("workflow-extract")) {
|
|
23742
|
-
output.error("Built-in 'workflow-extract' agent is not available. ");
|
|
24615
|
+
output.error("Built-in 'workflow-extract' agent is not available. This usually means the environment was not fully initialized.");
|
|
23743
24616
|
process.exit(1);
|
|
23744
24617
|
}
|
|
23745
24618
|
const prompt = `## 任务
|
|
@@ -24153,9 +25026,9 @@ import chalk73 from "chalk";
|
|
|
24153
25026
|
import fs5 from "fs";
|
|
24154
25027
|
import path8 from "path";
|
|
24155
25028
|
import { createRunWorkflowTool } from "@ai-setting/roy-agent-core/env/workflow/tools";
|
|
24156
|
-
import { getTracerProvider as
|
|
25029
|
+
import { getTracerProvider as getTracerProvider5, propagation, wrapFunction as wrapFunction8 } from "@ai-setting/roy-agent-core";
|
|
24157
25030
|
import { isValidSessionId } from "@ai-setting/roy-agent-core/env/session";
|
|
24158
|
-
var runWorkflow =
|
|
25031
|
+
var runWorkflow = wrapFunction8(async function runWorkflowImpl(args) {
|
|
24159
25032
|
const output = new OutputService2;
|
|
24160
25033
|
const envService = new EnvironmentService(output);
|
|
24161
25034
|
const traceparent = process.env.TRACEPARENT;
|
|
@@ -24175,7 +25048,7 @@ var runWorkflow = wrapFunction(async function runWorkflowImpl(args) {
|
|
|
24175
25048
|
output.info(`[OTel Trace] TRACEPARENT=${traceparent || "none"}, traceId=${traceId}, parentSpanId=${parentSpanId}`);
|
|
24176
25049
|
let workflowSpan = undefined;
|
|
24177
25050
|
try {
|
|
24178
|
-
const provider =
|
|
25051
|
+
const provider = getTracerProvider5();
|
|
24179
25052
|
await provider.initialize();
|
|
24180
25053
|
const tracer = provider.getTracer("roy-tracer");
|
|
24181
25054
|
const restoredContext = tracer.getCurrentContext();
|
|
@@ -24432,8 +25305,8 @@ var WorkflowRunCommand = {
|
|
|
24432
25305
|
// src/commands/workflow/commands/stop.ts
|
|
24433
25306
|
import chalk74 from "chalk";
|
|
24434
25307
|
import { createWorkflowRunStopTool } from "@ai-setting/roy-agent-core/env/workflow/tools";
|
|
24435
|
-
import { wrapFunction as
|
|
24436
|
-
var stopWorkflow =
|
|
25308
|
+
import { wrapFunction as wrapFunction9 } from "@ai-setting/roy-agent-core";
|
|
25309
|
+
var stopWorkflow = wrapFunction9(async function stopWorkflowImpl(args) {
|
|
24437
25310
|
const output = new OutputService2;
|
|
24438
25311
|
const envService = new EnvironmentService(output);
|
|
24439
25312
|
try {
|
|
@@ -25088,7 +25961,7 @@ Error: ${error.message}`));
|
|
|
25088
25961
|
|
|
25089
25962
|
// src/commands/workflow/commands/search.ts
|
|
25090
25963
|
import chalk78 from "chalk";
|
|
25091
|
-
import { wrapFunction as
|
|
25964
|
+
import { wrapFunction as wrapFunction10 } from "@ai-setting/roy-agent-core";
|
|
25092
25965
|
var WorkflowSearchCommand = {
|
|
25093
25966
|
command: "search",
|
|
25094
25967
|
describe: "Search workflows by keyword and/or tags (multiple tags use AND filter). v2: returns available_tags.",
|
|
@@ -25263,14 +26136,14 @@ var _runWorkflowSearchImpl = async function(opts) {
|
|
|
25263
26136
|
}
|
|
25264
26137
|
}
|
|
25265
26138
|
};
|
|
25266
|
-
var runWorkflowSearch =
|
|
26139
|
+
var runWorkflowSearch = wrapFunction10(_runWorkflowSearchImpl, "workflow.cli.search", {
|
|
25267
26140
|
recordParams: true,
|
|
25268
26141
|
recordResult: false,
|
|
25269
26142
|
log: false
|
|
25270
26143
|
});
|
|
25271
26144
|
|
|
25272
26145
|
// src/commands/workflow/commands/tag.ts
|
|
25273
|
-
import { wrapFunction as
|
|
26146
|
+
import { wrapFunction as wrapFunction11 } from "@ai-setting/roy-agent-core";
|
|
25274
26147
|
import chalk79 from "chalk";
|
|
25275
26148
|
var WorkflowTagListCommand = {
|
|
25276
26149
|
command: "list",
|
|
@@ -25470,12 +26343,12 @@ function formatDate2(iso) {
|
|
|
25470
26343
|
return iso;
|
|
25471
26344
|
}
|
|
25472
26345
|
}
|
|
25473
|
-
var runWorkflowTagList =
|
|
26346
|
+
var runWorkflowTagList = wrapFunction11(_runWorkflowTagListImpl, "workflow.cli.tag.list", {
|
|
25474
26347
|
recordParams: true,
|
|
25475
26348
|
recordResult: false,
|
|
25476
26349
|
log: false
|
|
25477
26350
|
});
|
|
25478
|
-
var runWorkflowTagGet =
|
|
26351
|
+
var runWorkflowTagGet = wrapFunction11(_runWorkflowTagGetImpl, "workflow.cli.tag.get", {
|
|
25479
26352
|
recordParams: true,
|
|
25480
26353
|
recordResult: false,
|
|
25481
26354
|
log: false
|