@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.mjs CHANGED
@@ -6452,10 +6452,10 @@ var InMemoryThreadMessageQueueStore = class {
6452
6452
  return this.messages.get(threadId);
6453
6453
  }
6454
6454
  async addMessage(params) {
6455
- const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command } = params;
6455
+ const { threadId, tenantId, assistantId, content, type = "human", priority = 0, command, id } = params;
6456
6456
  const threadMessages = this.getMessagesForThread(threadId);
6457
6457
  const message = {
6458
- id: this.generateId(),
6458
+ id: id || this.generateId(),
6459
6459
  content,
6460
6460
  type,
6461
6461
  sequence: threadMessages.length,
@@ -6469,38 +6469,38 @@ var InMemoryThreadMessageQueueStore = class {
6469
6469
  threadMessages.push(message);
6470
6470
  return message;
6471
6471
  }
6472
- async addMessageAtHead(threadId, content, type = "system") {
6472
+ async addMessageAtHead(threadId, content, type = "system", id, command) {
6473
6473
  const threadMessages = this.getMessagesForThread(threadId);
6474
- threadMessages.forEach((msg) => {
6475
- msg.sequence += 1;
6476
- });
6477
6474
  let tenantId = "default";
6478
6475
  let assistantId = "";
6479
6476
  if (threadMessages.length > 0) {
6480
6477
  tenantId = threadMessages[0].tenantId || "default";
6481
6478
  assistantId = threadMessages[0].assistantId || "";
6482
6479
  }
6480
+ const nextSequence = threadMessages.length;
6483
6481
  const message = {
6484
- id: this.generateId(),
6482
+ id: id || this.generateId(),
6485
6483
  content,
6486
6484
  type,
6487
- sequence: 0,
6485
+ sequence: nextSequence,
6488
6486
  createdAt: /* @__PURE__ */ new Date(),
6489
6487
  status: "pending",
6490
6488
  tenantId,
6491
6489
  assistantId,
6492
- priority: 0
6490
+ priority: 100,
6491
+ // High priority for head messages (STEER/Command)
6492
+ command
6493
6493
  };
6494
- threadMessages.unshift(message);
6494
+ threadMessages.push(message);
6495
6495
  return message;
6496
6496
  }
6497
6497
  async getPendingMessages(threadId) {
6498
6498
  const threadMessages = this.getMessagesForThread(threadId);
6499
- return threadMessages.filter((msg) => msg.status === "pending" || !msg.status).sort((a, b) => a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6499
+ 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);
6500
6500
  }
6501
6501
  async getProcessingMessages(threadId) {
6502
6502
  const threadMessages = this.getMessagesForThread(threadId);
6503
- return threadMessages.filter((msg) => msg.status === "processing").sort((a, b) => a.sequence - b.sequence).map(({ status, tenantId, assistantId, ...message }) => message);
6503
+ 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);
6504
6504
  }
6505
6505
  async getQueueSize(threadId) {
6506
6506
  const pending = await this.getPendingMessages(threadId);
@@ -6509,11 +6509,11 @@ var InMemoryThreadMessageQueueStore = class {
6509
6509
  async getThreadsWithPendingMessages() {
6510
6510
  const result = [];
6511
6511
  for (const [threadId, messages] of this.messages.entries()) {
6512
- const pendingMessages = messages.filter(
6513
- (msg) => msg.status === "pending" || !msg.status
6512
+ const pendingOrProcessingMessages = messages.filter(
6513
+ (msg) => msg.status === "pending" || msg.status === "processing" || !msg.status
6514
6514
  );
6515
- if (pendingMessages.length > 0) {
6516
- const firstMessage = pendingMessages[0];
6515
+ if (pendingOrProcessingMessages.length > 0) {
6516
+ const firstMessage = pendingOrProcessingMessages[0];
6517
6517
  result.push({
6518
6518
  tenantId: firstMessage.tenantId || "default",
6519
6519
  assistantId: firstMessage.assistantId || "",
@@ -6563,6 +6563,20 @@ var InMemoryThreadMessageQueueStore = class {
6563
6563
  this.messages.set(threadId, filtered);
6564
6564
  }
6565
6565
  }
6566
+ async resetProcessingToPending(threadId) {
6567
+ const messages = this.messages.get(threadId);
6568
+ if (!messages) {
6569
+ return 0;
6570
+ }
6571
+ let count = 0;
6572
+ for (const msg of messages) {
6573
+ if (msg.status === "processing") {
6574
+ msg.status = "pending";
6575
+ count++;
6576
+ }
6577
+ }
6578
+ return count;
6579
+ }
6566
6580
  };
6567
6581
 
6568
6582
  // src/store_lattice/StoreLatticeManager.ts
@@ -9897,7 +9911,7 @@ import {
9897
9911
  ToolMessage as ToolMessage3,
9898
9912
  humanInTheLoopMiddleware
9899
9913
  } from "langchain";
9900
- import { Command as Command2, getCurrentTaskInput as getCurrentTaskInput2 } from "@langchain/langgraph";
9914
+ import { Command as Command2, getCurrentTaskInput as getCurrentTaskInput2, GraphInterrupt as GraphInterrupt3 } from "@langchain/langgraph";
9901
9915
  import { HumanMessage } from "@langchain/core/messages";
9902
9916
 
9903
9917
  // src/agent_worker/agent_worker_graph.ts
@@ -10595,6 +10609,9 @@ function createTaskTool(options) {
10595
10609
  }
10596
10610
  return returnCommandWithStateUpdate(result, config.toolCall.id);
10597
10611
  } catch (error) {
10612
+ if (error instanceof GraphInterrupt3) {
10613
+ throw error;
10614
+ }
10598
10615
  return new Command2({
10599
10616
  update: {
10600
10617
  messages: [
@@ -13948,7 +13965,7 @@ var AgentParamsBuilder = class {
13948
13965
  * @param options build options
13949
13966
  * @returns Agent build parameters
13950
13967
  */
13951
- buildParams(agentLattice, options) {
13968
+ async buildParams(agentLattice, options) {
13952
13969
  const skills = isDeepAgentConfig2(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
13953
13970
  const toolKeys = options?.overrideTools || getToolsFromConfig2(agentLattice.config);
13954
13971
  const tools = toolKeys.map((toolKey) => {
@@ -13968,8 +13985,8 @@ var AgentParamsBuilder = class {
13968
13985
  throw new Error(`Model "${modelKey}" does not exist`);
13969
13986
  }
13970
13987
  const subAgentKeys = getSubAgentsFromConfig2(agentLattice.config);
13971
- const subAgents = subAgentKeys.map((agentKey) => {
13972
- const subAgentLattice = this.getAgentLatticeFunc(agentKey);
13988
+ const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
13989
+ const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
13973
13990
  if (!subAgentLattice) {
13974
13991
  throw new Error(`SubAgent "${agentKey}" does not exist`);
13975
13992
  }
@@ -13978,7 +13995,7 @@ var AgentParamsBuilder = class {
13978
13995
  config: subAgentLattice.config,
13979
13996
  client: subAgentLattice.client
13980
13997
  };
13981
- });
13998
+ }));
13982
13999
  let internalSubAgents = [];
13983
14000
  if (isDeepAgentConfig2(agentLattice.config)) {
13984
14001
  internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
@@ -14056,7 +14073,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14056
14073
  }
14057
14074
  const config = assistantToConfig(assistant);
14058
14075
  const agentLattice = {
14059
- config,
14076
+ config: { ...config, tenantId },
14060
14077
  client: void 0
14061
14078
  };
14062
14079
  return agentLattice;
@@ -14363,13 +14380,13 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14363
14380
  * @param options 构建选项
14364
14381
  * @returns 返回Agent构建参数
14365
14382
  */
14366
- buildAgentParams(agentLattice, options) {
14383
+ async buildAgentParams(agentLattice, options) {
14367
14384
  const tenantId = agentLattice.config.tenantId || "default";
14368
- const paramsBuilder = new AgentParamsBuilder((key) => {
14369
- this.initializeClient(tenantId, key);
14385
+ const paramsBuilder = new AgentParamsBuilder(async (key) => {
14386
+ await this.initializeClientAsync(tenantId, key);
14370
14387
  return this.getAgentLatticeWithTenant(tenantId, key);
14371
14388
  });
14372
- const params = paramsBuilder.buildParams(agentLattice, options);
14389
+ const params = await paramsBuilder.buildParams(agentLattice, options);
14373
14390
  return {
14374
14391
  ...params,
14375
14392
  tenantId
@@ -14390,7 +14407,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14390
14407
  };
14391
14408
  const factory = AgentGraphBuilderFactory.getInstance();
14392
14409
  const builder = factory.getBuilder(resolvedConfig.type);
14393
- const params = this.buildAgentParams(resolvedLattice, options);
14410
+ const params = await this.buildAgentParams(resolvedLattice, options);
14394
14411
  return await builder.build(resolvedLattice, params);
14395
14412
  }
14396
14413
  /**
@@ -16818,7 +16835,7 @@ var Agent = class {
16818
16835
  command,
16819
16836
  custom_run_config
16820
16837
  }, signal) => {
16821
- const runnable_agent = await getAgentClient(this.tenant_id, this.assistant_id);
16838
+ const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
16822
16839
  const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
16823
16840
  const { messages, ...rest } = input;
16824
16841
  const lifecycleManager = this;
@@ -16938,27 +16955,30 @@ var Agent = class {
16938
16955
  break;
16939
16956
  }
16940
16957
  const firstMessage = pendings[0];
16941
- const hasCommand = firstMessage.content?.command;
16958
+ const hasCommand = firstMessage.command;
16942
16959
  if (hasCommand) {
16943
16960
  for (const p of pendings) {
16944
16961
  if (signal?.aborted) break;
16945
- if (!p.content?.command) break;
16962
+ if (!p.command) break;
16946
16963
  await this.queueStore?.markProcessing(p.id);
16947
16964
  const startTime = Date.now();
16948
16965
  this.publish("message:started", {
16949
16966
  type: "message:started",
16950
- messageId: p.content.id,
16951
- messageContent: p.content.message,
16967
+ messageId: this.getHumanPendingContent(p).id,
16968
+ messageContent: this.getHumanPendingContent(p).message,
16952
16969
  timestamp: /* @__PURE__ */ new Date(),
16953
16970
  queueMode: this.queueMode.mode
16954
16971
  });
16972
+ const humanContent = p.content;
16955
16973
  const input = {
16956
- messages: [new HumanMessage2({ id: p.content.id, content: p.content.message })]
16974
+ messages: [new HumanMessage2({ id: humanContent.id, content: humanContent.message })]
16957
16975
  };
16976
+ const queueMessageData = humanContent.queueMessage;
16958
16977
  try {
16959
16978
  await this.agentStreamExecutor({
16960
16979
  input,
16961
- command: p.content.command
16980
+ command: p.command,
16981
+ custom_run_config: queueMessageData.custom_run_config
16962
16982
  }, signal);
16963
16983
  await this.queueStore?.markCompleted(p.id);
16964
16984
  const runStatus = await this.getRunStatus();
@@ -16966,7 +16986,7 @@ var Agent = class {
16966
16986
  if (runStatus === "interrupted" /* INTERRUPTED */) {
16967
16987
  this.publish("message:interrupted", {
16968
16988
  type: "message:interrupted",
16969
- messageId: p.content.id,
16989
+ messageId: humanContent.id,
16970
16990
  timestamp: /* @__PURE__ */ new Date(),
16971
16991
  duration: Date.now() - startTime,
16972
16992
  state
@@ -16975,13 +16995,13 @@ var Agent = class {
16975
16995
  this.addChunk({
16976
16996
  type: "message_completed",
16977
16997
  data: {
16978
- id: p.content.id,
16998
+ id: humanContent.id,
16979
16999
  content: ""
16980
17000
  }
16981
17001
  });
16982
17002
  this.publish("message:completed", {
16983
17003
  type: "message:completed",
16984
- messageId: p.content.id,
17004
+ messageId: humanContent.id,
16985
17005
  timestamp: /* @__PURE__ */ new Date(),
16986
17006
  duration: Date.now() - startTime,
16987
17007
  state
@@ -16992,13 +17012,13 @@ var Agent = class {
16992
17012
  this.addChunk({
16993
17013
  type: "message_failed",
16994
17014
  data: {
16995
- id: p.content.id,
17015
+ id: humanContent.id,
16996
17016
  content: error instanceof Error ? error.message : String(error)
16997
17017
  }
16998
17018
  });
16999
17019
  this.publish("message:failed", {
17000
17020
  type: "message:failed",
17001
- messageId: p.content.id,
17021
+ messageId: humanContent.id,
17002
17022
  error: error instanceof Error ? error.message : String(error),
17003
17023
  timestamp: /* @__PURE__ */ new Date()
17004
17024
  });
@@ -17013,17 +17033,22 @@ var Agent = class {
17013
17033
  const startTime = Date.now();
17014
17034
  remainingPendings.forEach((p) => {
17015
17035
  this.queueStore?.markProcessing(p.id);
17016
- userMessages.push(new HumanMessage2({ id: p.content.id, content: p.content.message }));
17036
+ const humanContent = p.content;
17037
+ userMessages.push(new HumanMessage2({ id: humanContent.id, content: humanContent.message }));
17017
17038
  this.publish("message:started", {
17018
17039
  type: "message:started",
17019
- messageId: p.content.id,
17020
- messageContent: p.content.message,
17040
+ messageId: humanContent.id,
17041
+ messageContent: humanContent.message,
17021
17042
  timestamp: /* @__PURE__ */ new Date(),
17022
17043
  queueMode: "collect" /* COLLECT */
17023
17044
  });
17024
17045
  });
17046
+ const firstQueueMessage = remainingPendings[0] ? this.getHumanPendingContent(remainingPendings[0]).queueMessage : void 0;
17025
17047
  try {
17026
- await this.agentStreamExecutor({ input: { messages: userMessages } }, signal);
17048
+ await this.agentStreamExecutor({
17049
+ input: { messages: userMessages },
17050
+ custom_run_config: firstQueueMessage?.custom_run_config
17051
+ }, signal);
17027
17052
  const runStatus = await this.getRunStatus();
17028
17053
  const state = await this.getCurrentState();
17029
17054
  for (const p of remainingPendings) {
@@ -17076,24 +17101,29 @@ var Agent = class {
17076
17101
  for (const p of remainingPendings) {
17077
17102
  if (signal?.aborted) break;
17078
17103
  await this.queueStore?.markProcessing(p.id);
17079
- const message = new HumanMessage2({ id: p.id, content: p.content.message });
17104
+ const humanContent = p.content;
17105
+ const message = new HumanMessage2({ id: humanContent.id, content: humanContent.message });
17080
17106
  const startTime = Date.now();
17081
17107
  this.publish("message:started", {
17082
17108
  type: "message:started",
17083
- messageId: p.content.id,
17084
- messageContent: p.content.message,
17109
+ messageId: humanContent.id,
17110
+ messageContent: humanContent.message,
17085
17111
  timestamp: /* @__PURE__ */ new Date(),
17086
17112
  queueMode: "followup" /* FOLLOWUP */
17087
17113
  });
17114
+ const queueMessageData = humanContent.queueMessage || {};
17088
17115
  try {
17089
- await this.agentStreamExecutor({ input: { messages: [message] } }, signal);
17116
+ await this.agentStreamExecutor({
17117
+ input: { messages: [message] },
17118
+ custom_run_config: queueMessageData.custom_run_config
17119
+ }, signal);
17090
17120
  await this.queueStore?.markCompleted(p.id);
17091
17121
  const runStatus = await this.getRunStatus();
17092
17122
  const state = await this.getCurrentState();
17093
17123
  if (runStatus === "interrupted" /* INTERRUPTED */) {
17094
17124
  this.publish("message:interrupted", {
17095
17125
  type: "message:interrupted",
17096
- messageId: p.content.id,
17126
+ messageId: humanContent.id,
17097
17127
  timestamp: /* @__PURE__ */ new Date(),
17098
17128
  duration: Date.now() - startTime,
17099
17129
  state
@@ -17102,13 +17132,13 @@ var Agent = class {
17102
17132
  this.addChunk({
17103
17133
  type: "message_completed",
17104
17134
  data: {
17105
- id: p.content.id,
17135
+ id: humanContent.id,
17106
17136
  content: ""
17107
17137
  }
17108
17138
  });
17109
17139
  this.publish("message:completed", {
17110
17140
  type: "message:completed",
17111
- messageId: p.content.id,
17141
+ messageId: humanContent.id,
17112
17142
  timestamp: /* @__PURE__ */ new Date(),
17113
17143
  duration: Date.now() - startTime,
17114
17144
  state
@@ -17119,13 +17149,13 @@ var Agent = class {
17119
17149
  this.addChunk({
17120
17150
  type: "message_failed",
17121
17151
  data: {
17122
- id: p.content.id,
17152
+ id: humanContent.id,
17123
17153
  content: error instanceof Error ? error.message : String(error)
17124
17154
  }
17125
17155
  });
17126
17156
  this.publish("message:failed", {
17127
17157
  type: "message:failed",
17128
- messageId: p.content.id,
17158
+ messageId: humanContent.id,
17129
17159
  error: error instanceof Error ? error.message : String(error),
17130
17160
  timestamp: /* @__PURE__ */ new Date()
17131
17161
  });
@@ -17143,6 +17173,12 @@ var Agent = class {
17143
17173
  this.project_id = project_id;
17144
17174
  this.custom_run_config = custom_run_config;
17145
17175
  }
17176
+ getHumanPendingContent(message) {
17177
+ if (typeof message.content === "string" || !message.content || !("id" in message.content) || !("message" in message.content)) {
17178
+ throw new Error(`Expected human pending message content for message ${message.id}`);
17179
+ }
17180
+ return message.content;
17181
+ }
17146
17182
  /**
17147
17183
  * Initialize with message queue store
17148
17184
  */
@@ -17257,7 +17293,7 @@ var Agent = class {
17257
17293
  */
17258
17294
  async addMessage(queueMessage, mode) {
17259
17295
  const useMode = mode ?? this.queueMode.mode;
17260
- const messageId = v4();
17296
+ const messageId = queueMessage.input.id || v4();
17261
17297
  const isHighPriority = useMode === "steer" /* STEER */ || !!queueMessage.command;
17262
17298
  const store = this.getQueueStore();
17263
17299
  const currentSize = await store.getQueueSize(this.thread_id);
@@ -17267,20 +17303,30 @@ var Agent = class {
17267
17303
  }
17268
17304
  const content = {
17269
17305
  message: queueMessage.input.message,
17270
- id: messageId
17306
+ id: messageId,
17307
+ // Store complete queue message data for recovery
17308
+ queueMessage: {
17309
+ input: queueMessage.input,
17310
+ command: queueMessage.command,
17311
+ custom_run_config: queueMessage.custom_run_config
17312
+ }
17271
17313
  };
17272
- if (queueMessage.command) {
17273
- content.command = queueMessage.command;
17274
- }
17275
17314
  if (isHighPriority) {
17276
- await store.addMessageAtHead(this.thread_id, content, "human");
17315
+ await store.addMessageAtHead(this.thread_id, content, "human", messageId, queueMessage.command);
17316
+ if (useMode === "steer" /* STEER */) {
17317
+ this.stopQueueProcessor();
17318
+ await store.resetProcessingToPending(this.thread_id);
17319
+ console.log(`[Agent] STEER mode: stopped current processing, reset queue, message ${messageId} will execute next`);
17320
+ }
17277
17321
  } else {
17278
17322
  await store.addMessage({
17279
17323
  threadId: this.thread_id,
17280
17324
  tenantId: this.tenant_id,
17281
17325
  assistantId: this.assistant_id,
17282
17326
  content,
17283
- type: "human"
17327
+ type: "human",
17328
+ command: queueMessage.command,
17329
+ id: messageId
17284
17330
  });
17285
17331
  }
17286
17332
  this.startQueueProcessorIfNeeded().catch((err) => {
@@ -17299,7 +17345,7 @@ var Agent = class {
17299
17345
  }
17300
17346
  /**
17301
17347
  * Start queue processor if not already running
17302
- * Private method used internally by addMessage
17348
+ * Public method to allow external triggering (e.g., from recovery)
17303
17349
  */
17304
17350
  async startQueueProcessorIfNeeded() {
17305
17351
  const store = this.getQueueStore();
@@ -17313,7 +17359,7 @@ var Agent = class {
17313
17359
  this.publish("thread:busy", {
17314
17360
  type: "thread:busy",
17315
17361
  timestamp: /* @__PURE__ */ new Date(),
17316
- messageId: firstMessage?.content?.id
17362
+ messageId: firstMessage ? this.getHumanPendingContent(firstMessage).id : void 0
17317
17363
  });
17318
17364
  this.waitingForQueueEnd(this.abortController.signal).catch((error) => {
17319
17365
  console.error(`Queue processing error for thread ${this.thread_id}:`, error);
@@ -17387,6 +17433,30 @@ var Agent = class {
17387
17433
  }
17388
17434
  return "idle" /* IDLE */;
17389
17435
  }
17436
+ /**
17437
+ * Resume task processing after server restart
17438
+ * Resets any stuck processing messages to pending and starts queue processing
17439
+ * Note: Does not rely on LangGraph state as it may be stale after crash/restart
17440
+ */
17441
+ async resumeTask() {
17442
+ try {
17443
+ await agentLatticeManager.initializeClientAsync(this.tenant_id, this.assistant_id);
17444
+ } catch (error) {
17445
+ console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
17446
+ throw error;
17447
+ }
17448
+ const runStatus = await this.getRunStatus();
17449
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
17450
+ console.log(`[Agent] Skipping resume for ${this.assistant_id} (tenant: ${this.tenant_id}) - agent is in interrupted state`);
17451
+ return;
17452
+ }
17453
+ const store = this.getQueueStore();
17454
+ const resetCount = await store.resetProcessingToPending(this.thread_id);
17455
+ if (resetCount > 0) {
17456
+ console.log(`[Agent] Reset ${resetCount} processing messages to pending for thread ${this.thread_id}`);
17457
+ }
17458
+ await this.startQueueProcessorIfNeeded();
17459
+ }
17390
17460
  /**
17391
17461
  * Abort the current agent execution
17392
17462
  * This will cancel any ongoing invoke or stream operations
@@ -17496,6 +17566,57 @@ var AgentInstanceManager = class _AgentInstanceManager {
17496
17566
  });
17497
17567
  this.agents.clear();
17498
17568
  }
17569
+ /**
17570
+ * Restore agent instances for threads with pending messages after server restart
17571
+ * Queries the message queue store for threads with pending/processing messages
17572
+ * and recreates agent instances to resume processing
17573
+ */
17574
+ async restore() {
17575
+ const stats = { restored: 0, errors: 0 };
17576
+ try {
17577
+ const queueStoreLattice = storeLatticeManager.getStoreLattice("default", "threadMessageQueue");
17578
+ const queueStore = queueStoreLattice.store;
17579
+ const threadsWithPending = await queueStore.getThreadsWithPendingMessages();
17580
+ if (threadsWithPending.length === 0) {
17581
+ console.log("[AgentInstanceManager] No threads with pending messages found");
17582
+ return stats;
17583
+ }
17584
+ console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
17585
+ for (const threadInfo of threadsWithPending) {
17586
+ try {
17587
+ await this.restoreThread(threadInfo, queueStore);
17588
+ stats.restored++;
17589
+ } catch (error) {
17590
+ console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
17591
+ stats.errors++;
17592
+ }
17593
+ }
17594
+ console.log(`[AgentInstanceManager] Restore complete: ${stats.restored} restored, ${stats.errors} errors`);
17595
+ return stats;
17596
+ } catch (error) {
17597
+ console.error("[AgentInstanceManager] Restore failed:", error);
17598
+ throw error;
17599
+ }
17600
+ }
17601
+ /**
17602
+ * Restore a single thread
17603
+ * Delegates actual recovery logic to Agent.resumeTask()
17604
+ */
17605
+ async restoreThread(threadInfo, queueStore) {
17606
+ const { tenantId, assistantId, threadId } = threadInfo;
17607
+ const threadParams = {
17608
+ tenant_id: tenantId,
17609
+ assistant_id: assistantId,
17610
+ thread_id: threadId,
17611
+ workspace_id: "default",
17612
+ // TODO: Get from thread store
17613
+ project_id: "default"
17614
+ // TODO: Get from thread store
17615
+ };
17616
+ const agent = this.getAgent(threadParams);
17617
+ await agent.resumeTask();
17618
+ console.log(`[AgentInstanceManager] Restored thread ${threadId}`);
17619
+ }
17499
17620
  };
17500
17621
  var agentInstanceManager = AgentInstanceManager.getInstance();
17501
17622