@axiom-lattice/core 4.2.9 → 4.2.11

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
@@ -2763,6 +2763,40 @@ function validDate2(value) {
2763
2763
  }
2764
2764
  }
2765
2765
 
2766
+ // src/store_lattice/InMemoryUserPushSubscriptionStore.ts
2767
+ var InMemoryUserPushSubscriptionStore = class {
2768
+ constructor() {
2769
+ this.entries = /* @__PURE__ */ new Map();
2770
+ }
2771
+ /** Lists defensive copies of every subscription for a user. */
2772
+ async list(tenantId2, userId) {
2773
+ return [...this.entries.values()].filter((entry) => entry.tenantId === tenantId2 && entry.userId === userId).map((entry) => structuredClone(entry));
2774
+ }
2775
+ /** Saves (upserts) a subscription keyed by tenant + user + endpoint. */
2776
+ async save(input) {
2777
+ const key5 = entryKey(input.tenantId, input.userId, input.endpoint);
2778
+ const existing = this.entries.get(key5);
2779
+ const next = {
2780
+ id: existing?.id ?? crypto.randomUUID(),
2781
+ tenantId: input.tenantId,
2782
+ userId: input.userId,
2783
+ endpoint: input.endpoint,
2784
+ keys: { p256dh: input.keys.p256dh, auth: input.keys.auth },
2785
+ ...input.userAgent === void 0 ? {} : { userAgent: input.userAgent },
2786
+ createdAt: existing?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
2787
+ };
2788
+ this.entries.set(key5, next);
2789
+ return structuredClone(next);
2790
+ }
2791
+ /** Deletes a subscription by endpoint. Returns whether a row was removed. */
2792
+ async delete(tenantId2, userId, endpoint) {
2793
+ return this.entries.delete(entryKey(tenantId2, userId, endpoint));
2794
+ }
2795
+ };
2796
+ function entryKey(tenantId2, userId, endpoint) {
2797
+ return JSON.stringify([tenantId2, userId, endpoint]);
2798
+ }
2799
+
2766
2800
  // src/store_lattice/InMemoryUserStore.ts
2767
2801
  var InMemoryUserStore = class {
2768
2802
  constructor() {
@@ -4392,6 +4426,7 @@ var defaultProjectMembershipStore = new InMemoryProjectMembershipStore(defaultPr
4392
4426
  var defaultProjectBotMembershipStore = new InMemoryProjectBotMembershipStore(defaultProjectRoomCoordinator);
4393
4427
  var defaultProjectRoomMessageStore = new InMemoryProjectRoomMessageStore(defaultProjectRoomCoordinator);
4394
4428
  var defaultProjectRoomReadStateStore = new InMemoryProjectRoomReadStateStore();
4429
+ var defaultUserPushSubscriptionStore = new InMemoryUserPushSubscriptionStore();
4395
4430
  storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
4396
4431
  storeLatticeManager.registerLattice(
4397
4432
  "default",
@@ -4411,6 +4446,7 @@ storeLatticeManager.registerLattice("default", "projectMembership", defaultProje
4411
4446
  storeLatticeManager.registerLattice("default", "projectBotMembership", defaultProjectBotMembershipStore);
4412
4447
  storeLatticeManager.registerLattice("default", "projectRoomMessage", defaultProjectRoomMessageStore);
4413
4448
  storeLatticeManager.registerLattice("default", "projectRoomReadState", defaultProjectRoomReadStateStore);
4449
+ storeLatticeManager.registerLattice("default", "userPushSubscription", defaultUserPushSubscriptionStore);
4414
4450
  var defaultUserStore = new InMemoryUserStore();
4415
4451
  var defaultTenantStore = new InMemoryTenantStore();
4416
4452
  var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
@@ -13549,7 +13585,7 @@ function hasExplicitAllowedTools(policy) {
13549
13585
  return Object.prototype.hasOwnProperty.call(policy, "allowedTools");
13550
13586
  }
13551
13587
  function hasActiveRuntimePolicy(runtime) {
13552
- return runtime.revision.trim().length > 0 || Object.keys(runtime.middleware).length > 0;
13588
+ return Object.keys(runtime.middleware).length > 0;
13553
13589
  }
13554
13590
  function tenantIdFromRequest(request) {
13555
13591
  if (!isRecord8(request) || !isRecord8(request.runtime)) return void 0;
@@ -14719,6 +14755,17 @@ var ChunkBuffer = class {
14719
14755
 
14720
14756
  // src/chunk_buffer_lattice/InMemoryChunkBuffer.ts
14721
14757
  import { MessageChunkTypes } from "@axiom-lattice/protocols";
14758
+
14759
+ // src/chunk_buffer_lattice/types.ts
14760
+ var ThreadEndError = class extends Error {
14761
+ constructor(message, code) {
14762
+ super(message);
14763
+ this.name = "ThreadEndError";
14764
+ this.code = code;
14765
+ }
14766
+ };
14767
+
14768
+ // src/chunk_buffer_lattice/InMemoryChunkBuffer.ts
14722
14769
  import {
14723
14770
  ReplaySubject,
14724
14771
  observeOn,
@@ -14836,12 +14883,12 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
14836
14883
  buffer2.chunks$.complete();
14837
14884
  }
14838
14885
  }
14839
- async abortThread(threadId) {
14886
+ async abortThread(threadId, message, code = "aborted") {
14840
14887
  const buffer2 = this.getBufferIfValid(threadId);
14841
14888
  if (buffer2) {
14842
14889
  buffer2.status = "aborted" /* ABORTED */;
14843
14890
  buffer2.updatedAt = Date.now();
14844
- buffer2.chunks$.error(new Error("Thread aborted"));
14891
+ buffer2.chunks$.error(new ThreadEndError(message ?? "Thread aborted", code));
14845
14892
  }
14846
14893
  }
14847
14894
  async isThreadActive(threadId) {
@@ -15793,6 +15840,17 @@ var CapabilityBundleMerger = class {
15793
15840
  };
15794
15841
 
15795
15842
  // src/capability/CapabilityRuntimeResolver.ts
15843
+ var EMPTY_CAPABILITY_RUNTIME_REVISION = createCapabilityRevision([], {});
15844
+ function emptyCapabilityRuntime(expectedRevision) {
15845
+ if (expectedRevision !== void 0 && expectedRevision !== "" && expectedRevision !== EMPTY_CAPABILITY_RUNTIME_REVISION) {
15846
+ throw new CapabilityRuntimeResolutionError(
15847
+ "CAPABILITY_RUNTIME_REVISION_MISMATCH",
15848
+ "Capability runtime revision no longer matches the checkpoint",
15849
+ { expectedRevision, actualRevision: EMPTY_CAPABILITY_RUNTIME_REVISION }
15850
+ );
15851
+ }
15852
+ return { revision: EMPTY_CAPABILITY_RUNTIME_REVISION, middleware: {} };
15853
+ }
15796
15854
  var CapabilityRuntimeResolutionError = class extends Error {
15797
15855
  /**
15798
15856
  * Creates a runtime resolution error.
@@ -15973,14 +16031,7 @@ var CapabilityRuntimeResolver = class {
15973
16031
  };
15974
16032
  }
15975
16033
  emptyRuntime(expectedRevision) {
15976
- if (expectedRevision) {
15977
- throw new CapabilityRuntimeResolutionError(
15978
- "CAPABILITY_RUNTIME_REVISION_MISMATCH",
15979
- "Capability runtime revision no longer matches the checkpoint",
15980
- { expectedRevision, actualRevision: "" }
15981
- );
15982
- }
15983
- return { revision: "", middleware: {} };
16034
+ return emptyCapabilityRuntime(expectedRevision);
15984
16035
  }
15985
16036
  };
15986
16037
 
@@ -16219,6 +16270,10 @@ function requireTrustedCapabilityRevision(value) {
16219
16270
  }
16220
16271
  return value;
16221
16272
  }
16273
+ function trustedCapabilityRevision(value) {
16274
+ if (value === "") return void 0;
16275
+ return requireTrustedCapabilityRevision(value);
16276
+ }
16222
16277
  function finalAiMessageMarker(state) {
16223
16278
  if (!isPlainRecord(state) || !isPlainRecord(state.values) || !Array.isArray(state.values.messages)) {
16224
16279
  return void 0;
@@ -16434,7 +16489,9 @@ var Agent = class {
16434
16489
  throw error;
16435
16490
  }
16436
16491
  } catch (error) {
16437
- await this.chunkBuffer.abortThread(this.thread_id);
16492
+ const endCode = signal?.aborted ? "aborted" : "stream_error";
16493
+ const endMessage = endCode === "stream_error" ? error instanceof Error ? error.message : "Stream processing error" : "Thread aborted";
16494
+ await this.chunkBuffer.abortThread(this.thread_id, endMessage, endCode);
16438
16495
  throw error;
16439
16496
  }
16440
16497
  };
@@ -16493,7 +16550,7 @@ var Agent = class {
16493
16550
  const interruptedExecutionContext = commandRunStatus === "interrupted" /* INTERRUPTED */ ? this.processingExecutionContext(interruptedMessages, true) : void 0;
16494
16551
  const interruptedConfig = interruptedExecutionContext?.customRunConfig;
16495
16552
  const queuedCapabilityRevision = typeof interruptedConfig === "object" && interruptedConfig !== null ? interruptedConfig.capabilityRuntimeRevision : void 0;
16496
- const expectedCapabilityRevision = interruptedExecutionContext?.trustedRunContext !== void 0 ? requireTrustedCapabilityRevision(queuedCapabilityRevision) : typeof queuedCapabilityRevision === "string" ? queuedCapabilityRevision : void 0;
16553
+ const expectedCapabilityRevision = interruptedExecutionContext?.trustedRunContext !== void 0 ? trustedCapabilityRevision(queuedCapabilityRevision) : typeof queuedCapabilityRevision === "string" ? queuedCapabilityRevision : void 0;
16497
16554
  try {
16498
16555
  const preRunMarker = finalAiMessageMarker(preRunState);
16499
16556
  await this.agentStreamExecutor({
@@ -16859,7 +16916,8 @@ var Agent = class {
16859
16916
  consumedInputMessageIds: rows.map(({ id }) => id)
16860
16917
  };
16861
16918
  }
16862
- if (rows.length !== 1 || markedRows.length !== 1) {
16919
+ const unmarkedCommandRows = rows.filter((row2) => row2.trusted_run_context === void 0 && row2.execution_mode === void 0 && row2.command !== void 0);
16920
+ if (markedRows.length !== 1 || markedRows.length + unmarkedCommandRows.length !== rows.length) {
16863
16921
  throw new TrustedRunContextRecoveryError("Trusted processing rows are inconsistent");
16864
16922
  }
16865
16923
  const row = markedRows[0];
@@ -17018,14 +17076,7 @@ var Agent = class {
17018
17076
  });
17019
17077
  let capabilityRuntime;
17020
17078
  if (this.queue_project_id === null) {
17021
- if (expectedRevision) {
17022
- throw new CapabilityRuntimeResolutionError(
17023
- "CAPABILITY_RUNTIME_REVISION_MISMATCH",
17024
- "Capability runtime revision no longer matches the checkpoint",
17025
- { expectedRevision, actualRevision: "" }
17026
- );
17027
- }
17028
- capabilityRuntime = { revision: "", middleware: {} };
17079
+ capabilityRuntime = emptyCapabilityRuntime(expectedRevision);
17029
17080
  } else {
17030
17081
  capabilityRuntime = await resolver.resolve({
17031
17082
  tenantId: this.tenant_id,
@@ -17156,7 +17207,7 @@ var Agent = class {
17156
17207
  const persistedConfig = recoveryContext?.customRunConfig;
17157
17208
  const queuedRevision = typeof persistedConfig === "object" && persistedConfig !== null ? persistedConfig.capabilityRuntimeRevision : void 0;
17158
17209
  if (recoveryContext?.trustedRunContext !== void 0) {
17159
- return requireTrustedCapabilityRevision(queuedRevision);
17210
+ return trustedCapabilityRevision(queuedRevision);
17160
17211
  }
17161
17212
  const persistedRevision = typeof queuedRevision === "string" && queuedRevision.length > 0 ? queuedRevision : void 0;
17162
17213
  if (persistedRevision !== void 0 && recoveryContext.checkpointCapabilityRevision !== void 0 && persistedRevision !== recoveryContext.checkpointCapabilityRevision) {
@@ -17175,7 +17226,7 @@ var Agent = class {
17175
17226
  const emittedToolCallIds = /* @__PURE__ */ new Set();
17176
17227
  for await (const chunk of agentStream) {
17177
17228
  if (signal?.aborted) {
17178
- await this.chunkBuffer.abortThread(this.thread_id);
17229
+ await this.chunkBuffer.abortThread(this.thread_id, "Thread aborted", "aborted");
17179
17230
  throw new Error("Agent execution was aborted");
17180
17231
  }
17181
17232
  let data;
@@ -17293,6 +17344,7 @@ var Agent = class {
17293
17344
  this.abortController.abort();
17294
17345
  this.abortController = null;
17295
17346
  }
17347
+ void this.chunkBuffer.abortThread(this.thread_id, "Thread superseded", "superseded");
17296
17348
  }
17297
17349
  /**
17298
17350
  * Enqueue a message for this thread.
@@ -17675,16 +17727,18 @@ var Agent = class {
17675
17727
  }
17676
17728
  if (runStatus === "busy" /* BUSY */) {
17677
17729
  this.abortController = new AbortController();
17730
+ const resumeSignal = this.abortController.signal;
17678
17731
  try {
17679
17732
  const executionContext = this.processingExecutionContext(processingMessages, true);
17680
17733
  const customRunConfig = executionContext.customRunConfig;
17681
- if (typeof customRunConfig.capabilityRuntimeRevision !== "string" || executionContext.trustedRunContext !== void 0 && customRunConfig.capabilityRuntimeRevision.length === 0) {
17734
+ if (typeof customRunConfig.capabilityRuntimeRevision !== "string") {
17682
17735
  throw new Error("Capability runtime revision is missing from the checkpoint message");
17683
17736
  }
17737
+ const resumeRunConfig = executionContext.trustedRunContext !== void 0 && customRunConfig.capabilityRuntimeRevision === "" ? { ...customRunConfig, capabilityRuntimeRevision: void 0 } : customRunConfig;
17684
17738
  await this.resumeGraphFromCheckpoint(
17685
- customRunConfig,
17739
+ resumeRunConfig,
17686
17740
  executionContext.trustedRunContext,
17687
- this.abortController.signal
17741
+ resumeSignal
17688
17742
  );
17689
17743
  const state = await this.getCurrentState();
17690
17744
  const resumedStatus = await this.getRunStatus(state);
@@ -17728,7 +17782,12 @@ var Agent = class {
17728
17782
  };
17729
17783
  } catch (error) {
17730
17784
  console.error(`[Agent] Failed to resume graph for thread ${this.thread_id}:`, error);
17731
- await this.chunkBuffer.abortThread(this.thread_id);
17785
+ const endCode = resumeSignal.aborted ? "aborted" : "stream_error";
17786
+ await this.chunkBuffer.abortThread(
17787
+ this.thread_id,
17788
+ endCode === "aborted" ? "Thread aborted" : error instanceof Error ? error.message : "Resume failed",
17789
+ endCode
17790
+ );
17732
17791
  throw error;
17733
17792
  } finally {
17734
17793
  this.abortController = null;
@@ -17778,7 +17837,7 @@ var Agent = class {
17778
17837
  this.abortController.abort();
17779
17838
  this.abortController = null;
17780
17839
  }
17781
- await this.chunkBuffer.abortThread(this.thread_id);
17840
+ await this.chunkBuffer.abortThread(this.thread_id, "Thread aborted", "aborted");
17782
17841
  const store = this.getQueueStore();
17783
17842
  await store.clearMessages(this.thread_id, this.queueScope());
17784
17843
  }
@@ -25761,6 +25820,13 @@ When a bot is @mentioned, that bot answers; you stay silent unless asked.
25761
25820
  - Someone @mentions a bot \u2192 let that bot respond. Only correct or summarize when the bot fails or the user asks you.
25762
25821
  - @team mention \u2192 treat as addressed to you; you may summarize and optionally propose task work.
25763
25822
 
25823
+ ## Clarifying questions
25824
+ When you need more information before acting, ask the user directly in your room
25825
+ reply text and then stop. Do NOT use HITL/approval tools such as
25826
+ \`ask_user_to_clarify\`: project rooms are asynchronous and have no interactive
25827
+ approval UI, so an interrupt would stall the room with no visible prompt. The
25828
+ user's next room message continues the conversation.
25829
+
25764
25830
  ## Task policy
25765
25831
  - Turn actionable, verifiable room requests into persistent Project Tasks (task middleware), UNLESS they are simple, immediate, single-response work handled conversationally per the Delegation decision below.
25766
25832
  - A task must have an owner. Prefer assigning to a room bot via Project Task assignment.
@@ -28453,14 +28519,6 @@ var roomCoordinatorConfig = {
28453
28519
  enabled: true,
28454
28520
  config: { readAll: true }
28455
28521
  },
28456
- {
28457
- id: "ask_user_to_clarify",
28458
- type: "ask_user_to_clarify",
28459
- name: "Ask User",
28460
- description: "Wait for user input at approval gates",
28461
- enabled: true,
28462
- config: {}
28463
- },
28464
28522
  {
28465
28523
  id: "project_room",
28466
28524
  type: "project_room",
@@ -33926,6 +33984,7 @@ var INPUT_KEYS = [
33926
33984
  "idempotencyKey"
33927
33985
  ];
33928
33986
  var REPLY_INPUT_KEYS = ["tenantId", "membershipId", "text", "sourceRoomMessageId", "inputMessageId", "sourceId", "idempotencyKey"];
33987
+ var INTERRUPT_INPUT_KEYS = ["tenantId", "membershipId", "text", "sourceRoomMessageId", "inputMessageId"];
33929
33988
  var RoomAgentMessageService = class {
33930
33989
  /**
33931
33990
  * Creates a room writer over the durable membership and message stores.
@@ -33958,6 +34017,21 @@ var RoomAgentMessageService = class {
33958
34017
  }
33959
34018
  return this.persistDerived(snapshot);
33960
34019
  }
34020
+ /**
34021
+ * Persists a pending HITL interrupt (question/notice) as an Agent-authored room message.
34022
+ *
34023
+ * @param input Exact correlation IDs, target membership, and question text.
34024
+ * @returns A deep clone of the canonical idempotent room message.
34025
+ */
34026
+ postInterrupt(input) {
34027
+ const snapshot = exactStringRecord(input, INTERRUPT_INPUT_KEYS, "Invalid project room interrupt input");
34028
+ const sourceId = `interrupt:${snapshot.inputMessageId}`;
34029
+ return this.persistDerived({
34030
+ ...snapshot,
34031
+ sourceId,
34032
+ idempotencyKey: `room-interrupt:${snapshot.sourceRoomMessageId}:${snapshot.membershipId}:${sourceId}`
34033
+ });
34034
+ }
33961
34035
  async persistDerived(input) {
33962
34036
  const source = snapshotSource(await this.deps.messages.findById(input.tenantId, input.sourceRoomMessageId));
33963
34037
  if (!source || source.id !== input.sourceRoomMessageId || source.tenantId !== input.tenantId) throw new Error("Invalid project room message");
@@ -34036,24 +34110,37 @@ function date(value) {
34036
34110
  }
34037
34111
  function snapshotSource(value) {
34038
34112
  const values = exactValues(value, ["id", "tenantId", "workspaceId", "projectId", "roomId", "author", "content", "mentions", "source", "createdAt"], ["replyToMessageId", "sourceId", "idempotencyKey"]);
34039
- const author = exactValues(values?.author, ["type", "userId"]);
34113
+ const author = snapshotSourceAuthor(values?.author);
34040
34114
  const content = exactValues(values?.content, ["type", "text"]);
34041
34115
  const createdAt = date(values?.createdAt);
34042
34116
  const mentions = snapshotMentions(values?.mentions);
34043
- if (!values || values.source !== "user" || author?.type !== "human" || typeof author.userId !== "string" || !author.userId || content?.type !== "text" || typeof content.text !== "string" || !mentions || !createdAt || ["id", "tenantId", "workspaceId", "projectId", "roomId"].some((key5) => typeof values[key5] !== "string" || !values[key5])) return void 0;
34117
+ if (!values || !author || !sourceOriginMatches(author, values.source) || content?.type !== "text" || typeof content.text !== "string" || !mentions || !createdAt || ["id", "tenantId", "workspaceId", "projectId", "roomId"].some((key5) => typeof values[key5] !== "string" || !values[key5])) return void 0;
34044
34118
  return {
34045
34119
  id: values.id,
34046
34120
  tenantId: values.tenantId,
34047
34121
  workspaceId: values.workspaceId,
34048
34122
  projectId: values.projectId,
34049
34123
  roomId: values.roomId,
34050
- author: { type: "human", userId: author.userId },
34124
+ author,
34051
34125
  content: { type: "text", text: content.text },
34052
34126
  mentions,
34053
- source: "user",
34127
+ source: values.source,
34054
34128
  createdAt
34055
34129
  };
34056
34130
  }
34131
+ function snapshotSourceAuthor(value) {
34132
+ const human = exactValues(value, ["type", "userId"]);
34133
+ if (human?.type === "human" && typeof human.userId === "string" && human.userId.length > 0) {
34134
+ return { type: "human", userId: human.userId };
34135
+ }
34136
+ const system = exactValues(value, ["type"]);
34137
+ return system?.type === "system" ? { type: "system" } : void 0;
34138
+ }
34139
+ function sourceOriginMatches(author, source) {
34140
+ if (author.type === "human") return source === "user";
34141
+ if (author.type === "system") return source === "task";
34142
+ return false;
34143
+ }
34057
34144
  function snapshotMentions(value) {
34058
34145
  const rows = snapshotExactArray(value);
34059
34146
  if (!rows) return void 0;
@@ -39681,6 +39768,17 @@ function createAskUserToClarifyTool() {
39681
39768
  }
39682
39769
 
39683
39770
  // src/middlewares/askUserClarifyMiddleware.ts
39771
+ function isRecord9(value) {
39772
+ return typeof value === "object" && value !== null && !Array.isArray(value);
39773
+ }
39774
+ function isProjectRoomRun(request) {
39775
+ if (!isRecord9(request) || !isRecord9(request.runtime)) return false;
39776
+ const runtime = request.runtime;
39777
+ const configurable = isRecord9(runtime.configurable) ? runtime.configurable.runConfig : void 0;
39778
+ const context = isRecord9(runtime.context) ? runtime.context.runConfig : void 0;
39779
+ const runConfig = isRecord9(configurable) ? configurable : isRecord9(context) ? context : void 0;
39780
+ return isRecord9(runConfig?.projectRoom);
39781
+ }
39684
39782
  function createAskUserClarifyMiddleware() {
39685
39783
  return createMiddleware22({
39686
39784
  name: "AskUserClarifyMiddleware",
@@ -39691,6 +39789,13 @@ function createAskUserClarifyMiddleware() {
39691
39789
  if (toolName2 !== "ask_user_to_clarify") {
39692
39790
  return handler(request);
39693
39791
  }
39792
+ if (isProjectRoomRun(request)) {
39793
+ return new ToolMessage10({
39794
+ content: "You are replying inside a project room, which has no interactive clarification UI. Ask your clarifying questions directly in your reply text and stop; the user's next room message will continue the conversation.",
39795
+ tool_call_id: toolCall?.id,
39796
+ name: toolName2
39797
+ });
39798
+ }
39694
39799
  const parsed = inputSchema.safeParse(toolCall?.args);
39695
39800
  if (!parsed.success) {
39696
39801
  return new ToolMessage10({
@@ -41756,12 +41861,20 @@ function createTaskMiddleware(options = {}) {
41756
41861
  sourceId: trustedProject?.projectRoom?.sourceRoomMessageId ?? trustedProject?.projectTask?.inputMessageId ?? input.sourceId,
41757
41862
  context: trustedProject?.projectTask ? {
41758
41863
  ...trustedSharedContext(input.context),
41759
- source: "project_task"
41864
+ source: "project_task",
41865
+ created_by: {
41866
+ assistantId: trustedProject.projectTask.assistantId,
41867
+ membershipId: trustedProject.projectTask.membershipId
41868
+ }
41760
41869
  } : trustedProject?.projectRoom ? {
41761
41870
  ...trustedSharedContext(input.context),
41762
41871
  source: "project_room",
41763
41872
  room_id: trustedProject.projectRoom.roomId,
41764
- source_message_id: trustedProject.projectRoom.sourceRoomMessageId
41873
+ source_message_id: trustedProject.projectRoom.sourceRoomMessageId,
41874
+ created_by: {
41875
+ assistantId: trustedProject.projectRoom.assistantId,
41876
+ membershipId: trustedProject.projectRoom.membershipId
41877
+ }
41765
41878
  } : input.context,
41766
41879
  requireReview: input.requireReview,
41767
41880
  dependencies: input.dependencies,
@@ -42584,6 +42697,15 @@ function createTaskMiddleware(options = {}) {
42584
42697
  if (!needsReview) {
42585
42698
  const callerError2 = await revalidateCaller();
42586
42699
  if (callerError2) return callerError2;
42700
+ if (existing.status === "interrupted" && !reviewInterruption(existing)) {
42701
+ const resumed = await lifecycle.resumeInterruption({
42702
+ tenantId: tenantId2,
42703
+ taskId: input.id,
42704
+ actor,
42705
+ threadId: statusThreadId
42706
+ });
42707
+ if (!resumed.success) return lifecycleMutationResponse(resumed);
42708
+ }
42587
42709
  const result = existing.status === "completed" ? await lifecycle.repairCompletion(completionInput) : await lifecycle.completeAgentTask(completionInput);
42588
42710
  return lifecycleMutationResponse(result);
42589
42711
  }
@@ -45358,6 +45480,7 @@ export {
45358
45480
  InMemoryTenantStore,
45359
45481
  InMemoryThreadMessageQueueStore,
45360
45482
  InMemoryThreadStore,
45483
+ InMemoryUserPushSubscriptionStore,
45361
45484
  InMemoryUserStore,
45362
45485
  InMemoryUserTenantLinkStore,
45363
45486
  LINE_NUMBER_WIDTH,
@@ -45399,6 +45522,7 @@ export {
45399
45522
  Protocols,
45400
45523
  QueueLatticeManager,
45401
45524
  QueueMode,
45525
+ ROOM_COORDINATOR_KEY,
45402
45526
  RemoteSandboxInstance,
45403
45527
  RemoteSandboxProvider,
45404
45528
  RoomAgentMessageService,
@@ -45427,6 +45551,7 @@ export {
45427
45551
  TaskStatus,
45428
45552
  TeamAgentGraphBuilder,
45429
45553
  TenantPluginCatalog,
45554
+ ThreadEndError,
45430
45555
  ThreadStatus2 as ThreadStatus,
45431
45556
  TokenCache,
45432
45557
  ToolLatticeManager,
@@ -45624,6 +45749,7 @@ export {
45624
45749
  resolvePath,
45625
45750
  resolveSandboxPluginConnections,
45626
45751
  resolveTenantPluginSkill,
45752
+ roomCoordinatorConfig,
45627
45753
  runRemotePackDirectory,
45628
45754
  safeTaskResponseId,
45629
45755
  sandboxLatticeManager,