evolcore 0.0.7 → 0.0.9
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 +38 -4
- package/dist/agents/baseagent.js +117 -24
- package/dist/agents/claude-runner.js +31 -2
- package/dist/agents/codex-app-server-client.js +37 -2
- package/dist/agents/codex-runner.js +11 -3
- package/dist/aun/aid/control-aid.js +40 -27
- package/dist/aun/aid/domain.js +23 -0
- package/dist/aun/msg/group.js +9 -9
- package/dist/aun/msg/p2p.js +11 -6
- package/dist/aun/msg/upload.js +43 -29
- package/dist/aun/outbox.js +48 -5
- package/dist/channels/aun.js +225 -71
- package/dist/cli/aun-commands.js +10 -7
- package/dist/cli/bench.js +4 -3
- package/dist/cli/daemon-commands.js +208 -68
- package/dist/cli/data-command.js +62 -35
- package/dist/cli/index.js +11 -1
- package/dist/cli/init-channel.js +1 -1
- package/dist/cli/init.js +112 -17
- package/dist/cli/model.js +5 -5
- package/dist/cli/restart-monitor.js +102 -22
- package/dist/config/builtin-role-templates.js +4 -3
- package/dist/config/config-field-policy.js +6 -2
- package/dist/config/config-manager.js +79 -11
- package/dist/config/gateway-config.js +80 -35
- package/dist/config/role-schema.js +18 -3
- package/dist/config/role-service.js +3 -3
- package/dist/config/role-store.js +4 -3
- package/dist/config-store.js +19 -3
- package/dist/core/auth/operation-authorizer.js +3 -1
- package/dist/core/baseagent-loader.js +5 -3
- package/dist/core/bootstrap-service.js +0 -12
- package/dist/core/capability/providers/codex-capability-provider.js +2 -2
- package/dist/core/channel-loader.js +15 -2
- package/dist/core/command/command-handler.js +1 -1
- package/dist/core/command/evol-menu-version-gate.js +3 -2
- package/dist/core/command/menu-handler.js +50 -28
- package/dist/core/command/menu-protocol.js +7 -4
- package/dist/core/command/slash-handler.js +4 -4
- package/dist/core/data-migration.js +517 -24
- package/dist/core/inference/text-inference.js +18 -5
- package/dist/core/message/message-bridge.js +17 -6
- package/dist/core/message/response-engine.js +22 -3
- package/dist/core/model/config-scope.js +3 -3
- package/dist/core/permission/tool-policy.js +18 -0
- package/dist/core/protected-paths.js +12 -1
- package/dist/index.js +794 -725
- package/dist/ipc.js +3 -1
- package/dist/product.js +1 -0
- package/dist/utils/autostart.js +27 -0
- package/dist/utils/codex-cli.js +39 -0
- package/dist/utils/cross-platform.js +147 -18
- package/dist/utils/ecweb-utils.js +15 -2
- package/dist/utils/instance-registry.js +43 -6
- package/dist/utils/macos-autostart.js +179 -0
- package/dist/utils/process-introspect.js +7 -3
- package/dist/utils/windows-autostart.js +130 -0
- package/ecagent/dist/agent-loop.d.ts +1 -1
- package/ecagent/dist/agent-loop.js +1 -1
- package/ecagent/dist/agent.d.ts +1 -1
- package/ecagent/dist/agent.js +1 -1
- package/ecagent/dist/harness/agent-harness.d.ts +1 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts +1 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts +1 -1
- package/ecagent/dist/harness/compaction/utils.d.ts +1 -1
- package/ecagent/dist/harness/messages.d.ts +1 -1
- package/ecagent/dist/harness/session/session.d.ts +1 -1
- package/ecagent/dist/harness/types.d.ts +1 -1
- package/ecagent/dist/proxy.d.ts +1 -1
- package/ecagent/dist/proxy.js +1 -1
- package/ecagent/dist/types.d.ts +1 -1
- package/kits/migrations/migrate-role-config-v5.mjs +27 -2
- package/kits/rules/01-overview.md +3 -2
- package/kits/schemas/_meta.json +2 -1
- package/kits/schemas/agent-config.schema.10.json +19 -1
- package/kits/schemas/daemon.schema.4.json +136 -0
- package/kits/schemas/defaults.schema.4.json +15 -1
- package/kits/schemas/relation-config.schema.8.json +22 -1
- package/kits/schemas/role-config.schema.1.json +2 -2
- package/package.json +2 -4
- package/ecagent/dist/agent-loop.d.ts.map +0 -1
- package/ecagent/dist/agent-loop.js.map +0 -1
- package/ecagent/dist/agent.d.ts.map +0 -1
- package/ecagent/dist/agent.js.map +0 -1
- package/ecagent/dist/harness/agent-harness.d.ts.map +0 -1
- package/ecagent/dist/harness/agent-harness.js.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/branch-summarization.js.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/compaction.js.map +0 -1
- package/ecagent/dist/harness/compaction/utils.d.ts.map +0 -1
- package/ecagent/dist/harness/compaction/utils.js.map +0 -1
- package/ecagent/dist/harness/env/nodejs.d.ts.map +0 -1
- package/ecagent/dist/harness/env/nodejs.js.map +0 -1
- package/ecagent/dist/harness/messages.d.ts.map +0 -1
- package/ecagent/dist/harness/messages.js.map +0 -1
- package/ecagent/dist/harness/prompt-templates.d.ts.map +0 -1
- package/ecagent/dist/harness/prompt-templates.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-repo.js.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/jsonl-storage.js.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-repo.js.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.d.ts.map +0 -1
- package/ecagent/dist/harness/session/memory-storage.js.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.d.ts.map +0 -1
- package/ecagent/dist/harness/session/repo-utils.js.map +0 -1
- package/ecagent/dist/harness/session/session.d.ts.map +0 -1
- package/ecagent/dist/harness/session/session.js.map +0 -1
- package/ecagent/dist/harness/session/uuid.d.ts.map +0 -1
- package/ecagent/dist/harness/session/uuid.js.map +0 -1
- package/ecagent/dist/harness/skills.d.ts.map +0 -1
- package/ecagent/dist/harness/skills.js.map +0 -1
- package/ecagent/dist/harness/system-prompt.d.ts.map +0 -1
- package/ecagent/dist/harness/system-prompt.js.map +0 -1
- package/ecagent/dist/harness/types.d.ts.map +0 -1
- package/ecagent/dist/harness/types.js.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/shell-output.js.map +0 -1
- package/ecagent/dist/harness/utils/truncate.d.ts.map +0 -1
- package/ecagent/dist/harness/utils/truncate.js.map +0 -1
- package/ecagent/dist/index.d.ts.map +0 -1
- package/ecagent/dist/index.js.map +0 -1
- package/ecagent/dist/node.d.ts.map +0 -1
- package/ecagent/dist/node.js.map +0 -1
- package/ecagent/dist/proxy.d.ts.map +0 -1
- package/ecagent/dist/proxy.js.map +0 -1
- package/ecagent/dist/runtime/api/lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/lazy.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.js.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.d.ts.map +0 -1
- package/ecagent/dist/runtime/api/pi-messages.lazy.js.map +0 -1
- package/ecagent/dist/runtime/auth/context.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/context.js.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/credential-store.js.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/helpers.js.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/resolve.js.map +0 -1
- package/ecagent/dist/runtime/auth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/auth/types.js.map +0 -1
- package/ecagent/dist/runtime/compat.d.ts.map +0 -1
- package/ecagent/dist/runtime/compat.js.map +0 -1
- package/ecagent/dist/runtime/index.d.ts.map +0 -1
- package/ecagent/dist/runtime/index.js.map +0 -1
- package/ecagent/dist/runtime/models.d.ts.map +0 -1
- package/ecagent/dist/runtime/models.js.map +0 -1
- package/ecagent/dist/runtime/oauth.d.ts.map +0 -1
- package/ecagent/dist/runtime/oauth.js.map +0 -1
- package/ecagent/dist/runtime/providers/faux.d.ts.map +0 -1
- package/ecagent/dist/runtime/providers/faux.js.map +0 -1
- package/ecagent/dist/runtime/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/diagnostics.js.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/event-stream.js.map +0 -1
- package/ecagent/dist/runtime/utils/headers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/headers.js.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/json-parse.js.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/oauth/types.js.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/overflow.js.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/provider-env.js.map +0 -1
- package/ecagent/dist/runtime/utils/retry.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/retry.js.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/typebox-helpers.js.map +0 -1
- package/ecagent/dist/runtime/utils/validation.d.ts.map +0 -1
- package/ecagent/dist/runtime/utils/validation.js.map +0 -1
- package/ecagent/dist/types.d.ts.map +0 -1
- package/ecagent/dist/types.js.map +0 -1
- package/ecagent/package.json +0 -93
- package/ecagent/src/agent-loop.ts +0 -792
- package/ecagent/src/agent.ts +0 -575
- package/ecagent/src/harness/agent-harness.ts +0 -1029
- package/ecagent/src/harness/compaction/branch-summarization.ts +0 -261
- package/ecagent/src/harness/compaction/compaction.ts +0 -753
- package/ecagent/src/harness/compaction/utils.ts +0 -144
- package/ecagent/src/harness/env/nodejs.ts +0 -569
- package/ecagent/src/harness/messages.ts +0 -164
- package/ecagent/src/harness/prompt-templates.ts +0 -267
- package/ecagent/src/harness/session/jsonl-repo.ts +0 -179
- package/ecagent/src/harness/session/jsonl-storage.ts +0 -314
- package/ecagent/src/harness/session/memory-repo.ts +0 -50
- package/ecagent/src/harness/session/memory-storage.ts +0 -133
- package/ecagent/src/harness/session/repo-utils.ts +0 -51
- package/ecagent/src/harness/session/session.ts +0 -338
- package/ecagent/src/harness/session/uuid.ts +0 -54
- package/ecagent/src/harness/skills.ts +0 -375
- package/ecagent/src/harness/system-prompt.ts +0 -34
- package/ecagent/src/harness/types.ts +0 -838
- package/ecagent/src/harness/utils/shell-output.ts +0 -135
- package/ecagent/src/harness/utils/truncate.ts +0 -344
- package/ecagent/src/index.ts +0 -46
- package/ecagent/src/node.ts +0 -2
- package/ecagent/src/proxy.ts +0 -367
- package/ecagent/src/runtime/api/lazy.ts +0 -70
- package/ecagent/src/runtime/api/pi-messages.lazy.ts +0 -4
- package/ecagent/src/runtime/api/pi-messages.ts +0 -436
- package/ecagent/src/runtime/auth/context.ts +0 -45
- package/ecagent/src/runtime/auth/credential-store.ts +0 -47
- package/ecagent/src/runtime/auth/helpers.ts +0 -46
- package/ecagent/src/runtime/auth/resolve.ts +0 -141
- package/ecagent/src/runtime/auth/types.ts +0 -182
- package/ecagent/src/runtime/compat.ts +0 -158
- package/ecagent/src/runtime/index.ts +0 -31
- package/ecagent/src/runtime/models.ts +0 -452
- package/ecagent/src/runtime/oauth.ts +0 -1
- package/ecagent/src/runtime/providers/faux.ts +0 -538
- package/ecagent/src/runtime/types.ts +0 -718
- package/ecagent/src/runtime/utils/diagnostics.ts +0 -45
- package/ecagent/src/runtime/utils/event-stream.ts +0 -88
- package/ecagent/src/runtime/utils/headers.ts +0 -18
- package/ecagent/src/runtime/utils/json-parse.ts +0 -124
- package/ecagent/src/runtime/utils/oauth/types.ts +0 -79
- package/ecagent/src/runtime/utils/overflow.ts +0 -165
- package/ecagent/src/runtime/utils/provider-env.ts +0 -52
- package/ecagent/src/runtime/utils/retry.ts +0 -101
- package/ecagent/src/runtime/utils/typebox-helpers.ts +0 -24
- package/ecagent/src/runtime/utils/validation.ts +0 -310
- package/ecagent/src/types.ts +0 -430
- package/ecagent/tsconfig.build.json +0 -32
package/dist/aun/msg/group.js
CHANGED
|
@@ -5,7 +5,7 @@ import { TextDecoder } from 'util';
|
|
|
5
5
|
import { createShortConnection } from '../rpc/index.js';
|
|
6
6
|
import { getAidStore, loadClient, SLOT } from '../aid/store.js';
|
|
7
7
|
import { uploadFileAndBuildPayload } from './upload.js';
|
|
8
|
-
import { daemonTaskSendIpcTimeoutMs } from './p2p.js';
|
|
8
|
+
import { daemonTaskSendIpcTimeoutMs, resolveAunMessageEncrypt } from './p2p.js';
|
|
9
9
|
import { checkGroupIndex, getGroupIndex } from './group-index.js';
|
|
10
10
|
import { appendMessageLog, buildOutboundEntry, classifyAunPayloadForLog } from '../../core/message/message-log.js';
|
|
11
11
|
import { chatDirPath } from '../../core/session/session-fs-store.js';
|
|
@@ -50,7 +50,7 @@ function groupSendLogMetadata(args, payload, runtimeContext) {
|
|
|
50
50
|
source: (runtimeContext ? 'msg' : 'cli'),
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
function appendGroupSendOutboundLog(args, messageId, payload, runtimeContext) {
|
|
53
|
+
function appendGroupSendOutboundLog(args, messageId, payload, runtimeContext, encrypt = resolveAunMessageEncrypt(args.encrypt)) {
|
|
54
54
|
const log = groupSendLogMetadata(args, payload, runtimeContext);
|
|
55
55
|
const chatDir = chatDirPath(resolvePaths().sessionsDir, 'aun', args.groupId, args.from);
|
|
56
56
|
fs.mkdirSync(chatDir, { recursive: true });
|
|
@@ -63,7 +63,7 @@ function appendGroupSendOutboundLog(args, messageId, payload, runtimeContext) {
|
|
|
63
63
|
groupId: args.groupId,
|
|
64
64
|
msgId: messageId,
|
|
65
65
|
content: log.content,
|
|
66
|
-
encrypt
|
|
66
|
+
encrypt,
|
|
67
67
|
msgType: log.msgType,
|
|
68
68
|
payloadType: log.payloadType,
|
|
69
69
|
payloadSummary: log.payloadSummary,
|
|
@@ -95,7 +95,7 @@ async function tryDaemonGroupSend(args, payload, runtimeContext, file) {
|
|
|
95
95
|
scope: 'group',
|
|
96
96
|
...(payload ? { payload } : { file }),
|
|
97
97
|
mentions: args.mentions,
|
|
98
|
-
encrypt: args.encrypt
|
|
98
|
+
encrypt: args.encrypt,
|
|
99
99
|
thread,
|
|
100
100
|
returnPolicy: args.returnPolicy,
|
|
101
101
|
originSessionId: runtimeContext.sessionId,
|
|
@@ -135,7 +135,7 @@ async function daemonGroupSendResult(args, payload, runtimeContext, result) {
|
|
|
135
135
|
const messageId = result.message_id
|
|
136
136
|
?? (typeof result.message.message_id === 'string' ? result.message.message_id : undefined);
|
|
137
137
|
if (messageId && !result.log_written) {
|
|
138
|
-
appendGroupSendOutboundLog(args, messageId, payload, runtimeContext);
|
|
138
|
+
appendGroupSendOutboundLog(args, messageId, payload, runtimeContext, result.encrypt ?? resolveAunMessageEncrypt(args.encrypt));
|
|
139
139
|
}
|
|
140
140
|
return {
|
|
141
141
|
ok: true,
|
|
@@ -193,12 +193,12 @@ export async function groupSend(args) {
|
|
|
193
193
|
payload.mentions = args.mentions;
|
|
194
194
|
}
|
|
195
195
|
applyGroupRoutingPayloadFields(payload, args, runtimeContext);
|
|
196
|
-
const
|
|
197
|
-
sendParams
|
|
196
|
+
const encrypt = resolveAunMessageEncrypt(args.encrypt);
|
|
197
|
+
const sendParams = { group_id: args.groupId, payload, encrypt };
|
|
198
198
|
const result = await conn.call('group.send', sendParams);
|
|
199
199
|
const messageId = typeof result?.message?.message_id === 'string' ? result.message.message_id : undefined;
|
|
200
200
|
if (messageId)
|
|
201
|
-
appendGroupSendOutboundLog(args, messageId, payload, runtimeContext);
|
|
201
|
+
appendGroupSendOutboundLog(args, messageId, payload, runtimeContext, encrypt);
|
|
202
202
|
return {
|
|
203
203
|
ok: true,
|
|
204
204
|
group_id: result?.group_id ?? args.groupId,
|
|
@@ -954,7 +954,7 @@ async function sendGroupRulesUpdatedNotice(client, args) {
|
|
|
954
954
|
const result = await client.group.send({
|
|
955
955
|
group_id: args.groupId,
|
|
956
956
|
payload,
|
|
957
|
-
encrypt:
|
|
957
|
+
encrypt: resolveAunMessageEncrypt(),
|
|
958
958
|
});
|
|
959
959
|
const message = isRecord(result.message) ? result.message : {};
|
|
960
960
|
const messageId = typeof result.message_id === 'string'
|
package/dist/aun/msg/p2p.js
CHANGED
|
@@ -9,6 +9,7 @@ import { chatDirPath } from '../../core/session/session-fs-store.js';
|
|
|
9
9
|
import { resolvePaths } from '../../paths.js';
|
|
10
10
|
import { ipcQuery } from '../../ipc.js';
|
|
11
11
|
import { AGENT_DELEGATION_TOKEN_ENV } from '../../core/auth/agent-delegation.js';
|
|
12
|
+
import { loadDaemonConfig } from '../../config-store.js';
|
|
12
13
|
const DEFAULT_TASK_EXECUTION_MS = 60 * 60 * 1000;
|
|
13
14
|
const DAEMON_SEND_TIMEOUT_GRACE_MS = 10_000;
|
|
14
15
|
const MAX_TIMER_MS = 2_147_483_647;
|
|
@@ -24,6 +25,11 @@ export function daemonTaskSendIpcTimeoutMs(file = false) {
|
|
|
24
25
|
catch { }
|
|
25
26
|
return Math.min(MAX_TIMER_MS, Math.max(file ? 120_000 : 5_000, executionMs + DAEMON_SEND_TIMEOUT_GRACE_MS));
|
|
26
27
|
}
|
|
28
|
+
export function resolveAunMessageEncrypt(explicit) {
|
|
29
|
+
if (typeof explicit === 'boolean')
|
|
30
|
+
return explicit;
|
|
31
|
+
return loadDaemonConfig().aun?.defaultEncrypt ?? true;
|
|
32
|
+
}
|
|
27
33
|
function buildSimplePayload(body) {
|
|
28
34
|
switch (body.mode) {
|
|
29
35
|
case 'text':
|
|
@@ -113,7 +119,7 @@ async function tryDaemonMsgSend(args, payload, runtimeContext, file) {
|
|
|
113
119
|
to: args.to,
|
|
114
120
|
scope: 'msg',
|
|
115
121
|
...(payload ? { payload } : { file }),
|
|
116
|
-
encrypt: args.encrypt
|
|
122
|
+
encrypt: args.encrypt,
|
|
117
123
|
thread,
|
|
118
124
|
returnPolicy: args.returnPolicy,
|
|
119
125
|
originSessionId: runtimeContext.sessionId,
|
|
@@ -155,7 +161,7 @@ async function daemonMsgSendResult(args, payload, runtimeContext, daemonResult)
|
|
|
155
161
|
payload,
|
|
156
162
|
runtimeContext,
|
|
157
163
|
chatmode: daemonResult.chatmode,
|
|
158
|
-
encrypt: daemonResult.encrypt ?? args.encrypt
|
|
164
|
+
encrypt: daemonResult.encrypt ?? resolveAunMessageEncrypt(args.encrypt),
|
|
159
165
|
});
|
|
160
166
|
}
|
|
161
167
|
return sent;
|
|
@@ -259,9 +265,8 @@ export async function msgSend(args) {
|
|
|
259
265
|
// 5. 写入 payload.thread_id/ref_message_id(如果指定)
|
|
260
266
|
applyRoutingPayloadFields(payload, args, runtimeContext, false);
|
|
261
267
|
applyRoutingPayloadFields(payload, args, runtimeContext);
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
sendParams.encrypt = args.encrypt === true;
|
|
268
|
+
const encrypt = resolveAunMessageEncrypt(args.encrypt);
|
|
269
|
+
const sendParams = { to: args.to, payload, encrypt };
|
|
265
270
|
const result = await conn.call('message.send', sendParams);
|
|
266
271
|
// 5. 写出方向 jsonl(与 daemon 一致格式,标记 source)
|
|
267
272
|
// source 标记:
|
|
@@ -273,7 +278,7 @@ export async function msgSend(args) {
|
|
|
273
278
|
payload,
|
|
274
279
|
runtimeContext,
|
|
275
280
|
chatmode,
|
|
276
|
-
encrypt
|
|
281
|
+
encrypt,
|
|
277
282
|
});
|
|
278
283
|
}
|
|
279
284
|
catch { }
|
package/dist/aun/msg/upload.js
CHANGED
|
@@ -4,37 +4,30 @@ import path from 'path';
|
|
|
4
4
|
import { guessMime, formatSize } from '../../utils/media-cache.js';
|
|
5
5
|
import { inferPayloadType, isValidPayloadType } from './payload-type.js';
|
|
6
6
|
/** 单次上传最大大小(与 daemon sendFile 一致)。 */
|
|
7
|
-
const
|
|
7
|
+
export const MAX_AUN_ATTACHMENT_SIZE = 10 * 1024 * 1024;
|
|
8
8
|
/** server 端 inline 上限错误的识别特征。优先匹配错误消息里的“inline 上限”字样。 */
|
|
9
9
|
function isInlineLimitError(err) {
|
|
10
10
|
const msg = err?.message ?? '';
|
|
11
11
|
return /inline\s*上限|inline limit|create_upload_session/i.test(msg);
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* 策略:先无脑 storage.put_object(内联 base64)。server 报“超过 inline 上限”
|
|
17
|
-
* 时降级到 storage.create_upload_session + HTTP PUT + storage.complete_upload,
|
|
18
|
-
* 此时通过 onProgress 上报字节级进度。
|
|
14
|
+
* 上传内存中的二进制内容并构造发送用的标准附件 payload。
|
|
19
15
|
*/
|
|
20
|
-
export async function
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
23
|
-
throw new Error(
|
|
16
|
+
export async function uploadBufferAndBuildPayload(conn, ownerAid, data, filename, opts) {
|
|
17
|
+
const safeFilename = path.basename(filename.trim());
|
|
18
|
+
if (!safeFilename || safeFilename === '.' || safeFilename === '..') {
|
|
19
|
+
throw new Error('文件名不能为空');
|
|
24
20
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
throw new Error(`文件为空: ${absPath}`);
|
|
21
|
+
if (data.length === 0) {
|
|
22
|
+
throw new Error(`文件为空: ${safeFilename}`);
|
|
28
23
|
}
|
|
29
|
-
if (
|
|
30
|
-
throw new Error(`文件过大 (${formatSize(
|
|
24
|
+
if (data.length > MAX_AUN_ATTACHMENT_SIZE) {
|
|
25
|
+
throw new Error(`文件过大 (${formatSize(data.length)}, 上限 ${formatSize(MAX_AUN_ATTACHMENT_SIZE)}): ${safeFilename}`);
|
|
31
26
|
}
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const objectKey = `shared/${crypto.randomUUID()}/${filename}`;
|
|
37
|
-
const total = stat.size;
|
|
27
|
+
const sha256 = crypto.createHash('sha256').update(data).digest('hex');
|
|
28
|
+
const contentType = opts?.contentType ?? guessMime(safeFilename);
|
|
29
|
+
const objectKey = `shared/${crypto.randomUUID()}/${safeFilename}`;
|
|
30
|
+
const total = data.length;
|
|
38
31
|
const report = (phase, bytes) => opts?.onProgress?.({ phase, bytes, total });
|
|
39
32
|
// 1. 先按 inline 走
|
|
40
33
|
let inlineRejected = false;
|
|
@@ -42,7 +35,7 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
42
35
|
report('inline', 0);
|
|
43
36
|
await conn.call('storage.put_object', {
|
|
44
37
|
object_key: objectKey,
|
|
45
|
-
content:
|
|
38
|
+
content: data.toString('base64'),
|
|
46
39
|
content_type: contentType,
|
|
47
40
|
is_private: false,
|
|
48
41
|
overwrite: true,
|
|
@@ -70,10 +63,9 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
70
63
|
const PROGRESS_TICK_MS = 250;
|
|
71
64
|
let lastBytes = 0;
|
|
72
65
|
const tickerStart = Date.now();
|
|
73
|
-
//
|
|
66
|
+
// 实际上一次性发送;等待响应期间按 2MB/s 估算进度,且不超过 99%。
|
|
74
67
|
const ticker = setInterval(() => {
|
|
75
68
|
const elapsed = Date.now() - tickerStart;
|
|
76
|
-
// 假设 2MB/s 估算;不超过 99%
|
|
77
69
|
const estimated = Math.min(total - 1, Math.floor((elapsed / 1000) * 2 * 1024 * 1024));
|
|
78
70
|
if (estimated > lastBytes) {
|
|
79
71
|
lastBytes = estimated;
|
|
@@ -84,7 +76,7 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
84
76
|
try {
|
|
85
77
|
uploadResp = await fetch(uploadUrl, {
|
|
86
78
|
method: 'PUT',
|
|
87
|
-
body: new Blob([new Uint8Array(
|
|
79
|
+
body: new Blob([new Uint8Array(data)], { type: contentType }),
|
|
88
80
|
headers: { 'Content-Type': contentType },
|
|
89
81
|
});
|
|
90
82
|
}
|
|
@@ -107,12 +99,11 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
107
99
|
const attachment = {
|
|
108
100
|
owner_aid: ownerAid,
|
|
109
101
|
object_key: objectKey,
|
|
110
|
-
filename,
|
|
102
|
+
filename: safeFilename,
|
|
111
103
|
size_bytes: total,
|
|
112
104
|
sha256,
|
|
113
105
|
content_type: contentType,
|
|
114
106
|
};
|
|
115
|
-
// 确定渲染类型
|
|
116
107
|
let type;
|
|
117
108
|
if (opts?.as) {
|
|
118
109
|
if (!isValidPayloadType(opts.as)) {
|
|
@@ -121,7 +112,7 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
121
112
|
type = opts.as;
|
|
122
113
|
}
|
|
123
114
|
else {
|
|
124
|
-
type = inferPayloadType(
|
|
115
|
+
type = inferPayloadType(safeFilename);
|
|
125
116
|
}
|
|
126
117
|
const payload = {
|
|
127
118
|
type,
|
|
@@ -130,8 +121,31 @@ export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts)
|
|
|
130
121
|
if (opts?.text)
|
|
131
122
|
payload.text = opts.text;
|
|
132
123
|
else if (type === 'file')
|
|
133
|
-
payload.text = `📎 ${
|
|
124
|
+
payload.text = `📎 ${safeFilename} (${formatSize(total)})`;
|
|
134
125
|
if (type === 'voice' && opts?.transcript)
|
|
135
126
|
payload.transcript = opts.transcript;
|
|
136
127
|
return { payload, type, attachment };
|
|
137
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* 上传本地文件并构造发送用的 payload。
|
|
131
|
+
*
|
|
132
|
+
* 策略:先无脑 storage.put_object(内联 base64)。server 报“超过 inline 上限”
|
|
133
|
+
* 时降级到 storage.create_upload_session + HTTP PUT + storage.complete_upload,
|
|
134
|
+
* 此时通过 onProgress 上报字节级进度。
|
|
135
|
+
*/
|
|
136
|
+
export async function uploadFileAndBuildPayload(conn, ownerAid, filePath, opts) {
|
|
137
|
+
const absPath = path.resolve(filePath);
|
|
138
|
+
if (!fs.existsSync(absPath)) {
|
|
139
|
+
throw new Error(`文件不存在: ${absPath}`);
|
|
140
|
+
}
|
|
141
|
+
const stat = fs.statSync(absPath);
|
|
142
|
+
if (stat.size === 0) {
|
|
143
|
+
throw new Error(`文件为空: ${absPath}`);
|
|
144
|
+
}
|
|
145
|
+
if (stat.size > MAX_AUN_ATTACHMENT_SIZE) {
|
|
146
|
+
throw new Error(`文件过大 (${formatSize(stat.size)}, 上限 ${formatSize(MAX_AUN_ATTACHMENT_SIZE)}): ${absPath}`);
|
|
147
|
+
}
|
|
148
|
+
const filename = path.basename(absPath);
|
|
149
|
+
const fileData = fs.readFileSync(absPath);
|
|
150
|
+
return uploadBufferAndBuildPayload(conn, ownerAid, fileData, filename, opts);
|
|
151
|
+
}
|
package/dist/aun/outbox.js
CHANGED
|
@@ -59,6 +59,7 @@ export function enqueue(aid, opts) {
|
|
|
59
59
|
payload: opts.payload,
|
|
60
60
|
text: opts.text,
|
|
61
61
|
filePath: opts.filePath,
|
|
62
|
+
image: opts.image,
|
|
62
63
|
logText: opts.logText,
|
|
63
64
|
context: opts.context,
|
|
64
65
|
ttl: opts.ttl ?? DEFAULT_TTL,
|
|
@@ -81,6 +82,16 @@ export function remove(aid, id) {
|
|
|
81
82
|
const entries = readEntries(aid).filter(e => e.id !== id);
|
|
82
83
|
writeEntries(aid, entries);
|
|
83
84
|
}
|
|
85
|
+
/** Replace an existing entry without consuming another outbox slot. */
|
|
86
|
+
export function replace(aid, entry) {
|
|
87
|
+
const entries = readEntries(aid);
|
|
88
|
+
const index = entries.findIndex(candidate => candidate.id === entry.id);
|
|
89
|
+
if (index < 0)
|
|
90
|
+
return false;
|
|
91
|
+
entries[index] = entry;
|
|
92
|
+
writeEntries(aid, entries);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
84
95
|
/** Remove durable interaction cards that were cancelled before delivery. */
|
|
85
96
|
export function removeInteractionCards(aid, requestId) {
|
|
86
97
|
const entries = readEntries(aid);
|
|
@@ -102,7 +113,11 @@ export function cleanup(aid) {
|
|
|
102
113
|
writeEntries(aid, valid);
|
|
103
114
|
return removed;
|
|
104
115
|
}
|
|
105
|
-
|
|
116
|
+
// Each caller gets its own pass over the current disk state. This prevents
|
|
117
|
+
// duplicate sends while allowing a later drain trigger to pick up entries
|
|
118
|
+
// enqueued during an active pass.
|
|
119
|
+
const activeDrainTails = new Map();
|
|
120
|
+
async function drainOnce(aid, sender) {
|
|
106
121
|
const entries = readEntries(aid);
|
|
107
122
|
if (entries.length === 0)
|
|
108
123
|
return { sent: 0, expired: 0, failed: 0 };
|
|
@@ -135,12 +150,40 @@ export async function drain(aid, sender) {
|
|
|
135
150
|
}
|
|
136
151
|
}
|
|
137
152
|
const current = readEntries(aid);
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
const failedById = new Map(remaining.map(entry => [entry.id, entry]));
|
|
154
|
+
const retained = current.flatMap(entry => {
|
|
155
|
+
if (!drainedIds.has(entry.id))
|
|
156
|
+
return [entry];
|
|
157
|
+
const failedEntry = failedById.get(entry.id);
|
|
158
|
+
if (!failedEntry)
|
|
159
|
+
return [];
|
|
160
|
+
return [{
|
|
161
|
+
...failedEntry,
|
|
162
|
+
...entry,
|
|
163
|
+
attempts: failedEntry.attempts,
|
|
164
|
+
lastError: failedEntry.lastError,
|
|
165
|
+
}];
|
|
166
|
+
});
|
|
167
|
+
writeEntries(aid, retained);
|
|
142
168
|
return { sent, expired, failed };
|
|
143
169
|
}
|
|
170
|
+
export async function drain(aid, sender) {
|
|
171
|
+
const previous = activeDrainTails.get(aid);
|
|
172
|
+
let releaseTurn;
|
|
173
|
+
const turn = new Promise(resolve => { releaseTurn = resolve; });
|
|
174
|
+
const tail = (previous ?? Promise.resolve()).then(() => turn);
|
|
175
|
+
activeDrainTails.set(aid, tail);
|
|
176
|
+
if (previous)
|
|
177
|
+
await previous;
|
|
178
|
+
try {
|
|
179
|
+
return await drainOnce(aid, sender);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
releaseTurn();
|
|
183
|
+
if (activeDrainTails.get(aid) === tail)
|
|
184
|
+
activeDrainTails.delete(aid);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
144
187
|
export function hasPending(aid) {
|
|
145
188
|
const file = outboxFile(aid);
|
|
146
189
|
if (!fs.existsSync(file))
|