@lota-sdk/core 0.4.8 → 0.4.9
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 +11 -12
- package/src/ai/embedding-cache.ts +94 -22
- package/src/ai-gateway/ai-gateway.ts +738 -223
- package/src/config/agent-defaults.ts +176 -75
- package/src/config/agent-types.ts +54 -4
- package/src/config/constants.ts +8 -2
- package/src/config/logger.ts +286 -19
- package/src/config/thread-defaults.ts +33 -21
- package/src/create-runtime.ts +725 -387
- package/src/db/base.service.ts +52 -28
- package/src/db/cursor-pagination.ts +71 -30
- package/src/db/memory-store.helpers.ts +4 -7
- package/src/db/memory-store.ts +856 -598
- package/src/db/memory.ts +398 -275
- package/src/db/record-id.ts +32 -10
- package/src/db/schema-fingerprint.ts +30 -12
- package/src/db/service-normalization.ts +255 -0
- package/src/db/service.ts +726 -761
- package/src/db/startup.ts +140 -66
- package/src/db/transaction-conflict.ts +15 -0
- package/src/effect/awaitable-effect.ts +87 -0
- package/src/effect/errors.ts +121 -0
- package/src/effect/helpers.ts +98 -0
- package/src/effect/index.ts +22 -0
- package/src/effect/layers.ts +228 -0
- package/src/effect/runtime-ref.ts +25 -0
- package/src/effect/runtime.ts +31 -0
- package/src/effect/services.ts +57 -0
- package/src/effect/zod.ts +43 -0
- package/src/embeddings/provider.ts +122 -76
- package/src/index.ts +46 -1
- package/src/openrouter/direct-provider.ts +11 -35
- package/src/queues/autonomous-job.queue.ts +130 -74
- package/src/queues/context-compaction.queue.ts +60 -15
- package/src/queues/delayed-node-promotion.queue.ts +52 -15
- package/src/queues/document-processor.queue.ts +52 -77
- package/src/queues/memory-consolidation.queue.ts +47 -32
- package/src/queues/organization-learning.queue.ts +13 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +65 -21
- package/src/queues/plan-scheduler.queue.ts +107 -31
- package/src/queues/post-chat-memory.queue.ts +66 -24
- package/src/queues/queue-factory.ts +142 -52
- package/src/queues/standalone-worker.ts +39 -0
- package/src/queues/title-generation.queue.ts +54 -9
- package/src/redis/connection.ts +84 -32
- package/src/redis/index.ts +6 -8
- package/src/redis/org-memory-lock.ts +60 -27
- package/src/redis/redis-lease-lock.ts +200 -121
- package/src/redis/runtime-connection.ts +10 -0
- package/src/redis/stream-context.ts +84 -46
- package/src/runtime/agent-identity-overrides.ts +2 -2
- package/src/runtime/agent-runtime-policy.ts +4 -1
- package/src/runtime/agent-stream-helpers.ts +20 -9
- package/src/runtime/chat-run-orchestration.ts +102 -19
- package/src/runtime/chat-run-registry.ts +36 -2
- package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
- package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +114 -91
- package/src/runtime/execution-plan-visibility.ts +2 -2
- package/src/runtime/execution-plan.ts +42 -15
- package/src/runtime/graph-designer.ts +11 -7
- package/src/runtime/helper-model.ts +135 -48
- package/src/runtime/index.ts +7 -7
- package/src/runtime/indexed-repositories-policy.ts +3 -3
- package/src/runtime/{memory-block.ts → memory/memory-block.ts} +40 -36
- package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
- package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +1 -1
- package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
- package/src/runtime/{memory-scope.ts → memory/memory-scope.ts} +12 -6
- package/src/runtime/plugin-resolution.ts +144 -24
- package/src/runtime/plugin-types.ts +9 -1
- package/src/runtime/post-turn-side-effects.ts +197 -130
- package/src/runtime/retrieval-adapters.ts +38 -4
- package/src/runtime/runtime-config.ts +150 -61
- package/src/runtime/runtime-extensions.ts +21 -34
- package/src/runtime/social-chat/social-chat-agent-runner.ts +157 -0
- package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +42 -20
- package/src/runtime/social-chat/social-chat.ts +594 -0
- package/src/runtime/specialist-runner.ts +36 -10
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +427 -0
- package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
- package/src/runtime/thread-chat-helpers.ts +2 -2
- package/src/runtime/thread-plan-turn.ts +2 -1
- package/src/runtime/thread-turn-context.ts +172 -94
- package/src/runtime/turn-lifecycle.ts +93 -27
- package/src/services/agent-activity.service.ts +287 -203
- package/src/services/agent-executor.service.ts +329 -217
- package/src/services/artifact.service.ts +225 -148
- package/src/services/attachment.service.ts +137 -115
- package/src/services/autonomous-job.service.ts +888 -491
- package/src/services/chat-run-registry.service.ts +11 -1
- package/src/services/context-compaction.service.ts +136 -86
- package/src/services/document-chunk.service.ts +162 -90
- package/src/services/execution-plan/execution-plan-approval.ts +26 -0
- package/src/services/execution-plan/execution-plan-context.ts +29 -0
- package/src/services/execution-plan/execution-plan-graph.ts +256 -0
- package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
- package/src/services/execution-plan/execution-plan-spec.ts +75 -0
- package/src/services/execution-plan/execution-plan.service.ts +1041 -0
- package/src/services/feedback-loop.service.ts +132 -76
- package/src/services/global-orchestrator.service.ts +80 -170
- package/src/services/graph-full-routing.ts +182 -0
- package/src/services/index.ts +18 -21
- package/src/services/institutional-memory.service.ts +220 -123
- package/src/services/learned-skill.service.ts +364 -259
- package/src/services/memory/memory-conversation.ts +95 -0
- package/src/services/memory/memory-org-memory.ts +39 -0
- package/src/services/memory/memory-preseeded.ts +80 -0
- package/src/services/memory/memory-rerank.ts +297 -0
- package/src/services/{memory-utils.ts → memory/memory-utils.ts} +5 -5
- package/src/services/memory/memory.service.ts +692 -0
- package/src/services/memory/rerank.service.ts +209 -0
- package/src/services/monitoring-window.service.ts +92 -70
- package/src/services/mutating-approval.service.ts +62 -53
- package/src/services/node-workspace.service.ts +141 -98
- package/src/services/notification.service.ts +17 -16
- package/src/services/organization-member.service.ts +120 -66
- package/src/services/organization.service.ts +144 -51
- package/src/services/ownership-dispatcher.service.ts +415 -264
- package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
- package/src/services/plan/plan-agent-query.service.ts +322 -0
- package/src/services/plan/plan-approval.service.ts +102 -0
- package/src/services/plan/plan-artifact.service.ts +60 -0
- package/src/services/plan/plan-builder.service.ts +76 -0
- package/src/services/plan/plan-checkpoint.service.ts +103 -0
- package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
- package/src/services/plan/plan-completion-side-effects.ts +175 -0
- package/src/services/plan/plan-coordination.service.ts +181 -0
- package/src/services/plan/plan-cycle.service.ts +398 -0
- package/src/services/plan/plan-deadline.service.ts +547 -0
- package/src/services/plan/plan-event-delivery.service.ts +261 -0
- package/src/services/plan/plan-executor-context.ts +35 -0
- package/src/services/plan/plan-executor-graph.ts +475 -0
- package/src/services/plan/plan-executor-helpers.ts +322 -0
- package/src/services/plan/plan-executor-persistence.ts +209 -0
- package/src/services/plan/plan-executor.service.ts +1654 -0
- package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
- package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
- package/src/services/plan/plan-run-serialization.ts +15 -0
- package/src/services/plan/plan-run.service.ts +644 -0
- package/src/services/plan/plan-scheduler.service.ts +385 -0
- package/src/services/plan/plan-template.service.ts +224 -0
- package/src/services/plan/plan-transaction-events.ts +33 -0
- package/src/services/plan/plan-validator.service.ts +907 -0
- package/src/services/plan/plan-workspace.service.ts +125 -0
- package/src/services/plugin-executor.service.ts +97 -68
- package/src/services/quality-metrics.service.ts +112 -94
- package/src/services/queue-job.service.ts +296 -230
- package/src/services/recent-activity-title.service.ts +65 -36
- package/src/services/recent-activity.service.ts +274 -259
- package/src/services/skill-resolver.service.ts +38 -12
- package/src/services/social-chat-history.service.ts +176 -125
- package/src/services/system-executor.service.ts +91 -61
- package/src/services/thread/thread-active-run.ts +203 -0
- package/src/services/thread/thread-bootstrap.ts +369 -0
- package/src/services/thread/thread-listing.ts +198 -0
- package/src/services/thread/thread-memory-block.ts +117 -0
- package/src/services/thread/thread-message.service.ts +363 -0
- package/src/services/thread/thread-record-store.ts +155 -0
- package/src/services/thread/thread-title.service.ts +74 -0
- package/src/services/thread/thread-turn-execution.ts +280 -0
- package/src/services/thread/thread-turn-message-context.ts +73 -0
- package/src/services/thread/thread-turn-preparation.service.ts +1146 -0
- package/src/services/thread/thread-turn-streaming.ts +402 -0
- package/src/services/thread/thread-turn-tracing.ts +35 -0
- package/src/services/thread/thread-turn.ts +343 -0
- package/src/services/thread/thread.service.ts +335 -0
- package/src/services/user.service.ts +82 -32
- package/src/services/write-intent-validator.service.ts +63 -51
- package/src/storage/attachment-parser.ts +69 -27
- package/src/storage/attachment-storage.service.ts +331 -275
- package/src/storage/generated-document-storage.service.ts +66 -34
- package/src/system-agents/agent-result.ts +3 -1
- package/src/system-agents/context-compaction.agent.ts +2 -2
- package/src/system-agents/delegated-agent-factory.ts +159 -90
- package/src/system-agents/memory-reranker.agent.ts +2 -2
- package/src/system-agents/memory.agent.ts +2 -2
- package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -2
- package/src/system-agents/regular-chat-memory-digest.agent.ts +2 -2
- package/src/system-agents/skill-extractor.agent.ts +2 -2
- package/src/system-agents/skill-manager.agent.ts +2 -2
- package/src/system-agents/thread-router.agent.ts +157 -113
- package/src/system-agents/title-generator.agent.ts +2 -2
- package/src/tools/execution-plan.tool.ts +220 -161
- package/src/tools/fetch-webpage.tool.ts +21 -17
- package/src/tools/firecrawl-client.ts +16 -6
- package/src/tools/index.ts +1 -0
- package/src/tools/memory-block.tool.ts +14 -6
- package/src/tools/plan-approval.tool.ts +49 -47
- package/src/tools/read-file-parts.tool.ts +44 -33
- package/src/tools/remember-memory.tool.ts +65 -45
- package/src/tools/search-web.tool.ts +26 -22
- package/src/tools/search.tool.ts +41 -29
- package/src/tools/team-think.tool.ts +124 -83
- package/src/tools/user-questions.tool.ts +4 -3
- package/src/tools/web-tool-shared.ts +6 -0
- package/src/utils/async.ts +17 -23
- package/src/utils/crypto.ts +21 -0
- package/src/utils/date-time.ts +40 -1
- package/src/utils/errors.ts +95 -16
- package/src/utils/hono-error-handler.ts +24 -39
- package/src/utils/index.ts +2 -1
- package/src/utils/null-proto-record.ts +41 -0
- package/src/utils/sse-keepalive.ts +124 -21
- package/src/workers/bootstrap.ts +186 -51
- package/src/workers/memory-consolidation.worker.ts +325 -237
- package/src/workers/organization-learning.worker.ts +50 -16
- package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
- package/src/workers/regular-chat-memory-digest.runner.ts +175 -114
- package/src/workers/skill-extraction.runner.ts +176 -93
- package/src/workers/utils/file-section-chunker.ts +8 -10
- package/src/workers/utils/repo-structure-extractor.ts +349 -260
- package/src/workers/utils/repomix-file-sections.ts +2 -2
- package/src/workers/utils/thread-message-query.ts +97 -38
- package/src/workers/worker-utils.ts +56 -31
- package/src/config/debug-logger.ts +0 -47
- package/src/redis/connection-accessor.ts +0 -26
- package/src/runtime/context-compaction-runtime.ts +0 -87
- package/src/runtime/social-chat-agent-runner.ts +0 -118
- package/src/runtime/social-chat.ts +0 -516
- package/src/runtime/team-consultation-orchestrator.ts +0 -272
- package/src/services/adaptive-playbook.service.ts +0 -152
- package/src/services/artifact-provenance.service.ts +0 -172
- package/src/services/chat-attachments.service.ts +0 -17
- package/src/services/context-compaction-runtime.singleton.ts +0 -13
- package/src/services/execution-plan.service.ts +0 -1118
- package/src/services/memory.service.ts +0 -914
- package/src/services/plan-agent-heartbeat.service.ts +0 -136
- package/src/services/plan-agent-query.service.ts +0 -267
- package/src/services/plan-approval.service.ts +0 -83
- package/src/services/plan-artifact.service.ts +0 -50
- package/src/services/plan-builder.service.ts +0 -67
- package/src/services/plan-checkpoint.service.ts +0 -81
- package/src/services/plan-completion-side-effects.ts +0 -80
- package/src/services/plan-coordination.service.ts +0 -157
- package/src/services/plan-cycle.service.ts +0 -284
- package/src/services/plan-deadline.service.ts +0 -430
- package/src/services/plan-event-delivery.service.ts +0 -166
- package/src/services/plan-executor.service.ts +0 -1950
- package/src/services/plan-run.service.ts +0 -515
- package/src/services/plan-scheduler.service.ts +0 -240
- package/src/services/plan-template.service.ts +0 -177
- package/src/services/plan-validator.service.ts +0 -818
- package/src/services/plan-workspace.service.ts +0 -83
- package/src/services/rerank.service.ts +0 -156
- package/src/services/thread-message.service.ts +0 -275
- package/src/services/thread-plan-registry.service.ts +0 -22
- package/src/services/thread-title.service.ts +0 -39
- package/src/services/thread-turn-preparation.service.ts +0 -1147
- package/src/services/thread-turn.ts +0 -172
- package/src/services/thread.service.ts +0 -869
- package/src/utils/env.ts +0 -8
- /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
- /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
- /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
- /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
- /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
- /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
- /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
- /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
package/src/create-runtime.ts
CHANGED
|
@@ -1,121 +1,152 @@
|
|
|
1
1
|
import type { ChatMessage } from '@lota-sdk/shared'
|
|
2
|
+
import type { Context } from 'effect'
|
|
3
|
+
import { Effect, Layer, ManagedRuntime } from 'effect'
|
|
4
|
+
import { DevTools } from 'effect/unstable/devtools'
|
|
5
|
+
import { FetchHttpClient } from 'effect/unstable/http'
|
|
6
|
+
import { Otlp } from 'effect/unstable/observability'
|
|
7
|
+
import type { Subscriber } from 'resumable-stream/ioredis'
|
|
2
8
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { configureLotaLogger } from './config/logger'
|
|
6
|
-
import { configureThreads } from './config/thread-defaults'
|
|
9
|
+
import { AiGatewayLive } from './ai-gateway/ai-gateway'
|
|
10
|
+
import { EmbeddingCacheLive } from './ai/embedding-cache'
|
|
7
11
|
import { ensureRecordId } from './db/record-id'
|
|
8
12
|
import { computeSchemaFingerprint } from './db/schema-fingerprint'
|
|
9
|
-
import { LOTA_SDK_DATABASE_NAME } from './db/sdk-database'
|
|
10
13
|
import type { SurrealDBService } from './db/service'
|
|
11
|
-
import {
|
|
12
|
-
import { publishDatabaseBootstrap } from './db/startup'
|
|
14
|
+
import { publishDatabaseBootstrapEffect } from './db/startup'
|
|
13
15
|
import { TABLES } from './db/tables'
|
|
16
|
+
import {
|
|
17
|
+
buildInfrastructureLayer,
|
|
18
|
+
clearLotaSdkRuntime,
|
|
19
|
+
DatabaseServiceTag as EffectDatabaseService,
|
|
20
|
+
RedisServiceTag as EffectRedisService,
|
|
21
|
+
runPromise,
|
|
22
|
+
setLotaSdkRuntime,
|
|
23
|
+
} from './effect'
|
|
24
|
+
import type { AwaitableService, AwaitableValue } from './effect/awaitable-effect'
|
|
25
|
+
import { toAwaitableService } from './effect/awaitable-effect'
|
|
26
|
+
import { BadRequestError, ConfigurationError, NotFoundError, ServiceError } from './effect/errors'
|
|
27
|
+
import { effectTryPromise } from './effect/helpers'
|
|
14
28
|
import type { RedisConnectionManager } from './redis/connection'
|
|
15
|
-
import {
|
|
16
|
-
import { setRedisConnectionManager } from './redis/index'
|
|
17
|
-
import { closeSharedSubscriber } from './redis/stream-context'
|
|
29
|
+
import { SharedThreadStreamSubscriberLive, SharedThreadStreamSubscriberTag } from './redis/stream-context'
|
|
18
30
|
import type { isApprovalContinuationRequest } from './runtime/approval-continuation'
|
|
19
31
|
import { routeThreadChatMessages } from './runtime/chat-request-routing'
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
import {
|
|
32
|
+
import { CompactionCoordinationLive } from './runtime/chat-run-orchestration'
|
|
33
|
+
import { HelperModelLive } from './runtime/helper-model'
|
|
34
|
+
import type { LotaPlugin, PluginLifecycleServices, SystemNodeExecutor } from './runtime/plugin-types'
|
|
35
|
+
import { LOTA_RUNTIME_ENV_KEYS, loadLotaRuntimeConfigFromEnv, parseLotaRuntimeConfig } from './runtime/runtime-config'
|
|
23
36
|
import type { LotaRuntimeConfig, ResolvedLotaRuntimeConfig } from './runtime/runtime-config'
|
|
24
|
-
import { configureRuntimeExtensions } from './runtime/runtime-extensions'
|
|
25
37
|
import type { LotaRuntimeWorkers } from './runtime/runtime-worker-registry'
|
|
26
38
|
import { buildRuntimeWorkerRegistry } from './runtime/runtime-worker-registry'
|
|
27
|
-
import type { LotaRuntimeSocialChat } from './runtime/social-chat'
|
|
28
|
-
import { createSocialChatRuntime } from './runtime/social-chat'
|
|
29
|
-
|
|
30
|
-
import {
|
|
31
|
-
import
|
|
32
|
-
import {
|
|
33
|
-
import
|
|
34
|
-
import {
|
|
35
|
-
import
|
|
36
|
-
import {
|
|
37
|
-
import
|
|
38
|
-
import {
|
|
39
|
-
import
|
|
40
|
-
import {
|
|
41
|
-
import
|
|
42
|
-
import {
|
|
43
|
-
import
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import
|
|
47
|
-
import {
|
|
48
|
-
import
|
|
49
|
-
import {
|
|
50
|
-
import
|
|
51
|
-
import {
|
|
52
|
-
import type { planAgentQueryService } from './services/plan-agent-query.service'
|
|
53
|
-
import { planAgentQueryService as planAgentQueryServiceSingleton } from './services/plan-agent-query.service'
|
|
54
|
-
import type { planCoordinationService } from './services/plan-coordination.service'
|
|
55
|
-
import { planCoordinationService as planCoordinationServiceSingleton } from './services/plan-coordination.service'
|
|
56
|
-
import type { planCycleService } from './services/plan-cycle.service'
|
|
57
|
-
import { planCycleService as planCycleServiceSingleton } from './services/plan-cycle.service'
|
|
58
|
-
import type { planSchedulerService } from './services/plan-scheduler.service'
|
|
59
|
-
import { planSchedulerService as planSchedulerServiceSingleton } from './services/plan-scheduler.service'
|
|
60
|
-
import type { planTemplateService } from './services/plan-template.service'
|
|
61
|
-
import { planTemplateService as planTemplateServiceSingleton } from './services/plan-template.service'
|
|
62
|
-
import type { recentActivityTitleService } from './services/recent-activity-title.service'
|
|
63
|
-
import { recentActivityTitleService as recentActivityTitleServiceSingleton } from './services/recent-activity-title.service'
|
|
64
|
-
import type { recentActivityService } from './services/recent-activity.service'
|
|
65
|
-
import { recentActivityService as recentActivityServiceSingleton } from './services/recent-activity.service'
|
|
66
|
-
import type { rerankService } from './services/rerank.service'
|
|
67
|
-
import { rerankService as rerankServiceSingleton } from './services/rerank.service'
|
|
39
|
+
import type { LotaRuntimeSocialChat } from './runtime/social-chat/social-chat'
|
|
40
|
+
import { createSocialChatRuntime } from './runtime/social-chat/social-chat'
|
|
41
|
+
// ── Service Layer & Tag imports ────────────────────────────────────────
|
|
42
|
+
import { AgentActivityServiceLive, AgentActivityServiceTag } from './services/agent-activity.service'
|
|
43
|
+
import { AgentExecutorServiceLive } from './services/agent-executor.service'
|
|
44
|
+
import { ArtifactServiceLive, ArtifactServiceTag } from './services/artifact.service'
|
|
45
|
+
import { AttachmentServiceLive, AttachmentServiceTag } from './services/attachment.service'
|
|
46
|
+
import { AutonomousJobServiceLive, AutonomousJobServiceTag } from './services/autonomous-job.service'
|
|
47
|
+
import { ChatRunRegistryLive } from './services/chat-run-registry.service'
|
|
48
|
+
import { ContextCompactionServiceLive, ContextCompactionServiceTag } from './services/context-compaction.service'
|
|
49
|
+
import { DocumentChunkServiceLive, DocumentChunkServiceTag } from './services/document-chunk.service'
|
|
50
|
+
import { ExecutionPlanServiceLive, ExecutionPlanServiceTag } from './services/execution-plan/execution-plan.service'
|
|
51
|
+
import { FeedbackLoopServiceLive } from './services/feedback-loop.service'
|
|
52
|
+
import { GlobalOrchestratorServiceLive } from './services/global-orchestrator.service'
|
|
53
|
+
import { InstitutionalMemoryServiceLive } from './services/institutional-memory.service'
|
|
54
|
+
import { LearnedSkillServiceLive, LearnedSkillServiceTag } from './services/learned-skill.service'
|
|
55
|
+
import { MemoryServiceLive, MemoryServiceTag } from './services/memory/memory.service'
|
|
56
|
+
import { RerankServiceLive, RerankServiceTag } from './services/memory/rerank.service'
|
|
57
|
+
import { MonitoringWindowServiceLive } from './services/monitoring-window.service'
|
|
58
|
+
import { MutatingApprovalServiceLive, MutatingApprovalServiceTag } from './services/mutating-approval.service'
|
|
59
|
+
import { NodeWorkspaceServiceLive } from './services/node-workspace.service'
|
|
60
|
+
import { NotificationServiceLive } from './services/notification.service'
|
|
61
|
+
import { OrganizationMemberServiceLive, OrganizationMemberServiceTag } from './services/organization-member.service'
|
|
62
|
+
import { OrganizationServiceLive, OrganizationServiceTag } from './services/organization.service'
|
|
63
|
+
import { OwnershipDispatcherServiceLive } from './services/ownership-dispatcher.service'
|
|
68
64
|
import {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} from './services/
|
|
72
|
-
import {
|
|
73
|
-
import
|
|
74
|
-
import {
|
|
75
|
-
import
|
|
76
|
-
import {
|
|
65
|
+
PlanAgentHeartbeatServiceLive,
|
|
66
|
+
PlanAgentHeartbeatServiceTag,
|
|
67
|
+
} from './services/plan/plan-agent-heartbeat.service'
|
|
68
|
+
import { PlanAgentQueryServiceLive, PlanAgentQueryServiceTag } from './services/plan/plan-agent-query.service'
|
|
69
|
+
import { PlanApprovalServiceLive } from './services/plan/plan-approval.service'
|
|
70
|
+
import { PlanArtifactServiceLive } from './services/plan/plan-artifact.service'
|
|
71
|
+
import { PlanBuilderServiceLive } from './services/plan/plan-builder.service'
|
|
72
|
+
import { PlanCheckpointServiceLive } from './services/plan/plan-checkpoint.service'
|
|
73
|
+
import { PlanCompilerServiceLive } from './services/plan/plan-compiler.service'
|
|
74
|
+
import { PlanCoordinationServiceLive, PlanCoordinationServiceTag } from './services/plan/plan-coordination.service'
|
|
75
|
+
import { PlanCycleServiceLive, PlanCycleServiceTag } from './services/plan/plan-cycle.service'
|
|
76
|
+
import { PlanDeadlineServiceLive, PlanDeadlineServiceTag } from './services/plan/plan-deadline.service'
|
|
77
|
+
import { PlanEventDeliveryServiceLive } from './services/plan/plan-event-delivery.service'
|
|
78
|
+
import { PlanExecutorServiceLive, PlanExecutorServiceTag } from './services/plan/plan-executor.service'
|
|
79
|
+
import { PlanRunServiceLive, PlanRunServiceTag } from './services/plan/plan-run.service'
|
|
80
|
+
import { PlanSchedulerServiceLive, PlanSchedulerServiceTag } from './services/plan/plan-scheduler.service'
|
|
81
|
+
import { PlanTemplateServiceLive, PlanTemplateServiceTag } from './services/plan/plan-template.service'
|
|
82
|
+
import { PlanValidatorServiceLive } from './services/plan/plan-validator.service'
|
|
83
|
+
import { PlanWorkspaceServiceLive } from './services/plan/plan-workspace.service'
|
|
84
|
+
import { PluginExecutorServiceLive } from './services/plugin-executor.service'
|
|
85
|
+
import { QualityMetricsServiceLive } from './services/quality-metrics.service'
|
|
86
|
+
import { QueueJobServiceLive } from './services/queue-job.service'
|
|
87
|
+
import { RecentActivityTitleServiceLive, RecentActivityTitleServiceTag } from './services/recent-activity-title.service'
|
|
88
|
+
import { RecentActivityServiceLive, RecentActivityServiceTag } from './services/recent-activity.service'
|
|
89
|
+
import { SkillResolverServiceLive } from './services/skill-resolver.service'
|
|
90
|
+
import type { makeSocialChatHistoryService } from './services/social-chat-history.service'
|
|
91
|
+
import { SocialChatHistoryServiceLive, SocialChatHistoryServiceTag } from './services/social-chat-history.service'
|
|
92
|
+
import { getBuiltInSystemExecutors, SystemExecutorServiceLive } from './services/system-executor.service'
|
|
93
|
+
import { ThreadMessageServiceLive, ThreadMessageServiceTag } from './services/thread/thread-message.service'
|
|
94
|
+
import { ThreadTitleServiceLive, ThreadTitleServiceTag } from './services/thread/thread-title.service'
|
|
77
95
|
import type {
|
|
78
96
|
createThreadApprovalContinuationStream,
|
|
79
97
|
createThreadNativeToolApprovalStream,
|
|
80
98
|
createThreadTurnStream,
|
|
81
99
|
runThreadTurnInBackground,
|
|
82
100
|
triggerPlanNodeTurn,
|
|
83
|
-
} from './services/thread-turn'
|
|
101
|
+
} from './services/thread/thread-turn'
|
|
102
|
+
import {
|
|
103
|
+
isApprovalContinuationRequest as isApprovalContinuationRequestFn,
|
|
104
|
+
ThreadTurnServiceLive,
|
|
105
|
+
ThreadTurnServiceTag,
|
|
106
|
+
} from './services/thread/thread-turn'
|
|
107
|
+
import { ThreadTurnPreparationServiceLive } from './services/thread/thread-turn-preparation.service'
|
|
108
|
+
import { ThreadServiceLive, ThreadServiceTag } from './services/thread/thread.service'
|
|
109
|
+
import { UserServiceLive, UserServiceTag } from './services/user.service'
|
|
110
|
+
import { WriteIntentValidatorServiceLive } from './services/write-intent-validator.service'
|
|
111
|
+
import { AttachmentStorageServiceLive } from './storage/attachment-storage.service'
|
|
84
112
|
import {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
import { generatedDocumentStorageService as generatedDocumentStorageServiceSingleton } from './storage/generated-document-storage.service'
|
|
113
|
+
GeneratedDocumentStorageServiceLive,
|
|
114
|
+
GeneratedDocumentStorageServiceTag,
|
|
115
|
+
} from './storage/generated-document-storage.service'
|
|
116
|
+
import { FirecrawlLive } from './tools/firecrawl-client'
|
|
117
|
+
|
|
118
|
+
// ── Type helpers ────────────────────────────────────────────────────────
|
|
119
|
+
type Svc<T extends { readonly Service: unknown }> = T['Service']
|
|
120
|
+
type HostSvc<T extends { readonly Service: object }> = AwaitableService<T['Service']>
|
|
121
|
+
type AwaitableThreadService = HostSvc<typeof ThreadServiceTag> &
|
|
122
|
+
Pick<Svc<typeof ThreadServiceTag>, 'withActiveRunLease'>
|
|
123
|
+
type AwaitableDocumentChunkService = HostSvc<typeof DocumentChunkServiceTag> &
|
|
124
|
+
Pick<Svc<typeof DocumentChunkServiceTag>, 'syncVersionedChunks'>
|
|
98
125
|
|
|
99
126
|
type ArchiveSdkThread = (
|
|
100
|
-
threadId: Parameters<typeof
|
|
127
|
+
threadId: Parameters<Svc<typeof ThreadServiceTag>['updateStatus']>[0],
|
|
101
128
|
status?: 'archived',
|
|
102
|
-
) => ReturnType<typeof
|
|
129
|
+
) => ReturnType<Svc<typeof ThreadServiceTag>['updateStatus']>
|
|
103
130
|
|
|
104
131
|
type UnarchiveSdkThread = (
|
|
105
|
-
threadId: Parameters<typeof
|
|
132
|
+
threadId: Parameters<Svc<typeof ThreadServiceTag>['updateStatus']>[0],
|
|
106
133
|
status?: 'active',
|
|
107
|
-
) => ReturnType<typeof
|
|
134
|
+
) => ReturnType<Svc<typeof ThreadServiceTag>['updateStatus']>
|
|
108
135
|
|
|
109
136
|
let activeRuntimeToken: symbol | null = null
|
|
110
137
|
|
|
111
|
-
function claimRuntimeToken(): symbol {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
138
|
+
function claimRuntimeToken(): Effect.Effect<symbol, ConfigurationError> {
|
|
139
|
+
return Effect.gen(function* () {
|
|
140
|
+
if (activeRuntimeToken) {
|
|
141
|
+
return yield* new ConfigurationError({
|
|
142
|
+
message: 'createLotaRuntime() is process-scoped. Disconnect the active runtime before creating another one.',
|
|
143
|
+
})
|
|
144
|
+
}
|
|
115
145
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
146
|
+
const token = Symbol('lota-runtime')
|
|
147
|
+
activeRuntimeToken = token
|
|
148
|
+
return token
|
|
149
|
+
})
|
|
119
150
|
}
|
|
120
151
|
|
|
121
152
|
function releaseRuntimeToken(token: symbol) {
|
|
@@ -124,36 +155,69 @@ function releaseRuntimeToken(token: symbol) {
|
|
|
124
155
|
}
|
|
125
156
|
}
|
|
126
157
|
|
|
158
|
+
function buildObservabilityLayer(runtimeConfig: ResolvedLotaRuntimeConfig): Layer.Layer<never> {
|
|
159
|
+
let layer = Layer.empty
|
|
160
|
+
const observability = runtimeConfig.observability
|
|
161
|
+
|
|
162
|
+
if (observability.otlpBaseUrl) {
|
|
163
|
+
layer = Layer.merge(
|
|
164
|
+
layer,
|
|
165
|
+
Otlp.layerJson({
|
|
166
|
+
baseUrl: observability.otlpBaseUrl,
|
|
167
|
+
resource: {
|
|
168
|
+
serviceName: observability.serviceName,
|
|
169
|
+
...(observability.serviceVersion ? { serviceVersion: observability.serviceVersion } : {}),
|
|
170
|
+
},
|
|
171
|
+
...(observability.otlpHeaders ? { headers: observability.otlpHeaders } : {}),
|
|
172
|
+
}).pipe(Layer.provide(FetchHttpClient.layer)),
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (observability.devToolsUrl && Bun.env.NODE_ENV !== 'production') {
|
|
177
|
+
layer = Layer.merge(layer, DevTools.layer(observability.devToolsUrl))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return layer
|
|
181
|
+
}
|
|
182
|
+
|
|
127
183
|
export interface LotaRuntime {
|
|
184
|
+
/** Run an Effect as a Promise through the SDK runtime (carries OTLP context). */
|
|
185
|
+
runPromise: <A, E>(effect: Effect.Effect<A, E>, options?: { readonly signal?: AbortSignal }) => Promise<A>
|
|
186
|
+
/** Run an Effect synchronously through the SDK runtime. */
|
|
187
|
+
runSync: <A, E>(effect: Effect.Effect<A, E>) => A
|
|
128
188
|
services: {
|
|
129
189
|
database: SurrealDBService
|
|
130
190
|
redis: RedisConnectionManager
|
|
131
191
|
closeRedisConnection: () => Promise<void>
|
|
132
|
-
agentActivityService: typeof
|
|
133
|
-
artifactService: typeof
|
|
134
|
-
attachmentService: typeof
|
|
135
|
-
autonomousJobService: typeof
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
192
|
+
agentActivityService: HostSvc<typeof AgentActivityServiceTag>
|
|
193
|
+
artifactService: HostSvc<typeof ArtifactServiceTag>
|
|
194
|
+
attachmentService: HostSvc<typeof AttachmentServiceTag>
|
|
195
|
+
autonomousJobService: HostSvc<typeof AutonomousJobServiceTag>
|
|
196
|
+
contextCompactionService: HostSvc<typeof ContextCompactionServiceTag>
|
|
197
|
+
documentChunkService: AwaitableDocumentChunkService
|
|
198
|
+
generatedDocumentStorageService: HostSvc<typeof GeneratedDocumentStorageServiceTag>
|
|
199
|
+
memoryService: HostSvc<typeof MemoryServiceTag>
|
|
200
|
+
rerankService: HostSvc<typeof RerankServiceTag>
|
|
201
|
+
verifyMutatingApproval: HostSvc<typeof MutatingApprovalServiceTag>
|
|
202
|
+
organizationService: HostSvc<typeof OrganizationServiceTag>
|
|
203
|
+
organizationMemberService: HostSvc<typeof OrganizationMemberServiceTag>
|
|
204
|
+
userService: HostSvc<typeof UserServiceTag>
|
|
205
|
+
recentActivityService: HostSvc<typeof RecentActivityServiceTag>
|
|
206
|
+
recentActivityTitleService: HostSvc<typeof RecentActivityTitleServiceTag>
|
|
207
|
+
socialChatHistoryService: ReturnType<typeof makeSocialChatHistoryService>
|
|
208
|
+
executionPlanService: HostSvc<typeof ExecutionPlanServiceTag>
|
|
209
|
+
planDeadlineService: HostSvc<typeof PlanDeadlineServiceTag>
|
|
210
|
+
planExecutorService: HostSvc<typeof PlanExecutorServiceTag>
|
|
211
|
+
planRunService: HostSvc<typeof PlanRunServiceTag>
|
|
212
|
+
planTemplateService: HostSvc<typeof PlanTemplateServiceTag>
|
|
213
|
+
planCoordinationService: HostSvc<typeof PlanCoordinationServiceTag>
|
|
214
|
+
planSchedulerService: HostSvc<typeof PlanSchedulerServiceTag>
|
|
215
|
+
planAgentHeartbeatService: HostSvc<typeof PlanAgentHeartbeatServiceTag>
|
|
216
|
+
planAgentQueryService: HostSvc<typeof PlanAgentQueryServiceTag>
|
|
217
|
+
planCycleService: HostSvc<typeof PlanCycleServiceTag>
|
|
218
|
+
threadMessageService: HostSvc<typeof ThreadMessageServiceTag>
|
|
219
|
+
threadService: AwaitableThreadService
|
|
220
|
+
threadTitleService: HostSvc<typeof ThreadTitleServiceTag>
|
|
157
221
|
createThreadApprovalContinuationStream: typeof createThreadApprovalContinuationStream
|
|
158
222
|
createThreadNativeToolApprovalStream: typeof createThreadNativeToolApprovalStream
|
|
159
223
|
createThreadTurnStream: typeof createThreadTurnStream
|
|
@@ -163,37 +227,37 @@ export interface LotaRuntime {
|
|
|
163
227
|
}
|
|
164
228
|
lota: {
|
|
165
229
|
organizations: {
|
|
166
|
-
create: typeof
|
|
167
|
-
upsert: typeof
|
|
168
|
-
get: typeof
|
|
169
|
-
list: typeof
|
|
170
|
-
update: typeof
|
|
171
|
-
delete: typeof
|
|
230
|
+
create: AwaitableValue<Svc<typeof OrganizationServiceTag>['createOrganization']>
|
|
231
|
+
upsert: AwaitableValue<Svc<typeof OrganizationServiceTag>['upsertOrganization']>
|
|
232
|
+
get: AwaitableValue<Svc<typeof OrganizationServiceTag>['getOrganization']>
|
|
233
|
+
list: AwaitableValue<Svc<typeof OrganizationServiceTag>['listOrganizations']>
|
|
234
|
+
update: AwaitableValue<Svc<typeof OrganizationServiceTag>['updateOrganization']>
|
|
235
|
+
delete: AwaitableValue<Svc<typeof OrganizationServiceTag>['deleteOrganization']>
|
|
172
236
|
}
|
|
173
237
|
users: {
|
|
174
|
-
upsert: typeof
|
|
175
|
-
get: typeof
|
|
176
|
-
list: typeof
|
|
177
|
-
update: typeof
|
|
178
|
-
delete: typeof
|
|
238
|
+
upsert: AwaitableValue<Svc<typeof UserServiceTag>['upsertUser']>
|
|
239
|
+
get: AwaitableValue<Svc<typeof UserServiceTag>['getUser']>
|
|
240
|
+
list: AwaitableValue<Svc<typeof UserServiceTag>['listUsers']>
|
|
241
|
+
update: AwaitableValue<Svc<typeof UserServiceTag>['updateUser']>
|
|
242
|
+
delete: AwaitableValue<Svc<typeof UserServiceTag>['deleteUser']>
|
|
179
243
|
}
|
|
180
244
|
memberships: {
|
|
181
|
-
add: typeof
|
|
182
|
-
listForOrganization: typeof
|
|
183
|
-
listForUser: typeof
|
|
184
|
-
remove: typeof
|
|
185
|
-
isMember: typeof
|
|
245
|
+
add: AwaitableValue<Svc<typeof OrganizationMemberServiceTag>['addMembership']>
|
|
246
|
+
listForOrganization: AwaitableValue<Svc<typeof OrganizationMemberServiceTag>['listMembershipsForOrganization']>
|
|
247
|
+
listForUser: AwaitableValue<Svc<typeof OrganizationMemberServiceTag>['listMembershipsForUser']>
|
|
248
|
+
remove: AwaitableValue<Svc<typeof OrganizationMemberServiceTag>['removeMembership']>
|
|
249
|
+
isMember: AwaitableValue<Svc<typeof OrganizationMemberServiceTag>['isMember']>
|
|
186
250
|
}
|
|
187
251
|
threads: {
|
|
188
|
-
create: typeof
|
|
189
|
-
list: typeof
|
|
190
|
-
get: typeof
|
|
191
|
-
update: typeof
|
|
192
|
-
archive: ArchiveSdkThread
|
|
193
|
-
unarchive: UnarchiveSdkThread
|
|
194
|
-
delete: typeof
|
|
195
|
-
stop: typeof
|
|
196
|
-
listMessages: typeof
|
|
252
|
+
create: AwaitableValue<Svc<typeof ThreadServiceTag>['createThread']>
|
|
253
|
+
list: AwaitableValue<Svc<typeof ThreadServiceTag>['listThreads']>
|
|
254
|
+
get: AwaitableValue<Svc<typeof ThreadServiceTag>['getThread']>
|
|
255
|
+
update: AwaitableValue<Svc<typeof ThreadServiceTag>['updateTitle']>
|
|
256
|
+
archive: AwaitableValue<ArchiveSdkThread>
|
|
257
|
+
unarchive: AwaitableValue<UnarchiveSdkThread>
|
|
258
|
+
delete: AwaitableValue<Svc<typeof ThreadServiceTag>['deleteThread']>
|
|
259
|
+
stop: AwaitableValue<Svc<typeof ThreadServiceTag>['stopActiveRun']>
|
|
260
|
+
listMessages: AwaitableValue<Svc<typeof ThreadMessageServiceTag>['listMessageHistoryPage']>
|
|
197
261
|
getMessage: (params: { threadId: string; messageId: string }) => Promise<ChatMessage>
|
|
198
262
|
sendMessage: (params: {
|
|
199
263
|
threadId: string
|
|
@@ -209,11 +273,12 @@ export interface LotaRuntime {
|
|
|
209
273
|
userName: string
|
|
210
274
|
messages: Parameters<typeof routeThreadChatMessages>[0]
|
|
211
275
|
}) => Promise<Awaited<ReturnType<typeof createThreadApprovalContinuationStream>>>
|
|
212
|
-
uploadAttachment: typeof
|
|
276
|
+
uploadAttachment: AwaitableValue<Svc<typeof AttachmentServiceTag>['uploadThreadAttachment']>
|
|
213
277
|
}
|
|
214
278
|
}
|
|
215
279
|
redis: {
|
|
216
280
|
manager: RedisConnectionManager
|
|
281
|
+
subscriber: Subscriber
|
|
217
282
|
getConnection: () => ReturnType<RedisConnectionManager['getConnection']>
|
|
218
283
|
getConnectionForBullMQ: () => ReturnType<RedisConnectionManager['getConnectionForBullMQ']>
|
|
219
284
|
closeConnection: () => Promise<void>
|
|
@@ -230,253 +295,483 @@ export interface LotaRuntime {
|
|
|
230
295
|
disconnect(): Promise<void>
|
|
231
296
|
}
|
|
232
297
|
|
|
233
|
-
export
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
|
|
265
|
-
: runtimeConfig.agents.displayNames
|
|
266
|
-
|
|
267
|
-
configureAgents({
|
|
268
|
-
roster: runtimeConfig.agents.roster,
|
|
269
|
-
leadAgentId: runtimeConfig.agents.leadAgentId,
|
|
270
|
-
displayNames: agentDisplayNames,
|
|
271
|
-
shortDisplayNames: runtimeConfig.agents.shortDisplayNames,
|
|
272
|
-
descriptions: runtimeConfig.agents.descriptions,
|
|
273
|
-
routerModelId: runtimeConfig.agents.routerModelId,
|
|
274
|
-
teamConsultParticipants: runtimeConfig.agents.teamConsultParticipants,
|
|
275
|
-
getCoreThreadProfile: runtimeConfig.agents.getCoreThreadProfile,
|
|
276
|
-
})
|
|
277
|
-
configureAgentFactory({
|
|
278
|
-
createAgent: runtimeConfig.agents.createAgent,
|
|
279
|
-
buildAgentTools: runtimeConfig.agents.buildAgentTools,
|
|
280
|
-
getAgentRuntimeConfig: runtimeConfig.agents.getAgentRuntimeConfig,
|
|
281
|
-
pluginRuntime: runtimeConfig.pluginRuntime,
|
|
282
|
-
})
|
|
283
|
-
configureThreads({ agentRoster: runtimeConfig.agents.roster, config: runtimeConfig.threads })
|
|
284
|
-
configureNotificationService(runtimeConfig.notificationService ?? null)
|
|
285
|
-
configureRuntimeExtensions({
|
|
286
|
-
adapters: runtimeConfig.runtimeAdapters,
|
|
287
|
-
turnHooks: runtimeConfig.turnHooks,
|
|
288
|
-
toolProviders: (runtimeConfig.toolProviders ?? {}) as never,
|
|
289
|
-
extraWorkers: runtimeConfig.extraWorkers,
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
|
|
293
|
-
if (runtimeConfig.graphDesigner) {
|
|
294
|
-
configureGraphDesigner(runtimeConfig.graphDesigner)
|
|
295
|
-
}
|
|
298
|
+
export function createLotaRuntimeFromEnv(
|
|
299
|
+
config: Parameters<typeof loadLotaRuntimeConfigFromEnv>[0],
|
|
300
|
+
options?: Parameters<typeof loadLotaRuntimeConfigFromEnv>[1],
|
|
301
|
+
): Promise<LotaRuntime> {
|
|
302
|
+
return Effect.runPromise(loadLotaRuntimeConfigFromEnv(config, options)).then((resolvedConfig) =>
|
|
303
|
+
createLotaRuntime(resolvedConfig),
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
|
|
308
|
+
let runtimeToken: symbol | null = null
|
|
309
|
+
let effectRuntime: { dispose(): Promise<void> } | null = null
|
|
310
|
+
|
|
311
|
+
return Effect.runPromise(
|
|
312
|
+
Effect.gen(function* () {
|
|
313
|
+
runtimeToken = yield* claimRuntimeToken()
|
|
314
|
+
const resolvedConfig = parseLotaRuntimeConfig(config)
|
|
315
|
+
const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
|
|
316
|
+
const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
|
|
317
|
+
|
|
318
|
+
const socialChatAgentId = runtimeConfig.socialChat?.agentId?.trim() || 'socialChat'
|
|
319
|
+
const socialChatAgentDisplayName = runtimeConfig.socialChat?.agentDisplayName?.trim() || 'Lota'
|
|
320
|
+
if (runtimeConfig.socialChat && !runtimeConfig.agents.roster.includes(socialChatAgentId)) {
|
|
321
|
+
return yield* new ConfigurationError({
|
|
322
|
+
message: `socialChat.agentId must be present in agents.roster: ${socialChatAgentId}`,
|
|
323
|
+
key: 'socialChat.agentId',
|
|
324
|
+
})
|
|
325
|
+
}
|
|
326
|
+
const resolvedAgentDisplayNames = runtimeConfig.socialChat
|
|
327
|
+
? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
|
|
328
|
+
: runtimeConfig.agents.displayNames
|
|
296
329
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
users: {
|
|
322
|
-
upsert: userServiceSingleton.upsertUser.bind(userServiceSingleton),
|
|
323
|
-
get: userServiceSingleton.getUser.bind(userServiceSingleton),
|
|
324
|
-
list: userServiceSingleton.listUsers.bind(userServiceSingleton),
|
|
325
|
-
update: userServiceSingleton.updateUser.bind(userServiceSingleton),
|
|
326
|
-
delete: userServiceSingleton.deleteUser.bind(userServiceSingleton),
|
|
327
|
-
},
|
|
328
|
-
memberships: {
|
|
329
|
-
add: organizationMemberServiceSingleton.addMembership.bind(organizationMemberServiceSingleton),
|
|
330
|
-
listForOrganization: organizationMemberServiceSingleton.listMembershipsForOrganization.bind(
|
|
331
|
-
organizationMemberServiceSingleton,
|
|
330
|
+
// ── Infrastructure layers ───────────────────────────────────────────
|
|
331
|
+
const infrastructureLayer = buildInfrastructureLayer(runtimeConfig, {
|
|
332
|
+
resolvedAgentDisplayNames,
|
|
333
|
+
observabilityLayer: buildObservabilityLayer(runtimeConfig),
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
// ── Domain service layers ───────────────────────────────────────────
|
|
337
|
+
function provide<A, E, R extends RCtx, RCtx, E2>(
|
|
338
|
+
layer: Layer.Layer<A, E, R>,
|
|
339
|
+
ctx: Layer.Layer<RCtx, E2, never>,
|
|
340
|
+
): Layer.Layer<A, E | E2, never> {
|
|
341
|
+
return Layer.provideMerge(ctx)(layer)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const tier0 = provide(
|
|
345
|
+
Layer.mergeAll(
|
|
346
|
+
ChatRunRegistryLive,
|
|
347
|
+
CompactionCoordinationLive,
|
|
348
|
+
DocumentChunkServiceLive,
|
|
349
|
+
NodeWorkspaceServiceLive,
|
|
350
|
+
NotificationServiceLive,
|
|
351
|
+
PlanArtifactServiceLive,
|
|
352
|
+
PlanBuilderServiceLive,
|
|
353
|
+
WriteIntentValidatorServiceLive,
|
|
332
354
|
),
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
get: threadServiceSingleton.getThread.bind(threadServiceSingleton),
|
|
341
|
-
update: threadServiceSingleton.updateTitle.bind(threadServiceSingleton),
|
|
342
|
-
archive: async (threadId, status = 'archived') => await threadServiceSingleton.updateStatus(threadId, status),
|
|
343
|
-
unarchive: async (threadId, status = 'active') => await threadServiceSingleton.updateStatus(threadId, status),
|
|
344
|
-
delete: threadServiceSingleton.deleteThread.bind(threadServiceSingleton),
|
|
345
|
-
stop: threadServiceSingleton.stopActiveRun.bind(threadServiceSingleton),
|
|
346
|
-
listMessages: threadMessageServiceSingleton.listMessageHistoryPage.bind(threadMessageServiceSingleton),
|
|
347
|
-
getMessage: async ({ threadId, messageId }) => {
|
|
348
|
-
const messages = await threadMessageServiceSingleton.listMessages(ensureRecordId(threadId, TABLES.THREAD))
|
|
349
|
-
const message = messages.find((candidate) => candidate.id === messageId)
|
|
350
|
-
if (!message) {
|
|
351
|
-
throw new Error(`Thread message not found: ${messageId}`)
|
|
352
|
-
}
|
|
353
|
-
return message
|
|
354
|
-
},
|
|
355
|
-
sendMessage: async ({ threadId, organizationId, userId, userName, messages }) => {
|
|
356
|
-
const threadRef = ensureRecordId(threadId, TABLES.THREAD)
|
|
357
|
-
const thread = await threadServiceSingleton.getThread(threadRef)
|
|
358
|
-
const routed = routeThreadChatMessages(messages)
|
|
359
|
-
if (routed.kind !== 'turn') {
|
|
360
|
-
throw new Error(routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.')
|
|
361
|
-
}
|
|
355
|
+
infrastructureLayer,
|
|
356
|
+
)
|
|
357
|
+
const ctx0 = Layer.mergeAll(
|
|
358
|
+
infrastructureLayer,
|
|
359
|
+
provide(Layer.mergeAll(AiGatewayLive, EmbeddingCacheLive, FirecrawlLive, HelperModelLive), infrastructureLayer),
|
|
360
|
+
tier0,
|
|
361
|
+
)
|
|
362
362
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
363
|
+
const tier1 = provide(
|
|
364
|
+
Layer.mergeAll(
|
|
365
|
+
SharedThreadStreamSubscriberLive,
|
|
366
|
+
AgentExecutorServiceLive,
|
|
367
|
+
AttachmentStorageServiceLive,
|
|
368
|
+
GeneratedDocumentStorageServiceLive,
|
|
369
|
+
LearnedSkillServiceLive,
|
|
370
|
+
OrganizationServiceLive,
|
|
371
|
+
OrganizationMemberServiceLive,
|
|
372
|
+
PlanApprovalServiceLive,
|
|
373
|
+
PlanRunServiceLive,
|
|
374
|
+
PlanSchedulerServiceLive,
|
|
375
|
+
PlanWorkspaceServiceLive,
|
|
376
|
+
PluginExecutorServiceLive,
|
|
377
|
+
QualityMetricsServiceLive,
|
|
378
|
+
QueueJobServiceLive,
|
|
379
|
+
RecentActivityServiceLive,
|
|
380
|
+
RerankServiceLive,
|
|
381
|
+
SocialChatHistoryServiceLive,
|
|
382
|
+
SystemExecutorServiceLive,
|
|
383
|
+
ThreadMessageServiceLive,
|
|
384
|
+
UserServiceLive,
|
|
385
|
+
),
|
|
386
|
+
ctx0,
|
|
387
|
+
)
|
|
388
|
+
const ctx1 = Layer.mergeAll(ctx0, tier1)
|
|
381
389
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
390
|
+
const tier2 = provide(
|
|
391
|
+
Layer.mergeAll(
|
|
392
|
+
ArtifactServiceLive,
|
|
393
|
+
AttachmentServiceLive,
|
|
394
|
+
ContextCompactionServiceLive,
|
|
395
|
+
FeedbackLoopServiceLive,
|
|
396
|
+
InstitutionalMemoryServiceLive,
|
|
397
|
+
MemoryServiceLive,
|
|
398
|
+
MonitoringWindowServiceLive,
|
|
399
|
+
MutatingApprovalServiceLive,
|
|
400
|
+
PlanAgentQueryServiceLive,
|
|
401
|
+
PlanCheckpointServiceLive,
|
|
402
|
+
PlanCoordinationServiceLive,
|
|
403
|
+
PlanEventDeliveryServiceLive,
|
|
404
|
+
SkillResolverServiceLive,
|
|
405
|
+
RecentActivityTitleServiceLive,
|
|
406
|
+
),
|
|
407
|
+
ctx1,
|
|
408
|
+
)
|
|
409
|
+
const ctx2 = Layer.mergeAll(ctx1, tier2)
|
|
410
|
+
|
|
411
|
+
const tier3 = provide(Layer.mergeAll(PlanValidatorServiceLive, ThreadServiceLive), ctx2)
|
|
412
|
+
const ctx3 = Layer.mergeAll(ctx2, tier3)
|
|
413
|
+
|
|
414
|
+
const tier4 = provide(Layer.mergeAll(PlanCompilerServiceLive, ThreadTitleServiceLive), ctx3)
|
|
415
|
+
const ctx4 = Layer.mergeAll(ctx3, tier4)
|
|
416
|
+
|
|
417
|
+
const tier5 = provide(PlanExecutorServiceLive, ctx4)
|
|
418
|
+
const ctx5 = Layer.mergeAll(ctx4, tier5)
|
|
419
|
+
|
|
420
|
+
const tier6 = provide(
|
|
421
|
+
Layer.mergeAll(OwnershipDispatcherServiceLive, PlanAgentHeartbeatServiceLive, PlanDeadlineServiceLive),
|
|
422
|
+
ctx5,
|
|
423
|
+
)
|
|
424
|
+
const ctx6 = Layer.mergeAll(ctx5, tier6)
|
|
425
|
+
|
|
426
|
+
const tier7 = provide(Layer.mergeAll(ExecutionPlanServiceLive, GlobalOrchestratorServiceLive), ctx6)
|
|
427
|
+
const ctx7 = Layer.mergeAll(ctx6, tier7)
|
|
428
|
+
|
|
429
|
+
const tier8 = provide(
|
|
430
|
+
Layer.mergeAll(
|
|
431
|
+
PlanTemplateServiceLive,
|
|
432
|
+
AutonomousJobServiceLive,
|
|
433
|
+
AgentActivityServiceLive,
|
|
434
|
+
ThreadTurnPreparationServiceLive,
|
|
435
|
+
),
|
|
436
|
+
ctx7,
|
|
437
|
+
)
|
|
438
|
+
const ctx8 = Layer.mergeAll(ctx7, tier8)
|
|
439
|
+
|
|
440
|
+
const tier9 = provide(Layer.mergeAll(PlanCycleServiceLive, ThreadTurnServiceLive), ctx8)
|
|
441
|
+
const fullLayer = Layer.mergeAll(ctx8, tier9)
|
|
442
|
+
|
|
443
|
+
const managedRuntime = ManagedRuntime.make(fullLayer)
|
|
444
|
+
effectRuntime = managedRuntime
|
|
445
|
+
const resolvedServices = yield* Effect.tryPromise({
|
|
446
|
+
try: () =>
|
|
447
|
+
managedRuntime.runPromise(
|
|
448
|
+
Effect.gen(function* () {
|
|
449
|
+
return {
|
|
450
|
+
db: yield* EffectDatabaseService,
|
|
451
|
+
redisManager: yield* EffectRedisService,
|
|
452
|
+
sharedSubscriber: yield* SharedThreadStreamSubscriberTag,
|
|
453
|
+
threadTurnService: yield* ThreadTurnServiceTag,
|
|
454
|
+
socialChatHistoryService: yield* SocialChatHistoryServiceTag,
|
|
455
|
+
learnedSkillService: yield* LearnedSkillServiceTag,
|
|
456
|
+
memoryService: yield* MemoryServiceTag,
|
|
457
|
+
}
|
|
458
|
+
}),
|
|
459
|
+
),
|
|
460
|
+
catch: (error) =>
|
|
461
|
+
new ServiceError({
|
|
462
|
+
message: `Failed to initialize Effect runtime services: ${error instanceof Error ? error.message : String(error)}`,
|
|
463
|
+
cause: error,
|
|
464
|
+
}),
|
|
465
|
+
})
|
|
466
|
+
const {
|
|
467
|
+
db,
|
|
468
|
+
redisManager,
|
|
469
|
+
sharedSubscriber,
|
|
470
|
+
threadTurnService,
|
|
471
|
+
socialChatHistoryService,
|
|
472
|
+
learnedSkillService,
|
|
473
|
+
memoryService,
|
|
474
|
+
} = resolvedServices
|
|
475
|
+
|
|
476
|
+
setLotaSdkRuntime(managedRuntime)
|
|
394
477
|
|
|
395
|
-
|
|
478
|
+
type RuntimeServices = Layer.Success<typeof fullLayer>
|
|
479
|
+
const resolve = <I extends RuntimeServices, T>(tag: Context.Key<I, T>): T =>
|
|
480
|
+
managedRuntime.runSync(Effect.service(tag))
|
|
481
|
+
const resolveAwaitableService = <I extends RuntimeServices, T extends object>(
|
|
482
|
+
tag: Context.Key<I, T>,
|
|
483
|
+
): AwaitableService<T> =>
|
|
484
|
+
toAwaitableService(resolve(tag), { runPromise: (effect) => managedRuntime.runPromise(effect) })
|
|
396
485
|
|
|
397
|
-
|
|
398
|
-
|
|
486
|
+
const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
|
|
487
|
+
const pluginContributions = Object.values(pluginRuntime).map((plugin) => plugin.contributions)
|
|
488
|
+
const hostContributionSchemaFiles = pluginContributions.flatMap((plugin) => plugin.schemaFiles)
|
|
489
|
+
const schemaFiles = [
|
|
490
|
+
...getBuiltInSchemaFiles(),
|
|
491
|
+
...(runtimeConfig.extraSchemaFiles ?? []),
|
|
492
|
+
...hostContributionSchemaFiles,
|
|
493
|
+
]
|
|
494
|
+
const contributionEnvKeys = [...LOTA_RUNTIME_ENV_KEYS, ...pluginContributions.flatMap((plugin) => plugin.envKeys)]
|
|
495
|
+
const connectedPluginDatabases = new Set<string>()
|
|
496
|
+
const connectPluginDatabases = createPluginDatabaseConnector(pluginRuntime, connectedPluginDatabases)
|
|
497
|
+
const disconnectPluginDatabases = createPluginDatabaseDisconnector(pluginRuntime, connectedPluginDatabases)
|
|
498
|
+
const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
|
|
499
|
+
const socialChat = createSocialChatRuntime({
|
|
500
|
+
redisClient: redisManager.getConnection() as unknown as Parameters<
|
|
501
|
+
typeof createSocialChatRuntime
|
|
502
|
+
>[0]['redisClient'],
|
|
503
|
+
socialChat: runtimeConfig.socialChat,
|
|
504
|
+
services: { learnedSkillService, memoryService, socialChatHistoryService },
|
|
505
|
+
})
|
|
506
|
+
|
|
507
|
+
const services: LotaRuntime['services'] = {
|
|
399
508
|
database: db,
|
|
400
509
|
redis: redisManager,
|
|
401
|
-
closeRedisConnection:
|
|
402
|
-
agentActivityService
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
510
|
+
closeRedisConnection: () => runPromise(effectTryPromise(() => redisManager.closeConnection())),
|
|
511
|
+
get agentActivityService() {
|
|
512
|
+
return resolveAwaitableService(AgentActivityServiceTag)
|
|
513
|
+
},
|
|
514
|
+
get artifactService() {
|
|
515
|
+
return resolveAwaitableService(ArtifactServiceTag)
|
|
516
|
+
},
|
|
517
|
+
get attachmentService() {
|
|
518
|
+
return resolveAwaitableService(AttachmentServiceTag)
|
|
519
|
+
},
|
|
520
|
+
get autonomousJobService() {
|
|
521
|
+
return resolveAwaitableService(AutonomousJobServiceTag)
|
|
522
|
+
},
|
|
523
|
+
get contextCompactionService() {
|
|
524
|
+
return resolveAwaitableService(ContextCompactionServiceTag)
|
|
525
|
+
},
|
|
526
|
+
get documentChunkService() {
|
|
527
|
+
return resolveAwaitableService(DocumentChunkServiceTag) as AwaitableDocumentChunkService
|
|
528
|
+
},
|
|
529
|
+
get generatedDocumentStorageService() {
|
|
530
|
+
return resolveAwaitableService(GeneratedDocumentStorageServiceTag)
|
|
531
|
+
},
|
|
532
|
+
get memoryService() {
|
|
533
|
+
return resolveAwaitableService(MemoryServiceTag)
|
|
534
|
+
},
|
|
535
|
+
get rerankService() {
|
|
536
|
+
return resolveAwaitableService(RerankServiceTag)
|
|
537
|
+
},
|
|
538
|
+
get verifyMutatingApproval() {
|
|
539
|
+
return resolveAwaitableService(MutatingApprovalServiceTag)
|
|
540
|
+
},
|
|
541
|
+
get organizationService() {
|
|
542
|
+
return resolveAwaitableService(OrganizationServiceTag)
|
|
543
|
+
},
|
|
544
|
+
get organizationMemberService() {
|
|
545
|
+
return resolveAwaitableService(OrganizationMemberServiceTag)
|
|
546
|
+
},
|
|
547
|
+
get userService() {
|
|
548
|
+
return resolveAwaitableService(UserServiceTag)
|
|
549
|
+
},
|
|
550
|
+
get recentActivityService() {
|
|
551
|
+
return resolveAwaitableService(RecentActivityServiceTag)
|
|
552
|
+
},
|
|
553
|
+
get recentActivityTitleService() {
|
|
554
|
+
return resolveAwaitableService(RecentActivityTitleServiceTag)
|
|
555
|
+
},
|
|
556
|
+
socialChatHistoryService,
|
|
557
|
+
get executionPlanService() {
|
|
558
|
+
return resolveAwaitableService(ExecutionPlanServiceTag)
|
|
559
|
+
},
|
|
560
|
+
get planDeadlineService() {
|
|
561
|
+
return resolveAwaitableService(PlanDeadlineServiceTag)
|
|
562
|
+
},
|
|
563
|
+
get planExecutorService() {
|
|
564
|
+
return resolveAwaitableService(PlanExecutorServiceTag)
|
|
565
|
+
},
|
|
566
|
+
get planRunService() {
|
|
567
|
+
return resolveAwaitableService(PlanRunServiceTag)
|
|
568
|
+
},
|
|
569
|
+
get planTemplateService() {
|
|
570
|
+
return resolveAwaitableService(PlanTemplateServiceTag)
|
|
571
|
+
},
|
|
572
|
+
get planCoordinationService() {
|
|
573
|
+
return resolveAwaitableService(PlanCoordinationServiceTag)
|
|
574
|
+
},
|
|
575
|
+
get planSchedulerService() {
|
|
576
|
+
return resolveAwaitableService(PlanSchedulerServiceTag)
|
|
577
|
+
},
|
|
578
|
+
get planAgentHeartbeatService() {
|
|
579
|
+
return resolveAwaitableService(PlanAgentHeartbeatServiceTag)
|
|
580
|
+
},
|
|
581
|
+
get planAgentQueryService() {
|
|
582
|
+
return resolveAwaitableService(PlanAgentQueryServiceTag)
|
|
583
|
+
},
|
|
584
|
+
get planCycleService() {
|
|
585
|
+
return resolveAwaitableService(PlanCycleServiceTag)
|
|
586
|
+
},
|
|
587
|
+
get threadMessageService() {
|
|
588
|
+
return resolveAwaitableService(ThreadMessageServiceTag)
|
|
589
|
+
},
|
|
590
|
+
get threadService() {
|
|
591
|
+
return resolveAwaitableService(ThreadServiceTag) as AwaitableThreadService
|
|
592
|
+
},
|
|
593
|
+
get threadTitleService() {
|
|
594
|
+
return resolveAwaitableService(ThreadTitleServiceTag)
|
|
595
|
+
},
|
|
596
|
+
createThreadApprovalContinuationStream: (...args) =>
|
|
597
|
+
runPromise(threadTurnService.createThreadApprovalContinuationStream(...args)),
|
|
598
|
+
createThreadNativeToolApprovalStream: (...args) =>
|
|
599
|
+
runPromise(threadTurnService.createThreadNativeToolApprovalStream(...args)),
|
|
600
|
+
createThreadTurnStream: (...args) => runPromise(threadTurnService.createThreadTurnStream(...args)),
|
|
601
|
+
isApprovalContinuationRequest: isApprovalContinuationRequestFn,
|
|
602
|
+
runThreadTurnInBackground: (...args) => runPromise(threadTurnService.runThreadTurnInBackground(...args)),
|
|
603
|
+
triggerPlanNodeTurn: (...args) => runPromise(threadTurnService.triggerPlanNodeTurn(...args)),
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const lota: LotaRuntime['lota'] = {
|
|
607
|
+
organizations: {
|
|
608
|
+
create: (...args) => resolveAwaitableService(OrganizationServiceTag).createOrganization(...args),
|
|
609
|
+
upsert: (...args) => resolveAwaitableService(OrganizationServiceTag).upsertOrganization(...args),
|
|
610
|
+
get: (...args) => resolveAwaitableService(OrganizationServiceTag).getOrganization(...args),
|
|
611
|
+
list: (...args) => resolveAwaitableService(OrganizationServiceTag).listOrganizations(...args),
|
|
612
|
+
update: (...args) => resolveAwaitableService(OrganizationServiceTag).updateOrganization(...args),
|
|
613
|
+
delete: (...args) => resolveAwaitableService(OrganizationServiceTag).deleteOrganization(...args),
|
|
614
|
+
},
|
|
615
|
+
users: {
|
|
616
|
+
upsert: (...args) => resolveAwaitableService(UserServiceTag).upsertUser(...args),
|
|
617
|
+
get: (...args) => resolveAwaitableService(UserServiceTag).getUser(...args),
|
|
618
|
+
list: (...args) => resolveAwaitableService(UserServiceTag).listUsers(...args),
|
|
619
|
+
update: (...args) => resolveAwaitableService(UserServiceTag).updateUser(...args),
|
|
620
|
+
delete: (...args) => resolveAwaitableService(UserServiceTag).deleteUser(...args),
|
|
621
|
+
},
|
|
622
|
+
memberships: {
|
|
623
|
+
add: (...args) => resolveAwaitableService(OrganizationMemberServiceTag).addMembership(...args),
|
|
624
|
+
listForOrganization: (...args) =>
|
|
625
|
+
resolveAwaitableService(OrganizationMemberServiceTag).listMembershipsForOrganization(...args),
|
|
626
|
+
listForUser: (...args) =>
|
|
627
|
+
resolveAwaitableService(OrganizationMemberServiceTag).listMembershipsForUser(...args),
|
|
628
|
+
remove: (...args) => resolveAwaitableService(OrganizationMemberServiceTag).removeMembership(...args),
|
|
629
|
+
isMember: (...args) => resolveAwaitableService(OrganizationMemberServiceTag).isMember(...args),
|
|
630
|
+
},
|
|
631
|
+
threads: {
|
|
632
|
+
create: (...args) => resolveAwaitableService(ThreadServiceTag).createThread(...args),
|
|
633
|
+
list: (...args) => resolveAwaitableService(ThreadServiceTag).listThreads(...args),
|
|
634
|
+
get: (...args) => resolveAwaitableService(ThreadServiceTag).getThread(...args),
|
|
635
|
+
update: (...args) => resolveAwaitableService(ThreadServiceTag).updateTitle(...args),
|
|
636
|
+
archive: (threadId, status = 'archived') =>
|
|
637
|
+
resolveAwaitableService(ThreadServiceTag).updateStatus(threadId, status),
|
|
638
|
+
unarchive: (threadId, status = 'active') =>
|
|
639
|
+
resolveAwaitableService(ThreadServiceTag).updateStatus(threadId, status),
|
|
640
|
+
delete: (...args) => resolveAwaitableService(ThreadServiceTag).deleteThread(...args),
|
|
641
|
+
stop: (...args) => resolveAwaitableService(ThreadServiceTag).stopActiveRun(...args),
|
|
642
|
+
listMessages: (...args) => resolveAwaitableService(ThreadMessageServiceTag).listMessageHistoryPage(...args),
|
|
643
|
+
getMessage: ({ threadId, messageId }) =>
|
|
644
|
+
runPromise(
|
|
645
|
+
Effect.gen(function* () {
|
|
646
|
+
const messages = yield* resolve(ThreadMessageServiceTag).listMessages(
|
|
647
|
+
ensureRecordId(threadId, TABLES.THREAD),
|
|
648
|
+
)
|
|
649
|
+
const message = messages.find((candidate: ChatMessage) => candidate.id === messageId)
|
|
650
|
+
if (!message) {
|
|
651
|
+
return yield* new NotFoundError({
|
|
652
|
+
resource: 'Thread message',
|
|
653
|
+
id: messageId,
|
|
654
|
+
message: `Thread message not found: ${messageId}`,
|
|
655
|
+
})
|
|
656
|
+
}
|
|
657
|
+
return message
|
|
658
|
+
}),
|
|
659
|
+
),
|
|
660
|
+
sendMessage: ({ threadId, organizationId, userId, userName, messages }) =>
|
|
661
|
+
runPromise(
|
|
662
|
+
Effect.gen(function* () {
|
|
663
|
+
const threadRef = ensureRecordId(threadId, TABLES.THREAD)
|
|
664
|
+
const thread = yield* resolve(ThreadServiceTag).getThread(threadRef)
|
|
665
|
+
const routed = routeThreadChatMessages(messages)
|
|
666
|
+
if (routed.kind !== 'turn') {
|
|
667
|
+
return yield* new BadRequestError({
|
|
668
|
+
message: routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.',
|
|
669
|
+
})
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
return yield* threadTurnService.createThreadTurnStream({
|
|
673
|
+
thread,
|
|
674
|
+
threadRef,
|
|
675
|
+
orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
|
|
676
|
+
userRef: ensureRecordId(userId, TABLES.USER),
|
|
677
|
+
userName,
|
|
678
|
+
inputMessage: routed.inputMessage,
|
|
679
|
+
})
|
|
680
|
+
}),
|
|
681
|
+
),
|
|
682
|
+
continueApproval: ({ threadId, organizationId, userId, userName, messages }) =>
|
|
683
|
+
runPromise(
|
|
684
|
+
Effect.gen(function* () {
|
|
685
|
+
const threadRef = ensureRecordId(threadId, TABLES.THREAD)
|
|
686
|
+
const thread = yield* resolve(ThreadServiceTag).getThread(threadRef)
|
|
687
|
+
const routed = routeThreadChatMessages(messages)
|
|
688
|
+
if (routed.kind !== 'approval-continuation') {
|
|
689
|
+
return yield* new BadRequestError({
|
|
690
|
+
message:
|
|
691
|
+
routed.kind === 'invalid' ? routed.message : 'Expected approval continuation messages payload.',
|
|
692
|
+
})
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return yield* threadTurnService.createThreadApprovalContinuationStream({
|
|
696
|
+
thread,
|
|
697
|
+
threadRef,
|
|
698
|
+
orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
|
|
699
|
+
userRef: ensureRecordId(userId, TABLES.USER),
|
|
700
|
+
userName,
|
|
701
|
+
approvalMessages: routed.approvalMessages,
|
|
702
|
+
})
|
|
703
|
+
}),
|
|
704
|
+
),
|
|
705
|
+
uploadAttachment: (...args) => resolveAwaitableService(AttachmentServiceTag).uploadThreadAttachment(...args),
|
|
706
|
+
},
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
let disconnectPromise: Promise<void> | null = null
|
|
710
|
+
|
|
711
|
+
const lotaRuntime: LotaRuntime = {
|
|
712
|
+
runPromise: (effect, options) => managedRuntime.runPromise(effect, options),
|
|
713
|
+
runSync: (effect) => managedRuntime.runSync(effect),
|
|
714
|
+
services,
|
|
715
|
+
lota,
|
|
716
|
+
redis: {
|
|
717
|
+
manager: redisManager,
|
|
718
|
+
subscriber: sharedSubscriber.subscriber,
|
|
719
|
+
getConnection: () => redisManager.getConnection(),
|
|
720
|
+
getConnectionForBullMQ: () => redisManager.getConnectionForBullMQ(),
|
|
721
|
+
closeConnection: () => runPromise(effectTryPromise(() => redisManager.closeConnection())),
|
|
722
|
+
},
|
|
723
|
+
workers,
|
|
724
|
+
socialChat,
|
|
725
|
+
schemaFiles,
|
|
726
|
+
contributions: { envKeys: [...new Set(contributionEnvKeys)], schemaFiles: hostContributionSchemaFiles },
|
|
727
|
+
config: runtimeConfig,
|
|
728
|
+
plugins: pluginRuntime,
|
|
729
|
+
systemExecutors,
|
|
730
|
+
connectPluginDatabases: () => runPromise(effectTryPromise(() => connectPluginDatabases())),
|
|
731
|
+
connect: () =>
|
|
732
|
+
runPromise(
|
|
733
|
+
Effect.gen(function* () {
|
|
734
|
+
yield* db.connect()
|
|
735
|
+
const bunFiles = schemaFiles.map((schemaFile) =>
|
|
736
|
+
schemaFile instanceof URL ? Bun.file(schemaFile.pathname) : Bun.file(schemaFile),
|
|
737
|
+
)
|
|
738
|
+
yield* db.applySchema(bunFiles)
|
|
739
|
+
const schemaFingerprint = yield* effectTryPromise(() => computeSchemaFingerprint(schemaFiles))
|
|
740
|
+
yield* publishDatabaseBootstrapEffect({ databaseService: db, schemaFingerprint })
|
|
741
|
+
}),
|
|
742
|
+
),
|
|
743
|
+
disconnect: () => {
|
|
744
|
+
if (disconnectPromise) {
|
|
745
|
+
return disconnectPromise
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
disconnectPromise = Effect.runPromise(
|
|
749
|
+
Effect.gen(function* () {
|
|
750
|
+
yield* Effect.ignore(effectTryPromise(() => socialChat.shutdown()))
|
|
751
|
+
yield* Effect.ignore(effectTryPromise(() => disconnectPluginDatabases()))
|
|
752
|
+
yield* effectTryPromise(() => managedRuntime.dispose())
|
|
753
|
+
}).pipe(
|
|
754
|
+
Effect.ensuring(
|
|
755
|
+
Effect.sync(() => {
|
|
756
|
+
clearLotaSdkRuntime()
|
|
757
|
+
if (runtimeToken) releaseRuntimeToken(runtimeToken)
|
|
758
|
+
}),
|
|
759
|
+
),
|
|
760
|
+
),
|
|
761
|
+
)
|
|
762
|
+
return disconnectPromise
|
|
763
|
+
},
|
|
764
|
+
}
|
|
765
|
+
return lotaRuntime
|
|
766
|
+
}),
|
|
767
|
+
).catch((error) => {
|
|
768
|
+
if (effectRuntime) {
|
|
769
|
+
clearLotaSdkRuntime()
|
|
770
|
+
void effectRuntime.dispose().catch(() => undefined)
|
|
475
771
|
}
|
|
476
|
-
|
|
477
|
-
releaseRuntimeToken(runtimeToken)
|
|
772
|
+
if (runtimeToken) releaseRuntimeToken(runtimeToken)
|
|
478
773
|
throw error
|
|
479
|
-
}
|
|
774
|
+
})
|
|
480
775
|
}
|
|
481
776
|
|
|
482
777
|
function getBuiltInSchemaFiles(): URL[] {
|
|
@@ -496,16 +791,59 @@ function getBuiltInSchemaFiles(): URL[] {
|
|
|
496
791
|
]
|
|
497
792
|
}
|
|
498
793
|
|
|
499
|
-
function
|
|
500
|
-
return
|
|
501
|
-
|
|
502
|
-
const services = plugin.services
|
|
503
|
-
const connectDatabase = services.connectDatabase
|
|
504
|
-
if (typeof connectDatabase !== 'function') {
|
|
505
|
-
continue
|
|
506
|
-
}
|
|
794
|
+
function getPluginLifecycleServices(plugin: LotaPlugin): PluginLifecycleServices {
|
|
795
|
+
return plugin.services as PluginLifecycleServices
|
|
796
|
+
}
|
|
507
797
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
798
|
+
function createPluginDatabaseConnector(
|
|
799
|
+
pluginRuntime: Record<string, LotaPlugin>,
|
|
800
|
+
connectedPluginDatabases: Set<string>,
|
|
801
|
+
): () => Promise<void> {
|
|
802
|
+
return () =>
|
|
803
|
+
Effect.runPromise(
|
|
804
|
+
Effect.gen(function* () {
|
|
805
|
+
for (const [pluginName, plugin] of Object.entries(pluginRuntime)) {
|
|
806
|
+
if (connectedPluginDatabases.has(pluginName)) {
|
|
807
|
+
continue
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const services = getPluginLifecycleServices(plugin)
|
|
811
|
+
const connectDatabase = Reflect.get(services, 'connectDatabase')
|
|
812
|
+
if (typeof connectDatabase !== 'function') {
|
|
813
|
+
continue
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
const connectDatabaseFn = connectDatabase as (this: typeof services) => Promise<void>
|
|
817
|
+
yield* effectTryPromise(() => connectDatabaseFn.call(services))
|
|
818
|
+
connectedPluginDatabases.add(pluginName)
|
|
819
|
+
}
|
|
820
|
+
}),
|
|
821
|
+
)
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
function createPluginDatabaseDisconnector(
|
|
825
|
+
pluginRuntime: Record<string, LotaPlugin>,
|
|
826
|
+
connectedPluginDatabases: Set<string>,
|
|
827
|
+
): () => Promise<void> {
|
|
828
|
+
return () =>
|
|
829
|
+
Effect.runPromise(
|
|
830
|
+
Effect.gen(function* () {
|
|
831
|
+
for (const [pluginName, plugin] of Object.entries(pluginRuntime)) {
|
|
832
|
+
if (!connectedPluginDatabases.has(pluginName)) {
|
|
833
|
+
continue
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
const services = getPluginLifecycleServices(plugin)
|
|
837
|
+
const disconnectDatabase = Reflect.get(services, 'disconnectDatabase')
|
|
838
|
+
if (typeof disconnectDatabase !== 'function') {
|
|
839
|
+
connectedPluginDatabases.delete(pluginName)
|
|
840
|
+
continue
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const disconnectDatabaseFn = disconnectDatabase as (this: typeof services) => Promise<void>
|
|
844
|
+
yield* effectTryPromise(() => disconnectDatabaseFn.call(services))
|
|
845
|
+
connectedPluginDatabases.delete(pluginName)
|
|
846
|
+
}
|
|
847
|
+
}),
|
|
848
|
+
)
|
|
511
849
|
}
|