@evomap/evolver-proxy 2.0.0-beta.9 → 2.0.1

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.
Files changed (59) hide show
  1. package/dist/bin/evolver-proxy.d.ts +26 -2
  2. package/dist/bin/evolver-proxy.js +284 -51
  3. package/dist/daemon/atpConsent.js +5 -2
  4. package/dist/daemon/collaborationFacade.js +23 -13
  5. package/dist/daemon/proxyDaemon.d.ts +52 -0
  6. package/dist/daemon/proxyDaemon.js +1067 -24
  7. package/dist/daemon/publishRecallVerifier.d.ts +114 -0
  8. package/dist/daemon/publishRecallVerifier.js +495 -0
  9. package/dist/daemon/selectHub.js +5 -3
  10. package/dist/daemon/systemdNotifier.d.ts +46 -0
  11. package/dist/daemon/systemdNotifier.js +153 -0
  12. package/dist/index.d.ts +4 -1
  13. package/dist/index.js +4 -1
  14. package/dist/lifecycle/claimNudge.d.ts +20 -0
  15. package/dist/lifecycle/claimNudge.js +1 -0
  16. package/dist/lifecycle/deployGuard.js +1 -53
  17. package/dist/lifecycle/legacyNodeId.js +1 -178
  18. package/dist/lifecycle/manager.d.ts +4 -0
  19. package/dist/lifecycle/manager.js +1 -390
  20. package/dist/llm/bodyCapture.js +1 -293
  21. package/dist/llm/index.js +1 -3
  22. package/dist/llm/server.js +1 -359
  23. package/dist/llm/traceBackfill.js +1 -525
  24. package/dist/llm/traceConfig.js +1 -44
  25. package/dist/llm/traceControl.js +1 -85
  26. package/dist/llm/traceEnvelope.js +1 -286
  27. package/dist/llm/traceSink.js +1 -278
  28. package/dist/llm/traceUploadPayload.js +1 -27
  29. package/dist/llm/upstream.d.ts +5 -1
  30. package/dist/llm/upstream.js +1 -491
  31. package/dist/private/accountAssetCompatibility.d.ts +29 -0
  32. package/dist/private/accountAssetCompatibility.js +196 -0
  33. package/dist/private/adapterLoader.d.ts +21 -1
  34. package/dist/private/adapterLoader.js +242 -7
  35. package/dist/private/nodeCredentialStore.d.ts +23 -0
  36. package/dist/private/nodeCredentialStore.js +210 -0
  37. package/dist/router/cachePassthrough.js +1 -13
  38. package/dist/router/features.js +1 -52
  39. package/dist/router/index.js +1 -6
  40. package/dist/router/messagesRoute.js +1 -809
  41. package/dist/router/modelRouter.js +1 -66
  42. package/dist/router/providerRoutes.js +1 -1579
  43. package/dist/router/sseScan.js +1 -543
  44. package/dist/selfUpdate/bootstrap.d.ts +69 -0
  45. package/dist/selfUpdate/bootstrap.js +282 -0
  46. package/dist/selfUpdate/builtinKey.d.ts +4 -0
  47. package/dist/selfUpdate/builtinKey.js +16 -0
  48. package/dist/selfUpdate/executor.d.ts +1 -1
  49. package/dist/selfUpdate/executor.js +1 -1
  50. package/dist/selfUpdate/failureCodes.d.ts +4 -0
  51. package/dist/selfUpdate/failureCodes.js +7 -0
  52. package/dist/selfUpdate/migration.d.ts +93 -0
  53. package/dist/selfUpdate/migration.js +315 -0
  54. package/dist/selfUpdate/policy.d.ts +19 -2
  55. package/dist/selfUpdate/policy.js +82 -2
  56. package/dist/selfUpdate/releaseBinary.js +4 -1
  57. package/dist/sync/engine.d.ts +12 -0
  58. package/dist/sync/engine.js +1 -505
  59. package/package.json +7 -4
@@ -353,16 +353,19 @@ export class CollaborationFacade {
353
353
  async mailboxPoll(ctx) {
354
354
  const body = asRecord(await ctx.readJson());
355
355
  const type = optionalString(body['type']);
356
- const direction = optionalDirection(body['direction']);
356
+ const channel = optionalString(body['channel']);
357
+ const direction = optionalDirection(body['direction']) ?? 'inbound';
357
358
  const limit = boundedMailboxPollLimit(body['limit']);
358
- const messages = this.deps.store.list({
359
- status: 'pending',
360
- runtimeNamespace: this.deps.runtimeNamespace ?? 'default',
361
- ...(type ? { type } : {}),
362
- ...(direction ? { direction } : {}),
363
- limit,
364
- })
365
- .map((message) => TASK_RESULT_TYPES.has(message.type) ? v1Message(message) : message);
359
+ const runtimeNamespace = legacyMailboxRuntimeNamespace(channel, this.deps.runtimeNamespace ?? 'default');
360
+ const messages = runtimeNamespace === undefined
361
+ ? []
362
+ : this.deps.store.list({
363
+ status: 'pending',
364
+ runtimeNamespace,
365
+ ...(type ? { type } : {}),
366
+ direction,
367
+ limit,
368
+ }).map(v1Message);
366
369
  ctx.json(200, { messages, count: messages.length });
367
370
  return true;
368
371
  }
@@ -671,18 +674,19 @@ function v1Message(message) {
671
674
  return {
672
675
  id: message.id,
673
676
  message_id: message.id,
674
- channel: 'evomap-hub',
677
+ channel: message.runtimeNamespace === 'default' ? 'evomap-hub' : message.runtimeNamespace,
675
678
  direction: message.direction,
676
679
  type: message.type === 'dm_outbound' || isDirectDialogMessage(message) ? 'dm' : message.type,
677
680
  status: message.status === 'done' ? (message.direction === 'inbound' ? 'delivered' : 'synced') : message.status,
678
681
  payload: message.payload,
679
- priority: 'normal',
680
- ref_id: message.replyTo,
682
+ priority: message.priority,
683
+ ref_id: message.replyTo ?? message.correlationId,
681
684
  created_at: message.createdAt,
682
685
  synced_at: message.status === 'done' ? message.updatedAt : null,
683
686
  expires_at: message.ttlAt,
684
687
  retry_count: message.attempts,
685
- error: null,
688
+ next_retry_at: message.nextRetryAt,
689
+ error: message.lastError,
686
690
  };
687
691
  }
688
692
  function writeOperationError(ctx, error) {
@@ -794,6 +798,12 @@ function optionalString(value) {
794
798
  function optionalDirection(value) {
795
799
  return value === 'inbound' || value === 'outbound' || value === 'local' ? value : undefined;
796
800
  }
801
+ function legacyMailboxRuntimeNamespace(requestedChannel, runtimeNamespace) {
802
+ if (requestedChannel === undefined || requestedChannel === 'evomap-hub' || requestedChannel === runtimeNamespace) {
803
+ return runtimeNamespace;
804
+ }
805
+ return undefined;
806
+ }
797
807
  function requiredValue(record, ...keys) {
798
808
  for (const key of keys) {
799
809
  const value = optionalString(record[key]);
@@ -3,11 +3,14 @@ import { SyncEngine, type OutboundResult, type InboundResult } from '../sync/eng
3
3
  import { LifecycleManager, type HelloLifecycleMode, type HelloResult, type HeartbeatOptions, type HeartbeatResult, type HeartbeatTickResult } from '../lifecycle/manager.js';
4
4
  import { type SelfUpdateDeps } from '../selfUpdate/executor.js';
5
5
  import type { AtpOrderConsentGate } from './atpConsent.js';
6
+ import { type PublishRecallVerifierPort } from './publishRecallVerifier.js';
6
7
  type HubCapability = hubNs.HubCapability;
7
8
  type AssetStoreProvider = assetstore.AssetStoreProvider;
8
9
  export declare const DEFAULT_IPC_PORT = 19820;
9
10
  export interface ProxyDaemonDeps {
10
11
  hub: HubCapability;
12
+ /** Immutable Hub selection for IPC callers that must fail closed across public/private runtimes. */
13
+ hubMode?: 'public' | 'private';
11
14
  /** 二选一: 传 storePath 让 ProxyDaemon 建 store, 或传已建 store(供 hub senderId 共享同一 node_id). */
12
15
  storePath?: string;
13
16
  store?: mailbox.MailboxStore;
@@ -16,6 +19,16 @@ export interface ProxyDaemonDeps {
16
19
  ipcHost?: string;
17
20
  runtimeNamespace?: string;
18
21
  now?: () => number;
22
+ /** Hub lifecycle heartbeat cadence. LifecycleManager applies its 30s safety floor and backoff policy. */
23
+ heartbeatIntervalMs?: number;
24
+ /** Remote asset-search cache TTL. Local asset-store reads are never cached. */
25
+ assetSearchCacheTtlMs?: number;
26
+ /** Maximum number of remote asset-search results cached by this daemon. */
27
+ assetSearchCacheMax?: number;
28
+ /** Time after cache expiry during which a rate-limited search may serve stale remote results. */
29
+ assetSearchStaleGraceMs?: number;
30
+ /** Maximum time the compatibility HTTP request waits before returning a durable pending receipt. */
31
+ assetSubmitResponseTimeoutMs?: number;
19
32
  /** Random source for heartbeat force_update staggering. Defaults to Math.random; tests inject a deterministic value. */
20
33
  random?: () => number;
21
34
  /** 注入 adapter 的 /a2a/hello + heartbeat wire 调用(M6-6 提供; M6-4 测试用 fake). evolverVersion 随报供 hub 观测. */
@@ -58,6 +71,10 @@ export interface ProxyDaemonDeps {
58
71
  };
59
72
  /** V1 collaboration task operations are synchronous; tests may shorten the Hub timeout. */
60
73
  collaborationOperationTimeoutMs?: number;
74
+ /** Optional test/composition seam. Production defaults to the restart-safe verifier backed by this daemon's store. */
75
+ publishRecallVerifier?: PublishRecallVerifierPort;
76
+ /** Optional deterministic sanitizer environment for composition tests. Production omits this to scan process.env. */
77
+ publishSanitizeEnv?: Record<string, string | undefined>;
61
78
  }
62
79
  export interface ProxyTickReport {
63
80
  outbound: OutboundResult;
@@ -75,8 +92,12 @@ export interface ProxyTickError {
75
92
  export interface ProxyHealth {
76
93
  running: boolean;
77
94
  ipcListening: boolean;
95
+ lifecycleArmed: boolean;
78
96
  nodeId?: string;
79
97
  lastWriteAt: number;
98
+ lastTickAt?: number;
99
+ nextTickDueAt?: number;
100
+ consecutiveFailures: number;
80
101
  }
81
102
  export interface AtpProxyClient {
82
103
  placeOrder(opts: {
@@ -121,9 +142,21 @@ export declare class ProxyDaemon {
121
142
  private readonly validator;
122
143
  private readonly atp;
123
144
  private readonly collaborationFacade;
145
+ private readonly publishRecallVerifier;
146
+ private readonly proxyHandler;
124
147
  private ipc;
125
148
  private readonly now;
126
149
  private readonly random;
150
+ private readonly assetSearchCacheTtlMs;
151
+ private readonly assetSearchCacheMax;
152
+ private readonly assetSearchStaleGraceMs;
153
+ private readonly assetSubmitResponseTimeoutMs;
154
+ private readonly synchronousAssetSubmitScope;
155
+ private readonly shadowMode;
156
+ private readonly assetSearchCache;
157
+ private readonly assetSearchInflight;
158
+ private readonly synchronousAssetSubmitInflight;
159
+ private assetSearchCooldownUntil;
127
160
  private nextHeartbeatAt;
128
161
  private heartbeatFailures;
129
162
  private heartbeatGeneration;
@@ -132,6 +165,10 @@ export declare class ProxyDaemon {
132
165
  /** A poke that arrived between ticks (no sleep in flight) parks the wake here so it is not lost. */
133
166
  private wakeRunnerPending;
134
167
  private started;
168
+ private lifecycleArmed;
169
+ private lastTickAt;
170
+ private nextTickDueAt;
171
+ private consecutiveTickFailures;
135
172
  private storeClosed;
136
173
  private forceUpdateTriggerInFlight;
137
174
  private forceUpdateLastTriggeredAt;
@@ -157,6 +194,7 @@ export declare class ProxyDaemon {
157
194
  /** 下一轮建议延时: inbound 背压/idle 与 outbound pending cadence 取更快者. */
158
195
  nextDelay(last: InboundResult): number;
159
196
  setWakeHandler(wake: (() => void) | undefined): void;
197
+ setExpectedNextTick(delayMs: number | undefined): void;
160
198
  notifyNewOutbound(): void;
161
199
  /**
162
200
  * Expedite the next heartbeat: clear the failure backoff, mark the heartbeat due now, and wake an
@@ -189,6 +227,20 @@ export declare class ProxyDaemon {
189
227
  private stateNumber;
190
228
  private handleProxyRoute;
191
229
  private searchAssets;
230
+ private searchRemoteAssets;
231
+ private cacheRemoteAssetSearch;
232
+ private publishAssetSubmitSynchronously;
233
+ private createSynchronousAssetSubmitEnvelope;
234
+ private currentHubMode;
235
+ private handleHubModeBoundOutbound;
236
+ private publishSynchronousBundle;
237
+ private waitForSynchronousAssetSubmit;
238
+ private executeSynchronousAssetSubmit;
239
+ private handleSynchronousProxyOutbound;
240
+ private readSynchronousAssetSubmitOutcome;
241
+ private cacheSynchronousAssetSubmitSuccess;
242
+ private cacheSynchronousAssetSubmitTerminal;
243
+ private writeSynchronousAssetSubmitOutcome;
192
244
  private handleAtpRoute;
193
245
  private writeAtpJson;
194
246
  }