@lota-sdk/core 0.4.10 → 0.4.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.
Files changed (108) hide show
  1. package/package.json +2 -2
  2. package/src/ai-gateway/ai-gateway.ts +149 -95
  3. package/src/ai-gateway/index.ts +16 -1
  4. package/src/config/agent-defaults.ts +4 -120
  5. package/src/config/logger.ts +18 -34
  6. package/src/config/thread-defaults.ts +1 -18
  7. package/src/create-runtime.ts +90 -28
  8. package/src/db/base.service.ts +30 -38
  9. package/src/db/service.ts +489 -545
  10. package/src/effect/index.ts +0 -2
  11. package/src/effect/layers.ts +6 -13
  12. package/src/embeddings/provider.ts +2 -7
  13. package/src/index.ts +4 -5
  14. package/src/queues/autonomous-job.queue.ts +159 -113
  15. package/src/queues/context-compaction.queue.ts +39 -25
  16. package/src/queues/delayed-node-promotion.queue.ts +56 -29
  17. package/src/queues/document-processor.queue.ts +5 -3
  18. package/src/queues/index.ts +1 -0
  19. package/src/queues/memory-consolidation.queue.ts +79 -53
  20. package/src/queues/organization-learning.queue.ts +63 -39
  21. package/src/queues/plan-agent-heartbeat.queue.ts +104 -79
  22. package/src/queues/plan-scheduler.queue.ts +100 -84
  23. package/src/queues/post-chat-memory.queue.ts +55 -33
  24. package/src/queues/queue-factory.ts +40 -41
  25. package/src/queues/queues.service.ts +61 -0
  26. package/src/queues/title-generation.queue.ts +42 -31
  27. package/src/redis/org-memory-lock.ts +24 -9
  28. package/src/redis/redis-lease-lock.ts +8 -1
  29. package/src/runtime/agent-identity-overrides.ts +7 -3
  30. package/src/runtime/agent-runtime-policy.ts +9 -4
  31. package/src/runtime/agent-stream-helpers.ts +9 -4
  32. package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
  33. package/src/runtime/context-compaction/context-compaction.ts +9 -7
  34. package/src/runtime/domain-layer.ts +15 -4
  35. package/src/runtime/execution-plan-visibility.ts +5 -2
  36. package/src/runtime/graph-designer.ts +0 -22
  37. package/src/runtime/index.ts +1 -0
  38. package/src/runtime/indexed-repositories-policy.ts +2 -6
  39. package/src/runtime/plugin-resolution.ts +29 -12
  40. package/src/runtime/post-turn-side-effects.ts +139 -141
  41. package/src/runtime/runtime-config.ts +0 -6
  42. package/src/runtime/runtime-extensions.ts +0 -54
  43. package/src/runtime/runtime-lifecycle.ts +4 -4
  44. package/src/runtime/runtime-services.ts +122 -53
  45. package/src/runtime/runtime-worker-registry.ts +113 -30
  46. package/src/runtime/social-chat/social-chat-agent-runner.ts +6 -3
  47. package/src/runtime/social-chat/social-chat-history.ts +3 -1
  48. package/src/runtime/social-chat/social-chat.ts +35 -20
  49. package/src/runtime/team-consultation/team-consultation-orchestrator.ts +6 -5
  50. package/src/runtime/team-consultation/team-consultation-prompts.ts +11 -6
  51. package/src/runtime/thread-chat-helpers.ts +18 -9
  52. package/src/runtime/thread-turn-context.ts +7 -47
  53. package/src/runtime/turn-lifecycle.ts +6 -14
  54. package/src/services/agent-activity.service.ts +168 -175
  55. package/src/services/agent-executor.service.ts +35 -16
  56. package/src/services/attachment.service.ts +4 -70
  57. package/src/services/autonomous-job.service.ts +53 -61
  58. package/src/services/context-compaction.service.ts +7 -9
  59. package/src/services/execution-plan/execution-plan-graph.ts +106 -115
  60. package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
  61. package/src/services/execution-plan/execution-plan.service.ts +67 -50
  62. package/src/services/global-orchestrator.service.ts +18 -7
  63. package/src/services/graph-full-routing.ts +7 -6
  64. package/src/services/memory/memory-conversation.ts +10 -5
  65. package/src/services/memory/memory.service.ts +11 -8
  66. package/src/services/ownership-dispatcher.service.ts +16 -5
  67. package/src/services/plan/plan-agent-heartbeat.service.ts +29 -15
  68. package/src/services/plan/plan-agent-query.service.ts +12 -8
  69. package/src/services/plan/plan-completion-side-effects.ts +93 -101
  70. package/src/services/plan/plan-cycle.service.ts +7 -45
  71. package/src/services/plan/plan-deadline.service.ts +28 -17
  72. package/src/services/plan/plan-event-delivery.service.ts +47 -40
  73. package/src/services/plan/plan-executor-context.ts +2 -0
  74. package/src/services/plan/plan-executor-graph.ts +366 -391
  75. package/src/services/plan/plan-executor.service.ts +13 -91
  76. package/src/services/plan/plan-scheduler.service.ts +62 -49
  77. package/src/services/plan/plan-transaction-events.ts +1 -1
  78. package/src/services/recent-activity-title.service.ts +6 -2
  79. package/src/services/thread/thread-bootstrap.ts +11 -9
  80. package/src/services/thread/thread-message.service.ts +6 -5
  81. package/src/services/thread/thread-turn-execution.ts +86 -82
  82. package/src/services/thread/thread-turn-preparation.service.ts +47 -24
  83. package/src/services/thread/thread-turn-streaming.ts +20 -25
  84. package/src/services/thread/thread-turn.ts +25 -44
  85. package/src/services/thread/thread.service.ts +21 -6
  86. package/src/system-agents/recent-activity-title-refiner.agent.ts +8 -5
  87. package/src/system-agents/thread-router.agent.ts +23 -20
  88. package/src/tools/execution-plan.tool.ts +8 -3
  89. package/src/tools/fetch-webpage.tool.ts +10 -9
  90. package/src/tools/firecrawl-client.ts +0 -15
  91. package/src/tools/remember-memory.tool.ts +3 -6
  92. package/src/tools/research-topic.tool.ts +12 -3
  93. package/src/tools/search-web.tool.ts +10 -9
  94. package/src/tools/search.tool.ts +4 -5
  95. package/src/tools/team-think.tool.ts +139 -121
  96. package/src/workers/bootstrap.ts +9 -10
  97. package/src/workers/memory-consolidation.worker.ts +4 -1
  98. package/src/workers/organization-learning.worker.ts +15 -2
  99. package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
  100. package/src/workers/regular-chat-memory-digest.runner.ts +21 -14
  101. package/src/workers/skill-extraction.runner.ts +13 -15
  102. package/src/workers/worker-utils.ts +6 -18
  103. package/src/effect/awaitable-effect.ts +0 -96
  104. package/src/effect/runtime-ref.ts +0 -25
  105. package/src/effect/runtime.ts +0 -46
  106. package/src/redis/runtime-connection.ts +0 -20
  107. package/src/runtime/runtime-accessors.ts +0 -92
  108. package/src/runtime/runtime-token.ts +0 -47
@@ -13,14 +13,13 @@ import type { Message, Thread, WebhookOptions } from 'chat'
13
13
  import type { Context, Cause } from 'effect'
14
14
  import { Clock, Effect, Schema } from 'effect'
15
15
 
16
- import { getAgentDisplayNames, getTeamConsultParticipants } from '../../config/agent-defaults'
16
+ import type { ResolvedAgentConfig, ResolvedAgentFactoryConfig } from '../../config/agent-defaults'
17
17
  import { aiLogger } from '../../config/logger'
18
18
  import { recordIdToString } from '../../db/record-id'
19
19
  import { TABLES } from '../../db/tables'
20
20
  import { ForbiddenError } from '../../effect/errors'
21
21
  import { effectTryMaybeAsync, effectTryPromise } from '../../effect/helpers'
22
- import { enqueueRegularChatMemoryDigest, enqueueSkillExtraction } from '../../queues/organization-learning.queue'
23
- import { enqueuePostChatMemory } from '../../queues/post-chat-memory.queue'
22
+ import type { LotaQueuesRuntime } from '../../queues/queues.service'
24
23
  import type { LearnedSkillServiceTag } from '../../services/learned-skill.service'
25
24
  import type { MemoryServiceTag } from '../../services/memory/memory.service'
26
25
  import type { SocialChatHistoryError, makeSocialChatHistoryService } from '../../services/social-chat-history.service'
@@ -32,7 +31,7 @@ import type {
32
31
  LotaRuntimeSocialChatConfig,
33
32
  LotaSocialChatResolvedContext,
34
33
  } from '../runtime-config'
35
- import { getRuntimeAdapters } from '../runtime-extensions'
34
+ import type { LotaRuntimeAdapters } from '../runtime-extensions'
36
35
  import { runSpecialistSession } from '../specialist-runner'
37
36
  import {
38
37
  buildAgentHistoryMessages,
@@ -58,6 +57,8 @@ export interface SocialChatRuntimeServices {
58
57
  learnedSkillService: Context.Service.Shape<typeof LearnedSkillServiceTag>
59
58
  memoryService: Context.Service.Shape<typeof MemoryServiceTag>
60
59
  socialChatHistoryService: ReturnType<typeof makeSocialChatHistoryService>
60
+ runtimeAdapters: LotaRuntimeAdapters
61
+ queues: LotaQueuesRuntime
61
62
  }
62
63
 
63
64
  class SocialChatServiceError extends Schema.TaggedErrorClass<SocialChatServiceError>()('SocialChatServiceError', {
@@ -112,8 +113,8 @@ function createAssistantMessage(params: {
112
113
  }
113
114
  }
114
115
 
115
- function getAgentDisplayName(agentId: string): string {
116
- return getAgentDisplayNames()[agentId] ?? agentId
116
+ function getAgentDisplayName(agentConfig: ResolvedAgentConfig, agentId: string): string {
117
+ return agentConfig.displayNames[agentId] ?? agentId
117
118
  }
118
119
 
119
120
  function toSafeJobIdSegment(value: string): string {
@@ -157,6 +158,8 @@ function buildBuildToolsParams(params: {
157
158
  }
158
159
 
159
160
  export function createSocialChatRuntime(params: {
161
+ agentConfig: ResolvedAgentConfig
162
+ agentFactoryConfig: ResolvedAgentFactoryConfig
160
163
  redisClient: SocialChatStateRedisClient
161
164
  socialChat?: LotaRuntimeSocialChatConfig
162
165
  services: SocialChatRuntimeServices
@@ -205,6 +208,8 @@ export function createSocialChatRuntime(params: {
205
208
  Effect.scoped(
206
209
  Effect.gen(function* () {
207
210
  const { memoryService, learnedSkillService, socialChatHistoryService } = params.services
211
+ const agentConfig = params.agentConfig
212
+ const agentFactoryConfig = params.agentFactoryConfig
208
213
  const currentContext = yield* Effect.context()
209
214
  const runPromiseWithCurrentContext = Effect.runPromiseWith(currentContext)
210
215
  const rawSlackMessage = incomingMessage.raw as { channel?: unknown } | undefined
@@ -258,7 +263,7 @@ export function createSocialChatRuntime(params: {
258
263
  ? historyBeforeReply.filter((message) => message.cursor.id !== currentUserMessage.cursor.id)
259
264
  : historyBeforeReply
260
265
 
261
- const workspaceProvider = getRuntimeAdapters().workspaceProvider
266
+ const workspaceProvider = params.services.runtimeAdapters.workspaceProvider
262
267
  const getWorkspace = workspaceProvider?.getWorkspace
263
268
  ? workspaceProvider.getWorkspace.bind(workspaceProvider)
264
269
  : undefined
@@ -352,7 +357,7 @@ export function createSocialChatRuntime(params: {
352
357
  platform: 'slack',
353
358
  }),
354
359
  )
355
- : [...getTeamConsultParticipants()]
360
+ : [...agentConfig.teamConsultParticipants]
356
361
  const consultParticipants = [...new Set(consultedAgents)].filter((agentId) => agentId !== socialAgentId)
357
362
  const executedToolNames: string[] = []
358
363
 
@@ -380,7 +385,7 @@ export function createSocialChatRuntime(params: {
380
385
  },
381
386
  )
382
387
 
383
- const transcript = buildSocialChatThreadTranscript(historyBeforeReply)
388
+ const transcript = buildSocialChatThreadTranscript(agentConfig, historyBeforeReply)
384
389
  const runAbort = yield* Effect.acquireRelease(
385
390
  Effect.sync(() => createServerRunAbortController()),
386
391
  (controller) => Effect.sync(() => controller.dispose()),
@@ -458,6 +463,7 @@ export function createSocialChatRuntime(params: {
458
463
 
459
464
  return yield* effectTryPromise(() =>
460
465
  runSocialAgentTurn({
466
+ agentFactoryConfig,
461
467
  agentId,
462
468
  mode: 'fixedThreadMode',
463
469
  threadType: 'group',
@@ -474,7 +480,7 @@ export function createSocialChatRuntime(params: {
474
480
  tools,
475
481
  prompt: buildSpecialistSocialChatPrompt({
476
482
  requesterName: socialAgentDisplayName,
477
- agentName: getAgentDisplayName(agentId),
483
+ agentName: getAgentDisplayName(agentConfig, agentId),
478
484
  task,
479
485
  transcript,
480
486
  }),
@@ -488,7 +494,12 @@ export function createSocialChatRuntime(params: {
488
494
  const text = specialistRun.text
489
495
  const createdAt = yield* Clock.currentTimeMillis
490
496
 
491
- return createAssistantMessage({ agentId, agentName: getAgentDisplayName(agentId), text, createdAt })
497
+ return createAssistantMessage({
498
+ agentId,
499
+ agentName: getAgentDisplayName(agentConfig, agentId),
500
+ text,
501
+ createdAt,
502
+ })
492
503
  }),
493
504
  ),
494
505
  toModelOutput: ({ output }) => {
@@ -509,6 +520,7 @@ export function createSocialChatRuntime(params: {
509
520
  aiLogger.debug`Slack social-chat generating reply: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}`
510
521
  const leadRun = yield* effectTryPromise(() =>
511
522
  runSocialAgentTurn({
523
+ agentFactoryConfig,
512
524
  agentId: socialAgentId,
513
525
  mode: 'threadMode',
514
526
  threadType: 'group',
@@ -549,13 +561,13 @@ export function createSocialChatRuntime(params: {
549
561
  yield* socialChatHistoryService.upsertMessages([normalizedResponse])
550
562
  }
551
563
 
552
- const priorHistoryMessages = toHistoryMessages(priorHistory)
553
- const agentMessages = normalizedResponse ? buildAgentHistoryMessages([normalizedResponse]) : []
564
+ const priorHistoryMessages = toHistoryMessages(agentConfig, priorHistory)
565
+ const agentMessages = normalizedResponse ? buildAgentHistoryMessages(agentConfig, [normalizedResponse]) : []
554
566
  if (messageContext.text && agentMessages.length > 0) {
555
567
  yield* effectTryPromise(() =>
556
568
  safeEnqueue(
557
569
  () =>
558
- enqueuePostChatMemory(
570
+ params.services.queues.postChatMemory.enqueuePostChatMemory(
559
571
  {
560
572
  orgId: workspaceIdString,
561
573
  threadId: `social:slack:${messageContext.threadId}`,
@@ -592,14 +604,17 @@ export function createSocialChatRuntime(params: {
592
604
  }
593
605
 
594
606
  yield* effectTryPromise(() =>
595
- safeEnqueue(() => enqueueRegularChatMemoryDigest({ orgId: workspaceIdString }), {
596
- operationName: 'social regular chat memory digest enqueue',
597
- }),
607
+ safeEnqueue(
608
+ () =>
609
+ params.services.queues.organizationLearning.enqueueRegularChatMemoryDigest({ orgId: workspaceIdString }),
610
+ { operationName: 'social regular chat memory digest enqueue' },
611
+ ),
598
612
  )
599
613
  yield* effectTryPromise(() =>
600
- safeEnqueue(() => enqueueSkillExtraction({ orgId: workspaceIdString }), {
601
- operationName: 'social skill extraction enqueue',
602
- }),
614
+ safeEnqueue(
615
+ () => params.services.queues.organizationLearning.enqueueSkillExtraction({ orgId: workspaceIdString }),
616
+ { operationName: 'social skill extraction enqueue' },
617
+ ),
603
618
  )
604
619
  }),
605
620
  )
@@ -3,7 +3,7 @@ import type { ChatMessage, ConsultTeamResultData } from '@lota-sdk/shared'
3
3
  import { convertToModelMessages, tool as createTool } from 'ai'
4
4
  import { Schema, Deferred, Effect, Exit, Fiber, Queue, Ref, Scope } from 'effect'
5
5
 
6
- import { getAgentDisplayNames, getTeamConsultParticipants } from '../../config/agent-defaults'
6
+ import type { ResolvedAgentConfig } from '../../config/agent-defaults'
7
7
  import { nowEpochMillis } from '../../utils/date-time'
8
8
  import { createTimedAbortSignal } from '../agent-stream-helpers'
9
9
  import { buildModelInputMessagesWithUploadMetadata, buildReadableUploadMetadataText } from '../chat-attachments'
@@ -91,6 +91,7 @@ export interface TeamConsultationParticipantRunner {
91
91
  }
92
92
 
93
93
  export interface CreateConsultTeamToolParams {
94
+ agentConfig: ResolvedAgentConfig
94
95
  historyMessages: ChatMessage[]
95
96
  latestUserMessageId: string
96
97
  availableUploads: ReadableUploadMetadataLike[]
@@ -278,9 +279,9 @@ class ConsultTeamSnapshotIterable implements AsyncIterableIterator<ConsultTeamRe
278
279
  private completed = false
279
280
 
280
281
  constructor(params: CreateConsultTeamToolParams, task: string) {
281
- const teamConsultParticipants = getTeamConsultParticipants()
282
+ const teamConsultParticipants = params.agentConfig.teamConsultParticipants
282
283
  const uploadMetadataText = buildReadableUploadMetadataText(params.availableUploads)
283
- const agentDisplayNames = getAgentDisplayNames()
284
+ const agentDisplayNames = params.agentConfig.displayNames
284
285
  const resolveDisplayName = (agentId: string) => {
285
286
  if (params.displayNamesById && Object.hasOwn(params.displayNamesById, agentId)) {
286
287
  const override = params.displayNamesById[agentId]
@@ -390,8 +391,8 @@ class ConsultTeamSnapshotIterable implements AsyncIterableIterator<ConsultTeamRe
390
391
  }
391
392
 
392
393
  export function createConsultTeamTool(params: CreateConsultTeamToolParams) {
393
- const teamConsultParticipants = getTeamConsultParticipants()
394
- const agentDisplayNames = getAgentDisplayNames()
394
+ const teamConsultParticipants = params.agentConfig.teamConsultParticipants
395
+ const agentDisplayNames = params.agentConfig.displayNames
395
396
  const resolveDisplayName = (agentId: string) => {
396
397
  if (params.displayNamesById && Object.hasOwn(params.displayNamesById, agentId)) {
397
398
  const override = params.displayNamesById[agentId]
@@ -1,12 +1,17 @@
1
- import { getAgentDisplayNames, getLeadAgentDisplayName } from '../../config/agent-defaults'
1
+ import type { ResolvedAgentConfig } from '../../config/agent-defaults'
2
2
 
3
- function resolveDisplayName(agentId: string): string {
4
- return getAgentDisplayNames()[agentId] ?? agentId
3
+ function resolveDisplayName(agentConfig: ResolvedAgentConfig, agentId: string): string {
4
+ return agentConfig.displayNames[agentId] ?? agentId
5
5
  }
6
6
 
7
- export function buildTeamConsultationResponseGuard(params: { agentId: string; task: string }) {
8
- const agentName = resolveDisplayName(params.agentId)
9
- const leadAgentDisplayName = getLeadAgentDisplayName()
7
+ export function buildTeamConsultationResponseGuard(params: {
8
+ agentConfig: ResolvedAgentConfig
9
+ agentId: string
10
+ task: string
11
+ }) {
12
+ const agentName = resolveDisplayName(params.agentConfig, params.agentId)
13
+ const leadAgentDisplayName =
14
+ params.agentConfig.displayNames[params.agentConfig.leadAgentId] ?? params.agentConfig.leadAgentId
10
15
  const mentorConstraint =
11
16
  params.agentId === 'mentor'
12
17
  ? ['- As Mentor, answer as an experienced operator reviewing launch discipline, not as a coach or therapist.']
@@ -1,7 +1,8 @@
1
1
  import { toTimestamp } from '@lota-sdk/shared'
2
2
  import type { ChatMessage } from '@lota-sdk/shared'
3
3
 
4
- import { getAgentDisplayNames, resolveAgentNameAlias } from '../config/agent-defaults'
4
+ import type { ResolvedAgentConfig } from '../config/agent-defaults'
5
+ import { resolveAgentNameAlias } from '../config/agent-defaults'
5
6
  import type { ChatMessageLike, ReadableUploadMetadataLike } from './chat-types'
6
7
 
7
8
  export interface ThreadHistoryMessage {
@@ -29,13 +30,13 @@ export function readInstructionSections(value: unknown): string[] {
29
30
  .filter((section) => section.length > 0)
30
31
  }
31
32
 
32
- function getAgentName(message: ChatMessageLike): string | undefined {
33
+ function getAgentName(agentConfig: ResolvedAgentConfig, message: ChatMessageLike): string | undefined {
33
34
  const metadata = message.metadata
34
35
  if (!metadata || typeof metadata !== 'object') return undefined
35
36
  const value = (metadata as Record<string, unknown>).agentName
36
37
  if (typeof value !== 'string' || !value.trim()) return undefined
37
- const resolvedAgentName = resolveAgentNameAlias(value)
38
- return resolvedAgentName ? (getAgentDisplayNames()[resolvedAgentName] ?? value.trim()) : value.trim()
38
+ const resolvedAgentName = resolveAgentNameAlias(agentConfig, value)
39
+ return resolvedAgentName ? (agentConfig.displayNames[resolvedAgentName] ?? value.trim()) : value.trim()
39
40
  }
40
41
 
41
42
  export function extractMessageText(message: ChatMessageLike): string {
@@ -45,7 +46,11 @@ export function extractMessageText(message: ChatMessageLike): string {
45
46
  .trim()
46
47
  }
47
48
 
48
- export function toHistoryMessages(messages: ChatMessageLike[], maxItems = 24): ThreadHistoryMessage[] {
49
+ export function toHistoryMessages(
50
+ agentConfig: ResolvedAgentConfig,
51
+ messages: ChatMessageLike[],
52
+ maxItems = 24,
53
+ ): ThreadHistoryMessage[] {
49
54
  return messages
50
55
  .map((message): ThreadHistoryMessage | null => {
51
56
  const content = extractMessageText(message)
@@ -55,7 +60,7 @@ export function toHistoryMessages(messages: ChatMessageLike[], maxItems = 24): T
55
60
  return { role: 'user', content }
56
61
  }
57
62
  if (message.role === 'assistant') {
58
- const agentName = getAgentName(message)
63
+ const agentName = getAgentName(agentConfig, message)
59
64
  return { role: 'agent', content, ...(agentName ? { agentName } : {}) }
60
65
  }
61
66
  return null
@@ -65,6 +70,7 @@ export function toHistoryMessages(messages: ChatMessageLike[], maxItems = 24): T
65
70
  }
66
71
 
67
72
  export function buildConversationSummary(params: {
73
+ agentConfig: ResolvedAgentConfig
68
74
  userMessageText: string
69
75
  assistantMessages: ChatMessageLike[]
70
76
  }): string {
@@ -76,15 +82,18 @@ export function buildConversationSummary(params: {
76
82
  for (const message of params.assistantMessages) {
77
83
  const content = extractMessageText(message)
78
84
  if (!content) continue
79
- const agentName = getAgentName(message)
85
+ const agentName = getAgentName(params.agentConfig, message)
80
86
  lines.push(agentName ? `${agentName}: ${content}` : `Assistant: ${content}`)
81
87
  }
82
88
 
83
89
  return lines.join('\n\n').trim()
84
90
  }
85
91
 
86
- export function buildAgentHistoryMessages(messages: ChatMessageLike[]): Array<{ content: string; agentName?: string }> {
87
- return toHistoryMessages(messages)
92
+ export function buildAgentHistoryMessages(
93
+ agentConfig: ResolvedAgentConfig,
94
+ messages: ChatMessageLike[],
95
+ ): Array<{ content: string; agentName?: string }> {
96
+ return toHistoryMessages(agentConfig, messages)
88
97
  .filter((message) => message.role === 'agent')
89
98
  .map((message) => ({ content: message.content, ...(message.agentName ? { agentName: message.agentName } : {}) }))
90
99
  }
@@ -1,8 +1,6 @@
1
1
  import { Schema, Effect } from 'effect'
2
2
 
3
3
  import type { RecordIdRef } from '../db/record-id'
4
- import { recordIdToString } from '../db/record-id'
5
- import { TABLES } from '../db/tables'
6
4
  import { effectTryMaybeAsync as effectTryMaybeAsyncShared, makeEffectTryPromiseWithMessage } from '../effect/helpers'
7
5
  import { buildAgentPromptContext } from './agent-prompt-context'
8
6
  import {
@@ -11,10 +9,9 @@ import {
11
9
  getLinearInstallationByOrgId,
12
10
  } from './plugin-resolution'
13
11
  import type {
12
+ LotaRuntimeAdapters,
14
13
  LotaRuntimeIndexedRepositoriesContext,
15
14
  LotaRuntimeTurnHooks,
16
- LotaRuntimeWorkspaceLifecycleState,
17
- LotaRuntimeWorkspaceProjectionState,
18
15
  LotaRuntimeWorkspaceProvider,
19
16
  } from './runtime-extensions'
20
17
  import { readInstructionSections, readOptionalString } from './thread-chat-helpers'
@@ -43,21 +40,7 @@ function effectTryMaybeAsync<A>(
43
40
  return effectTryMaybeAsyncShared(evaluate, (cause) => new ThreadTurnContextError({ message, cause }))
44
41
  }
45
42
 
46
- interface AssembledThreadTurnContext {
47
- workspace: Record<string, unknown>
48
- workspaceLifecycleState: LotaRuntimeWorkspaceLifecycleState | undefined
49
- workspaceProfileState: LotaRuntimeWorkspaceProjectionState | undefined
50
- onboardingActive: boolean
51
- linearInstalled: boolean
52
- githubInstalled: boolean
53
- indexedRepoContext: LotaRuntimeIndexedRepositoriesContext
54
- promptContext: { systemWorkspaceDetails?: string }
55
- retrievedKnowledgeSection: string | undefined
56
- buildContextResult: Record<string, unknown> | null
57
- hookInstructionSections: string[]
58
- }
59
-
60
- const assembleThreadTurnContextEffect = Effect.fn('ThreadTurnContext.assemble')(function* (params: {
43
+ export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')(function* (params: {
61
44
  thread: unknown
62
45
  threadRef: RecordIdRef
63
46
  orgRef: RecordIdRef
@@ -69,6 +52,8 @@ const assembleThreadTurnContextEffect = Effect.fn('ThreadTurnContext.assemble')(
69
52
  workspacePromise: Promise<Record<string, unknown>>
70
53
  workspaceProvider?: LotaRuntimeWorkspaceProvider
71
54
  turnHooks: LotaRuntimeTurnHooks
55
+ runtimeAdapters: LotaRuntimeAdapters
56
+ pluginRuntime?: Record<string, unknown>
72
57
  }) {
73
58
  const workspace = yield* effectTryPromise(() => params.workspacePromise, 'Failed to load thread workspace').pipe(
74
59
  Effect.withSpan('ThreadTurnContext.loadWorkspace'),
@@ -85,21 +70,21 @@ const assembleThreadTurnContextEffect = Effect.fn('ThreadTurnContext.assemble')(
85
70
 
86
71
  const onboardingActive = workspaceLifecycleState?.bootstrapActive ?? false
87
72
  const linearInstallation = yield* effectTryPromise(
88
- () => getLinearInstallationByOrgId(params.orgRef),
73
+ () => getLinearInstallationByOrgId(params.pluginRuntime, params.orgRef),
89
74
  'Failed to load Linear installation',
90
75
  ).pipe(
91
76
  Effect.catch(() => Effect.succeed(null)),
92
77
  Effect.withSpan('ThreadTurnContext.loadLinearInstallation'),
93
78
  )
94
79
  const githubInstallation = yield* effectTryPromise(
95
- () => getGithubInstallationForOrganization(params.orgIdString),
80
+ () => getGithubInstallationForOrganization(params.pluginRuntime, params.orgIdString),
96
81
  'Failed to load GitHub installation',
97
82
  ).pipe(
98
83
  Effect.catch(() => Effect.succeed(null)),
99
84
  Effect.withSpan('ThreadTurnContext.loadGithubInstallation'),
100
85
  )
101
86
  const indexedRepoContext = yield* effectTryPromise(
102
- () => buildIndexedRepositoriesContext(params.orgIdString),
87
+ () => buildIndexedRepositoriesContext(params.runtimeAdapters, params.orgIdString),
103
88
  'Failed to build indexed repository context',
104
89
  ).pipe(
105
90
  Effect.catch(() =>
@@ -227,28 +212,3 @@ const assembleThreadTurnContextEffect = Effect.fn('ThreadTurnContext.assemble')(
227
212
  hookInstructionSections,
228
213
  }
229
214
  })
230
-
231
- export function assembleThreadTurnContext(params: {
232
- thread: unknown
233
- threadRef: RecordIdRef
234
- orgRef: RecordIdRef
235
- userRef: RecordIdRef
236
- userName?: string | null
237
- orgIdString: string
238
- userIdString: string
239
- messageText: string
240
- workspacePromise: Promise<Record<string, unknown>>
241
- workspaceProvider?: LotaRuntimeWorkspaceProvider
242
- turnHooks: LotaRuntimeTurnHooks
243
- }): Promise<AssembledThreadTurnContext> {
244
- return Effect.runPromise(
245
- assembleThreadTurnContextEffect(params).pipe(
246
- Effect.annotateSpans({
247
- threadId: recordIdToString(params.threadRef, TABLES.THREAD),
248
- orgId: params.orgIdString,
249
- userId: params.userIdString,
250
- messageLength: params.messageText.length,
251
- }),
252
- ),
253
- )
254
- }
@@ -86,17 +86,9 @@ export function finalizeTurnRunEffect(params: {
86
86
  })
87
87
  }
88
88
 
89
- export function finalizeTurnRun(params: {
90
- serverRunId: string
91
- getEntity: () => MaybeEffect<{ lastCompactedMessageId?: string | null; compactionSummary?: string | null }>
92
- getUncompactedMessages: (cursor?: string) => MaybeEffect<ChatMessage[]>
93
- assessCompaction: (summaryText: string, messages: ChatMessage[]) => { shouldCompact: boolean }
94
- enqueueCompaction: () => MaybeEffect<void>
95
- unregisterRun: (runId: string) => void
96
- clearActiveRunId: (runId: string) => MaybeEffect<void>
97
- disposeAbort: () => void
98
- activeStreamId?: string
99
- clearActiveStreamId?: (streamId: string) => MaybeEffect<void>
100
- }): Promise<void> {
101
- return Effect.runPromise(finalizeTurnRunEffect(params))
102
- }
89
+ /**
90
+ * Alias for `finalizeTurnRunEffect`. Kept as the public name consumers use.
91
+ * Callers pipe the returned Effect through their own runtime rather than
92
+ * relying on a process-wide promise adapter.
93
+ */
94
+ export { finalizeTurnRunEffect as finalizeTurnRun }