doer-agent 0.8.6 → 0.8.8
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-settings.js +74 -4
- package/dist/agent-skill-rpc.js +11 -1
- package/dist/codex-app-server-manager.js +86 -4
- package/dist/codex-chat-bridge.js +1489 -0
- package/dist/codex-chat-bridge.test.js +656 -0
- package/dist/litellm-responses-proxy.js +685 -0
- package/package.json +2 -1
package/dist/agent-settings.js
CHANGED
|
@@ -15,7 +15,9 @@ export function createDefaultAgentSettingsConfig() {
|
|
|
15
15
|
personality: "pragmatic",
|
|
16
16
|
},
|
|
17
17
|
codex: {
|
|
18
|
-
|
|
18
|
+
providerModels: { openai: "gpt-5.5" },
|
|
19
|
+
modelProvider: null,
|
|
20
|
+
customProvider: null,
|
|
19
21
|
reasoningEffort: "medium",
|
|
20
22
|
serviceTier: null,
|
|
21
23
|
authMode: "api_key",
|
|
@@ -63,6 +65,50 @@ function normalizeServiceTier(value) {
|
|
|
63
65
|
}
|
|
64
66
|
return normalized;
|
|
65
67
|
}
|
|
68
|
+
function normalizeCodexCustomProvider(value, fallback = null) {
|
|
69
|
+
if (value === null) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
73
|
+
return fallback;
|
|
74
|
+
}
|
|
75
|
+
const raw = value;
|
|
76
|
+
const id = typeof raw.id === "string" ? raw.id.trim() : "";
|
|
77
|
+
const baseUrl = typeof raw.baseUrl === "string" ? raw.baseUrl.trim() : "";
|
|
78
|
+
if (!id || !baseUrl) {
|
|
79
|
+
return fallback;
|
|
80
|
+
}
|
|
81
|
+
const name = typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : id;
|
|
82
|
+
const envKey = typeof raw.envKey === "string" && raw.envKey.trim() ? raw.envKey.trim() : `${id.toUpperCase()}_API_KEY`;
|
|
83
|
+
const apiKey = raw.apiKey === null
|
|
84
|
+
? null
|
|
85
|
+
: typeof raw.apiKey === "string" && raw.apiKey.trim()
|
|
86
|
+
? raw.apiKey.trim()
|
|
87
|
+
: fallback?.id === id
|
|
88
|
+
? fallback.apiKey
|
|
89
|
+
: null;
|
|
90
|
+
return {
|
|
91
|
+
id,
|
|
92
|
+
name,
|
|
93
|
+
baseUrl,
|
|
94
|
+
envKey,
|
|
95
|
+
apiKey,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function normalizeCodexProviderModels(value, fallback) {
|
|
99
|
+
const models = { ...fallback };
|
|
100
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
101
|
+
return models;
|
|
102
|
+
}
|
|
103
|
+
for (const [rawKey, rawModel] of Object.entries(value)) {
|
|
104
|
+
const key = rawKey.trim();
|
|
105
|
+
const model = typeof rawModel === "string" ? rawModel.trim() : "";
|
|
106
|
+
if (key && model) {
|
|
107
|
+
models[key] = model;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return models;
|
|
111
|
+
}
|
|
66
112
|
function normalizeCodexPersonality(value, fallback) {
|
|
67
113
|
return value === "friendly" || value === "pragmatic" ? value : fallback;
|
|
68
114
|
}
|
|
@@ -200,7 +246,13 @@ export function normalizeAgentSettingsConfig(value, fallback) {
|
|
|
200
246
|
personality: normalizeCodexPersonality(general.personality, base.general.personality),
|
|
201
247
|
},
|
|
202
248
|
codex: {
|
|
203
|
-
|
|
249
|
+
providerModels: normalizeCodexProviderModels(codex.providerModels, base.codex.providerModels),
|
|
250
|
+
modelProvider: codex.modelProvider === null
|
|
251
|
+
? null
|
|
252
|
+
: typeof codex.modelProvider === "string" && codex.modelProvider.trim()
|
|
253
|
+
? codex.modelProvider.trim()
|
|
254
|
+
: base.codex.modelProvider,
|
|
255
|
+
customProvider: normalizeCodexCustomProvider(codex.customProvider, base.codex.customProvider),
|
|
204
256
|
reasoningEffort: normalizeReasoningEffort(codex.reasoningEffort, base.codex.reasoningEffort),
|
|
205
257
|
serviceTier: codex.serviceTier === null ? null : normalizeServiceTier(codex.serviceTier) ?? base.codex.serviceTier,
|
|
206
258
|
authMode: codex.authMode === "chatgpt" ? "chatgpt" : codex.authMode === "api_key" ? "api_key" : base.codex.authMode,
|
|
@@ -275,6 +327,7 @@ function toMaskedSecret(value) {
|
|
|
275
327
|
export async function toAgentSettingsPublic(args) {
|
|
276
328
|
const realtimeKey = toMaskedSecret(args.config.realtime.apiKey);
|
|
277
329
|
const gitOauth = toMaskedSecret(args.config.git.oauthToken);
|
|
330
|
+
const codexProviderKey = toMaskedSecret(args.config.codex.customProvider?.apiKey ?? null);
|
|
278
331
|
const customInstructions = await readAgentModelInstructions(args.workspaceRoot);
|
|
279
332
|
return {
|
|
280
333
|
general: {
|
|
@@ -282,7 +335,19 @@ export async function toAgentSettingsPublic(args) {
|
|
|
282
335
|
customInstructions,
|
|
283
336
|
},
|
|
284
337
|
codex: {
|
|
285
|
-
|
|
338
|
+
providerModels: { ...args.config.codex.providerModels },
|
|
339
|
+
modelProvider: args.config.codex.modelProvider,
|
|
340
|
+
customProvider: args.config.codex.customProvider
|
|
341
|
+
? {
|
|
342
|
+
id: args.config.codex.customProvider.id,
|
|
343
|
+
name: args.config.codex.customProvider.name,
|
|
344
|
+
baseUrl: args.config.codex.customProvider.baseUrl,
|
|
345
|
+
envKey: args.config.codex.customProvider.envKey,
|
|
346
|
+
hasApiKey: codexProviderKey.has,
|
|
347
|
+
apiKeyMasked: codexProviderKey.masked,
|
|
348
|
+
apiKeyLength: codexProviderKey.length,
|
|
349
|
+
}
|
|
350
|
+
: null,
|
|
286
351
|
reasoningEffort: args.config.codex.reasoningEffort,
|
|
287
352
|
serviceTier: args.config.codex.serviceTier,
|
|
288
353
|
authMode: args.config.codex.authMode,
|
|
@@ -353,7 +418,9 @@ export function normalizeAgentSettingsPatch(value) {
|
|
|
353
418
|
delete patch[flatKey];
|
|
354
419
|
};
|
|
355
420
|
move("personality", "general", "personality");
|
|
356
|
-
move("
|
|
421
|
+
move("codexProviderModels", "codex", "providerModels");
|
|
422
|
+
move("codexModelProvider", "codex", "modelProvider");
|
|
423
|
+
move("codexCustomProvider", "codex", "customProvider");
|
|
357
424
|
move("codexReasoningEffort", "codex", "reasoningEffort");
|
|
358
425
|
move("codexServiceTier", "codex", "serviceTier");
|
|
359
426
|
move("codexAuthMode", "codex", "authMode");
|
|
@@ -377,6 +444,9 @@ export function normalizeAgentSettingsPatch(value) {
|
|
|
377
444
|
}
|
|
378
445
|
export function buildAgentSettingsEnvPatch(config) {
|
|
379
446
|
const envPatch = {};
|
|
447
|
+
if (config.codex.customProvider?.apiKey && config.codex.customProvider.envKey) {
|
|
448
|
+
envPatch[config.codex.customProvider.envKey] = config.codex.customProvider.apiKey;
|
|
449
|
+
}
|
|
380
450
|
if (config.git.enabled) {
|
|
381
451
|
if (config.git.name)
|
|
382
452
|
envPatch.GIT_AUTHOR_NAME = config.git.name;
|
package/dist/agent-skill-rpc.js
CHANGED
|
@@ -70,11 +70,21 @@ function normalizeGeneratedSkill(value) {
|
|
|
70
70
|
function buildSkillGeneratorCodexArgs(prompt, model) {
|
|
71
71
|
return ["--dangerously-bypass-approvals-and-sandbox", "--model", model, "exec", "--", prompt];
|
|
72
72
|
}
|
|
73
|
+
function resolveCodexModel(settings) {
|
|
74
|
+
const providerKey = settings.codex.modelProvider || "openai";
|
|
75
|
+
if (providerKey === "zai") {
|
|
76
|
+
return settings.codex.providerModels.zai || "glm-5.2";
|
|
77
|
+
}
|
|
78
|
+
if (providerKey === "anthropic") {
|
|
79
|
+
return settings.codex.providerModels.anthropic || "claude-sonnet-4-6";
|
|
80
|
+
}
|
|
81
|
+
return settings.codex.providerModels[providerKey] || settings.codex.providerModels.openai || "gpt-5.5";
|
|
82
|
+
}
|
|
73
83
|
async function generateSkillViaCodex(args) {
|
|
74
84
|
const localAgentSettings = await args.readAgentSettingsConfig({ workspaceRoot: args.workspaceRoot });
|
|
75
85
|
const envPatch = args.buildAgentSettingsEnvPatch(localAgentSettings);
|
|
76
86
|
const prompt = buildSkillGeneratorPrompt(args.userPrompt);
|
|
77
|
-
const result = await args.runLocalCodexCli(buildSkillGeneratorCodexArgs(prompt, localAgentSettings
|
|
87
|
+
const result = await args.runLocalCodexCli(buildSkillGeneratorCodexArgs(prompt, resolveCodexModel(localAgentSettings)), 120_000, envPatch);
|
|
78
88
|
if (result.timedOut) {
|
|
79
89
|
throw new Error("Codex timed out while generating the skill");
|
|
80
90
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { buildAgentSettingsEnvPatch, readAgentModelInstructions, resolveAgentModelInstructionsFilePath, } from "./agent-settings.js";
|
|
2
2
|
import { buildCustomMcpConfigArgs, buildDaemonMcpConfigArgs, buildMobileMcpConfigArgs, buildThreadsMcpConfigArgs } from "./agent-codex-cli.js";
|
|
3
3
|
import { CodexAppServerClient } from "./codex-app-server-client.js";
|
|
4
|
+
import { startCodexChatBridge } from "./codex-chat-bridge.js";
|
|
4
5
|
function toTomlStringLiteral(value) {
|
|
5
6
|
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
6
7
|
}
|
|
@@ -10,9 +11,47 @@ function buildConfigArg(key, tomlValue) {
|
|
|
10
11
|
function buildFeatureArg(enabled, name) {
|
|
11
12
|
return [enabled ? "--enable" : "--disable", name];
|
|
12
13
|
}
|
|
14
|
+
function resolveCodexModel(settings) {
|
|
15
|
+
const providerKey = settings.codex.modelProvider || "openai";
|
|
16
|
+
if (providerKey === "zai") {
|
|
17
|
+
return settings.codex.providerModels.zai || "glm-5.2";
|
|
18
|
+
}
|
|
19
|
+
if (providerKey === "anthropic") {
|
|
20
|
+
return settings.codex.providerModels.anthropic || "claude-sonnet-4-6";
|
|
21
|
+
}
|
|
22
|
+
return settings.codex.providerModels[providerKey] || settings.codex.providerModels.openai || "gpt-5.5";
|
|
23
|
+
}
|
|
24
|
+
function resolveCodexModelContextWindow(settings) {
|
|
25
|
+
if (settings.codex.modelProvider === "zai") {
|
|
26
|
+
return 258400;
|
|
27
|
+
}
|
|
28
|
+
if (settings.codex.modelProvider === "anthropic") {
|
|
29
|
+
const model = resolveCodexModel(settings);
|
|
30
|
+
return model.startsWith("claude-haiku-") ? 200000 : 1000000;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
function buildModelProviderConfigArgs(settings) {
|
|
35
|
+
const provider = settings.codex.customProvider;
|
|
36
|
+
const providerId = settings.codex.modelProvider;
|
|
37
|
+
if (!provider || !providerId || provider.id !== providerId) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
return [
|
|
41
|
+
...buildConfigArg("model_provider", toTomlStringLiteral(provider.id)),
|
|
42
|
+
...buildConfigArg(`model_providers.${provider.id}.name`, toTomlStringLiteral(provider.name)),
|
|
43
|
+
...buildConfigArg(`model_providers.${provider.id}.base_url`, toTomlStringLiteral(provider.baseUrl)),
|
|
44
|
+
...buildConfigArg(`model_providers.${provider.id}.env_key`, toTomlStringLiteral(provider.envKey)),
|
|
45
|
+
...buildConfigArg(`model_providers.${provider.id}.wire_api`, toTomlStringLiteral("responses")),
|
|
46
|
+
];
|
|
47
|
+
}
|
|
13
48
|
async function buildCodexAppServerArgs(args) {
|
|
49
|
+
const codexModel = resolveCodexModel(args.settings);
|
|
50
|
+
const modelContextWindow = resolveCodexModelContextWindow(args.settings);
|
|
14
51
|
const configArgs = [
|
|
15
|
-
...buildConfigArg("model", toTomlStringLiteral(
|
|
52
|
+
...buildConfigArg("model", toTomlStringLiteral(codexModel)),
|
|
53
|
+
...(modelContextWindow ? buildConfigArg("model_context_window", String(modelContextWindow)) : []),
|
|
54
|
+
...buildModelProviderConfigArgs(args.settings),
|
|
16
55
|
...buildConfigArg("model_reasoning_effort", toTomlStringLiteral(args.settings.codex.reasoningEffort)),
|
|
17
56
|
...(args.settings.codex.serviceTier
|
|
18
57
|
? buildConfigArg("service_tier", toTomlStringLiteral(args.settings.codex.serviceTier))
|
|
@@ -56,6 +95,36 @@ async function buildCodexAppServerArgs(args) {
|
|
|
56
95
|
"stdio://",
|
|
57
96
|
];
|
|
58
97
|
}
|
|
98
|
+
async function resolveAppServerSettings(args) {
|
|
99
|
+
const provider = args.settings.codex.customProvider;
|
|
100
|
+
const providerId = args.settings.codex.modelProvider;
|
|
101
|
+
const gatewayProviderIds = new Set(["zai", "anthropic"]);
|
|
102
|
+
if (!providerId || provider?.id !== providerId || !gatewayProviderIds.has(providerId)) {
|
|
103
|
+
return { settings: args.settings, proxy: null };
|
|
104
|
+
}
|
|
105
|
+
const proxy = await startCodexChatBridge({
|
|
106
|
+
providerApiKey: provider.apiKey ?? "",
|
|
107
|
+
providerId: provider.id,
|
|
108
|
+
providerName: provider.name,
|
|
109
|
+
targetBaseUrl: provider.baseUrl,
|
|
110
|
+
onLog: args.onLog,
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
proxy,
|
|
114
|
+
settings: {
|
|
115
|
+
...args.settings,
|
|
116
|
+
codex: {
|
|
117
|
+
...args.settings.codex,
|
|
118
|
+
customProvider: {
|
|
119
|
+
...provider,
|
|
120
|
+
baseUrl: proxy.baseUrl,
|
|
121
|
+
envKey: proxy.envKey,
|
|
122
|
+
apiKey: proxy.apiKey,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
}
|
|
59
128
|
async function buildCodexAppServerEnv(args) {
|
|
60
129
|
return {
|
|
61
130
|
...process.env,
|
|
@@ -69,18 +138,21 @@ async function buildCodexAppServerEnv(args) {
|
|
|
69
138
|
}
|
|
70
139
|
export function createCodexAppServerManager(args) {
|
|
71
140
|
let client = null;
|
|
141
|
+
let providerProxy = null;
|
|
72
142
|
let createPromise = null;
|
|
73
143
|
let generation = 0;
|
|
74
144
|
const notificationListeners = new Set();
|
|
75
145
|
const createClient = async () => {
|
|
76
146
|
const settings = await args.readAgentSettingsConfig({ workspaceRoot: args.workspaceRoot });
|
|
147
|
+
const resolved = await resolveAppServerSettings({ settings, onLog: args.onLog });
|
|
148
|
+
providerProxy = resolved.proxy;
|
|
77
149
|
const appServerArgs = await buildCodexAppServerArgs({
|
|
78
150
|
agentId: args.agentId,
|
|
79
151
|
agentToken: args.agentToken,
|
|
80
152
|
workspaceRoot: args.workspaceRoot,
|
|
81
153
|
agentProjectDir: args.agentProjectDir,
|
|
82
154
|
serverBaseUrl: args.serverBaseUrl,
|
|
83
|
-
settings,
|
|
155
|
+
settings: resolved.settings,
|
|
84
156
|
userId: args.userId,
|
|
85
157
|
});
|
|
86
158
|
const env = await buildCodexAppServerEnv({
|
|
@@ -89,10 +161,10 @@ export function createCodexAppServerManager(args) {
|
|
|
89
161
|
workspaceRoot: args.workspaceRoot,
|
|
90
162
|
serverBaseUrl: args.serverBaseUrl,
|
|
91
163
|
resolveCodexHomePath: args.resolveCodexHomePath,
|
|
92
|
-
settings,
|
|
164
|
+
settings: resolved.settings,
|
|
93
165
|
userId: args.userId,
|
|
94
166
|
});
|
|
95
|
-
args.onLog?.(`starting codex app-server model=${settings
|
|
167
|
+
args.onLog?.(`starting codex app-server model=${resolveCodexModel(resolved.settings)} reasoningEffort=${resolved.settings.codex.reasoningEffort} personality=${resolved.settings.general.personality} computerUse=${resolved.settings.codex.computerUseEnabled} browserUse=${resolved.settings.codex.browserUseEnabled} mcpServers=${resolved.settings.mcp.servers.filter((server) => server.enabled).length}`);
|
|
96
168
|
return new CodexAppServerClient({
|
|
97
169
|
cwd: args.workspaceRoot,
|
|
98
170
|
args: appServerArgs,
|
|
@@ -144,7 +216,9 @@ export function createCodexAppServerManager(args) {
|
|
|
144
216
|
async restart(reason) {
|
|
145
217
|
generation += 1;
|
|
146
218
|
const activeClient = client;
|
|
219
|
+
const activeProxy = providerProxy;
|
|
147
220
|
client = null;
|
|
221
|
+
providerProxy = null;
|
|
148
222
|
createPromise = null;
|
|
149
223
|
if (!activeClient) {
|
|
150
224
|
args.onLog?.(`codex app-server restart requested before start reason=${reason}`);
|
|
@@ -152,12 +226,20 @@ export function createCodexAppServerManager(args) {
|
|
|
152
226
|
}
|
|
153
227
|
args.onLog?.(`restarting codex app-server reason=${reason}`);
|
|
154
228
|
await activeClient.stop();
|
|
229
|
+
await activeProxy?.stop().catch((error) => {
|
|
230
|
+
args.onLog?.(`failed to stop provider proxy: ${error instanceof Error ? error.message : String(error)}`);
|
|
231
|
+
});
|
|
155
232
|
},
|
|
156
233
|
async stop() {
|
|
157
234
|
const activeClient = client;
|
|
235
|
+
const activeProxy = providerProxy;
|
|
158
236
|
client = null;
|
|
237
|
+
providerProxy = null;
|
|
159
238
|
createPromise = null;
|
|
160
239
|
await activeClient?.stop();
|
|
240
|
+
await activeProxy?.stop().catch((error) => {
|
|
241
|
+
args.onLog?.(`failed to stop provider proxy: ${error instanceof Error ? error.message : String(error)}`);
|
|
242
|
+
});
|
|
161
243
|
},
|
|
162
244
|
};
|
|
163
245
|
}
|