@lota-sdk/core 0.4.8 → 0.4.10

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.
Files changed (272) hide show
  1. package/package.json +11 -12
  2. package/src/ai/embedding-cache.ts +96 -22
  3. package/src/ai-gateway/ai-gateway.ts +766 -223
  4. package/src/config/agent-defaults.ts +189 -75
  5. package/src/config/agent-types.ts +54 -4
  6. package/src/config/background-processing.ts +1 -1
  7. package/src/config/constants.ts +8 -2
  8. package/src/config/index.ts +0 -1
  9. package/src/config/logger.ts +299 -19
  10. package/src/config/thread-defaults.ts +40 -20
  11. package/src/create-runtime.ts +200 -449
  12. package/src/db/base.service.ts +52 -28
  13. package/src/db/cursor-pagination.ts +71 -30
  14. package/src/db/memory-query-builder.ts +2 -1
  15. package/src/db/memory-store.helpers.ts +4 -7
  16. package/src/db/memory-store.ts +868 -601
  17. package/src/db/memory.ts +396 -280
  18. package/src/db/record-id.ts +32 -10
  19. package/src/db/schema-fingerprint.ts +30 -12
  20. package/src/db/service-normalization.ts +288 -0
  21. package/src/db/service.ts +912 -779
  22. package/src/db/startup.ts +153 -68
  23. package/src/db/transaction-conflict.ts +15 -0
  24. package/src/effect/awaitable-effect.ts +96 -0
  25. package/src/effect/errors.ts +121 -0
  26. package/src/effect/helpers.ts +123 -0
  27. package/src/effect/index.ts +24 -0
  28. package/src/effect/layers.ts +238 -0
  29. package/src/effect/runtime-ref.ts +25 -0
  30. package/src/effect/runtime.ts +46 -0
  31. package/src/effect/services.ts +61 -0
  32. package/src/effect/zod.ts +43 -0
  33. package/src/embeddings/provider.ts +128 -83
  34. package/src/index.ts +48 -1
  35. package/src/openrouter/direct-provider.ts +11 -35
  36. package/src/queues/autonomous-job.queue.ts +117 -73
  37. package/src/queues/context-compaction.queue.ts +50 -17
  38. package/src/queues/delayed-node-promotion.queue.ts +46 -17
  39. package/src/queues/document-processor.queue.ts +52 -77
  40. package/src/queues/memory-consolidation.queue.ts +47 -32
  41. package/src/queues/organization-learning.queue.ts +26 -4
  42. package/src/queues/plan-agent-heartbeat.queue.ts +71 -24
  43. package/src/queues/plan-scheduler.queue.ts +97 -33
  44. package/src/queues/post-chat-memory.queue.ts +56 -26
  45. package/src/queues/queue-factory.ts +227 -59
  46. package/src/queues/standalone-worker.ts +39 -0
  47. package/src/queues/title-generation.queue.ts +45 -11
  48. package/src/redis/connection.ts +182 -113
  49. package/src/redis/index.ts +6 -8
  50. package/src/redis/org-memory-lock.ts +60 -27
  51. package/src/redis/redis-lease-lock.ts +200 -121
  52. package/src/redis/runtime-connection.ts +20 -0
  53. package/src/redis/stream-context.ts +92 -46
  54. package/src/runtime/agent-identity-overrides.ts +2 -2
  55. package/src/runtime/agent-runtime-policy.ts +5 -2
  56. package/src/runtime/agent-stream-helpers.ts +24 -9
  57. package/src/runtime/chat-run-orchestration.ts +102 -19
  58. package/src/runtime/chat-run-registry.ts +36 -2
  59. package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
  60. package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +161 -94
  61. package/src/runtime/domain-layer.ts +192 -0
  62. package/src/runtime/execution-plan-visibility.ts +2 -2
  63. package/src/runtime/execution-plan.ts +42 -15
  64. package/src/runtime/graph-designer.ts +16 -4
  65. package/src/runtime/helper-model.ts +139 -48
  66. package/src/runtime/index.ts +7 -8
  67. package/src/runtime/indexed-repositories-policy.ts +3 -3
  68. package/src/runtime/{memory-block.ts → memory/memory-block.ts} +50 -36
  69. package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
  70. package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +54 -67
  71. package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
  72. package/src/runtime/memory/memory-scope.ts +53 -0
  73. package/src/runtime/plugin-resolution.ts +124 -25
  74. package/src/runtime/plugin-types.ts +9 -1
  75. package/src/runtime/post-turn-side-effects.ts +177 -130
  76. package/src/runtime/retrieval-adapters.ts +40 -6
  77. package/src/runtime/runtime-accessors.ts +92 -0
  78. package/src/runtime/runtime-config.ts +150 -61
  79. package/src/runtime/runtime-extensions.ts +23 -25
  80. package/src/runtime/runtime-lifecycle.ts +124 -0
  81. package/src/runtime/runtime-services.ts +386 -0
  82. package/src/runtime/runtime-token.ts +47 -0
  83. package/src/runtime/social-chat/social-chat-agent-runner.ts +159 -0
  84. package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +51 -20
  85. package/src/runtime/social-chat/social-chat.ts +630 -0
  86. package/src/runtime/specialist-runner.ts +36 -10
  87. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +433 -0
  88. package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
  89. package/src/runtime/thread-chat-helpers.ts +2 -2
  90. package/src/runtime/thread-plan-turn.ts +2 -1
  91. package/src/runtime/thread-turn-context.ts +183 -111
  92. package/src/runtime/turn-lifecycle.ts +93 -27
  93. package/src/services/agent-activity.service.ts +287 -203
  94. package/src/services/agent-executor.service.ts +253 -149
  95. package/src/services/artifact.service.ts +231 -149
  96. package/src/services/attachment.service.ts +171 -115
  97. package/src/services/autonomous-job.service.ts +890 -491
  98. package/src/services/background-work.service.ts +54 -0
  99. package/src/services/chat-run-registry.service.ts +13 -1
  100. package/src/services/context-compaction.service.ts +136 -86
  101. package/src/services/document-chunk.service.ts +151 -88
  102. package/src/services/execution-plan/execution-plan-approval.ts +26 -0
  103. package/src/services/execution-plan/execution-plan-context.ts +29 -0
  104. package/src/services/execution-plan/execution-plan-graph.ts +278 -0
  105. package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
  106. package/src/services/execution-plan/execution-plan-spec.ts +75 -0
  107. package/src/services/execution-plan/execution-plan.service.ts +1041 -0
  108. package/src/services/feedback-loop.service.ts +132 -76
  109. package/src/services/global-orchestrator.service.ts +101 -168
  110. package/src/services/graph-full-routing.ts +193 -0
  111. package/src/services/index.ts +19 -21
  112. package/src/services/institutional-memory.service.ts +213 -125
  113. package/src/services/learned-skill.service.ts +368 -260
  114. package/src/services/memory/memory-conversation.ts +95 -0
  115. package/src/services/memory/memory-errors.ts +27 -0
  116. package/src/services/memory/memory-org-memory.ts +50 -0
  117. package/src/services/memory/memory-preseeded.ts +86 -0
  118. package/src/services/memory/memory-rerank.ts +297 -0
  119. package/src/services/{memory-utils.ts → memory/memory-utils.ts} +6 -5
  120. package/src/services/memory/memory.service.ts +674 -0
  121. package/src/services/memory/rerank.service.ts +201 -0
  122. package/src/services/monitoring-window.service.ts +92 -70
  123. package/src/services/mutating-approval.service.ts +62 -53
  124. package/src/services/node-workspace.service.ts +141 -98
  125. package/src/services/notification.service.ts +29 -16
  126. package/src/services/organization-member.service.ts +120 -66
  127. package/src/services/organization.service.ts +153 -77
  128. package/src/services/ownership-dispatcher.service.ts +456 -263
  129. package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
  130. package/src/services/plan/plan-agent-query.service.ts +322 -0
  131. package/src/services/{plan-approval.service.ts → plan/plan-approval.service.ts} +45 -22
  132. package/src/services/plan/plan-artifact.service.ts +60 -0
  133. package/src/services/plan/plan-builder.service.ts +76 -0
  134. package/src/services/plan/plan-checkpoint.service.ts +103 -0
  135. package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
  136. package/src/services/plan/plan-completion-side-effects.ts +169 -0
  137. package/src/services/plan/plan-coordination.service.ts +181 -0
  138. package/src/services/plan/plan-cycle.service.ts +405 -0
  139. package/src/services/plan/plan-deadline.service.ts +533 -0
  140. package/src/services/plan/plan-event-delivery.service.ts +266 -0
  141. package/src/services/plan/plan-executor-context.ts +35 -0
  142. package/src/services/plan/plan-executor-graph.ts +522 -0
  143. package/src/services/plan/plan-executor-helpers.ts +307 -0
  144. package/src/services/plan/plan-executor-persistence.ts +209 -0
  145. package/src/services/plan/plan-executor.service.ts +1737 -0
  146. package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
  147. package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
  148. package/src/services/plan/plan-run-serialization.ts +15 -0
  149. package/src/services/plan/plan-run.service.ts +637 -0
  150. package/src/services/plan/plan-scheduler.service.ts +379 -0
  151. package/src/services/plan/plan-template.service.ts +224 -0
  152. package/src/services/plan/plan-transaction-events.ts +36 -0
  153. package/src/services/plan/plan-validator.service.ts +907 -0
  154. package/src/services/plan/plan-workspace.service.ts +131 -0
  155. package/src/services/plugin-executor.service.ts +102 -68
  156. package/src/services/quality-metrics.service.ts +112 -94
  157. package/src/services/queue-job.service.ts +288 -231
  158. package/src/services/recent-activity-title.service.ts +73 -36
  159. package/src/services/recent-activity.service.ts +274 -259
  160. package/src/services/skill-resolver.service.ts +38 -12
  161. package/src/services/social-chat-history.service.ts +190 -122
  162. package/src/services/system-executor.service.ts +96 -61
  163. package/src/services/thread/thread-active-run.ts +203 -0
  164. package/src/services/thread/thread-bootstrap.ts +385 -0
  165. package/src/services/thread/thread-listing.ts +199 -0
  166. package/src/services/thread/thread-memory-block.ts +130 -0
  167. package/src/services/thread/thread-message.service.ts +379 -0
  168. package/src/services/thread/thread-record-store.ts +155 -0
  169. package/src/services/thread/thread-title.service.ts +74 -0
  170. package/src/services/thread/thread-turn-execution.ts +280 -0
  171. package/src/services/thread/thread-turn-message-context.ts +73 -0
  172. package/src/services/thread/thread-turn-preparation.service.ts +1148 -0
  173. package/src/services/thread/thread-turn-streaming.ts +403 -0
  174. package/src/services/thread/thread-turn-tracing.ts +35 -0
  175. package/src/services/thread/thread-turn.ts +376 -0
  176. package/src/services/thread/thread.service.ts +344 -0
  177. package/src/services/user.service.ts +82 -32
  178. package/src/services/write-intent-validator.service.ts +63 -51
  179. package/src/storage/attachment-parser.ts +69 -27
  180. package/src/storage/attachment-storage.service.ts +334 -275
  181. package/src/storage/generated-document-storage.service.ts +66 -34
  182. package/src/system-agents/agent-result.ts +3 -1
  183. package/src/system-agents/context-compaction.agent.ts +3 -3
  184. package/src/system-agents/delegated-agent-factory.ts +159 -90
  185. package/src/system-agents/helper-agent-options.ts +1 -1
  186. package/src/system-agents/memory-reranker.agent.ts +3 -3
  187. package/src/system-agents/memory.agent.ts +3 -3
  188. package/src/system-agents/recent-activity-title-refiner.agent.ts +3 -3
  189. package/src/system-agents/regular-chat-memory-digest.agent.ts +3 -3
  190. package/src/system-agents/skill-extractor.agent.ts +3 -3
  191. package/src/system-agents/skill-manager.agent.ts +3 -3
  192. package/src/system-agents/thread-router.agent.ts +157 -113
  193. package/src/system-agents/title-generator.agent.ts +3 -3
  194. package/src/tools/execution-plan.tool.ts +241 -171
  195. package/src/tools/fetch-webpage.tool.ts +29 -18
  196. package/src/tools/firecrawl-client.ts +26 -6
  197. package/src/tools/index.ts +1 -0
  198. package/src/tools/memory-block.tool.ts +14 -6
  199. package/src/tools/plan-approval.tool.ts +57 -47
  200. package/src/tools/read-file-parts.tool.ts +44 -33
  201. package/src/tools/remember-memory.tool.ts +65 -45
  202. package/src/tools/search-web.tool.ts +33 -22
  203. package/src/tools/search.tool.ts +41 -29
  204. package/src/tools/team-think.tool.ts +125 -84
  205. package/src/tools/user-questions.tool.ts +4 -3
  206. package/src/tools/web-tool-shared.ts +6 -0
  207. package/src/utils/async.ts +25 -22
  208. package/src/utils/crypto.ts +21 -0
  209. package/src/utils/date-time.ts +40 -1
  210. package/src/utils/errors.ts +111 -20
  211. package/src/utils/hono-error-handler.ts +24 -39
  212. package/src/utils/index.ts +2 -1
  213. package/src/utils/null-proto-record.ts +41 -0
  214. package/src/utils/sse-keepalive.ts +124 -21
  215. package/src/workers/bootstrap.ts +164 -52
  216. package/src/workers/memory-consolidation.worker.ts +325 -237
  217. package/src/workers/organization-learning.worker.ts +50 -16
  218. package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
  219. package/src/workers/regular-chat-memory-digest.runner.ts +185 -114
  220. package/src/workers/skill-extraction.runner.ts +176 -93
  221. package/src/workers/utils/file-section-chunker.ts +8 -10
  222. package/src/workers/utils/repo-structure-extractor.ts +349 -260
  223. package/src/workers/utils/repomix-file-sections.ts +2 -2
  224. package/src/workers/utils/thread-message-query.ts +97 -38
  225. package/src/workers/worker-utils.ts +74 -31
  226. package/src/config/debug-logger.ts +0 -47
  227. package/src/config/search.ts +0 -3
  228. package/src/redis/connection-accessor.ts +0 -26
  229. package/src/runtime/agent-types.ts +0 -1
  230. package/src/runtime/context-compaction-runtime.ts +0 -87
  231. package/src/runtime/memory-scope.ts +0 -43
  232. package/src/runtime/social-chat-agent-runner.ts +0 -118
  233. package/src/runtime/social-chat.ts +0 -516
  234. package/src/runtime/team-consultation-orchestrator.ts +0 -272
  235. package/src/services/adaptive-playbook.service.ts +0 -152
  236. package/src/services/artifact-provenance.service.ts +0 -172
  237. package/src/services/chat-attachments.service.ts +0 -17
  238. package/src/services/context-compaction-runtime.singleton.ts +0 -13
  239. package/src/services/execution-plan.service.ts +0 -1118
  240. package/src/services/memory.service.ts +0 -914
  241. package/src/services/plan-agent-heartbeat.service.ts +0 -136
  242. package/src/services/plan-agent-query.service.ts +0 -267
  243. package/src/services/plan-artifact.service.ts +0 -50
  244. package/src/services/plan-builder.service.ts +0 -67
  245. package/src/services/plan-checkpoint.service.ts +0 -81
  246. package/src/services/plan-completion-side-effects.ts +0 -80
  247. package/src/services/plan-coordination.service.ts +0 -157
  248. package/src/services/plan-cycle.service.ts +0 -284
  249. package/src/services/plan-deadline.service.ts +0 -430
  250. package/src/services/plan-event-delivery.service.ts +0 -166
  251. package/src/services/plan-executor.service.ts +0 -1950
  252. package/src/services/plan-run.service.ts +0 -515
  253. package/src/services/plan-scheduler.service.ts +0 -240
  254. package/src/services/plan-template.service.ts +0 -177
  255. package/src/services/plan-validator.service.ts +0 -818
  256. package/src/services/plan-workspace.service.ts +0 -83
  257. package/src/services/rerank.service.ts +0 -156
  258. package/src/services/thread-message.service.ts +0 -275
  259. package/src/services/thread-plan-registry.service.ts +0 -22
  260. package/src/services/thread-title.service.ts +0 -39
  261. package/src/services/thread-turn-preparation.service.ts +0 -1147
  262. package/src/services/thread-turn.ts +0 -172
  263. package/src/services/thread.service.ts +0 -869
  264. package/src/utils/env.ts +0 -8
  265. /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
  266. /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
  267. /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
  268. /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
  269. /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
  270. /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
  271. /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
  272. /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
@@ -1,272 +0,0 @@
1
- import { ConsultTeamArgsSchema, withMessageCreatedAt } from '@lota-sdk/shared'
2
- import type { ChatMessage, ConsultTeamResultData } from '@lota-sdk/shared'
3
- import { convertToModelMessages, tool as createTool } from 'ai'
4
-
5
- import { agentDisplayNames, teamConsultParticipants } from '../config/agent-defaults'
6
- import { createTimedAbortSignal } from './agent-stream-helpers'
7
- import { buildModelInputMessagesWithUploadMetadata, buildReadableUploadMetadataText } from './chat-attachments'
8
- import type { ReadableUploadMetadataLike } from './chat-attachments'
9
- import type { RepoSectionName } from './indexed-repositories-policy'
10
- import { buildTeamConsultationFailureMessage } from './team-consultation-prompts'
11
- import { extractMessageText } from './thread-chat-helpers'
12
-
13
- export type DefaultRepoSections = RepoSectionName[]
14
- const TEAM_CONSULTATION_TIMEOUT_MS = 90_000
15
-
16
- function buildSnapshot(responses: ConsultTeamResultData['responses']): ConsultTeamResultData {
17
- return { responses: responses.map((response) => ({ ...response })) }
18
- }
19
-
20
- function getConsultTeamOutput(output: unknown): ConsultTeamResultData | undefined {
21
- if (output && typeof output === 'object' && Array.isArray((output as { responses?: unknown }).responses)) {
22
- return output as ConsultTeamResultData
23
- }
24
-
25
- if (Array.isArray(output)) {
26
- for (let index = output.length - 1; index >= 0; index -= 1) {
27
- const candidate = getConsultTeamOutput(output[index])
28
- if (candidate) return candidate
29
- }
30
- }
31
-
32
- return undefined
33
- }
34
-
35
- function findLastUserMessage(
36
- messages: ChatMessage[],
37
- predicate: (message: ChatMessage) => boolean,
38
- ): ChatMessage | null {
39
- for (let index = messages.length - 1; index >= 0; index -= 1) {
40
- const message = messages[index]
41
- if (predicate(message)) {
42
- return message
43
- }
44
- }
45
-
46
- return null
47
- }
48
-
49
- function selectTeamConsultationContextMessages(messages: ChatMessage[], latestUserMessageId: string): ChatMessage[] {
50
- const latestUserMessage =
51
- findLastUserMessage(messages, (message) => message.id === latestUserMessageId && message.role === 'user') ??
52
- findLastUserMessage(messages, (message) => message.role === 'user')
53
-
54
- return latestUserMessage ? [latestUserMessage] : []
55
- }
56
-
57
- interface ParticipantObserver {
58
- run<T>(fn: () => T | Promise<T>): Promise<T>
59
- recordError?: (error: unknown) => void
60
- recordAbort?: (error: unknown) => void
61
- }
62
-
63
- export interface TeamConsultationParticipantRunner {
64
- buildParticipantAgent(
65
- agentId: string,
66
- params: {
67
- task: string
68
- systemWorkspaceDetails?: string
69
- preSeededMemoriesSection?: string
70
- retrievedKnowledgeSection?: string
71
- },
72
- ): Promise<{
73
- agent: {
74
- generate(params: Record<string, unknown>): Promise<{ text: string }>
75
- stream(
76
- params: Record<string, unknown>,
77
- ): Promise<{
78
- consumeStream(): unknown
79
- toUIMessageStream(options: Record<string, unknown>): ReadableStream<unknown>
80
- }>
81
- }
82
- observer: ParticipantObserver
83
- }>
84
- }
85
-
86
- export interface CreateConsultTeamToolParams {
87
- historyMessages: ChatMessage[]
88
- latestUserMessageId: string
89
- availableUploads: ReadableUploadMetadataLike[]
90
- defaultRepoSectionsByAgent: Record<string, DefaultRepoSections | undefined>
91
- systemWorkspaceDetails?: string
92
- getPreSeededMemoriesSection: (agentId: string) => Promise<string | undefined>
93
- retrievedKnowledgeSection?: string
94
- displayNamesById?: Partial<Record<string, string>>
95
- abortSignal: AbortSignal
96
- participantRunner: TeamConsultationParticipantRunner
97
- onReadError?: (agentId: string, error: unknown) => void
98
- }
99
-
100
- export function createConsultTeamTool(params: CreateConsultTeamToolParams) {
101
- const resolveDisplayName = (agentId: string) => {
102
- if (params.displayNamesById && Object.hasOwn(params.displayNamesById, agentId)) {
103
- const override = params.displayNamesById[agentId]
104
- if (override !== undefined) {
105
- return override
106
- }
107
- }
108
-
109
- return agentDisplayNames[agentId] ?? agentId
110
- }
111
- const participantNames = teamConsultParticipants
112
- .map((agentId) => resolveDisplayName(agentId))
113
- .filter((value) => value.trim().length > 0)
114
- const participantSummary =
115
- participantNames.length > 0 ? participantNames.join(', ') : 'the configured specialist participants'
116
-
117
- return createTool({
118
- description: `Consult the specialist team in parallel before replying. Use this when the answer benefits from structured input across ${participantSummary}.`,
119
- inputSchema: ConsultTeamArgsSchema,
120
- execute: async function* ({ task }) {
121
- const uploadMetadataText = buildReadableUploadMetadataText(params.availableUploads)
122
- const responses: ConsultTeamResultData['responses'] = teamConsultParticipants.map((agentId) => ({
123
- agentId,
124
- agentName: resolveDisplayName(agentId),
125
- status: 'running',
126
- }))
127
- const queue: ConsultTeamResultData[] = []
128
- let wake: (() => void) | undefined
129
- let completedWorkers = 0
130
- let fatalError: unknown
131
-
132
- const pushSnapshot = () => {
133
- queue.push(buildSnapshot(responses))
134
- wake?.()
135
- wake = undefined
136
- }
137
-
138
- const workerPromises = teamConsultParticipants.map(async (agentId, index) => {
139
- const agentName = resolveDisplayName(agentId)
140
- const timedAbort = createTimedAbortSignal(params.abortSignal, TEAM_CONSULTATION_TIMEOUT_MS)
141
- let latestMessage: ChatMessage | null = null
142
-
143
- try {
144
- const { agent, observer } = await params.participantRunner.buildParticipantAgent(agentId, {
145
- task,
146
- systemWorkspaceDetails: params.systemWorkspaceDetails,
147
- preSeededMemoriesSection: await params.getPreSeededMemoriesSection(agentId),
148
- retrievedKnowledgeSection: params.retrievedKnowledgeSection,
149
- })
150
- const modelMessages = await convertToModelMessages(
151
- buildModelInputMessagesWithUploadMetadata({
152
- messages: selectTeamConsultationContextMessages(params.historyMessages, params.latestUserMessageId),
153
- latestUserMessageId: params.latestUserMessageId,
154
- uploadMetadataText,
155
- }),
156
- { ignoreIncompleteToolCalls: true },
157
- )
158
-
159
- let result: Awaited<ReturnType<typeof agent.generate>>
160
- try {
161
- result = await observer.run(() =>
162
- agent.generate({
163
- messages: modelMessages,
164
- abortSignal: timedAbort.signal,
165
- timeout: TEAM_CONSULTATION_TIMEOUT_MS,
166
- }),
167
- )
168
- } catch (error) {
169
- if (params.abortSignal.aborted || timedAbort.signal.aborted) {
170
- observer.recordAbort?.(error)
171
- } else {
172
- observer.recordError?.(error)
173
- }
174
- throw error
175
- }
176
-
177
- const responseText = result.text.trim()
178
- if (!responseText) {
179
- throw new Error(`Team participant ${agentId} did not produce a response.`)
180
- }
181
-
182
- latestMessage = withMessageCreatedAt(
183
- {
184
- id: Bun.randomUUIDv7(),
185
- role: 'assistant',
186
- parts: [{ type: 'text', text: responseText }],
187
- metadata: { agentId, agentName },
188
- } satisfies ChatMessage,
189
- Date.now(),
190
- )
191
-
192
- responses[index] = {
193
- agentId,
194
- agentName,
195
- status: 'complete',
196
- summary: extractMessageText(latestMessage).trim() || undefined,
197
- message: latestMessage,
198
- }
199
- pushSnapshot()
200
- } catch (error) {
201
- if (params.abortSignal.aborted) {
202
- fatalError = error
203
- wake?.()
204
- wake = undefined
205
- return
206
- }
207
-
208
- responses[index] = {
209
- agentId,
210
- agentName,
211
- status: 'error',
212
- summary: latestMessage ? extractMessageText(latestMessage).trim() || undefined : undefined,
213
- error: buildTeamConsultationFailureMessage(
214
- agentName,
215
- TEAM_CONSULTATION_TIMEOUT_MS,
216
- timedAbort.didTimeout(),
217
- error,
218
- ),
219
- ...(latestMessage ? { message: latestMessage } : {}),
220
- }
221
- pushSnapshot()
222
- } finally {
223
- timedAbort.dispose()
224
- completedWorkers += 1
225
- wake?.()
226
- wake = undefined
227
- }
228
- })
229
-
230
- pushSnapshot()
231
-
232
- while (queue.length > 0 || completedWorkers < teamConsultParticipants.length) {
233
- if (fatalError) {
234
- await Promise.allSettled(workerPromises)
235
- throw fatalError
236
- }
237
-
238
- if (queue.length === 0) {
239
- await new Promise<void>((resolve) => {
240
- wake = resolve
241
- })
242
- continue
243
- }
244
-
245
- const snapshot = queue.shift()
246
- if (snapshot) {
247
- yield snapshot
248
- }
249
- }
250
-
251
- await Promise.all(workerPromises)
252
- return buildSnapshot(responses)
253
- },
254
- toModelOutput: ({ output }) => {
255
- const result = getConsultTeamOutput(output)
256
- const summaryLines =
257
- result?.responses
258
- .map((response) => {
259
- const summary =
260
- typeof response.error === 'string' && response.error.trim().length > 0
261
- ? response.error.trim()
262
- : typeof response.summary === 'string' && response.summary.trim().length > 0
263
- ? response.summary.trim()
264
- : 'No response.'
265
- return `${response.agentName}: ${summary}`
266
- })
267
- .join('\n') ?? 'Team consultation completed.'
268
-
269
- return { type: 'text', value: summaryLines }
270
- },
271
- })
272
- }
@@ -1,152 +0,0 @@
1
- import type { PlaybookVersion, Recommendation } from '@lota-sdk/shared'
2
- import { PlaybookSchema, PlaybookVersionSchema } from '@lota-sdk/shared'
3
-
4
- import { ensureRecordId, recordIdToString } from '../db/record-id'
5
- import { databaseService } from '../db/service'
6
- import { TABLES } from '../db/tables'
7
-
8
- class AdaptivePlaybookService {
9
- async refineFromCycle(params: {
10
- playbookId: string
11
- runId: string
12
- recommendations: Recommendation[]
13
- organizationId: string
14
- }): Promise<PlaybookVersion> {
15
- const playbook = await databaseService.findOne(
16
- TABLES.PLAYBOOK,
17
- { id: ensureRecordId(params.playbookId, TABLES.PLAYBOOK) },
18
- PlaybookSchema,
19
- )
20
- if (!playbook) {
21
- throw new Error(`Playbook not found: ${params.playbookId}`)
22
- }
23
-
24
- const currentVersion = await databaseService.findOne(
25
- TABLES.PLAYBOOK_VERSION,
26
- {
27
- id: ensureRecordId(
28
- recordIdToString(playbook.currentVersionId, TABLES.PLAYBOOK_VERSION),
29
- TABLES.PLAYBOOK_VERSION,
30
- ),
31
- },
32
- PlaybookVersionSchema,
33
- )
34
-
35
- const nextVersionNumber = currentVersion ? currentVersion.version + 1 : 1
36
- const now = new Date()
37
-
38
- const newVersion = await databaseService.create(
39
- TABLES.PLAYBOOK_VERSION,
40
- {
41
- playbookId: ensureRecordId(params.playbookId, TABLES.PLAYBOOK),
42
- version: nextVersionNumber,
43
- parentVersionId: playbook.currentVersionId,
44
- appliedRecommendations: params.recommendations.map((r) => r.description),
45
- status: 'testing',
46
- createdAt: now,
47
- },
48
- PlaybookVersionSchema,
49
- )
50
-
51
- await databaseService.update(
52
- TABLES.PLAYBOOK,
53
- ensureRecordId(params.playbookId, TABLES.PLAYBOOK),
54
- {
55
- currentVersionId: newVersion.id,
56
- previousVersionId: playbook.currentVersionId,
57
- cycleCount: playbook.cycleCount + 1,
58
- },
59
- PlaybookSchema,
60
- )
61
-
62
- return newVersion
63
- }
64
-
65
- evaluateRegression(params: { currentScore: number; previousScore: number; threshold?: number }): {
66
- shouldRollback: boolean
67
- } {
68
- const threshold = params.threshold ?? 0.9
69
- if (params.previousScore === 0) return { shouldRollback: false }
70
- return { shouldRollback: params.currentScore < params.previousScore * threshold }
71
- }
72
-
73
- async rollback(params: {
74
- playbookId: string
75
- organizationId: string
76
- maxLevels?: number
77
- }): Promise<PlaybookVersion | null> {
78
- const maxLevels = params.maxLevels ?? 3
79
- return this.rollbackRecursive(params.playbookId, params.organizationId, maxLevels)
80
- }
81
-
82
- private async rollbackRecursive(
83
- playbookId: string,
84
- organizationId: string,
85
- remainingLevels: number,
86
- ): Promise<PlaybookVersion | null> {
87
- if (remainingLevels <= 0) return null
88
-
89
- const playbook = await databaseService.findOne(
90
- TABLES.PLAYBOOK,
91
- { id: ensureRecordId(playbookId, TABLES.PLAYBOOK) },
92
- PlaybookSchema,
93
- )
94
- if (!playbook) return null
95
-
96
- const currentVersion = await databaseService.findOne(
97
- TABLES.PLAYBOOK_VERSION,
98
- {
99
- id: ensureRecordId(
100
- recordIdToString(playbook.currentVersionId, TABLES.PLAYBOOK_VERSION),
101
- TABLES.PLAYBOOK_VERSION,
102
- ),
103
- },
104
- PlaybookVersionSchema,
105
- )
106
- if (!currentVersion?.parentVersionId) return null
107
-
108
- // Mark current version as rolled-back
109
- await databaseService.update(
110
- TABLES.PLAYBOOK_VERSION,
111
- ensureRecordId(recordIdToString(currentVersion.id, TABLES.PLAYBOOK_VERSION), TABLES.PLAYBOOK_VERSION),
112
- { status: 'rolled-back' },
113
- PlaybookVersionSchema,
114
- )
115
-
116
- // Restore parent version as active
117
- const parentVersion = await databaseService.findOne(
118
- TABLES.PLAYBOOK_VERSION,
119
- {
120
- id: ensureRecordId(
121
- recordIdToString(currentVersion.parentVersionId, TABLES.PLAYBOOK_VERSION),
122
- TABLES.PLAYBOOK_VERSION,
123
- ),
124
- },
125
- PlaybookVersionSchema,
126
- )
127
- if (!parentVersion) return null
128
-
129
- await databaseService.update(
130
- TABLES.PLAYBOOK_VERSION,
131
- ensureRecordId(recordIdToString(parentVersion.id, TABLES.PLAYBOOK_VERSION), TABLES.PLAYBOOK_VERSION),
132
- { status: 'active' },
133
- PlaybookVersionSchema,
134
- )
135
-
136
- await databaseService.update(
137
- TABLES.PLAYBOOK,
138
- ensureRecordId(playbookId, TABLES.PLAYBOOK),
139
- { currentVersionId: parentVersion.id, previousVersionId: parentVersion.parentVersionId },
140
- PlaybookSchema,
141
- )
142
-
143
- // Check if parent version is also regressed (caller can evaluate and re-invoke)
144
- if (parentVersion.qualityScore !== undefined && parentVersion.qualityScore < 0.5) {
145
- return this.rollbackRecursive(playbookId, organizationId, remainingLevels - 1)
146
- }
147
-
148
- return parentVersion
149
- }
150
- }
151
-
152
- export const adaptivePlaybookService = new AdaptivePlaybookService()
@@ -1,172 +0,0 @@
1
- import type { ImpactAnalysis, PlanNodeRunRecord, ProvenanceChain, ProvenanceNode } from '@lota-sdk/shared'
2
-
3
- import { recordIdToString } from '../db/record-id'
4
-
5
- class ArtifactProvenanceService {
6
- /**
7
- * Backward: trace which upstream nodes/artifacts produced the inputs for this artifact's node.
8
- * From nodeId, follow edges upstream. At each upstream node, collect its artifacts.
9
- * Continue until maxDepth or no more upstreams.
10
- */
11
- async traceBackward(params: { runId: string; nodeId: string; maxDepth?: number }): Promise<ProvenanceChain> {
12
- const { planRunService } = await import('./plan-run.service')
13
-
14
- const run = await planRunService.getRunById(params.runId)
15
- const spec = await planRunService.getPlanSpecById(run.planSpecId)
16
- const nodeSpecs = await planRunService.listNodeSpecs(spec.id)
17
- const artifacts = await planRunService.listArtifacts(run.id)
18
-
19
- const nodeSpecsByNodeId = new Map(nodeSpecs.map((n) => [n.nodeId, n]))
20
- const artifactsByNodeId = new Map<string, typeof artifacts>()
21
- for (const artifact of artifacts) {
22
- const list = artifactsByNodeId.get(artifact.nodeId) ?? []
23
- list.push(artifact)
24
- artifactsByNodeId.set(artifact.nodeId, list)
25
- }
26
-
27
- const maxDepth = params.maxDepth ?? 10
28
- const chain: ProvenanceNode[] = []
29
- const visited = new Set<string>()
30
- const queue: Array<{ nodeId: string; depth: number }> = [{ nodeId: params.nodeId, depth: 0 }]
31
-
32
- while (queue.length > 0) {
33
- const entry = queue.shift()
34
- if (!entry || visited.has(entry.nodeId) || entry.depth > maxDepth) continue
35
- visited.add(entry.nodeId)
36
-
37
- const nodeSpec = nodeSpecsByNodeId.get(entry.nodeId)
38
- if (!nodeSpec) continue
39
-
40
- const nodeArtifacts = (artifactsByNodeId.get(entry.nodeId) ?? []).map((a) => ({
41
- name: a.name,
42
- kind: a.kind,
43
- id: recordIdToString(a.id),
44
- }))
45
-
46
- chain.push({ nodeId: entry.nodeId, label: nodeSpec.label, artifacts: nodeArtifacts })
47
-
48
- // Walk upstream
49
- for (const upstreamId of nodeSpec.upstreamNodeIds) {
50
- if (!visited.has(upstreamId)) {
51
- queue.push({ nodeId: upstreamId, depth: entry.depth + 1 })
52
- }
53
- }
54
- }
55
-
56
- return { root: { nodeId: params.nodeId }, chain, depth: Math.max(0, chain.length - 1) }
57
- }
58
-
59
- /**
60
- * Forward: trace which downstream nodes consume this artifact's node output.
61
- * Same as backward but follow edges downstream.
62
- */
63
- async traceForward(params: { runId: string; nodeId: string; maxDepth?: number }): Promise<ProvenanceChain> {
64
- const { planRunService } = await import('./plan-run.service')
65
-
66
- const run = await planRunService.getRunById(params.runId)
67
- const spec = await planRunService.getPlanSpecById(run.planSpecId)
68
- const nodeSpecs = await planRunService.listNodeSpecs(spec.id)
69
- const artifacts = await planRunService.listArtifacts(run.id)
70
-
71
- const nodeSpecsByNodeId = new Map(nodeSpecs.map((n) => [n.nodeId, n]))
72
- const artifactsByNodeId = new Map<string, typeof artifacts>()
73
- for (const artifact of artifacts) {
74
- const list = artifactsByNodeId.get(artifact.nodeId) ?? []
75
- list.push(artifact)
76
- artifactsByNodeId.set(artifact.nodeId, list)
77
- }
78
-
79
- const maxDepth = params.maxDepth ?? 10
80
- const chain: ProvenanceNode[] = []
81
- const visited = new Set<string>()
82
- const queue: Array<{ nodeId: string; depth: number }> = [{ nodeId: params.nodeId, depth: 0 }]
83
-
84
- while (queue.length > 0) {
85
- const entry = queue.shift()
86
- if (!entry || visited.has(entry.nodeId) || entry.depth > maxDepth) continue
87
- visited.add(entry.nodeId)
88
-
89
- const nodeSpec = nodeSpecsByNodeId.get(entry.nodeId)
90
- if (!nodeSpec) continue
91
-
92
- const nodeArtifacts = (artifactsByNodeId.get(entry.nodeId) ?? []).map((a) => ({
93
- name: a.name,
94
- kind: a.kind,
95
- id: recordIdToString(a.id),
96
- }))
97
-
98
- chain.push({ nodeId: entry.nodeId, label: nodeSpec.label, artifacts: nodeArtifacts })
99
-
100
- // Walk downstream
101
- for (const downstreamId of nodeSpec.downstreamNodeIds) {
102
- if (!visited.has(downstreamId)) {
103
- queue.push({ nodeId: downstreamId, depth: entry.depth + 1 })
104
- }
105
- }
106
- }
107
-
108
- return { root: { nodeId: params.nodeId }, chain, depth: Math.max(0, chain.length - 1) }
109
- }
110
-
111
- /**
112
- * Impact: which downstream nodes/artifacts would be affected.
113
- * Forward traversal collecting all affected nodes and their artifacts.
114
- * Includes non-completed nodes.
115
- */
116
- async analyzeImpact(params: { runId: string; nodeId: string }): Promise<ImpactAnalysis> {
117
- const { planRunService } = await import('./plan-run.service')
118
-
119
- const run = await planRunService.getRunById(params.runId)
120
- const spec = await planRunService.getPlanSpecById(run.planSpecId)
121
- const nodeSpecs = await planRunService.listNodeSpecs(spec.id)
122
- const nodeRuns = await planRunService.listNodeRuns(run.id)
123
- const artifacts = await planRunService.listArtifacts(run.id)
124
-
125
- const nodeSpecsByNodeId = new Map(nodeSpecs.map((n) => [n.nodeId, n]))
126
- const nodeRunsByNodeId = new Map(nodeRuns.map((n: PlanNodeRunRecord) => [n.nodeId, n]))
127
-
128
- const affectedNodes: Array<{ nodeId: string; label: string; status: PlanNodeRunRecord['status'] }> = []
129
- const affectedArtifacts: Array<{ name: string; nodeId: string }> = []
130
-
131
- const visited = new Set<string>()
132
- const queue: string[] = []
133
-
134
- // Seed: downstream neighbors of the source node
135
- const sourceSpec = nodeSpecsByNodeId.get(params.nodeId)
136
- if (sourceSpec) {
137
- for (const downstreamId of sourceSpec.downstreamNodeIds) {
138
- queue.push(downstreamId)
139
- }
140
- }
141
-
142
- while (queue.length > 0) {
143
- const nodeId = queue.shift()
144
- if (!nodeId || visited.has(nodeId)) continue
145
- visited.add(nodeId)
146
-
147
- const nodeSpec = nodeSpecsByNodeId.get(nodeId)
148
- if (!nodeSpec) continue
149
-
150
- const nodeRun = nodeRunsByNodeId.get(nodeId)
151
- affectedNodes.push({ nodeId, label: nodeSpec.label, status: nodeRun?.status ?? 'pending' })
152
-
153
- // Collect artifacts for this node
154
- for (const artifact of artifacts.filter((a) => a.nodeId === nodeId)) {
155
- affectedArtifacts.push({ name: artifact.name, nodeId })
156
- }
157
-
158
- // Continue downstream
159
- for (const downstreamId of nodeSpec.downstreamNodeIds) {
160
- if (!visited.has(downstreamId)) queue.push(downstreamId)
161
- }
162
- }
163
-
164
- return {
165
- sourceNodeId: params.nodeId,
166
- affectedNodes: affectedNodes as ImpactAnalysis['affectedNodes'],
167
- affectedArtifacts,
168
- }
169
- }
170
- }
171
-
172
- export const artifactProvenanceService = new ArtifactProvenanceService()
@@ -1,17 +0,0 @@
1
- import type { ChatMessage } from '@lota-sdk/shared'
2
-
3
- import type { RecordIdRef } from '../db/record-id'
4
- import { attachmentService } from './attachment.service'
5
- import type { ReadableUploadMetadata } from './attachment.service'
6
-
7
- export function listReadableUploadsFromChatMessages(params: {
8
- messages: ChatMessage[]
9
- orgId: RecordIdRef
10
- userId: RecordIdRef
11
- }): ReadableUploadMetadata[] {
12
- return attachmentService.listReadableUploadsFromMessages({
13
- messages: params.messages.map((message) => ({ parts: message.parts as Array<Record<string, unknown>> })),
14
- orgId: params.orgId,
15
- userId: params.userId,
16
- })
17
- }
@@ -1,13 +0,0 @@
1
- import { createWiredContextCompactionRuntime } from '../runtime/context-compaction-runtime'
2
- import { createHelperModelRuntime } from '../runtime/helper-model'
3
-
4
- const helperModelRuntime = createHelperModelRuntime()
5
-
6
- const wiredRuntime = createWiredContextCompactionRuntime({
7
- helperModelRuntime,
8
- now: () => Date.now(),
9
- randomId: () => Bun.randomUUIDv7(),
10
- })
11
-
12
- export const contextCompactionRuntime = wiredRuntime
13
- export const compactMemoryBlockSummary = wiredRuntime.compactMemoryBlockSummary