@lota-sdk/core 0.4.9 → 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.
- package/package.json +2 -2
- package/src/ai/embedding-cache.ts +3 -1
- package/src/ai-gateway/ai-gateway.ts +164 -82
- package/src/ai-gateway/index.ts +16 -1
- package/src/config/agent-defaults.ts +4 -107
- package/src/config/agent-types.ts +1 -1
- package/src/config/background-processing.ts +1 -1
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +22 -25
- package/src/config/thread-defaults.ts +1 -10
- package/src/create-runtime.ts +145 -670
- package/src/db/base.service.ts +30 -38
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.ts +29 -20
- package/src/db/memory.ts +188 -195
- package/src/db/service-normalization.ts +97 -64
- package/src/db/service.ts +496 -384
- package/src/db/startup.ts +30 -19
- package/src/effect/helpers.ts +30 -5
- package/src/effect/index.ts +7 -7
- package/src/effect/layers.ts +75 -72
- package/src/effect/services.ts +15 -11
- package/src/embeddings/provider.ts +65 -71
- package/src/index.ts +13 -12
- package/src/queues/autonomous-job.queue.ts +177 -143
- package/src/queues/context-compaction.queue.ts +41 -39
- package/src/queues/delayed-node-promotion.queue.ts +61 -42
- package/src/queues/document-processor.queue.ts +5 -3
- package/src/queues/index.ts +1 -0
- package/src/queues/memory-consolidation.queue.ts +79 -53
- package/src/queues/organization-learning.queue.ts +70 -33
- package/src/queues/plan-agent-heartbeat.queue.ts +111 -83
- package/src/queues/plan-scheduler.queue.ts +101 -97
- package/src/queues/post-chat-memory.queue.ts +56 -46
- package/src/queues/queue-factory.ts +146 -69
- package/src/queues/queues.service.ts +61 -0
- package/src/queues/title-generation.queue.ts +44 -44
- package/src/redis/connection.ts +181 -164
- package/src/redis/org-memory-lock.ts +24 -9
- package/src/redis/redis-lease-lock.ts +8 -1
- package/src/redis/stream-context.ts +17 -9
- package/src/runtime/agent-identity-overrides.ts +7 -3
- package/src/runtime/agent-runtime-policy.ts +10 -5
- package/src/runtime/agent-stream-helpers.ts +24 -15
- package/src/runtime/chat-run-orchestration.ts +1 -1
- package/src/runtime/context-compaction/context-compaction-runtime.ts +28 -32
- package/src/runtime/context-compaction/context-compaction.ts +131 -85
- package/src/runtime/domain-layer.ts +203 -0
- package/src/runtime/execution-plan-visibility.ts +5 -2
- package/src/runtime/graph-designer.ts +0 -14
- package/src/runtime/helper-model.ts +8 -4
- package/src/runtime/index.ts +1 -1
- package/src/runtime/indexed-repositories-policy.ts +2 -6
- package/src/runtime/memory/memory-block.ts +19 -9
- package/src/runtime/memory/memory-pipeline.ts +53 -66
- package/src/runtime/memory/memory-scope.ts +33 -29
- package/src/runtime/plugin-resolution.ts +58 -62
- package/src/runtime/post-turn-side-effects.ts +139 -161
- package/src/runtime/retrieval-adapters.ts +4 -4
- package/src/runtime/runtime-config.ts +3 -9
- package/src/runtime/runtime-extensions.ts +0 -43
- package/src/runtime/runtime-lifecycle.ts +124 -0
- package/src/runtime/runtime-services.ts +455 -0
- package/src/runtime/runtime-worker-registry.ts +113 -30
- package/src/runtime/social-chat/social-chat-agent-runner.ts +13 -8
- package/src/runtime/social-chat/social-chat-history.ts +24 -13
- package/src/runtime/social-chat/social-chat.ts +420 -369
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +64 -57
- package/src/runtime/team-consultation/team-consultation-prompts.ts +11 -6
- package/src/runtime/thread-chat-helpers.ts +18 -9
- package/src/runtime/thread-turn-context.ts +28 -74
- package/src/runtime/turn-lifecycle.ts +6 -14
- package/src/services/agent-activity.service.ts +169 -176
- package/src/services/agent-executor.service.ts +207 -196
- package/src/services/artifact.service.ts +10 -5
- package/src/services/attachment.service.ts +16 -48
- package/src/services/autonomous-job.service.ts +81 -87
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +3 -1
- package/src/services/context-compaction.service.ts +8 -10
- package/src/services/document-chunk.service.ts +8 -17
- package/src/services/execution-plan/execution-plan-graph.ts +122 -109
- package/src/services/execution-plan/execution-plan-schedule.ts +1 -15
- package/src/services/execution-plan/execution-plan.service.ts +68 -51
- package/src/services/feedback-loop.service.ts +1 -1
- package/src/services/global-orchestrator.service.ts +49 -15
- package/src/services/graph-full-routing.ts +49 -37
- package/src/services/index.ts +1 -0
- package/src/services/institutional-memory.service.ts +8 -17
- package/src/services/learned-skill.service.ts +38 -35
- package/src/services/memory/memory-conversation.ts +10 -5
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +14 -3
- package/src/services/memory/memory-preseeded.ts +10 -4
- package/src/services/memory/memory-utils.ts +2 -1
- package/src/services/memory/memory.service.ts +37 -52
- package/src/services/memory/rerank.service.ts +3 -11
- package/src/services/monitoring-window.service.ts +1 -1
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +2 -2
- package/src/services/notification.service.ts +16 -4
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +34 -51
- package/src/services/ownership-dispatcher.service.ts +148 -95
- package/src/services/plan/plan-agent-heartbeat.service.ts +30 -16
- package/src/services/plan/plan-agent-query.service.ts +13 -9
- package/src/services/plan/plan-approval.service.ts +52 -48
- package/src/services/plan/plan-artifact.service.ts +2 -2
- package/src/services/plan/plan-builder.service.ts +2 -2
- package/src/services/plan/plan-checkpoint.service.ts +1 -1
- package/src/services/plan/plan-compiler.service.ts +1 -1
- package/src/services/plan/plan-completion-side-effects.ts +99 -113
- package/src/services/plan/plan-coordination.service.ts +1 -1
- package/src/services/plan/plan-cycle.service.ts +171 -202
- package/src/services/plan/plan-deadline.service.ts +304 -307
- package/src/services/plan/plan-event-delivery.service.ts +84 -72
- package/src/services/plan/plan-executor-context.ts +2 -0
- package/src/services/plan/plan-executor-graph.ts +375 -353
- package/src/services/plan/plan-executor-helpers.ts +60 -75
- package/src/services/plan/plan-executor.service.ts +494 -489
- package/src/services/plan/plan-run.service.ts +12 -19
- package/src/services/plan/plan-scheduler.service.ts +89 -82
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +8 -5
- package/src/services/plan/plan-validator.service.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +17 -11
- package/src/services/plugin-executor.service.ts +26 -21
- package/src/services/quality-metrics.service.ts +1 -1
- package/src/services/queue-job.service.ts +8 -17
- package/src/services/recent-activity-title.service.ts +22 -10
- package/src/services/recent-activity.service.ts +1 -1
- package/src/services/skill-resolver.service.ts +1 -1
- package/src/services/social-chat-history.service.ts +37 -20
- package/src/services/system-executor.service.ts +25 -20
- package/src/services/thread/thread-bootstrap.ts +37 -19
- package/src/services/thread/thread-listing.ts +2 -1
- package/src/services/thread/thread-memory-block.ts +18 -5
- package/src/services/thread/thread-message.service.ts +30 -13
- package/src/services/thread/thread-title.service.ts +1 -1
- package/src/services/thread/thread-turn-execution.ts +87 -83
- package/src/services/thread/thread-turn-preparation.service.ts +65 -40
- package/src/services/thread/thread-turn-streaming.ts +32 -36
- package/src/services/thread/thread-turn.ts +43 -29
- package/src/services/thread/thread.service.ts +32 -8
- package/src/services/user.service.ts +1 -1
- package/src/services/write-intent-validator.service.ts +1 -1
- package/src/storage/attachment-storage.service.ts +7 -4
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +1 -1
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +1 -1
- package/src/system-agents/memory.agent.ts +1 -1
- package/src/system-agents/recent-activity-title-refiner.agent.ts +9 -6
- package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
- package/src/system-agents/skill-extractor.agent.ts +1 -1
- package/src/system-agents/skill-manager.agent.ts +1 -1
- package/src/system-agents/thread-router.agent.ts +23 -20
- package/src/system-agents/title-generator.agent.ts +1 -1
- package/src/tools/execution-plan.tool.ts +36 -20
- package/src/tools/fetch-webpage.tool.ts +30 -22
- package/src/tools/firecrawl-client.ts +1 -6
- package/src/tools/plan-approval.tool.ts +9 -1
- package/src/tools/remember-memory.tool.ts +3 -6
- package/src/tools/research-topic.tool.ts +12 -3
- package/src/tools/search-web.tool.ts +26 -18
- package/src/tools/search.tool.ts +4 -5
- package/src/tools/team-think.tool.ts +139 -121
- package/src/utils/async.ts +15 -6
- package/src/utils/errors.ts +27 -15
- package/src/workers/bootstrap.ts +34 -58
- package/src/workers/memory-consolidation.worker.ts +4 -1
- package/src/workers/organization-learning.worker.ts +16 -3
- package/src/workers/regular-chat-memory-digest.helpers.ts +3 -4
- package/src/workers/regular-chat-memory-digest.runner.ts +46 -29
- package/src/workers/skill-extraction.runner.ts +13 -15
- package/src/workers/worker-utils.ts +14 -8
- package/src/config/search.ts +0 -3
- package/src/effect/awaitable-effect.ts +0 -87
- package/src/effect/runtime-ref.ts +0 -25
- package/src/effect/runtime.ts +0 -31
- package/src/redis/runtime-connection.ts +0 -10
- package/src/runtime/agent-types.ts +0 -1
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { isAgentName } from '../config/agent-defaults'
|
|
2
1
|
import { compactWhitespace, readRecord, readString } from '../utils/string'
|
|
3
2
|
import type { DigestMessage } from './utils/thread-message-query'
|
|
4
3
|
|
|
@@ -26,7 +25,7 @@ function normalizeFilePartMetadata(part: DigestMessagePart): string | null {
|
|
|
26
25
|
|
|
27
26
|
function extractAssistantLabel(
|
|
28
27
|
message: DigestMessageForTranscript,
|
|
29
|
-
isKnownAgentName: (value: string) => boolean
|
|
28
|
+
isKnownAgentName: (value: string) => boolean,
|
|
30
29
|
): string {
|
|
31
30
|
const metadataAgentId =
|
|
32
31
|
typeof message.metadata?.agentId === 'string' ? message.metadata.agentId.trim().toLowerCase() : ''
|
|
@@ -44,11 +43,11 @@ function extractAssistantLabel(
|
|
|
44
43
|
|
|
45
44
|
export function buildDigestTranscript(params: {
|
|
46
45
|
messages: DigestMessageForTranscript[]
|
|
47
|
-
isKnownAgentName
|
|
46
|
+
isKnownAgentName: (value: string) => boolean
|
|
48
47
|
}): { transcript: string; involvedAgentNames: string[] } {
|
|
49
48
|
const lines: string[] = []
|
|
50
49
|
const involvedAgentNames = new Set<string>()
|
|
51
|
-
const isKnownAgentName = params
|
|
50
|
+
const { isKnownAgentName } = params
|
|
52
51
|
|
|
53
52
|
for (const message of params.messages) {
|
|
54
53
|
if (message.role !== 'user' && message.role !== 'assistant') continue
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Effect, Schema } from 'effect'
|
|
2
2
|
import type { Context } from 'effect'
|
|
3
3
|
import { BoundQuery } from 'surrealdb'
|
|
4
4
|
import { z } from 'zod'
|
|
5
5
|
|
|
6
|
+
import type { ResolvedAgentConfig } from '../config/agent-defaults'
|
|
7
|
+
import { isAgentName } from '../config/agent-defaults'
|
|
6
8
|
import { serverLogger } from '../config/logger'
|
|
7
9
|
import { ensureRecordId, recordIdToString } from '../db/record-id'
|
|
8
10
|
import type { RecordIdRef } from '../db/record-id'
|
|
9
11
|
import type { SurrealDBService } from '../db/service'
|
|
10
12
|
import { TABLES } from '../db/tables'
|
|
11
13
|
import { effectTryPromise } from '../effect/helpers'
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
import type {
|
|
15
|
+
OrganizationLearningQueueRuntime,
|
|
16
|
+
RegularChatMemoryDigestJob,
|
|
15
17
|
} from '../queues/organization-learning.queue'
|
|
16
|
-
import type { RegularChatMemoryDigestJob } from '../queues/organization-learning.queue'
|
|
17
18
|
import { createHelperModelRuntime } from '../runtime/helper-model'
|
|
18
19
|
import type { LotaRuntimeAdapters, LotaRuntimeBackgroundCursor } from '../runtime/runtime-extensions'
|
|
19
20
|
import type { MemoryServiceTag } from '../services/memory/memory.service'
|
|
@@ -35,13 +36,20 @@ import type { DigestMessage } from './utils/thread-message-query'
|
|
|
35
36
|
// can be digested into durable memory and profile projections in the background.
|
|
36
37
|
const StructuredProfilePatchSchema = z.record(z.string(), z.unknown()).default({})
|
|
37
38
|
|
|
39
|
+
class MemoryDigestError extends Schema.TaggedErrorClass<MemoryDigestError>()('MemoryDigestError', {
|
|
40
|
+
message: Schema.String,
|
|
41
|
+
cause: Schema.Defect,
|
|
42
|
+
}) {}
|
|
43
|
+
|
|
38
44
|
const REGULAR_CHAT_MEMORY_DIGEST_TIMEOUT_MS = 10 * 60 * 1000
|
|
39
45
|
const WorkspaceMemoryRowSchema = z.object({ content: z.string() })
|
|
40
46
|
export interface RegularChatDigestServices {
|
|
47
|
+
agentConfig: ResolvedAgentConfig
|
|
41
48
|
databaseService: SurrealDBService
|
|
42
49
|
memoryService: Context.Service.Shape<typeof MemoryServiceTag>
|
|
43
50
|
socialChatHistoryService: Context.Service.Shape<typeof SocialChatHistoryServiceTag>
|
|
44
51
|
runtimeAdapters: LotaRuntimeAdapters
|
|
52
|
+
organizationLearningQueue: OrganizationLearningQueueRuntime
|
|
45
53
|
}
|
|
46
54
|
|
|
47
55
|
const ExtractedFactSchema = z.object({
|
|
@@ -120,11 +128,9 @@ function hasNewEligibleThreadMessages(params: {
|
|
|
120
128
|
Effect.gen(function* () {
|
|
121
129
|
if (params.threadIds.length === 0) return false
|
|
122
130
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
query = new BoundQuery(
|
|
127
|
-
`SELECT id, createdAt FROM ${TABLES.THREAD_MESSAGE}
|
|
131
|
+
const query: BoundQuery | null = params.cursor
|
|
132
|
+
? new BoundQuery(
|
|
133
|
+
`SELECT id, createdAt FROM ${TABLES.THREAD_MESSAGE}
|
|
128
134
|
WHERE threadId IN $threadIds
|
|
129
135
|
AND (
|
|
130
136
|
createdAt > $cursorCreatedAt
|
|
@@ -132,18 +138,22 @@ function hasNewEligibleThreadMessages(params: {
|
|
|
132
138
|
)
|
|
133
139
|
ORDER BY createdAt ASC, id ASC
|
|
134
140
|
LIMIT 1`,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
{
|
|
142
|
+
threadIds: params.threadIds,
|
|
143
|
+
cursorCreatedAt: params.cursor.createdAt,
|
|
144
|
+
cursorRowId: ensureRecordId(params.cursor.id, TABLES.THREAD_MESSAGE),
|
|
145
|
+
},
|
|
146
|
+
)
|
|
147
|
+
: params.onboardingCutoff
|
|
148
|
+
? new BoundQuery(
|
|
149
|
+
`SELECT id, createdAt FROM ${TABLES.THREAD_MESSAGE}
|
|
140
150
|
WHERE threadId IN $threadIds
|
|
141
151
|
AND createdAt > $onboardingCutoff
|
|
142
152
|
ORDER BY createdAt ASC, id ASC
|
|
143
153
|
LIMIT 1`,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
{ threadIds: params.threadIds, onboardingCutoff: params.onboardingCutoff },
|
|
155
|
+
)
|
|
156
|
+
: null
|
|
147
157
|
|
|
148
158
|
if (!query) return false
|
|
149
159
|
const rows = yield* effectTryPromise(() => params.db.query<unknown>(query))
|
|
@@ -233,7 +243,10 @@ function runRegularChatMemoryDigestEffect(
|
|
|
233
243
|
}
|
|
234
244
|
|
|
235
245
|
const combinedMessages = [...threadMessages, ...socialMessages].sort(compareDigestMessageOrder)
|
|
236
|
-
const { transcript, involvedAgentNames } = buildDigestTranscript({
|
|
246
|
+
const { transcript, involvedAgentNames } = buildDigestTranscript({
|
|
247
|
+
messages: combinedMessages,
|
|
248
|
+
isKnownAgentName: (value: string) => isAgentName(services.agentConfig, value),
|
|
249
|
+
})
|
|
237
250
|
const existingMemories = yield* effectTryPromise(() =>
|
|
238
251
|
loadExistingOrganizationMemories(services.databaseService, orgId),
|
|
239
252
|
)
|
|
@@ -261,7 +274,10 @@ function runRegularChatMemoryDigestEffect(
|
|
|
261
274
|
|
|
262
275
|
const summaryBlock = normalizeBlock(synthesis.summaryBlock)
|
|
263
276
|
if (!summaryBlock) {
|
|
264
|
-
return yield* new
|
|
277
|
+
return yield* new MemoryDigestError({
|
|
278
|
+
message: 'Regular chat memory digest returned an empty summaryBlock',
|
|
279
|
+
cause: new Error('Regular chat memory digest returned an empty summaryBlock'),
|
|
280
|
+
})
|
|
265
281
|
}
|
|
266
282
|
|
|
267
283
|
const processedThreadCursor = getLastCursor(threadMessages)
|
|
@@ -321,8 +337,10 @@ function runRegularChatMemoryDigestEffect(
|
|
|
321
337
|
|
|
322
338
|
const followUpScheduled = hasMoreThreadMessages || hasMoreSocialMessages
|
|
323
339
|
if (followUpScheduled) {
|
|
324
|
-
yield* effectTryPromise(() =>
|
|
325
|
-
|
|
340
|
+
yield* effectTryPromise(() =>
|
|
341
|
+
services.organizationLearningQueue.clearRegularChatMemoryDigestDeduplicationKey(orgId),
|
|
342
|
+
)
|
|
343
|
+
yield* effectTryPromise(() => services.organizationLearningQueue.enqueueRegularChatMemoryDigest({ orgId }))
|
|
326
344
|
}
|
|
327
345
|
|
|
328
346
|
serverLogger.info`Regular chat memory digest completed for ${orgId}: threadMessages=${threadMessages.length}, socialMessages=${socialMessages.length}, facts=${synthesis.facts.length}, followUpScheduled=${followUpScheduled}`
|
|
@@ -340,7 +358,7 @@ export function runRegularChatMemoryDigest(
|
|
|
340
358
|
data: RegularChatMemoryDigestJob,
|
|
341
359
|
services: RegularChatDigestServices,
|
|
342
360
|
): Promise<RegularChatDigestRunResult> {
|
|
343
|
-
const {
|
|
361
|
+
const { runtimeAdapters } = services
|
|
344
362
|
const orgRef = ensureRecordId(data.orgId, TABLES.ORGANIZATION)
|
|
345
363
|
const orgId = recordIdToString(orgRef, TABLES.ORGANIZATION)
|
|
346
364
|
const workspaceProvider = runtimeAdapters.workspaceProvider
|
|
@@ -357,12 +375,11 @@ export function runRegularChatMemoryDigest(
|
|
|
357
375
|
const withMemoryLock = runtimeAdapters.withWorkspaceMemoryLock
|
|
358
376
|
const runDigest = () =>
|
|
359
377
|
Effect.runPromise(
|
|
360
|
-
runRegularChatMemoryDigestEffect(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
),
|
|
378
|
+
runRegularChatMemoryDigestEffect(services, orgRef, orgId, workspaceProvider) as Effect.Effect<
|
|
379
|
+
RegularChatDigestRunResult,
|
|
380
|
+
never,
|
|
381
|
+
never
|
|
382
|
+
>,
|
|
366
383
|
)
|
|
367
384
|
|
|
368
385
|
return withMemoryLock ? withMemoryLock(orgId, runDigest) : runDigest()
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Context, Cause } from 'effect'
|
|
2
2
|
import { Effect } from 'effect'
|
|
3
3
|
|
|
4
|
+
import type { ResolvedAgentConfig } from '../config/agent-defaults'
|
|
5
|
+
import { isAgentName } from '../config/agent-defaults'
|
|
4
6
|
import { serverLogger } from '../config/logger'
|
|
5
7
|
import { ensureRecordId, recordIdToString } from '../db/record-id'
|
|
6
8
|
import type { RecordIdRef } from '../db/record-id'
|
|
@@ -27,6 +29,7 @@ const SKILL_EXTRACTION_TIMEOUT_MS = 10 * 60 * 1000
|
|
|
27
29
|
const MIN_MESSAGE_THRESHOLD = 10
|
|
28
30
|
|
|
29
31
|
export interface SkillExtractionServices {
|
|
32
|
+
agentConfig: ResolvedAgentConfig
|
|
30
33
|
databaseService: SurrealDBService
|
|
31
34
|
learnedSkillService: Context.Service.Shape<typeof LearnedSkillServiceTag>
|
|
32
35
|
socialChatHistoryService: Context.Service.Shape<typeof SocialChatHistoryServiceTag>
|
|
@@ -149,7 +152,10 @@ function runSkillExtractionEffect(
|
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
const sortedMessages = [...messages].sort(compareDigestMessageOrder)
|
|
152
|
-
const { transcript } = buildDigestTranscript({
|
|
155
|
+
const { transcript } = buildDigestTranscript({
|
|
156
|
+
messages: sortedMessages,
|
|
157
|
+
isKnownAgentName: (value: string) => isAgentName(services.agentConfig, value),
|
|
158
|
+
})
|
|
153
159
|
|
|
154
160
|
const existingSkills = yield* services.learnedSkillService.listForOrg(orgId)
|
|
155
161
|
const existingSkillsSummary =
|
|
@@ -301,7 +307,7 @@ export function runSkillExtraction(
|
|
|
301
307
|
data: SkillExtractionJob,
|
|
302
308
|
services: SkillExtractionServices,
|
|
303
309
|
): Promise<SkillExtractionRunResult> {
|
|
304
|
-
const {
|
|
310
|
+
const { runtimeAdapters } = services
|
|
305
311
|
const orgRef = ensureRecordId(data.orgId, TABLES.ORGANIZATION)
|
|
306
312
|
const orgId = recordIdToString(orgRef, TABLES.ORGANIZATION)
|
|
307
313
|
const workspaceProvider = runtimeAdapters.workspaceProvider
|
|
@@ -317,19 +323,11 @@ export function runSkillExtraction(
|
|
|
317
323
|
const withMemoryLock = runtimeAdapters.withWorkspaceMemoryLock
|
|
318
324
|
const runExtraction = () =>
|
|
319
325
|
Effect.runPromise(
|
|
320
|
-
runSkillExtractionEffect(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
runtimeAdapters,
|
|
326
|
-
embeddingModel: services.embeddingModel,
|
|
327
|
-
},
|
|
328
|
-
orgRef,
|
|
329
|
-
orgId,
|
|
330
|
-
workspaceProvider,
|
|
331
|
-
embeddings,
|
|
332
|
-
),
|
|
326
|
+
runSkillExtractionEffect(services, orgRef, orgId, workspaceProvider, embeddings) as Effect.Effect<
|
|
327
|
+
SkillExtractionRunResult,
|
|
328
|
+
never,
|
|
329
|
+
never
|
|
330
|
+
>,
|
|
333
331
|
)
|
|
334
332
|
|
|
335
333
|
return withMemoryLock ? withMemoryLock(orgId, runExtraction) : runExtraction()
|
|
@@ -5,12 +5,9 @@ import { Effect } from 'effect'
|
|
|
5
5
|
import type { Context } from 'effect'
|
|
6
6
|
|
|
7
7
|
import { chatLogger } from '../config/logger'
|
|
8
|
-
import {
|
|
9
|
-
import { QueueJobServiceTag } from '../services/queue-job.service'
|
|
8
|
+
import type { QueueJobServiceTag } from '../services/queue-job.service'
|
|
10
9
|
|
|
11
|
-
export
|
|
12
|
-
return getCurrentRuntime().runSync(Effect.service(QueueJobServiceTag))
|
|
13
|
-
}
|
|
10
|
+
export type QueueJobService = Context.Service.Shape<typeof QueueJobServiceTag>
|
|
14
11
|
|
|
15
12
|
export const DEFAULT_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 24 * 60 * 60, count: 200 } }
|
|
16
13
|
export const LOW_JOB_RETENTION = { removeOnComplete: true, removeOnFail: { age: 6 * 60 * 60, count: 50 } }
|
|
@@ -88,6 +85,7 @@ export const createWorkerShutdown = (worker: Worker, name: string, logger: typeo
|
|
|
88
85
|
export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TResult = void>(
|
|
89
86
|
queueName: string,
|
|
90
87
|
processor: (job: TJob) => Promise<TResult>,
|
|
88
|
+
queueJobService: QueueJobService,
|
|
91
89
|
): (job: TJob) => Promise<TResult> {
|
|
92
90
|
return (job: TJob) => {
|
|
93
91
|
const trackedJob = {
|
|
@@ -107,7 +105,7 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
107
105
|
return Effect.runPromise(
|
|
108
106
|
Effect.catch(
|
|
109
107
|
Effect.gen(function* () {
|
|
110
|
-
yield* Effect.catch(
|
|
108
|
+
yield* Effect.catch(queueJobService.markAttemptStarted(trackedJob), (error) =>
|
|
111
109
|
Effect.sync(() => {
|
|
112
110
|
logPersistenceError('start', error)
|
|
113
111
|
}),
|
|
@@ -115,7 +113,7 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
115
113
|
|
|
116
114
|
const result = yield* Effect.tryPromise(() => processor(job))
|
|
117
115
|
|
|
118
|
-
yield* Effect.catch(
|
|
116
|
+
yield* Effect.catch(queueJobService.markAttemptCompleted(trackedJob, result), (error) =>
|
|
119
117
|
Effect.sync(() => {
|
|
120
118
|
logPersistenceError('completion', error)
|
|
121
119
|
}),
|
|
@@ -125,13 +123,21 @@ export function createTracedWorkerProcessor<TJob extends TracedWorkerJobLike, TR
|
|
|
125
123
|
}),
|
|
126
124
|
(error) =>
|
|
127
125
|
Effect.gen(function* () {
|
|
128
|
-
yield* Effect.catch(
|
|
126
|
+
yield* Effect.catch(queueJobService.markAttemptFailed(trackedJob, error), (persistenceError) =>
|
|
129
127
|
Effect.sync(() => {
|
|
130
128
|
logPersistenceError('failure', persistenceError)
|
|
131
129
|
}),
|
|
132
130
|
)
|
|
133
131
|
return yield* error
|
|
134
132
|
}),
|
|
133
|
+
).pipe(
|
|
134
|
+
Effect.withSpan(`worker.${queueName}.${job.name}`),
|
|
135
|
+
Effect.annotateSpans({
|
|
136
|
+
'job.id': trackedJob.id !== undefined ? String(trackedJob.id) : 'unknown',
|
|
137
|
+
'job.name': job.name,
|
|
138
|
+
'job.attemptsMade': typeof job.attemptsMade === 'number' ? job.attemptsMade : -1,
|
|
139
|
+
'queue.name': queueName,
|
|
140
|
+
}),
|
|
135
141
|
),
|
|
136
142
|
)
|
|
137
143
|
}
|
package/src/config/search.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect'
|
|
2
|
-
|
|
3
|
-
const awaitableEffectMarker = Symbol('AwaitableEffect')
|
|
4
|
-
|
|
5
|
-
type AwaitableEffectState<A> = { promise?: Promise<A> }
|
|
6
|
-
|
|
7
|
-
export type AwaitableEffect<A, E> = Effect.Effect<A, E, never> & Promise<A>
|
|
8
|
-
|
|
9
|
-
export type AwaitableValue<T> = T extends (...args: infer TArgs) => Effect.Effect<infer A, infer E, never>
|
|
10
|
-
? (...args: TArgs) => AwaitableEffect<A, E>
|
|
11
|
-
: T extends (...args: infer TArgs) => infer TResult
|
|
12
|
-
? (...args: TArgs) => TResult
|
|
13
|
-
: T
|
|
14
|
-
|
|
15
|
-
type AwaitableServiceMethods<T> = {
|
|
16
|
-
[K in keyof T]: AwaitableValue<T[K]>
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type AwaitableService<T> = AwaitableServiceMethods<T>
|
|
20
|
-
|
|
21
|
-
export type MaybeAwaitableService<T extends object> = T | AwaitableService<T>
|
|
22
|
-
|
|
23
|
-
type AwaitableEffectOptions = { runPromise?: <A, E>(effect: Effect.Effect<A, E, never>) => Promise<A> }
|
|
24
|
-
|
|
25
|
-
export function toAwaitableEffect<A, E>(
|
|
26
|
-
effect: Effect.Effect<A, E, never>,
|
|
27
|
-
options?: AwaitableEffectOptions,
|
|
28
|
-
): AwaitableEffect<A, E> {
|
|
29
|
-
const existing = effect as AwaitableEffect<A, E> & { [awaitableEffectMarker]?: AwaitableEffectState<A> }
|
|
30
|
-
|
|
31
|
-
if (existing[awaitableEffectMarker]) {
|
|
32
|
-
return existing
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const state: AwaitableEffectState<A> = {}
|
|
36
|
-
const runPromise = options?.runPromise ?? Effect.runPromise
|
|
37
|
-
const ensurePromise = () => (state.promise ??= runPromise(effect))
|
|
38
|
-
const candidate = Object.create(
|
|
39
|
-
Object.getPrototypeOf(effect),
|
|
40
|
-
Object.getOwnPropertyDescriptors(effect),
|
|
41
|
-
) as AwaitableEffect<A, E> & { [awaitableEffectMarker]?: AwaitableEffectState<A> }
|
|
42
|
-
|
|
43
|
-
const then: Promise<A>['then'] = (onfulfilled, onrejected) => ensurePromise().then(onfulfilled, onrejected)
|
|
44
|
-
const catchMethod: Promise<A>['catch'] = (onrejected) => ensurePromise().catch(onrejected)
|
|
45
|
-
const finallyMethod: Promise<A>['finally'] = (onfinally) => ensurePromise().finally(onfinally)
|
|
46
|
-
|
|
47
|
-
void Object.defineProperties(candidate, {
|
|
48
|
-
then: { value: then, configurable: true },
|
|
49
|
-
catch: { value: catchMethod, configurable: true },
|
|
50
|
-
finally: { value: finallyMethod, configurable: true },
|
|
51
|
-
[Symbol.toStringTag]: { value: 'Promise', configurable: true },
|
|
52
|
-
[awaitableEffectMarker]: { value: state },
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
return candidate
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function toAwaitableService<T extends object>(
|
|
59
|
-
service: T,
|
|
60
|
-
options?: AwaitableEffectOptions,
|
|
61
|
-
): AwaitableService<T> {
|
|
62
|
-
const wrappedMethods = new Map<PropertyKey, unknown>()
|
|
63
|
-
|
|
64
|
-
return new Proxy(service, {
|
|
65
|
-
get(target, property, receiver) {
|
|
66
|
-
const value = Reflect.get(target, property, receiver)
|
|
67
|
-
if (typeof value !== 'function') {
|
|
68
|
-
return value
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const existing = wrappedMethods.get(property)
|
|
72
|
-
if (existing !== undefined) {
|
|
73
|
-
return existing
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const wrapped = (...args: unknown[]) => {
|
|
77
|
-
const result = Reflect.apply(value, target, args)
|
|
78
|
-
return Effect.isEffect(result)
|
|
79
|
-
? toAwaitableEffect(result as Effect.Effect<unknown, unknown, never>, options)
|
|
80
|
-
: result
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
wrappedMethods.set(property, wrapped)
|
|
84
|
-
return wrapped
|
|
85
|
-
},
|
|
86
|
-
}) as AwaitableService<T>
|
|
87
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { ManagedRuntime } from 'effect'
|
|
2
|
-
|
|
3
|
-
// eslint-disable-next-line typescript-eslint/no-explicit-any -- ManagedRuntime is contravariant in R; `any` is the only valid wildcard
|
|
4
|
-
type SdkManagedRuntime = ManagedRuntime.ManagedRuntime<any, any>
|
|
5
|
-
|
|
6
|
-
let currentRuntime: SdkManagedRuntime | null = null
|
|
7
|
-
|
|
8
|
-
export function setCurrentRuntime<R, E>(runtime: ManagedRuntime.ManagedRuntime<R, E>): void {
|
|
9
|
-
currentRuntime = runtime as SdkManagedRuntime
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function clearCurrentRuntime(): void {
|
|
13
|
-
currentRuntime = null
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function getCurrentRuntime(): SdkManagedRuntime {
|
|
17
|
-
if (!currentRuntime) {
|
|
18
|
-
throw new Error('Lota Effect runtime is not configured. Call createLotaRuntime() first.')
|
|
19
|
-
}
|
|
20
|
-
return currentRuntime
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function getOptionalCurrentRuntime(): SdkManagedRuntime | null {
|
|
24
|
-
return currentRuntime
|
|
25
|
-
}
|
package/src/effect/runtime.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type { Effect, ManagedRuntime } from 'effect'
|
|
2
|
-
|
|
3
|
-
import { clearCurrentRuntime, getCurrentRuntime, getOptionalCurrentRuntime, setCurrentRuntime } from './runtime-ref'
|
|
4
|
-
|
|
5
|
-
export function setLotaSdkRuntime<R, E>(runtime: ManagedRuntime.ManagedRuntime<R, E>): void {
|
|
6
|
-
setCurrentRuntime(runtime)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function clearLotaSdkRuntime(): void {
|
|
10
|
-
clearCurrentRuntime()
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function getOptionalLotaSdkRuntime() {
|
|
14
|
-
return getOptionalCurrentRuntime()
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Returns the current managed runtime or throws. */
|
|
18
|
-
export function getLotaSdkRuntime() {
|
|
19
|
-
return getCurrentRuntime()
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Run an effect as a Promise using the current managed runtime's context.
|
|
24
|
-
* The runtime must be initialized via `createLotaRuntime()` before any call.
|
|
25
|
-
*/
|
|
26
|
-
export function runPromise<A, E>(
|
|
27
|
-
effect: Effect.Effect<A, E, never>,
|
|
28
|
-
options?: { readonly signal?: AbortSignal },
|
|
29
|
-
): Promise<A> {
|
|
30
|
-
return getCurrentRuntime().runPromise(effect, options)
|
|
31
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect'
|
|
2
|
-
import type IORedis from 'ioredis'
|
|
3
|
-
|
|
4
|
-
import { getCurrentRuntime } from '../effect/runtime-ref'
|
|
5
|
-
import { RedisServiceTag } from '../effect/services'
|
|
6
|
-
|
|
7
|
-
export function getRuntimeRedisConnection(): IORedis {
|
|
8
|
-
const redis = getCurrentRuntime().runSync(Effect.service(RedisServiceTag))
|
|
9
|
-
return redis.getConnection()
|
|
10
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type { ChatMode, CreateHelperToolLoopAgentOptions, CreateRoutedAgentOptions } from '@lota-sdk/shared'
|