talentos 1.1.5 → 1.2.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/agent/adapters.js +73 -85
- package/dist/agent/codex-policy.js +72 -0
- package/dist/agent/codex-probe.js +424 -0
- package/dist/agent/mcp-entry.js +5 -2
- package/dist/agent/native/approvals.js +188 -0
- package/dist/agent/native/config.js +118 -0
- package/dist/agent/native/disqualify.js +46 -0
- package/dist/agent/native/env.js +29 -0
- package/dist/agent/native/gate.js +102 -0
- package/dist/agent/native/hook-entry.js +170 -0
- package/dist/agent/native/launch.js +91 -0
- package/dist/agent/native/paths.js +137 -0
- package/dist/agent/native/policy.js +653 -0
- package/dist/agent/native/probe.js +474 -0
- package/dist/agent/native/shell.js +174 -0
- package/dist/agent/native/workspace.js +87 -0
- package/dist/agent/serve.js +77 -8
- package/dist/args.js +1 -0
- package/dist/commands/agent-native.js +64 -0
- package/dist/commands/agent-serve.js +14 -11
- package/dist/commands/agent.js +5 -1
- package/dist/mcp-proxy.js +47 -6
- package/dist/upload-file.js +172 -0
- package/package.json +1 -1
package/dist/agent/adapters.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { execFile, spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
3
|
+
import { rm } from "node:fs/promises";
|
|
4
|
+
import { delimiter, dirname, join } from "node:path";
|
|
6
5
|
import { createInterface } from "node:readline";
|
|
7
6
|
import { fileURLToPath } from "node:url";
|
|
8
7
|
import { promisify } from "node:util";
|
|
@@ -10,6 +9,9 @@ import { writePrivateFile } from "../agent-config.js";
|
|
|
10
9
|
import { redactAgentOutput, } from "../agent-link.js";
|
|
11
10
|
import { gatewayLauncherPath } from "../gateway-install.js";
|
|
12
11
|
import { providerPathEnv, resolveProviderBinary } from "../provider-binary.js";
|
|
12
|
+
import { codexRoomArgs, ROOM_TOOLS } from "./codex-policy.js";
|
|
13
|
+
import { CodexBoundaryError, probeCodexBoundary } from "./codex-probe.js";
|
|
14
|
+
import { prepareOwnerLaunch } from "./native/launch.js";
|
|
13
15
|
const CHILD_ENV = [
|
|
14
16
|
"HOME",
|
|
15
17
|
"PATH",
|
|
@@ -26,26 +28,9 @@ const CHILD_ENV = [
|
|
|
26
28
|
"CODEX_HOME",
|
|
27
29
|
"CLAUDE_CONFIG_DIR",
|
|
28
30
|
];
|
|
29
|
-
// Shared with the preflight: older Codex parses agents.enabled as a role.
|
|
30
|
-
const CODEX_ROOM_GATES = ["agents.enabled=false", "features.goals=false"];
|
|
31
31
|
const CLAUDE_VERSION = /^\d+\.\d+\.\d+/u;
|
|
32
32
|
const CODEX_VERSION = /\b\d+\.\d+\.\d+\b/u;
|
|
33
33
|
const DONT_ASK = /\bdontAsk\b/u;
|
|
34
|
-
// Kept package-local for the published CLI. The launch tests compare both
|
|
35
|
-
// adapters against the server's exported ROOM_AGENT_TOOLS contract.
|
|
36
|
-
const ROOM_TOOLS = [
|
|
37
|
-
"list_rooms",
|
|
38
|
-
"read_room",
|
|
39
|
-
"list_room_files",
|
|
40
|
-
"read_file",
|
|
41
|
-
"get_skill",
|
|
42
|
-
"suggest_change",
|
|
43
|
-
"create_file",
|
|
44
|
-
"create_deck",
|
|
45
|
-
"post_message",
|
|
46
|
-
"share_link",
|
|
47
|
-
"whoami",
|
|
48
|
-
];
|
|
49
34
|
const CLAUDE_TOOLS = ROOM_TOOLS.map((tool) => `mcp__talentos__${tool}`).join(",");
|
|
50
35
|
export function childEnvironment(source = process.env, binary) {
|
|
51
36
|
return {
|
|
@@ -78,12 +63,13 @@ export async function verifyClaudeCode(configured) {
|
|
|
78
63
|
}
|
|
79
64
|
throw new Error(`Update Claude Code (${version}) to a version that supports --permission-mode dontAsk.`);
|
|
80
65
|
}
|
|
81
|
-
export async function verifyCodex(configured) {
|
|
66
|
+
export async function verifyCodex(configured, signal) {
|
|
82
67
|
const binary = resolveProviderBinary("codex", configured);
|
|
83
68
|
const execute = promisify(execFile);
|
|
84
69
|
const options = {
|
|
85
70
|
env: childEnvironment(process.env, binary),
|
|
86
71
|
timeout: 5000,
|
|
72
|
+
signal,
|
|
87
73
|
maxBuffer: 256_000,
|
|
88
74
|
};
|
|
89
75
|
let version = "unknown";
|
|
@@ -105,26 +91,14 @@ export async function verifyCodex(configured) {
|
|
|
105
91
|
}
|
|
106
92
|
}
|
|
107
93
|
if (version !== "unknown") {
|
|
108
|
-
await codexRoomCatalog(binary);
|
|
109
|
-
const directory = await mkdtemp(join(tmpdir(), "talentos-codex-probe-"));
|
|
110
|
-
try {
|
|
111
|
-
await execute(binary, [
|
|
112
|
-
...CODEX_ROOM_GATES.flatMap((gate) => ["-c", gate]),
|
|
113
|
-
"features",
|
|
114
|
-
"list",
|
|
115
|
-
], {
|
|
116
|
-
...options,
|
|
117
|
-
cwd: directory,
|
|
118
|
-
env: { ...options.env, CODEX_HOME: directory },
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
finally {
|
|
122
|
-
await rm(directory, { recursive: true, force: true });
|
|
123
|
-
}
|
|
94
|
+
await probeCodexBoundary(binary, version, await codexRoomCatalog(binary), signal);
|
|
124
95
|
return;
|
|
125
96
|
}
|
|
126
97
|
}
|
|
127
|
-
catch {
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error instanceof CodexBoundaryError) {
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
128
102
|
// Provider diagnostics can contain login details.
|
|
129
103
|
}
|
|
130
104
|
throw new Error(`Update Codex (${version}) to a version supporting isolated room turns, exec/resume flags and a local model catalog.`);
|
|
@@ -157,6 +131,7 @@ async function codexRoomCatalog(binary) {
|
|
|
157
131
|
// Code-mode-only models route MCP through native execution. Expose
|
|
158
132
|
// allowed MCP functions directly while native execution stays off.
|
|
159
133
|
tool_mode: "direct",
|
|
134
|
+
supports_search_tool: false,
|
|
160
135
|
};
|
|
161
136
|
});
|
|
162
137
|
return JSON.stringify({ ...catalog, models });
|
|
@@ -216,7 +191,26 @@ export async function runProvider(input) {
|
|
|
216
191
|
const catalogPath = join(dirname(workDir), ".talentos-codex-models.json");
|
|
217
192
|
const binary = resolveProviderBinary(config.provider, config.providerPath);
|
|
218
193
|
let command, args;
|
|
219
|
-
|
|
194
|
+
let ownerLaunch;
|
|
195
|
+
let stopWatching;
|
|
196
|
+
if (input.owner && config.provider === "claude_code") {
|
|
197
|
+
const watching = await input.owner.watch?.();
|
|
198
|
+
stopWatching = watching?.stop;
|
|
199
|
+
ownerLaunch = await prepareOwnerLaunch({
|
|
200
|
+
agentId: config.agentId,
|
|
201
|
+
askSocket: watching?.socketPath,
|
|
202
|
+
directory: dirname(workDir),
|
|
203
|
+
home: input.owner.home,
|
|
204
|
+
instructions,
|
|
205
|
+
jobId: job.jobId,
|
|
206
|
+
prompt,
|
|
207
|
+
sessionId,
|
|
208
|
+
workspace: input.owner.workspace,
|
|
209
|
+
});
|
|
210
|
+
command = binary;
|
|
211
|
+
args = ownerLaunch.args;
|
|
212
|
+
}
|
|
213
|
+
else if (config.provider === "claude_code") {
|
|
220
214
|
await writePrivateFile(mcpPath, JSON.stringify({
|
|
221
215
|
mcpServers: {
|
|
222
216
|
talentos: {
|
|
@@ -258,56 +252,43 @@ export async function runProvider(input) {
|
|
|
258
252
|
await writePrivateFile(catalogPath, await codexRoomCatalog(binary));
|
|
259
253
|
// Resume has a different flag surface. Root overrides are inherited by
|
|
260
254
|
// both exec paths; shell_tool=false enforces ADR 0093's default no-Bash.
|
|
261
|
-
args =
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"-c",
|
|
277
|
-
"features.apps=false",
|
|
278
|
-
"-c",
|
|
279
|
-
"features.plugins=false",
|
|
280
|
-
"-c",
|
|
281
|
-
"features.multi_agent=false",
|
|
282
|
-
// Codex also gates collaboration separately from the legacy feature.
|
|
283
|
-
...CODEX_ROOM_GATES.flatMap((gate) => ["-c", gate]),
|
|
284
|
-
"-c",
|
|
285
|
-
"features.skip_host_skill_discovery=true",
|
|
286
|
-
"-c",
|
|
287
|
-
"memories.use_memories=false",
|
|
288
|
-
"-c",
|
|
289
|
-
"memories.generate_memories=false",
|
|
290
|
-
"-c",
|
|
291
|
-
`model_catalog_json=${JSON.stringify(catalogPath)}`,
|
|
292
|
-
"-c",
|
|
293
|
-
`mcp_servers.talentos.enabled_tools=${JSON.stringify(ROOM_TOOLS)}`,
|
|
294
|
-
"-c",
|
|
295
|
-
`mcp_servers.talentos.command=${JSON.stringify(useLauncher ? launcher : process.execPath)}`,
|
|
296
|
-
"-c",
|
|
297
|
-
`mcp_servers.talentos.args=${JSON.stringify([...(useLauncher ? [] : [fileURLToPath(new URL("../index.js", import.meta.url))]), "agent", "mcp", "--agent", config.agentId])}`,
|
|
298
|
-
"exec",
|
|
299
|
-
];
|
|
300
|
-
if (sessionId) {
|
|
301
|
-
args.push("resume", sessionId);
|
|
302
|
-
}
|
|
303
|
-
args.push("--json", "--skip-git-repo-check", "--ignore-user-config", "--ignore-rules", prompt);
|
|
255
|
+
args = codexRoomArgs({
|
|
256
|
+
catalogPath,
|
|
257
|
+
mcpCommand: useLauncher ? launcher : process.execPath,
|
|
258
|
+
mcpArgs: [
|
|
259
|
+
...(useLauncher
|
|
260
|
+
? []
|
|
261
|
+
: [fileURLToPath(new URL("../index.js", import.meta.url))]),
|
|
262
|
+
"agent",
|
|
263
|
+
"mcp",
|
|
264
|
+
"--agent",
|
|
265
|
+
config.agentId,
|
|
266
|
+
],
|
|
267
|
+
prompt,
|
|
268
|
+
sessionId,
|
|
269
|
+
});
|
|
304
270
|
}
|
|
305
271
|
const child = spawn(command, args, {
|
|
306
|
-
cwd: workDir,
|
|
307
|
-
env:
|
|
272
|
+
cwd: input.owner?.workspace.cwd ?? workDir,
|
|
273
|
+
env: input.owner
|
|
274
|
+
? {
|
|
275
|
+
...input.owner.env,
|
|
276
|
+
PATH: [dirname(binary), input.owner.env.PATH]
|
|
277
|
+
.filter(Boolean)
|
|
278
|
+
.join(delimiter),
|
|
279
|
+
}
|
|
280
|
+
: childEnvironment(process.env, binary),
|
|
308
281
|
stdio: ["ignore", "pipe", "ignore"],
|
|
309
282
|
detached: process.platform !== "win32",
|
|
310
283
|
});
|
|
284
|
+
const marked = new Set();
|
|
285
|
+
const mark = (name) => {
|
|
286
|
+
if (!marked.has(name)) {
|
|
287
|
+
marked.add(name);
|
|
288
|
+
input.mark?.(name);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
child.once("spawn", () => mark("spawn"));
|
|
311
292
|
let killTimer;
|
|
312
293
|
const stop = () => {
|
|
313
294
|
const pid = child.pid;
|
|
@@ -356,6 +337,10 @@ export async function runProvider(input) {
|
|
|
356
337
|
continue;
|
|
357
338
|
}
|
|
358
339
|
const event = readProviderEvent(config.provider, value);
|
|
340
|
+
mark("firstEvent");
|
|
341
|
+
if (event.status) {
|
|
342
|
+
mark("firstTool");
|
|
343
|
+
}
|
|
359
344
|
if (event.failed) {
|
|
360
345
|
failed = true;
|
|
361
346
|
}
|
|
@@ -363,7 +348,8 @@ export async function runProvider(input) {
|
|
|
363
348
|
await input.remember(event.sessionId);
|
|
364
349
|
}
|
|
365
350
|
if (event.status) {
|
|
366
|
-
|
|
351
|
+
// Room-visible status never names the owner's private tools.
|
|
352
|
+
input.status(ownerLaunch ? "Working on your computer…" : event.status);
|
|
367
353
|
}
|
|
368
354
|
if (event.text !== undefined) {
|
|
369
355
|
text = event.text.slice(0, 12_000);
|
|
@@ -388,5 +374,7 @@ export async function runProvider(input) {
|
|
|
388
374
|
}
|
|
389
375
|
await rm(mcpPath, { force: true });
|
|
390
376
|
await rm(catalogPath, { force: true });
|
|
377
|
+
stopWatching?.();
|
|
378
|
+
await ownerLaunch?.cleanup();
|
|
391
379
|
}
|
|
392
380
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export const ROOM_TOOLS = [
|
|
2
|
+
"list_rooms",
|
|
3
|
+
"read_room",
|
|
4
|
+
"list_room_files",
|
|
5
|
+
"read_file",
|
|
6
|
+
"get_skill",
|
|
7
|
+
"suggest_change",
|
|
8
|
+
"create_file",
|
|
9
|
+
"create_deck",
|
|
10
|
+
"create_web_app",
|
|
11
|
+
"revise_web_app",
|
|
12
|
+
"upload_file",
|
|
13
|
+
"prepare_upload",
|
|
14
|
+
"commit_upload",
|
|
15
|
+
"post_message",
|
|
16
|
+
"share_link",
|
|
17
|
+
"whoami",
|
|
18
|
+
];
|
|
19
|
+
export function codexRoomArgs(input) {
|
|
20
|
+
const { catalogPath, mcpCommand, mcpArgs, prompt, sessionId } = input;
|
|
21
|
+
const args = [
|
|
22
|
+
"-c",
|
|
23
|
+
'sandbox_mode="read-only"',
|
|
24
|
+
"-c",
|
|
25
|
+
'approval_policy="never"',
|
|
26
|
+
"-c",
|
|
27
|
+
"features.shell_tool=false",
|
|
28
|
+
"-c",
|
|
29
|
+
"features.unified_exec=false",
|
|
30
|
+
"-c",
|
|
31
|
+
'web_search="disabled"',
|
|
32
|
+
"-c",
|
|
33
|
+
"features.view_image=false",
|
|
34
|
+
"-c",
|
|
35
|
+
"features.image_generation=false",
|
|
36
|
+
"-c",
|
|
37
|
+
"features.apps=false",
|
|
38
|
+
"-c",
|
|
39
|
+
"features.plugins=false",
|
|
40
|
+
"-c",
|
|
41
|
+
"features.multi_agent=false",
|
|
42
|
+
// Codex also gates collaboration separately from the legacy feature.
|
|
43
|
+
"-c",
|
|
44
|
+
"agents.enabled=false",
|
|
45
|
+
"-c",
|
|
46
|
+
"features.goals=false",
|
|
47
|
+
"-c",
|
|
48
|
+
"tools.experimental_request_user_input.enabled=false",
|
|
49
|
+
"-c",
|
|
50
|
+
"features.tool_search=false",
|
|
51
|
+
"-c",
|
|
52
|
+
"features.skip_host_skill_discovery=true",
|
|
53
|
+
"-c",
|
|
54
|
+
"memories.use_memories=false",
|
|
55
|
+
"-c",
|
|
56
|
+
"memories.generate_memories=false",
|
|
57
|
+
"-c",
|
|
58
|
+
`model_catalog_json=${JSON.stringify(catalogPath)}`,
|
|
59
|
+
"-c",
|
|
60
|
+
`mcp_servers.talentos.enabled_tools=${JSON.stringify(ROOM_TOOLS)}`,
|
|
61
|
+
"-c",
|
|
62
|
+
`mcp_servers.talentos.command=${JSON.stringify(mcpCommand)}`,
|
|
63
|
+
"-c",
|
|
64
|
+
`mcp_servers.talentos.args=${JSON.stringify(mcpArgs)}`,
|
|
65
|
+
"exec",
|
|
66
|
+
];
|
|
67
|
+
if (sessionId) {
|
|
68
|
+
args.push("resume", sessionId);
|
|
69
|
+
}
|
|
70
|
+
args.push("--json", "--skip-git-repo-check", "--ignore-user-config", "--ignore-rules", prompt);
|
|
71
|
+
return args;
|
|
72
|
+
}
|