@lota-sdk/core 0.4.7 → 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/model-constants.ts +1 -0
- package/src/config/thread-defaults.ts +33 -21
- package/src/create-runtime.ts +725 -383
- 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 -71
- package/src/index.ts +46 -1
- package/src/openrouter/direct-provider.ts +29 -0
- 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 +165 -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 -20
- 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 -844
- 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/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,119 +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'
|
|
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'
|
|
66
64
|
import {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
} from './services/
|
|
70
|
-
import {
|
|
71
|
-
import
|
|
72
|
-
import {
|
|
73
|
-
import
|
|
74
|
-
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'
|
|
75
95
|
import type {
|
|
76
96
|
createThreadApprovalContinuationStream,
|
|
77
97
|
createThreadNativeToolApprovalStream,
|
|
78
98
|
createThreadTurnStream,
|
|
79
99
|
runThreadTurnInBackground,
|
|
80
100
|
triggerPlanNodeTurn,
|
|
81
|
-
} 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'
|
|
82
112
|
import {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
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'>
|
|
96
125
|
|
|
97
126
|
type ArchiveSdkThread = (
|
|
98
|
-
threadId: Parameters<typeof
|
|
127
|
+
threadId: Parameters<Svc<typeof ThreadServiceTag>['updateStatus']>[0],
|
|
99
128
|
status?: 'archived',
|
|
100
|
-
) => ReturnType<typeof
|
|
129
|
+
) => ReturnType<Svc<typeof ThreadServiceTag>['updateStatus']>
|
|
101
130
|
|
|
102
131
|
type UnarchiveSdkThread = (
|
|
103
|
-
threadId: Parameters<typeof
|
|
132
|
+
threadId: Parameters<Svc<typeof ThreadServiceTag>['updateStatus']>[0],
|
|
104
133
|
status?: 'active',
|
|
105
|
-
) => ReturnType<typeof
|
|
134
|
+
) => ReturnType<Svc<typeof ThreadServiceTag>['updateStatus']>
|
|
106
135
|
|
|
107
136
|
let activeRuntimeToken: symbol | null = null
|
|
108
137
|
|
|
109
|
-
function claimRuntimeToken(): symbol {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
+
}
|
|
113
145
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
146
|
+
const token = Symbol('lota-runtime')
|
|
147
|
+
activeRuntimeToken = token
|
|
148
|
+
return token
|
|
149
|
+
})
|
|
117
150
|
}
|
|
118
151
|
|
|
119
152
|
function releaseRuntimeToken(token: symbol) {
|
|
@@ -122,35 +155,69 @@ function releaseRuntimeToken(token: symbol) {
|
|
|
122
155
|
}
|
|
123
156
|
}
|
|
124
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
|
+
|
|
125
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
|
|
126
188
|
services: {
|
|
127
189
|
database: SurrealDBService
|
|
128
190
|
redis: RedisConnectionManager
|
|
129
191
|
closeRedisConnection: () => Promise<void>
|
|
130
|
-
agentActivityService: typeof
|
|
131
|
-
artifactService: typeof
|
|
132
|
-
attachmentService: typeof
|
|
133
|
-
autonomousJobService: typeof
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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>
|
|
154
221
|
createThreadApprovalContinuationStream: typeof createThreadApprovalContinuationStream
|
|
155
222
|
createThreadNativeToolApprovalStream: typeof createThreadNativeToolApprovalStream
|
|
156
223
|
createThreadTurnStream: typeof createThreadTurnStream
|
|
@@ -160,37 +227,37 @@ export interface LotaRuntime {
|
|
|
160
227
|
}
|
|
161
228
|
lota: {
|
|
162
229
|
organizations: {
|
|
163
|
-
create: typeof
|
|
164
|
-
upsert: typeof
|
|
165
|
-
get: typeof
|
|
166
|
-
list: typeof
|
|
167
|
-
update: typeof
|
|
168
|
-
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']>
|
|
169
236
|
}
|
|
170
237
|
users: {
|
|
171
|
-
upsert: typeof
|
|
172
|
-
get: typeof
|
|
173
|
-
list: typeof
|
|
174
|
-
update: typeof
|
|
175
|
-
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']>
|
|
176
243
|
}
|
|
177
244
|
memberships: {
|
|
178
|
-
add: typeof
|
|
179
|
-
listForOrganization: typeof
|
|
180
|
-
listForUser: typeof
|
|
181
|
-
remove: typeof
|
|
182
|
-
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']>
|
|
183
250
|
}
|
|
184
251
|
threads: {
|
|
185
|
-
create: typeof
|
|
186
|
-
list: typeof
|
|
187
|
-
get: typeof
|
|
188
|
-
update: typeof
|
|
189
|
-
archive: ArchiveSdkThread
|
|
190
|
-
unarchive: UnarchiveSdkThread
|
|
191
|
-
delete: typeof
|
|
192
|
-
stop: typeof
|
|
193
|
-
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']>
|
|
194
261
|
getMessage: (params: { threadId: string; messageId: string }) => Promise<ChatMessage>
|
|
195
262
|
sendMessage: (params: {
|
|
196
263
|
threadId: string
|
|
@@ -206,11 +273,12 @@ export interface LotaRuntime {
|
|
|
206
273
|
userName: string
|
|
207
274
|
messages: Parameters<typeof routeThreadChatMessages>[0]
|
|
208
275
|
}) => Promise<Awaited<ReturnType<typeof createThreadApprovalContinuationStream>>>
|
|
209
|
-
uploadAttachment: typeof
|
|
276
|
+
uploadAttachment: AwaitableValue<Svc<typeof AttachmentServiceTag>['uploadThreadAttachment']>
|
|
210
277
|
}
|
|
211
278
|
}
|
|
212
279
|
redis: {
|
|
213
280
|
manager: RedisConnectionManager
|
|
281
|
+
subscriber: Subscriber
|
|
214
282
|
getConnection: () => ReturnType<RedisConnectionManager['getConnection']>
|
|
215
283
|
getConnectionForBullMQ: () => ReturnType<RedisConnectionManager['getConnectionForBullMQ']>
|
|
216
284
|
closeConnection: () => Promise<void>
|
|
@@ -227,252 +295,483 @@ export interface LotaRuntime {
|
|
|
227
295
|
disconnect(): Promise<void>
|
|
228
296
|
}
|
|
229
297
|
|
|
230
|
-
export
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
|
|
262
|
-
: runtimeConfig.agents.displayNames
|
|
263
|
-
|
|
264
|
-
configureAgents({
|
|
265
|
-
roster: runtimeConfig.agents.roster,
|
|
266
|
-
leadAgentId: runtimeConfig.agents.leadAgentId,
|
|
267
|
-
displayNames: agentDisplayNames,
|
|
268
|
-
shortDisplayNames: runtimeConfig.agents.shortDisplayNames,
|
|
269
|
-
descriptions: runtimeConfig.agents.descriptions,
|
|
270
|
-
routerModelId: runtimeConfig.agents.routerModelId,
|
|
271
|
-
teamConsultParticipants: runtimeConfig.agents.teamConsultParticipants,
|
|
272
|
-
getCoreThreadProfile: runtimeConfig.agents.getCoreThreadProfile,
|
|
273
|
-
})
|
|
274
|
-
configureAgentFactory({
|
|
275
|
-
createAgent: runtimeConfig.agents.createAgent,
|
|
276
|
-
buildAgentTools: runtimeConfig.agents.buildAgentTools,
|
|
277
|
-
getAgentRuntimeConfig: runtimeConfig.agents.getAgentRuntimeConfig,
|
|
278
|
-
pluginRuntime: runtimeConfig.pluginRuntime,
|
|
279
|
-
})
|
|
280
|
-
configureThreads({ agentRoster: runtimeConfig.agents.roster, config: runtimeConfig.threads })
|
|
281
|
-
configureNotificationService(runtimeConfig.notificationService ?? null)
|
|
282
|
-
configureRuntimeExtensions({
|
|
283
|
-
adapters: runtimeConfig.runtimeAdapters,
|
|
284
|
-
turnHooks: runtimeConfig.turnHooks,
|
|
285
|
-
toolProviders: (runtimeConfig.toolProviders ?? {}) as never,
|
|
286
|
-
extraWorkers: runtimeConfig.extraWorkers,
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
|
|
290
|
-
if (runtimeConfig.graphDesigner) {
|
|
291
|
-
configureGraphDesigner(runtimeConfig.graphDesigner)
|
|
292
|
-
}
|
|
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
|
|
293
329
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
users: {
|
|
319
|
-
upsert: userServiceSingleton.upsertUser.bind(userServiceSingleton),
|
|
320
|
-
get: userServiceSingleton.getUser.bind(userServiceSingleton),
|
|
321
|
-
list: userServiceSingleton.listUsers.bind(userServiceSingleton),
|
|
322
|
-
update: userServiceSingleton.updateUser.bind(userServiceSingleton),
|
|
323
|
-
delete: userServiceSingleton.deleteUser.bind(userServiceSingleton),
|
|
324
|
-
},
|
|
325
|
-
memberships: {
|
|
326
|
-
add: organizationMemberServiceSingleton.addMembership.bind(organizationMemberServiceSingleton),
|
|
327
|
-
listForOrganization: organizationMemberServiceSingleton.listMembershipsForOrganization.bind(
|
|
328
|
-
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,
|
|
329
354
|
),
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
get: threadServiceSingleton.getThread.bind(threadServiceSingleton),
|
|
338
|
-
update: threadServiceSingleton.updateTitle.bind(threadServiceSingleton),
|
|
339
|
-
archive: async (threadId, status = 'archived') => await threadServiceSingleton.updateStatus(threadId, status),
|
|
340
|
-
unarchive: async (threadId, status = 'active') => await threadServiceSingleton.updateStatus(threadId, status),
|
|
341
|
-
delete: threadServiceSingleton.deleteThread.bind(threadServiceSingleton),
|
|
342
|
-
stop: threadServiceSingleton.stopActiveRun.bind(threadServiceSingleton),
|
|
343
|
-
listMessages: threadMessageServiceSingleton.listMessageHistoryPage.bind(threadMessageServiceSingleton),
|
|
344
|
-
getMessage: async ({ threadId, messageId }) => {
|
|
345
|
-
const messages = await threadMessageServiceSingleton.listMessages(ensureRecordId(threadId, TABLES.THREAD))
|
|
346
|
-
const message = messages.find((candidate) => candidate.id === messageId)
|
|
347
|
-
if (!message) {
|
|
348
|
-
throw new Error(`Thread message not found: ${messageId}`)
|
|
349
|
-
}
|
|
350
|
-
return message
|
|
351
|
-
},
|
|
352
|
-
sendMessage: async ({ threadId, organizationId, userId, userName, messages }) => {
|
|
353
|
-
const threadRef = ensureRecordId(threadId, TABLES.THREAD)
|
|
354
|
-
const thread = await threadServiceSingleton.getThread(threadRef)
|
|
355
|
-
const routed = routeThreadChatMessages(messages)
|
|
356
|
-
if (routed.kind !== 'turn') {
|
|
357
|
-
throw new Error(routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.')
|
|
358
|
-
}
|
|
355
|
+
infrastructureLayer,
|
|
356
|
+
)
|
|
357
|
+
const ctx0 = Layer.mergeAll(
|
|
358
|
+
infrastructureLayer,
|
|
359
|
+
provide(Layer.mergeAll(AiGatewayLive, EmbeddingCacheLive, FirecrawlLive, HelperModelLive), infrastructureLayer),
|
|
360
|
+
tier0,
|
|
361
|
+
)
|
|
359
362
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
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)
|
|
378
389
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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)
|
|
391
477
|
|
|
392
|
-
|
|
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) })
|
|
393
485
|
|
|
394
|
-
|
|
395
|
-
|
|
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'] = {
|
|
396
508
|
database: db,
|
|
397
509
|
redis: redisManager,
|
|
398
|
-
closeRedisConnection:
|
|
399
|
-
agentActivityService
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
-
return
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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)
|
|
471
771
|
}
|
|
472
|
-
|
|
473
|
-
releaseRuntimeToken(runtimeToken)
|
|
772
|
+
if (runtimeToken) releaseRuntimeToken(runtimeToken)
|
|
474
773
|
throw error
|
|
475
|
-
}
|
|
774
|
+
})
|
|
476
775
|
}
|
|
477
776
|
|
|
478
777
|
function getBuiltInSchemaFiles(): URL[] {
|
|
@@ -492,16 +791,59 @@ function getBuiltInSchemaFiles(): URL[] {
|
|
|
492
791
|
]
|
|
493
792
|
}
|
|
494
793
|
|
|
495
|
-
function
|
|
496
|
-
return
|
|
497
|
-
|
|
498
|
-
const services = plugin.services
|
|
499
|
-
const connectDatabase = services.connectDatabase
|
|
500
|
-
if (typeof connectDatabase !== 'function') {
|
|
501
|
-
continue
|
|
502
|
-
}
|
|
794
|
+
function getPluginLifecycleServices(plugin: LotaPlugin): PluginLifecycleServices {
|
|
795
|
+
return plugin.services as PluginLifecycleServices
|
|
796
|
+
}
|
|
503
797
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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
|
+
)
|
|
507
849
|
}
|