evolcore 0.0.5 → 0.0.7
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 +49 -0
- package/README.md +4 -12
- package/dist/agents/baseagent.js +39 -0
- package/dist/agents/claude-runner.js +10 -2
- package/dist/agents/codex-runner.js +37 -8
- package/dist/agents/ecagent-runner.js +1159 -0
- package/dist/agents/gemini-runner.js +4 -1
- package/dist/agents/runner-types.js +20 -4
- package/dist/aun/msg/history.js +32 -9
- package/dist/aun/outbox.js +4 -9
- package/dist/channels/aun.js +32 -6
- package/dist/channels/daemon.js +7 -4
- package/dist/channels/dingtalk.js +3 -5
- package/dist/channels/feishu.js +16 -108
- package/dist/channels/wechat.js +4 -4
- package/dist/channels/wecom.js +4 -6
- package/dist/cli/agent-command.js +1 -1
- package/dist/cli/agent.js +42 -11
- package/dist/cli/aun-commands.js +50 -3
- package/dist/cli/daemon-commands.js +88 -8
- package/dist/cli/data-command.js +132 -0
- package/dist/cli/index.js +11 -3
- package/dist/cli/init.js +76 -17
- package/dist/cli/net-check.js +9 -20
- package/dist/cli/restart-monitor.js +25 -2
- package/dist/cli/trigger-command.js +1 -1
- package/dist/cli/watch-msg.js +12 -25
- package/dist/config/builtin-roles.js +3 -1
- package/dist/config/config-field-policy.js +1 -1
- package/dist/config/gateway-config.js +21 -4
- package/dist/config/resolved-config-op.js +10 -0
- package/dist/core/command/command-handler.js +2 -2
- package/dist/core/command/menu-handler.js +11 -9
- package/dist/core/command/role-menu.js +11 -0
- package/dist/core/command/slash-handler.js +18 -14
- package/dist/core/data-migration.js +1434 -0
- package/dist/core/handoff/store.js +14 -4
- package/dist/core/inference/text-inference.js +42 -1
- package/dist/core/message/pending-hints.js +1 -1
- package/dist/core/message/response-engine.js +406 -167
- package/dist/core/message/retry-scheduler.js +71 -0
- package/dist/core/model/model-catalog.js +7 -2
- package/dist/core/model/model-fallback.js +81 -0
- package/dist/core/protected-paths.js +41 -8
- package/dist/core/session/adapters/ecagent-session-file-adapter.js +112 -0
- package/dist/core/session/session-fs-store.js +283 -59
- package/dist/core/session/session-manager.js +19 -21
- package/dist/core/session/session-title.js +1 -0
- package/dist/core/session/session-turn-coordinator.js +8 -1
- package/dist/core/system-channels.js +1 -0
- package/dist/index.js +13 -10
- package/dist/paths.js +35 -27
- package/dist/trigger/feedback.js +16 -0
- package/dist/trigger/legacy-session-history.js +19 -0
- package/dist/trigger/manager.js +12 -1
- package/dist/trigger/parser.js +4 -2
- package/dist/trigger/scheduler.js +185 -15
- package/dist/trigger/session-lock.js +62 -0
- package/dist/trigger/state.js +64 -0
- package/dist/trigger/validation.js +32 -2
- package/dist/utils/aid-bind.js +1 -1
- package/dist/utils/error-utils.js +9 -0
- package/dist/utils/instance-registry.js +2 -2
- package/dist/utils/welcome.js +2 -3
- package/ecagent/LICENSE +21 -0
- package/ecagent/NOTICE +11 -0
- package/ecagent/README.md +61 -0
- package/ecagent/dist/agent-loop.d.ts +24 -0
- package/ecagent/dist/agent-loop.d.ts.map +1 -0
- package/ecagent/dist/agent-loop.js +547 -0
- package/ecagent/dist/agent-loop.js.map +1 -0
- package/ecagent/dist/agent.d.ts +127 -0
- package/ecagent/dist/agent.d.ts.map +1 -0
- package/ecagent/dist/agent.js +386 -0
- package/ecagent/dist/agent.js.map +1 -0
- package/ecagent/dist/harness/agent-harness.d.ts +95 -0
- package/ecagent/dist/harness/agent-harness.d.ts.map +1 -0
- package/ecagent/dist/harness/agent-harness.js +926 -0
- package/ecagent/dist/harness/agent-harness.js.map +1 -0
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts +51 -0
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +1 -0
- package/ecagent/dist/harness/compaction/branch-summarization.js +174 -0
- package/ecagent/dist/harness/compaction/branch-summarization.js.map +1 -0
- package/ecagent/dist/harness/compaction/compaction.d.ts +95 -0
- package/ecagent/dist/harness/compaction/compaction.d.ts.map +1 -0
- package/ecagent/dist/harness/compaction/compaction.js +528 -0
- package/ecagent/dist/harness/compaction/compaction.js.map +1 -0
- package/ecagent/dist/harness/compaction/utils.d.ts +25 -0
- package/ecagent/dist/harness/compaction/utils.d.ts.map +1 -0
- package/ecagent/dist/harness/compaction/utils.js +131 -0
- package/ecagent/dist/harness/compaction/utils.js.map +1 -0
- package/ecagent/dist/harness/env/nodejs.d.ts +51 -0
- package/ecagent/dist/harness/env/nodejs.d.ts.map +1 -0
- package/ecagent/dist/harness/env/nodejs.js +513 -0
- package/ecagent/dist/harness/env/nodejs.js.map +1 -0
- package/ecagent/dist/harness/messages.d.ts +51 -0
- package/ecagent/dist/harness/messages.d.ts.map +1 -0
- package/ecagent/dist/harness/messages.js +102 -0
- package/ecagent/dist/harness/messages.js.map +1 -0
- package/ecagent/dist/harness/prompt-templates.d.ts +48 -0
- package/ecagent/dist/harness/prompt-templates.d.ts.map +1 -0
- package/ecagent/dist/harness/prompt-templates.js +230 -0
- package/ecagent/dist/harness/prompt-templates.js.map +1 -0
- package/ecagent/dist/harness/session/jsonl-repo.d.ts +26 -0
- package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +1 -0
- package/ecagent/dist/harness/session/jsonl-repo.js +100 -0
- package/ecagent/dist/harness/session/jsonl-repo.js.map +1 -0
- package/ecagent/dist/harness/session/jsonl-storage.d.ts +34 -0
- package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +1 -0
- package/ecagent/dist/harness/session/jsonl-storage.js +234 -0
- package/ecagent/dist/harness/session/jsonl-storage.js.map +1 -0
- package/ecagent/dist/harness/session/memory-repo.d.ts +18 -0
- package/ecagent/dist/harness/session/memory-repo.d.ts.map +1 -0
- package/ecagent/dist/harness/session/memory-repo.js +44 -0
- package/ecagent/dist/harness/session/memory-repo.js.map +1 -0
- package/ecagent/dist/harness/session/memory-storage.d.ts +25 -0
- package/ecagent/dist/harness/session/memory-storage.d.ts.map +1 -0
- package/ecagent/dist/harness/session/memory-storage.js +111 -0
- package/ecagent/dist/harness/session/memory-storage.js.map +1 -0
- package/ecagent/dist/harness/session/repo-utils.d.ts +11 -0
- package/ecagent/dist/harness/session/repo-utils.d.ts.map +1 -0
- package/ecagent/dist/harness/session/repo-utils.js +39 -0
- package/ecagent/dist/harness/session/repo-utils.js.map +1 -0
- package/ecagent/dist/harness/session/session.d.ts +47 -0
- package/ecagent/dist/harness/session/session.d.ts.map +1 -0
- package/ecagent/dist/harness/session/session.js +245 -0
- package/ecagent/dist/harness/session/session.js.map +1 -0
- package/ecagent/dist/harness/session/uuid.d.ts +2 -0
- package/ecagent/dist/harness/session/uuid.d.ts.map +1 -0
- package/ecagent/dist/harness/session/uuid.js +50 -0
- package/ecagent/dist/harness/session/uuid.js.map +1 -0
- package/ecagent/dist/harness/skills.d.ts +44 -0
- package/ecagent/dist/harness/skills.d.ts.map +1 -0
- package/ecagent/dist/harness/skills.js +311 -0
- package/ecagent/dist/harness/skills.js.map +1 -0
- package/ecagent/dist/harness/system-prompt.d.ts +3 -0
- package/ecagent/dist/harness/system-prompt.d.ts.map +1 -0
- package/ecagent/dist/harness/system-prompt.js +30 -0
- package/ecagent/dist/harness/system-prompt.js.map +1 -0
- package/ecagent/dist/harness/types.d.ts +619 -0
- package/ecagent/dist/harness/types.d.ts.map +1 -0
- package/ecagent/dist/harness/types.js +81 -0
- package/ecagent/dist/harness/types.js.map +1 -0
- package/ecagent/dist/harness/utils/shell-output.d.ts +14 -0
- package/ecagent/dist/harness/utils/shell-output.d.ts.map +1 -0
- package/ecagent/dist/harness/utils/shell-output.js +126 -0
- package/ecagent/dist/harness/utils/shell-output.js.map +1 -0
- package/ecagent/dist/harness/utils/truncate.d.ts +70 -0
- package/ecagent/dist/harness/utils/truncate.d.ts.map +1 -0
- package/ecagent/dist/harness/utils/truncate.js +290 -0
- package/ecagent/dist/harness/utils/truncate.js.map +1 -0
- package/ecagent/dist/index.d.ts +22 -0
- package/ecagent/dist/index.d.ts.map +1 -0
- package/ecagent/dist/index.js +27 -0
- package/ecagent/dist/index.js.map +1 -0
- package/ecagent/dist/node.d.ts +3 -0
- package/ecagent/dist/node.d.ts.map +1 -0
- package/ecagent/dist/node.js +3 -0
- package/ecagent/dist/node.js.map +1 -0
- package/ecagent/dist/proxy.d.ts +69 -0
- package/ecagent/dist/proxy.d.ts.map +1 -0
- package/ecagent/dist/proxy.js +278 -0
- package/ecagent/dist/proxy.js.map +1 -0
- package/ecagent/dist/runtime/api/lazy.d.ts +15 -0
- package/ecagent/dist/runtime/api/lazy.d.ts.map +1 -0
- package/ecagent/dist/runtime/api/lazy.js +59 -0
- package/ecagent/dist/runtime/api/lazy.js.map +1 -0
- package/ecagent/dist/runtime/api/pi-messages.d.ts +97 -0
- package/ecagent/dist/runtime/api/pi-messages.d.ts.map +1 -0
- package/ecagent/dist/runtime/api/pi-messages.js +307 -0
- package/ecagent/dist/runtime/api/pi-messages.js.map +1 -0
- package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts +3 -0
- package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +1 -0
- package/ecagent/dist/runtime/api/pi-messages.lazy.js +3 -0
- package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +1 -0
- package/ecagent/dist/runtime/auth/context.d.ts +7 -0
- package/ecagent/dist/runtime/auth/context.d.ts.map +1 -0
- package/ecagent/dist/runtime/auth/context.js +42 -0
- package/ecagent/dist/runtime/auth/context.js.map +1 -0
- package/ecagent/dist/runtime/auth/credential-store.d.ts +16 -0
- package/ecagent/dist/runtime/auth/credential-store.d.ts.map +1 -0
- package/ecagent/dist/runtime/auth/credential-store.js +39 -0
- package/ecagent/dist/runtime/auth/credential-store.js.map +1 -0
- package/ecagent/dist/runtime/auth/helpers.d.ts +20 -0
- package/ecagent/dist/runtime/auth/helpers.d.ts.map +1 -0
- package/ecagent/dist/runtime/auth/helpers.js +46 -0
- package/ecagent/dist/runtime/auth/helpers.js.map +1 -0
- package/ecagent/dist/runtime/auth/resolve.d.ts +26 -0
- package/ecagent/dist/runtime/auth/resolve.d.ts.map +1 -0
- package/ecagent/dist/runtime/auth/resolve.js +100 -0
- package/ecagent/dist/runtime/auth/resolve.js.map +1 -0
- package/ecagent/dist/runtime/auth/types.d.ts +180 -0
- package/ecagent/dist/runtime/auth/types.d.ts.map +1 -0
- package/ecagent/dist/runtime/auth/types.js +2 -0
- package/ecagent/dist/runtime/auth/types.js.map +1 -0
- package/ecagent/dist/runtime/compat.d.ts +28 -0
- package/ecagent/dist/runtime/compat.d.ts.map +1 -0
- package/ecagent/dist/runtime/compat.js +86 -0
- package/ecagent/dist/runtime/compat.js.map +1 -0
- package/ecagent/dist/runtime/index.d.ts +20 -0
- package/ecagent/dist/runtime/index.d.ts.map +1 -0
- package/ecagent/dist/runtime/index.js +17 -0
- package/ecagent/dist/runtime/index.js.map +1 -0
- package/ecagent/dist/runtime/models.d.ts +142 -0
- package/ecagent/dist/runtime/models.d.ts.map +1 -0
- package/ecagent/dist/runtime/models.js +245 -0
- package/ecagent/dist/runtime/models.js.map +1 -0
- package/ecagent/dist/runtime/oauth.d.ts +2 -0
- package/ecagent/dist/runtime/oauth.d.ts.map +1 -0
- package/ecagent/dist/runtime/oauth.js +2 -0
- package/ecagent/dist/runtime/oauth.js.map +1 -0
- package/ecagent/dist/runtime/providers/faux.d.ts +97 -0
- package/ecagent/dist/runtime/providers/faux.d.ts.map +1 -0
- package/ecagent/dist/runtime/providers/faux.js +395 -0
- package/ecagent/dist/runtime/providers/faux.js.map +1 -0
- package/ecagent/dist/runtime/types.d.ts +607 -0
- package/ecagent/dist/runtime/types.d.ts.map +1 -0
- package/ecagent/dist/runtime/types.js +2 -0
- package/ecagent/dist/runtime/types.js.map +1 -0
- package/ecagent/dist/runtime/utils/diagnostics.d.ts +19 -0
- package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/diagnostics.js +25 -0
- package/ecagent/dist/runtime/utils/diagnostics.js.map +1 -0
- package/ecagent/dist/runtime/utils/event-stream.d.ts +21 -0
- package/ecagent/dist/runtime/utils/event-stream.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/event-stream.js +77 -0
- package/ecagent/dist/runtime/utils/event-stream.js.map +1 -0
- package/ecagent/dist/runtime/utils/headers.d.ts +4 -0
- package/ecagent/dist/runtime/utils/headers.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/headers.js +18 -0
- package/ecagent/dist/runtime/utils/headers.js.map +1 -0
- package/ecagent/dist/runtime/utils/json-parse.d.ts +16 -0
- package/ecagent/dist/runtime/utils/json-parse.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/json-parse.js +113 -0
- package/ecagent/dist/runtime/utils/json-parse.js.map +1 -0
- package/ecagent/dist/runtime/utils/oauth/types.d.ts +64 -0
- package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/oauth/types.js +2 -0
- package/ecagent/dist/runtime/utils/oauth/types.js.map +1 -0
- package/ecagent/dist/runtime/utils/overflow.d.ts +58 -0
- package/ecagent/dist/runtime/utils/overflow.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/overflow.js +158 -0
- package/ecagent/dist/runtime/utils/overflow.js.map +1 -0
- package/ecagent/dist/runtime/utils/provider-env.d.ts +7 -0
- package/ecagent/dist/runtime/utils/provider-env.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/provider-env.js +44 -0
- package/ecagent/dist/runtime/utils/provider-env.js.map +1 -0
- package/ecagent/dist/runtime/utils/retry.d.ts +12 -0
- package/ecagent/dist/runtime/utils/retry.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/retry.js +90 -0
- package/ecagent/dist/runtime/utils/retry.js.map +1 -0
- package/ecagent/dist/runtime/utils/typebox-helpers.d.ts +17 -0
- package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/typebox-helpers.js +21 -0
- package/ecagent/dist/runtime/utils/typebox-helpers.js.map +1 -0
- package/ecagent/dist/runtime/utils/validation.d.ts +18 -0
- package/ecagent/dist/runtime/utils/validation.d.ts.map +1 -0
- package/ecagent/dist/runtime/utils/validation.js +269 -0
- package/ecagent/dist/runtime/utils/validation.js.map +1 -0
- package/ecagent/dist/types.d.ts +401 -0
- package/ecagent/dist/types.d.ts.map +1 -0
- package/ecagent/dist/types.js +2 -0
- package/ecagent/dist/types.js.map +1 -0
- package/ecagent/package.json +93 -0
- package/ecagent/src/agent-loop.ts +792 -0
- package/ecagent/src/agent.ts +575 -0
- package/ecagent/src/harness/agent-harness.ts +1029 -0
- package/ecagent/src/harness/compaction/branch-summarization.ts +261 -0
- package/ecagent/src/harness/compaction/compaction.ts +753 -0
- package/ecagent/src/harness/compaction/utils.ts +144 -0
- package/ecagent/src/harness/env/nodejs.ts +569 -0
- package/ecagent/src/harness/messages.ts +164 -0
- package/ecagent/src/harness/prompt-templates.ts +267 -0
- package/ecagent/src/harness/session/jsonl-repo.ts +179 -0
- package/ecagent/src/harness/session/jsonl-storage.ts +314 -0
- package/ecagent/src/harness/session/memory-repo.ts +50 -0
- package/ecagent/src/harness/session/memory-storage.ts +133 -0
- package/ecagent/src/harness/session/repo-utils.ts +51 -0
- package/ecagent/src/harness/session/session.ts +338 -0
- package/ecagent/src/harness/session/uuid.ts +54 -0
- package/ecagent/src/harness/skills.ts +375 -0
- package/ecagent/src/harness/system-prompt.ts +34 -0
- package/ecagent/src/harness/types.ts +838 -0
- package/ecagent/src/harness/utils/shell-output.ts +135 -0
- package/ecagent/src/harness/utils/truncate.ts +344 -0
- package/ecagent/src/index.ts +46 -0
- package/ecagent/src/node.ts +2 -0
- package/ecagent/src/proxy.ts +367 -0
- package/ecagent/src/runtime/api/lazy.ts +70 -0
- package/ecagent/src/runtime/api/pi-messages.lazy.ts +4 -0
- package/ecagent/src/runtime/api/pi-messages.ts +436 -0
- package/ecagent/src/runtime/auth/context.ts +45 -0
- package/ecagent/src/runtime/auth/credential-store.ts +47 -0
- package/ecagent/src/runtime/auth/helpers.ts +46 -0
- package/ecagent/src/runtime/auth/resolve.ts +141 -0
- package/ecagent/src/runtime/auth/types.ts +182 -0
- package/ecagent/src/runtime/compat.ts +158 -0
- package/ecagent/src/runtime/index.ts +31 -0
- package/ecagent/src/runtime/models.ts +452 -0
- package/ecagent/src/runtime/oauth.ts +1 -0
- package/ecagent/src/runtime/providers/faux.ts +538 -0
- package/ecagent/src/runtime/types.ts +718 -0
- package/ecagent/src/runtime/utils/diagnostics.ts +45 -0
- package/ecagent/src/runtime/utils/event-stream.ts +88 -0
- package/ecagent/src/runtime/utils/headers.ts +18 -0
- package/ecagent/src/runtime/utils/json-parse.ts +124 -0
- package/ecagent/src/runtime/utils/oauth/types.ts +79 -0
- package/ecagent/src/runtime/utils/overflow.ts +165 -0
- package/ecagent/src/runtime/utils/provider-env.ts +52 -0
- package/ecagent/src/runtime/utils/retry.ts +101 -0
- package/ecagent/src/runtime/utils/typebox-helpers.ts +24 -0
- package/ecagent/src/runtime/utils/validation.ts +310 -0
- package/ecagent/src/types.ts +430 -0
- package/ecagent/tsconfig.build.json +32 -0
- package/kits/schemas/_meta.json +7 -4
- package/kits/schemas/agent-config.schema.10.json +370 -0
- package/kits/schemas/defaults.schema.4.json +93 -0
- package/kits/schemas/relation-config.schema.8.json +69 -0
- package/kits/templates/roles/admin.json +1 -1
- package/package.json +22 -6
- package/skills/eclink/SKILL.md +70 -0
- package/skills/eclink/agents/openai.yaml +4 -0
- package/assets/.env.template +0 -4
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task-level retry policy. Transport clients may retry an individual HTTP
|
|
3
|
+
* request, but only this scheduler decides whether the user task is replayed.
|
|
4
|
+
*/
|
|
5
|
+
export const API_RETRY_DELAYS_MS = [5_000, 10_000, 30_000];
|
|
6
|
+
export const MAX_PROTOCOL_REPLAY_ATTEMPTS = 1;
|
|
7
|
+
export class RetryScheduler {
|
|
8
|
+
resolveModelId;
|
|
9
|
+
protocolReplayAttempts = 0;
|
|
10
|
+
apiRetryAttempts = 0;
|
|
11
|
+
modelFallbackAttempts = 0;
|
|
12
|
+
attemptedModels = new Set();
|
|
13
|
+
candidates;
|
|
14
|
+
constructor(candidates, currentModel, resolveModelId = model => model) {
|
|
15
|
+
this.resolveModelId = resolveModelId;
|
|
16
|
+
this.candidates = candidates;
|
|
17
|
+
if (currentModel)
|
|
18
|
+
this.attemptedModels.add(this.key(currentModel));
|
|
19
|
+
}
|
|
20
|
+
get protocolReplays() {
|
|
21
|
+
return this.protocolReplayAttempts;
|
|
22
|
+
}
|
|
23
|
+
get apiRetryAttemptsMade() {
|
|
24
|
+
return this.apiRetryAttempts;
|
|
25
|
+
}
|
|
26
|
+
shouldTimeoutAttempt() {
|
|
27
|
+
return this.apiRetryAttempts > 0;
|
|
28
|
+
}
|
|
29
|
+
markModelAttempted(model) {
|
|
30
|
+
this.attemptedModels.add(this.key(model));
|
|
31
|
+
}
|
|
32
|
+
afterProtocolFailure(reason, safeToReplay) {
|
|
33
|
+
if (!reason || !safeToReplay)
|
|
34
|
+
return { kind: 'none' };
|
|
35
|
+
if (this.protocolReplayAttempts >= MAX_PROTOCOL_REPLAY_ATTEMPTS)
|
|
36
|
+
return { kind: 'exhausted' };
|
|
37
|
+
this.protocolReplayAttempts++;
|
|
38
|
+
return {
|
|
39
|
+
kind: 'protocol_replay',
|
|
40
|
+
attempt: this.protocolReplayAttempts,
|
|
41
|
+
maxAttempts: MAX_PROTOCOL_REPLAY_ATTEMPTS,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
afterModelUnavailable() {
|
|
45
|
+
const candidate = this.candidates.find(item => !this.attemptedModels.has(this.key(item.model)));
|
|
46
|
+
if (!candidate)
|
|
47
|
+
return { kind: 'exhausted' };
|
|
48
|
+
this.attemptedModels.add(this.key(candidate.model));
|
|
49
|
+
this.modelFallbackAttempts++;
|
|
50
|
+
this.apiRetryAttempts = 0;
|
|
51
|
+
return {
|
|
52
|
+
kind: 'model_fallback',
|
|
53
|
+
candidate,
|
|
54
|
+
attempt: this.modelFallbackAttempts,
|
|
55
|
+
candidateCount: this.candidates.length,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
afterTransientFailure(madeProgress) {
|
|
59
|
+
if (madeProgress)
|
|
60
|
+
this.apiRetryAttempts = 0;
|
|
61
|
+
if (this.apiRetryAttempts >= API_RETRY_DELAYS_MS.length)
|
|
62
|
+
return { kind: 'exhausted' };
|
|
63
|
+
const attempt = this.apiRetryAttempts + 1;
|
|
64
|
+
const delayMs = API_RETRY_DELAYS_MS[this.apiRetryAttempts];
|
|
65
|
+
this.apiRetryAttempts++;
|
|
66
|
+
return { kind: 'api_retry', attempt, maxAttempts: API_RETRY_DELAYS_MS.length, delayMs };
|
|
67
|
+
}
|
|
68
|
+
key(model) {
|
|
69
|
+
return this.resolveModelId(model).trim().toLowerCase();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 详见 docs/model-command-design.md。
|
|
11
11
|
*/
|
|
12
|
-
import { resolveAnthropicConfig, resolveOpenaiConfig } from '../../agents/baseagent.js';
|
|
12
|
+
import { resolveAnthropicConfig, resolveEcagentConfig, resolveOpenaiConfig } from '../../agents/baseagent.js';
|
|
13
13
|
import { activeBaseagent } from './config-scope.js';
|
|
14
14
|
import { resolveEffective } from '../../config/config-manager.js';
|
|
15
15
|
/** 取指定 baseagent 的 baseUrl + apiKey(复用现有解析链)。 */
|
|
@@ -24,6 +24,11 @@ function resolveCreds(self, ba) {
|
|
|
24
24
|
const r = resolveOpenaiConfig({ agents: { codex: c } }, c);
|
|
25
25
|
return { baseUrl: r.baseUrl, apiKey: r.apiKey };
|
|
26
26
|
}
|
|
27
|
+
if (baseagent === 'ecagent') {
|
|
28
|
+
const c = block.ecagent;
|
|
29
|
+
const r = resolveEcagentConfig({ agents: { ecagent: c } }, c);
|
|
30
|
+
return { baseUrl: r.baseUrl, apiKey: r.apiKey };
|
|
31
|
+
}
|
|
27
32
|
const c = block.claude;
|
|
28
33
|
const r = resolveAnthropicConfig({ agents: { claude: c } }, c);
|
|
29
34
|
return { baseUrl: r.baseUrl, apiKey: r.apiKey };
|
|
@@ -167,7 +172,7 @@ export async function getCatalog(self, ba) {
|
|
|
167
172
|
const { baseUrl, apiKey } = resolveCreds(self, baseagent);
|
|
168
173
|
if (baseUrl) {
|
|
169
174
|
const base = baseUrl.replace(/\/+$/, '');
|
|
170
|
-
const v1 = await fetchModelList(`${base}/v1/models`, apiKey);
|
|
175
|
+
const v1 = await fetchModelList(base.endsWith('/v1') ? `${base}/models` : `${base}/v1/models`, apiKey);
|
|
171
176
|
if (v1)
|
|
172
177
|
return { models: withAliases(v1, baseagent), source: 'v1/models' };
|
|
173
178
|
const plain = await fetchModelList(`${base}/models`, apiKey);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getCodexEfforts } from '../../agents/codex-runner.js';
|
|
2
|
+
import { ConfigTarget, read } from '../../config/config-manager.js';
|
|
3
|
+
export const MAX_FALLBACK_MODELS = 3;
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function normalizeCandidate(value) {
|
|
8
|
+
if (!isRecord(value) || typeof value.model !== 'string')
|
|
9
|
+
return undefined;
|
|
10
|
+
const model = value.model.trim();
|
|
11
|
+
if (!model)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (value.effort !== undefined && (typeof value.effort !== 'string' || !value.effort.trim()))
|
|
14
|
+
return undefined;
|
|
15
|
+
return {
|
|
16
|
+
model,
|
|
17
|
+
...(typeof value.effort === 'string' ? { effort: value.effort.trim() } : {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Read only defaults.json: fallback policy must not participate in H-chain merging. */
|
|
21
|
+
export function configuredFallbackModels(baseagent) {
|
|
22
|
+
const defaults = read(ConfigTarget.Defaults, undefined, { cache: true });
|
|
23
|
+
const block = isRecord(defaults?.baseagents) ? defaults.baseagents[baseagent] : undefined;
|
|
24
|
+
const raw = isRecord(block) ? block.fallbackModels : undefined;
|
|
25
|
+
if (!Array.isArray(raw))
|
|
26
|
+
return { candidates: [], rejected: [] };
|
|
27
|
+
const candidates = [];
|
|
28
|
+
const rejected = [];
|
|
29
|
+
for (const [index, value] of raw.entries()) {
|
|
30
|
+
const candidate = normalizeCandidate(value);
|
|
31
|
+
if (!candidate) {
|
|
32
|
+
rejected.push({ reason: 'invalid' });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (index >= MAX_FALLBACK_MODELS) {
|
|
36
|
+
rejected.push({ model: candidate.model, reason: 'limit' });
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
candidates.push(candidate);
|
|
40
|
+
}
|
|
41
|
+
return { candidates, rejected };
|
|
42
|
+
}
|
|
43
|
+
function supportsEffort(baseagent, model, effort) {
|
|
44
|
+
if (!effort)
|
|
45
|
+
return true;
|
|
46
|
+
if (baseagent === 'codex')
|
|
47
|
+
return getCodexEfforts(model).includes(effort);
|
|
48
|
+
if (baseagent === 'claude')
|
|
49
|
+
return ['low', 'medium', 'high', 'xhigh', 'max'].includes(effort);
|
|
50
|
+
if (baseagent === 'ecagent')
|
|
51
|
+
return ['minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(effort);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
export function eligibleFallbackModels(input) {
|
|
55
|
+
const configured = configuredFallbackModels(input.baseagent);
|
|
56
|
+
const candidates = [];
|
|
57
|
+
const rejected = [...configured.rejected];
|
|
58
|
+
const key = (model) => (input.resolveModelId?.(model) ?? model).trim().toLowerCase();
|
|
59
|
+
const seen = new Set();
|
|
60
|
+
if (input.currentModel)
|
|
61
|
+
seen.add(key(input.currentModel));
|
|
62
|
+
for (const candidate of configured.candidates) {
|
|
63
|
+
const resolvedModel = input.resolveModelId?.(candidate.model) ?? candidate.model;
|
|
64
|
+
const candidateKey = key(candidate.model);
|
|
65
|
+
if (seen.has(candidateKey)) {
|
|
66
|
+
rejected.push({ model: candidate.model, reason: candidateKey === key(input.currentModel ?? '') ? 'current_model' : 'duplicate' });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (!input.isAllowed(resolvedModel)) {
|
|
70
|
+
rejected.push({ model: candidate.model, reason: 'not_allowed' });
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (!supportsEffort(input.baseagent, resolvedModel, candidate.effort)) {
|
|
74
|
+
rejected.push({ model: candidate.model, reason: 'unsupported_effort' });
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
seen.add(candidateKey);
|
|
78
|
+
candidates.push({ ...candidate, model: resolvedModel });
|
|
79
|
+
}
|
|
80
|
+
return { candidates, rejected };
|
|
81
|
+
}
|
|
@@ -22,24 +22,28 @@ const H_CLASS_RELATIVE_PATTERNS = [
|
|
|
22
22
|
/^\.lock$/,
|
|
23
23
|
/^daemon\.pid$/,
|
|
24
24
|
/^data\/causation-aun\.json(?:_|__)?$/,
|
|
25
|
-
/^data\/
|
|
25
|
+
/^data\/triggers(?:\/|$)/,
|
|
26
|
+
/^data\/(?:sessions(?:\/|$)|contact-book-audit\.jsonl$|feishu-seen-.*\.jsonl$|[a-z0-9_-]+-greeted-.*\.jsonl$|message-queue\.json(?:_|__|\.tmp-.*)?$|daemon\/(?:message-queue\.json(?:_|__|\.tmp-.*)?$|control(?:\/|$)|migrations(?:\/|$))|channel-state(?:\/|$))/,
|
|
26
27
|
/^data\/instance\/control\.token$/,
|
|
27
28
|
/^data\/outbox(?:\/|$)/,
|
|
28
29
|
/^data\/handoff(?:\/|$)/,
|
|
30
|
+
/^agents\/[^/]+\/sessions(?:\/|$)/,
|
|
31
|
+
/^agents\/[^/]+\/data\/(?:channels(?:\/|$)|handoff(?:\/|$)|outbox\.jsonl(?:_|__|\.tmp-.*)?$|contact-audit\.jsonl$)/,
|
|
29
32
|
];
|
|
30
33
|
const H_CLASS_REFERENCE_PATTERNS = [
|
|
31
34
|
/(?:^|[^A-Za-z0-9_.-])daemon\.json(?=$|[^A-Za-z0-9_.-])/,
|
|
32
35
|
/(?:^|[^A-Za-z0-9_.-])agents[\\/](?:defaults\.json|[^/\\\s"']+[\\/](?:(?:config|contact)\.json|contact-operations\.jsonl|relations[\\/][^/\\\s"']+[\\/]config\.json))(?=$|[\s"';&|<>)},])/,
|
|
33
36
|
/(?:^|[^A-Za-z0-9_.-])(?:backups[\\/]config|\.snapshots|CA|(?:AIDs|aids)[\\/][^/\\\s"']+[\\/](?:cert|keys))(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
34
|
-
/(?:^|[/\\\s"'=<>])(?:\.device_id|\.env|\.seed(?:\.[^/\\\s"']*)?|\.migrated-[^/\\\s"']*|\.lock|daemon\.pid|data[\\/](?:causation-aun\.json(?:_|__)?|message-queue\.json(?:_|__|\.tmp-[^/\\\s"']*)?|instance[\\/]control\.token|outbox|handoff))(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
37
|
+
/(?:^|[/\\\s"'=<>])(?:\.device_id|\.env|\.seed(?:\.[^/\\\s"']*)?|\.migrated-[^/\\\s"']*|\.lock|daemon\.pid|data[\\/](?:causation-aun\.json(?:_|__)?|sessions|contact-book-audit\.jsonl|feishu-seen-[^/\\\s"']+\.jsonl|[a-z0-9_-]+-greeted-[^/\\\s"']+\.jsonl|message-queue\.json(?:_|__|\.tmp-[^/\\\s"']*)?|daemon[\\/](?:message-queue\.json(?:_|__|\.tmp-[^/\\\s"']*)?|control|migrations)|channel-state|instance[\\/]control\.token|outbox|handoff)|agents[\\/][^/\\\s"']+[\\/](?:sessions|data[\\/](?:channels|handoff|outbox\.jsonl|contact-audit\.jsonl)))(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
38
|
+
/(?:^|[/\\\s"'=<>])data[\\/]triggers(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
35
39
|
/(?:^|[/\\\s"'=<>])(?:[^/\\\s"']+\.json_|[^/\\\s"']+\.json\.migrated|defaults_\d+\.json)(?=$|[\s"';&|<>)},])/,
|
|
36
40
|
];
|
|
37
41
|
const L_CLASS_RELATIVE_PATTERNS = [
|
|
38
|
-
/^
|
|
42
|
+
/^agents\/[^/]+\/triggers(?:\/|$)/,
|
|
39
43
|
/^agents\/[^/]+\/roles(?:\/|$)/,
|
|
40
44
|
];
|
|
41
45
|
const L_CLASS_REFERENCE_PATTERNS = [
|
|
42
|
-
/(?:^|[
|
|
46
|
+
/(?:^|[^A-Za-z0-9_.-])agents[\\/][^/\\\s"']+[\\/]triggers(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
43
47
|
/(?:^|[^A-Za-z0-9_.-])agents[\\/][^/\\\s"']+[\\/]roles(?:[\\/]|$|[\s"';&|<>)},])/,
|
|
44
48
|
];
|
|
45
49
|
function normalizeForComparison(value) {
|
|
@@ -155,20 +159,34 @@ export function getHClassSandboxPatterns(root = resolveRoot()) {
|
|
|
155
159
|
'.lock',
|
|
156
160
|
'daemon.pid',
|
|
157
161
|
path.join('data', 'causation-aun.json*'),
|
|
162
|
+
path.join('data', 'triggers', '**'),
|
|
163
|
+
path.join('data', 'sessions', '**'),
|
|
164
|
+
path.join('data', 'contact-book-audit.jsonl'),
|
|
165
|
+
path.join('data', 'feishu-seen-*.jsonl'),
|
|
166
|
+
path.join('data', '*-greeted-*.jsonl'),
|
|
158
167
|
path.join('data', 'message-queue.json*'),
|
|
168
|
+
path.join('data', 'daemon', 'message-queue.json*'),
|
|
169
|
+
path.join('data', 'daemon', 'control', '**'),
|
|
170
|
+
path.join('data', 'daemon', 'migrations', '**'),
|
|
171
|
+
path.join('data', 'channel-state', '**'),
|
|
159
172
|
path.join('data', 'instance', 'control.token'),
|
|
160
173
|
path.join('data', 'outbox'),
|
|
161
174
|
path.join('data', 'outbox', '**'),
|
|
162
175
|
path.join('data', 'handoff'),
|
|
163
176
|
path.join('data', 'handoff', '**'),
|
|
177
|
+
path.join('agents', '*', 'sessions', '**'),
|
|
178
|
+
path.join('agents', '*', 'data', 'channels', '**'),
|
|
179
|
+
path.join('agents', '*', 'data', 'handoff', '**'),
|
|
180
|
+
path.join('agents', '*', 'data', 'outbox.jsonl*'),
|
|
181
|
+
path.join('agents', '*', 'data', 'contact-audit.jsonl'),
|
|
164
182
|
];
|
|
165
183
|
return entries.map(entry => path.join(absoluteRoot, entry));
|
|
166
184
|
}
|
|
167
185
|
export function getLClassWritePatterns(root = resolveRoot()) {
|
|
168
186
|
const absoluteRoot = resolveThroughExistingAncestor(root);
|
|
169
187
|
return [
|
|
170
|
-
path.join(absoluteRoot, '
|
|
171
|
-
path.join(absoluteRoot, '
|
|
188
|
+
path.join(absoluteRoot, 'agents', '*', 'triggers'),
|
|
189
|
+
path.join(absoluteRoot, 'agents', '*', 'triggers', '**'),
|
|
172
190
|
path.join(absoluteRoot, 'agents', '*', 'roles', '**'),
|
|
173
191
|
];
|
|
174
192
|
}
|
|
@@ -190,7 +208,9 @@ export function getExistingHClassMaskTargets(root = resolveRoot()) {
|
|
|
190
208
|
for (const relative of [
|
|
191
209
|
'daemon.json', 'backups/config', '.snapshots', 'CA',
|
|
192
210
|
'.device_id', '.env', '.seed', '.lock', 'daemon.pid',
|
|
193
|
-
'data/causation-aun.json', 'data/
|
|
211
|
+
'data/causation-aun.json', 'data/sessions', 'data/triggers', 'data/contact-book-audit.jsonl',
|
|
212
|
+
'data/message-queue.json', 'data/message-queue.json_', 'data/message-queue.json__',
|
|
213
|
+
'data/daemon/message-queue.json', 'data/daemon/control', 'data/daemon/migrations', 'data/channel-state',
|
|
194
214
|
'data/instance/control.token',
|
|
195
215
|
'data/outbox', 'data/handoff',
|
|
196
216
|
]) {
|
|
@@ -204,6 +224,14 @@ export function getExistingHClassMaskTargets(root = resolveRoot()) {
|
|
|
204
224
|
}
|
|
205
225
|
}
|
|
206
226
|
catch { }
|
|
227
|
+
try {
|
|
228
|
+
for (const entry of fs.readdirSync(path.join(absoluteRoot, 'data'))) {
|
|
229
|
+
if (/^feishu-seen-.+\.jsonl$/.test(entry) || /^[a-z0-9_-]+-greeted-.+\.jsonl$/i.test(entry)) {
|
|
230
|
+
addExistingTarget(targets, path.join(absoluteRoot, 'data', entry));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch { }
|
|
207
235
|
const agentsDir = path.join(absoluteRoot, 'agents');
|
|
208
236
|
addExistingTarget(targets, path.join(agentsDir, 'defaults.json'));
|
|
209
237
|
try {
|
|
@@ -228,6 +256,11 @@ export function getExistingHClassMaskTargets(root = resolveRoot()) {
|
|
|
228
256
|
}
|
|
229
257
|
}
|
|
230
258
|
catch { }
|
|
259
|
+
addExistingTarget(targets, path.join(agentRoot, 'sessions'));
|
|
260
|
+
addExistingTarget(targets, path.join(agentRoot, 'data', 'channels'));
|
|
261
|
+
addExistingTarget(targets, path.join(agentRoot, 'data', 'handoff'));
|
|
262
|
+
addExistingTarget(targets, path.join(agentRoot, 'data', 'outbox.jsonl'));
|
|
263
|
+
addExistingTarget(targets, path.join(agentRoot, 'data', 'contact-audit.jsonl'));
|
|
231
264
|
}
|
|
232
265
|
}
|
|
233
266
|
catch { }
|
|
@@ -248,12 +281,12 @@ export function getExistingHClassMaskTargets(root = resolveRoot()) {
|
|
|
248
281
|
export function getExistingLClassReadOnlyTargets(root = resolveRoot()) {
|
|
249
282
|
const targets = new Map();
|
|
250
283
|
const absoluteRoot = resolveThroughExistingAncestor(root);
|
|
251
|
-
addExistingTarget(targets, path.join(absoluteRoot, 'data', 'triggers'));
|
|
252
284
|
const agentsDir = path.join(absoluteRoot, 'agents');
|
|
253
285
|
try {
|
|
254
286
|
for (const entry of fs.readdirSync(agentsDir, { withFileTypes: true })) {
|
|
255
287
|
if (!entry.isDirectory())
|
|
256
288
|
continue;
|
|
289
|
+
addExistingTarget(targets, path.join(agentsDir, entry.name, 'triggers'));
|
|
257
290
|
addExistingTarget(targets, path.join(agentsDir, entry.name, 'roles'));
|
|
258
291
|
}
|
|
259
292
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { agentSessionsDir } from '../../../paths.js';
|
|
4
|
+
function projectDirectory(projectPath, agentAid) {
|
|
5
|
+
if (!agentAid?.trim())
|
|
6
|
+
return null;
|
|
7
|
+
const encoded = path.resolve(projectPath).replace(/^[/\\]/, '').replace(/[/\\:]/g, '-');
|
|
8
|
+
return path.join(agentSessionsDir(agentAid.trim()), `--${encoded}--`);
|
|
9
|
+
}
|
|
10
|
+
function messageText(content) {
|
|
11
|
+
if (typeof content === 'string')
|
|
12
|
+
return content;
|
|
13
|
+
if (!Array.isArray(content))
|
|
14
|
+
return '';
|
|
15
|
+
return content
|
|
16
|
+
.filter((block) => block?.type === 'text' && typeof block.text === 'string')
|
|
17
|
+
.map(block => block.text)
|
|
18
|
+
.join('\n');
|
|
19
|
+
}
|
|
20
|
+
function preview(text) {
|
|
21
|
+
const normalized = text.trim().replace(/\s+/g, ' ');
|
|
22
|
+
if (!normalized)
|
|
23
|
+
return null;
|
|
24
|
+
return normalized.length > 50 ? `${normalized.slice(0, 50)}...` : normalized;
|
|
25
|
+
}
|
|
26
|
+
export class EcagentSessionFileAdapter {
|
|
27
|
+
baseagent = 'ecagent';
|
|
28
|
+
findSessionFile(projectPath, agentSessionId, agentAid) {
|
|
29
|
+
const dir = projectDirectory(projectPath, agentAid);
|
|
30
|
+
if (!dir)
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
const file = fs.readdirSync(dir).find(name => name.endsWith(`_${agentSessionId}.jsonl`));
|
|
34
|
+
return file ? path.join(dir, file) : null;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
readEntries(projectPath, agentSessionId, agentAid) {
|
|
41
|
+
const file = this.findSessionFile(projectPath, agentSessionId, agentAid);
|
|
42
|
+
if (!file)
|
|
43
|
+
return [];
|
|
44
|
+
try {
|
|
45
|
+
return fs.readFileSync(file, 'utf8').split('\n').slice(1).flatMap(line => {
|
|
46
|
+
if (!line.trim())
|
|
47
|
+
return [];
|
|
48
|
+
try {
|
|
49
|
+
return [JSON.parse(line)];
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
checkExists(projectPath, agentSessionId, agentAid) {
|
|
61
|
+
return this.findSessionFile(projectPath, agentSessionId, agentAid) !== null;
|
|
62
|
+
}
|
|
63
|
+
getFileInfo(projectPath, agentSessionId, agentAid) {
|
|
64
|
+
const entries = this.readEntries(projectPath, agentSessionId, agentAid);
|
|
65
|
+
const userMessages = entries.filter(entry => entry.type === 'message' && entry.message?.role === 'user');
|
|
66
|
+
const names = entries.filter(entry => entry.type === 'session_info' && typeof entry.name === 'string');
|
|
67
|
+
const title = names.at(-1)?.name?.trim() || preview(messageText(userMessages[0]?.message?.content));
|
|
68
|
+
return { turns: userMessages.length, title: title || undefined };
|
|
69
|
+
}
|
|
70
|
+
readFirstMessage(projectPath, agentSessionId, agentAid) {
|
|
71
|
+
const entry = this.readEntries(projectPath, agentSessionId, agentAid)
|
|
72
|
+
.find(item => item.type === 'message' && item.message?.role === 'user');
|
|
73
|
+
return preview(messageText(entry?.message?.content));
|
|
74
|
+
}
|
|
75
|
+
readLastUserMessage(projectPath, agentSessionId, agentAid) {
|
|
76
|
+
const entries = this.readEntries(projectPath, agentSessionId, agentAid)
|
|
77
|
+
.filter(item => item.type === 'message' && item.message?.role === 'user');
|
|
78
|
+
return preview(messageText(entries.at(-1)?.message?.content));
|
|
79
|
+
}
|
|
80
|
+
scanCliSessions(projectPath, _limit = 10, agentAid) {
|
|
81
|
+
const dir = projectDirectory(projectPath, agentAid);
|
|
82
|
+
if (!dir)
|
|
83
|
+
return [];
|
|
84
|
+
try {
|
|
85
|
+
return fs.readdirSync(dir)
|
|
86
|
+
.filter(name => name.endsWith('.jsonl'))
|
|
87
|
+
.flatMap(name => {
|
|
88
|
+
const file = path.join(dir, name);
|
|
89
|
+
try {
|
|
90
|
+
const header = JSON.parse(fs.readFileSync(file, 'utf8').split('\n', 1)[0] || '{}');
|
|
91
|
+
if (header.type !== 'session' || typeof header.id !== 'string')
|
|
92
|
+
return [];
|
|
93
|
+
return [{ uuid: header.id, mtime: fs.statSync(file).mtimeMs }];
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
.sort((a, b) => b.mtime - a.mtime)
|
|
100
|
+
.slice(0, _limit);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async listSdkSessions(projectPath, agentAid) {
|
|
107
|
+
return this.scanCliSessions(projectPath, 10, agentAid).map(entry => ({
|
|
108
|
+
sessionId: entry.uuid,
|
|
109
|
+
title: this.getFileInfo(projectPath, entry.uuid, agentAid).title,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
}
|