@lota-sdk/core 0.1.48 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lota-sdk/core",
3
- "version": "0.1.48",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -32,7 +32,7 @@
32
32
  "@chat-adapter/slack": "^4.23.0",
33
33
  "@chat-adapter/state-ioredis": "^4.23.0",
34
34
  "@logtape/logtape": "^2.0.5",
35
- "@lota-sdk/shared": "0.1.48",
35
+ "@lota-sdk/shared": "0.2.1",
36
36
  "@mendable/firecrawl-js": "^4.18.0",
37
37
  "@surrealdb/node": "^3.0.3",
38
38
  "ai": "^6.0.141",
@@ -4,10 +4,11 @@ type ExecutionPlanPromptSummary = Pick<SerializableExecutionPlan, 'runId' | 'tit
4
4
 
5
5
  const EXECUTION_PLAN_AGENT_PROTOCOL_PROMPT = `<execution-plan-protocol>
6
6
  - Create execution plans for multi-step work. Review existing plans before creating new ones.
7
+ - The active execution runs in <execution-plan-state> are a summary inventory only. They list runId and title, not node-level state.
7
8
  - The runtime executor owns lifecycle truth. Do not claim node completion until the executor confirms.
8
- - Work only on active/ready nodes assigned to you. Stop at human gates.
9
+ - Do not invent or restate run/node lifecycle details that are not present in the prompt or tool results.
9
10
  - During plan-triggered turns, use the dedicated result-submission tool. Include handoffContext.
10
- - Treat the active execution runs in <execution-plan-state> as authoritative. Do not mutate run or node status in prose.
11
+ - Treat the active execution runs in <execution-plan-state> as authoritative for whether a plan already exists.
11
12
  - If contracts or criteria materially change, replace the plan.
12
13
  </execution-plan-protocol>`
13
14
 
@@ -741,6 +741,9 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
741
741
  const runAbort = createServerRunAbortController(
742
742
  runAbortSignals.filter((signal): signal is AbortSignal => Boolean(signal)),
743
743
  )
744
+ if (runAbort.signal.aborted) {
745
+ throw runAbort.signal.reason ?? new DOMException('The operation was aborted.', 'AbortError')
746
+ }
744
747
  // Plan turns run without the chat lease — don't claim the active run slot.
745
748
  if (params.kind !== 'planTurn') {
746
749
  await workstreamService.setActiveTurn(workstreamRef, serverRunId, params.streamId ?? null)
@@ -749,6 +752,11 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
749
752
  runTimer.step('set-active-run+stream')
750
753
 
751
754
  try {
755
+ const throwIfRunAborted = () => {
756
+ if (!runAbort.signal.aborted) return
757
+ throw runAbort.signal.reason ?? new DOMException('The operation was aborted.', 'AbortError')
758
+ }
759
+
752
760
  const buildAgentMetadataPatch = (agentId: string, agentName: string): NonNullable<MessageMetadata> => ({
753
761
  agentId,
754
762
  agentName,
@@ -771,6 +779,8 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
771
779
  agentName: string,
772
780
  metadataPatch?: NonNullable<MessageMetadata>,
773
781
  ) => {
782
+ throwIfRunAborted()
783
+
774
784
  const committed = withMessageCreatedAt(
775
785
  {
776
786
  ...response,
@@ -782,6 +792,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
782
792
  await workstreamMessageService.upsertMessages({ workstreamId: workstreamRef, messages: [committed] })
783
793
  currentMessages = upsertChatHistoryMessage(currentMessages, committed)
784
794
  allAssistantMessages = upsertChatHistoryMessage(allAssistantMessages, committed)
795
+ throwIfRunAborted()
785
796
 
786
797
  return committed
787
798
  }
@@ -843,6 +854,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
843
854
  const tools = runParams.filterTools ? runParams.filterTools(rawTools) : rawTools
844
855
  visibleTimer.step('build-agent-tools')
845
856
  streamCtx.memoryBlock = memoryBlock
857
+ throwIfRunAborted()
846
858
  const responseMessage = await streamAgentResponse(streamCtx, {
847
859
  agentId: runParams.agentId,
848
860
  mode: runParams.mode,
@@ -902,6 +914,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
902
914
  const wsMembers = (workstream as { members?: string[] }).members ?? []
903
915
  const members = wsMembers.length > 0 ? wsMembers : [...agentRoster]
904
916
  const fallbackAgentId = coreWorkstreamProfile?.config.agentId ?? defaultLeadAgentId
917
+ throwIfRunAborted()
905
918
  writeMultiAgentEvent(writer, { phase: 'routing', note: 'Routing this turn to the right agent.' })
906
919
 
907
920
  const recentContext = currentMessages
@@ -915,6 +928,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
915
928
  messageText,
916
929
  recentContext,
917
930
  })
931
+ throwIfRunAborted()
918
932
 
919
933
  const runGroupAgent = async (
920
934
  agentId: string,
@@ -941,6 +955,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
941
955
  if (!triageResult) {
942
956
  // No specialist match — fallback to owner (core) or chief (non-core), single visible turn.
943
957
  await runGroupAgent(fallbackAgentId)
958
+ throwIfRunAborted()
944
959
  writeMultiAgentEvent(writer, { phase: 'complete' })
945
960
  } else {
946
961
  const respondedAgents: string[] = []
@@ -948,6 +963,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
948
963
  routingContext: triageResult.routingContext,
949
964
  })
950
965
  respondedAgents.push(triageResult.agentId)
966
+ throwIfRunAborted()
951
967
 
952
968
  // Follow-up specialists run headless, persist their own messages,
953
969
  // and are surfaced by transient events plus cache refresh.
@@ -960,6 +976,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
960
976
  respondedAgents,
961
977
  lastResponseSummary: lastResponseText,
962
978
  })
979
+ throwIfRunAborted()
963
980
 
964
981
  if (checkResult.done || !checkResult.agentId) break
965
982
 
@@ -982,17 +999,20 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
982
999
  ],
983
1000
  metadata: { hidden: true, createdAt: Date.now() } as MessageMetadata,
984
1001
  }
1002
+ throwIfRunAborted()
985
1003
  await workstreamMessageService.upsertMessages({
986
1004
  workstreamId: workstreamRef,
987
1005
  messages: [bridgeMessage],
988
1006
  })
989
1007
  currentMessages = upsertChatHistoryMessage(currentMessages, bridgeMessage)
1008
+ throwIfRunAborted()
990
1009
 
991
1010
  lastResponse = await runGroupAgent(checkResult.agentId, {
992
1011
  routingContext: checkResult.routingContext,
993
1012
  headless: true,
994
1013
  })
995
1014
  respondedAgents.push(checkResult.agentId)
1015
+ throwIfRunAborted()
996
1016
  writeMultiAgentEvent(writer, {
997
1017
  phase: 'agent-message-persisted',
998
1018
  agentId: checkResult.agentId,
@@ -1001,6 +1021,7 @@ export async function prepareWorkstreamRunCore(params: WorkstreamRunCoreParams):
1001
1021
  })
1002
1022
  }
1003
1023
 
1024
+ throwIfRunAborted()
1004
1025
  writeMultiAgentEvent(writer, { phase: 'complete' })
1005
1026
  }
1006
1027
  }