evolcore 0.0.25 → 0.0.26
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/CHANGELOG.md +607 -565
- package/LICENSE +21 -21
- package/README.md +455 -455
- package/bin/codex-managed-acl.ps1 +160 -160
- package/bin/codex-managed-hook.mjs +208 -208
- package/bin/ec-safe-output.js +327 -327
- package/bin/ec.js +40 -29
- package/bin/install-codex-managed-hooks.mjs +582 -555
- package/dist/agents/baseagent.js +96 -46
- package/dist/agents/claude-runner.js +50 -12
- package/dist/agents/codex/app-server-client.js +13 -5
- package/dist/agents/codex/catalog.js +1 -1
- package/dist/agents/codex/diagnostics.js +34 -1
- package/dist/agents/codex-runner.js +121 -38
- package/dist/agents/ecagent-runner.js +4 -9
- package/dist/agents/gemini-runner.js +2 -7
- package/dist/agents/runner-types.js +25 -17
- package/dist/aun/aid/agentmd.js +81 -8
- package/dist/aun/aid/client.js +1 -1
- package/dist/aun/aid/identity.js +1 -1
- package/dist/aun/aid/index.js +1 -1
- package/dist/aun/aid/store.js +17 -13
- package/dist/aun/menu-client.js +74 -0
- package/dist/aun/msg/group.js +1 -1
- package/dist/aun/msg/managed-operation.js +1 -1
- package/dist/aun/msg/p2p.js +6 -1
- package/dist/aun/msg/upload.js +30 -22
- package/dist/channels/aun.js +329 -94
- package/dist/cli/agent-command.js +105 -84
- package/dist/cli/agent-create.js +112 -10
- package/dist/cli/agent.js +16 -5
- package/dist/cli/aun-commands.js +297 -296
- package/dist/cli/bench.js +20 -20
- package/dist/cli/config.js +47 -28
- package/dist/cli/contact.js +70 -13
- package/dist/cli/ctl-command.js +22 -22
- package/dist/cli/daemon-commands.js +105 -40
- package/dist/cli/diag.js +31 -0
- package/dist/cli/fs-command.js +67 -67
- package/dist/cli/handoff-command.js +41 -9
- package/dist/cli/index.js +83 -77
- package/dist/cli/link-rules.js +21 -21
- package/dist/cli/managed-command-guard.js +3 -0
- package/dist/cli/menu-client.js +46 -31
- package/dist/cli/net-check.js +22 -22
- package/dist/cli/queue-command.js +29 -29
- package/dist/cli/response.js +30 -30
- package/dist/cli/restart-monitor.js +87 -40
- package/dist/cli/stats.js +51 -51
- package/dist/cli/trigger-command.js +56 -56
- package/dist/config/builtin-roles.js +1 -0
- package/dist/config/config-operation-service.js +145 -0
- package/dist/config/contact-operation-service.js +96 -7
- package/dist/config/resolved-config-op.js +27 -7
- package/dist/core/agent-application-service.js +2 -1
- package/dist/core/auth/authorization-audit.js +20 -12
- package/dist/core/auth/operation-authorizer.js +25 -4
- package/dist/core/auth/operation-catalog.js +35 -4
- package/dist/core/auth/remote-access-store.js +40 -1
- package/dist/core/bootstrap-service.js +1 -1
- package/dist/core/command/command-handler.js +83 -26
- package/dist/core/command/diag-service.js +118 -0
- package/dist/core/command/menu-catalog.js +12 -3
- package/dist/core/command/menu-handler.js +47 -26
- package/dist/core/command/menu-protocol.js +5 -0
- package/dist/core/command/menu-token-store.js +41 -8
- package/dist/core/command/slash-gate.js +34 -4
- package/dist/core/command/slash-handler.js +86 -21
- package/dist/core/handoff/runtime.js +205 -27
- package/dist/core/handoff/store.js +193 -4
- package/dist/core/message/im-renderer.js +72 -21
- package/dist/core/message/message-bridge.js +69 -9
- package/dist/core/message/message-queue.js +26 -0
- package/dist/core/message/message-utils.js +1 -0
- package/dist/core/message/response-engine.js +47 -28
- package/dist/core/model/catalog-service.js +79 -49
- package/dist/core/model/context-window-suffix.js +33 -0
- package/dist/core/model/model-catalog.js +1 -1
- package/dist/core/model/model-permission.js +12 -3
- package/dist/core/permission/ec-command-parser.js +51 -12
- package/dist/core/permission/sandbox-runtime.js +36 -14
- package/dist/core/permission/tool-policy.js +2 -1
- package/dist/index.js +280 -163
- package/dist/ipc.js +54 -2
- package/dist/response-system/engines/v1/proactive-flow.js +59 -2
- package/dist/stats/billing.js +41 -15
- package/dist/stats/db.js +159 -159
- package/dist/stats/eck-vars.js +9 -9
- package/dist/stats/price-resolver.js +28 -10
- package/dist/stats/query.js +139 -139
- package/dist/stats/role-budget.js +6 -6
- package/dist/stats/writer.js +51 -51
- package/dist/utils/cross-platform.js +30 -1
- package/dist/utils/error-dict.json +160 -160
- package/dist/utils/error-utils.js +21 -0
- package/dist/utils/evolcore-version.js +129 -0
- package/dist/utils/logger.js +3 -1
- package/dist/utils/macos-autostart.js +22 -22
- package/dist/utils/model-prices.jsonl +23 -23
- package/dist/utils/npm-ops.js +176 -35
- package/dist/utils/welcome.js +22 -22
- package/ecagent/LICENSE +21 -21
- package/ecagent/NOTICE +11 -11
- package/ecagent/README.md +61 -61
- package/ecagent/dist/harness/compaction/branch-summarization.js +30 -30
- package/ecagent/dist/harness/compaction/compaction.js +83 -83
- package/ecagent/dist/harness/messages.js +7 -7
- package/kits/docs/GUIDE.md +20 -20
- package/kits/docs/INDEX.md +66 -66
- package/kits/docs/aun/CHEATSHEET.md +19 -19
- package/kits/docs/aun/SYNC_PROTOCOL.md +15 -15
- package/kits/docs/channels/aun.md +56 -56
- package/kits/docs/channels/feishu.md +56 -56
- package/kits/docs/context-assembly.md +364 -364
- package/kits/docs/eck_templates/GUIDE.template.md +22 -22
- package/kits/docs/eck_templates/INDEX.template.md +28 -28
- package/kits/docs/eck_templates/path-registry.template.md +33 -33
- package/kits/docs/eck_templates/runtime.template.md +19 -19
- package/kits/docs/evolcore/INDEX.md +71 -71
- package/kits/docs/evolcore/agent-create.md +170 -165
- package/kits/docs/evolcore/agent.md +66 -66
- package/kits/docs/evolcore/aid.md +60 -60
- package/kits/docs/evolcore/codex-windows-sandbox.md +146 -146
- package/kits/docs/evolcore/config.md +202 -195
- package/kits/docs/evolcore/contact.md +75 -68
- package/kits/docs/evolcore/ctl.md +46 -46
- package/kits/docs/evolcore/event.md +216 -216
- package/kits/docs/evolcore/fs-architecture.md +1215 -1215
- package/kits/docs/evolcore/fs.md +110 -110
- package/kits/docs/evolcore/group-collaboration.md +243 -243
- package/kits/docs/evolcore/group-fs.md +17 -17
- package/kits/docs/evolcore/group-rules.md +251 -251
- package/kits/docs/evolcore/group.md +152 -152
- package/kits/docs/evolcore/menu-client.md +42 -34
- package/kits/docs/evolcore/model.md +50 -50
- package/kits/docs/evolcore/msg.md +166 -165
- package/kits/docs/evolcore/response.md +75 -75
- package/kits/docs/evolcore/rpc.md +37 -37
- package/kits/docs/evolcore/self-summary.md +29 -29
- package/kits/docs/evolcore/stats.md +83 -83
- package/kits/docs/evolcore/storage.md +50 -50
- package/kits/docs/evolcore/trigger.md +575 -575
- package/kits/docs/identity/AID_PROFILE_SPEC.md +26 -26
- package/kits/docs/identity/PATH_OPS.md +16 -16
- package/kits/docs/identity/ROLE_DETAIL.md +25 -25
- package/kits/docs/identity/identity-tools.md +26 -26
- package/kits/docs/path-registry.md +62 -62
- package/kits/docs/prompt-loading-architecture.md +269 -269
- package/kits/docs/venues/aun-group.md +45 -45
- package/kits/docs/venues/aun-private.md +10 -10
- package/kits/docs/venues/client-desktop.md +10 -10
- package/kits/docs/venues/client-mobile.md +10 -10
- package/kits/docs/venues/feishu-group.md +13 -13
- package/kits/docs/venues/feishu-private.md +9 -9
- package/kits/docs/venues/group.md +37 -25
- package/kits/docs/venues/private.md +10 -10
- package/kits/eck_manifest.auxiliary.json +43 -43
- package/kits/eck_manifest.json +190 -190
- package/kits/eck_message_manifest.json +74 -74
- package/kits/migrations/README-role-config-v4.md +32 -32
- package/kits/migrations/migrate-contact-book-v2.mjs +748 -748
- package/kits/migrations/migrate-role-config-v4.mjs +614 -614
- package/kits/migrations/migrate-role-config-v5.mjs +365 -365
- package/kits/migrations/rename-config-file.mjs +99 -99
- package/kits/rules/01-overview.md +162 -162
- package/kits/rules/02-navigation.md +96 -96
- package/kits/rules/03-identity.md +36 -36
- package/kits/rules/04-relation.md +75 -75
- package/kits/rules/05-venue.md +60 -60
- package/kits/rules/06-channel.md +63 -63
- package/kits/schemas/_meta.json +53 -53
- package/kits/schemas/agent-config.schema.1.json +177 -177
- package/kits/schemas/agent-config.schema.10.json +395 -395
- package/kits/schemas/agent-config.schema.11.json +421 -421
- package/kits/schemas/agent-config.schema.12.json +427 -427
- package/kits/schemas/agent-config.schema.2.json +239 -239
- package/kits/schemas/agent-config.schema.3.json +119 -119
- package/kits/schemas/agent-config.schema.4.json +208 -208
- package/kits/schemas/agent-config.schema.5.json +326 -326
- package/kits/schemas/agent-config.schema.6.json +322 -322
- package/kits/schemas/agent-config.schema.7.json +303 -303
- package/kits/schemas/agent-config.schema.8.json +304 -304
- package/kits/schemas/agent-config.schema.9.json +364 -364
- package/kits/schemas/contact-book.schema.1.json +36 -36
- package/kits/schemas/contact-book.schema.2.json +43 -43
- package/kits/schemas/contact-book.schema.3.json +67 -67
- package/kits/schemas/daemon.schema.1.json +91 -91
- package/kits/schemas/daemon.schema.2.json +101 -101
- package/kits/schemas/daemon.schema.3.json +123 -123
- package/kits/schemas/daemon.schema.4.json +136 -136
- package/kits/schemas/daemon.schema.5.json +135 -135
- package/kits/schemas/daemon.schema.6.json +131 -131
- package/kits/schemas/defaults.schema.1.json +81 -81
- package/kits/schemas/defaults.schema.2.json +85 -85
- package/kits/schemas/defaults.schema.3.json +73 -73
- package/kits/schemas/defaults.schema.4.json +107 -107
- package/kits/schemas/defaults.schema.5.json +119 -119
- package/kits/schemas/menu-exec-schema-commands.md +208 -208
- package/kits/schemas/migrations/README.md +30 -30
- package/kits/schemas/relation-config.schema.1.json +158 -158
- package/kits/schemas/relation-config.schema.2.json +73 -73
- package/kits/schemas/relation-config.schema.3.json +50 -50
- package/kits/schemas/relation-config.schema.4.json +47 -47
- package/kits/schemas/relation-config.schema.5.json +47 -47
- package/kits/schemas/relation-config.schema.6.json +46 -46
- package/kits/schemas/relation-config.schema.7.json +59 -59
- package/kits/schemas/relation-config.schema.8.json +103 -103
- package/kits/schemas/role-config.schema.1.json +201 -201
- package/kits/schemas/role-registry.schema.1.json +35 -35
- package/kits/schemas/single-session.schema.1.json +31 -31
- package/kits/schemas/single-session.schema.2.json +57 -57
- package/kits/schemas/single-session.schema.3.json +32 -32
- package/kits/templates/bootstrap-welcome.md +17 -17
- package/kits/templates/message-fragments/handoff-context-to-target.md +9 -9
- package/kits/templates/message-fragments/handoff-request-to-target.md +19 -19
- package/kits/templates/message-fragments/handoff-response-to-origin.md +9 -9
- package/kits/templates/message-fragments/inject-default.md +2 -2
- package/kits/templates/message-fragments/item.md +2 -2
- package/kits/templates/roles/admin.json +92 -92
- package/kits/templates/roles/member.json +96 -96
- package/kits/templates/roles/owner.json +9 -9
- package/kits/templates/roles/visitor.json +85 -85
- package/kits/templates/system-fragments/baseagent.md +14 -14
- package/kits/templates/system-fragments/bootstrap.md +31 -29
- package/kits/templates/system-fragments/channel.md +64 -64
- package/kits/templates/system-fragments/commands.md +28 -28
- package/kits/templates/system-fragments/identity.md +13 -13
- package/kits/templates/system-fragments/relation.md +19 -19
- package/kits/templates/system-fragments/session.md +59 -59
- package/kits/templates/system-fragments/venue.md +31 -31
- package/package.json +100 -98
package/dist/agents/baseagent.js
CHANGED
|
@@ -14,6 +14,7 @@ import path from 'path';
|
|
|
14
14
|
import os from 'os';
|
|
15
15
|
import { commandExists, isWindows, resolveProbePath } from '../utils/cross-platform.js';
|
|
16
16
|
import { execFileSync } from 'child_process';
|
|
17
|
+
import { parse as parseToml } from 'smol-toml';
|
|
17
18
|
/** Resolve the installed Codex CLI entrypoint, including npm shims on Windows. */
|
|
18
19
|
export function resolveCodexCliPath() {
|
|
19
20
|
return resolveProbePath('codex');
|
|
@@ -185,55 +186,74 @@ export function resolveAnthropicConfig(config, override) {
|
|
|
185
186
|
|| pickExec(config.agents?.claude?.pathToClaudeCodeExecutable);
|
|
186
187
|
return { apiKey, baseUrl, headers, queryParams, model, effort, pathToClaudeCodeExecutable };
|
|
187
188
|
}
|
|
189
|
+
function nonEmptyString(value) {
|
|
190
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
191
|
+
}
|
|
192
|
+
function recordValue(value) {
|
|
193
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
194
|
+
? value
|
|
195
|
+
: undefined;
|
|
196
|
+
}
|
|
188
197
|
export function loadCodexSettings() {
|
|
198
|
+
const configuredHome = process.env.CODEX_HOME?.trim();
|
|
199
|
+
const codexHome = configuredHome ? path.resolve(configuredHome) : path.join(os.homedir(), '.codex');
|
|
200
|
+
const authPath = path.join(codexHome, 'auth.json');
|
|
201
|
+
const configPath = path.join(codexHome, 'config.toml');
|
|
202
|
+
let authJsonApiKey;
|
|
189
203
|
try {
|
|
190
|
-
const configuredHome = process.env.CODEX_HOME?.trim();
|
|
191
|
-
const codexHome = configuredHome ? path.resolve(configuredHome) : path.join(os.homedir(), '.codex');
|
|
192
|
-
const authPath = path.join(codexHome, 'auth.json');
|
|
193
|
-
let apiKey;
|
|
194
204
|
if (fs.existsSync(authPath)) {
|
|
195
205
|
const auth = JSON.parse(fs.readFileSync(authPath, 'utf-8'));
|
|
196
|
-
|
|
206
|
+
authJsonApiKey = nonEmptyString(auth?.OPENAI_API_KEY);
|
|
197
207
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// A corrupt auth.json must not prevent the provider config from loading.
|
|
211
|
+
}
|
|
212
|
+
let model;
|
|
213
|
+
let baseUrl;
|
|
214
|
+
let provider;
|
|
215
|
+
let bearerToken;
|
|
216
|
+
let requiresOpenaiAuth;
|
|
217
|
+
try {
|
|
202
218
|
if (fs.existsSync(configPath)) {
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
219
|
+
const parsed = recordValue(parseToml(fs.readFileSync(configPath, 'utf-8')));
|
|
220
|
+
model = nonEmptyString(parsed?.model);
|
|
221
|
+
provider = nonEmptyString(parsed?.model_provider);
|
|
222
|
+
const providers = recordValue(parsed?.model_providers);
|
|
223
|
+
const selectedProvider = provider ? recordValue(providers?.[provider]) : undefined;
|
|
224
|
+
baseUrl = nonEmptyString(selectedProvider?.base_url);
|
|
225
|
+
bearerToken = nonEmptyString(selectedProvider?.experimental_bearer_token);
|
|
226
|
+
requiresOpenaiAuth = typeof selectedProvider?.requires_openai_auth === 'boolean'
|
|
227
|
+
? selectedProvider.requires_openai_auth
|
|
228
|
+
: undefined;
|
|
212
229
|
}
|
|
213
|
-
return { apiKey, baseUrl, model, provider };
|
|
214
230
|
}
|
|
215
231
|
catch { }
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
continue;
|
|
229
|
-
const tail = content.slice(section.index + section[0].length);
|
|
230
|
-
const nextSection = tail.search(/^\s*\[/m);
|
|
231
|
-
const block = nextSection >= 0 ? tail.slice(0, nextSection) : tail;
|
|
232
|
-
const baseUrl = block.match(/^\s*base_url\s*=\s*"([^"]+)"/m)?.[1];
|
|
233
|
-
if (baseUrl)
|
|
234
|
-
return baseUrl;
|
|
232
|
+
// Codex applies a provider's explicit bearer token before auth.json. Keep
|
|
233
|
+
// that precedence so EvolCore and the app-server select the same identity.
|
|
234
|
+
if (bearerToken) {
|
|
235
|
+
return {
|
|
236
|
+
apiKey: bearerToken,
|
|
237
|
+
authType: 'bearerToken',
|
|
238
|
+
authSource: 'config.toml',
|
|
239
|
+
baseUrl,
|
|
240
|
+
model,
|
|
241
|
+
provider,
|
|
242
|
+
requiresOpenaiAuth,
|
|
243
|
+
};
|
|
235
244
|
}
|
|
236
|
-
|
|
245
|
+
if (authJsonApiKey) {
|
|
246
|
+
return {
|
|
247
|
+
apiKey: authJsonApiKey,
|
|
248
|
+
authType: 'apiKey',
|
|
249
|
+
authSource: 'auth.json',
|
|
250
|
+
baseUrl,
|
|
251
|
+
model,
|
|
252
|
+
provider,
|
|
253
|
+
requiresOpenaiAuth,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return { baseUrl, model, provider, requiresOpenaiAuth };
|
|
237
257
|
}
|
|
238
258
|
/**
|
|
239
259
|
* Resolve a complete credential/endpoint pair for direct OpenAI HTTP calls.
|
|
@@ -248,14 +268,23 @@ export function resolveOpenaiDirectConfig(override) {
|
|
|
248
268
|
...normalizeRequestMetadata(override),
|
|
249
269
|
};
|
|
250
270
|
}
|
|
251
|
-
const
|
|
271
|
+
const settings = loadCodexSettings();
|
|
272
|
+
const configuredBearer = settings.authType === 'bearerToken'
|
|
273
|
+
? directInferencePair(settings.apiKey, settings.baseUrl)
|
|
274
|
+
: undefined;
|
|
275
|
+
if (configuredBearer) {
|
|
276
|
+
return {
|
|
277
|
+
...configuredBearer,
|
|
278
|
+
...normalizeRequestMetadata(override),
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const environment = directInferencePair(process.env.OPENAI_API_KEY || process.env.CODEX_API_KEY, process.env.OPENAI_BASE_URL);
|
|
252
282
|
if (environment) {
|
|
253
283
|
return {
|
|
254
284
|
...environment,
|
|
255
285
|
...normalizeRequestMetadata(override),
|
|
256
286
|
};
|
|
257
287
|
}
|
|
258
|
-
const settings = loadCodexSettings();
|
|
259
288
|
const settingsResolved = directInferencePair(settings.apiKey, settings.baseUrl);
|
|
260
289
|
return settingsResolved
|
|
261
290
|
? {
|
|
@@ -269,12 +298,31 @@ export function resolveOpenaiConfig(config, override, runtime) {
|
|
|
269
298
|
const isPlaceholder = (v) => !v || v.includes('your-') || v.includes('placeholder');
|
|
270
299
|
const overrideApiKey = isPlaceholder(override?.apiKey) ? undefined : override?.apiKey;
|
|
271
300
|
const globalApiKey = isPlaceholder(config.agents?.codex?.apiKey) ? undefined : config.agents?.codex?.apiKey;
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
301
|
+
const environmentApiKey = [process.env.OPENAI_API_KEY, process.env.CODEX_API_KEY]
|
|
302
|
+
.map(value => isPlaceholder(value) ? undefined : value)
|
|
303
|
+
.find((value) => !!value);
|
|
304
|
+
const configuredBearer = codexSettings.authType === 'bearerToken' ? codexSettings.apiKey : undefined;
|
|
305
|
+
const storedApiKey = codexSettings.authType === 'apiKey' ? codexSettings.apiKey : undefined;
|
|
306
|
+
// A selected provider's explicit token is authoritative for that provider.
|
|
307
|
+
// OPENAI_API_KEY is not used by Codex when the provider declares its own
|
|
308
|
+
// bearer token, so choosing it here would make EvolCore and app-server use
|
|
309
|
+
// different credentials.
|
|
310
|
+
const credential = overrideApiKey
|
|
311
|
+
? { apiKey: overrideApiKey, authType: 'apiKey', authSource: 'agent-config' }
|
|
312
|
+
: globalApiKey
|
|
313
|
+
? { apiKey: globalApiKey, authType: 'apiKey', authSource: 'agent-config' }
|
|
314
|
+
: configuredBearer
|
|
315
|
+
? { apiKey: configuredBearer, authType: 'bearerToken', authSource: 'config.toml' }
|
|
316
|
+
: environmentApiKey
|
|
317
|
+
? { apiKey: environmentApiKey, authType: 'apiKey', authSource: 'environment' }
|
|
318
|
+
: storedApiKey
|
|
319
|
+
? { apiKey: storedApiKey, authType: 'apiKey', authSource: 'auth.json' }
|
|
320
|
+
: undefined;
|
|
321
|
+
const apiKey = credential?.apiKey;
|
|
322
|
+
const authType = credential?.authType;
|
|
323
|
+
const authSource = credential?.authSource;
|
|
276
324
|
if (!apiKey) {
|
|
277
|
-
throw new Error('No
|
|
325
|
+
throw new Error('No Codex credential found. Set baseagents.codex.apiKey, env OPENAI_API_KEY/CODEX_API_KEY, ~/.codex/auth.json, or a provider experimental_bearer_token in ~/.codex/config.toml');
|
|
278
326
|
}
|
|
279
327
|
const isPlaceholderUrl = (v) => !v || v.includes('api.openai.com');
|
|
280
328
|
const overrideBaseUrl = isPlaceholderUrl(override?.baseUrl) ? undefined : override?.baseUrl;
|
|
@@ -303,6 +351,8 @@ export function resolveOpenaiConfig(config, override, runtime) {
|
|
|
303
351
|
?? undefined;
|
|
304
352
|
return {
|
|
305
353
|
apiKey,
|
|
354
|
+
authType,
|
|
355
|
+
authSource,
|
|
306
356
|
baseUrl,
|
|
307
357
|
provider: codexSettings.provider,
|
|
308
358
|
headers,
|
|
@@ -25,12 +25,13 @@ import { sanitizeSessionTitle } from '../core/session/session-title.js';
|
|
|
25
25
|
import { resolveClaudeCapabilityRunOptionsForProject } from '../core/capability/capability-manager.js';
|
|
26
26
|
import { normalizeExecutionPermissionMode, normalizePermissionMode, resolvePhaseOneExecutionSandbox } from '../core/permission/mode.js';
|
|
27
27
|
import { buildClaudeProtectedFilesystem, containsHClassReference, containsLClassReference, isHClassPath, isLClassPath, isSameOrDescendant, resolveProtectedCandidate, } from '../core/permission/protected-paths.js';
|
|
28
|
-
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, createSandboxInitializationError, getActiveSandboxInitializationFailure, isSandboxInitializationFailure, recordSandboxInitializationFailure, SANDBOX_INITIALIZATION_COOLDOWN_MS, SANDBOX_INITIALIZATION_FAILED, ensureClaudeGitWorktreeConfig, prependExecutableDirectory, resolveBubblewrapPath, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, shouldFailIfClaudeSandboxUnavailable, shouldLogSandboxCircuitNotice, } from '../core/permission/sandbox-runtime.js';
|
|
28
|
+
import { buildHClassGuardCommand, collectSandboxGuardDiagnostics, createSandboxInitializationError, getActiveSandboxInitializationFailure, isSandboxInitializationFailure, isSandboxInitializationToolResult, recordSandboxInitializationFailure, SANDBOX_INITIALIZATION_COOLDOWN_MS, SANDBOX_INITIALIZATION_FAILED, ensureClaudeGitWorktreeConfig, prependExecutableDirectory, resolveBubblewrapPath, summarizeBubblewrapArgsForLog, summarizeSandboxGuardDiagnostics, shouldFailIfClaudeSandboxUnavailable, shouldLogSandboxCircuitNotice, } from '../core/permission/sandbox-runtime.js';
|
|
29
29
|
import { buildClaudeUnixSocketAllowlist } from '../core/permission/unix-socket-policy.js';
|
|
30
30
|
import { auditToolInfrastructureFailure, auditToolPreflightDenial } from '../core/auth/authorization-audit.js';
|
|
31
31
|
import { getManagedTaskTempDir, isManagedSessionRuntimeDir } from '../cli/task-context.js';
|
|
32
32
|
import { hasTrustedFullAccessContext } from './runner-types.js';
|
|
33
|
-
import { contextTokensForUsage, usageForContext, isClaudeContextUsageModel, isOneMillionContextModel, realContextWindowForModel, autoCompactWindowForModel } from './runner-types.js';
|
|
33
|
+
import { contextTokensForUsage, usageForContext, isClaudeContextUsageModel, isOneMillionContextModel, realContextWindowForModel, autoCompactWindowForModel, sdkAutoCompactWindowForModel } from './runner-types.js';
|
|
34
|
+
import { hasContextWindowSuffix, stripContextWindowSuffix } from '../core/model/context-window-suffix.js';
|
|
34
35
|
const resolveModule = createRequire(import.meta.url);
|
|
35
36
|
/**
|
|
36
37
|
* Resolve the platform package explicitly instead of relying on the SDK's
|
|
@@ -409,11 +410,18 @@ async function refreshGatewayPricing(baseUrl, apiKey, requestHeaders) {
|
|
|
409
410
|
}
|
|
410
411
|
/**
|
|
411
412
|
* 为支持 1M 上下文的模型追加 `[1m]` 后缀——仅在交给 SDK query() 时调用。
|
|
412
|
-
*
|
|
413
|
+
*
|
|
414
|
+
* 若网关把窗口变体作为独立条目下发(目录里同时有 `claude-opus-5` 与
|
|
415
|
+
* `claude-opus-5[1m]`),裸 ID 就是用户明确选的非 1M 变体,不能擅自升级,
|
|
416
|
+
* 否则两条列表项的实际效果无法区分。只有目录未提供任何窗口变体时,才沿用
|
|
417
|
+
* 按本地名单补 `[1m]` 的旧行为。
|
|
413
418
|
*/
|
|
414
|
-
function applyContextWindow(modelId) {
|
|
415
|
-
if (
|
|
416
|
-
return modelId; //
|
|
419
|
+
function applyContextWindow(modelId, catalog) {
|
|
420
|
+
if (hasContextWindowSuffix(modelId))
|
|
421
|
+
return modelId; // 窗口已显式指定
|
|
422
|
+
const variantListed = catalog?.models.some(m => hasContextWindowSuffix(m.id) && stripContextWindowSuffix(m.id) === modelId);
|
|
423
|
+
if (variantListed)
|
|
424
|
+
return modelId;
|
|
417
425
|
if (isOneMillionContextModel(modelId))
|
|
418
426
|
return `${modelId}[1m]`;
|
|
419
427
|
return modelId;
|
|
@@ -500,9 +508,9 @@ export class AgentRunner {
|
|
|
500
508
|
/** 每个 session 最近的子进程 stderr 行(环形缓冲),用于子进程崩溃时还原真正原因 */
|
|
501
509
|
recentStderr = new Map();
|
|
502
510
|
static STDERR_BUFFER_MAX = 80;
|
|
503
|
-
async recordSandboxInfrastructureFailure(sessionId, inputId, permissionMode, error, stderr = []) {
|
|
511
|
+
async recordSandboxInfrastructureFailure(sessionId, inputId, permissionMode, error, stderr = [], scope = 'process') {
|
|
504
512
|
const detail = createSandboxInitializationError(error, stderr);
|
|
505
|
-
const circuit = recordSandboxInitializationFailure(detail, stderr);
|
|
513
|
+
const circuit = recordSandboxInitializationFailure(detail, stderr, Date.now(), scope === 'session' ? sessionId : undefined);
|
|
506
514
|
const context = this.permissionContexts.get(sessionId);
|
|
507
515
|
auditToolInfrastructureFailure({
|
|
508
516
|
toolName: 'Bash',
|
|
@@ -1343,6 +1351,7 @@ export class AgentRunner {
|
|
|
1343
1351
|
const taskMetadata = new Map();
|
|
1344
1352
|
// tool_use_id → tool_name 映射,用于从 SDKUserMessage 的 tool_result 块中还原工具名
|
|
1345
1353
|
const toolUseNames = new Map();
|
|
1354
|
+
const sandboxedBashCalls = new Set();
|
|
1346
1355
|
const emittedToolResultIds = new Set();
|
|
1347
1356
|
let turnCount = 0;
|
|
1348
1357
|
const seenMessageIds = new Set();
|
|
@@ -1617,6 +1626,10 @@ export class AgentRunner {
|
|
|
1617
1626
|
if (content.type === 'tool_use') {
|
|
1618
1627
|
if (content.id)
|
|
1619
1628
|
toolUseNames.set(content.id, content.name);
|
|
1629
|
+
if (content.id && content.name === 'Bash' && content.input?.dangerouslyDisableSandbox !== true
|
|
1630
|
+
&& resolvePhaseOneExecutionSandbox(permissionMode, this.permissionContexts.get(sessionId)?.role).state !== 'off') {
|
|
1631
|
+
sandboxedBashCalls.add(content.id);
|
|
1632
|
+
}
|
|
1620
1633
|
yield { type: 'tool_use', name: content.name, input: content.input, callId: content.id, turn: turnCount, outputTokens: turnOutputChars, assistantUuid: event.uuid };
|
|
1621
1634
|
}
|
|
1622
1635
|
else if (content.type === 'text' && content.text) {
|
|
@@ -1635,6 +1648,31 @@ export class AgentRunner {
|
|
|
1635
1648
|
: block.content != null ? JSON.stringify(block.content) : '';
|
|
1636
1649
|
if (block.tool_use_id)
|
|
1637
1650
|
emittedToolResultIds.add(block.tool_use_id);
|
|
1651
|
+
if (sandboxedBashCalls.delete(block.tool_use_id) && block.is_error === true
|
|
1652
|
+
&& isSandboxInitializationToolResult(block.content)) {
|
|
1653
|
+
const { detail } = await this.recordSandboxInfrastructureFailure(sessionId, block.tool_use_id, permissionMode, new Error(resultContent), [], 'session');
|
|
1654
|
+
// Stop this SDK query before another model/tool retry. Do not use
|
|
1655
|
+
// interrupt(), which waits for this very generator to finish.
|
|
1656
|
+
this.activeMessageStreams.get(sessionId)?.end();
|
|
1657
|
+
const query = sdkStream;
|
|
1658
|
+
try {
|
|
1659
|
+
await query.close?.();
|
|
1660
|
+
}
|
|
1661
|
+
catch (error) {
|
|
1662
|
+
logger.warn(`[ClaudeSandbox] failed to close sandbox-failed query: ${error}`);
|
|
1663
|
+
}
|
|
1664
|
+
yield {
|
|
1665
|
+
type: 'tool_result', name: toolName, result: resultContent, isError: true,
|
|
1666
|
+
error: detail.message, errorCode: 'CAPABILITY_UNAVAILABLE', callId: block.tool_use_id,
|
|
1667
|
+
correlationId: block.tool_use_id, decision: 'error', decisionSource: 'infrastructure',
|
|
1668
|
+
policyCode: SANDBOX_INITIALIZATION_FAILED, executed: false, executionState: 'blocked',
|
|
1669
|
+
};
|
|
1670
|
+
yield {
|
|
1671
|
+
type: 'complete', isError: true, subtype: 'infrastructure',
|
|
1672
|
+
terminalReason: SANDBOX_INITIALIZATION_FAILED, errors: [detail.message], queryFinal: true,
|
|
1673
|
+
};
|
|
1674
|
+
return;
|
|
1675
|
+
}
|
|
1638
1676
|
yield {
|
|
1639
1677
|
type: 'tool_result',
|
|
1640
1678
|
name: toolName,
|
|
@@ -1992,7 +2030,7 @@ export class AgentRunner {
|
|
|
1992
2030
|
const executionSandbox = resolvePhaseOneExecutionSandbox(callPermissionMode, runPermissionContext?.role);
|
|
1993
2031
|
const inputId = modelOverride?.turn?.inputId ?? crypto.randomUUID();
|
|
1994
2032
|
if (executionSandbox.state !== 'off') {
|
|
1995
|
-
const activeSandboxFailure = getActiveSandboxInitializationFailure();
|
|
2033
|
+
const activeSandboxFailure = getActiveSandboxInitializationFailure(undefined, undefined, sessionId);
|
|
1996
2034
|
if (activeSandboxFailure) {
|
|
1997
2035
|
const detail = createSandboxInitializationError(new Error(`sandbox bootstrap circuit open; firstObservedAt=${activeSandboxFailure.openedAt} ` +
|
|
1998
2036
|
`occurrences=${activeSandboxFailure.occurrences}; ${activeSandboxFailure.detail}`));
|
|
@@ -2469,7 +2507,7 @@ export class AgentRunner {
|
|
|
2469
2507
|
else {
|
|
2470
2508
|
logger.info(`[AgentRunner] systemPromptAppend: none`);
|
|
2471
2509
|
}
|
|
2472
|
-
const sdkModel = applyContextWindow(resolveCatalogModel(runCatalog, callModel));
|
|
2510
|
+
const sdkModel = applyContextWindow(resolveCatalogModel(runCatalog, callModel), runCatalog);
|
|
2473
2511
|
const capabilityOptions = await this.resolveCapabilityRunOptions(projectPath);
|
|
2474
2512
|
const managedSettings = callPermissionMode === 'fullaccess'
|
|
2475
2513
|
? undefined
|
|
@@ -2552,7 +2590,7 @@ export class AgentRunner {
|
|
|
2552
2590
|
...(executionSandbox.state === 'off' && callPermissionMode !== 'fullaccess' && process.platform === 'linux' ? {
|
|
2553
2591
|
spawnClaudeCodeProcess: (options) => spawnClaudeWithHClassGuard(options, resolvePaths().root, handleClaudeStderr),
|
|
2554
2592
|
} : {}),
|
|
2555
|
-
autoCompactWindow:
|
|
2593
|
+
autoCompactWindow: sdkAutoCompactWindowForModel(sdkModel),
|
|
2556
2594
|
advisorModel: 'haiku',
|
|
2557
2595
|
canUseTool: canUseToolCallback,
|
|
2558
2596
|
permissionMode: sdkPermissionMode,
|
|
@@ -2891,7 +2929,7 @@ export class AgentRunner {
|
|
|
2891
2929
|
prompt,
|
|
2892
2930
|
options: {
|
|
2893
2931
|
cwd: projectPath,
|
|
2894
|
-
...(catalog && callModel ? { model: applyContextWindow(resolveCatalogModel(catalog, callModel)) } : {}),
|
|
2932
|
+
...(catalog && callModel ? { model: applyContextWindow(resolveCatalogModel(catalog, callModel), catalog) } : {}),
|
|
2895
2933
|
resume: agentSessionId,
|
|
2896
2934
|
maxTurns: 1,
|
|
2897
2935
|
tools: [],
|
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient {
|
|
|
232
232
|
: { sandbox: options?.sandbox ?? null }),
|
|
233
233
|
config: this.buildThreadConfig(effort, options?.config),
|
|
234
234
|
excludeTurns: false,
|
|
235
|
-
|
|
235
|
+
...(options?.lastTurnId ? { lastTurnId: options.lastTurnId } : {}),
|
|
236
236
|
});
|
|
237
237
|
const forkedThreadId = response.thread?.id;
|
|
238
238
|
if (title && forkedThreadId) {
|
|
@@ -252,16 +252,19 @@ export class CodexAppServerClient {
|
|
|
252
252
|
await this.request('thread/compact/start', { threadId });
|
|
253
253
|
return true;
|
|
254
254
|
}
|
|
255
|
-
async threadTurnsList(threadId, limit) {
|
|
255
|
+
async threadTurnsList(threadId, limit, cursor) {
|
|
256
256
|
return this.request('thread/turns/list', {
|
|
257
257
|
threadId,
|
|
258
258
|
...(limit ? { limit } : {}),
|
|
259
|
-
|
|
259
|
+
...(cursor ? { cursor } : {}),
|
|
260
|
+
// The app-server defaults to newest-first. `nextCursor` then walks
|
|
261
|
+
// toward older turns, which is the direction needed to hydrate history.
|
|
262
|
+
sortDirection: 'desc',
|
|
260
263
|
itemsView: 'full',
|
|
261
264
|
});
|
|
262
265
|
}
|
|
263
266
|
async threadTurnsItemsList(threadId, turnId, limit) {
|
|
264
|
-
return this.request('thread/
|
|
267
|
+
return this.request('thread/items/list', {
|
|
265
268
|
threadId,
|
|
266
269
|
turnId,
|
|
267
270
|
...(limit ? { limit } : {}),
|
|
@@ -643,7 +646,12 @@ export class CodexAppServerClient {
|
|
|
643
646
|
logger.warn(`[CodexAppServer] managed runtime lock directory unavailable: ${runtimeLockDir}`);
|
|
644
647
|
}
|
|
645
648
|
}
|
|
646
|
-
|
|
649
|
+
if (this.options.authType === 'bearerToken') {
|
|
650
|
+
delete env.CODEX_API_KEY;
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
env.CODEX_API_KEY = this.options.apiKey;
|
|
654
|
+
}
|
|
647
655
|
env.EVOLCORE_INSTANCE_SOCKET = resolvePaths().instanceSocket;
|
|
648
656
|
for (const [name, value] of Object.entries(this.options.headers ?? {})) {
|
|
649
657
|
env[codexHeaderEnvName(name)] = value;
|
|
@@ -28,7 +28,7 @@ export async function codexNativeCatalog(context) {
|
|
|
28
28
|
if (context.baseagent !== 'codex')
|
|
29
29
|
return null;
|
|
30
30
|
const client = new CodexAppServerClient({
|
|
31
|
-
apiKey: context.apiKey ?? '', baseUrl: context.baseUrl, provider: context.provider,
|
|
31
|
+
apiKey: context.apiKey ?? '', authType: context.authType, baseUrl: context.baseUrl, provider: context.provider,
|
|
32
32
|
headers: context.headers, queryParams: context.queryParams,
|
|
33
33
|
});
|
|
34
34
|
let timer;
|
|
@@ -179,6 +179,39 @@ function realDirectoryState(directory) {
|
|
|
179
179
|
return 'unavailable';
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
/** Read back the package root that managedHookLauncher() embedded. */
|
|
183
|
+
function launcherPackageRoot(launcher) {
|
|
184
|
+
const match = /^\s*const packageRoot = ("(?:[^"\\]|\\.)*")\s*;/m.exec(launcher);
|
|
185
|
+
if (!match)
|
|
186
|
+
return null;
|
|
187
|
+
try {
|
|
188
|
+
const value = JSON.parse(match[1]);
|
|
189
|
+
return typeof value === 'string' && value ? value : null;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* A `npm link` install reaches the package through a symlinked global path, so
|
|
197
|
+
* the launcher and the running CLI legitimately spell the same package root
|
|
198
|
+
* differently. Compare the resolved targets instead of the literal strings;
|
|
199
|
+
* a launcher pointing at a genuinely different package still fails closed.
|
|
200
|
+
*/
|
|
201
|
+
function samePackageRoot(embedded, expected) {
|
|
202
|
+
if (!embedded)
|
|
203
|
+
return false;
|
|
204
|
+
const normalize = (value) => path.normalize(value).replace(/[\\/]+$/, '').toLowerCase();
|
|
205
|
+
const resolved = (value) => {
|
|
206
|
+
try {
|
|
207
|
+
return normalize(fs.realpathSync(value));
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return normalize(value);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
return normalize(embedded) === normalize(expected) || resolved(embedded) === resolved(expected);
|
|
214
|
+
}
|
|
182
215
|
/** Read-only inspection of the machine-wide Windows Codex managed hook. */
|
|
183
216
|
export function inspectCodexManagedHook(options = {}) {
|
|
184
217
|
const paths = codexManagedHookPaths(options);
|
|
@@ -252,7 +285,7 @@ export function inspectCodexManagedHook(options = {}) {
|
|
|
252
285
|
const normalized = (value) => path.normalize(String(value || '')).toLowerCase();
|
|
253
286
|
const expectedPackageRoot = path.resolve(options.packageRoot || process.cwd());
|
|
254
287
|
const launcherValid = launcher.includes('EVOLCORE_MANAGED_HOOK_LAUNCHER')
|
|
255
|
-
&& launcher
|
|
288
|
+
&& samePackageRoot(launcherPackageRoot(launcher), expectedPackageRoot);
|
|
256
289
|
const configuredDir = config.hooks?.windows_managed_dir ?? config.hooks?.managed_dir;
|
|
257
290
|
const groups = config.hooks?.PreToolUse;
|
|
258
291
|
const canonicalCommand = (value) => {
|