@ai-setting/roy-agent-cli 1.6.41 → 1.7.0
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 +379 -173
- package/dist/index.js +379 -173
- package/dist/roy-agent-linux-x64/bin/roy-agent +0 -0
- package/package.json +3 -2
package/dist/bin/roy-agent.js
CHANGED
|
@@ -797,99 +797,6 @@ var init_welcome_card = __esm(() => {
|
|
|
797
797
|
];
|
|
798
798
|
});
|
|
799
799
|
|
|
800
|
-
// package.json
|
|
801
|
-
var require_package = __commonJS((exports, module) => {
|
|
802
|
-
module.exports = {
|
|
803
|
-
name: "@ai-setting/roy-agent-cli",
|
|
804
|
-
version: "1.6.41",
|
|
805
|
-
type: "module",
|
|
806
|
-
description: "CLI for roy-agent - Non-interactive command execution",
|
|
807
|
-
main: "./dist/index.js",
|
|
808
|
-
module: "./dist/index.js",
|
|
809
|
-
types: "./dist/index.d.ts",
|
|
810
|
-
bin: {
|
|
811
|
-
"roy-agent": "./dist/bin/roy-agent.js"
|
|
812
|
-
},
|
|
813
|
-
exports: {
|
|
814
|
-
".": {
|
|
815
|
-
import: "./dist/index.js",
|
|
816
|
-
types: "./dist/index.d.ts"
|
|
817
|
-
},
|
|
818
|
-
"./package.json": "./package.json"
|
|
819
|
-
},
|
|
820
|
-
files: [
|
|
821
|
-
"dist/**/*",
|
|
822
|
-
"README.md"
|
|
823
|
-
],
|
|
824
|
-
scripts: {
|
|
825
|
-
build: "bunup && bun run postbuild",
|
|
826
|
-
postbuild: "bun run scripts/postbuild.ts",
|
|
827
|
-
clean: "rm -rf dist",
|
|
828
|
-
lint: "eslint --max-warnings 0 src/",
|
|
829
|
-
"lint:fix": "eslint --fix src/",
|
|
830
|
-
typecheck: "npx tsc --noEmit --skipLibCheck"
|
|
831
|
-
},
|
|
832
|
-
dependencies: {
|
|
833
|
-
"@ai-setting/roy-agent-coder-harness": "^1.5.50",
|
|
834
|
-
"@ai-setting/roy-agent-core": "^1.5.83",
|
|
835
|
-
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
836
|
-
"@clack/prompts": "^1.7.0",
|
|
837
|
-
chalk: "^5.6.2",
|
|
838
|
-
"cli-highlight": "^2.1.11",
|
|
839
|
-
commander: "^14.0.3",
|
|
840
|
-
effect: "^3.21.2",
|
|
841
|
-
ink: "^5.2.1",
|
|
842
|
-
"ink-text-input": "^6.0.0",
|
|
843
|
-
marked: "^18.0.7",
|
|
844
|
-
pyright: "^1.1.409",
|
|
845
|
-
react: "^18",
|
|
846
|
-
"react-devtools-core": "^7.0.1",
|
|
847
|
-
"react-dom": "^18",
|
|
848
|
-
"typescript-language-server": "^5.1.3",
|
|
849
|
-
"vscode-css-languageserver-bin": "^1.4.0",
|
|
850
|
-
"vscode-html-languageserver-bin": "^1.4.0",
|
|
851
|
-
"vscode-json-languageserver": "^1.3.4",
|
|
852
|
-
yargs: "^17.7.2",
|
|
853
|
-
"zod-to-json-schema": "^3.25.2"
|
|
854
|
-
},
|
|
855
|
-
devDependencies: {
|
|
856
|
-
"@types/node": "^20.10.0",
|
|
857
|
-
"@types/react": "^18",
|
|
858
|
-
"@types/react-dom": "^18",
|
|
859
|
-
"@types/yargs": "^17.0.32",
|
|
860
|
-
"@typescript-eslint/parser": "^8.62.1",
|
|
861
|
-
bunup: "^0.16.0",
|
|
862
|
-
eslint: "^10.6.0",
|
|
863
|
-
"ink-testing-library": "^4.0.0",
|
|
864
|
-
typescript: "^5.3.0"
|
|
865
|
-
},
|
|
866
|
-
engines: {
|
|
867
|
-
node: ">=18.0.0"
|
|
868
|
-
},
|
|
869
|
-
repository: {
|
|
870
|
-
type: "git",
|
|
871
|
-
url: "https://github.com/ai-setting/roy-agent.git",
|
|
872
|
-
directory: "packages/cli"
|
|
873
|
-
},
|
|
874
|
-
publishConfig: {
|
|
875
|
-
registry: "https://registry.npmjs.org",
|
|
876
|
-
access: "public"
|
|
877
|
-
},
|
|
878
|
-
keywords: [
|
|
879
|
-
"roy-agent",
|
|
880
|
-
"agent",
|
|
881
|
-
"ai",
|
|
882
|
-
"cli",
|
|
883
|
-
"command-line"
|
|
884
|
-
],
|
|
885
|
-
author: "ai-setting",
|
|
886
|
-
license: "MIT",
|
|
887
|
-
bugs: {
|
|
888
|
-
url: "https://github.com/ai-setting/roy-agent/issues"
|
|
889
|
-
}
|
|
890
|
-
};
|
|
891
|
-
});
|
|
892
|
-
|
|
893
800
|
// src/commands/shared/clipboard-helper.ts
|
|
894
801
|
var exports_clipboard_helper = {};
|
|
895
802
|
__export(exports_clipboard_helper, {
|
|
@@ -9551,6 +9458,105 @@ class CliQuietModeService {
|
|
|
9551
9458
|
setCoreQuietMode(false);
|
|
9552
9459
|
}
|
|
9553
9460
|
}
|
|
9461
|
+
// package.json
|
|
9462
|
+
var package_default = {
|
|
9463
|
+
name: "@ai-setting/roy-agent-cli",
|
|
9464
|
+
version: "1.7.0",
|
|
9465
|
+
type: "module",
|
|
9466
|
+
description: "CLI for roy-agent - Non-interactive command execution",
|
|
9467
|
+
main: "./dist/index.js",
|
|
9468
|
+
module: "./dist/index.js",
|
|
9469
|
+
types: "./dist/index.d.ts",
|
|
9470
|
+
bin: {
|
|
9471
|
+
"roy-agent": "./dist/bin/roy-agent.js"
|
|
9472
|
+
},
|
|
9473
|
+
exports: {
|
|
9474
|
+
".": {
|
|
9475
|
+
import: "./dist/index.js",
|
|
9476
|
+
types: "./dist/index.d.ts"
|
|
9477
|
+
},
|
|
9478
|
+
"./package.json": "./package.json"
|
|
9479
|
+
},
|
|
9480
|
+
files: [
|
|
9481
|
+
"dist/**/*",
|
|
9482
|
+
"README.md"
|
|
9483
|
+
],
|
|
9484
|
+
scripts: {
|
|
9485
|
+
build: "bunup && bun run postbuild",
|
|
9486
|
+
postbuild: "bun run scripts/postbuild.ts",
|
|
9487
|
+
clean: "rm -rf dist",
|
|
9488
|
+
lint: "eslint --max-warnings 0 src/",
|
|
9489
|
+
"lint:fix": "eslint --fix src/",
|
|
9490
|
+
typecheck: "npx tsc --noEmit --skipLibCheck"
|
|
9491
|
+
},
|
|
9492
|
+
dependencies: {
|
|
9493
|
+
"@ai-setting/roy-agent-coder-harness": "^1.5.50",
|
|
9494
|
+
"@ai-setting/roy-agent-core": "^1.5.83",
|
|
9495
|
+
"@ai-setting/roy-agent-ontology-harness": "^1.5.47",
|
|
9496
|
+
"@clack/prompts": "^1.7.0",
|
|
9497
|
+
chalk: "^5.6.2",
|
|
9498
|
+
"cli-highlight": "^2.1.11",
|
|
9499
|
+
commander: "^14.0.3",
|
|
9500
|
+
effect: "^3.21.2",
|
|
9501
|
+
ink: "^5.2.1",
|
|
9502
|
+
"ink-text-input": "^6.0.0",
|
|
9503
|
+
marked: "^18.0.7",
|
|
9504
|
+
pyright: "^1.1.409",
|
|
9505
|
+
react: "^18",
|
|
9506
|
+
"react-devtools-core": "^7.0.1",
|
|
9507
|
+
"react-dom": "^18",
|
|
9508
|
+
"typescript-language-server": "^5.1.3",
|
|
9509
|
+
"vscode-css-languageserver-bin": "^1.4.0",
|
|
9510
|
+
"vscode-html-languageserver-bin": "^1.4.0",
|
|
9511
|
+
"vscode-json-languageserver": "^1.3.4",
|
|
9512
|
+
yargs: "^17.7.2",
|
|
9513
|
+
"zod-to-json-schema": "^3.25.2",
|
|
9514
|
+
"@earendil-works/pi-ai": "^0.74.2"
|
|
9515
|
+
},
|
|
9516
|
+
devDependencies: {
|
|
9517
|
+
"@types/node": "^20.10.0",
|
|
9518
|
+
"@types/react": "^18",
|
|
9519
|
+
"@types/react-dom": "^18",
|
|
9520
|
+
"@types/yargs": "^17.0.32",
|
|
9521
|
+
"@typescript-eslint/parser": "^8.62.1",
|
|
9522
|
+
bunup: "^0.16.0",
|
|
9523
|
+
eslint: "^10.6.0",
|
|
9524
|
+
"ink-testing-library": "^4.0.0",
|
|
9525
|
+
typescript: "^5.3.0"
|
|
9526
|
+
},
|
|
9527
|
+
engines: {
|
|
9528
|
+
node: ">=18.0.0"
|
|
9529
|
+
},
|
|
9530
|
+
repository: {
|
|
9531
|
+
type: "git",
|
|
9532
|
+
url: "https://github.com/ai-setting/roy-agent.git",
|
|
9533
|
+
directory: "packages/cli"
|
|
9534
|
+
},
|
|
9535
|
+
publishConfig: {
|
|
9536
|
+
registry: "https://registry.npmjs.org",
|
|
9537
|
+
access: "public"
|
|
9538
|
+
},
|
|
9539
|
+
keywords: [
|
|
9540
|
+
"roy-agent",
|
|
9541
|
+
"agent",
|
|
9542
|
+
"ai",
|
|
9543
|
+
"cli",
|
|
9544
|
+
"command-line"
|
|
9545
|
+
],
|
|
9546
|
+
author: "ai-setting",
|
|
9547
|
+
license: "MIT",
|
|
9548
|
+
bugs: {
|
|
9549
|
+
url: "https://github.com/ai-setting/roy-agent/issues"
|
|
9550
|
+
}
|
|
9551
|
+
};
|
|
9552
|
+
|
|
9553
|
+
// src/lib/version.ts
|
|
9554
|
+
function getPackageVersion() {
|
|
9555
|
+
if (typeof ROY_AGENT_VERSION !== "undefined") {
|
|
9556
|
+
return ROY_AGENT_VERSION;
|
|
9557
|
+
}
|
|
9558
|
+
return package_default.version;
|
|
9559
|
+
}
|
|
9554
9560
|
|
|
9555
9561
|
// src/commands/act.ts
|
|
9556
9562
|
import { execFile, execFileSync } from "node:child_process";
|
|
@@ -12270,12 +12276,6 @@ var COLOR_BY_STATUS = {
|
|
|
12270
12276
|
running: COLORS.accent,
|
|
12271
12277
|
busy: COLORS.accent
|
|
12272
12278
|
};
|
|
12273
|
-
// src/lib/version.ts
|
|
12274
|
-
var import__package = __toESM(require_package(), 1);
|
|
12275
|
-
function getPackageVersion() {
|
|
12276
|
-
return import__package.default.version;
|
|
12277
|
-
}
|
|
12278
|
-
|
|
12279
12279
|
// src/commands/interactive.ts
|
|
12280
12280
|
var logger4 = createLogger5("cli:interactive");
|
|
12281
12281
|
var USER_PROMPT = COLORS.accent("❯ ");
|
|
@@ -13381,6 +13381,9 @@ function createInteractiveCommand(externalEnvService) {
|
|
|
13381
13381
|
showToolCalls: args.toolCalls,
|
|
13382
13382
|
showToolResults: args.toolResults
|
|
13383
13383
|
}, traceId, mergedContext);
|
|
13384
|
+
if (result && !queryExecutor.getFullText()) {
|
|
13385
|
+
console.log(result);
|
|
13386
|
+
}
|
|
13384
13387
|
repl.setLastUsage(queryExecutor.getLastUsage());
|
|
13385
13388
|
return result;
|
|
13386
13389
|
},
|
|
@@ -13519,7 +13522,7 @@ import React6 from "react";
|
|
|
13519
13522
|
import { render } from "ink";
|
|
13520
13523
|
|
|
13521
13524
|
// src/RunTui.tsx
|
|
13522
|
-
import { useState as useState6, useCallback as useCallback4, useRef as useRef2 } from "react";
|
|
13525
|
+
import { useState as useState6, useCallback as useCallback4, useRef as useRef2, useEffect as useEffect5 } from "react";
|
|
13523
13526
|
import { Box as Box6, Text as Text8, useApp as useApp2 } from "ink";
|
|
13524
13527
|
|
|
13525
13528
|
// src/tui/App.tsx
|
|
@@ -13831,7 +13834,7 @@ function useStreamingAccumulator() {
|
|
|
13831
13834
|
let snapshot = "";
|
|
13832
13835
|
setStreamingText((prev) => {
|
|
13833
13836
|
snapshot = prev;
|
|
13834
|
-
return
|
|
13837
|
+
return "";
|
|
13835
13838
|
});
|
|
13836
13839
|
return snapshot;
|
|
13837
13840
|
}, []);
|
|
@@ -13840,7 +13843,7 @@ function useStreamingAccumulator() {
|
|
|
13840
13843
|
let snapshot = "";
|
|
13841
13844
|
setStreamingText((prev) => {
|
|
13842
13845
|
snapshot = prev;
|
|
13843
|
-
return
|
|
13846
|
+
return "";
|
|
13844
13847
|
});
|
|
13845
13848
|
return snapshot;
|
|
13846
13849
|
}, []);
|
|
@@ -13931,7 +13934,8 @@ var RunScreen = ({
|
|
|
13931
13934
|
workdir,
|
|
13932
13935
|
maxLines: initialMaxLines,
|
|
13933
13936
|
markdownEnabled: markdownEnabled2,
|
|
13934
|
-
onExit
|
|
13937
|
+
onExit,
|
|
13938
|
+
onRegisterHandlers
|
|
13935
13939
|
}) => {
|
|
13936
13940
|
const [history, setHistory] = useState6([]);
|
|
13937
13941
|
const [errorMessage, setErrorMessage] = useState6(null);
|
|
@@ -13942,11 +13946,60 @@ var RunScreen = ({
|
|
|
13942
13946
|
const { exit } = useApp2();
|
|
13943
13947
|
const userTurnCountRef = useRef2(0);
|
|
13944
13948
|
const assistantTurnCountRef = useRef2(0);
|
|
13949
|
+
const isProcessingRef = useRef2(0);
|
|
13950
|
+
const executeQueryRef = useRef2(null);
|
|
13945
13951
|
const width = process.stdout.columns ?? 80;
|
|
13946
13952
|
const doExit = useCallback4(() => {
|
|
13947
13953
|
onExit?.();
|
|
13948
13954
|
exit();
|
|
13949
13955
|
}, [onExit, exit]);
|
|
13956
|
+
const executeQuery = useCallback4(async (message) => {
|
|
13957
|
+
isProcessingRef.current += 1;
|
|
13958
|
+
stream.start();
|
|
13959
|
+
try {
|
|
13960
|
+
let responseText;
|
|
13961
|
+
if (streamHandleQuery) {
|
|
13962
|
+
responseText = await streamHandleQuery(message, (chunk) => stream.append(chunk));
|
|
13963
|
+
} else {
|
|
13964
|
+
responseText = await handleQuery(message);
|
|
13965
|
+
}
|
|
13966
|
+
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
13967
|
+
const finalText = truncateForTerminal(rendered, maxLines);
|
|
13968
|
+
stream.finish();
|
|
13969
|
+
setHistory((h) => [...h, { role: "assistant", content: finalText }]);
|
|
13970
|
+
assistantTurnCountRef.current += 1;
|
|
13971
|
+
} catch (err) {
|
|
13972
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
13973
|
+
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
13974
|
+
setErrorMessage(msg);
|
|
13975
|
+
setHistory((h) => [
|
|
13976
|
+
...h,
|
|
13977
|
+
{ role: "tool", content: `❌ Error: ${msg}` }
|
|
13978
|
+
]);
|
|
13979
|
+
} finally {
|
|
13980
|
+
isProcessingRef.current -= 1;
|
|
13981
|
+
}
|
|
13982
|
+
}, [handleQuery, markdownEnabled2, maxLines, stream, streamHandleQuery, width]);
|
|
13983
|
+
useEffect5(() => {
|
|
13984
|
+
executeQueryRef.current = executeQuery;
|
|
13985
|
+
}, [executeQuery]);
|
|
13986
|
+
useEffect5(() => {
|
|
13987
|
+
if (!onRegisterHandlers)
|
|
13988
|
+
return;
|
|
13989
|
+
const handleNotification = async (message, _envEvent) => {
|
|
13990
|
+
setHistory((h) => [
|
|
13991
|
+
...h,
|
|
13992
|
+
{ role: "tool", content: `\uD83D\uDCE2 ${message}` }
|
|
13993
|
+
]);
|
|
13994
|
+
if (executeQueryRef.current) {
|
|
13995
|
+
await executeQueryRef.current(message);
|
|
13996
|
+
}
|
|
13997
|
+
};
|
|
13998
|
+
const isIdle = () => {
|
|
13999
|
+
return isProcessingRef.current === 0;
|
|
14000
|
+
};
|
|
14001
|
+
onRegisterHandlers({ onNotification: handleNotification, isIdle });
|
|
14002
|
+
}, [onRegisterHandlers]);
|
|
13950
14003
|
const handleSubmit = useCallback4(async (raw) => {
|
|
13951
14004
|
const trimmed = raw.trim();
|
|
13952
14005
|
if (!trimmed)
|
|
@@ -14008,38 +14061,14 @@ var RunScreen = ({
|
|
|
14008
14061
|
setHistory((h) => [...h, { role: "user", content: trimmed }]);
|
|
14009
14062
|
setUserHistory((uh) => [trimmed, ...uh]);
|
|
14010
14063
|
userTurnCountRef.current += 1;
|
|
14011
|
-
|
|
14012
|
-
try {
|
|
14013
|
-
let responseText;
|
|
14014
|
-
if (streamHandleQuery) {
|
|
14015
|
-
responseText = await streamHandleQuery(trimmed, (chunk) => stream.append(chunk));
|
|
14016
|
-
} else {
|
|
14017
|
-
responseText = await handleQuery(trimmed);
|
|
14018
|
-
}
|
|
14019
|
-
const rendered = markdownEnabled2 ? renderMarkdown(responseText, { width }) : responseText;
|
|
14020
|
-
const finalText = truncateForTerminal(rendered, maxLines);
|
|
14021
|
-
stream.finish();
|
|
14022
|
-
setHistory((h) => [...h, { role: "assistant", content: finalText }]);
|
|
14023
|
-
assistantTurnCountRef.current += 1;
|
|
14024
|
-
} catch (err) {
|
|
14025
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
14026
|
-
stream.fail(err instanceof Error ? err : new Error(msg));
|
|
14027
|
-
setErrorMessage(msg);
|
|
14028
|
-
setHistory((h) => [
|
|
14029
|
-
...h,
|
|
14030
|
-
{ role: "tool", content: `❌ Error: ${msg}` }
|
|
14031
|
-
]);
|
|
14032
|
-
}
|
|
14064
|
+
await executeQuery(trimmed);
|
|
14033
14065
|
}, [
|
|
14034
14066
|
doExit,
|
|
14035
14067
|
exit,
|
|
14036
|
-
|
|
14037
|
-
markdownEnabled2,
|
|
14068
|
+
executeQuery,
|
|
14038
14069
|
maxLines,
|
|
14039
14070
|
model,
|
|
14040
|
-
|
|
14041
|
-
streamHandleQuery,
|
|
14042
|
-
width
|
|
14071
|
+
workdir
|
|
14043
14072
|
]);
|
|
14044
14073
|
const handleCancel = useCallback4(() => {
|
|
14045
14074
|
doExit();
|
|
@@ -14082,7 +14111,7 @@ var RunTui_default = RunScreen;
|
|
|
14082
14111
|
|
|
14083
14112
|
// src/commands/run.ts
|
|
14084
14113
|
init_markdown();
|
|
14085
|
-
async function loadHandleQuery(options) {
|
|
14114
|
+
async function loadHandleQuery(options, hooks) {
|
|
14086
14115
|
const quiet = CliQuietModeService.getInstance().isQuiet();
|
|
14087
14116
|
const output = new OutputService2;
|
|
14088
14117
|
output.configure({ quiet });
|
|
@@ -14099,10 +14128,126 @@ async function loadHandleQuery(options) {
|
|
|
14099
14128
|
if (!env) {
|
|
14100
14129
|
throw new Error("Failed to create environment");
|
|
14101
14130
|
}
|
|
14102
|
-
|
|
14103
|
-
|
|
14104
|
-
|
|
14131
|
+
const sessionComponent = envService.getSession();
|
|
14132
|
+
if (!sessionComponent) {
|
|
14133
|
+
throw new Error("Failed to create session component");
|
|
14134
|
+
}
|
|
14135
|
+
const sessionManager = new SessionManager({
|
|
14136
|
+
sessionComponent,
|
|
14137
|
+
output,
|
|
14138
|
+
quiet: true
|
|
14139
|
+
});
|
|
14140
|
+
const sessionResult = await sessionManager.init(options.session, options.continue);
|
|
14141
|
+
const sessionId = sessionResult.sessionId;
|
|
14142
|
+
const queryExecutor = new QueryExecutor({
|
|
14143
|
+
env,
|
|
14144
|
+
sessionComponent,
|
|
14145
|
+
output,
|
|
14146
|
+
quiet: true,
|
|
14147
|
+
silent: true
|
|
14148
|
+
});
|
|
14149
|
+
let agentContext = undefined;
|
|
14150
|
+
if (options.agent && options.agent !== "default") {
|
|
14151
|
+
const agentComponent = env.getComponent("agent");
|
|
14152
|
+
const validation = validateActAgent(agentComponent, options.agent);
|
|
14153
|
+
if (!validation.valid) {
|
|
14154
|
+
output.error(validation.message);
|
|
14155
|
+
output.info("提示: roy-agent agents list");
|
|
14156
|
+
process.exit(1);
|
|
14157
|
+
}
|
|
14158
|
+
agentContext = buildActAgentContext(options.agent);
|
|
14159
|
+
}
|
|
14160
|
+
let eventSourceSystemPrompt;
|
|
14161
|
+
const rawEventSourceIds = options.eventSource;
|
|
14162
|
+
const eventSourceIds = Array.isArray(rawEventSourceIds) ? rawEventSourceIds.filter((s) => !!s) : rawEventSourceIds ? [rawEventSourceIds] : [];
|
|
14163
|
+
if (eventSourceIds.length > 0) {
|
|
14164
|
+
const eventSourceComponent = env.getComponent("event-source");
|
|
14165
|
+
if (!eventSourceComponent || typeof eventSourceComponent.startSource !== "function") {
|
|
14166
|
+
output.error("❌ 未找到事件源组件或 startSource 方法");
|
|
14167
|
+
output.info("请确保 EventSourceComponent 已正确注册");
|
|
14168
|
+
process.exit(1);
|
|
14169
|
+
}
|
|
14170
|
+
const summary = await startEventSources(eventSourceIds, eventSourceComponent, output);
|
|
14171
|
+
const preloadedPrompts = collectEventSourceSystemPrompts(eventSourceIds, eventSourceComponent);
|
|
14172
|
+
eventSourceSystemPrompt = preloadedPrompts.length > 0 ? joinResolvedSystemPrompts(preloadedPrompts) : undefined;
|
|
14173
|
+
if (eventSourceIds.length === 1 && summary.failedCount > 0) {
|
|
14174
|
+
process.exit(1);
|
|
14175
|
+
}
|
|
14176
|
+
}
|
|
14177
|
+
const llmComponent = envService.getLLM();
|
|
14178
|
+
queryExecutor.initStreamOutput(llmComponent ?? null);
|
|
14179
|
+
const handleQuery = async (message) => {
|
|
14180
|
+
const mergedContext = {
|
|
14181
|
+
...agentContext,
|
|
14182
|
+
model: options.model,
|
|
14183
|
+
eventSourceSystemPrompt,
|
|
14184
|
+
metadata: {
|
|
14185
|
+
...agentContext?.metadata ?? {},
|
|
14186
|
+
defaultAgentName: options.defaultAgentName
|
|
14187
|
+
}
|
|
14188
|
+
};
|
|
14189
|
+
const result = await queryExecutor.execute(message, sessionId, {
|
|
14190
|
+
showReasoning: options.reasoning ?? true,
|
|
14191
|
+
showToolCalls: options.toolCalls ?? true,
|
|
14192
|
+
showToolResults: options.toolResults ?? false
|
|
14193
|
+
}, undefined, mergedContext);
|
|
14194
|
+
return String(result ?? "");
|
|
14195
|
+
};
|
|
14196
|
+
const taskEventHandler = new TaskEventHandler({
|
|
14197
|
+
env,
|
|
14198
|
+
enabled: true
|
|
14199
|
+
});
|
|
14200
|
+
const eventHandler = new EventHandler({
|
|
14201
|
+
env,
|
|
14202
|
+
eventTypes: ["task.background.*", "event-source.event.*"],
|
|
14203
|
+
formatter: new EventMessageFormatter({ prefix: "[通知]" }),
|
|
14204
|
+
isIdle: hooks?.isIdle ?? (() => true),
|
|
14205
|
+
sessionComponent,
|
|
14206
|
+
onEvent: async (_message) => {},
|
|
14207
|
+
onEventWithEnv: async (formattedEvent) => {
|
|
14208
|
+
if (hooks?.onNotification) {
|
|
14209
|
+
await hooks.onNotification(formattedEvent.message, formattedEvent.envEvent);
|
|
14210
|
+
}
|
|
14211
|
+
}
|
|
14212
|
+
});
|
|
14213
|
+
return {
|
|
14214
|
+
handleQuery,
|
|
14215
|
+
envService,
|
|
14216
|
+
env,
|
|
14217
|
+
sessionId,
|
|
14218
|
+
queryExecutor,
|
|
14219
|
+
agentContext,
|
|
14220
|
+
eventSourceSystemPrompt,
|
|
14221
|
+
sessionComponent,
|
|
14222
|
+
eventHandler,
|
|
14223
|
+
taskEventHandler
|
|
14224
|
+
};
|
|
14225
|
+
}
|
|
14226
|
+
function createStreamHandleQuery(queryExecutor, sessionId, options, agentContext, eventSourceSystemPrompt) {
|
|
14227
|
+
return async (message, onChunk) => {
|
|
14228
|
+
queryExecutor.setChunkCallback((event) => {
|
|
14229
|
+
if (event.type === "llm.text") {
|
|
14230
|
+
if (event.delta) {
|
|
14231
|
+
onChunk(event.delta);
|
|
14232
|
+
} else if (event.content) {
|
|
14233
|
+
onChunk(event.content);
|
|
14234
|
+
}
|
|
14235
|
+
}
|
|
14105
14236
|
});
|
|
14237
|
+
const mergedContext = {
|
|
14238
|
+
...agentContext,
|
|
14239
|
+
model: options.model,
|
|
14240
|
+
eventSourceSystemPrompt,
|
|
14241
|
+
metadata: {
|
|
14242
|
+
...agentContext?.metadata ?? {},
|
|
14243
|
+
defaultAgentName: options.defaultAgentName
|
|
14244
|
+
}
|
|
14245
|
+
};
|
|
14246
|
+
const result = await queryExecutor.execute(message, sessionId, {
|
|
14247
|
+
showReasoning: options.reasoning ?? true,
|
|
14248
|
+
showToolCalls: options.toolCalls ?? true,
|
|
14249
|
+
showToolResults: options.toolResults ?? false
|
|
14250
|
+
}, undefined, mergedContext);
|
|
14106
14251
|
return String(result ?? "");
|
|
14107
14252
|
};
|
|
14108
14253
|
}
|
|
@@ -14142,6 +14287,41 @@ function createRunCommand() {
|
|
|
14142
14287
|
}).option("env", {
|
|
14143
14288
|
type: "string",
|
|
14144
14289
|
describe: "Environment name"
|
|
14290
|
+
}).option("session", {
|
|
14291
|
+
type: "string",
|
|
14292
|
+
describe: "指定会话 ID(注: -s 已被 --system-prompt 占用)"
|
|
14293
|
+
}).option("continue", {
|
|
14294
|
+
alias: "c",
|
|
14295
|
+
type: "boolean",
|
|
14296
|
+
describe: "继续上次会话",
|
|
14297
|
+
default: false
|
|
14298
|
+
}).option("reasoning", {
|
|
14299
|
+
alias: "r",
|
|
14300
|
+
type: "boolean",
|
|
14301
|
+
describe: "显示 AI 思考过程",
|
|
14302
|
+
default: true
|
|
14303
|
+
}).option("tool-calls", {
|
|
14304
|
+
type: "boolean",
|
|
14305
|
+
describe: "显示工具调用",
|
|
14306
|
+
default: true
|
|
14307
|
+
}).option("tool-results", {
|
|
14308
|
+
type: "boolean",
|
|
14309
|
+
describe: "显示工具执行结果",
|
|
14310
|
+
default: false
|
|
14311
|
+
}).option("event-source", {
|
|
14312
|
+
alias: "es",
|
|
14313
|
+
type: "array",
|
|
14314
|
+
string: true,
|
|
14315
|
+
describe: "启动时一并启动的事件源 ID(可多次指定,支持 --es a --es b)"
|
|
14316
|
+
}).option("agent", {
|
|
14317
|
+
alias: "a",
|
|
14318
|
+
type: "string",
|
|
14319
|
+
describe: "指定使用的 agent (如 explore, general)"
|
|
14320
|
+
}).option("default-agent-name", {
|
|
14321
|
+
alias: "dan",
|
|
14322
|
+
type: "string",
|
|
14323
|
+
describe: "Default agent 名字(默认 Roy,可被覆盖)",
|
|
14324
|
+
default: "Roy"
|
|
14145
14325
|
}),
|
|
14146
14326
|
handler: async (argv) => {
|
|
14147
14327
|
if (argv.markdown === false) {
|
|
@@ -14150,18 +14330,44 @@ function createRunCommand() {
|
|
|
14150
14330
|
setMarkdownEnabled(true);
|
|
14151
14331
|
}
|
|
14152
14332
|
const maxLines = Number.parseInt(argv.maxLines ?? "500", 10);
|
|
14153
|
-
const
|
|
14333
|
+
const runState = {
|
|
14334
|
+
isIdle: () => true,
|
|
14335
|
+
onNotification: () => {}
|
|
14336
|
+
};
|
|
14337
|
+
const {
|
|
14338
|
+
handleQuery,
|
|
14339
|
+
queryExecutor,
|
|
14340
|
+
sessionId,
|
|
14341
|
+
agentContext,
|
|
14342
|
+
eventSourceSystemPrompt,
|
|
14343
|
+
eventHandler,
|
|
14344
|
+
taskEventHandler
|
|
14345
|
+
} = await loadHandleQuery(argv, {
|
|
14346
|
+
isIdle: () => runState.isIdle(),
|
|
14347
|
+
onNotification: (msg, envEvent) => runState.onNotification(msg, envEvent)
|
|
14348
|
+
});
|
|
14349
|
+
const streamHandleQuery = createStreamHandleQuery(queryExecutor, sessionId, argv, agentContext, eventSourceSystemPrompt);
|
|
14350
|
+
const stopEventHandler = eventHandler.start();
|
|
14351
|
+
const stopTaskEventHandler = taskEventHandler.start();
|
|
14154
14352
|
const { waitUntilExit } = render(React6.createElement(RunTui_default, {
|
|
14155
14353
|
handleQuery,
|
|
14354
|
+
streamHandleQuery,
|
|
14156
14355
|
model: argv.model,
|
|
14157
14356
|
workdir: argv.workdir,
|
|
14158
14357
|
maxLines,
|
|
14159
14358
|
markdownEnabled: argv.markdown !== false,
|
|
14359
|
+
onRegisterHandlers: (handlers) => {
|
|
14360
|
+
runState.onNotification = handlers.onNotification;
|
|
14361
|
+
runState.isIdle = handlers.isIdle;
|
|
14362
|
+
},
|
|
14160
14363
|
onExit: () => {}
|
|
14161
14364
|
}), { exitOnCtrlC: true });
|
|
14162
14365
|
try {
|
|
14163
14366
|
await waitUntilExit();
|
|
14164
14367
|
} finally {
|
|
14368
|
+
stopEventHandler();
|
|
14369
|
+
stopTaskEventHandler();
|
|
14370
|
+
queryExecutor.dispose();
|
|
14165
14371
|
process.exit(0);
|
|
14166
14372
|
}
|
|
14167
14373
|
}
|
|
@@ -14174,7 +14380,7 @@ import React8 from "react";
|
|
|
14174
14380
|
import { render as render2 } from "ink";
|
|
14175
14381
|
|
|
14176
14382
|
// src/ChatTui.tsx
|
|
14177
|
-
import { useEffect as
|
|
14383
|
+
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
14178
14384
|
import { Box as Box7, useApp as useApp3 } from "ink";
|
|
14179
14385
|
init_markdown();
|
|
14180
14386
|
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
@@ -14193,7 +14399,7 @@ var ChatScreen = ({
|
|
|
14193
14399
|
const stream = useStreamingAccumulator();
|
|
14194
14400
|
const { exit } = useApp3();
|
|
14195
14401
|
const width = process.stdout.columns ?? 80;
|
|
14196
|
-
|
|
14402
|
+
useEffect6(() => {
|
|
14197
14403
|
let cancelled = false;
|
|
14198
14404
|
stream.start();
|
|
14199
14405
|
(async () => {
|
|
@@ -25057,10 +25263,10 @@ var LspInstallCommand = {
|
|
|
25057
25263
|
console.log(`
|
|
25058
25264
|
\uD83D\uDCE6 LSP Server Status
|
|
25059
25265
|
`);
|
|
25060
|
-
for (const
|
|
25061
|
-
const isInstalled = installed.includes(
|
|
25266
|
+
for (const pkg of LSP_PACKAGES) {
|
|
25267
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
25062
25268
|
const status = isInstalled ? "✓ installed" : "✗ not installed";
|
|
25063
|
-
console.log(` ${status.padEnd(20)} ${
|
|
25269
|
+
console.log(` ${status.padEnd(20)} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25064
25270
|
}
|
|
25065
25271
|
console.log(`
|
|
25066
25272
|
${installed.length}/${LSP_PACKAGES.length} installed
|
|
@@ -25111,10 +25317,10 @@ ${installed.length}/${LSP_PACKAGES.length} installed
|
|
|
25111
25317
|
console.log(`
|
|
25112
25318
|
\uD83D\uDCE6 Available LSP Servers
|
|
25113
25319
|
`);
|
|
25114
|
-
for (const
|
|
25115
|
-
const isInstalled = installer.isInstalled(
|
|
25320
|
+
for (const pkg of LSP_PACKAGES) {
|
|
25321
|
+
const isInstalled = installer.isInstalled(pkg.npmPackage);
|
|
25116
25322
|
const status = isInstalled ? "✓" : "○";
|
|
25117
|
-
console.log(` ${status} ${
|
|
25323
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25118
25324
|
}
|
|
25119
25325
|
console.log(`
|
|
25120
25326
|
Run 'roy-agent lsp install <language>' to install specific servers`);
|
|
@@ -25143,11 +25349,11 @@ var LspListCommand = {
|
|
|
25143
25349
|
const installer = createInstaller2();
|
|
25144
25350
|
const installed = installer.getInstalledPackages();
|
|
25145
25351
|
if (argv.json) {
|
|
25146
|
-
const result = LSP_PACKAGES2.map((
|
|
25147
|
-
serverId:
|
|
25148
|
-
npmPackage:
|
|
25149
|
-
description:
|
|
25150
|
-
installed: installed.includes(
|
|
25352
|
+
const result = LSP_PACKAGES2.map((pkg) => ({
|
|
25353
|
+
serverId: pkg.serverId,
|
|
25354
|
+
npmPackage: pkg.npmPackage,
|
|
25355
|
+
description: pkg.description,
|
|
25356
|
+
installed: installed.includes(pkg.serverId)
|
|
25151
25357
|
}));
|
|
25152
25358
|
console.log(JSON.stringify(result, null, 2));
|
|
25153
25359
|
return;
|
|
@@ -25155,14 +25361,14 @@ var LspListCommand = {
|
|
|
25155
25361
|
console.log(`
|
|
25156
25362
|
\uD83D\uDCE6 LSP Servers
|
|
25157
25363
|
`);
|
|
25158
|
-
for (const
|
|
25159
|
-
const isInstalled = installed.includes(
|
|
25364
|
+
for (const pkg of LSP_PACKAGES2) {
|
|
25365
|
+
const isInstalled = installed.includes(pkg.serverId);
|
|
25160
25366
|
const status = isInstalled ? "✓" : "○";
|
|
25161
25367
|
const installedText = isInstalled ? "installed" : "not installed";
|
|
25162
|
-
console.log(` ${status} ${
|
|
25163
|
-
console.log(` ${
|
|
25368
|
+
console.log(` ${status} ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25369
|
+
console.log(` ${pkg.npmPackage} - ${installedText}`);
|
|
25164
25370
|
if (argv.verbose && isInstalled) {
|
|
25165
|
-
const verify = installer.verify(
|
|
25371
|
+
const verify = installer.verify(pkg.serverId);
|
|
25166
25372
|
if (verify.binary) {
|
|
25167
25373
|
console.log(` Binary: ${verify.binary}`);
|
|
25168
25374
|
}
|
|
@@ -25200,12 +25406,12 @@ var LspCheckCommand = {
|
|
|
25200
25406
|
const servers2 = argv.serverId ? LSP_PACKAGES3.filter((p) => p.serverId === argv.serverId) : LSP_PACKAGES3;
|
|
25201
25407
|
const result = {
|
|
25202
25408
|
config: config.toJSON(),
|
|
25203
|
-
servers: servers2.map((
|
|
25204
|
-
serverId:
|
|
25205
|
-
npmPackage:
|
|
25206
|
-
description:
|
|
25207
|
-
installed: installer.isInstalled(
|
|
25208
|
-
verify: installer.verify(
|
|
25409
|
+
servers: servers2.map((pkg) => ({
|
|
25410
|
+
serverId: pkg.serverId,
|
|
25411
|
+
npmPackage: pkg.npmPackage,
|
|
25412
|
+
description: pkg.description,
|
|
25413
|
+
installed: installer.isInstalled(pkg.npmPackage),
|
|
25414
|
+
verify: installer.verify(pkg.serverId)
|
|
25209
25415
|
}))
|
|
25210
25416
|
};
|
|
25211
25417
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -25223,12 +25429,12 @@ var LspCheckCommand = {
|
|
|
25223
25429
|
\uD83D\uDCE6 LSP Servers Status
|
|
25224
25430
|
`);
|
|
25225
25431
|
let hasIssues = false;
|
|
25226
|
-
for (const
|
|
25227
|
-
const verify = installer.verify(
|
|
25432
|
+
for (const pkg of servers) {
|
|
25433
|
+
const verify = installer.verify(pkg.serverId);
|
|
25228
25434
|
const installed = verify.installed ? "✓ Installed" : "✗ Not installed";
|
|
25229
|
-
console.log(` ${
|
|
25435
|
+
console.log(` ${pkg.serverId.padEnd(12)} ${pkg.description}`);
|
|
25230
25436
|
console.log(` ${installed}`);
|
|
25231
|
-
console.log(` Package: ${
|
|
25437
|
+
console.log(` Package: ${pkg.npmPackage}`);
|
|
25232
25438
|
if (verify.binary) {
|
|
25233
25439
|
console.log(` Binary in PATH: ${verify.binary}`);
|
|
25234
25440
|
} else if (verify.installed) {
|
|
@@ -25303,11 +25509,11 @@ function readPackageInfo(packageName) {
|
|
|
25303
25509
|
const localPkgPath = join5(packageName, "package.json");
|
|
25304
25510
|
if (existsSync4(localPkgPath)) {
|
|
25305
25511
|
try {
|
|
25306
|
-
const
|
|
25512
|
+
const pkg = JSON.parse(readFileSync3(localPkgPath, "utf-8"));
|
|
25307
25513
|
return {
|
|
25308
|
-
version:
|
|
25309
|
-
name:
|
|
25310
|
-
description:
|
|
25514
|
+
version: pkg.version ?? "0.0.0",
|
|
25515
|
+
name: pkg.name ?? packageName,
|
|
25516
|
+
description: pkg.description
|
|
25311
25517
|
};
|
|
25312
25518
|
} catch (err) {
|
|
25313
25519
|
console.warn(`⚠️ Failed to parse local package.json at '${localPkgPath}': ${err}`);
|
|
@@ -25327,11 +25533,11 @@ function readPackageInfo(packageName) {
|
|
|
25327
25533
|
for (const pkgPath of searchPaths) {
|
|
25328
25534
|
try {
|
|
25329
25535
|
if (existsSync4(pkgPath)) {
|
|
25330
|
-
const
|
|
25536
|
+
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
25331
25537
|
return {
|
|
25332
|
-
version:
|
|
25333
|
-
name:
|
|
25334
|
-
description:
|
|
25538
|
+
version: pkg.version ?? "0.0.0",
|
|
25539
|
+
name: pkg.name ?? bareName,
|
|
25540
|
+
description: pkg.description
|
|
25335
25541
|
};
|
|
25336
25542
|
}
|
|
25337
25543
|
} catch (err) {
|
|
@@ -25670,9 +25876,9 @@ Examples:
|
|
|
25670
25876
|
--plugin reminder Enable iteration reminder
|
|
25671
25877
|
--plugin tslsp code-check Enable multiple plugins`;
|
|
25672
25878
|
async function runCli() {
|
|
25673
|
-
const
|
|
25879
|
+
const version = getPackageVersion();
|
|
25674
25880
|
const yargs = yargsLib;
|
|
25675
|
-
await yargs(hideBin(process.argv)).scriptName("roy-agent").version(
|
|
25881
|
+
await yargs(hideBin(process.argv)).scriptName("roy-agent").version(version).option("quiet", {
|
|
25676
25882
|
describe: "Quiet mode (default: on, use --no-quiet to enable logging)",
|
|
25677
25883
|
type: "boolean",
|
|
25678
25884
|
default: true,
|