@axiom-lattice/core 2.1.41 → 2.1.43

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
@@ -6471,36 +6471,35 @@ var InMemoryThreadMessageQueueStore = class {
6471
6471
  }
6472
6472
  async addMessageAtHead(threadId, content, type = "system") {
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
6482
  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)
6493
6492
  };
6494
- threadMessages.unshift(message);
6493
+ threadMessages.push(message);
6495
6494
  return message;
6496
6495
  }
6497
6496
  async getPendingMessages(threadId) {
6498
6497
  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);
6498
+ 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
6499
  }
6501
6500
  async getProcessingMessages(threadId) {
6502
6501
  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);
6502
+ 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
6503
  }
6505
6504
  async getQueueSize(threadId) {
6506
6505
  const pending = await this.getPendingMessages(threadId);
@@ -6509,11 +6508,11 @@ var InMemoryThreadMessageQueueStore = class {
6509
6508
  async getThreadsWithPendingMessages() {
6510
6509
  const result = [];
6511
6510
  for (const [threadId, messages] of this.messages.entries()) {
6512
- const pendingMessages = messages.filter(
6513
- (msg) => msg.status === "pending" || !msg.status
6511
+ const pendingOrProcessingMessages = messages.filter(
6512
+ (msg) => msg.status === "pending" || msg.status === "processing" || !msg.status
6514
6513
  );
6515
- if (pendingMessages.length > 0) {
6516
- const firstMessage = pendingMessages[0];
6514
+ if (pendingOrProcessingMessages.length > 0) {
6515
+ const firstMessage = pendingOrProcessingMessages[0];
6517
6516
  result.push({
6518
6517
  tenantId: firstMessage.tenantId || "default",
6519
6518
  assistantId: firstMessage.assistantId || "",
@@ -6563,6 +6562,20 @@ var InMemoryThreadMessageQueueStore = class {
6563
6562
  this.messages.set(threadId, filtered);
6564
6563
  }
6565
6564
  }
6565
+ async resetProcessingToPending(threadId) {
6566
+ const messages = this.messages.get(threadId);
6567
+ if (!messages) {
6568
+ return 0;
6569
+ }
6570
+ let count = 0;
6571
+ for (const msg of messages) {
6572
+ if (msg.status === "processing") {
6573
+ msg.status = "pending";
6574
+ count++;
6575
+ }
6576
+ }
6577
+ return count;
6578
+ }
6566
6579
  };
6567
6580
 
6568
6581
  // src/store_lattice/StoreLatticeManager.ts
@@ -9897,7 +9910,7 @@ import {
9897
9910
  ToolMessage as ToolMessage3,
9898
9911
  humanInTheLoopMiddleware
9899
9912
  } from "langchain";
9900
- import { Command as Command2, getCurrentTaskInput as getCurrentTaskInput2 } from "@langchain/langgraph";
9913
+ import { Command as Command2, getCurrentTaskInput as getCurrentTaskInput2, GraphInterrupt as GraphInterrupt3 } from "@langchain/langgraph";
9901
9914
  import { HumanMessage } from "@langchain/core/messages";
9902
9915
 
9903
9916
  // src/agent_worker/agent_worker_graph.ts
@@ -10595,6 +10608,9 @@ function createTaskTool(options) {
10595
10608
  }
10596
10609
  return returnCommandWithStateUpdate(result, config.toolCall.id);
10597
10610
  } catch (error) {
10611
+ if (error instanceof GraphInterrupt3) {
10612
+ throw error;
10613
+ }
10598
10614
  return new Command2({
10599
10615
  update: {
10600
10616
  messages: [
@@ -10788,13 +10804,13 @@ var StoreBackend = class {
10788
10804
  * @returns List of all items matching the search criteria
10789
10805
  */
10790
10806
  async searchStorePaginated(store, namespace, options = {}) {
10791
- const { query, filter, pageSize = 100 } = options;
10807
+ const { query, filter: filter2, pageSize = 100 } = options;
10792
10808
  const allItems = [];
10793
10809
  let offset = 0;
10794
10810
  while (true) {
10795
10811
  const pageItems = await store.search(namespace, {
10796
10812
  query,
10797
- filter,
10813
+ filter: filter2,
10798
10814
  limit: pageSize,
10799
10815
  offset
10800
10816
  });
@@ -13948,7 +13964,7 @@ var AgentParamsBuilder = class {
13948
13964
  * @param options build options
13949
13965
  * @returns Agent build parameters
13950
13966
  */
13951
- buildParams(agentLattice, options) {
13967
+ async buildParams(agentLattice, options) {
13952
13968
  const skills = isDeepAgentConfig2(agentLattice.config) ? agentLattice.config.skillCategories : void 0;
13953
13969
  const toolKeys = options?.overrideTools || getToolsFromConfig2(agentLattice.config);
13954
13970
  const tools = toolKeys.map((toolKey) => {
@@ -13968,8 +13984,8 @@ var AgentParamsBuilder = class {
13968
13984
  throw new Error(`Model "${modelKey}" does not exist`);
13969
13985
  }
13970
13986
  const subAgentKeys = getSubAgentsFromConfig2(agentLattice.config);
13971
- const subAgents = subAgentKeys.map((agentKey) => {
13972
- const subAgentLattice = this.getAgentLatticeFunc(agentKey);
13987
+ const subAgents = await Promise.all(subAgentKeys.map(async (agentKey) => {
13988
+ const subAgentLattice = await this.getAgentLatticeFunc(agentKey);
13973
13989
  if (!subAgentLattice) {
13974
13990
  throw new Error(`SubAgent "${agentKey}" does not exist`);
13975
13991
  }
@@ -13978,7 +13994,7 @@ var AgentParamsBuilder = class {
13978
13994
  config: subAgentLattice.config,
13979
13995
  client: subAgentLattice.client
13980
13996
  };
13981
- });
13997
+ }));
13982
13998
  let internalSubAgents = [];
13983
13999
  if (isDeepAgentConfig2(agentLattice.config)) {
13984
14000
  internalSubAgents = agentLattice.config.internalSubAgents?.map((i) => ({
@@ -14056,7 +14072,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14056
14072
  }
14057
14073
  const config = assistantToConfig(assistant);
14058
14074
  const agentLattice = {
14059
- config,
14075
+ config: { ...config, tenantId },
14060
14076
  client: void 0
14061
14077
  };
14062
14078
  return agentLattice;
@@ -14363,13 +14379,13 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14363
14379
  * @param options 构建选项
14364
14380
  * @returns 返回Agent构建参数
14365
14381
  */
14366
- buildAgentParams(agentLattice, options) {
14382
+ async buildAgentParams(agentLattice, options) {
14367
14383
  const tenantId = agentLattice.config.tenantId || "default";
14368
- const paramsBuilder = new AgentParamsBuilder((key) => {
14369
- this.initializeClient(tenantId, key);
14384
+ const paramsBuilder = new AgentParamsBuilder(async (key) => {
14385
+ await this.initializeClientAsync(tenantId, key);
14370
14386
  return this.getAgentLatticeWithTenant(tenantId, key);
14371
14387
  });
14372
- const params = paramsBuilder.buildParams(agentLattice, options);
14388
+ const params = await paramsBuilder.buildParams(agentLattice, options);
14373
14389
  return {
14374
14390
  ...params,
14375
14391
  tenantId
@@ -14390,7 +14406,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
14390
14406
  };
14391
14407
  const factory = AgentGraphBuilderFactory.getInstance();
14392
14408
  const builder = factory.getBuilder(resolvedConfig.type);
14393
- const params = this.buildAgentParams(resolvedLattice, options);
14409
+ const params = await this.buildAgentParams(resolvedLattice, options);
14394
14410
  return await builder.build(resolvedLattice, params);
14395
14411
  }
14396
14412
  /**
@@ -14468,11 +14484,14 @@ var ChunkBuffer = class {
14468
14484
  };
14469
14485
 
14470
14486
  // src/chunk_buffer_lattice/InMemoryChunkBuffer.ts
14487
+ import { MessageChunkTypes } from "@axiom-lattice/protocols";
14471
14488
  import {
14472
14489
  ReplaySubject,
14473
14490
  observeOn,
14474
14491
  asyncScheduler
14475
14492
  } from "rxjs";
14493
+ import { eachValueFrom } from "rxjs-for-await";
14494
+ import { filter, takeWhile } from "rxjs/operators";
14476
14495
  var InMemoryChunkBuffer = class extends ChunkBuffer {
14477
14496
  constructor(config) {
14478
14497
  super();
@@ -14557,7 +14576,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
14557
14576
  let chunk;
14558
14577
  if (typeof arg2 === "string" && arg3 !== void 0) {
14559
14578
  chunk = {
14560
- type: "message_chunk",
14579
+ type: MessageChunkTypes.AI,
14561
14580
  data: {
14562
14581
  id: arg2,
14563
14582
  content: arg3
@@ -14573,7 +14592,6 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
14573
14592
  buffer2.status = "active" /* ACTIVE */;
14574
14593
  }
14575
14594
  async completeThread(threadId) {
14576
- console.log("completeThread");
14577
14595
  const buffer2 = this.getBufferIfValid(threadId);
14578
14596
  if (buffer2) {
14579
14597
  buffer2.status = "completed" /* COMPLETED */;
@@ -14672,75 +14690,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
14672
14690
  buffer2.updatedAt = Date.now();
14673
14691
  }
14674
14692
  }
14675
- async *getNewChunksSinceContentIterator(threadId, messageId, knownContent) {
14693
+ async *getNewChunksSinceContentIterator(threadId, messageId, knownContent, stopTypes) {
14676
14694
  const buffer2 = this.getBufferIfValid(threadId);
14677
14695
  if (!buffer2) return;
14678
- let accumulatedContent = "";
14679
- const queue = [];
14680
- let resolveNext = null;
14681
- let errorNext = null;
14682
- let isCompleted = false;
14683
- let pendingError = null;
14684
- const subscription = buffer2.chunks$.pipe(observeOn(asyncScheduler)).subscribe({
14685
- next: (chunk) => {
14686
- queue.push(chunk);
14687
- if (resolveNext) {
14688
- const resolve3 = resolveNext;
14689
- resolveNext = null;
14690
- resolve3();
14691
- }
14692
- },
14693
- error: (err) => {
14694
- pendingError = err;
14695
- if (errorNext) {
14696
- const reject = errorNext;
14697
- errorNext = null;
14698
- reject(err);
14699
- } else if (resolveNext) {
14700
- const resolve3 = resolveNext;
14701
- resolveNext = null;
14702
- resolve3();
14703
- }
14704
- },
14705
- complete: () => {
14706
- isCompleted = true;
14707
- if (resolveNext) {
14708
- const resolve3 = resolveNext;
14709
- resolveNext = null;
14710
- resolve3();
14711
- }
14712
- }
14713
- });
14696
+ const defaultStopTypes = [
14697
+ MessageChunkTypes.MESSAGE_COMPLETED,
14698
+ MessageChunkTypes.THREAD_IDLE
14699
+ ];
14700
+ const typesToStop = stopTypes ?? defaultStopTypes;
14714
14701
  let startYieldChunk = false;
14715
- try {
14716
- while (true) {
14717
- if (pendingError) {
14718
- throw pendingError;
14719
- }
14720
- if (queue.length === 0) {
14721
- if (isCompleted) break;
14722
- await new Promise((resolve3, reject) => {
14723
- resolveNext = resolve3;
14724
- errorNext = reject;
14725
- });
14726
- }
14727
- if (pendingError) {
14728
- throw pendingError;
14729
- }
14730
- while (queue.length > 0) {
14731
- const chunk = queue.shift();
14732
- if (!chunk) continue;
14733
- if (chunk.data?.id === messageId) {
14734
- startYieldChunk = true;
14735
- }
14736
- if (startYieldChunk) {
14737
- yield chunk;
14738
- }
14739
- }
14740
- }
14741
- } finally {
14742
- subscription.unsubscribe();
14743
- }
14702
+ console.log("start from messageId", messageId);
14703
+ const filtered$ = buffer2.chunks$.pipe(
14704
+ observeOn(asyncScheduler),
14705
+ // 1. 从指定 messageId 开始
14706
+ filter((chunk) => {
14707
+ if (chunk.data?.id === messageId) startYieldChunk = true;
14708
+ return startYieldChunk;
14709
+ }),
14710
+ // 2. 包含指定的停止类型,但收到后停止
14711
+ takeWhile((chunk) => !typesToStop.includes(chunk.type), true)
14712
+ );
14713
+ yield* eachValueFrom(filtered$);
14744
14714
  }
14745
14715
  getStats() {
14746
14716
  let activeCount = 0;
@@ -16864,7 +16834,7 @@ var Agent = class {
16864
16834
  command,
16865
16835
  custom_run_config
16866
16836
  }, signal) => {
16867
- const runnable_agent = await getAgentClient(this.tenant_id, this.assistant_id);
16837
+ const runnable_agent = await getAgentClientAsync(this.tenant_id, this.assistant_id);
16868
16838
  const agentLattice = agentLatticeManager.getAgentLatticeWithTenant(this.tenant_id, this.assistant_id);
16869
16839
  const { messages, ...rest } = input;
16870
16840
  const lifecycleManager = this;
@@ -16946,9 +16916,7 @@ var Agent = class {
16946
16916
  };
16947
16917
  }
16948
16918
  if (data) {
16949
- if (data.type !== "interrupt") {
16950
- await lifecycleManager.addChunk(data);
16951
- }
16919
+ lifecycleManager.addChunk(data);
16952
16920
  }
16953
16921
  }
16954
16922
  } catch (error) {
@@ -16965,8 +16933,8 @@ var Agent = class {
16965
16933
  while (!signal?.aborted) {
16966
16934
  const pendings = await this.getPendingMessages();
16967
16935
  if (pendings.length === 0) {
16968
- await this.tryToCompleteThread();
16969
16936
  const state = await this.getCurrentState();
16937
+ const runStatus = await this.getRunStatus();
16970
16938
  const pendingCount = await this.getQueueStore().getQueueSize(this.thread_id);
16971
16939
  this.publish("thread:idle", {
16972
16940
  type: "thread:idle",
@@ -16974,6 +16942,15 @@ var Agent = class {
16974
16942
  pendingCount,
16975
16943
  state
16976
16944
  });
16945
+ if (runStatus === "idle" /* IDLE */) {
16946
+ this.addChunk({
16947
+ type: "thread_idle",
16948
+ data: {
16949
+ id: this.thread_id,
16950
+ content: ""
16951
+ }
16952
+ });
16953
+ }
16977
16954
  break;
16978
16955
  }
16979
16956
  const firstMessage = pendings[0];
@@ -16994,22 +16971,49 @@ var Agent = class {
16994
16971
  const input = {
16995
16972
  messages: [new HumanMessage2({ id: p.content.id, content: p.content.message })]
16996
16973
  };
16974
+ const queueMessageData = p.content.queueMessage || {};
16997
16975
  try {
16998
16976
  await this.agentStreamExecutor({
16999
16977
  input,
17000
- command: p.content.command
16978
+ command: queueMessageData.command || p.content.command,
16979
+ custom_run_config: queueMessageData.custom_run_config
17001
16980
  }, signal);
17002
16981
  await this.queueStore?.markCompleted(p.id);
16982
+ const runStatus = await this.getRunStatus();
17003
16983
  const state = await this.getCurrentState();
17004
- this.publish("message:completed", {
17005
- type: "message:completed",
17006
- messageId: p.content.id,
17007
- timestamp: /* @__PURE__ */ new Date(),
17008
- duration: Date.now() - startTime,
17009
- state
17010
- });
16984
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
16985
+ this.publish("message:interrupted", {
16986
+ type: "message:interrupted",
16987
+ messageId: p.content.id,
16988
+ timestamp: /* @__PURE__ */ new Date(),
16989
+ duration: Date.now() - startTime,
16990
+ state
16991
+ });
16992
+ } else {
16993
+ this.addChunk({
16994
+ type: "message_completed",
16995
+ data: {
16996
+ id: p.content.id,
16997
+ content: ""
16998
+ }
16999
+ });
17000
+ this.publish("message:completed", {
17001
+ type: "message:completed",
17002
+ messageId: p.content.id,
17003
+ timestamp: /* @__PURE__ */ new Date(),
17004
+ duration: Date.now() - startTime,
17005
+ state
17006
+ });
17007
+ }
17011
17008
  } catch (error) {
17012
17009
  console.error(`STEER/Command message ${p.id} execution failed:`, error);
17010
+ this.addChunk({
17011
+ type: "message_failed",
17012
+ data: {
17013
+ id: p.content.id,
17014
+ content: error instanceof Error ? error.message : String(error)
17015
+ }
17016
+ });
17013
17017
  this.publish("message:failed", {
17014
17018
  type: "message:failed",
17015
17019
  messageId: p.content.id,
@@ -17036,22 +17040,51 @@ var Agent = class {
17036
17040
  queueMode: "collect" /* COLLECT */
17037
17041
  });
17038
17042
  });
17043
+ const firstQueueMessage = remainingPendings[0]?.content?.queueMessage || {};
17039
17044
  try {
17040
- await this.agentStreamExecutor({ input: { messages: userMessages } }, signal);
17045
+ await this.agentStreamExecutor({
17046
+ input: { messages: userMessages },
17047
+ custom_run_config: firstQueueMessage.custom_run_config
17048
+ }, signal);
17049
+ const runStatus = await this.getRunStatus();
17041
17050
  const state = await this.getCurrentState();
17042
17051
  for (const p of remainingPendings) {
17043
17052
  await this.queueStore?.markCompleted(p.id);
17044
- this.publish("message:completed", {
17045
- type: "message:completed",
17046
- messageId: p.content.id,
17047
- timestamp: /* @__PURE__ */ new Date(),
17048
- duration: Date.now() - startTime,
17049
- state
17050
- });
17053
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
17054
+ this.publish("message:interrupted", {
17055
+ type: "message:interrupted",
17056
+ messageId: p.content.id,
17057
+ timestamp: /* @__PURE__ */ new Date(),
17058
+ duration: Date.now() - startTime,
17059
+ state
17060
+ });
17061
+ } else {
17062
+ this.addChunk({
17063
+ type: "message_completed",
17064
+ data: {
17065
+ id: p.content.id,
17066
+ content: ""
17067
+ }
17068
+ });
17069
+ this.publish("message:completed", {
17070
+ type: "message:completed",
17071
+ messageId: p.content.id,
17072
+ timestamp: /* @__PURE__ */ new Date(),
17073
+ duration: Date.now() - startTime,
17074
+ state
17075
+ });
17076
+ }
17051
17077
  }
17052
17078
  } catch (error) {
17053
17079
  console.error(`COLLECT mode execution failed:`, error);
17054
17080
  for (const p of remainingPendings) {
17081
+ this.addChunk({
17082
+ type: "message_failed",
17083
+ data: {
17084
+ id: p.content.id,
17085
+ content: error instanceof Error ? error.message : String(error)
17086
+ }
17087
+ });
17055
17088
  this.publish("message:failed", {
17056
17089
  type: "message:failed",
17057
17090
  messageId: p.content.id,
@@ -17074,19 +17107,48 @@ var Agent = class {
17074
17107
  timestamp: /* @__PURE__ */ new Date(),
17075
17108
  queueMode: "followup" /* FOLLOWUP */
17076
17109
  });
17110
+ const queueMessageData = p.content.queueMessage || {};
17077
17111
  try {
17078
- await this.agentStreamExecutor({ input: { messages: [message] } }, signal);
17112
+ await this.agentStreamExecutor({
17113
+ input: { messages: [message] },
17114
+ custom_run_config: queueMessageData.custom_run_config
17115
+ }, signal);
17079
17116
  await this.queueStore?.markCompleted(p.id);
17117
+ const runStatus = await this.getRunStatus();
17080
17118
  const state = await this.getCurrentState();
17081
- this.publish("message:completed", {
17082
- type: "message:completed",
17083
- messageId: p.content.id,
17084
- timestamp: /* @__PURE__ */ new Date(),
17085
- duration: Date.now() - startTime,
17086
- state
17087
- });
17119
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
17120
+ this.publish("message:interrupted", {
17121
+ type: "message:interrupted",
17122
+ messageId: p.content.id,
17123
+ timestamp: /* @__PURE__ */ new Date(),
17124
+ duration: Date.now() - startTime,
17125
+ state
17126
+ });
17127
+ } else {
17128
+ this.addChunk({
17129
+ type: "message_completed",
17130
+ data: {
17131
+ id: p.content.id,
17132
+ content: ""
17133
+ }
17134
+ });
17135
+ this.publish("message:completed", {
17136
+ type: "message:completed",
17137
+ messageId: p.content.id,
17138
+ timestamp: /* @__PURE__ */ new Date(),
17139
+ duration: Date.now() - startTime,
17140
+ state
17141
+ });
17142
+ }
17088
17143
  } catch (error) {
17089
17144
  console.error(`FOLLOWUP mode message ${p.id} execution failed:`, error);
17145
+ this.addChunk({
17146
+ type: "message_failed",
17147
+ data: {
17148
+ id: p.content.id,
17149
+ content: error instanceof Error ? error.message : String(error)
17150
+ }
17151
+ });
17090
17152
  this.publish("message:failed", {
17091
17153
  type: "message:failed",
17092
17154
  messageId: p.content.id,
@@ -17116,11 +17178,12 @@ var Agent = class {
17116
17178
  addChunk(content) {
17117
17179
  return this.chunkBuffer.addChunk(this.thread_id, content);
17118
17180
  }
17119
- chunkStream(message_id, known_content = "") {
17181
+ chunkStream(message_id, stopTypes) {
17120
17182
  const stream = this.chunkBuffer.getNewChunksSinceContentIterator(
17121
17183
  this.thread_id,
17122
17184
  message_id,
17123
- known_content
17185
+ "",
17186
+ stopTypes
17124
17187
  );
17125
17188
  return {
17126
17189
  [Symbol.asyncIterator]: async function* () {
@@ -17175,11 +17238,6 @@ var Agent = class {
17175
17238
  const store = this.getQueueStore();
17176
17239
  return await store.getPendingMessages(this.thread_id);
17177
17240
  }
17178
- async tryToCompleteThread() {
17179
- setTimeout(async () => {
17180
- await this.chunkBuffer.completeThread(this.thread_id);
17181
- }, 100);
17182
- }
17183
17241
  getQueueStore() {
17184
17242
  if (!this.queueStore) {
17185
17243
  try {
@@ -17235,11 +17293,14 @@ var Agent = class {
17235
17293
  }
17236
17294
  const content = {
17237
17295
  message: queueMessage.input.message,
17238
- id: messageId
17296
+ id: messageId,
17297
+ // Store complete queue message data for recovery
17298
+ queueMessage: {
17299
+ input: queueMessage.input,
17300
+ command: queueMessage.command,
17301
+ custom_run_config: queueMessage.custom_run_config
17302
+ }
17239
17303
  };
17240
- if (queueMessage.command) {
17241
- content.command = queueMessage.command;
17242
- }
17243
17304
  if (isHighPriority) {
17244
17305
  await store.addMessageAtHead(this.thread_id, content, "human");
17245
17306
  } else {
@@ -17267,7 +17328,7 @@ var Agent = class {
17267
17328
  }
17268
17329
  /**
17269
17330
  * Start queue processor if not already running
17270
- * Private method used internally by addMessage
17331
+ * Public method to allow external triggering (e.g., from recovery)
17271
17332
  */
17272
17333
  async startQueueProcessorIfNeeded() {
17273
17334
  const store = this.getQueueStore();
@@ -17355,6 +17416,30 @@ var Agent = class {
17355
17416
  }
17356
17417
  return "idle" /* IDLE */;
17357
17418
  }
17419
+ /**
17420
+ * Resume task processing after server restart
17421
+ * Resets any stuck processing messages to pending and starts queue processing
17422
+ * Note: Does not rely on LangGraph state as it may be stale after crash/restart
17423
+ */
17424
+ async resumeTask() {
17425
+ try {
17426
+ await agentLatticeManager.initializeClientAsync(this.tenant_id, this.assistant_id);
17427
+ } catch (error) {
17428
+ console.error(`[Agent] Failed to initialize agent lattice for ${this.assistant_id} (tenant: ${this.tenant_id}):`, error);
17429
+ throw error;
17430
+ }
17431
+ const runStatus = await this.getRunStatus();
17432
+ if (runStatus === "interrupted" /* INTERRUPTED */) {
17433
+ console.log(`[Agent] Skipping resume for ${this.assistant_id} (tenant: ${this.tenant_id}) - agent is in interrupted state`);
17434
+ return;
17435
+ }
17436
+ const store = this.getQueueStore();
17437
+ const resetCount = await store.resetProcessingToPending(this.thread_id);
17438
+ if (resetCount > 0) {
17439
+ console.log(`[Agent] Reset ${resetCount} processing messages to pending for thread ${this.thread_id}`);
17440
+ }
17441
+ await this.startQueueProcessorIfNeeded();
17442
+ }
17358
17443
  /**
17359
17444
  * Abort the current agent execution
17360
17445
  * This will cancel any ongoing invoke or stream operations
@@ -17398,6 +17483,7 @@ var Agent = class {
17398
17483
  */
17399
17484
  publish(eventName, data) {
17400
17485
  const namespacedEvent = `${eventName}:${this.tenant_id}:${this.thread_id}`;
17486
+ console.log(namespacedEvent);
17401
17487
  event_bus_default.publish(namespacedEvent, data);
17402
17488
  }
17403
17489
  };
@@ -17463,6 +17549,57 @@ var AgentInstanceManager = class _AgentInstanceManager {
17463
17549
  });
17464
17550
  this.agents.clear();
17465
17551
  }
17552
+ /**
17553
+ * Restore agent instances for threads with pending messages after server restart
17554
+ * Queries the message queue store for threads with pending/processing messages
17555
+ * and recreates agent instances to resume processing
17556
+ */
17557
+ async restore() {
17558
+ const stats = { restored: 0, errors: 0 };
17559
+ try {
17560
+ const queueStoreLattice = storeLatticeManager.getStoreLattice("default", "threadMessageQueue");
17561
+ const queueStore = queueStoreLattice.store;
17562
+ const threadsWithPending = await queueStore.getThreadsWithPendingMessages();
17563
+ if (threadsWithPending.length === 0) {
17564
+ console.log("[AgentInstanceManager] No threads with pending messages found");
17565
+ return stats;
17566
+ }
17567
+ console.log(`[AgentInstanceManager] Found ${threadsWithPending.length} threads with pending messages, restoring...`);
17568
+ for (const threadInfo of threadsWithPending) {
17569
+ try {
17570
+ await this.restoreThread(threadInfo, queueStore);
17571
+ stats.restored++;
17572
+ } catch (error) {
17573
+ console.error(`[AgentInstanceManager] Failed to restore thread ${threadInfo.threadId}:`, error);
17574
+ stats.errors++;
17575
+ }
17576
+ }
17577
+ console.log(`[AgentInstanceManager] Restore complete: ${stats.restored} restored, ${stats.errors} errors`);
17578
+ return stats;
17579
+ } catch (error) {
17580
+ console.error("[AgentInstanceManager] Restore failed:", error);
17581
+ throw error;
17582
+ }
17583
+ }
17584
+ /**
17585
+ * Restore a single thread
17586
+ * Delegates actual recovery logic to Agent.resumeTask()
17587
+ */
17588
+ async restoreThread(threadInfo, queueStore) {
17589
+ const { tenantId, assistantId, threadId } = threadInfo;
17590
+ const threadParams = {
17591
+ tenant_id: tenantId,
17592
+ assistant_id: assistantId,
17593
+ thread_id: threadId,
17594
+ workspace_id: "default",
17595
+ // TODO: Get from thread store
17596
+ project_id: "default"
17597
+ // TODO: Get from thread store
17598
+ };
17599
+ const agent = this.getAgent(threadParams);
17600
+ await agent.resumeTask();
17601
+ console.log(`[AgentInstanceManager] Restored thread ${threadId}`);
17602
+ }
17466
17603
  };
17467
17604
  var agentInstanceManager = AgentInstanceManager.getInstance();
17468
17605