@axiom-lattice/core 2.1.42 → 2.1.44

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/dist/index.js CHANGED
@@ -6635,10 +6635,10 @@ var InMemoryThreadMessageQueueStore = class {
6635
6635
  return this.messages.get(threadId);
6636
6636
  }
6637
6637
  async addMessage(params) {
6638
- const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command } = params;
6638
+ const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, id } = params;
6639
6639
  const threadMessages = this.getMessagesForThread(threadId);
6640
6640
  const message = {
6641
- id: this.generateId(),
6641
+ id: id || this.generateId(),
6642
6642
  content,
6643
6643
  type,
6644
6644
  sequence: threadMessages.length,
@@ -6652,38 +6652,38 @@ var InMemoryThreadMessageQueueStore = class {
6652
6652
  threadMessages.push(message);
6653
6653
  return message;
6654
6654
  }
6655
- async addMessageAtHead(threadId, content, type = "system") {
6655
+ async addMessageAtHead(threadId, content, type = "system", id, command) {
6656
6656
  const threadMessages = this.getMessagesForThread(threadId);
6657
- threadMessages.forEach((msg) => {
6658
- msg.sequence += 1;
6659
- });
6660
6657
  let tenantId = "default";
6661
6658
  let assistantId = "";
6662
6659
  if (threadMessages.length > 0) {
6663
6660
  tenantId = threadMessages[0].tenantId || "default";
6664
6661
  assistantId = threadMessages[0].assistantId || "";
6665
6662
  }
6663
+ const nextSequence = threadMessages.length;
6666
6664
  const message = {
6667
- id: this.generateId(),
6665
+ id: id || this.generateId(),
6668
6666
  content,
6669
6667
  type,
6670
- sequence: 0,
6668
+ sequence: nextSequence,
6671
6669
  createdAt: /* @__PURE__ */ new Date(),
6672
6670
  status: "pending",
6673
6671
  tenantId,
6674
6672
  assistantId,
6675
- priority: 0
6673
+ priority: 100,
6674
+ // High priority for head messages (STEER/Command)
6675
+ command
6676
6676
  };
6677
- threadMessages.unshift(message);
6677
+ threadMessages.push(message);
6678
6678
  return message;
6679
6679
  }
6680
6680
  async getPendingMessages(threadId) {
6681
6681
  const threadMessages = this.getMessagesForThread(threadId);
6682
- return threadMessages.filter((msg) => msg.status === "pending" || !msg.status).sort((a, b) => a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6682
+ return threadMessages.filter((msg) => msg.status === "pending" || !msg.status).sort((a, b) => (b.priority || 0) - (a.priority || 0) || a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6683
6683
  }
6684
6684
  async getProcessingMessages(threadId) {
6685
6685
  const threadMessages = this.getMessagesForThread(threadId);
6686
- return threadMessages.filter((msg) => msg.status === "processing").sort((a, b) => a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6686
+ return threadMessages.filter((msg) => msg.status === "processing").sort((a, b) => (b.priority || 0) - (a.priority || 0) || a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6687
6687
  }
6688
6688
  async getQueueSize(threadId) {
6689
6689
  const pending = await this.getPendingMessages(threadId);
@@ -6692,11 +6692,11 @@ var InMemoryThreadMessageQueueStore = class {
6692
6692
  async getThreadsWithPendingMessages() {
6693
6693
  const result = [];
6694
6694
  for (const [threadId, messages] of this.messages.entries()) {
6695
- const pendingMessages = messages.filter(
6696
- (msg) => msg.status === "pending" || !msg.status
6695
+ const pendingOrProcessingMessages = messages.filter(
6696
+ (msg) => msg.status === "pending" || msg.status === "processing" || !msg.status
6697
6697
  );
6698
- if (pendingMessages.length > 0) {
6699
- const firstMessage = pendingMessages[0];
6698
+ if (pendingOrProcessingMessages.length > 0) {
6699
+ const firstMessage = pendingOrProcessingMessages[0];
6700
6700
  result.push({
6701
6701
  tenantId: firstMessage.tenantId || "default",
6702
6702
  assistantId: firstMessage.assistantId || "",
@@ -6746,6 +6746,20 @@ var InMemoryThreadMessageQueueStore = class {
6746
6746
  this.messages.set(threadId, filtered);
6747
6747
  }
6748
6748
  }
6749
+ async resetProcessingToPending(threadId) {
6750
+ const messages = this.messages.get(threadId);
6751
+ if (!messages) {
6752
+ return 0;
6753
+ }
6754
+ let count = 0;
6755
+ for (const msg of messages) {
6756
+ if (msg.status === "processing") {
6757
+ msg.status = "pending";
6758
+ count++;
6759
+ }
6760
+ }
6761
+ return count;
6762
+ }
6749
6763
  };
6750
6764
 
6751
6765
  // src/store_lattice/StoreLatticeManager.ts
@@ -10760,6 +10774,9 @@ function createTaskTool(options) {
10760
10774
  }
10761
10775
  return returnCommandWithStateUpdate(result, config.toolCall.id);
10762
10776
  } catch (error) {
10777
+ if (error instanceof import_langgraph7.GraphInterrupt) {
10778
+ throw error;
10779
+ }
10763
10780
  return new import_langgraph7.Command({
10764
10781
  update: {
10765
10782
  messages: [
@@ -14105,7 +14122,7 @@ var AgentParamsBuilder = class {
14105
14122
  * @param options build options
14106
14123
  * @returns Agent build parameters
14107
14124
  */
14108
- buildParams(agentLattice, options) {
14125
+ async buildParams(agentLattice, options) {
14109
14126
  const skills = (0, import_protocols4.isDeepAgentConfig)(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
14110
14127
  const toolKeys = options?.overrideTools || (0, import_protocols4.getToolsFromConfig)(agentLattice.config);
14111
14128
  const tools = toolKeys.map((toolKey) => {
@@ -14125,8 +14142,8 @@ var AgentParamsBuilder = class {
14125
14142
  throw new Error(`Model "${modelKey}" does not exist`);
14126
14143
  }
14127
14144
  const subAgentKeys = (0, import_protocols4.getSubAgentsFromConfig)(agentLattice.config);
14128
- const subAgents = subAgentKeys.map((agentKey) => {
14129
- const subAgentLattice = this.getAgentLatticeFunc(agentKey);
14145
+ const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
14146
+ const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
14130
14147
  if (!subAgentLattice) {
14131
14148
  throw new Error(`SubAgent "${agentKey}" does not exist`);
14132
14149
  }
@@ -14135,7 +14152,7 @@ var AgentParamsBuilder = class {
14135
14152
  config: subAgentLattice.config,
14136
14153
  client: subAgentLattice.client
14137
14154
  };
14138
- });
14155
+ }));
14139
14156
  let internalSubAgents = [];
14140
14157
  if ((0, import_protocols4.isDeepAgentConfig)(agentLattice.config)) {
14141
14158
  internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
@@ -14213,7 +14230,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14213
14230
  }
14214
14231
  const config = assistantToConfig(assistant);
14215
14232
  const agentLattice = {
14216
- config,
14233
+ config: { ...config, tenantId },
14217
14234
  client: void 0
14218
14235
  };
14219
14236
  return agentLattice;
@@ -14520,13 +14537,13 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14520
14537
  * @param options 构建选项
14521
14538
  * @returns 返回Agent构建参数
14522
14539
  */
14523
- buildAgentParams(agentLattice, options) {
14540
+ async buildAgentParams(agentLattice, options) {
14524
14541
  const tenantId = agentLattice.config.tenantId || "default";
14525
- const paramsBuilder = new AgentParamsBuilder((key) => {
14526
- this.initializeClient(tenantId, key);
14542
+ const paramsBuilder = new AgentParamsBuilder(async (key) => {
14543
+ await this.initializeClientAsync(tenantId, key);
14527
14544
  return this.getAgentLatticeWithTenant(tenantId, key);
14528
14545
  });
14529
- const params = paramsBuilder.buildParams(agentLattice, options);
14546
+ const params = await paramsBuilder.buildParams(agentLattice, options);
14530
14547
  return {
14531
14548
  ...params,
14532
14549
  tenantId
@@ -14547,7 +14564,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14547
14564
  };
14548
14565
  const factory = AgentGraphBuilderFactory.getInstance();
14549
14566
  const builder = factory.getBuilder(resolvedConfig.type);
14550
- const params = this.buildAgentParams(resolvedLattice, options);
14567
+ const params = await this.buildAgentParams(resolvedLattice, options);
14551
14568
  return await builder.build(resolvedLattice, params);
14552
14569
  }
14553
14570
  /**
@@ -16962,7 +16979,7 @@ var Agent = class {
16962
16979
  command,
16963
16980
  custom_run_config
16964
16981
  }, signal) => {
16965
- const runnable_agent = await getAgentClient(this.tenant_id, this.assistant_id);
16982
+ const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
16966
16983
  const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
16967
16984
  const { messages, ...rest } = input;
16968
16985
  const lifecycleManager = this;
@@ -17082,27 +17099,30 @@ var Agent = class {
17082
17099
  break;
17083
17100
  }
17084
17101
  const firstMessage = pendings[0];
17085
- const hasCommand = firstMessage.content?.command;
17102
+ const hasCommand = firstMessage.command;
17086
17103
  if (hasCommand) {
17087
17104
  for (const p of pendings) {
17088
17105
  if (signal?.aborted) break;
17089
- if (!p.content?.command) break;
17106
+ if (!p.command) break;
17090
17107
  await this.queueStore?.markProcessing(p.id);
17091
17108
  const startTime = Date.now();
17092
17109
  this.publish("message:started", {
17093
17110
  type: "message:started",
17094
- messageId: p.content.id,
17095
- messageContent: p.content.message,
17111
+ messageId: this.getHumanPendingContent(p).id,
17112
+ messageContent: this.getHumanPendingContent(p).message,
17096
17113
  timestamp: /* @__PURE__ */ new Date(),
17097
17114
  queueMode: this.queueMode.mode
17098
17115
  });
17116
+ const humanContent = p.content;
17099
17117
  const input = {
17100
- messages: [new import_langchain61.HumanMessage({ id: p.content.id, content: p.content.message })]
17118
+ messages: [new import_langchain61.HumanMessage({ id: humanContent.id, content: humanContent.message })]
17101
17119
  };
17120
+ const queueMessageData = humanContent.queueMessage;
17102
17121
  try {
17103
17122
  await this.agentStreamExecutor({
17104
17123
  input,
17105
- command: p.content.command
17124
+ command: p.command,
17125
+ custom_run_config: queueMessageData.custom_run_config
17106
17126
  }, signal);
17107
17127
  await this.queueStore?.markCompleted(p.id);
17108
17128
  const runStatus = await this.getRunStatus();
@@ -17110,7 +17130,7 @@ var Agent = class {
17110
17130
  if (runStatus === "interrupted" /* INTERRUPTED */) {
17111
17131
  this.publish("message:interrupted", {
17112
17132
  type: "message:interrupted",
17113
- messageId: p.content.id,
17133
+ messageId: humanContent.id,
17114
17134
  timestamp: /* @__PURE__ */ new Date(),
17115
17135
  duration: Date.now() - startTime,
17116
17136
  state
@@ -17119,13 +17139,13 @@ var Agent = class {
17119
17139
  this.addChunk({
17120
17140
  type: "message_completed",
17121
17141
  data: {
17122
- id: p.content.id,
17142
+ id: humanContent.id,
17123
17143
  content: ""
17124
17144
  }
17125
17145
  });
17126
17146
  this.publish("message:completed", {
17127
17147
  type: "message:completed",
17128
- messageId: p.content.id,
17148
+ messageId: humanContent.id,
17129
17149
  timestamp: /* @__PURE__ */ new Date(),
17130
17150
  duration: Date.now() - startTime,
17131
17151
  state
@@ -17136,13 +17156,13 @@ var Agent = class {
17136
17156
  this.addChunk({
17137
17157
  type: "message_failed",
17138
17158
  data: {
17139
- id: p.content.id,
17159
+ id: humanContent.id,
17140
17160
  content: error instanceof Error ? error.message : String(error)
17141
17161
  }
17142
17162
  });
17143
17163
  this.publish("message:failed", {
17144
17164
  type: "message:failed",
17145
- messageId: p.content.id,
17165
+ messageId: humanContent.id,
17146
17166
  error: error instanceof Error ? error.message : String(error),
17147
17167
  timestamp: /* @__PURE__ */ new Date()
17148
17168
  });
@@ -17157,17 +17177,22 @@ var Agent = class {
17157
17177
  const startTime = Date.now();
17158
17178
  remainingPendings.forEach((p) => {
17159
17179
  this.queueStore?.markProcessing(p.id);
17160
- userMessages.push(new import_langchain61.HumanMessage({ id: p.content.id, content: p.content.message }));
17180
+ const humanContent = p.content;
17181
+ userMessages.push(new import_langchain61.HumanMessage({ id: humanContent.id, content: humanContent.message }));
17161
17182
  this.publish("message:started", {
17162
17183
  type: "message:started",
17163
- messageId: p.content.id,
17164
- messageContent: p.content.message,
17184
+ messageId: humanContent.id,
17185
+ messageContent: humanContent.message,
17165
17186
  timestamp: /* @__PURE__ */ new Date(),
17166
17187
  queueMode: "collect" /* COLLECT */
17167
17188
  });
17168
17189
  });
17190
+ const firstQueueMessage = remainingPendings[0] ? this.getHumanPendingContent(remainingPendings[0]).queueMessage : void 0;
17169
17191
  try {
17170
- await this.agentStreamExecutor({ input: { messages: userMessages } }, signal);
17192
+ await this.agentStreamExecutor({
17193
+ input: { messages: userMessages },
17194
+ custom_run_config: firstQueueMessage?.custom_run_config
17195
+ }, signal);
17171
17196
  const runStatus = await this.getRunStatus();
17172
17197
  const state = await this.getCurrentState();
17173
17198
  for (const p of remainingPendings) {
@@ -17220,24 +17245,29 @@ var Agent = class {
17220
17245
  for (const p of remainingPendings) {
17221
17246
  if (signal?.aborted) break;
17222
17247
  await this.queueStore?.markProcessing(p.id);
17223
- const message = new import_langchain61.HumanMessage({ id: p.id, content: p.content.message });
17248
+ const humanContent = p.content;
17249
+ const message = new import_langchain61.HumanMessage({ id: humanContent.id, content: humanContent.message });
17224
17250
  const startTime = Date.now();
17225
17251
  this.publish("message:started", {
17226
17252
  type: "message:started",
17227
- messageId: p.content.id,
17228
- messageContent: p.content.message,
17253
+ messageId: humanContent.id,
17254
+ messageContent: humanContent.message,
17229
17255
  timestamp: /* @__PURE__ */ new Date(),
17230
17256
  queueMode: "followup" /* FOLLOWUP */
17231
17257
  });
17258
+ const queueMessageData = humanContent.queueMessage || {};
17232
17259
  try {
17233
- await this.agentStreamExecutor({ input: { messages: [message] } }, signal);
17260
+ await this.agentStreamExecutor({
17261
+ input: { messages: [message] },
17262
+ custom_run_config: queueMessageData.custom_run_config
17263
+ }, signal);
17234
17264
  await this.queueStore?.markCompleted(p.id);
17235
17265
  const runStatus = await this.getRunStatus();
17236
17266
  const state = await this.getCurrentState();
17237
17267
  if (runStatus === "interrupted" /* INTERRUPTED */) {
17238
17268
  this.publish("message:interrupted", {
17239
17269
  type: "message:interrupted",
17240
- messageId: p.content.id,
17270
+ messageId: humanContent.id,
17241
17271
  timestamp: /* @__PURE__ */ new Date(),
17242
17272
  duration: Date.now() - startTime,
17243
17273
  state
@@ -17246,13 +17276,13 @@ var Agent = class {
17246
17276
  this.addChunk({
17247
17277
  type: "message_completed",
17248
17278
  data: {
17249
- id: p.content.id,
17279
+ id: humanContent.id,
17250
17280
  content: ""
17251
17281
  }
17252
17282
  });
17253
17283
  this.publish("message:completed", {
17254
17284
  type: "message:completed",
17255
- messageId: p.content.id,
17285
+ messageId: humanContent.id,
17256
17286
  timestamp: /* @__PURE__ */ new Date(),
17257
17287
  duration: Date.now() - startTime,
17258
17288
  state
@@ -17263,13 +17293,13 @@ var Agent = class {
17263
17293
  this.addChunk({
17264
17294
  type: "message_failed",
17265
17295
  data: {
17266
- id: p.content.id,
17296
+ id: humanContent.id,
17267
17297
  content: error instanceof Error ? error.message : String(error)
17268
17298
  }
17269
17299
  });
17270
17300
  this.publish("message:failed", {
17271
17301
  type: "message:failed",
17272
- messageId: p.content.id,
17302
+ messageId: humanContent.id,
17273
17303
  error: error instanceof Error ? error.message : String(error),
17274
17304
  timestamp: /* @__PURE__ */ new Date()
17275
17305
  });
@@ -17287,6 +17317,12 @@ var Agent = class {
17287
17317
  this.project_id = project_id;
17288
17318
  this.custom_run_config = custom_run_config;
17289
17319
  }
17320
+ getHumanPendingContent(message) {
17321
+ if (typeof message.content === "string" || !message.content || !("id" in message.content) || !("message" in message.content)) {
17322
+ throw new Error(`Expected human pending message content for message ${message.id}`);
17323
+ }
17324
+ return message.content;
17325
+ }
17290
17326
  /**
17291
17327
  * Initialize with message queue store
17292
17328
  */
@@ -17401,7 +17437,7 @@ var Agent = class {
17401
17437
  */
17402
17438
  async addMessage(queueMessage, mode) {
17403
17439
  const useMode = mode ?? this.queueMode.mode;
17404
- const messageId = (0, import_uuid2.v4)();
17440
+ const messageId = queueMessage.input.id || (0, import_uuid2.v4)();
17405
17441
  const isHighPriority = useMode === "steer" /* STEER */ || !!queueMessage.command;
17406
17442
  const store = this.getQueueStore();
17407
17443
  const currentSize = await store.getQueueSize(this.thread_id);
@@ -17411,20 +17447,30 @@ var Agent = class {
17411
17447
  }
17412
17448
  const content = {
17413
17449
  message: queueMessage.input.message,
17414
- id: messageId
17450
+ id: messageId,
17451
+ // Store complete queue message data for recovery
17452
+ queueMessage: {
17453
+ input: queueMessage.input,
17454
+ command: queueMessage.command,
17455
+ custom_run_config: queueMessage.custom_run_config
17456
+ }
17415
17457
  };
17416
- if (queueMessage.command) {
17417
- content.command = queueMessage.command;
17418
- }
17419
17458
  if (isHighPriority) {
17420
- await store.addMessageAtHead(this.thread_id, content, "human");
17459
+ await store.addMessageAtHead(this.thread_id, content, "human", messageId, queueMessage.command);
17460
+ if (useMode === "steer" /* STEER */) {
17461
+ this.stopQueueProcessor();
17462
+ await store.resetProcessingToPending(this.thread_id);
17463
+ console.log(`[Agent] STEER mode: stopped current processing, reset queue, message ${messageId} will execute next`);
17464
+ }
17421
17465
  } else {
17422
17466
  await store.addMessage({
17423
17467
  threadId: this.thread_id,
17424
17468
  tenantId: this.tenant_id,
17425
17469
  assistantId: this.assistant_id,
17426
17470
  content,
17427
- type: "human"
17471
+ type: "human",
17472
+ command: queueMessage.command,
17473
+ id: messageId
17428
17474
  });
17429
17475
  }
17430
17476
  this.startQueueProcessorIfNeeded().catch((err) => {
@@ -17443,7 +17489,7 @@ var Agent = class {
17443
17489
  }
17444
17490
  /**
17445
17491
  * Start queue processor if not already running
17446
- * Private method used internally by addMessage
17492
+ * Public method to allow external triggering (e.g., from recovery)
17447
17493
  */
17448
17494
  async startQueueProcessorIfNeeded() {
17449
17495
  const store = this.getQueueStore();
@@ -17457,7 +17503,7 @@ var Agent = class {
17457
17503
  this.publish("thread:busy", {
17458
17504
  type: "thread:busy",
17459
17505
  timestamp: /* @__PURE__ */ new Date(),
17460
- messageId: firstMessage?.content?.id
17506
+ messageId: firstMessage ? this.getHumanPendingContent(firstMessage).id : void 0
17461
17507
  });
17462
17508
  this.waitingForQueueEnd(this.abortController.signal).catch((error) => {
17463
17509
  console.error(`Queue processing error for thread ${this.thread_id}:`, error);
@@ -17531,6 +17577,30 @@ var Agent = class {
17531
17577
  }
17532
17578
  return "idle" /* IDLE */;
17533
17579
  }
17580
+ /**
17581
+ * Resume task processing after server restart
17582
+ * Resets any stuck processing messages to pending and starts queue processing
17583
+ * Note: Does not rely on LangGraph state as it may be stale after crash/restart
17584
+ */
17585
+ async resumeTask() {
17586
+ try {
17587
+ await agentLatticeManager.initializeClientAsync(this.tenant_id, this.assistant_id);
17588
+ } catch (error) {
17589
+ console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
17590
+ throw error;
17591
+ }
17592
+ const runStatus = await this.getRunStatus();
17593
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
17594
+ console.log(`[Agent] Skipping resume for ${this.assistant_id} (tenant: ${this.tenant_id}) - agent is in interrupted state`);
17595
+ return;
17596
+ }
17597
+ const store = this.getQueueStore();
17598
+ const resetCount = await store.resetProcessingToPending(this.thread_id);
17599
+ if (resetCount > 0) {
17600
+ console.log(`[Agent] Reset ${resetCount} processing messages to pending for thread ${this.thread_id}`);
17601
+ }
17602
+ await this.startQueueProcessorIfNeeded();
17603
+ }
17534
17604
  /**
17535
17605
  * Abort the current agent execution
17536
17606
  * This will cancel any ongoing invoke or stream operations
@@ -17640,6 +17710,57 @@ var AgentInstanceManager = class _AgentInstanceManager {
17640
17710
  });
17641
17711
  this.agents.clear();
17642
17712
  }
17713
+ /**
17714
+ * Restore agent instances for threads with pending messages after server restart
17715
+ * Queries the message queue store for threads with pending/processing messages
17716
+ * and recreates agent instances to resume processing
17717
+ */
17718
+ async restore() {
17719
+ const stats = { restored: 0, errors: 0 };
17720
+ try {
17721
+ const queueStoreLattice = storeLatticeManager.getStoreLattice("default", "threadMessageQueue");
17722
+ const queueStore = queueStoreLattice.store;
17723
+ const threadsWithPending = await queueStore.getThreadsWithPendingMessages();
17724
+ if (threadsWithPending.length === 0) {
17725
+ console.log("[AgentInstanceManager] No threads with pending messages found");
17726
+ return stats;
17727
+ }
17728
+ console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
17729
+ for (const threadInfo of threadsWithPending) {
17730
+ try {
17731
+ await this.restoreThread(threadInfo, queueStore);
17732
+ stats.restored++;
17733
+ } catch (error) {
17734
+ console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
17735
+ stats.errors++;
17736
+ }
17737
+ }
17738
+ console.log(`[AgentInstanceManager] Restore complete: ${stats.restored} restored, ${stats.errors} errors`);
17739
+ return stats;
17740
+ } catch (error) {
17741
+ console.error("[AgentInstanceManager] Restore failed:", error);
17742
+ throw error;
17743
+ }
17744
+ }
17745
+ /**
17746
+ * Restore a single thread
17747
+ * Delegates actual recovery logic to Agent.resumeTask()
17748
+ */
17749
+ async restoreThread(threadInfo, queueStore) {
17750
+ const { tenantId, assistantId, threadId } = threadInfo;
17751
+ const threadParams = {
17752
+ tenant_id: tenantId,
17753
+ assistant_id: assistantId,
17754
+ thread_id: threadId,
17755
+ workspace_id: "default",
17756
+ // TODO: Get from thread store
17757
+ project_id: "default"
17758
+ // TODO: Get from thread store
17759
+ };
17760
+ const agent = this.getAgent(threadParams);
17761
+ await agent.resumeTask();
17762
+ console.log(`[AgentInstanceManager] Restored thread ${threadId}`);
17763
+ }
17643
17764
  };
17644
17765
  var agentInstanceManager = AgentInstanceManager.getInstance();
17645
17766