evolcore 0.0.5 → 0.0.6
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 +43 -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 +81 -6
- 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 +11 -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 +10 -9
- 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/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
|
@@ -119,9 +119,12 @@ const GEMINI_H_CLASS_PATTERNS = [
|
|
|
119
119
|
String.raw `(?:^|[/\\"])daemon\.pid(?:[/\\"]|$)`,
|
|
120
120
|
String.raw `\.json_`,
|
|
121
121
|
String.raw `\.json\.migrated`,
|
|
122
|
+
String.raw `agents[/\\][^/\\"]+[/\\](?:sessions|data[/\\](?:channels|handoff|outbox\.jsonl|contact-audit\.jsonl))`,
|
|
123
|
+
String.raw `data[/\\]triggers(?:[/\\]|$)`,
|
|
124
|
+
String.raw `data[/\\](?:sessions|contact-book-audit\.jsonl|feishu-seen-[^/\\"]+\.jsonl|[a-z0-9_-]+-greeted-[^/\\"]+\.jsonl|channel-state|daemon[/\\](?:control|migrations|message-queue\.json))`,
|
|
122
125
|
];
|
|
123
126
|
const GEMINI_L_CLASS_PATTERNS = [
|
|
124
|
-
String.raw `
|
|
127
|
+
String.raw `agents[/\\][^/\\"]+[/\\]triggers(?:[/\\]|$)`,
|
|
125
128
|
];
|
|
126
129
|
const GEMINI_L_CLASS_WRITE_TOOLS = [
|
|
127
130
|
'write_file', 'replace', 'delete_file', 'move_file', 'rename_file',
|
|
@@ -65,11 +65,27 @@ export function isOneMillionContextModel(model) {
|
|
|
65
65
|
const baseModel = model.replace(/\[1m\]$/i, '');
|
|
66
66
|
return ONE_M_CONTEXT_MODEL_PREFIXES.some(prefix => baseModel === prefix || baseModel.startsWith(`${prefix}-`));
|
|
67
67
|
}
|
|
68
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* EvolCore's conservative local context-window catalog: 1M models = 1,000,000;
|
|
70
|
+
* every other model falls back to 200,000 until provider metadata is available.
|
|
71
|
+
* This is an operational guardrail, not a claim about an upstream provider's
|
|
72
|
+
* advertised capacity.
|
|
73
|
+
*/
|
|
69
74
|
export function realContextWindowForModel(model) {
|
|
70
75
|
return isOneMillionContextModel(model) ? 1000000 : 200000;
|
|
71
76
|
}
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
/**
|
|
78
|
+
* The SDK's compaction threshold must leave room for the next model turn and
|
|
79
|
+
* its tool results. Keep a 10k reserve for 200k-class windows and retain the
|
|
80
|
+
* historical 350k cap for large-context models.
|
|
81
|
+
*/
|
|
82
|
+
export function autoCompactWindowForContextWindow(contextWindow) {
|
|
83
|
+
if (!contextWindow || contextWindow <= 0)
|
|
84
|
+
return undefined;
|
|
85
|
+
const reserve = Math.min(10_000, Math.floor(contextWindow * 0.05));
|
|
86
|
+
return Math.min(350_000, Math.max(1, contextWindow - reserve));
|
|
87
|
+
}
|
|
88
|
+
/** Auto-compact threshold derived from the configured model context window. */
|
|
89
|
+
export function autoCompactWindowForModel(model) {
|
|
90
|
+
return autoCompactWindowForContextWindow(realContextWindowForModel(model)) ?? 350_000;
|
|
75
91
|
}
|
package/dist/aun/msg/history.js
CHANGED
|
@@ -6,13 +6,24 @@ import { resolvePaths } from '../../paths.js';
|
|
|
6
6
|
const DEFAULT_LIMIT = 50;
|
|
7
7
|
export const MAX_MSG_HISTORY_LIMIT = 500;
|
|
8
8
|
const SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,255}$/;
|
|
9
|
+
const CHANNELS = new Set(['aun', 'feishu', 'wechat', 'dingtalk', 'qqbot', 'wecom']);
|
|
9
10
|
export function msgHistory(args, options = {}) {
|
|
10
11
|
if (!isValidAid(args.from)) {
|
|
11
12
|
return error('INVALID_SELF_AID', `无效 self AID: ${args.from}`);
|
|
12
13
|
}
|
|
13
|
-
|
|
14
|
+
const channel = args.channel ?? 'aun';
|
|
15
|
+
if (!CHANNELS.has(channel)) {
|
|
16
|
+
return error('INVALID_CHANNEL', `不支持的 channel: ${String(args.channel)}`);
|
|
17
|
+
}
|
|
18
|
+
if (channel === 'aun' && !isValidAid(args.target)) {
|
|
14
19
|
return error('INVALID_TARGET_AID', `无效 target AID: ${args.target}`);
|
|
15
20
|
}
|
|
21
|
+
if (channel !== 'aun' && !isSafeChannelPeerId(args.target)) {
|
|
22
|
+
return error('INVALID_TARGET_ID', `无效 ${channel} 对端 ID`);
|
|
23
|
+
}
|
|
24
|
+
if (args.channelName !== undefined && !isSafeChannelName(args.channelName)) {
|
|
25
|
+
return error('INVALID_CHANNEL_NAME', '无效 channel 实例名');
|
|
26
|
+
}
|
|
16
27
|
const limit = args.limit ?? DEFAULT_LIMIT;
|
|
17
28
|
if (!Number.isInteger(limit) || limit < 1 || limit > MAX_MSG_HISTORY_LIMIT) {
|
|
18
29
|
return error('INVALID_LIMIT', `limit 必须是 1-${MAX_MSG_HISTORY_LIMIT} 的整数`);
|
|
@@ -31,8 +42,8 @@ export function msgHistory(args, options = {}) {
|
|
|
31
42
|
return error('INVALID_TIME_RANGE', 'after 必须早于 before');
|
|
32
43
|
}
|
|
33
44
|
const sessionsDir = options.sessionsDir ?? resolvePaths().sessionsDir;
|
|
34
|
-
const chatDir = chatDirPath(sessionsDir,
|
|
35
|
-
const resolvedSession = resolveSessionFilter(chatDir, args.from, args.target, args.session ?? 'latest');
|
|
45
|
+
const chatDir = chatDirPath(sessionsDir, channel, args.target, args.from, channel === 'aun' && !args.channelName ? undefined : `${channel}#${args.from}#${args.channelName ?? 'main'}`);
|
|
46
|
+
const resolvedSession = resolveSessionFilter(chatDir, args.from, args.target, channel, args.session ?? 'latest');
|
|
36
47
|
if (!resolvedSession.ok)
|
|
37
48
|
return resolvedSession;
|
|
38
49
|
let entries;
|
|
@@ -60,7 +71,7 @@ export function msgHistory(args, options = {}) {
|
|
|
60
71
|
messages,
|
|
61
72
|
};
|
|
62
73
|
}
|
|
63
|
-
function resolveSessionFilter(chatDir, selfAid, targetAid, requested) {
|
|
74
|
+
function resolveSessionFilter(chatDir, selfAid, targetAid, channel, requested) {
|
|
64
75
|
if (requested === 'all')
|
|
65
76
|
return { ok: true };
|
|
66
77
|
if (requested === 'latest') {
|
|
@@ -68,7 +79,7 @@ function resolveSessionFilter(chatDir, selfAid, targetAid, requested) {
|
|
|
68
79
|
if (!active?.id) {
|
|
69
80
|
return error('LATEST_SESSION_NOT_FOUND', '该 AID 对暂无最新会话');
|
|
70
81
|
}
|
|
71
|
-
if (!sessionBelongsToPair(active, selfAid, targetAid)) {
|
|
82
|
+
if (!sessionBelongsToPair(active, selfAid, targetAid, channel)) {
|
|
72
83
|
return error('SESSION_SCOPE_MISMATCH', 'active.json 不属于指定 AID 对');
|
|
73
84
|
}
|
|
74
85
|
return { ok: true, sessionId: active.id };
|
|
@@ -78,7 +89,7 @@ function resolveSessionFilter(chatDir, selfAid, targetAid, requested) {
|
|
|
78
89
|
}
|
|
79
90
|
const active = readJsonFile(path.join(chatDir, 'active.json'));
|
|
80
91
|
if (active?.id === requested) {
|
|
81
|
-
if (!sessionBelongsToPair(active, selfAid, targetAid)) {
|
|
92
|
+
if (!sessionBelongsToPair(active, selfAid, targetAid, channel)) {
|
|
82
93
|
return error('SESSION_SCOPE_MISMATCH', '指定会话不属于该 AID 对');
|
|
83
94
|
}
|
|
84
95
|
return { ok: true, sessionId: requested };
|
|
@@ -90,15 +101,15 @@ function resolveSessionFilter(chatDir, selfAid, targetAid, requested) {
|
|
|
90
101
|
const session = readLastJsonlLine(sessionPath);
|
|
91
102
|
if (!session || session.id !== requested)
|
|
92
103
|
continue;
|
|
93
|
-
if (!sessionBelongsToPair(session, selfAid, targetAid)) {
|
|
104
|
+
if (!sessionBelongsToPair(session, selfAid, targetAid, channel)) {
|
|
94
105
|
return error('SESSION_SCOPE_MISMATCH', '指定会话不属于该 AID 对');
|
|
95
106
|
}
|
|
96
107
|
return { ok: true, sessionId: requested };
|
|
97
108
|
}
|
|
98
109
|
return error('SESSION_NOT_FOUND', `在该 AID 对中找不到会话: ${requested}`);
|
|
99
110
|
}
|
|
100
|
-
function sessionBelongsToPair(session, selfAid, targetAid) {
|
|
101
|
-
if (session.channelType && session.channelType !==
|
|
111
|
+
function sessionBelongsToPair(session, selfAid, targetAid, channel) {
|
|
112
|
+
if (session.channelType && session.channelType !== channel)
|
|
102
113
|
return false;
|
|
103
114
|
if (session.channelId && session.channelId !== targetAid)
|
|
104
115
|
return false;
|
|
@@ -107,6 +118,18 @@ function sessionBelongsToPair(session, selfAid, targetAid) {
|
|
|
107
118
|
return false;
|
|
108
119
|
return true;
|
|
109
120
|
}
|
|
121
|
+
function isSafeChannelPeerId(value) {
|
|
122
|
+
return typeof value === 'string'
|
|
123
|
+
&& value.trim().length > 0
|
|
124
|
+
&& value.length <= 512
|
|
125
|
+
&& !/[\u0000-\u001f\u007f]/.test(value);
|
|
126
|
+
}
|
|
127
|
+
function isSafeChannelName(value) {
|
|
128
|
+
return typeof value === 'string'
|
|
129
|
+
&& value.trim().length > 0
|
|
130
|
+
&& value.length <= 128
|
|
131
|
+
&& !/[\u0000-\u001f\u007f#\/\\]/.test(value);
|
|
132
|
+
}
|
|
110
133
|
function isMessageLogEntry(value) {
|
|
111
134
|
if (!value || typeof value !== 'object')
|
|
112
135
|
return false;
|
package/dist/aun/outbox.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import crypto from 'crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { agentOutboxPath } from '../paths.js';
|
|
5
5
|
const MAX_ENTRIES_PER_AID = 20;
|
|
6
6
|
const DEFAULT_TTL = 300_000; // 5 minutes
|
|
7
|
-
function outboxDir() {
|
|
8
|
-
return resolvePaths().outboxDir;
|
|
9
|
-
}
|
|
10
7
|
function outboxFile(aid) {
|
|
11
|
-
return
|
|
8
|
+
return agentOutboxPath(aid);
|
|
12
9
|
}
|
|
13
10
|
function generateId() {
|
|
14
11
|
const ts = Date.now();
|
|
@@ -48,8 +45,7 @@ function writeEntries(aid, entries) {
|
|
|
48
45
|
catch { }
|
|
49
46
|
return;
|
|
50
47
|
}
|
|
51
|
-
|
|
52
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
53
49
|
fs.writeFileSync(file, entries.map(e => JSON.stringify(e)).join('\n') + '\n');
|
|
54
50
|
}
|
|
55
51
|
export function enqueue(aid, opts) {
|
|
@@ -68,9 +64,8 @@ export function enqueue(aid, opts) {
|
|
|
68
64
|
ttl: opts.ttl ?? DEFAULT_TTL,
|
|
69
65
|
postSend: opts.postSend,
|
|
70
66
|
};
|
|
71
|
-
const dir = outboxDir();
|
|
72
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
73
67
|
const file = outboxFile(aid);
|
|
68
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
74
69
|
// Enforce cap: read existing, drop oldest if over limit
|
|
75
70
|
let entries = readEntries(aid);
|
|
76
71
|
if (entries.length >= MAX_ENTRIES_PER_AID) {
|
package/dist/channels/aun.js
CHANGED
|
@@ -317,6 +317,10 @@ export class AUNChannel {
|
|
|
317
317
|
logger.error(`${this.logPrefix()} Failed to send card action error:`, err);
|
|
318
318
|
});
|
|
319
319
|
}
|
|
320
|
+
auditActionCardInteraction(behavior, cardMessageId, interactionId, result, textLength) {
|
|
321
|
+
logger.info(`${this.logPrefix()} ActionInteraction audit: behavior=${behavior ?? 'reply'} `
|
|
322
|
+
+ `cardId=${cardMessageId} interactionId=${interactionId} result=${result} textLength=${textLength}`);
|
|
323
|
+
}
|
|
320
324
|
extractTextPayload(payload, channelId, senderAid) {
|
|
321
325
|
if (typeof payload === 'string')
|
|
322
326
|
return payload;
|
|
@@ -329,8 +333,8 @@ export class AUNChannel {
|
|
|
329
333
|
: typeof obj.card_message_id === 'string' ? obj.card_message_id : '';
|
|
330
334
|
const cardInfo = cardMsgId ? this.cardMessageIdMap.get(cardMsgId) : undefined;
|
|
331
335
|
if (cardInfo) {
|
|
332
|
-
// compose
|
|
333
|
-
//
|
|
336
|
+
// compose 按钮由新版客户端在卡片内采集输入;旧版客户端可继续从主编辑器
|
|
337
|
+
// 采集。两者最终都回传 action_card_reply{behavior:"compose", text}。
|
|
334
338
|
// 映射为 _custom_input + values.custom_text,复用 claude-runner 已有的自定义输入分支
|
|
335
339
|
// (原为多选表单提交而设),不需要新增 action 类型,也不必拦截消息队列。
|
|
336
340
|
const behaviorRaw = typeof obj.behavior === 'string' ? obj.behavior : undefined;
|
|
@@ -399,16 +403,35 @@ export class AUNChannel {
|
|
|
399
403
|
// ActionInteraction:后端明确接受后才消费 mapping。撤权、过期或
|
|
400
404
|
// 重复点击返回 false 时保持 fail-closed,并提示用户卡片已失效。
|
|
401
405
|
if (channelId && this.isGroupId(channelId) && !cardClickerAid) {
|
|
406
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'rejected_unauthenticated', text.length);
|
|
402
407
|
this.notifyCardActionFailure(channelId, '⚠️ 无法验证卡片操作者身份', undefined, threadId);
|
|
403
408
|
return '';
|
|
404
409
|
}
|
|
405
410
|
if (channelId && this.isGroupId(channelId) && cardInfo.initiatorAid
|
|
406
411
|
&& cardClickerAid !== cardInfo.initiatorAid) {
|
|
412
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'rejected_non_initiator', text.length);
|
|
407
413
|
this.notifyCardActionFailure(channelId, '⚠️ 仅卡片发起者可操作', cardClickerAid, threadId);
|
|
408
414
|
return '';
|
|
409
415
|
}
|
|
416
|
+
// Compose reply 入参校验:text 必须非空且未超长。
|
|
417
|
+
// 校验失败不调用 callback、不消费卡片 mapping,让用户可修改重试。
|
|
418
|
+
if (isComposeReply) {
|
|
419
|
+
const trimmedText = text.trim();
|
|
420
|
+
const MAX_COMPOSE_TEXT_LENGTH = 64 * 1024; // 64K 字符
|
|
421
|
+
if (!trimmedText) {
|
|
422
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'rejected_empty', text.length);
|
|
423
|
+
this.notifyCardActionFailure(channelId, '⚠️ 输入内容不能为空,请重新输入', cardClickerAid, threadId);
|
|
424
|
+
return '';
|
|
425
|
+
}
|
|
426
|
+
if (text.length > MAX_COMPOSE_TEXT_LENGTH) {
|
|
427
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'rejected_too_long', text.length);
|
|
428
|
+
this.notifyCardActionFailure(channelId, `⚠️ 输入内容过长(${text.length} 字符,限制 ${MAX_COMPOSE_TEXT_LENGTH}),请缩短后重试`, cardClickerAid, threadId);
|
|
429
|
+
return '';
|
|
430
|
+
}
|
|
431
|
+
}
|
|
410
432
|
if (this.interactionCallback) {
|
|
411
433
|
if (this.interactionActionsInFlight.has(cardMsgId)) {
|
|
434
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'rejected_in_flight', text.length);
|
|
412
435
|
this.notifyCardActionFailure(channelId, '⏳ 操作正在处理,请勿重复点击', cardClickerAid, threadId);
|
|
413
436
|
return '';
|
|
414
437
|
}
|
|
@@ -428,6 +451,7 @@ export class AUNChannel {
|
|
|
428
451
|
};
|
|
429
452
|
const settle = (accepted) => {
|
|
430
453
|
this.interactionActionsInFlight.delete(cardMsgId);
|
|
454
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, accepted ? 'accepted' : 'backend_rejected', text.length);
|
|
431
455
|
if (accepted) {
|
|
432
456
|
this.forgetInteractionCard(cardMsgId, cardInfo.requestId);
|
|
433
457
|
return;
|
|
@@ -448,6 +472,7 @@ export class AUNChannel {
|
|
|
448
472
|
if (result && typeof result.then === 'function') {
|
|
449
473
|
Promise.resolve(result).then(accepted => settle(accepted !== false), err => {
|
|
450
474
|
this.interactionActionsInFlight.delete(cardMsgId);
|
|
475
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'callback_error', text.length);
|
|
451
476
|
logger.error(`${this.logPrefix()} ActionInteraction callback failed: request=${cardInfo.requestId}`, err);
|
|
452
477
|
this.notifyCardActionFailure(channelId, '❌ 操作失败,请稍后重试', cardClickerAid, threadId);
|
|
453
478
|
});
|
|
@@ -458,11 +483,13 @@ export class AUNChannel {
|
|
|
458
483
|
}
|
|
459
484
|
catch (err) {
|
|
460
485
|
this.interactionActionsInFlight.delete(cardMsgId);
|
|
486
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'callback_error', text.length);
|
|
461
487
|
logger.error(`${this.logPrefix()} ActionInteraction callback failed: request=${cardInfo.requestId}`, err);
|
|
462
488
|
this.notifyCardActionFailure(channelId, '❌ 操作失败,请稍后重试', cardClickerAid, threadId);
|
|
463
489
|
}
|
|
464
490
|
}
|
|
465
491
|
else {
|
|
492
|
+
this.auditActionCardInteraction(behaviorRaw, cardMsgId, cardInfo.requestId, 'handler_unavailable', text.length);
|
|
466
493
|
this.notifyCardActionFailure(channelId, '❌ 操作失败:交互处理器未就绪', cardClickerAid, threadId);
|
|
467
494
|
}
|
|
468
495
|
}
|
|
@@ -4130,10 +4157,9 @@ export class AUNChannelPlugin {
|
|
|
4130
4157
|
label: btn.label, value: btn.key, style: btn.style ?? 'default', behavior: 'reply',
|
|
4131
4158
|
})),
|
|
4132
4159
|
};
|
|
4133
|
-
// AUN action_card
|
|
4134
|
-
//
|
|
4135
|
-
//
|
|
4136
|
-
// extractTextPayload 的 compose 分支),不依赖 interceptNextMessage 拦截消息队列。
|
|
4160
|
+
// AUN action_card 以 compose behavior 声明自由文本动作。新版客户端
|
|
4161
|
+
// 在卡片内采集并确认;旧版客户端可继续从主编辑器采集。两者都结构化
|
|
4162
|
+
// 回传 action_card_reply{behavior:"compose"},Core 不拦截普通消息队列。
|
|
4137
4163
|
if (action.allowCustomInput) {
|
|
4138
4164
|
aunCard.actions.push({ label: '✏️ 手动输入', style: 'default', behavior: 'compose', compose_timeout_ms: cardTtlMs });
|
|
4139
4165
|
}
|
package/dist/channels/daemon.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeExecutionMode } from '../trigger/validation.js';
|
|
1
2
|
import { resolvePeerRoleDetail } from '../config/peer-role-resolver.js';
|
|
2
3
|
const DEFAULT_WATCHDOG_MS = 11 * 60 * 1000;
|
|
3
4
|
export class DaemonChannel {
|
|
@@ -204,10 +205,11 @@ export class DaemonChannel {
|
|
|
204
205
|
this.resetWatchdog(pendingId, slot);
|
|
205
206
|
return true;
|
|
206
207
|
}
|
|
207
|
-
async getOrCreateConversationSession(trigger, projectPath, baseagent, runId,
|
|
208
|
+
async getOrCreateConversationSession(trigger, projectPath, baseagent, runId, _attemptId) {
|
|
208
209
|
const channelId = `trigger:${trigger.id}`;
|
|
209
|
-
const
|
|
210
|
-
|
|
210
|
+
const mode = normalizeExecutionMode(trigger.execution);
|
|
211
|
+
const threadId = mode.thread === 'by_run'
|
|
212
|
+
? `trigger:${trigger.id}:${runId}`
|
|
211
213
|
: `trigger:${trigger.id}`;
|
|
212
214
|
return await this.sessionManager.getOrCreateSession(this.channelName, channelId, projectPath, threadId, { channelKey: this.channelKey, peerId: `trigger:${trigger.id}`, peerName: trigger.name }, trigger.name, undefined, 'private', baseagent, trigger.agentAid, this.channelName, 'system');
|
|
213
215
|
}
|
|
@@ -218,7 +220,7 @@ export class DaemonChannel {
|
|
|
218
220
|
const session = await this.sessionManager.getSessionById(sessionId);
|
|
219
221
|
if (!session?.agentSessionId)
|
|
220
222
|
return undefined;
|
|
221
|
-
if (!this.sessionManager.checkSessionFileExists(session.projectPath, session.agentSessionId, session.baseagent))
|
|
223
|
+
if (!this.sessionManager.checkSessionFileExists(session.projectPath, session.agentSessionId, session.baseagent, session.selfAID))
|
|
222
224
|
return undefined;
|
|
223
225
|
return session;
|
|
224
226
|
}
|
|
@@ -309,6 +311,7 @@ export class DaemonChannel {
|
|
|
309
311
|
numTurns: typeof metadata?.numTurns === 'number' ? metadata.numTurns : undefined,
|
|
310
312
|
tokenUsage: isObject(metadata?.tokenUsage) ? metadata.tokenUsage : undefined,
|
|
311
313
|
contextUsage: metadata?.contextUsage,
|
|
314
|
+
contextRecoveryAttempts: typeof metadata?.contextRecoveryAttempts === 'number' ? metadata.contextRecoveryAttempts : undefined,
|
|
312
315
|
toolCallCount: Math.max(slot.acc.toolCallCount, completedToolCallCount),
|
|
313
316
|
},
|
|
314
317
|
});
|
|
@@ -9,7 +9,7 @@ import { createSendFileMarkerPattern } from '../core/message/file-markers.js';
|
|
|
9
9
|
import { sentReceipt, suppressedReceipt } from '../core/message/send-receipt.js';
|
|
10
10
|
import { initWelcomeManager, sendWelcomeIfNeeded } from '../utils/welcome.js';
|
|
11
11
|
import { CONTACT_BIND_CODE_TTL_MS, CONTACT_BIND_MAX_FAILED_ATTEMPTS, ContactBindCodeRegistry, handleExplicitContactBindCommand, } from '../config/contact-bind-code.js';
|
|
12
|
-
import {
|
|
12
|
+
import { channelStatePath } from '../paths.js';
|
|
13
13
|
const DINGTALK_QUEUED_EMOTION = 'Pin';
|
|
14
14
|
const DINGTALK_THINKING_EMOTION = 'BusinessTrip';
|
|
15
15
|
const DINGTALK_DONE_EMOTION = 'Done';
|
|
@@ -1280,8 +1280,6 @@ export class DingtalkChannelPlugin {
|
|
|
1280
1280
|
return null;
|
|
1281
1281
|
if (!isValidCredential(inst.clientId) || !isValidCredential(inst.clientSecret))
|
|
1282
1282
|
return null;
|
|
1283
|
-
const stateKey = createHash('sha256').update(`${ctx.agentName}:${inst.name}`).digest('hex').slice(0, 16);
|
|
1284
|
-
const dataDir = resolvePaths().dataDir;
|
|
1285
1283
|
if (inst.cardCallbackRouteKey) {
|
|
1286
1284
|
logger.warn(`[DingTalk] cardCallbackRouteKey is ignored for ${inst.name}; interactive cards use Stream callbacks`);
|
|
1287
1285
|
}
|
|
@@ -1291,8 +1289,8 @@ export class DingtalkChannelPlugin {
|
|
|
1291
1289
|
requireMention: inst.requireMention,
|
|
1292
1290
|
freeResponseChats: inst.freeResponseChats,
|
|
1293
1291
|
cardTemplateId: inst.cardTemplateId,
|
|
1294
|
-
seenMsgFile:
|
|
1295
|
-
routeFile:
|
|
1292
|
+
seenMsgFile: channelStatePath(inst.name, 'dingtalk-seen.jsonl'),
|
|
1293
|
+
routeFile: channelStatePath(inst.name, 'routes.json'),
|
|
1296
1294
|
}, ctx.agentName, inst.name);
|
|
1297
1295
|
const mode = resolveShowActivities(inst);
|
|
1298
1296
|
const adapter = {
|
package/dist/channels/feishu.js
CHANGED
|
@@ -6,7 +6,7 @@ import { logger } from '../utils/logger.js';
|
|
|
6
6
|
import { formatItemsAsText } from '../core/message/items-formatter.js';
|
|
7
7
|
import { createSendFileMarkerPattern } from '../core/message/file-markers.js';
|
|
8
8
|
import { initWelcomeManager, sendWelcomeIfNeeded } from '../utils/welcome.js';
|
|
9
|
-
import {
|
|
9
|
+
import { channelStatePath } from '../paths.js';
|
|
10
10
|
import { sentReceipt, suppressedReceipt } from '../core/message/send-receipt.js';
|
|
11
11
|
import { ContactBindCodeRegistry, handleExplicitContactBindCommand, } from '../config/contact-bind-code.js';
|
|
12
12
|
const feishuContactBinds = new ContactBindCodeRegistry({
|
|
@@ -724,15 +724,14 @@ export class FeishuChannel {
|
|
|
724
724
|
catch { }
|
|
725
725
|
}
|
|
726
726
|
seenMessageFile(chatId) {
|
|
727
|
-
if (!this.
|
|
727
|
+
if (!this.channelName)
|
|
728
728
|
return undefined;
|
|
729
|
-
return
|
|
729
|
+
return channelStatePath(this.channelName, 'dedup', 'feishu', encodeURIComponent(chatId) + '.jsonl');
|
|
730
730
|
}
|
|
731
731
|
loadSeenMessages() {
|
|
732
|
-
this.
|
|
733
|
-
if (!this.config.sessionsDir)
|
|
732
|
+
if (!this.channelName)
|
|
734
733
|
return;
|
|
735
|
-
const feishuDir =
|
|
734
|
+
const feishuDir = channelStatePath(this.channelName, 'dedup', 'feishu');
|
|
736
735
|
let entries;
|
|
737
736
|
try {
|
|
738
737
|
entries = fs.readdirSync(feishuDir, { withFileTypes: true });
|
|
@@ -743,10 +742,16 @@ export class FeishuChannel {
|
|
|
743
742
|
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
744
743
|
let loaded = 0;
|
|
745
744
|
for (const entry of entries) {
|
|
746
|
-
if (!entry.
|
|
745
|
+
if (!entry.isFile() || !entry.name.endsWith('.jsonl'))
|
|
747
746
|
continue;
|
|
748
|
-
|
|
749
|
-
|
|
747
|
+
let chatId;
|
|
748
|
+
try {
|
|
749
|
+
chatId = decodeURIComponent(entry.name.slice(0, -'.jsonl'.length));
|
|
750
|
+
}
|
|
751
|
+
catch {
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
const seenFile = path.join(feishuDir, entry.name);
|
|
750
755
|
let lines;
|
|
751
756
|
try {
|
|
752
757
|
lines = fs.readFileSync(seenFile, 'utf-8').split('\n').filter(Boolean);
|
|
@@ -784,88 +789,7 @@ export class FeishuChannel {
|
|
|
784
789
|
this.rewriteSeenMessageFile(chatId, this.seenMessages.get(chatId) ?? new Map());
|
|
785
790
|
}
|
|
786
791
|
if (loaded > 0)
|
|
787
|
-
logger.info(`[Feishu] Loaded ${loaded} seen message ID(s) from
|
|
788
|
-
}
|
|
789
|
-
migrateLegacySeenMessages() {
|
|
790
|
-
const legacyFile = this.config.seenMsgFile;
|
|
791
|
-
if (!legacyFile || !this.config.sessionsDir || !fs.existsSync(legacyFile))
|
|
792
|
-
return;
|
|
793
|
-
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
794
|
-
const records = [];
|
|
795
|
-
try {
|
|
796
|
-
for (const line of fs.readFileSync(legacyFile, 'utf-8').split('\n')) {
|
|
797
|
-
if (!line)
|
|
798
|
-
continue;
|
|
799
|
-
try {
|
|
800
|
-
const { id, ts } = JSON.parse(line);
|
|
801
|
-
if (typeof id === 'string' && typeof ts === 'number' && ts > cutoff) {
|
|
802
|
-
records.push({ id, ts, channel: this.channelName });
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
catch { }
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
catch {
|
|
809
|
-
return;
|
|
810
|
-
}
|
|
811
|
-
const chatIds = this.findChannelChatIds();
|
|
812
|
-
if (chatIds.length === 0)
|
|
813
|
-
return;
|
|
814
|
-
try {
|
|
815
|
-
for (const chatId of chatIds) {
|
|
816
|
-
const seenFile = this.seenMessageFile(chatId);
|
|
817
|
-
if (!seenFile)
|
|
818
|
-
continue;
|
|
819
|
-
fs.mkdirSync(path.dirname(seenFile), { recursive: true });
|
|
820
|
-
if (records.length > 0) {
|
|
821
|
-
fs.appendFileSync(seenFile, records.map(record => JSON.stringify(record)).join('\n') + '\n');
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
fs.unlinkSync(legacyFile);
|
|
825
|
-
logger.info(`[Feishu] Migrated ${records.length} seen message ID(s) into ${chatIds.length} chat director${chatIds.length === 1 ? 'y' : 'ies'}`);
|
|
826
|
-
}
|
|
827
|
-
catch (error) {
|
|
828
|
-
logger.warn('[Feishu] Failed to migrate legacy seen-message file:', error);
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
findChannelChatIds() {
|
|
832
|
-
if (!this.config.sessionsDir || !this.channelName)
|
|
833
|
-
return [];
|
|
834
|
-
const feishuDir = path.join(this.config.sessionsDir, 'feishu');
|
|
835
|
-
let entries;
|
|
836
|
-
try {
|
|
837
|
-
entries = fs.readdirSync(feishuDir, { withFileTypes: true });
|
|
838
|
-
}
|
|
839
|
-
catch {
|
|
840
|
-
return [];
|
|
841
|
-
}
|
|
842
|
-
const chatIds = [];
|
|
843
|
-
for (const entry of entries) {
|
|
844
|
-
if (!entry.isDirectory())
|
|
845
|
-
continue;
|
|
846
|
-
const chatDir = path.join(feishuDir, entry.name);
|
|
847
|
-
let candidates;
|
|
848
|
-
try {
|
|
849
|
-
candidates = ['active.json', ...fs.readdirSync(chatDir).filter(name => /^meta_.*\.jsonl$/.test(name))];
|
|
850
|
-
}
|
|
851
|
-
catch {
|
|
852
|
-
continue;
|
|
853
|
-
}
|
|
854
|
-
let matched = false;
|
|
855
|
-
for (const candidate of candidates) {
|
|
856
|
-
try {
|
|
857
|
-
const firstLine = fs.readFileSync(path.join(chatDir, candidate), 'utf-8').split('\n').find(Boolean);
|
|
858
|
-
if (firstLine && JSON.parse(firstLine).channel === this.channelName) {
|
|
859
|
-
matched = true;
|
|
860
|
-
break;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
catch { }
|
|
864
|
-
}
|
|
865
|
-
if (matched)
|
|
866
|
-
chatIds.push(decodeDirSegment(entry.name));
|
|
867
|
-
}
|
|
868
|
-
return chatIds;
|
|
792
|
+
logger.info(`[Feishu] Loaded ${loaded} seen message ID(s) from channel state`);
|
|
869
793
|
}
|
|
870
794
|
cleanupSeenMessages() {
|
|
871
795
|
const cutoff = Date.now() - 24 * 60 * 60 * 1000;
|
|
@@ -892,21 +816,8 @@ export class FeishuChannel {
|
|
|
892
816
|
if (!seenFile)
|
|
893
817
|
return;
|
|
894
818
|
try {
|
|
895
|
-
const foreignRecords = [];
|
|
896
|
-
if (fs.existsSync(seenFile)) {
|
|
897
|
-
for (const line of fs.readFileSync(seenFile, 'utf-8').split('\n')) {
|
|
898
|
-
if (!line)
|
|
899
|
-
continue;
|
|
900
|
-
try {
|
|
901
|
-
const record = JSON.parse(line);
|
|
902
|
-
if (record.channel && this.channelName && record.channel !== this.channelName)
|
|
903
|
-
foreignRecords.push(record);
|
|
904
|
-
}
|
|
905
|
-
catch { }
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
819
|
const ownRecords = [...chatMessages.entries()].map(([id, ts]) => ({ id, ts, channel: this.channelName }));
|
|
909
|
-
const records =
|
|
820
|
+
const records = ownRecords;
|
|
910
821
|
if (records.length === 0) {
|
|
911
822
|
fs.rmSync(seenFile, { force: true });
|
|
912
823
|
}
|
|
@@ -1788,7 +1699,6 @@ export function hasMarkdownSyntax(text) {
|
|
|
1788
1699
|
return markdownPatterns.some(pattern => pattern.test(text));
|
|
1789
1700
|
}
|
|
1790
1701
|
import { middleOutputModePolicy, resolveShowActivities, showActivitiesPolicy } from '../core/channel-loader.js';
|
|
1791
|
-
import { resolvePaths } from '../paths.js';
|
|
1792
1702
|
export class FeishuChannelPlugin {
|
|
1793
1703
|
name = 'feishu';
|
|
1794
1704
|
async createInstance(inst, ctx) {
|
|
@@ -1797,8 +1707,6 @@ export class FeishuChannelPlugin {
|
|
|
1797
1707
|
const channel = new FeishuChannel({
|
|
1798
1708
|
appId: inst.appId,
|
|
1799
1709
|
appSecret: inst.appSecret,
|
|
1800
|
-
sessionsDir: resolvePaths().sessionsDir,
|
|
1801
|
-
seenMsgFile: path.join(resolvePaths().dataDir, `feishu-seen-${inst.name}.jsonl`),
|
|
1802
1710
|
}, ctx.agentName, inst.name);
|
|
1803
1711
|
const mode = resolveShowActivities(inst);
|
|
1804
1712
|
const adapter = {
|
package/dist/channels/wechat.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import {
|
|
4
|
+
import { channelStatePath } from '../paths.js';
|
|
5
5
|
import { logger } from '../utils/logger.js';
|
|
6
6
|
import { sanitizeFileName, saveToUploads, safeFetch, bufferToInboundImage } from '../utils/media-cache.js';
|
|
7
7
|
import { markdownToPlainText } from '../utils/markdown-to-plain-text.js';
|
|
@@ -208,9 +208,9 @@ export class WechatChannel {
|
|
|
208
208
|
this.agentAid = agentAid;
|
|
209
209
|
this.channelName = channelName;
|
|
210
210
|
this.config = config;
|
|
211
|
-
const
|
|
212
|
-
this.syncBufPath =
|
|
213
|
-
this.contextTokensPath =
|
|
211
|
+
const stateKey = channelName || `wechat#${agentAid || '_unknown'}#main`;
|
|
212
|
+
this.syncBufPath = channelStatePath(stateKey, 'sync-buffer.txt');
|
|
213
|
+
this.contextTokensPath = channelStatePath(stateKey, 'context-tokens.json');
|
|
214
214
|
// 初始化 welcomeManager(使用共享帮助函数)
|
|
215
215
|
if (agentAid && channelName) {
|
|
216
216
|
this.welcomeManager = initWelcomeManager('wechat', agentAid, channelName);
|
package/dist/channels/wecom.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import os from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
4
|
import { logger } from '../utils/logger.js';
|
|
6
5
|
import { requireOptional } from '../utils/npm-ops.js';
|
|
7
6
|
import { middleOutputModePolicy, resolveShowActivities, showActivitiesPolicy } from '../core/channel-loader.js';
|
|
@@ -9,7 +8,7 @@ import { formatItemsAsText } from '../core/message/items-formatter.js';
|
|
|
9
8
|
import { createSendFileMarkerPattern } from '../core/message/file-markers.js';
|
|
10
9
|
import { initWelcomeManager, sendWelcomeIfNeeded } from '../utils/welcome.js';
|
|
11
10
|
import { bufferToInboundImage, sanitizeFileName, saveToUploads, validateUrl } from '../utils/media-cache.js';
|
|
12
|
-
import {
|
|
11
|
+
import { channelStatePath } from '../paths.js';
|
|
13
12
|
import { atomicReadJson, atomicWriteJson } from '../utils/atomic-write.js';
|
|
14
13
|
import { ContactBindCodeRegistry, handleExplicitContactBindCommand, } from '../config/contact-bind-code.js';
|
|
15
14
|
function wecomErrorCode(error) {
|
|
@@ -280,11 +279,10 @@ export class PersistentWecomCardStore {
|
|
|
280
279
|
}
|
|
281
280
|
}
|
|
282
281
|
export function wecomChannelDataPaths(agentAid, channelKey) {
|
|
283
|
-
|
|
284
|
-
const dir = path.join(agentDataDir(agentAid), 'channels', safeKey);
|
|
282
|
+
void agentAid;
|
|
285
283
|
return {
|
|
286
|
-
dedupFile:
|
|
287
|
-
cardFile:
|
|
284
|
+
dedupFile: channelStatePath(channelKey, 'dedup.json'),
|
|
285
|
+
cardFile: channelStatePath(channelKey, 'cards.json'),
|
|
288
286
|
};
|
|
289
287
|
}
|
|
290
288
|
export function createWecomCardTaskId(channelKey, interactionId) {
|
|
@@ -137,7 +137,7 @@ Options:
|
|
|
137
137
|
ec agent new <aid> --non-interactive [选项]
|
|
138
138
|
|
|
139
139
|
非交互模式选项:
|
|
140
|
-
--baseagent <claude|codex|gemini> 默认: PATH
|
|
140
|
+
--baseagent <claude|codex|gemini|ecagent> 默认: PATH 中第一个可用;ecagent 需显式选择
|
|
141
141
|
--project <absolute path> 必填
|
|
142
142
|
--owner <aid>
|
|
143
143
|
--name <display-name>
|