nolo-cli 0.1.36 → 0.1.38
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/README.md +11 -1
- package/agent-runtime/agentRecordConfig.ts +5 -1
- package/agent-runtime/index.ts +3 -0
- package/agent-runtime/localLoop.ts +1 -2
- package/agent-runtime/localToolPolicy.ts +8 -5
- package/agent-runtime/localWorkspaceTools.ts +68 -180
- package/agent-runtime/runtimeToolPolicy.ts +46 -6
- package/agent-runtime/taskWorkspace.ts +23 -23
- package/agent-runtime/types.ts +0 -1
- package/agentAliases.ts +50 -30
- package/agentRunCommand.ts +1 -1
- package/agentRuntimeLocal.ts +3 -0
- package/cli/agentAliases.ts +50 -30
- package/cli/agentRunCommand.ts +1 -1
- package/cli/agentRuntimeLocal.ts +3 -0
- package/cli/client/agentRun.ts +83 -105
- package/cli/client/localRuntimeAdapter.ts +22 -1
- package/cli/machineWsRunDispatch.ts +3 -5
- package/client/agentRun.test.ts +2 -32
- package/client/agentRun.ts +83 -105
- package/client/localRuntimeAdapter.test.ts +64 -0
- package/client/localRuntimeAdapter.ts +22 -1
- package/machineWsRunDispatch.ts +3 -5
- package/package.json +3 -3
package/agentAliases.ts
CHANGED
|
@@ -1,52 +1,72 @@
|
|
|
1
1
|
export const PLATFORM_DEMO_USER_ID = "b2e06f801f";
|
|
2
|
-
export const FRONTEND_IMPLEMENTER_AGENT_ID = "01FRONTENDAG0000000115N4E1";
|
|
3
|
-
export const FRONTEND_IMPLEMENTER_AGENT_KEY =
|
|
4
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${FRONTEND_IMPLEMENTER_AGENT_ID}`;
|
|
5
|
-
export const NOLO_FRONTEND_AGENT_ID = FRONTEND_IMPLEMENTER_AGENT_ID;
|
|
6
|
-
export const NOLO_FRONTEND_AGENT_KEY = FRONTEND_IMPLEMENTER_AGENT_KEY;
|
|
7
2
|
export const NOLO_PROJECT_MANAGER_AGENT_ID = "01NOLOPROJMGR00000000MSVGG";
|
|
8
3
|
export const NOLO_PROJECT_MANAGER_AGENT_KEY =
|
|
9
4
|
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_PROJECT_MANAGER_AGENT_ID}`;
|
|
10
|
-
export const NOLO_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000001J740Q";
|
|
11
|
-
export const NOLO_FULLSTACK_AGENT_KEY =
|
|
12
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_FULLSTACK_AGENT_ID}`;
|
|
13
5
|
export const NOLO_SENIOR_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000000T3XR4";
|
|
14
6
|
export const NOLO_SENIOR_FULLSTACK_AGENT_KEY =
|
|
15
7
|
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_SENIOR_FULLSTACK_AGENT_ID}`;
|
|
16
|
-
export const
|
|
17
|
-
export const
|
|
18
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${
|
|
8
|
+
export const NOLO_FRONTEND_AGENT_ID = "01FRONTENDAG0000000115N4E1";
|
|
9
|
+
export const NOLO_FRONTEND_AGENT_KEY =
|
|
10
|
+
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_FRONTEND_AGENT_ID}`;
|
|
11
|
+
export const WIN_CODEX_AGENT_ID = "WINCODEX00000000FQ0LK0";
|
|
12
|
+
export const WIN_CODEX_AGENT_KEY =
|
|
13
|
+
`agent-0e95801d90-${WIN_CODEX_AGENT_ID}`;
|
|
14
|
+
export const WIN_QWEN_AGENT_ID = "01CUSTOMCODEA00000001JEAG3";
|
|
15
|
+
export const WIN_QWEN_AGENT_KEY =
|
|
16
|
+
`agent-0e95801d90-${WIN_QWEN_AGENT_ID}`;
|
|
17
|
+
export const MIMO_MONTH_AGENT_ID = "01MIMO25MONTH0000000NEW001";
|
|
18
|
+
export const MIMO_MONTH_AGENT_KEY =
|
|
19
|
+
`agent-0e95801d90-${MIMO_MONTH_AGENT_ID}`;
|
|
19
20
|
|
|
20
21
|
const AGENT_ALIAS_TO_KEY: Record<string, string> = {
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"
|
|
22
|
+
// Win Codex (高智力终审与架构把关)
|
|
23
|
+
"win-codex": WIN_CODEX_AGENT_KEY,
|
|
24
|
+
"wincodex": WIN_CODEX_AGENT_KEY,
|
|
25
|
+
"win codex": WIN_CODEX_AGENT_KEY,
|
|
26
|
+
"nolo-reviewer": WIN_CODEX_AGENT_KEY,
|
|
27
|
+
reviewer: WIN_CODEX_AGENT_KEY,
|
|
28
|
+
"nolo-code-review": WIN_CODEX_AGENT_KEY,
|
|
29
|
+
"code-review": WIN_CODEX_AGENT_KEY,
|
|
30
|
+
review: WIN_CODEX_AGENT_KEY,
|
|
31
|
+
"代码审查": WIN_CODEX_AGENT_KEY,
|
|
32
|
+
"nolo 代码审查": WIN_CODEX_AGENT_KEY,
|
|
33
|
+
|
|
34
|
+
// 包月 Mimo (全栈业务代码与常规杂活物理实体)
|
|
35
|
+
"包月mimo": MIMO_MONTH_AGENT_KEY,
|
|
36
|
+
"包月mimo2.5": MIMO_MONTH_AGENT_KEY,
|
|
37
|
+
"mimo-month": MIMO_MONTH_AGENT_KEY,
|
|
38
|
+
"nolo-fullstack": MIMO_MONTH_AGENT_KEY,
|
|
39
|
+
fullstack: MIMO_MONTH_AGENT_KEY,
|
|
40
|
+
"full-stack": MIMO_MONTH_AGENT_KEY,
|
|
41
|
+
"全栈": MIMO_MONTH_AGENT_KEY,
|
|
42
|
+
"nolo 全栈工程师": MIMO_MONTH_AGENT_KEY,
|
|
43
|
+
|
|
44
|
+
// 产品前端实现
|
|
45
|
+
"frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
46
|
+
"frontend-agent": NOLO_FRONTEND_AGENT_KEY,
|
|
47
|
+
"frontend-implementer": NOLO_FRONTEND_AGENT_KEY,
|
|
48
|
+
"nolo-frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
49
|
+
"nolo frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
50
|
+
"前端agent": NOLO_FRONTEND_AGENT_KEY,
|
|
51
|
+
"前端 agent": NOLO_FRONTEND_AGENT_KEY,
|
|
52
|
+
"前端": NOLO_FRONTEND_AGENT_KEY,
|
|
53
|
+
|
|
54
|
+
// Win Qwen (本地轻量无Token消耗辅助)
|
|
55
|
+
"win-qwen": WIN_QWEN_AGENT_KEY,
|
|
56
|
+
"win qwen": WIN_QWEN_AGENT_KEY,
|
|
57
|
+
"winqwen": WIN_QWEN_AGENT_KEY,
|
|
58
|
+
|
|
59
|
+
// 其他辅助/特定角色
|
|
28
60
|
"nolo-project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
29
61
|
"project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
30
62
|
"nolo-pm": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
31
63
|
pm: NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
32
64
|
"项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
33
65
|
"nolo 项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
34
|
-
"nolo-fullstack": NOLO_FULLSTACK_AGENT_KEY,
|
|
35
|
-
fullstack: NOLO_FULLSTACK_AGENT_KEY,
|
|
36
|
-
"full-stack": NOLO_FULLSTACK_AGENT_KEY,
|
|
37
|
-
"全栈": NOLO_FULLSTACK_AGENT_KEY,
|
|
38
|
-
"nolo 全栈工程师": NOLO_FULLSTACK_AGENT_KEY,
|
|
39
66
|
"senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
40
67
|
"nolo-senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
41
68
|
"高级全栈": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
42
69
|
"nolo 高级全栈工程师": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
43
|
-
"nolo-reviewer": NOLO_REVIEW_AGENT_KEY,
|
|
44
|
-
reviewer: NOLO_REVIEW_AGENT_KEY,
|
|
45
|
-
"nolo-code-review": NOLO_REVIEW_AGENT_KEY,
|
|
46
|
-
"code-review": NOLO_REVIEW_AGENT_KEY,
|
|
47
|
-
review: NOLO_REVIEW_AGENT_KEY,
|
|
48
|
-
"代码审查": NOLO_REVIEW_AGENT_KEY,
|
|
49
|
-
"nolo 代码审查": NOLO_REVIEW_AGENT_KEY,
|
|
50
70
|
};
|
|
51
71
|
|
|
52
72
|
function parseAgentKeyFromInput(raw: string): string {
|
package/agentRunCommand.ts
CHANGED
|
@@ -400,7 +400,7 @@ function buildTaskWorktreeEnv(args: {
|
|
|
400
400
|
function writeUsage(output: OutputLike) {
|
|
401
401
|
output.write(
|
|
402
402
|
"Usage: nolo agent run <agent> <message> [--local|--server|--auto] [--continue <dialogId>] [--cwd <path>] [--max-tool-rounds <n>]\n" +
|
|
403
|
-
" nolo agent run --agent <agent> --msg <message> [--image <url-or-path>] [--space <spaceId>] [--category <name>] [--inherit-from-dialog <dialog>] [--task-row-dbkey <key>] [--bg] [--timeout-ms <n>] [--no-stream]\n"
|
|
403
|
+
" nolo agent run --agent <agent> (--msg <message>|--msg-file <path>) [--image <url-or-path>] [--space <spaceId>] [--category <name>] [--inherit-from-dialog <dialog>] [--task-row-dbkey <key>] [--bg] [--timeout-ms <n>] [--no-stream]\n"
|
|
404
404
|
);
|
|
405
405
|
}
|
|
406
406
|
|
package/agentRuntimeLocal.ts
CHANGED
|
@@ -16,6 +16,9 @@ export {
|
|
|
16
16
|
parsePlatformChatCompletionData,
|
|
17
17
|
parsePlatformChatCompletionResponse,
|
|
18
18
|
resolveAgentRuntimeConfigFromRecord,
|
|
19
|
+
resolveCurrentRunRuntimeToolPolicy,
|
|
20
|
+
resolveLocalRuntimeEnvFromPolicy,
|
|
21
|
+
resolveLocalWorkspaceExecutorOptionsFromPolicy,
|
|
19
22
|
resolvePlatformChatProviderConfig,
|
|
20
23
|
resolveLocalToolPolicy,
|
|
21
24
|
resolveOpenAiCompatibleProviderConfig,
|
package/cli/agentAliases.ts
CHANGED
|
@@ -1,52 +1,72 @@
|
|
|
1
1
|
export const PLATFORM_DEMO_USER_ID = "b2e06f801f";
|
|
2
|
-
export const FRONTEND_IMPLEMENTER_AGENT_ID = "01FRONTENDAG0000000115N4E1";
|
|
3
|
-
export const FRONTEND_IMPLEMENTER_AGENT_KEY =
|
|
4
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${FRONTEND_IMPLEMENTER_AGENT_ID}`;
|
|
5
|
-
export const NOLO_FRONTEND_AGENT_ID = FRONTEND_IMPLEMENTER_AGENT_ID;
|
|
6
|
-
export const NOLO_FRONTEND_AGENT_KEY = FRONTEND_IMPLEMENTER_AGENT_KEY;
|
|
7
2
|
export const NOLO_PROJECT_MANAGER_AGENT_ID = "01NOLOPROJMGR00000000MSVGG";
|
|
8
3
|
export const NOLO_PROJECT_MANAGER_AGENT_KEY =
|
|
9
4
|
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_PROJECT_MANAGER_AGENT_ID}`;
|
|
10
|
-
export const NOLO_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000001J740Q";
|
|
11
|
-
export const NOLO_FULLSTACK_AGENT_KEY =
|
|
12
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_FULLSTACK_AGENT_ID}`;
|
|
13
5
|
export const NOLO_SENIOR_FULLSTACK_AGENT_ID = "01NOLOFULLSTK00000000T3XR4";
|
|
14
6
|
export const NOLO_SENIOR_FULLSTACK_AGENT_KEY =
|
|
15
7
|
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_SENIOR_FULLSTACK_AGENT_ID}`;
|
|
16
|
-
export const
|
|
17
|
-
export const
|
|
18
|
-
`agent-${PLATFORM_DEMO_USER_ID}-${
|
|
8
|
+
export const NOLO_FRONTEND_AGENT_ID = "01FRONTENDAG0000000115N4E1";
|
|
9
|
+
export const NOLO_FRONTEND_AGENT_KEY =
|
|
10
|
+
`agent-${PLATFORM_DEMO_USER_ID}-${NOLO_FRONTEND_AGENT_ID}`;
|
|
11
|
+
export const WIN_CODEX_AGENT_ID = "WINCODEX00000000FQ0LK0";
|
|
12
|
+
export const WIN_CODEX_AGENT_KEY =
|
|
13
|
+
`agent-0e95801d90-${WIN_CODEX_AGENT_ID}`;
|
|
14
|
+
export const WIN_QWEN_AGENT_ID = "01CUSTOMCODEA00000001JEAG3";
|
|
15
|
+
export const WIN_QWEN_AGENT_KEY =
|
|
16
|
+
`agent-0e95801d90-${WIN_QWEN_AGENT_ID}`;
|
|
17
|
+
export const MIMO_MONTH_AGENT_ID = "01MIMO25MONTH0000000NEW001";
|
|
18
|
+
export const MIMO_MONTH_AGENT_KEY =
|
|
19
|
+
`agent-0e95801d90-${MIMO_MONTH_AGENT_ID}`;
|
|
19
20
|
|
|
20
21
|
const AGENT_ALIAS_TO_KEY: Record<string, string> = {
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"
|
|
22
|
+
// Win Codex (高智力终审与架构把关)
|
|
23
|
+
"win-codex": WIN_CODEX_AGENT_KEY,
|
|
24
|
+
"wincodex": WIN_CODEX_AGENT_KEY,
|
|
25
|
+
"win codex": WIN_CODEX_AGENT_KEY,
|
|
26
|
+
"nolo-reviewer": WIN_CODEX_AGENT_KEY,
|
|
27
|
+
reviewer: WIN_CODEX_AGENT_KEY,
|
|
28
|
+
"nolo-code-review": WIN_CODEX_AGENT_KEY,
|
|
29
|
+
"code-review": WIN_CODEX_AGENT_KEY,
|
|
30
|
+
review: WIN_CODEX_AGENT_KEY,
|
|
31
|
+
"代码审查": WIN_CODEX_AGENT_KEY,
|
|
32
|
+
"nolo 代码审查": WIN_CODEX_AGENT_KEY,
|
|
33
|
+
|
|
34
|
+
// 包月 Mimo (全栈业务代码与常规杂活物理实体)
|
|
35
|
+
"包月mimo": MIMO_MONTH_AGENT_KEY,
|
|
36
|
+
"包月mimo2.5": MIMO_MONTH_AGENT_KEY,
|
|
37
|
+
"mimo-month": MIMO_MONTH_AGENT_KEY,
|
|
38
|
+
"nolo-fullstack": MIMO_MONTH_AGENT_KEY,
|
|
39
|
+
fullstack: MIMO_MONTH_AGENT_KEY,
|
|
40
|
+
"full-stack": MIMO_MONTH_AGENT_KEY,
|
|
41
|
+
"全栈": MIMO_MONTH_AGENT_KEY,
|
|
42
|
+
"nolo 全栈工程师": MIMO_MONTH_AGENT_KEY,
|
|
43
|
+
|
|
44
|
+
// 产品前端实现
|
|
45
|
+
"frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
46
|
+
"frontend-agent": NOLO_FRONTEND_AGENT_KEY,
|
|
47
|
+
"frontend-implementer": NOLO_FRONTEND_AGENT_KEY,
|
|
48
|
+
"nolo-frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
49
|
+
"nolo frontend": NOLO_FRONTEND_AGENT_KEY,
|
|
50
|
+
"前端agent": NOLO_FRONTEND_AGENT_KEY,
|
|
51
|
+
"前端 agent": NOLO_FRONTEND_AGENT_KEY,
|
|
52
|
+
"前端": NOLO_FRONTEND_AGENT_KEY,
|
|
53
|
+
|
|
54
|
+
// Win Qwen (本地轻量无Token消耗辅助)
|
|
55
|
+
"win-qwen": WIN_QWEN_AGENT_KEY,
|
|
56
|
+
"win qwen": WIN_QWEN_AGENT_KEY,
|
|
57
|
+
"winqwen": WIN_QWEN_AGENT_KEY,
|
|
58
|
+
|
|
59
|
+
// 其他辅助/特定角色
|
|
28
60
|
"nolo-project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
29
61
|
"project-manager": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
30
62
|
"nolo-pm": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
31
63
|
pm: NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
32
64
|
"项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
33
65
|
"nolo 项目经理": NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
34
|
-
"nolo-fullstack": NOLO_FULLSTACK_AGENT_KEY,
|
|
35
|
-
fullstack: NOLO_FULLSTACK_AGENT_KEY,
|
|
36
|
-
"full-stack": NOLO_FULLSTACK_AGENT_KEY,
|
|
37
|
-
"全栈": NOLO_FULLSTACK_AGENT_KEY,
|
|
38
|
-
"nolo 全栈工程师": NOLO_FULLSTACK_AGENT_KEY,
|
|
39
66
|
"senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
40
67
|
"nolo-senior-fullstack": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
41
68
|
"高级全栈": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
42
69
|
"nolo 高级全栈工程师": NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
43
|
-
"nolo-reviewer": NOLO_REVIEW_AGENT_KEY,
|
|
44
|
-
reviewer: NOLO_REVIEW_AGENT_KEY,
|
|
45
|
-
"nolo-code-review": NOLO_REVIEW_AGENT_KEY,
|
|
46
|
-
"code-review": NOLO_REVIEW_AGENT_KEY,
|
|
47
|
-
review: NOLO_REVIEW_AGENT_KEY,
|
|
48
|
-
"代码审查": NOLO_REVIEW_AGENT_KEY,
|
|
49
|
-
"nolo 代码审查": NOLO_REVIEW_AGENT_KEY,
|
|
50
70
|
};
|
|
51
71
|
|
|
52
72
|
function parseAgentKeyFromInput(raw: string): string {
|
package/cli/agentRunCommand.ts
CHANGED
|
@@ -400,7 +400,7 @@ function buildTaskWorktreeEnv(args: {
|
|
|
400
400
|
function writeUsage(output: OutputLike) {
|
|
401
401
|
output.write(
|
|
402
402
|
"Usage: nolo agent run <agent> <message> [--local|--server|--auto] [--continue <dialogId>] [--cwd <path>] [--max-tool-rounds <n>]\n" +
|
|
403
|
-
" nolo agent run --agent <agent> --msg <message> [--image <url-or-path>] [--space <spaceId>] [--category <name>] [--inherit-from-dialog <dialog>] [--task-row-dbkey <key>] [--bg] [--timeout-ms <n>] [--no-stream]\n"
|
|
403
|
+
" nolo agent run --agent <agent> (--msg <message>|--msg-file <path>) [--image <url-or-path>] [--space <spaceId>] [--category <name>] [--inherit-from-dialog <dialog>] [--task-row-dbkey <key>] [--bg] [--timeout-ms <n>] [--no-stream]\n"
|
|
404
404
|
);
|
|
405
405
|
}
|
|
406
406
|
|
package/cli/agentRuntimeLocal.ts
CHANGED
|
@@ -16,6 +16,9 @@ export {
|
|
|
16
16
|
parsePlatformChatCompletionData,
|
|
17
17
|
parsePlatformChatCompletionResponse,
|
|
18
18
|
resolveAgentRuntimeConfigFromRecord,
|
|
19
|
+
resolveCurrentRunRuntimeToolPolicy,
|
|
20
|
+
resolveLocalRuntimeEnvFromPolicy,
|
|
21
|
+
resolveLocalWorkspaceExecutorOptionsFromPolicy,
|
|
19
22
|
resolvePlatformChatProviderConfig,
|
|
20
23
|
resolveLocalToolPolicy,
|
|
21
24
|
resolveOpenAiCompatibleProviderConfig,
|
package/cli/client/agentRun.ts
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
1
|
import { join } from "node:path";
|
|
3
2
|
import { runLocalAgentTurn } from "../agentRuntimeLocal";
|
|
4
3
|
import { LOCAL_AGENT_CONFIG_MISSING_CODE } from "../../agent-runtime/localLoop";
|
|
5
4
|
import {
|
|
6
|
-
|
|
7
|
-
NOLO_FULLSTACK_AGENT_KEY,
|
|
5
|
+
MIMO_MONTH_AGENT_KEY,
|
|
8
6
|
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
9
|
-
NOLO_REVIEW_AGENT_KEY,
|
|
10
7
|
NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
8
|
+
WIN_CODEX_AGENT_KEY,
|
|
11
9
|
} from "../agentAliases";
|
|
12
10
|
import type { LocalAgentToolEvent } from "../../agent-runtime/localLoop";
|
|
13
11
|
import type { AgentRuntimeHostAdapter, AgentRuntimeRequestedMode } from "../agentRuntimeLocal";
|
|
14
12
|
import { createCliLocalRuntimeAdapter } from "./localRuntimeAdapter";
|
|
15
13
|
import { createStreamingTextWriter } from "./streamingOutput";
|
|
16
14
|
import { prependTaskRunPrompt, type TaskRunPromptContext } from "./taskRunPrompt";
|
|
17
|
-
|
|
18
|
-
type EnvLike = Record<string, string | undefined>;
|
|
19
|
-
|
|
15
|
+
|
|
16
|
+
type EnvLike = Record<string, string | undefined>;
|
|
17
|
+
|
|
20
18
|
type OutputLike = {
|
|
21
19
|
write(chunk: string): unknown;
|
|
22
20
|
};
|
|
@@ -48,7 +46,7 @@ type RunAgentTurnOptions = {
|
|
|
48
46
|
noStream?: boolean;
|
|
49
47
|
noDefaultTestRoot?: boolean;
|
|
50
48
|
scriptDir: string;
|
|
51
|
-
env: EnvLike;
|
|
49
|
+
env: EnvLike;
|
|
52
50
|
output: OutputLike;
|
|
53
51
|
runtimeMode?: AgentRuntimeRequestedMode;
|
|
54
52
|
localRuntimeAdapter?: AgentRuntimeHostAdapter;
|
|
@@ -66,20 +64,55 @@ type RunAgentTurnOptions = {
|
|
|
66
64
|
errorCode?: string;
|
|
67
65
|
toolEvidence?: TaskRunToolEvidence;
|
|
68
66
|
}) => Promise<void>;
|
|
69
|
-
scriptPathExists?: (path: string) => boolean;
|
|
70
67
|
fetchImpl?: typeof fetch;
|
|
71
68
|
};
|
|
72
|
-
|
|
69
|
+
|
|
73
70
|
export type RunAgentTurnResult = {
|
|
74
71
|
exitCode: number;
|
|
75
72
|
dialogId?: string;
|
|
76
73
|
streamInterrupted?: boolean;
|
|
77
74
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
75
|
+
|
|
76
|
+
class Spinner {
|
|
77
|
+
private timer: any = null;
|
|
78
|
+
private frameIndex = 0;
|
|
79
|
+
private frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
80
|
+
private isTTY: boolean;
|
|
81
|
+
|
|
82
|
+
constructor(
|
|
83
|
+
private output: OutputLike,
|
|
84
|
+
private text: string
|
|
85
|
+
) {
|
|
86
|
+
this.isTTY = Boolean((output as any).isTTY ?? process.stdout.isTTY);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
start() {
|
|
90
|
+
if (!this.isTTY) {
|
|
91
|
+
this.output.write(`\n${this.text}...\n`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
this.frameIndex = 0;
|
|
96
|
+
this.output.write(`\x1b[36m${this.frames[0]}\x1b[39m ${this.text}...`);
|
|
97
|
+
|
|
98
|
+
this.timer = setInterval(() => {
|
|
99
|
+
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
100
|
+
this.output.write(`\r\x1b[36m${this.frames[this.frameIndex]}\x1b[39m ${this.text}...`);
|
|
101
|
+
}, 80);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
stop() {
|
|
105
|
+
if (this.timer) {
|
|
106
|
+
clearInterval(this.timer);
|
|
107
|
+
this.timer = null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (this.isTTY) {
|
|
111
|
+
this.output.write("\r\x1b[K");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
83
116
|
|
|
84
117
|
const SERVER_PLATFORM_TOOL_NAMES = new Set([
|
|
85
118
|
"addTableRow",
|
|
@@ -94,10 +127,9 @@ const SERVER_PLATFORM_TOOL_NAMES = new Set([
|
|
|
94
127
|
]);
|
|
95
128
|
|
|
96
129
|
const KNOWN_SERVER_PLATFORM_AGENT_KEYS = new Set([
|
|
97
|
-
|
|
98
|
-
NOLO_FULLSTACK_AGENT_KEY,
|
|
130
|
+
MIMO_MONTH_AGENT_KEY,
|
|
99
131
|
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
100
|
-
|
|
132
|
+
WIN_CODEX_AGENT_KEY,
|
|
101
133
|
NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
102
134
|
]);
|
|
103
135
|
|
|
@@ -125,10 +157,6 @@ const KNOWN_SERVER_PLATFORM_AGENT_ALIASES = new Set([
|
|
|
125
157
|
"reviewer",
|
|
126
158
|
]);
|
|
127
159
|
|
|
128
|
-
export function shouldUseScriptBridge(decision: ScriptBridgeDecision) {
|
|
129
|
-
return !decision.hasAuthToken && decision.scriptPathExists;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
160
|
export function findServerPlatformTools(toolNames?: string[]) {
|
|
133
161
|
if (!Array.isArray(toolNames)) return [];
|
|
134
162
|
return toolNames.filter((toolName) => SERVER_PLATFORM_TOOL_NAMES.has(toolName));
|
|
@@ -514,62 +542,9 @@ function buildTransportErrorHint(serverUrl: string, error: unknown) {
|
|
|
514
542
|
return detail;
|
|
515
543
|
}
|
|
516
544
|
|
|
517
|
-
async function runScriptBridge(options: RunAgentTurnOptions, scriptPath: string) {
|
|
518
|
-
options.output.write(`\n${options.agentName} -> working via local script...\n\n`);
|
|
519
|
-
const proc = Bun.spawn({
|
|
520
|
-
cmd: [
|
|
521
|
-
process.execPath,
|
|
522
|
-
scriptPath,
|
|
523
|
-
"--agent",
|
|
524
|
-
options.agentKey,
|
|
525
|
-
"--server",
|
|
526
|
-
options.serverUrl,
|
|
527
|
-
"--msg",
|
|
528
|
-
options.message,
|
|
529
|
-
...(options.taskRunContext?.rowDbKey
|
|
530
|
-
? ["--task-row-dbkey", options.taskRunContext.rowDbKey]
|
|
531
|
-
: []),
|
|
532
|
-
...(options.taskRunContext?.taskRunId
|
|
533
|
-
? ["--task-run-id", options.taskRunContext.taskRunId]
|
|
534
|
-
: []),
|
|
535
|
-
...(options.taskRunContext?.workItemId
|
|
536
|
-
? ["--work-item-id", options.taskRunContext.workItemId]
|
|
537
|
-
: []),
|
|
538
|
-
...(options.taskRunContext?.artifactIds?.length
|
|
539
|
-
? ["--artifact-ids", options.taskRunContext.artifactIds.join(",")]
|
|
540
|
-
: []),
|
|
541
|
-
...(options.noDefaultTestRoot ? ["--no-default-test-root"] : []),
|
|
542
|
-
...(options.continueDialogId
|
|
543
|
-
? ["--continue", options.continueDialogId]
|
|
544
|
-
: []),
|
|
545
|
-
...(options.spaceId ? ["--space", options.spaceId] : []),
|
|
546
|
-
...(options.category ? ["--category", options.category] : []),
|
|
547
|
-
...(options.inheritedFromDialogKey
|
|
548
|
-
? ["--inherit-from-dialog", options.inheritedFromDialogKey]
|
|
549
|
-
: []),
|
|
550
|
-
...(options.background ? ["--bg"] : []),
|
|
551
|
-
...(typeof options.timeoutMs === "number" ? ["--timeout-ms", String(options.timeoutMs)] : []),
|
|
552
|
-
...(options.noStream ? ["--no-stream"] : []),
|
|
553
|
-
],
|
|
554
|
-
stdin: "inherit",
|
|
555
|
-
stdout: "inherit",
|
|
556
|
-
stderr: "inherit",
|
|
557
|
-
env: {
|
|
558
|
-
...process.env,
|
|
559
|
-
...options.env,
|
|
560
|
-
ASSISTANT_LABEL: options.agentName,
|
|
561
|
-
},
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
const exitCode = await proc.exited;
|
|
565
|
-
if (exitCode !== 0) {
|
|
566
|
-
options.output.write(`\n[nolo] Agent run exited with code ${exitCode}.\n`);
|
|
567
|
-
}
|
|
568
|
-
return { exitCode };
|
|
569
|
-
}
|
|
570
|
-
|
|
571
545
|
async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string) {
|
|
572
|
-
options.output
|
|
546
|
+
const spinner = new Spinner(options.output, `${options.agentName} -> working`);
|
|
547
|
+
spinner.start();
|
|
573
548
|
|
|
574
549
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
575
550
|
let res: Response;
|
|
@@ -623,14 +598,16 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
|
|
|
623
598
|
...(typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {}),
|
|
624
599
|
stream: !options.noStream && !options.background,
|
|
625
600
|
}),
|
|
626
|
-
});
|
|
627
|
-
} catch (error) {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
601
|
+
});
|
|
602
|
+
} catch (error) {
|
|
603
|
+
spinner.stop();
|
|
604
|
+
options.output.write(buildTransportErrorHint(options.serverUrl, error));
|
|
605
|
+
return { exitCode: 1 };
|
|
606
|
+
}
|
|
607
|
+
|
|
632
608
|
const contentType = res.headers.get("content-type") || "";
|
|
633
609
|
if (contentType.includes("text/event-stream") && res.body) {
|
|
610
|
+
spinner.stop();
|
|
634
611
|
const result = await readStreamingAgentRun(options, res);
|
|
635
612
|
await recordTaskRunOutcome({
|
|
636
613
|
options,
|
|
@@ -644,14 +621,15 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
|
|
|
644
621
|
});
|
|
645
622
|
return result;
|
|
646
623
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
624
|
+
|
|
625
|
+
spinner.stop();
|
|
626
|
+
let data: any = {};
|
|
627
|
+
try {
|
|
628
|
+
data = await res.json();
|
|
629
|
+
} catch {
|
|
630
|
+
data = {};
|
|
631
|
+
}
|
|
632
|
+
|
|
655
633
|
if (!res.ok) {
|
|
656
634
|
options.output.write(`[nolo] Agent request failed: HTTP ${res.status}\n`);
|
|
657
635
|
if (data?.error || data?.message) {
|
|
@@ -758,7 +736,8 @@ async function runLocalAgentTurnForCli(
|
|
|
758
736
|
return { exitCode: 1 };
|
|
759
737
|
}
|
|
760
738
|
|
|
761
|
-
options.output
|
|
739
|
+
const spinner = new Spinner(options.output, `${options.agentName} -> working locally`);
|
|
740
|
+
spinner.start();
|
|
762
741
|
const toolEvents: LocalAgentToolEvent[] = [];
|
|
763
742
|
try {
|
|
764
743
|
const traceLocalTools = shouldTraceLocalTools(options);
|
|
@@ -783,11 +762,15 @@ async function runLocalAgentTurnForCli(
|
|
|
783
762
|
? {
|
|
784
763
|
onToolEvent: (event) => {
|
|
785
764
|
if (collectToolEvidence) toolEvents.push(event);
|
|
786
|
-
if (traceLocalTools)
|
|
765
|
+
if (traceLocalTools) {
|
|
766
|
+
spinner.stop();
|
|
767
|
+
options.output.write(formatToolTraceEvent(event));
|
|
768
|
+
}
|
|
787
769
|
},
|
|
788
770
|
}
|
|
789
771
|
: {}),
|
|
790
772
|
});
|
|
773
|
+
spinner.stop();
|
|
791
774
|
const content = result.content.trim();
|
|
792
775
|
if (content) {
|
|
793
776
|
options.output.write(`\n${options.agentName} > ${content}\n`);
|
|
@@ -803,6 +786,7 @@ async function runLocalAgentTurnForCli(
|
|
|
803
786
|
});
|
|
804
787
|
return { exitCode: 0, dialogId: result.dialogId };
|
|
805
788
|
} catch (error) {
|
|
789
|
+
spinner.stop();
|
|
806
790
|
if (settings.reportFailure) {
|
|
807
791
|
options.output.write(
|
|
808
792
|
`[nolo] Local agent run failed: ${
|
|
@@ -927,8 +911,6 @@ async function readStreamingAgentRun(
|
|
|
927
911
|
|
|
928
912
|
export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
929
913
|
const authToken = resolveAuthToken(options.env);
|
|
930
|
-
const scriptPath = join(options.scriptDir, "chatWithAgent.ts");
|
|
931
|
-
const scriptPathExists = (options.scriptPathExists ?? existsSync)(scriptPath);
|
|
932
914
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
933
915
|
|
|
934
916
|
if (runtimeMode === "local") {
|
|
@@ -969,17 +951,13 @@ export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
|
969
951
|
}
|
|
970
952
|
}
|
|
971
953
|
|
|
972
|
-
if (
|
|
973
|
-
|
|
954
|
+
if (!authToken) {
|
|
955
|
+
options.output.write(
|
|
956
|
+
"[nolo] This install needs an auth token before it can talk to agents.\n" +
|
|
957
|
+
"Run `nolo login`, or set AUTH_TOKEN / NOLO_SERVER for non-interactive runs.\n"
|
|
958
|
+
);
|
|
959
|
+
return { exitCode: 1 };
|
|
974
960
|
}
|
|
975
961
|
|
|
976
|
-
if (!authToken) {
|
|
977
|
-
options.output.write(
|
|
978
|
-
"[nolo] This install needs an auth token before it can talk to agents.\n" +
|
|
979
|
-
"Set AUTH_TOKEN, or use the repo-local CLI where the dev script bridge is available.\n"
|
|
980
|
-
);
|
|
981
|
-
return { exitCode: 1 };
|
|
982
|
-
}
|
|
983
|
-
|
|
984
962
|
return runHttpAgentTurn(options, authToken);
|
|
985
963
|
}
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
parsePlatformChatCompletionData,
|
|
17
17
|
parsePlatformChatCompletionResponse,
|
|
18
18
|
resolvePlatformChatProviderConfig,
|
|
19
|
+
resolveCurrentRunRuntimeToolPolicy,
|
|
20
|
+
resolveLocalWorkspaceExecutorOptionsFromPolicy,
|
|
19
21
|
resolveRequestedRuntimeToolNames,
|
|
20
22
|
shouldUsePlatformChatProvider,
|
|
21
23
|
} from "../agentRuntimeLocal";
|
|
@@ -337,9 +339,15 @@ function buildLocalToolExecutors(args: {
|
|
|
337
339
|
env: EnvLike;
|
|
338
340
|
fetchImpl: typeof fetch;
|
|
339
341
|
localToolExecutors?: CliLocalRuntimeAdapterDeps["localToolExecutors"];
|
|
342
|
+
commandTimeoutMs?: number;
|
|
343
|
+
commandOutputLimit?: number;
|
|
340
344
|
}) {
|
|
341
345
|
return {
|
|
342
|
-
...createLocalWorkspaceToolExecutors({
|
|
346
|
+
...createLocalWorkspaceToolExecutors({
|
|
347
|
+
workspaceRoot: args.workspaceRoot,
|
|
348
|
+
commandTimeoutMs: args.commandTimeoutMs,
|
|
349
|
+
commandOutputLimit: args.commandOutputLimit,
|
|
350
|
+
}),
|
|
343
351
|
...buildServerPlatformToolExecutors({
|
|
344
352
|
env: args.env,
|
|
345
353
|
fetchImpl: args.fetchImpl,
|
|
@@ -434,11 +442,13 @@ export function createCliLocalRuntimeAdapter(
|
|
|
434
442
|
? { defaultCwd: deps.cwd }
|
|
435
443
|
: { cwd: deps.cwd }
|
|
436
444
|
);
|
|
445
|
+
let runtimeToolExecutionLimits: ReturnType<typeof resolveLocalWorkspaceExecutorOptionsFromPolicy> = {};
|
|
437
446
|
let localToolExecutors = buildLocalToolExecutors({
|
|
438
447
|
workspaceRoot: workspaceSession.workspaceRoot,
|
|
439
448
|
env: deps.env,
|
|
440
449
|
fetchImpl,
|
|
441
450
|
localToolExecutors: deps.localToolExecutors,
|
|
451
|
+
...runtimeToolExecutionLimits,
|
|
442
452
|
});
|
|
443
453
|
|
|
444
454
|
async function activateAgentWorkspaceSession(args: {
|
|
@@ -458,6 +468,7 @@ export function createCliLocalRuntimeAdapter(
|
|
|
458
468
|
env: deps.env,
|
|
459
469
|
fetchImpl,
|
|
460
470
|
localToolExecutors: deps.localToolExecutors,
|
|
471
|
+
...runtimeToolExecutionLimits,
|
|
461
472
|
});
|
|
462
473
|
deps.output?.write(formatWorkspaceSessionActivation(workspaceSession));
|
|
463
474
|
}
|
|
@@ -478,7 +489,17 @@ export function createCliLocalRuntimeAdapter(
|
|
|
478
489
|
toolNames: requestedToolNames,
|
|
479
490
|
env: deps.env,
|
|
480
491
|
});
|
|
492
|
+
runtimeToolExecutionLimits = resolveLocalWorkspaceExecutorOptionsFromPolicy(
|
|
493
|
+
resolveCurrentRunRuntimeToolPolicy(agentConfig),
|
|
494
|
+
);
|
|
481
495
|
await activateAgentWorkspaceSession({ agentRef, agentConfig });
|
|
496
|
+
localToolExecutors = buildLocalToolExecutors({
|
|
497
|
+
workspaceRoot: workspaceSession.workspaceRoot,
|
|
498
|
+
env: deps.env,
|
|
499
|
+
fetchImpl,
|
|
500
|
+
localToolExecutors: deps.localToolExecutors,
|
|
501
|
+
...runtimeToolExecutionLimits,
|
|
502
|
+
});
|
|
482
503
|
return agentConfig;
|
|
483
504
|
},
|
|
484
505
|
loadDialogHistory: async (dialogId) => readDialogMessages({
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runLocalAgentTurn, type LocalAgentToolEvent } from "../agent-runtime/localLoop";
|
|
2
|
+
import { resolveLocalRuntimeEnvFromPolicy } from "../agent-runtime/runtimeToolPolicy";
|
|
2
3
|
import {
|
|
3
4
|
assertMachineRunAllowed as defaultAssertMachineRunAllowed,
|
|
4
5
|
resolveMachineRunPermissionPolicy as defaultResolveMachineRunPermissionPolicy,
|
|
@@ -225,11 +226,8 @@ function mergeToolNames(...values: unknown[]) {
|
|
|
225
226
|
return names;
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
function localRuntimeEnvFromPolicy(runtimeEnv: EnvLike, policy?: ConnectorRuntimePolicy): EnvLike {
|
|
229
|
-
return
|
|
230
|
-
...runtimeEnv,
|
|
231
|
-
...(policy?.workspace?.cwd ? { NOLO_LOCAL_WORKTREE: policy.workspace.cwd } : {}),
|
|
232
|
-
};
|
|
229
|
+
export function localRuntimeEnvFromPolicy(runtimeEnv: EnvLike, policy?: ConnectorRuntimePolicy): EnvLike {
|
|
230
|
+
return resolveLocalRuntimeEnvFromPolicy(runtimeEnv, policy);
|
|
233
231
|
}
|
|
234
232
|
|
|
235
233
|
function forwardedUserAuthToken(parsed: any): string {
|