nolo-cli 0.1.35 → 0.1.37
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 +5 -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/platformChatProvider.ts +17 -9
- package/agent-runtime/providerResolution.ts +71 -11
- 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 +15 -88
- package/cli/client/localRuntimeAdapter.ts +108 -3
- package/cli/machineWsRunDispatch.ts +45 -5
- package/client/agentRun.test.ts +2 -32
- package/client/agentRun.ts +15 -88
- package/client/localRuntimeAdapter.test.ts +64 -0
- package/client/localRuntimeAdapter.ts +108 -3
- package/machineWsRunDispatch.ts +45 -5
- package/package.json +3 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AgentRuntimeAgentConfig } from "./hostAdapter";
|
|
2
2
|
import type { AgentRuntimeHost, AgentRuntimeToolPolicy } from "./types";
|
|
3
3
|
|
|
4
|
+
type EnvLike = Record<string, string | undefined>;
|
|
5
|
+
|
|
4
6
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
5
7
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
6
8
|
}
|
|
@@ -56,6 +58,11 @@ function runtimeToolNamesFromPolicy(policy: AgentRuntimeToolPolicy | undefined)
|
|
|
56
58
|
return stringArray(policy?.runtimeTools);
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
function readPositiveNumber(value: unknown) {
|
|
62
|
+
const parsed = Number(value);
|
|
63
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
59
66
|
export function mergeAgentRuntimeToolPolicies(
|
|
60
67
|
base?: AgentRuntimeToolPolicy,
|
|
61
68
|
override?: AgentRuntimeToolPolicy,
|
|
@@ -110,6 +117,44 @@ export function resolveRequestedRuntimeToolNames(args: {
|
|
|
110
117
|
]);
|
|
111
118
|
}
|
|
112
119
|
|
|
120
|
+
export function resolveCurrentRunRuntimeToolPolicy(
|
|
121
|
+
agentConfig: Pick<AgentRuntimeAgentConfig, "runtimeToolPolicy" | "runtimeBinding"> | null | undefined,
|
|
122
|
+
): AgentRuntimeToolPolicy | undefined {
|
|
123
|
+
const runtimeBinding = runtimeBindingRecord(agentConfig?.runtimeBinding);
|
|
124
|
+
return normalizeAgentRuntimeToolPolicy(
|
|
125
|
+
runtimeBinding?.runtimeToolPolicySnapshot ??
|
|
126
|
+
agentConfig?.runtimeToolPolicy ??
|
|
127
|
+
runtimeBinding?.runtimeToolPolicy,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function resolveLocalRuntimeEnvFromPolicy(
|
|
132
|
+
runtimeEnv: EnvLike,
|
|
133
|
+
policy?: AgentRuntimeToolPolicy,
|
|
134
|
+
): EnvLike {
|
|
135
|
+
const enablesWorktreeShell =
|
|
136
|
+
Array.isArray(policy?.runtimeTools) &&
|
|
137
|
+
policy.runtimeTools.includes("execShell") &&
|
|
138
|
+
policy.shell?.enabled === true &&
|
|
139
|
+
policy.shell?.mode === "worktree";
|
|
140
|
+
return {
|
|
141
|
+
...runtimeEnv,
|
|
142
|
+
...(policy?.workspace?.cwd ? { NOLO_LOCAL_WORKTREE: policy.workspace.cwd } : {}),
|
|
143
|
+
...(enablesWorktreeShell && !runtimeEnv.NOLO_LOCAL_SHELL_MODE
|
|
144
|
+
? { NOLO_LOCAL_SHELL_MODE: "worktree" }
|
|
145
|
+
: {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function resolveLocalWorkspaceExecutorOptionsFromPolicy(
|
|
150
|
+
policy?: AgentRuntimeToolPolicy,
|
|
151
|
+
) {
|
|
152
|
+
const maxOutputBytes = readPositiveNumber(policy?.shell?.maxOutputBytes);
|
|
153
|
+
return {
|
|
154
|
+
...(maxOutputBytes ? { commandOutputLimit: Math.floor(maxOutputBytes) } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
113
158
|
function policyRequestsHostedWorkspace(policy: AgentRuntimeToolPolicy | undefined) {
|
|
114
159
|
if (!policy) return false;
|
|
115
160
|
const workspaceMode = policy.workspace?.mode;
|
|
@@ -150,12 +195,7 @@ export function resolveEffectiveRuntimeToolPolicy(args: {
|
|
|
150
195
|
taskRunControl?: { runtimeToolPolicy?: unknown } | null;
|
|
151
196
|
host?: AgentRuntimeHost;
|
|
152
197
|
}): AgentRuntimeToolPolicy | undefined {
|
|
153
|
-
const agentPolicy =
|
|
154
|
-
args.agentConfig.runtimeToolPolicy ??
|
|
155
|
-
(isRecord(args.agentConfig.runtimeBinding)
|
|
156
|
-
? args.agentConfig.runtimeBinding.runtimeToolPolicy
|
|
157
|
-
: undefined),
|
|
158
|
-
);
|
|
198
|
+
const agentPolicy = resolveCurrentRunRuntimeToolPolicy(args.agentConfig);
|
|
159
199
|
const taskPolicy = normalizeAgentRuntimeToolPolicy(
|
|
160
200
|
args.taskRunControl?.runtimeToolPolicy,
|
|
161
201
|
);
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
readlink,
|
|
7
7
|
rm,
|
|
8
8
|
symlink,
|
|
9
|
+
unlink,
|
|
9
10
|
} from "node:fs/promises";
|
|
10
11
|
import { dirname, join, resolve, sep } from "node:path";
|
|
11
12
|
|
|
@@ -73,22 +74,23 @@ export async function collectWorkspacePackageLinks(workspacePath: string) {
|
|
|
73
74
|
() => []
|
|
74
75
|
);
|
|
75
76
|
const nodeModulesPath = join(workspacePath, "node_modules");
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
77
|
+
|
|
78
|
+
const linksPromises = packageDirs
|
|
79
|
+
.filter((entry) => entry.isDirectory())
|
|
80
|
+
.map(async (entry) => {
|
|
81
|
+
const target = join(packagesRoot, entry.name);
|
|
82
|
+
const name = await readPackageName(join(target, "package.json")).catch(
|
|
83
|
+
() => null
|
|
84
|
+
);
|
|
85
|
+
if (!name) return null;
|
|
86
|
+
return {
|
|
87
|
+
name,
|
|
88
|
+
target,
|
|
89
|
+
linkPath: packageLinkPath(nodeModulesPath, name),
|
|
90
|
+
};
|
|
89
91
|
});
|
|
90
|
-
}
|
|
91
92
|
|
|
93
|
+
const links = (await Promise.all(linksPromises)).filter(Boolean) as WorkspacePackageLink[];
|
|
92
94
|
return links;
|
|
93
95
|
}
|
|
94
96
|
|
|
@@ -106,7 +108,7 @@ async function ensureWorkspacePackageLink(link: WorkspacePackageLink) {
|
|
|
106
108
|
if (!existingTarget) {
|
|
107
109
|
throw new Error(`Cannot replace non-symlink workspace package path: ${link.linkPath}`);
|
|
108
110
|
}
|
|
109
|
-
await
|
|
111
|
+
await unlink(link.linkPath);
|
|
110
112
|
}
|
|
111
113
|
await symlink(link.target, link.linkPath, "dir");
|
|
112
114
|
return true;
|
|
@@ -134,7 +136,7 @@ async function ensureWorkspaceNodeModulesDirectory(workspacePath: string) {
|
|
|
134
136
|
if (symlinkTarget) {
|
|
135
137
|
const resolvedTarget = resolve(dirname(nodeModulesPath), symlinkTarget);
|
|
136
138
|
if (!isInsideWorkspace(workspacePath, resolvedTarget)) {
|
|
137
|
-
await
|
|
139
|
+
await unlink(nodeModulesPath);
|
|
138
140
|
}
|
|
139
141
|
}
|
|
140
142
|
await mkdir(nodeModulesPath, { recursive: true });
|
|
@@ -150,12 +152,10 @@ export async function ensureWorkspacePackageLinks(workspacePath: string) {
|
|
|
150
152
|
};
|
|
151
153
|
}
|
|
152
154
|
await ensureWorkspaceNodeModulesDirectory(workspacePath);
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
}
|
|
155
|
+
const results = await Promise.all(
|
|
156
|
+
links.map((link) => ensureWorkspacePackageLink(link))
|
|
157
|
+
);
|
|
158
|
+
const createdOrUpdated = results.filter(Boolean).length;
|
|
159
159
|
return {
|
|
160
160
|
workspacePath,
|
|
161
161
|
links,
|
|
@@ -173,7 +173,7 @@ export async function prepareGitTaskWorkspace(args: {
|
|
|
173
173
|
return { path: args.env.NOLO_LOCAL_WORKTREE };
|
|
174
174
|
}
|
|
175
175
|
const cwd = args.cwd ?? process.cwd();
|
|
176
|
-
const root = await runGitForTaskWorkspace(["rev-parse", "--show-toplevel"], cwd);
|
|
176
|
+
const root = resolve(await runGitForTaskWorkspace(["rev-parse", "--show-toplevel"], cwd));
|
|
177
177
|
if (isFormalTaskWorkspacePath(root)) {
|
|
178
178
|
await ensureWorkspacePackageLinks(root);
|
|
179
179
|
return { path: root };
|
package/agent-runtime/types.ts
CHANGED
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,14 @@ 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
|
-
type ScriptBridgeDecision = {
|
|
80
|
-
hasAuthToken: boolean;
|
|
81
|
-
scriptPathExists: boolean;
|
|
82
|
-
};
|
|
83
75
|
|
|
84
76
|
const SERVER_PLATFORM_TOOL_NAMES = new Set([
|
|
85
77
|
"addTableRow",
|
|
@@ -94,10 +86,9 @@ const SERVER_PLATFORM_TOOL_NAMES = new Set([
|
|
|
94
86
|
]);
|
|
95
87
|
|
|
96
88
|
const KNOWN_SERVER_PLATFORM_AGENT_KEYS = new Set([
|
|
97
|
-
|
|
98
|
-
NOLO_FULLSTACK_AGENT_KEY,
|
|
89
|
+
MIMO_MONTH_AGENT_KEY,
|
|
99
90
|
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
100
|
-
|
|
91
|
+
WIN_CODEX_AGENT_KEY,
|
|
101
92
|
NOLO_SENIOR_FULLSTACK_AGENT_KEY,
|
|
102
93
|
]);
|
|
103
94
|
|
|
@@ -125,10 +116,6 @@ const KNOWN_SERVER_PLATFORM_AGENT_ALIASES = new Set([
|
|
|
125
116
|
"reviewer",
|
|
126
117
|
]);
|
|
127
118
|
|
|
128
|
-
export function shouldUseScriptBridge(decision: ScriptBridgeDecision) {
|
|
129
|
-
return !decision.hasAuthToken && decision.scriptPathExists;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
119
|
export function findServerPlatformTools(toolNames?: string[]) {
|
|
133
120
|
if (!Array.isArray(toolNames)) return [];
|
|
134
121
|
return toolNames.filter((toolName) => SERVER_PLATFORM_TOOL_NAMES.has(toolName));
|
|
@@ -514,60 +501,6 @@ function buildTransportErrorHint(serverUrl: string, error: unknown) {
|
|
|
514
501
|
return detail;
|
|
515
502
|
}
|
|
516
503
|
|
|
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
504
|
async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string) {
|
|
572
505
|
options.output.write(`\n${options.agentName} -> working...\n`);
|
|
573
506
|
|
|
@@ -927,8 +860,6 @@ async function readStreamingAgentRun(
|
|
|
927
860
|
|
|
928
861
|
export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
929
862
|
const authToken = resolveAuthToken(options.env);
|
|
930
|
-
const scriptPath = join(options.scriptDir, "chatWithAgent.ts");
|
|
931
|
-
const scriptPathExists = (options.scriptPathExists ?? existsSync)(scriptPath);
|
|
932
863
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
933
864
|
|
|
934
865
|
if (runtimeMode === "local") {
|
|
@@ -969,17 +900,13 @@ export async function runAgentTurn(options: RunAgentTurnOptions) {
|
|
|
969
900
|
}
|
|
970
901
|
}
|
|
971
902
|
|
|
972
|
-
if (
|
|
973
|
-
|
|
903
|
+
if (!authToken) {
|
|
904
|
+
options.output.write(
|
|
905
|
+
"[nolo] This install needs an auth token before it can talk to agents.\n" +
|
|
906
|
+
"Run `nolo login`, or set AUTH_TOKEN / NOLO_SERVER for non-interactive runs.\n"
|
|
907
|
+
);
|
|
908
|
+
return { exitCode: 1 };
|
|
974
909
|
}
|
|
975
910
|
|
|
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
911
|
return runHttpAgentTurn(options, authToken);
|
|
985
912
|
}
|