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