@lota-sdk/core 0.4.13 → 0.4.15
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 +4 -4
- package/src/ai/embedding-cache.ts +17 -11
- package/src/ai-gateway/ai-gateway.ts +164 -94
- package/src/ai-gateway/index.ts +4 -1
- package/src/config/agent-defaults.ts +2 -2
- package/src/config/agent-types.ts +1 -1
- package/src/config/constants.ts +1 -1
- package/src/create-runtime.ts +259 -200
- package/src/db/cursor-pagination.ts +2 -9
- package/src/db/memory-store.ts +194 -175
- package/src/db/memory.ts +125 -71
- package/src/db/schema-fingerprint.ts +5 -4
- package/src/db/service-normalization.ts +4 -3
- package/src/db/service.ts +3 -2
- package/src/db/startup.ts +15 -16
- package/src/effect/errors.ts +161 -21
- package/src/effect/index.ts +0 -1
- package/src/embeddings/provider.ts +15 -7
- package/src/queues/autonomous-job.queue.ts +10 -22
- package/src/queues/delayed-node-promotion.queue.ts +8 -14
- package/src/queues/document-processor.queue.ts +13 -4
- package/src/queues/memory-consolidation.queue.ts +26 -14
- package/src/queues/plan-agent-heartbeat.queue.ts +48 -31
- package/src/queues/plan-scheduler.queue.ts +37 -15
- package/src/queues/queue-factory.ts +59 -35
- package/src/queues/standalone-worker.ts +3 -2
- package/src/redis/connection.ts +10 -3
- package/src/redis/org-memory-lock.ts +1 -1
- package/src/redis/redis-lease-lock.ts +5 -5
- package/src/redis/stream-context.ts +1 -1
- package/src/runtime/chat-message.ts +64 -1
- package/src/runtime/chat-run-orchestration.ts +33 -20
- package/src/runtime/context-compaction/context-compaction-runtime.ts +14 -7
- package/src/runtime/context-compaction/context-compaction.ts +78 -66
- package/src/runtime/domain-layer.ts +19 -13
- package/src/runtime/execution-plan.ts +7 -3
- package/src/runtime/memory/memory-block.ts +3 -9
- package/src/runtime/memory/memory-scope.ts +3 -1
- package/src/runtime/plugin-resolution.ts +2 -1
- package/src/runtime/post-turn-side-effects.ts +6 -5
- package/src/runtime/retrieval-adapters.ts +8 -20
- package/src/runtime/runtime-config.ts +3 -9
- package/src/runtime/runtime-extensions.ts +2 -4
- package/src/runtime/runtime-lifecycle.ts +56 -16
- package/src/runtime/runtime-services.ts +180 -102
- package/src/runtime/runtime-worker-registry.ts +3 -1
- package/src/runtime/social-chat/social-chat-agent-runner.ts +1 -1
- package/src/runtime/social-chat/social-chat-history.ts +21 -18
- package/src/runtime/social-chat/social-chat.ts +356 -223
- package/src/runtime/specialist-runner.ts +3 -1
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +3 -2
- package/src/runtime/thread-turn-context.ts +142 -102
- package/src/runtime/turn-lifecycle.ts +15 -46
- package/src/services/agent-activity.service.ts +1 -1
- package/src/services/agent-executor.service.ts +107 -77
- package/src/services/autonomous-job.service.ts +354 -293
- package/src/services/background-work.service.ts +3 -3
- package/src/services/context-compaction.service.ts +7 -2
- package/src/services/document-chunk.service.ts +50 -32
- package/src/services/execution-plan/execution-plan-schedule.ts +5 -3
- package/src/services/execution-plan/execution-plan.service.ts +162 -179
- package/src/services/feedback-loop.service.ts +5 -4
- package/src/services/graph-full-routing.ts +37 -36
- package/src/services/institutional-memory.service.ts +28 -30
- package/src/services/learned-skill.service.ts +107 -72
- package/src/services/memory/memory-errors.ts +4 -23
- package/src/services/memory/memory-org-memory.ts +10 -5
- package/src/services/memory/memory-rerank.ts +18 -6
- package/src/services/memory/memory.service.ts +170 -111
- package/src/services/memory/rerank.service.ts +29 -20
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +69 -75
- package/src/services/ownership-dispatcher.service.ts +40 -39
- package/src/services/plan/plan-agent-heartbeat.service.ts +22 -24
- package/src/services/plan/plan-agent-query.service.ts +39 -31
- package/src/services/plan/plan-completion-side-effects.ts +13 -17
- package/src/services/plan/plan-coordination.service.ts +2 -1
- package/src/services/plan/plan-cycle.service.ts +6 -5
- package/src/services/plan/plan-deadline.service.ts +57 -54
- package/src/services/plan/plan-event-delivery.service.ts +5 -4
- package/src/services/plan/plan-executor-graph.ts +18 -15
- package/src/services/plan/plan-executor.service.ts +235 -262
- package/src/services/plan/plan-run.service.ts +169 -93
- package/src/services/plan/plan-scheduler.service.ts +192 -202
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +23 -14
- package/src/services/plugin-executor.service.ts +5 -9
- package/src/services/queue-job.service.ts +117 -59
- package/src/services/recent-activity-title.service.ts +13 -12
- package/src/services/recent-activity.service.ts +6 -1
- package/src/services/social-chat-history.service.ts +29 -25
- package/src/services/system-executor.service.ts +5 -9
- package/src/services/thread/thread-active-run.ts +2 -2
- package/src/services/thread/thread-listing.ts +61 -57
- package/src/services/thread/thread-memory-block.ts +73 -48
- package/src/services/thread/thread-message.service.ts +76 -65
- package/src/services/thread/thread-record-store.ts +8 -8
- package/src/services/thread/thread-title.service.ts +10 -4
- package/src/services/thread/thread-turn-execution.ts +43 -45
- package/src/services/thread/thread-turn-preparation.service.ts +257 -135
- package/src/services/thread/thread-turn-streaming.ts +83 -92
- package/src/services/thread/thread-turn.ts +18 -16
- package/src/services/thread/thread.service.ts +135 -100
- package/src/services/user.service.ts +45 -48
- package/src/storage/attachment-parser.ts +6 -2
- package/src/storage/attachment-storage.service.ts +5 -6
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +10 -9
- package/src/system-agents/delegated-agent-factory.ts +30 -6
- package/src/system-agents/memory-reranker.agent.ts +10 -9
- package/src/system-agents/memory.agent.ts +10 -9
- package/src/system-agents/recent-activity-title-refiner.agent.ts +13 -15
- package/src/system-agents/regular-chat-memory-digest.agent.ts +13 -12
- package/src/system-agents/skill-extractor.agent.ts +13 -12
- package/src/system-agents/skill-manager.agent.ts +13 -12
- package/src/system-agents/thread-router.agent.ts +11 -7
- package/src/system-agents/title-generator.agent.ts +13 -12
- package/src/tools/fetch-webpage.tool.ts +13 -13
- package/src/tools/memory-block.tool.ts +3 -1
- package/src/tools/plan-approval.tool.ts +4 -2
- package/src/tools/read-file-parts.tool.ts +10 -4
- package/src/tools/remember-memory.tool.ts +3 -1
- package/src/tools/research-topic.tool.ts +9 -5
- package/src/tools/search-web.tool.ts +16 -16
- package/src/tools/search.tool.ts +20 -5
- package/src/tools/team-think.tool.ts +61 -38
- package/src/utils/async.ts +5 -5
- package/src/utils/errors.ts +19 -18
- package/src/utils/sse-keepalive.ts +28 -25
- package/src/workers/bootstrap.ts +75 -11
- package/src/workers/memory-consolidation.worker.ts +82 -91
- package/src/workers/organization-learning.worker.ts +14 -4
- package/src/workers/regular-chat-memory-digest.runner.ts +105 -67
- package/src/workers/skill-extraction.runner.ts +97 -61
- package/src/workers/utils/repo-structure-extractor.ts +13 -8
- package/src/workers/utils/thread-message-query.ts +24 -24
- package/src/workers/worker-utils.ts +23 -4
- package/src/effect/helpers.ts +0 -123
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { ToolSet } from 'ai'
|
|
2
2
|
import { Schema, Effect } from 'effect'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
5
|
+
|
|
6
|
+
class SpecialistRunnerError extends Schema.TaggedErrorClass<SpecialistRunnerError>()(ERROR_TAGS.SpecialistRunnerError, {
|
|
5
7
|
message: Schema.String,
|
|
6
8
|
cause: Schema.optional(Schema.Defect),
|
|
7
9
|
}) {}
|
|
@@ -4,6 +4,7 @@ import { convertToModelMessages, tool as createTool } from 'ai'
|
|
|
4
4
|
import { Schema, Deferred, Effect, Exit, Fiber, Queue, Ref, Scope } from 'effect'
|
|
5
5
|
|
|
6
6
|
import type { ResolvedAgentConfig } from '../../config/agent-defaults'
|
|
7
|
+
import { ERROR_TAGS } from '../../effect/errors'
|
|
7
8
|
import { nowEpochMillis } from '../../utils/date-time'
|
|
8
9
|
import { createTimedAbortSignal } from '../agent-stream-helpers'
|
|
9
10
|
import { buildModelInputMessagesWithUploadMetadata, buildReadableUploadMetadataText } from '../chat-attachments'
|
|
@@ -15,7 +16,7 @@ import { buildTeamConsultationFailureMessage } from './team-consultation-prompts
|
|
|
15
16
|
export type DefaultRepoSections = RepoSectionName[]
|
|
16
17
|
const TEAM_CONSULTATION_TIMEOUT_MS = 90_000
|
|
17
18
|
|
|
18
|
-
class TeamConsultationError extends Schema.TaggedErrorClass<TeamConsultationError>()(
|
|
19
|
+
class TeamConsultationError extends Schema.TaggedErrorClass<TeamConsultationError>()(ERROR_TAGS.TeamConsultationError, {
|
|
19
20
|
message: Schema.String,
|
|
20
21
|
cause: Schema.optional(Schema.Defect),
|
|
21
22
|
}) {}
|
|
@@ -62,7 +63,7 @@ function selectTeamConsultationContextMessages(messages: ChatMessage[], latestUs
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
interface ParticipantObserver {
|
|
65
|
-
run<T>(fn: () =>
|
|
66
|
+
run<T>(fn: () => Promise<T>): Promise<T>
|
|
66
67
|
recordError?: (error: unknown) => void
|
|
67
68
|
recordAbort?: (error: unknown) => void
|
|
68
69
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Schema, Effect } from 'effect'
|
|
2
2
|
|
|
3
3
|
import type { RecordIdRef } from '../db/record-id'
|
|
4
|
-
import {
|
|
4
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
5
5
|
import { buildAgentPromptContext } from './agent-prompt-context'
|
|
6
6
|
import {
|
|
7
7
|
buildIndexedRepositoriesContext,
|
|
@@ -24,20 +24,13 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
24
24
|
return typeof value === 'object' && value !== null
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
class ThreadTurnContextError extends Schema.TaggedErrorClass<ThreadTurnContextError>()(
|
|
28
|
-
|
|
29
|
-
cause: Schema.optional(Schema.Defect),
|
|
30
|
-
|
|
27
|
+
class ThreadTurnContextError extends Schema.TaggedErrorClass<ThreadTurnContextError>()(
|
|
28
|
+
ERROR_TAGS.ThreadTurnContextError,
|
|
29
|
+
{ message: Schema.String, cause: Schema.optional(Schema.Defect) },
|
|
30
|
+
) {}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
function effectTryMaybeAsync<A>(
|
|
37
|
-
evaluate: () => A | PromiseLike<A>,
|
|
38
|
-
message: string,
|
|
39
|
-
): Effect.Effect<A, ThreadTurnContextError> {
|
|
40
|
-
return effectTryMaybeAsyncShared(evaluate, (cause) => new ThreadTurnContextError({ message, cause }))
|
|
32
|
+
function toThreadTurnContextError(message: string, cause: unknown): ThreadTurnContextError {
|
|
33
|
+
return new ThreadTurnContextError({ message, cause })
|
|
41
34
|
}
|
|
42
35
|
|
|
43
36
|
export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')(function* (params: {
|
|
@@ -55,38 +48,56 @@ export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')
|
|
|
55
48
|
runtimeAdapters: LotaRuntimeAdapters
|
|
56
49
|
pluginRuntime?: Record<string, unknown>
|
|
57
50
|
}) {
|
|
58
|
-
const workspace = yield*
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
const workspace = yield* Effect.tryPromise({
|
|
52
|
+
try: () => params.workspacePromise,
|
|
53
|
+
catch: (cause) => toThreadTurnContextError('Failed to load thread workspace', cause),
|
|
54
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.loadWorkspace'))
|
|
61
55
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
const workspaceProvider = params.workspaceProvider
|
|
57
|
+
const getLifecycleState = workspaceProvider?.getLifecycleState
|
|
58
|
+
? (() => {
|
|
59
|
+
const run = workspaceProvider.getLifecycleState.bind(workspaceProvider)
|
|
60
|
+
return (workspaceRecord: Record<string, unknown>) => run(workspaceRecord)
|
|
61
|
+
})()
|
|
62
|
+
: undefined
|
|
63
|
+
const workspaceLifecycleState = getLifecycleState
|
|
64
|
+
? yield* Effect.tryPromise({
|
|
65
|
+
try: () => getLifecycleState(workspace),
|
|
66
|
+
catch: (cause) => toThreadTurnContextError('Failed to load workspace lifecycle state', cause),
|
|
67
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.loadWorkspaceLifecycleState'))
|
|
68
|
+
: undefined
|
|
69
|
+
const readProfileProjectionState = workspaceProvider?.readProfileProjectionState
|
|
70
|
+
? (() => {
|
|
71
|
+
const run = workspaceProvider.readProfileProjectionState.bind(workspaceProvider)
|
|
72
|
+
return (workspaceRecord: Record<string, unknown>) => run(workspaceRecord)
|
|
73
|
+
})()
|
|
74
|
+
: undefined
|
|
75
|
+
const workspaceProfileState = readProfileProjectionState
|
|
76
|
+
? yield* Effect.tryPromise({
|
|
77
|
+
try: () => readProfileProjectionState(workspace),
|
|
78
|
+
catch: (cause) => toThreadTurnContextError('Failed to load workspace profile state', cause),
|
|
79
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.loadWorkspaceProfileState'))
|
|
80
|
+
: undefined
|
|
70
81
|
|
|
71
82
|
const onboardingActive = workspaceLifecycleState?.bootstrapActive ?? false
|
|
72
|
-
const linearInstallation = yield*
|
|
73
|
-
() => getLinearInstallationByOrgId(params.pluginRuntime, params.orgRef),
|
|
74
|
-
'Failed to load Linear installation',
|
|
75
|
-
).pipe(
|
|
83
|
+
const linearInstallation = yield* Effect.tryPromise({
|
|
84
|
+
try: () => getLinearInstallationByOrgId(params.pluginRuntime, params.orgRef),
|
|
85
|
+
catch: (cause) => toThreadTurnContextError('Failed to load Linear installation', cause),
|
|
86
|
+
}).pipe(
|
|
76
87
|
Effect.catch(() => Effect.succeed(null)),
|
|
77
88
|
Effect.withSpan('ThreadTurnContext.loadLinearInstallation'),
|
|
78
89
|
)
|
|
79
|
-
const githubInstallation = yield*
|
|
80
|
-
() => getGithubInstallationForOrganization(params.pluginRuntime, params.orgIdString),
|
|
81
|
-
'Failed to load GitHub installation',
|
|
82
|
-
).pipe(
|
|
90
|
+
const githubInstallation = yield* Effect.tryPromise({
|
|
91
|
+
try: () => getGithubInstallationForOrganization(params.pluginRuntime, params.orgIdString),
|
|
92
|
+
catch: (cause) => toThreadTurnContextError('Failed to load GitHub installation', cause),
|
|
93
|
+
}).pipe(
|
|
83
94
|
Effect.catch(() => Effect.succeed(null)),
|
|
84
95
|
Effect.withSpan('ThreadTurnContext.loadGithubInstallation'),
|
|
85
96
|
)
|
|
86
|
-
const indexedRepoContext = yield*
|
|
87
|
-
() => buildIndexedRepositoriesContext(params.runtimeAdapters, params.orgIdString),
|
|
88
|
-
'Failed to build indexed repository context',
|
|
89
|
-
).pipe(
|
|
97
|
+
const indexedRepoContext = yield* Effect.tryPromise({
|
|
98
|
+
try: () => buildIndexedRepositoriesContext(params.runtimeAdapters, params.orgIdString),
|
|
99
|
+
catch: (cause) => toThreadTurnContextError('Failed to build indexed repository context', cause),
|
|
100
|
+
}).pipe(
|
|
90
101
|
Effect.catch(() =>
|
|
91
102
|
Effect.succeed({
|
|
92
103
|
provideRepoTool: false,
|
|
@@ -96,17 +107,31 @@ export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')
|
|
|
96
107
|
),
|
|
97
108
|
Effect.withSpan('ThreadTurnContext.buildIndexedRepositoriesContext'),
|
|
98
109
|
)
|
|
99
|
-
const
|
|
100
|
-
() =>
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
const listRecentDomainEvents = workspaceProvider?.listRecentDomainEvents
|
|
111
|
+
? (() => {
|
|
112
|
+
const run = workspaceProvider.listRecentDomainEvents.bind(workspaceProvider)
|
|
113
|
+
return (workspaceId: RecordIdRef, limit?: number) => run(workspaceId, limit)
|
|
114
|
+
})()
|
|
115
|
+
: undefined
|
|
116
|
+
const recentDomainEvents = listRecentDomainEvents
|
|
117
|
+
? yield* Effect.tryPromise({
|
|
118
|
+
try: () => listRecentDomainEvents(params.orgRef, 5),
|
|
119
|
+
catch: (cause) => toThreadTurnContextError('Failed to load recent domain events', cause),
|
|
120
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.loadRecentDomainEvents'))
|
|
121
|
+
: []
|
|
122
|
+
const buildPromptSummary = workspaceProvider?.buildPromptSummary
|
|
123
|
+
? (() => {
|
|
124
|
+
const run = workspaceProvider.buildPromptSummary.bind(workspaceProvider)
|
|
125
|
+
return (workspaceId: RecordIdRef) => run(workspaceId)
|
|
126
|
+
})()
|
|
127
|
+
: undefined
|
|
103
128
|
const promptSummary =
|
|
104
|
-
|
|
129
|
+
buildPromptSummary === undefined
|
|
105
130
|
? undefined
|
|
106
|
-
: yield*
|
|
107
|
-
() =>
|
|
108
|
-
'Failed to build workspace prompt summary',
|
|
109
|
-
).pipe(
|
|
131
|
+
: yield* Effect.tryPromise({
|
|
132
|
+
try: () => buildPromptSummary(params.orgRef),
|
|
133
|
+
catch: (cause) => toThreadTurnContextError('Failed to build workspace prompt summary', cause),
|
|
134
|
+
}).pipe(
|
|
110
135
|
Effect.catch(() => Effect.as(Effect.void, undefined as string | undefined)),
|
|
111
136
|
Effect.withSpan('ThreadTurnContext.buildPromptSummary'),
|
|
112
137
|
)
|
|
@@ -120,41 +145,53 @@ export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')
|
|
|
120
145
|
userName: params.userName ?? undefined,
|
|
121
146
|
recentDomainEvents,
|
|
122
147
|
})
|
|
148
|
+
const buildRetrievedKnowledgeSection = workspaceProvider?.buildRetrievedKnowledgeSection
|
|
149
|
+
? (() => {
|
|
150
|
+
const run = workspaceProvider.buildRetrievedKnowledgeSection.bind(workspaceProvider)
|
|
151
|
+
return (input: Parameters<NonNullable<LotaRuntimeWorkspaceProvider['buildRetrievedKnowledgeSection']>>[0]) =>
|
|
152
|
+
run(input)
|
|
153
|
+
})()
|
|
154
|
+
: undefined
|
|
123
155
|
const initialRetrievedKnowledgeSection: string | undefined = !params.messageText
|
|
124
156
|
? undefined
|
|
125
|
-
:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
: buildRetrievedKnowledgeSection
|
|
158
|
+
? yield* Effect.tryPromise({
|
|
159
|
+
try: () =>
|
|
160
|
+
buildRetrievedKnowledgeSection({
|
|
161
|
+
workspaceId: params.orgIdString,
|
|
162
|
+
userId: params.userIdString,
|
|
163
|
+
query: params.messageText,
|
|
164
|
+
}),
|
|
165
|
+
catch: (cause) => toThreadTurnContextError('Failed to build retrieved knowledge section', cause),
|
|
166
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.buildRetrievedKnowledgeSection'))
|
|
167
|
+
: undefined
|
|
134
168
|
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
169
|
+
const buildContext = params.turnHooks.buildContext
|
|
170
|
+
const buildContextResultValue = buildContext
|
|
171
|
+
? yield* Effect.tryPromise({
|
|
172
|
+
try: () =>
|
|
173
|
+
buildContext({
|
|
174
|
+
thread: params.thread,
|
|
175
|
+
threadRef: params.threadRef,
|
|
176
|
+
orgRef: params.orgRef,
|
|
177
|
+
userRef: params.userRef,
|
|
178
|
+
userName: params.userName,
|
|
179
|
+
workspace,
|
|
180
|
+
onboardingActive,
|
|
181
|
+
messageText: params.messageText,
|
|
182
|
+
linearInstalled: initialLinearInstalled,
|
|
183
|
+
githubInstalled: initialGithubInstalled,
|
|
184
|
+
indexedRepoContext,
|
|
185
|
+
promptContext: initialPromptContext,
|
|
186
|
+
workspaceLifecycleState,
|
|
187
|
+
workspaceProfileState,
|
|
188
|
+
promptSummary,
|
|
189
|
+
recentDomainEvents,
|
|
190
|
+
retrievedKnowledgeSection: initialRetrievedKnowledgeSection,
|
|
191
|
+
}),
|
|
192
|
+
catch: (cause) => toThreadTurnContextError('Failed to build thread context', cause),
|
|
193
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.buildContextHook'))
|
|
194
|
+
: undefined
|
|
158
195
|
const buildContextResult = isRecord(buildContextResultValue) ? buildContextResultValue : null
|
|
159
196
|
|
|
160
197
|
const buildContextPromptDetails = readOptionalString(buildContextResult?.systemWorkspaceDetails)
|
|
@@ -171,31 +208,34 @@ export const assembleThreadTurnContext = Effect.fn('ThreadTurnContext.assemble')
|
|
|
171
208
|
const githubInstalled =
|
|
172
209
|
buildContextGithubInstalled !== undefined ? buildContextGithubInstalled : initialGithubInstalled
|
|
173
210
|
|
|
211
|
+
const buildExtraInstructionSections = params.turnHooks.buildExtraInstructionSections
|
|
174
212
|
const hookInstructionSections = readInstructionSections(
|
|
175
|
-
|
|
176
|
-
(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
213
|
+
buildExtraInstructionSections
|
|
214
|
+
? yield* Effect.tryPromise({
|
|
215
|
+
try: () =>
|
|
216
|
+
buildExtraInstructionSections({
|
|
217
|
+
thread: params.thread,
|
|
218
|
+
threadRef: params.threadRef,
|
|
219
|
+
orgRef: params.orgRef,
|
|
220
|
+
userRef: params.userRef,
|
|
221
|
+
userName: params.userName,
|
|
222
|
+
workspace,
|
|
223
|
+
onboardingActive,
|
|
224
|
+
messageText: params.messageText,
|
|
225
|
+
linearInstalled,
|
|
226
|
+
githubInstalled,
|
|
227
|
+
indexedRepoContext,
|
|
228
|
+
promptContext,
|
|
229
|
+
workspaceLifecycleState,
|
|
230
|
+
workspaceProfileState,
|
|
231
|
+
promptSummary,
|
|
232
|
+
recentDomainEvents,
|
|
233
|
+
retrievedKnowledgeSection,
|
|
234
|
+
context: buildContextResult,
|
|
235
|
+
}),
|
|
236
|
+
catch: (cause) => toThreadTurnContextError('Failed to build extra instruction sections', cause),
|
|
237
|
+
}).pipe(Effect.withSpan('ThreadTurnContext.buildExtraInstructionSections'))
|
|
238
|
+
: undefined,
|
|
199
239
|
)
|
|
200
240
|
|
|
201
241
|
return {
|
|
@@ -2,79 +2,48 @@ import type { ChatMessage } from '@lota-sdk/shared'
|
|
|
2
2
|
import { Schema, Effect } from 'effect'
|
|
3
3
|
|
|
4
4
|
import { serverLogger } from '../config/logger'
|
|
5
|
-
import {
|
|
5
|
+
import { ERROR_TAGS } from '../effect/errors'
|
|
6
6
|
|
|
7
|
-
export class TurnLifecycleError extends Schema.TaggedErrorClass<TurnLifecycleError>()(
|
|
7
|
+
export class TurnLifecycleError extends Schema.TaggedErrorClass<TurnLifecycleError>()(ERROR_TAGS.TurnLifecycleError, {
|
|
8
8
|
message: Schema.String,
|
|
9
9
|
cause: Schema.optional(Schema.Defect),
|
|
10
10
|
}) {}
|
|
11
11
|
|
|
12
|
-
type MaybeAsync<A> = A | PromiseLike<A>
|
|
13
|
-
type MaybeEffect<A> = MaybeAsync<A> | Effect.Effect<A, TurnLifecycleError>
|
|
14
|
-
|
|
15
|
-
function effectFromMaybeEffect<A>(
|
|
16
|
-
evaluate: () => MaybeEffect<A>,
|
|
17
|
-
onError: (error: unknown) => TurnLifecycleError,
|
|
18
|
-
): Effect.Effect<A, TurnLifecycleError> {
|
|
19
|
-
return Effect.suspend(() => {
|
|
20
|
-
try {
|
|
21
|
-
const result = evaluate()
|
|
22
|
-
return Effect.isEffect(result)
|
|
23
|
-
? result.pipe(Effect.mapError(onError))
|
|
24
|
-
: effectTryMaybeAsync(() => result, onError)
|
|
25
|
-
} catch (error) {
|
|
26
|
-
return Effect.fail(onError(error))
|
|
27
|
-
}
|
|
28
|
-
})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
12
|
export function finalizeTurnRunEffect(params: {
|
|
32
13
|
serverRunId: string
|
|
33
|
-
getEntity: () =>
|
|
34
|
-
|
|
14
|
+
getEntity: () => Effect.Effect<
|
|
15
|
+
{ lastCompactedMessageId?: string | null; compactionSummary?: string | null },
|
|
16
|
+
TurnLifecycleError
|
|
17
|
+
>
|
|
18
|
+
getUncompactedMessages: (cursor?: string) => Effect.Effect<ChatMessage[], TurnLifecycleError>
|
|
35
19
|
assessCompaction: (summaryText: string, messages: ChatMessage[]) => { shouldCompact: boolean }
|
|
36
|
-
enqueueCompaction: () =>
|
|
20
|
+
enqueueCompaction: () => Effect.Effect<void, TurnLifecycleError>
|
|
37
21
|
unregisterRun: (runId: string) => void
|
|
38
|
-
clearActiveRunId: (runId: string) =>
|
|
22
|
+
clearActiveRunId: (runId: string) => Effect.Effect<void, TurnLifecycleError>
|
|
39
23
|
disposeAbort: () => void
|
|
40
24
|
activeStreamId?: string
|
|
41
|
-
clearActiveStreamId?: (streamId: string) =>
|
|
25
|
+
clearActiveStreamId?: (streamId: string) => Effect.Effect<void, TurnLifecycleError>
|
|
42
26
|
}): Effect.Effect<void, TurnLifecycleError> {
|
|
43
27
|
return Effect.gen(function* () {
|
|
44
28
|
// Clear the active run immediately so new messages are not blocked
|
|
45
29
|
params.unregisterRun(params.serverRunId)
|
|
46
|
-
yield*
|
|
47
|
-
() => params.clearActiveRunId(params.serverRunId),
|
|
48
|
-
(error) => new TurnLifecycleError({ message: String(error), cause: error }),
|
|
49
|
-
)
|
|
30
|
+
yield* params.clearActiveRunId(params.serverRunId)
|
|
50
31
|
const activeStreamId = params.activeStreamId
|
|
51
32
|
const clearActiveStreamId = params.clearActiveStreamId
|
|
52
33
|
if (activeStreamId && clearActiveStreamId) {
|
|
53
|
-
yield*
|
|
54
|
-
() => clearActiveStreamId(activeStreamId),
|
|
55
|
-
(error) => new TurnLifecycleError({ message: String(error), cause: error }),
|
|
56
|
-
)
|
|
34
|
+
yield* clearActiveStreamId(activeStreamId)
|
|
57
35
|
}
|
|
58
36
|
params.disposeAbort()
|
|
59
37
|
|
|
60
38
|
yield* Effect.gen(function* () {
|
|
61
|
-
const entity = yield*
|
|
62
|
-
() => params.getEntity(),
|
|
63
|
-
(error) => new TurnLifecycleError({ message: String(error), cause: error }),
|
|
64
|
-
)
|
|
39
|
+
const entity = yield* params.getEntity()
|
|
65
40
|
const cursor = typeof entity.lastCompactedMessageId === 'string' ? entity.lastCompactedMessageId : undefined
|
|
66
|
-
const uncompactedMessages = yield*
|
|
67
|
-
() => params.getUncompactedMessages(cursor),
|
|
68
|
-
(error) => new TurnLifecycleError({ message: String(error), cause: error }),
|
|
69
|
-
)
|
|
41
|
+
const uncompactedMessages = yield* params.getUncompactedMessages(cursor)
|
|
70
42
|
const summaryText = typeof entity.compactionSummary === 'string' ? entity.compactionSummary : ''
|
|
71
43
|
const { shouldCompact } = params.assessCompaction(summaryText, uncompactedMessages)
|
|
72
44
|
|
|
73
45
|
if (shouldCompact) {
|
|
74
|
-
yield*
|
|
75
|
-
() => params.enqueueCompaction(),
|
|
76
|
-
(error) => new TurnLifecycleError({ message: String(error), cause: error }),
|
|
77
|
-
)
|
|
46
|
+
yield* params.enqueueCompaction()
|
|
78
47
|
}
|
|
79
48
|
}).pipe(
|
|
80
49
|
Effect.catch((error: unknown) =>
|
|
@@ -43,7 +43,7 @@ type AgentActivityDeps = {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
class AgentActivityServiceError extends Schema.TaggedErrorClass<AgentActivityServiceError>()(
|
|
46
|
-
'AgentActivityServiceError',
|
|
46
|
+
'@lota-sdk/core/AgentActivityServiceError',
|
|
47
47
|
{ message: Schema.String, cause: Schema.Defect },
|
|
48
48
|
) {}
|
|
49
49
|
|