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
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { getRunnerCatalog, catalogEfforts, assertCatalogSelectable } from '../core/model/model-catalog.js';
|
|
2
|
+
// Codex/OpenAI API 不认识 Claude Code SDK 的窗口后缀,必须传入基础模型 ID。
|
|
3
|
+
import { stripContextWindowSuffix } from '../core/model/context-window-suffix.js';
|
|
2
4
|
import { hasTrustedFullAccessContext } from './runner-types.js';
|
|
3
5
|
import { requestDangerousCommandPermission } from '../core/permission/approval-gateway.js';
|
|
4
6
|
import { checkReadonly, checkDangerousCommand, evaluateToolPreflight } from '../core/permission/tool-policy.js';
|
|
@@ -9,7 +11,7 @@ import { resolveOpenaiConfig, resolveCodexCliPath } from './baseagent.js';
|
|
|
9
11
|
import { logger } from '../utils/logger.js';
|
|
10
12
|
import { summarizeToolInputForAudit } from '../utils/tool-summary.js';
|
|
11
13
|
import { auditCodexApprovalDecision, auditPermissionLifecycle, auditToolPreflightDenial } from '../core/auth/authorization-audit.js';
|
|
12
|
-
import { isRetryableError } from '../utils/error-utils.js';
|
|
14
|
+
import { classifyError, ErrorType, isOutputTokenLimitError, isRetryableError } from '../utils/error-utils.js';
|
|
13
15
|
import { renderActionAsText } from '../core/interaction-router.js';
|
|
14
16
|
import { buildEnvelope, isInteractionSendAccepted, sendInteractionPayload } from '../core/message/message-utils.js';
|
|
15
17
|
import { resolveCodexCapabilityThreadConfigForProject } from '../core/capability/capability-manager.js';
|
|
@@ -36,19 +38,22 @@ const MIME_EXT = {
|
|
|
36
38
|
'image/webp': '.webp',
|
|
37
39
|
};
|
|
38
40
|
const APPROVAL_LOG_SUMMARY_MAX_LENGTH = 256;
|
|
41
|
+
function toAgentErrorType(message) {
|
|
42
|
+
switch (classifyError(new Error(message))) {
|
|
43
|
+
case ErrorType.CONTEXT_TOO_LONG: return 'context_too_long';
|
|
44
|
+
case ErrorType.AUTH_ERROR: return 'auth';
|
|
45
|
+
case ErrorType.API_ERROR:
|
|
46
|
+
case ErrorType.STREAM_ERROR:
|
|
47
|
+
case ErrorType.SDK_TIMEOUT: return 'network';
|
|
48
|
+
default: return 'unknown';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
39
51
|
export function formatApprovalLogSummary(summary) {
|
|
40
52
|
const singleLine = summary.replace(/\s+/gu, ' ').trim();
|
|
41
53
|
if (singleLine.length <= APPROVAL_LOG_SUMMARY_MAX_LENGTH)
|
|
42
54
|
return singleLine;
|
|
43
55
|
return singleLine.slice(0, APPROVAL_LOG_SUMMARY_MAX_LENGTH - 3).trimEnd() + '...';
|
|
44
56
|
}
|
|
45
|
-
/**
|
|
46
|
-
* 规范化模型 ID:去掉 Claude Code SDK 专有的上下文窗口后缀 [1m]/[200k]
|
|
47
|
-
* Codex/OpenAI API 不认识这些后缀,必须传入标准模型 ID
|
|
48
|
-
*/
|
|
49
|
-
function stripContextWindowSuffix(modelId) {
|
|
50
|
-
return modelId.replace(/\[(?:1m|200k)\]$/i, '');
|
|
51
|
-
}
|
|
52
57
|
// ── Codex 模型目录(动态获取,含 effort) ──
|
|
53
58
|
class AsyncEventQueue {
|
|
54
59
|
queue = [];
|
|
@@ -198,11 +203,13 @@ function parseManagedPreToolUseDenial(value) {
|
|
|
198
203
|
.trim();
|
|
199
204
|
if (!reason)
|
|
200
205
|
reason = 'EvolCore PreToolUse policy denied this tool call';
|
|
201
|
-
const policyCode =
|
|
202
|
-
? '
|
|
203
|
-
:
|
|
204
|
-
? '
|
|
205
|
-
:
|
|
206
|
+
const policyCode = /当前汇报命令(?:未通过规范解析|不符合当前会话)/.test(reason)
|
|
207
|
+
? 'proactive_send_invalid'
|
|
208
|
+
: /工具调用已达到\s*\d+\s*次/.test(reason)
|
|
209
|
+
? 'proactive_tool_report_required'
|
|
210
|
+
: /请先用\s+ec\s+(?:group\s+send|msg\s+send)/.test(reason)
|
|
211
|
+
? 'proactive_first_send_required'
|
|
212
|
+
: 'managed_pre_tool_use_denied';
|
|
206
213
|
return { policyCode, reason };
|
|
207
214
|
}
|
|
208
215
|
function outputTextForManagedHook(value) {
|
|
@@ -442,6 +449,7 @@ export class CodexRunner {
|
|
|
442
449
|
return existing;
|
|
443
450
|
const client = new CodexAppServerClient({
|
|
444
451
|
apiKey: this.resolvedConfig.apiKey,
|
|
452
|
+
authType: this.resolvedConfig.authType,
|
|
445
453
|
baseUrl: this.resolvedConfig.baseUrl,
|
|
446
454
|
provider: this.resolvedConfig.provider,
|
|
447
455
|
headers: this.resolvedConfig.headers,
|
|
@@ -2607,7 +2615,7 @@ export class CodexRunner {
|
|
|
2607
2615
|
release();
|
|
2608
2616
|
}
|
|
2609
2617
|
}
|
|
2610
|
-
async forkSessionLocked(agentSessionId, projectPath, title) {
|
|
2618
|
+
async forkSessionLocked(agentSessionId, projectPath, title, lastTurnId) {
|
|
2611
2619
|
const sessionKey = this.findSessionKeyByThread(agentSessionId);
|
|
2612
2620
|
const mode = this.chatModes.get(sessionKey) ?? this.currentMode;
|
|
2613
2621
|
const executionSandbox = this.buildExecutionSandboxOptions(sessionKey, mode, projectPath);
|
|
@@ -2625,6 +2633,7 @@ export class CodexRunner {
|
|
|
2625
2633
|
approvalsReviewer: 'user',
|
|
2626
2634
|
...(executionSandbox.sandbox ? { sandbox: executionSandbox.sandbox } : {}),
|
|
2627
2635
|
config: this.sanitizeThreadEnvironmentConfig(this.mergeThreadConfig(executionSandbox.permissionProfileConfig, capabilityConfig, externalToolConfig, this.buildEvolcoreShellEnvironmentConfig(sessionKey, delegationCarrier), this.buildLifecycleLockdownConfig(mode)), mode),
|
|
2636
|
+
...(lastTurnId ? { lastTurnId } : {}),
|
|
2628
2637
|
});
|
|
2629
2638
|
const forkedThreadId = response.thread?.id;
|
|
2630
2639
|
if (!forkedThreadId)
|
|
@@ -2639,29 +2648,80 @@ export class CodexRunner {
|
|
|
2639
2648
|
async forkSessionAt(agentSessionId, projectPath, assistantMessageId, title) {
|
|
2640
2649
|
const release = await this.acquireThreadOperation(this.threadOperationKey(agentSessionId), 'forkAt');
|
|
2641
2650
|
try {
|
|
2642
|
-
const
|
|
2651
|
+
const appServer = this.getAppServerClientForThread(agentSessionId);
|
|
2652
|
+
const history = await this.readForkHistory(appServer, agentSessionId);
|
|
2653
|
+
const messages = this.mapThreadToSessionMessages(history, agentSessionId);
|
|
2654
|
+
const turns = buildSessionTurnList(messages);
|
|
2643
2655
|
const targetIndex = turns.findIndex(turn => turn.assistantUuid === assistantMessageId);
|
|
2644
2656
|
if (targetIndex < 0)
|
|
2645
2657
|
throw new Error('fork point not found');
|
|
2646
|
-
const
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
try {
|
|
2651
|
-
const rolledBack = await this.rollbackSessionTurnsLocked(forkedThreadId, turnsToDiscard);
|
|
2652
|
-
if (!rolledBack)
|
|
2653
|
-
throw new Error('forked thread rollback failed');
|
|
2654
|
-
}
|
|
2655
|
-
finally {
|
|
2656
|
-
rollbackRelease();
|
|
2657
|
-
}
|
|
2658
|
-
}
|
|
2659
|
-
return forkedThreadId;
|
|
2658
|
+
const targetTurnId = this.findTurnIdForAssistantMessage(history, assistantMessageId);
|
|
2659
|
+
if (!targetTurnId)
|
|
2660
|
+
throw new Error('fork point turn not found');
|
|
2661
|
+
return await this.forkSessionLocked(agentSessionId, projectPath, title, targetTurnId);
|
|
2660
2662
|
}
|
|
2661
2663
|
finally {
|
|
2662
2664
|
release();
|
|
2663
2665
|
}
|
|
2664
2666
|
}
|
|
2667
|
+
findTurnIdForAssistantMessage(response, assistantMessageId) {
|
|
2668
|
+
for (const turn of response.thread?.turns ?? []) {
|
|
2669
|
+
if (typeof turn.id !== 'string' || !turn.id)
|
|
2670
|
+
continue;
|
|
2671
|
+
for (const item of this.getTurnItems(turn)) {
|
|
2672
|
+
if (item.type === 'agentMessage' && item.id === assistantMessageId)
|
|
2673
|
+
return turn.id;
|
|
2674
|
+
}
|
|
2675
|
+
// Older app-server histories may omit item ids; the mapper then uses the
|
|
2676
|
+
// turn id as the assistant message id fallback.
|
|
2677
|
+
if (turn.id === assistantMessageId)
|
|
2678
|
+
return turn.id;
|
|
2679
|
+
}
|
|
2680
|
+
return undefined;
|
|
2681
|
+
}
|
|
2682
|
+
async readForkHistory(appServer, threadId) {
|
|
2683
|
+
let directRead;
|
|
2684
|
+
let directReadError;
|
|
2685
|
+
try {
|
|
2686
|
+
directRead = await appServer.threadRead(threadId, true);
|
|
2687
|
+
if ((directRead.thread?.turns?.length ?? 0) > 0)
|
|
2688
|
+
return directRead;
|
|
2689
|
+
}
|
|
2690
|
+
catch (error) {
|
|
2691
|
+
directReadError = error;
|
|
2692
|
+
}
|
|
2693
|
+
// Paginated threads reject full-history thread/read. Hydrate turns through
|
|
2694
|
+
// the experimental paging RPC, retaining full items so assistant message
|
|
2695
|
+
// IDs can be mapped to their containing turn.
|
|
2696
|
+
const turns = [];
|
|
2697
|
+
let cursor;
|
|
2698
|
+
const seenCursors = new Set();
|
|
2699
|
+
try {
|
|
2700
|
+
do {
|
|
2701
|
+
const page = await appServer.threadTurnsList(threadId, 100, cursor);
|
|
2702
|
+
if (Array.isArray(page.data)) {
|
|
2703
|
+
turns.push(...page.data.filter((turn) => !!turn && typeof turn === 'object'));
|
|
2704
|
+
}
|
|
2705
|
+
const nextCursor = typeof page.nextCursor === 'string' && page.nextCursor ? page.nextCursor : undefined;
|
|
2706
|
+
if (!nextCursor || seenCursors.has(nextCursor))
|
|
2707
|
+
break;
|
|
2708
|
+
seenCursors.add(nextCursor);
|
|
2709
|
+
cursor = nextCursor;
|
|
2710
|
+
} while (true);
|
|
2711
|
+
}
|
|
2712
|
+
catch (error) {
|
|
2713
|
+
if (directReadError)
|
|
2714
|
+
throw directReadError;
|
|
2715
|
+
throw error;
|
|
2716
|
+
}
|
|
2717
|
+
// Pages are returned newest-first when following `nextCursor`; restore
|
|
2718
|
+
// chronological order before mapping turns to session messages.
|
|
2719
|
+
if (turns.length > 0)
|
|
2720
|
+
return { thread: { ...(directRead?.thread ?? {}), id: threadId, turns: turns.reverse() } };
|
|
2721
|
+
if (directRead)
|
|
2722
|
+
return directRead;
|
|
2723
|
+
throw directReadError instanceof Error ? directReadError : new Error('Codex thread history unavailable');
|
|
2724
|
+
}
|
|
2665
2725
|
async setSessionName(agentSessionId, name) {
|
|
2666
2726
|
return this.getAppServerClientForThread(agentSessionId).threadSetName(agentSessionId, name);
|
|
2667
2727
|
}
|
|
@@ -4415,24 +4475,46 @@ export class CodexRunner {
|
|
|
4415
4475
|
this.clearPendingToolDenialsForTurn(state.threadId, turnId);
|
|
4416
4476
|
yield* this.reconcileOpenAppServerToolCalls(state, turnId);
|
|
4417
4477
|
if (turn.status === 'failed' && turn.error?.message) {
|
|
4478
|
+
logger.warn(`[CodexRunner] turn failed: ${JSON.stringify({
|
|
4479
|
+
sessionId, threadId: state.threadId, turnId, model: state.model,
|
|
4480
|
+
errorType: classifyError(new Error(turn.error.message)),
|
|
4481
|
+
message: formatApprovalLogSummary(turn.error.message),
|
|
4482
|
+
lastReportedUsage: state.tokenUsage?.last,
|
|
4483
|
+
})}`);
|
|
4418
4484
|
if (isRetryableError(new Error(turn.error.message))) {
|
|
4419
4485
|
throw new Error(turn.error.message);
|
|
4420
4486
|
}
|
|
4421
|
-
yield { type: 'error', error: turn.error.message, errorType:
|
|
4487
|
+
yield { type: 'error', error: turn.error.message, errorType: toAgentErrorType(turn.error.message) };
|
|
4422
4488
|
}
|
|
4423
4489
|
yield this.mapAppServerTurnComplete(turn, state);
|
|
4424
4490
|
break;
|
|
4425
4491
|
}
|
|
4426
4492
|
case 'error': {
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4493
|
+
// Current app-server uses error.message; older builds used message.
|
|
4494
|
+
const message = typeof params.error?.message === 'string' ? params.error.message : params.message;
|
|
4495
|
+
if (typeof message !== 'string' || !message.trim()) {
|
|
4496
|
+
logger.debug('[CodexRunner] app-server error notification without a diagnostic message');
|
|
4430
4497
|
break;
|
|
4431
4498
|
}
|
|
4432
|
-
|
|
4433
|
-
|
|
4499
|
+
logger.warn(`[CodexRunner] error notification: ${JSON.stringify({
|
|
4500
|
+
sessionId, threadId: state.threadId, turnId: state.turnId, model: state.model,
|
|
4501
|
+
willRetry: params.willRetry ?? null,
|
|
4502
|
+
errorType: classifyError(new Error(message)), message: formatApprovalLogSummary(message),
|
|
4503
|
+
})}`);
|
|
4504
|
+
// Codex owns retries within this turn. Throwing here closes our subscription
|
|
4505
|
+
// before its recovery can finish; runQuery must not submit the input again.
|
|
4506
|
+
if (params.willRetry === true) {
|
|
4507
|
+
yield {
|
|
4508
|
+
type: 'notice', severity: 'warn', subtype: 'codex-model-retry',
|
|
4509
|
+
message: isOutputTokenLimitError(new Error(message))
|
|
4510
|
+
? '模型响应达到输出上限,Codex 正在当前轮内重试。'
|
|
4511
|
+
: 'Codex 正在当前轮内重试模型请求。',
|
|
4512
|
+
};
|
|
4513
|
+
break;
|
|
4434
4514
|
}
|
|
4435
|
-
|
|
4515
|
+
if (isRetryableError(new Error(message)))
|
|
4516
|
+
throw new Error(message);
|
|
4517
|
+
yield { type: 'error', error: message, errorType: toAgentErrorType(message) };
|
|
4436
4518
|
break;
|
|
4437
4519
|
}
|
|
4438
4520
|
}
|
|
@@ -4863,16 +4945,17 @@ export class CodexRunner {
|
|
|
4863
4945
|
}
|
|
4864
4946
|
mapAppServerTurnComplete(turn, state) {
|
|
4865
4947
|
const status = turn.status || 'completed';
|
|
4948
|
+
const outputLimit = status === 'failed' && isOutputTokenLimitError(new Error(turn.error?.message ?? ''));
|
|
4866
4949
|
const tokenUsage = this.mapCodexTokenUsage(state.tokenUsage?.last ?? turn.tokenUsage ?? turn.usage);
|
|
4867
4950
|
const contextUsage = this.mapCodexContextUsage(turn.contextUsage ?? state.tokenUsage?.contextUsage ?? state.tokenUsage?.context);
|
|
4868
4951
|
const terminalReason = status === 'completed'
|
|
4869
4952
|
? undefined
|
|
4870
4953
|
: status === 'interrupted'
|
|
4871
4954
|
? 'aborted_streaming'
|
|
4872
|
-
: status;
|
|
4955
|
+
: outputLimit ? 'max_output_tokens' : status;
|
|
4873
4956
|
return {
|
|
4874
4957
|
type: 'complete',
|
|
4875
|
-
subtype: status === 'completed' ? 'success' : status,
|
|
4958
|
+
subtype: status === 'completed' ? 'success' : outputLimit ? 'max_output_tokens' : status,
|
|
4876
4959
|
isError: status === 'failed',
|
|
4877
4960
|
errors: turn.error?.message ? [turn.error.message] : undefined,
|
|
4878
4961
|
terminalReason,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { getRunnerCatalog, catalogEfforts, assertCatalogSelectable } from '../core/model/model-catalog.js';
|
|
2
|
+
// Ecagent/OpenAI API 不认识 Claude Code SDK 的窗口后缀,必须传入基础模型 ID。
|
|
3
|
+
import { stripContextWindowSuffix } from '../core/model/context-window-suffix.js';
|
|
2
4
|
import fs from 'fs';
|
|
3
5
|
import path from 'path';
|
|
4
6
|
import { AgentHarness, JsonlSessionRepo, NodeExecutionEnv, } from '../../ecagent/dist/node.js';
|
|
@@ -18,21 +20,14 @@ import { appendRequestPath } from './request-identity.js';
|
|
|
18
20
|
import { getManagedTaskTempDir } from '../cli/task-context.js';
|
|
19
21
|
import { hasTrustedFullAccessContext } from './runner-types.js';
|
|
20
22
|
const PROVIDER_ID = 'evolcore-gateway';
|
|
21
|
-
const DEFAULT_SYSTEM_PROMPT = `You are ecagent, the coding agent built into EvolCore.
|
|
22
|
-
Work directly in the current project. Inspect relevant files before changing them, keep edits scoped, and verify the result.
|
|
23
|
+
const DEFAULT_SYSTEM_PROMPT = `You are ecagent, the coding agent built into EvolCore.
|
|
24
|
+
Work directly in the current project. Inspect relevant files before changing them, keep edits scoped, and verify the result.
|
|
23
25
|
Use the provided tools for filesystem and shell work. Never claim a tool action succeeded unless its result confirms success.`;
|
|
24
26
|
const MAX_READ_BYTES = 1024 * 1024;
|
|
25
27
|
const MAX_TOOL_OUTPUT = 200_000;
|
|
26
28
|
const MAX_SCAN_FILES = 5_000;
|
|
27
29
|
const MAX_SEARCH_RESULTS = 500;
|
|
28
30
|
const DEFAULT_BASH_TIMEOUT_MS = 120_000;
|
|
29
|
-
/**
|
|
30
|
-
* 规范化模型 ID:去掉 Claude Code SDK 专有的上下文窗口后缀 [1m]/[200k]
|
|
31
|
-
* Ecagent/OpenAI API 不认识这些后缀,必须传入标准模型 ID
|
|
32
|
-
*/
|
|
33
|
-
function stripContextWindowSuffix(modelId) {
|
|
34
|
-
return modelId.replace(/\[(?:1m|200k)\]$/i, '');
|
|
35
|
-
}
|
|
36
31
|
class AsyncEventQueue {
|
|
37
32
|
values = [];
|
|
38
33
|
waiters = [];
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { getCatalog, assertCatalogSelectable } from '../core/model/model-catalog.js';
|
|
2
|
+
// Gemini API 不认识 Claude Code SDK 的窗口后缀,必须传入基础模型 ID。
|
|
3
|
+
import { stripContextWindowSuffix } from '../core/model/context-window-suffix.js';
|
|
2
4
|
/**
|
|
3
5
|
* Gemini Agent Runner
|
|
4
6
|
*
|
|
@@ -33,13 +35,6 @@ const ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\].*?(?:\x1b\\|\x07)/g;
|
|
|
33
35
|
function stripAnsi(text) {
|
|
34
36
|
return text.replace(ANSI_RE, '');
|
|
35
37
|
}
|
|
36
|
-
/**
|
|
37
|
-
* 规范化模型 ID:去掉 Claude Code SDK 专有的上下文窗口后缀 [1m]/[200k]
|
|
38
|
-
* Gemini API 不认识这些后缀,必须传入标准模型 ID
|
|
39
|
-
*/
|
|
40
|
-
function stripContextWindowSuffix(modelId) {
|
|
41
|
-
return modelId.replace(/\[(?:1m|200k)\]$/i, '');
|
|
42
|
-
}
|
|
43
38
|
// ── MIME → 扩展名映射 ──
|
|
44
39
|
const MIME_EXT = {
|
|
45
40
|
'image/png': '.png',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseModelId, stripContextWindowSuffix } from '../core/model/context-window-suffix.js';
|
|
1
2
|
export const BASEAGENT_RUNNER_UNAVAILABLE = 'BASEAGENT_RUNNER_UNAVAILABLE';
|
|
2
3
|
export class BaseagentRunnerUnavailableError extends Error {
|
|
3
4
|
evolagentName;
|
|
@@ -69,20 +70,22 @@ const CLAUDE_CONTEXT_MODEL_ALIASES = ['opus', 'sonnet', 'haiku'];
|
|
|
69
70
|
export function isClaudeContextUsageModel(model) {
|
|
70
71
|
if (!model)
|
|
71
72
|
return false;
|
|
72
|
-
const baseModel = model
|
|
73
|
+
const baseModel = stripContextWindowSuffix(model);
|
|
73
74
|
return /^claude-/i.test(baseModel) || CLAUDE_CONTEXT_MODEL_ALIASES.includes(baseModel);
|
|
74
75
|
}
|
|
75
76
|
export function isOneMillionContextModel(model) {
|
|
76
77
|
if (!model)
|
|
77
78
|
return false;
|
|
79
|
+
// 显式后缀是网关给出的权威窗口,优先于本地前缀表:`claude-opus-5[200k]`
|
|
80
|
+
// 即使基础 ID 在 1M 名单里,也必须按 200k 处理。
|
|
81
|
+
const { base, contextWindow } = parseModelId(model);
|
|
82
|
+
if (contextWindow !== undefined)
|
|
83
|
+
return contextWindow >= 1_000_000;
|
|
78
84
|
if (ONE_M_CONTEXT_MODEL_ALIASES.includes(model))
|
|
79
85
|
return true;
|
|
80
|
-
if (
|
|
86
|
+
if (/deepseek-v4/i.test(base))
|
|
81
87
|
return true;
|
|
82
|
-
|
|
83
|
-
return true;
|
|
84
|
-
const baseModel = model.replace(/\[1m\]$/i, '');
|
|
85
|
-
return ONE_M_CONTEXT_MODEL_PREFIXES.some(prefix => baseModel === prefix || baseModel.startsWith(`${prefix}-`));
|
|
88
|
+
return ONE_M_CONTEXT_MODEL_PREFIXES.some(prefix => base === prefix || base.startsWith(`${prefix}-`));
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
88
91
|
* EvolCore's conservative local context-window catalog: 1M models = 1,000,000;
|
|
@@ -94,17 +97,22 @@ export function realContextWindowForModel(model) {
|
|
|
94
97
|
return isOneMillionContextModel(model) ? 1000000 : 200000;
|
|
95
98
|
}
|
|
96
99
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
+
* EvolCore auto-compact threshold: fixed at 650k tokens regardless of model
|
|
101
|
+
* context window. Large-window models (1M) compress at 650k; small-window
|
|
102
|
+
* models (200k/128k) never reach this threshold and rely on the SDK's own
|
|
103
|
+
* built-in compaction instead.
|
|
100
104
|
*/
|
|
101
|
-
export function
|
|
102
|
-
|
|
103
|
-
return undefined;
|
|
104
|
-
const reserve = Math.min(10_000, Math.floor(contextWindow * 0.05));
|
|
105
|
-
return Math.min(350_000, Math.max(1, contextWindow - reserve));
|
|
105
|
+
export function autoCompactWindowForModel(_model) {
|
|
106
|
+
return 650_000;
|
|
106
107
|
}
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Threshold passed to the Claude Code SDK's autoCompactWindow option.
|
|
110
|
+
* Kept window-aware so the SDK's own built-in compaction continues to fire
|
|
111
|
+
* at the right point for small-context models (200k/128k), where EvolCore's
|
|
112
|
+
* fixed 650k threshold would never trigger.
|
|
113
|
+
*/
|
|
114
|
+
export function sdkAutoCompactWindowForModel(model) {
|
|
115
|
+
const contextWindow = realContextWindowForModel(model);
|
|
116
|
+
const reserve = Math.min(10_000, Math.floor(contextWindow * 0.05));
|
|
117
|
+
return Math.min(650_000, Math.max(1, contextWindow - reserve));
|
|
110
118
|
}
|
package/dist/aun/aid/agentmd.js
CHANGED
|
@@ -4,10 +4,47 @@ import { parseDocument } from 'yaml';
|
|
|
4
4
|
import { getAidStore, loadAid, SLOT } from './store.js';
|
|
5
5
|
import { agentMdPath, aidLocalDir, resolveRoot } from '../../paths.js';
|
|
6
6
|
export const DEFAULT_AGENT_DESCRIPTION = 'EvolCore AI agent.';
|
|
7
|
+
/**
|
|
8
|
+
* AUN 主体类型白名单。没有 `ai` / `codeagent` 这类取值:使用大模型的服务程序
|
|
9
|
+
* 一律归为 `agent`。新建 AID 未指定类型时使用 DEFAULT_AGENT_TYPE。
|
|
10
|
+
*/
|
|
11
|
+
export const AGENT_TYPES = ['human', 'agent', 'group', 'service', 'device', 'org'];
|
|
12
|
+
export const DEFAULT_AGENT_TYPE = 'agent';
|
|
13
|
+
/**
|
|
14
|
+
* 归一化主体类型:大小写不敏感,统一收敛为白名单里的小写形式。
|
|
15
|
+
* `--type AGENT` / `Agent` 都接受,最终写进 agent.md 的一律是小写 `agent`。
|
|
16
|
+
* 返回 undefined 表示输入不是可识别的类型(交由 validateAgentType 报错)。
|
|
17
|
+
*/
|
|
18
|
+
export function normalizeAgentType(type) {
|
|
19
|
+
if (typeof type !== 'string')
|
|
20
|
+
return undefined;
|
|
21
|
+
const lowered = type.trim().toLowerCase();
|
|
22
|
+
return AGENT_TYPES.includes(lowered) ? lowered : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Return a human-readable validation error for a type value, or null when valid. */
|
|
25
|
+
export function validateAgentType(type) {
|
|
26
|
+
if (typeof type !== 'string' || !type.trim())
|
|
27
|
+
return 'must be a non-empty string';
|
|
28
|
+
if (!normalizeAgentType(type))
|
|
29
|
+
return `must be one of ${AGENT_TYPES.join(', ')}`;
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* agent.md 的尺寸与字段上限,取值必须与 fastaun 的 agent-md-schema 保持一致,
|
|
34
|
+
* 否则本地校验通过、上传时才被 SDK 拒绝(失败点后移且提示不同)。
|
|
35
|
+
* 参考 @agentunion/fastaun dist/agent-md-schema.js。
|
|
36
|
+
*/
|
|
37
|
+
export const AGENT_MD_MAX_PAYLOAD_BYTES = 4096;
|
|
38
|
+
export const AGENT_DESCRIPTION_MAX_LENGTH = 100;
|
|
39
|
+
export const AGENT_AVATAR_MAX_LENGTH = 256;
|
|
40
|
+
/** 按 Unicode 码点计数——与 SDK 的 Array.from(value).length 对齐(代理对算一个字符)。 */
|
|
41
|
+
function codePointLength(value) {
|
|
42
|
+
return Array.from(value).length;
|
|
43
|
+
}
|
|
7
44
|
export const AGENT_TAG_MIN_COUNT = 3;
|
|
8
45
|
export const AGENT_TAG_MAX_COUNT = 6;
|
|
9
46
|
export const AGENT_TAG_MAX_LENGTH = 50;
|
|
10
|
-
const AGENT_TAG_PATTERN = /^[\p{L}\p{N}]+$/u;
|
|
47
|
+
const AGENT_TAG_PATTERN = /^[\p{L}\p{N}-]+$/u;
|
|
11
48
|
/** Return a human-readable validation error for one tag, or null when valid. */
|
|
12
49
|
export function validateAgentTag(tag) {
|
|
13
50
|
if (typeof tag !== 'string' || !tag.trim())
|
|
@@ -17,7 +54,7 @@ export function validateAgentTag(tag) {
|
|
|
17
54
|
return `must be at most ${AGENT_TAG_MAX_LENGTH} characters`;
|
|
18
55
|
}
|
|
19
56
|
if (!AGENT_TAG_PATTERN.test(normalized)) {
|
|
20
|
-
return 'must contain only Unicode letters and
|
|
57
|
+
return 'must contain only Unicode letters, numbers, and hyphens';
|
|
21
58
|
}
|
|
22
59
|
return null;
|
|
23
60
|
}
|
|
@@ -130,7 +167,13 @@ export function invalidateAgentDisplayName(aid) {
|
|
|
130
167
|
}
|
|
131
168
|
export function buildInitialAgentMd(opts) {
|
|
132
169
|
const agentName = opts.name?.trim() || opts.aid.split('.')[0];
|
|
133
|
-
|
|
170
|
+
// 未指定类型时用 DEFAULT_AGENT_TYPE(agent);指定了就必须落在 AGENT_TYPES 白名单内。
|
|
171
|
+
// 大小写不敏感,写进 agent.md 的一律是归一化后的小写形式。
|
|
172
|
+
const requestedType = opts.type?.trim() || DEFAULT_AGENT_TYPE;
|
|
173
|
+
const typeError = validateAgentType(requestedType);
|
|
174
|
+
if (typeError)
|
|
175
|
+
throw new Error(`Invalid agent.md type: ${typeError}`);
|
|
176
|
+
const agentType = normalizeAgentType(requestedType) ?? DEFAULT_AGENT_TYPE;
|
|
134
177
|
const description = opts.description?.trim() || DEFAULT_AGENT_DESCRIPTION;
|
|
135
178
|
const rawTags = opts.tags?.length ? opts.tags : ['evolcore'];
|
|
136
179
|
const tagErrors = validateAgentTags(rawTags);
|
|
@@ -155,8 +198,9 @@ function yamlDoubleQuote(value) {
|
|
|
155
198
|
export function validateAgentMdFrontmatter(content, expectedAid) {
|
|
156
199
|
const errors = [];
|
|
157
200
|
const payload = stripAgentMdSignature(content);
|
|
158
|
-
|
|
159
|
-
|
|
201
|
+
const payloadBytes = Buffer.byteLength(payload, 'utf8');
|
|
202
|
+
if (payloadBytes > AGENT_MD_MAX_PAYLOAD_BYTES) {
|
|
203
|
+
errors.push(`agent.md frontmatter and body must not exceed ${AGENT_MD_MAX_PAYLOAD_BYTES} bytes before the signature block (current: ${payloadBytes} bytes)`);
|
|
160
204
|
}
|
|
161
205
|
const frontmatter = payload.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/)?.[1];
|
|
162
206
|
if (!frontmatter)
|
|
@@ -185,15 +229,44 @@ export function validateAgentMdFrontmatter(content, expectedAid) {
|
|
|
185
229
|
requiredString('name');
|
|
186
230
|
requiredString('type');
|
|
187
231
|
const version = requiredString('version');
|
|
188
|
-
|
|
232
|
+
// description 是可选字段(fastaun ≥0.5.13 起不再要求非空):缺失或空串都合法,
|
|
233
|
+
// 仅在实际提供时校验类型与长度,与 SDK 的 agent-md-schema 保持一致。
|
|
234
|
+
const rawDescription = values.description;
|
|
235
|
+
let description;
|
|
236
|
+
if (rawDescription !== undefined && rawDescription !== null) {
|
|
237
|
+
if (typeof rawDescription !== 'string') {
|
|
238
|
+
errors.push('agent.md frontmatter description must be a string');
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
description = rawDescription.trim();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
189
244
|
if (expectedAid && aid && aid !== expectedAid) {
|
|
190
245
|
errors.push(`agent.md frontmatter aid must match upload target ${expectedAid}`);
|
|
191
246
|
}
|
|
192
247
|
if (version && !/^\d+\.\d+\.\d+$/.test(version)) {
|
|
193
248
|
errors.push('agent.md frontmatter version must use major.minor.patch format');
|
|
194
249
|
}
|
|
195
|
-
|
|
196
|
-
|
|
250
|
+
// 长度按 Unicode 码点计、且对未 trim 的原值计数——与 SDK 完全一致,
|
|
251
|
+
// 否则含 emoji 或尾随空格的名片会本地放行、上传才被拒。
|
|
252
|
+
if (typeof rawDescription === 'string') {
|
|
253
|
+
const length = codePointLength(rawDescription);
|
|
254
|
+
if (length > AGENT_DESCRIPTION_MAX_LENGTH) {
|
|
255
|
+
errors.push(`agent.md frontmatter description must be at most ${AGENT_DESCRIPTION_MAX_LENGTH} characters (current: ${length})`);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// avatar:SDK 有 256 字符上限,本地此前完全没校验。
|
|
259
|
+
const rawAvatar = values.avatar;
|
|
260
|
+
if (rawAvatar !== undefined && rawAvatar !== null) {
|
|
261
|
+
if (typeof rawAvatar !== 'string') {
|
|
262
|
+
errors.push('agent.md frontmatter avatar must be a string');
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
const length = codePointLength(rawAvatar);
|
|
266
|
+
if (length > AGENT_AVATAR_MAX_LENGTH) {
|
|
267
|
+
errors.push(`agent.md frontmatter avatar must be at most ${AGENT_AVATAR_MAX_LENGTH} characters (current: ${length})`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
197
270
|
}
|
|
198
271
|
if (values.tags !== undefined) {
|
|
199
272
|
const tagErrors = validateAgentTags(values.tags);
|
package/dist/aun/aid/client.js
CHANGED
|
@@ -39,7 +39,7 @@ export function suppressSdkLogs() {
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
// ==================== SDK package ====================
|
|
42
|
-
export const MIN_AUN_CORE_SDK = [0, 5,
|
|
42
|
+
export const MIN_AUN_CORE_SDK = [0, 5, 16];
|
|
43
43
|
export const AUN_CORE_SDK_PKG = '@agentunion/fastaun';
|
|
44
44
|
function compareVersion(a, min) {
|
|
45
45
|
const parts = a.split('.').map(n => parseInt(n, 10));
|
package/dist/aun/aid/identity.js
CHANGED
|
@@ -114,7 +114,7 @@ export async function verifySignAbility(aid, opts) {
|
|
|
114
114
|
// signAgentMd validates the same frontmatter contract as a published agent.md.
|
|
115
115
|
// Keep the probe minimal, but make it a valid document so self-checks do not
|
|
116
116
|
// reject otherwise healthy identities before exercising sign + verify.
|
|
117
|
-
const probe = `---\naid: "${aid}"\nname: "probe"\ntype: "
|
|
117
|
+
const probe = `---\naid: "${aid}"\nname: "probe"\ntype: "agent"\nversion: "1.0.0"\ndescription: "Local signing self-check"\ntags:\n - evolcore\n---\n`;
|
|
118
118
|
const signRes = aidObj.signAgentMd(probe);
|
|
119
119
|
if (!signRes.ok) {
|
|
120
120
|
return { ok: false, reason: `sign failed: ${String(signRes.error?.message || signRes.error?.code).slice(0, 120)}` };
|
package/dist/aun/aid/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { AGENT_TAG_MIN_COUNT, AGENT_TAG_MAX_COUNT, AGENT_TAG_MAX_LENGTH, validateAgentTag, validateAgentTags, } from './agentmd.js';
|
|
2
2
|
export { isValidAid, aidList, aidListVerified, aidCreate, aidShow, aidDelete, aidLookup, verifySignAbility, probePkiRecoverability, appendAidLifecycle, readAidLifecycle } from './identity.js';
|
|
3
|
-
export { DEFAULT_AGENT_DESCRIPTION, buildInitialAgentMd, validateAgentMdFrontmatter, agentmdGet, agentmdPut, agentmdSync, invalidateAgentDisplayName, parseAgentDisplayName, refreshAgentDisplayName, resolveAgentDisplayName, stripAgentMdSignature, updateAgentMdFrontmatterAvatar, updateAgentMdFrontmatterName, } from './agentmd.js';
|
|
3
|
+
export { AGENT_TYPES, DEFAULT_AGENT_DESCRIPTION, DEFAULT_AGENT_TYPE, normalizeAgentType, validateAgentType, buildInitialAgentMd, validateAgentMdFrontmatter, agentmdGet, agentmdPut, agentmdSync, invalidateAgentDisplayName, parseAgentDisplayName, refreshAgentDisplayName, resolveAgentDisplayName, stripAgentMdSignature, updateAgentMdFrontmatterAvatar, updateAgentMdFrontmatterName, } from './agentmd.js';
|
|
4
4
|
export { MIN_AUN_CORE_SDK, AUN_CORE_SDK_PKG, isAunSdkVersionOk, resolveAunCoreSdkPkg, ensureAunSdk, isAunSdkReady, downloadCaRoot, suppressSdkLogs, } from './client.js';
|
|
5
5
|
export { getAidStore, loadClient, loadAid, AidLoadError, SLOT } from './store.js';
|
package/dist/aun/aid/store.js
CHANGED
|
@@ -80,10 +80,10 @@ export async function loadClient(store, aid) {
|
|
|
80
80
|
/**
|
|
81
81
|
* Enable bounded multi-page group pulls for the long-lived daemon client.
|
|
82
82
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
83
|
+
* Older SDK recovery paths used `maxPages=1`; for a daemon that can strand a
|
|
84
|
+
* backlog after a tail sync. SDK 0.5.15 normally chooses a larger recovery
|
|
85
|
+
* window, but this adapter still expands an explicit single-page request and
|
|
86
|
+
* keeps older clients safe. It is isolated to the client that opts in.
|
|
87
87
|
*/
|
|
88
88
|
export function enableFullGroupPullPagination(client) {
|
|
89
89
|
const target = client;
|
|
@@ -110,13 +110,12 @@ export function enableFullGroupPullPagination(client) {
|
|
|
110
110
|
/**
|
|
111
111
|
* Make SDK pull delivery wait until EvolCore's application handlers finish.
|
|
112
112
|
*
|
|
113
|
-
* fastaun
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* message events before the pull operation commits the sequence.
|
|
113
|
+
* fastaun publishes message events asynchronously, while the sequence tracker
|
|
114
|
+
* is a transport watermark. A daemon restart can therefore acknowledge a
|
|
115
|
+
* pulled message before the application has durably claimed it. SDK 0.5.15
|
|
116
|
+
* split protocol and application queues; prefer its application-only flush so
|
|
117
|
+
* an unrelated protocol event cannot delay the pull commit. Older SDKs fall
|
|
118
|
+
* back to the combined flush method.
|
|
120
119
|
*/
|
|
121
120
|
export function enableReliableMessageDelivery(client) {
|
|
122
121
|
const target = client;
|
|
@@ -124,7 +123,12 @@ export function enableReliableMessageDelivery(client) {
|
|
|
124
123
|
return false;
|
|
125
124
|
const publish = target._publishAppEvent;
|
|
126
125
|
const dispatcher = target._dispatcher;
|
|
127
|
-
|
|
126
|
+
const flushApplication = typeof dispatcher?.flushApplication === 'function'
|
|
127
|
+
? dispatcher.flushApplication.bind(dispatcher)
|
|
128
|
+
: typeof dispatcher?.flush === 'function'
|
|
129
|
+
? dispatcher.flush.bind(dispatcher)
|
|
130
|
+
: undefined;
|
|
131
|
+
if (typeof publish !== 'function' || !flushApplication)
|
|
128
132
|
return false;
|
|
129
133
|
const wrappedPublish = async function (event, payload, source, ...rest) {
|
|
130
134
|
const result = await publish.call(this, event, payload, source, ...rest);
|
|
@@ -135,7 +139,7 @@ export function enableReliableMessageDelivery(client) {
|
|
|
135
139
|
&& source !== 'push'
|
|
136
140
|
&& source !== 'inline-push';
|
|
137
141
|
if (reliable)
|
|
138
|
-
await
|
|
142
|
+
await flushApplication();
|
|
139
143
|
return result;
|
|
140
144
|
};
|
|
141
145
|
Object.defineProperty(target, RELIABLE_MESSAGE_DELIVERY_PATCH, {
|