@lota-sdk/core 0.1.15 → 0.1.17
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/infrastructure/schema/00_identity.surql +0 -2
- package/infrastructure/schema/01_memory.surql +1 -1
- package/infrastructure/schema/02_execution_plan.surql +62 -1
- package/infrastructure/schema/03_learned_skill.surql +1 -1
- package/infrastructure/schema/06_playbook.surql +25 -0
- package/infrastructure/schema/07_institutional_memory.surql +13 -0
- package/infrastructure/schema/08_quality_metrics.surql +17 -0
- package/package.json +12 -8
- package/src/ai/definitions.ts +81 -3
- package/src/ai/embedding-cache.ts +2 -4
- package/src/ai/index.ts +0 -2
- package/src/bifrost/bifrost.ts +2 -7
- package/src/bifrost/cache-headers.ts +8 -0
- package/src/bifrost/index.ts +1 -0
- package/src/config/agent-defaults.ts +31 -21
- package/src/config/agent-types.ts +11 -0
- package/src/config/constants.ts +2 -14
- package/src/config/debug-logger.ts +5 -1
- package/src/config/index.ts +3 -0
- package/src/config/model-constants.ts +16 -34
- package/src/config/search.ts +1 -15
- package/src/create-runtime.ts +269 -178
- package/src/db/cursor-pagination.ts +3 -6
- package/src/db/index.ts +2 -0
- package/src/db/memory-store.helpers.ts +1 -3
- package/src/db/memory-store.rows.ts +7 -7
- package/src/db/memory-store.ts +14 -18
- package/src/db/memory.ts +13 -13
- package/src/db/schema-fingerprint.ts +1 -3
- package/src/db/service.ts +153 -79
- package/src/db/startup.ts +6 -10
- package/src/db/surreal-mutation.ts +43 -0
- package/src/db/tables.ts +7 -0
- package/src/db/workstream-message-row.ts +15 -0
- package/src/embeddings/provider.ts +1 -1
- package/src/queues/context-compaction.queue.ts +15 -46
- package/src/queues/delayed-node-promotion.queue.ts +41 -0
- package/src/queues/document-processor.queue.ts +2 -4
- package/src/queues/index.ts +3 -0
- package/src/queues/memory-consolidation.queue.ts +16 -51
- package/src/queues/plan-scheduler.queue.ts +97 -0
- package/src/queues/post-chat-memory.queue.ts +20 -55
- package/src/queues/queue-factory.ts +100 -0
- package/src/queues/recent-activity-title-refinement.queue.ts +15 -50
- package/src/queues/regular-chat-memory-digest.queue.ts +16 -52
- package/src/queues/skill-extraction.queue.ts +15 -47
- package/src/queues/workstream-title-generation.queue.ts +15 -47
- package/src/redis/connection.ts +6 -0
- package/src/redis/index.ts +1 -1
- package/src/redis/redis-lease-lock.ts +1 -2
- package/src/redis/stream-context.ts +11 -0
- package/src/runtime/agent-runtime-policy.ts +109 -35
- package/src/runtime/approval-continuation.ts +12 -6
- package/src/runtime/context-compaction-runtime.ts +1 -1
- package/src/runtime/context-compaction.ts +24 -64
- package/src/runtime/execution-plan.ts +22 -18
- package/src/runtime/graph-designer.ts +15 -0
- package/src/runtime/helper-model.ts +9 -197
- package/src/runtime/index.ts +3 -1
- package/src/runtime/llm-content.ts +1 -1
- package/src/runtime/memory-block.ts +9 -11
- package/src/runtime/memory-pipeline.ts +6 -9
- package/src/runtime/plugin-resolution.ts +35 -0
- package/src/runtime/plugin-types.ts +72 -0
- package/src/runtime/retrieval-adapters.ts +1 -1
- package/src/runtime/runtime-config.ts +111 -14
- package/src/runtime/runtime-extensions.ts +2 -3
- package/src/runtime/runtime-worker-registry.ts +6 -0
- package/src/runtime/social-chat.ts +752 -0
- package/src/runtime/team-consultation-orchestrator.ts +45 -32
- package/src/runtime/team-consultation-prompts.ts +11 -2
- package/src/runtime/title-helpers.ts +2 -4
- package/src/runtime/workstream-chat-helpers.ts +1 -1
- package/src/services/adaptive-playbook.service.ts +152 -0
- package/src/services/agent-executor.service.ts +292 -0
- package/src/services/artifact-provenance.service.ts +172 -0
- package/src/services/attachment.service.ts +6 -11
- package/src/services/context-compaction.service.ts +72 -55
- package/src/services/context-enrichment.service.ts +33 -0
- package/src/services/coordination-registry.service.ts +117 -0
- package/src/services/document-chunk.service.ts +2 -4
- package/src/services/domain-agent-executor.service.ts +71 -0
- package/src/services/execution-plan.service.ts +269 -50
- package/src/services/feedback-loop.service.ts +96 -0
- package/src/services/global-orchestrator.service.ts +148 -0
- package/src/services/index.ts +27 -0
- package/src/services/institutional-memory.service.ts +145 -0
- package/src/services/learned-skill.service.ts +24 -5
- package/src/services/memory-assessment.service.ts +3 -2
- package/src/services/memory-utils.ts +3 -8
- package/src/services/memory.service.ts +49 -61
- package/src/services/monitoring-window.service.ts +86 -0
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +155 -0
- package/src/services/notification.service.ts +39 -0
- package/src/services/organization-member.service.ts +11 -4
- package/src/services/organization.service.ts +5 -5
- package/src/services/ownership-dispatcher.service.ts +403 -0
- package/src/services/plan-approval.service.ts +1 -1
- package/src/services/plan-builder.service.ts +1 -0
- package/src/services/plan-checkpoint.service.ts +30 -2
- package/src/services/plan-compiler.service.ts +5 -0
- package/src/services/plan-coordination.service.ts +152 -0
- package/src/services/plan-cycle.service.ts +284 -0
- package/src/services/plan-deadline.service.ts +287 -0
- package/src/services/plan-executor.service.ts +384 -40
- package/src/services/plan-run.service.ts +41 -7
- package/src/services/plan-scheduler.service.ts +240 -0
- package/src/services/plan-template.service.ts +117 -0
- package/src/services/plan-validator.service.ts +84 -2
- package/src/services/plan-workspace.service.ts +83 -0
- package/src/services/playbook-registry.service.ts +67 -0
- package/src/services/plugin-executor.service.ts +103 -0
- package/src/services/quality-metrics.service.ts +132 -0
- package/src/services/recent-activity.service.ts +28 -34
- package/src/services/skill-resolver.service.ts +19 -0
- package/src/services/social-chat-history.service.ts +197 -0
- package/src/services/system-executor.service.ts +105 -0
- package/src/services/workstream-message.service.ts +13 -37
- package/src/services/workstream-plan-registry.service.ts +22 -0
- package/src/services/workstream-title.service.ts +3 -1
- package/src/services/workstream-turn-preparation.service.ts +34 -89
- package/src/services/workstream.service.ts +33 -55
- package/src/services/workstream.types.ts +9 -9
- package/src/services/write-intent-validator.service.ts +81 -0
- package/src/storage/attachment-parser.ts +1 -1
- package/src/storage/attachment-utils.ts +1 -1
- package/src/storage/generated-document-storage.service.ts +3 -2
- package/src/system-agents/context-compaction.agent.ts +2 -0
- package/src/system-agents/delegated-agent-factory.ts +5 -0
- package/src/system-agents/memory-reranker.agent.ts +4 -2
- package/src/system-agents/memory.agent.ts +2 -0
- package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -0
- package/src/system-agents/regular-chat-memory-digest.agent.ts +2 -0
- package/src/system-agents/skill-extractor.agent.ts +2 -0
- package/src/system-agents/skill-manager.agent.ts +2 -0
- package/src/system-agents/title-generator.agent.ts +2 -0
- package/src/tools/execution-plan.tool.ts +17 -23
- package/src/tools/index.ts +0 -1
- package/src/tools/research-topic.tool.ts +2 -0
- package/src/tools/team-think.tool.ts +5 -6
- package/src/utils/async.ts +2 -1
- package/src/utils/date-time.ts +4 -32
- package/src/utils/env.ts +8 -0
- package/src/utils/errors.ts +42 -10
- package/src/utils/index.ts +9 -0
- package/src/utils/string.ts +114 -1
- package/src/workers/index.ts +1 -0
- package/src/workers/regular-chat-memory-digest.helpers.ts +1 -1
- package/src/workers/regular-chat-memory-digest.runner.ts +45 -12
- package/src/workers/skill-extraction.runner.ts +26 -6
- package/src/workers/utils/file-section-chunker.ts +2 -1
- package/src/workers/utils/repo-structure-extractor.ts +2 -2
- package/src/workers/utils/repomix-file-sections.ts +2 -2
- package/src/workers/utils/sandbox-error.ts +11 -2
- package/src/workers/utils/workstream-message-query.ts +14 -25
- package/src/workers/worker-utils.ts +2 -2
- package/src/runtime/workstream-routing-policy.ts +0 -267
- package/src/tools/log-hello-world.tool.ts +0 -17
package/src/config/search.ts
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
* Search-related constants for vector search and hybrid search
|
|
3
|
-
*/
|
|
1
|
+
export { VECTOR_SEARCH_OVERFETCH_MULTIPLIER } from '@lota-sdk/shared'
|
|
4
2
|
|
|
5
|
-
/**
|
|
6
|
-
* Multiplier for vector search fetch limit.
|
|
7
|
-
* We fetch more candidates than needed (limit * multiplier) to allow for:
|
|
8
|
-
* - RRF (Reciprocal Rank Fusion) re-ranking
|
|
9
|
-
* - Hybrid search combining vector + full-text results
|
|
10
|
-
* - Filtering out low-quality matches before returning final results
|
|
11
|
-
*/
|
|
12
|
-
export const VECTOR_SEARCH_OVERFETCH_MULTIPLIER = 2
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Default limit for memory search queries
|
|
16
|
-
*/
|
|
17
3
|
export const DEFAULT_MEMORY_SEARCH_LIMIT = 10
|
package/src/create-runtime.ts
CHANGED
|
@@ -15,32 +15,45 @@ import { TABLES } from './db/tables'
|
|
|
15
15
|
import type { RedisConnectionManager } from './redis/connection'
|
|
16
16
|
import { createRedisConnectionManager } from './redis/connection'
|
|
17
17
|
import { setRedisConnectionManager } from './redis/index'
|
|
18
|
+
import { closeSharedSubscriber } from './redis/stream-context'
|
|
18
19
|
import type { isApprovalContinuationRequest } from './runtime/approval-continuation'
|
|
19
20
|
import { routeWorkstreamChatMessages } from './runtime/chat-request-routing'
|
|
20
|
-
import
|
|
21
|
+
import { configureGraphDesigner } from './runtime/graph-designer'
|
|
22
|
+
import type { LotaPlugin, SystemNodeExecutor } from './runtime/plugin-types'
|
|
21
23
|
import { configureRuntimeConfig, LOTA_RUNTIME_ENV_KEYS, parseLotaRuntimeConfig } from './runtime/runtime-config'
|
|
22
24
|
import type { LotaRuntimeConfig, ResolvedLotaRuntimeConfig } from './runtime/runtime-config'
|
|
23
25
|
import { configureRuntimeExtensions } from './runtime/runtime-extensions'
|
|
24
26
|
import type { LotaRuntimeWorkers } from './runtime/runtime-worker-registry'
|
|
25
27
|
import { buildRuntimeWorkerRegistry } from './runtime/runtime-worker-registry'
|
|
28
|
+
import type { LotaRuntimeSocialChat } from './runtime/social-chat'
|
|
29
|
+
import { createSocialChatRuntime } from './runtime/social-chat'
|
|
26
30
|
import type { attachmentService } from './services/attachment.service'
|
|
27
31
|
import { attachmentService as attachmentServiceSingleton } from './services/attachment.service'
|
|
32
|
+
import { coordinationRegistryService as coordinationRegistryServiceSingleton } from './services/coordination-registry.service'
|
|
28
33
|
import type { documentChunkService } from './services/document-chunk.service'
|
|
29
34
|
import { documentChunkService as documentChunkServiceSingleton } from './services/document-chunk.service'
|
|
35
|
+
import { domainAgentExecutorService } from './services/domain-agent-executor.service'
|
|
30
36
|
import type { executionPlanService } from './services/execution-plan.service'
|
|
31
37
|
import { executionPlanService as executionPlanServiceSingleton } from './services/execution-plan.service'
|
|
32
38
|
import type { memoryService } from './services/memory.service'
|
|
33
39
|
import { memoryService as memoryServiceSingleton } from './services/memory.service'
|
|
34
40
|
import type { verifyMutatingApproval } from './services/mutating-approval.service'
|
|
35
41
|
import { verifyMutatingApproval as verifyMutatingApprovalSingleton } from './services/mutating-approval.service'
|
|
42
|
+
import { configureNotificationService } from './services/notification.service'
|
|
36
43
|
import type { organizationMemberService } from './services/organization-member.service'
|
|
37
44
|
import { organizationMemberService as organizationMemberServiceSingleton } from './services/organization-member.service'
|
|
38
45
|
import type { organizationService } from './services/organization.service'
|
|
39
46
|
import { organizationService as organizationServiceSingleton } from './services/organization.service'
|
|
47
|
+
import { playbookRegistryService } from './services/playbook-registry.service'
|
|
40
48
|
import type { recentActivityTitleService } from './services/recent-activity-title.service'
|
|
41
49
|
import { recentActivityTitleService as recentActivityTitleServiceSingleton } from './services/recent-activity-title.service'
|
|
42
50
|
import type { recentActivityService } from './services/recent-activity.service'
|
|
43
51
|
import { recentActivityService as recentActivityServiceSingleton } from './services/recent-activity.service'
|
|
52
|
+
import {
|
|
53
|
+
configureSocialChatHistory,
|
|
54
|
+
socialChatHistoryService as socialChatHistoryServiceSingleton,
|
|
55
|
+
} from './services/social-chat-history.service'
|
|
56
|
+
import { getBuiltInSystemExecutors } from './services/system-executor.service'
|
|
44
57
|
import type { userService } from './services/user.service'
|
|
45
58
|
import { userService as userServiceSingleton } from './services/user.service'
|
|
46
59
|
import type { workstreamMessageService } from './services/workstream-message.service'
|
|
@@ -75,6 +88,24 @@ type UnarchiveSdkWorkstream = (
|
|
|
75
88
|
status?: 'regular',
|
|
76
89
|
) => ReturnType<typeof workstreamServiceSingleton.updateStatus>
|
|
77
90
|
|
|
91
|
+
let activeRuntimeToken: symbol | null = null
|
|
92
|
+
|
|
93
|
+
function claimRuntimeToken(): symbol {
|
|
94
|
+
if (activeRuntimeToken) {
|
|
95
|
+
throw new Error('createLotaRuntime() is process-scoped. Disconnect the active runtime before creating another one.')
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const token = Symbol('lota-runtime')
|
|
99
|
+
activeRuntimeToken = token
|
|
100
|
+
return token
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function releaseRuntimeToken(token: symbol) {
|
|
104
|
+
if (activeRuntimeToken === token) {
|
|
105
|
+
activeRuntimeToken = null
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
78
109
|
export interface LotaRuntime {
|
|
79
110
|
services: {
|
|
80
111
|
database: SurrealDBService
|
|
@@ -90,6 +121,7 @@ export interface LotaRuntime {
|
|
|
90
121
|
userService: typeof userService
|
|
91
122
|
recentActivityService: typeof recentActivityService
|
|
92
123
|
recentActivityTitleService: typeof recentActivityTitleService
|
|
124
|
+
socialChatHistoryService: typeof socialChatHistoryServiceSingleton
|
|
93
125
|
executionPlanService: typeof executionPlanService
|
|
94
126
|
workstreamMessageService: typeof workstreamMessageService
|
|
95
127
|
workstreamService: typeof workstreamService
|
|
@@ -99,6 +131,7 @@ export interface LotaRuntime {
|
|
|
99
131
|
createWorkstreamTurnStream: typeof createWorkstreamTurnStream
|
|
100
132
|
isApprovalContinuationRequest: typeof isApprovalContinuationRequest
|
|
101
133
|
runWorkstreamTurnInBackground: typeof runWorkstreamTurnInBackground
|
|
134
|
+
syncPlaybookTemplates: typeof playbookRegistryService.syncPlaybookTemplates
|
|
102
135
|
}
|
|
103
136
|
lota: {
|
|
104
137
|
organizations: {
|
|
@@ -158,205 +191,263 @@ export interface LotaRuntime {
|
|
|
158
191
|
closeConnection: () => Promise<void>
|
|
159
192
|
}
|
|
160
193
|
workers: LotaRuntimeWorkers
|
|
194
|
+
socialChat: LotaRuntimeSocialChat
|
|
161
195
|
schemaFiles: Array<string | URL>
|
|
162
196
|
contributions: { envKeys: readonly string[]; schemaFiles: Array<string | URL> }
|
|
163
197
|
config: ResolvedLotaRuntimeConfig
|
|
164
198
|
plugins: Record<string, LotaPlugin>
|
|
199
|
+
systemExecutors: Record<string, SystemNodeExecutor>
|
|
165
200
|
connectPluginDatabases(): Promise<void>
|
|
166
201
|
connect(): Promise<void>
|
|
167
202
|
disconnect(): Promise<void>
|
|
168
203
|
}
|
|
169
204
|
|
|
170
205
|
export async function createLotaRuntime(config: LotaRuntimeConfig): Promise<LotaRuntime> {
|
|
171
|
-
const
|
|
172
|
-
|
|
206
|
+
const runtimeToken = claimRuntimeToken()
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const resolvedConfig = parseLotaRuntimeConfig(config)
|
|
210
|
+
const systemExecutors = { ...getBuiltInSystemExecutors(), ...resolvedConfig.systemExecutors }
|
|
211
|
+
const runtimeConfig = { ...resolvedConfig, systemExecutors } satisfies ResolvedLotaRuntimeConfig
|
|
212
|
+
configureRuntimeConfig(runtimeConfig)
|
|
173
213
|
|
|
174
|
-
|
|
214
|
+
await configureLotaLogger(runtimeConfig.logging.level)
|
|
175
215
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
216
|
+
const db = new SurrealDBServiceClass({
|
|
217
|
+
url: runtimeConfig.database.url,
|
|
218
|
+
namespace: runtimeConfig.database.namespace,
|
|
219
|
+
database: LOTA_SDK_DATABASE_NAME,
|
|
220
|
+
username: runtimeConfig.database.username,
|
|
221
|
+
password: runtimeConfig.database.password,
|
|
222
|
+
})
|
|
223
|
+
setDatabaseService(db)
|
|
184
224
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
225
|
+
const redisManager = createRedisConnectionManager({ url: runtimeConfig.redis.url })
|
|
226
|
+
setRedisConnectionManager(redisManager)
|
|
227
|
+
configureEmbeddingCache(redisManager.getConnection(), runtimeConfig.memory.embeddingCacheTtlSeconds)
|
|
228
|
+
configureBackgroundProcessing(runtimeConfig.backgroundProcessing)
|
|
229
|
+
configureSocialChatHistory({ keyPrefix: runtimeConfig.socialChat?.historyRedisKeyPrefix })
|
|
189
230
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
configureAgentFactory({
|
|
199
|
-
createAgent: resolvedConfig.agents.createAgent,
|
|
200
|
-
buildAgentTools: resolvedConfig.agents.buildAgentTools,
|
|
201
|
-
getAgentRuntimeConfig: resolvedConfig.agents.getAgentRuntimeConfig,
|
|
202
|
-
pluginRuntime: resolvedConfig.pluginRuntime,
|
|
203
|
-
})
|
|
204
|
-
configureWorkstreams({ agentRoster: resolvedConfig.agents.roster, config: resolvedConfig.workstreams })
|
|
205
|
-
configureRuntimeExtensions({
|
|
206
|
-
adapters: resolvedConfig.runtimeAdapters,
|
|
207
|
-
turnHooks: resolvedConfig.turnHooks,
|
|
208
|
-
toolProviders: (resolvedConfig.toolProviders ?? {}) as never,
|
|
209
|
-
extraWorkers: resolvedConfig.extraWorkers,
|
|
210
|
-
})
|
|
231
|
+
const socialChatAgentId = runtimeConfig.socialChat?.agentId?.trim() || 'socialChat'
|
|
232
|
+
const socialChatAgentDisplayName = runtimeConfig.socialChat?.agentDisplayName?.trim() || 'Lota'
|
|
233
|
+
if (runtimeConfig.socialChat && !runtimeConfig.agents.roster.includes(socialChatAgentId)) {
|
|
234
|
+
throw new Error(`socialChat.agentId must be present in agents.roster: ${socialChatAgentId}`)
|
|
235
|
+
}
|
|
236
|
+
const agentDisplayNames = runtimeConfig.socialChat
|
|
237
|
+
? { ...runtimeConfig.agents.displayNames, [socialChatAgentId]: socialChatAgentDisplayName }
|
|
238
|
+
: runtimeConfig.agents.displayNames
|
|
211
239
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
240
|
+
configureAgents({
|
|
241
|
+
roster: runtimeConfig.agents.roster,
|
|
242
|
+
leadAgentId: runtimeConfig.agents.leadAgentId,
|
|
243
|
+
displayNames: agentDisplayNames,
|
|
244
|
+
shortDisplayNames: runtimeConfig.agents.shortDisplayNames,
|
|
245
|
+
teamConsultParticipants: runtimeConfig.agents.teamConsultParticipants,
|
|
246
|
+
getCoreWorkstreamProfile: runtimeConfig.agents.getCoreWorkstreamProfile,
|
|
247
|
+
})
|
|
248
|
+
configureAgentFactory({
|
|
249
|
+
createAgent: runtimeConfig.agents.createAgent,
|
|
250
|
+
buildAgentTools: runtimeConfig.agents.buildAgentTools,
|
|
251
|
+
getAgentRuntimeConfig: runtimeConfig.agents.getAgentRuntimeConfig,
|
|
252
|
+
pluginRuntime: runtimeConfig.pluginRuntime,
|
|
253
|
+
})
|
|
254
|
+
configureWorkstreams({ agentRoster: runtimeConfig.agents.roster, config: runtimeConfig.workstreams })
|
|
255
|
+
configureNotificationService(runtimeConfig.notificationService ?? null)
|
|
256
|
+
configureRuntimeExtensions({
|
|
257
|
+
adapters: runtimeConfig.runtimeAdapters,
|
|
258
|
+
turnHooks: runtimeConfig.turnHooks,
|
|
259
|
+
toolProviders: (runtimeConfig.toolProviders ?? {}) as never,
|
|
260
|
+
extraWorkers: runtimeConfig.extraWorkers,
|
|
261
|
+
})
|
|
219
262
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
list: organizationServiceSingleton.listOrganizations.bind(organizationServiceSingleton),
|
|
226
|
-
update: organizationServiceSingleton.updateOrganization.bind(organizationServiceSingleton),
|
|
227
|
-
delete: organizationServiceSingleton.deleteOrganization.bind(organizationServiceSingleton),
|
|
228
|
-
},
|
|
229
|
-
users: {
|
|
230
|
-
upsert: userServiceSingleton.upsertUser.bind(userServiceSingleton),
|
|
231
|
-
get: userServiceSingleton.getUser.bind(userServiceSingleton),
|
|
232
|
-
list: userServiceSingleton.listUsers.bind(userServiceSingleton),
|
|
233
|
-
update: userServiceSingleton.updateUser.bind(userServiceSingleton),
|
|
234
|
-
delete: userServiceSingleton.deleteUser.bind(userServiceSingleton),
|
|
235
|
-
},
|
|
236
|
-
memberships: {
|
|
237
|
-
add: organizationMemberServiceSingleton.addMembership.bind(organizationMemberServiceSingleton),
|
|
238
|
-
listForOrganization: organizationMemberServiceSingleton.listMembershipsForOrganization.bind(
|
|
239
|
-
organizationMemberServiceSingleton,
|
|
240
|
-
),
|
|
241
|
-
listForUser: organizationMemberServiceSingleton.listMembershipsForUser.bind(organizationMemberServiceSingleton),
|
|
242
|
-
remove: organizationMemberServiceSingleton.removeMembership.bind(organizationMemberServiceSingleton),
|
|
243
|
-
isMember: organizationMemberServiceSingleton.isMember.bind(organizationMemberServiceSingleton),
|
|
244
|
-
},
|
|
245
|
-
workstreams: {
|
|
246
|
-
create: workstreamServiceSingleton.createWorkstream.bind(workstreamServiceSingleton),
|
|
247
|
-
list: workstreamServiceSingleton.listWorkstreams.bind(workstreamServiceSingleton),
|
|
248
|
-
get: workstreamServiceSingleton.getWorkstream.bind(workstreamServiceSingleton),
|
|
249
|
-
update: workstreamServiceSingleton.updateTitle.bind(workstreamServiceSingleton),
|
|
250
|
-
archive: async (workstreamId, status = 'archived') =>
|
|
251
|
-
await workstreamServiceSingleton.updateStatus(workstreamId, status),
|
|
252
|
-
unarchive: async (workstreamId, status = 'regular') =>
|
|
253
|
-
await workstreamServiceSingleton.updateStatus(workstreamId, status),
|
|
254
|
-
delete: workstreamServiceSingleton.deleteWorkstream.bind(workstreamServiceSingleton),
|
|
255
|
-
stop: workstreamServiceSingleton.stopActiveRun.bind(workstreamServiceSingleton),
|
|
256
|
-
listMessages: workstreamMessageServiceSingleton.listMessageHistoryPage.bind(workstreamMessageServiceSingleton),
|
|
257
|
-
getMessage: async ({ workstreamId, messageId }) => {
|
|
258
|
-
const messages = await workstreamMessageServiceSingleton.listMessages(
|
|
259
|
-
ensureRecordId(workstreamId, TABLES.WORKSTREAM),
|
|
260
|
-
)
|
|
261
|
-
const message = messages.find((candidate) => candidate.id === messageId)
|
|
262
|
-
if (!message) {
|
|
263
|
-
throw new Error(`Workstream message not found: ${messageId}`)
|
|
264
|
-
}
|
|
265
|
-
return message
|
|
266
|
-
},
|
|
267
|
-
sendMessage: async ({ workstreamId, organizationId, userId, userName, messages }) => {
|
|
268
|
-
const workstreamRef = ensureRecordId(workstreamId, TABLES.WORKSTREAM)
|
|
269
|
-
const workstream = await workstreamServiceSingleton.getWorkstream(workstreamRef)
|
|
270
|
-
const routed = routeWorkstreamChatMessages(messages)
|
|
271
|
-
if (routed.kind !== 'turn') {
|
|
272
|
-
throw new Error(routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.')
|
|
273
|
-
}
|
|
263
|
+
const pluginRuntime = runtimeConfig.pluginRuntime ?? {}
|
|
264
|
+
domainAgentExecutorService.configure(pluginRuntime)
|
|
265
|
+
if (runtimeConfig.graphDesigner) {
|
|
266
|
+
configureGraphDesigner(runtimeConfig.graphDesigner)
|
|
267
|
+
}
|
|
274
268
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
269
|
+
for (const [pluginRef, plugin] of Object.entries(pluginRuntime)) {
|
|
270
|
+
const signals = plugin.contributions.signals
|
|
271
|
+
if (signals && signals.length > 0) {
|
|
272
|
+
coordinationRegistryServiceSingleton.register(pluginRef, [...signals])
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
coordinationRegistryServiceSingleton.validate()
|
|
276
|
+
// Collect playbook contributions early to fail fast on misconfiguration
|
|
277
|
+
playbookRegistryService.collectPlaybooks()
|
|
278
|
+
|
|
279
|
+
const pluginContributions = Object.values(pluginRuntime).map((plugin) => plugin.contributions)
|
|
280
|
+
const schemaFiles = [...getBuiltInSchemaFiles(), ...(runtimeConfig.extraSchemaFiles ?? [])]
|
|
281
|
+
const hostContributionSchemaFiles = pluginContributions.flatMap((plugin) => plugin.schemaFiles)
|
|
282
|
+
const contributionEnvKeys = [...LOTA_RUNTIME_ENV_KEYS, ...pluginContributions.flatMap((plugin) => plugin.envKeys)]
|
|
283
|
+
const connectPluginDatabases = createPluginDatabaseConnector(pluginRuntime)
|
|
284
|
+
const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
|
|
285
|
+
const socialChat = createSocialChatRuntime({
|
|
286
|
+
redisClient: redisManager.getConnection(),
|
|
287
|
+
socialChat: runtimeConfig.socialChat,
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
const lota = {
|
|
291
|
+
organizations: {
|
|
292
|
+
create: organizationServiceSingleton.createOrganization.bind(organizationServiceSingleton),
|
|
293
|
+
upsert: organizationServiceSingleton.upsertOrganization.bind(organizationServiceSingleton),
|
|
294
|
+
get: organizationServiceSingleton.getOrganization.bind(organizationServiceSingleton),
|
|
295
|
+
list: organizationServiceSingleton.listOrganizations.bind(organizationServiceSingleton),
|
|
296
|
+
update: organizationServiceSingleton.updateOrganization.bind(organizationServiceSingleton),
|
|
297
|
+
delete: organizationServiceSingleton.deleteOrganization.bind(organizationServiceSingleton),
|
|
298
|
+
},
|
|
299
|
+
users: {
|
|
300
|
+
upsert: userServiceSingleton.upsertUser.bind(userServiceSingleton),
|
|
301
|
+
get: userServiceSingleton.getUser.bind(userServiceSingleton),
|
|
302
|
+
list: userServiceSingleton.listUsers.bind(userServiceSingleton),
|
|
303
|
+
update: userServiceSingleton.updateUser.bind(userServiceSingleton),
|
|
304
|
+
delete: userServiceSingleton.deleteUser.bind(userServiceSingleton),
|
|
283
305
|
},
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
306
|
+
memberships: {
|
|
307
|
+
add: organizationMemberServiceSingleton.addMembership.bind(organizationMemberServiceSingleton),
|
|
308
|
+
listForOrganization: organizationMemberServiceSingleton.listMembershipsForOrganization.bind(
|
|
309
|
+
organizationMemberServiceSingleton,
|
|
310
|
+
),
|
|
311
|
+
listForUser: organizationMemberServiceSingleton.listMembershipsForUser.bind(organizationMemberServiceSingleton),
|
|
312
|
+
remove: organizationMemberServiceSingleton.removeMembership.bind(organizationMemberServiceSingleton),
|
|
313
|
+
isMember: organizationMemberServiceSingleton.isMember.bind(organizationMemberServiceSingleton),
|
|
314
|
+
},
|
|
315
|
+
workstreams: {
|
|
316
|
+
create: workstreamServiceSingleton.createWorkstream.bind(workstreamServiceSingleton),
|
|
317
|
+
list: workstreamServiceSingleton.listWorkstreams.bind(workstreamServiceSingleton),
|
|
318
|
+
get: workstreamServiceSingleton.getWorkstream.bind(workstreamServiceSingleton),
|
|
319
|
+
update: workstreamServiceSingleton.updateTitle.bind(workstreamServiceSingleton),
|
|
320
|
+
archive: async (workstreamId, status = 'archived') =>
|
|
321
|
+
await workstreamServiceSingleton.updateStatus(workstreamId, status),
|
|
322
|
+
unarchive: async (workstreamId, status = 'regular') =>
|
|
323
|
+
await workstreamServiceSingleton.updateStatus(workstreamId, status),
|
|
324
|
+
delete: workstreamServiceSingleton.deleteWorkstream.bind(workstreamServiceSingleton),
|
|
325
|
+
stop: workstreamServiceSingleton.stopActiveRun.bind(workstreamServiceSingleton),
|
|
326
|
+
listMessages: workstreamMessageServiceSingleton.listMessageHistoryPage.bind(workstreamMessageServiceSingleton),
|
|
327
|
+
getMessage: async ({ workstreamId, messageId }) => {
|
|
328
|
+
const messages = await workstreamMessageServiceSingleton.listMessages(
|
|
329
|
+
ensureRecordId(workstreamId, TABLES.WORKSTREAM),
|
|
291
330
|
)
|
|
292
|
-
|
|
331
|
+
const message = messages.find((candidate) => candidate.id === messageId)
|
|
332
|
+
if (!message) {
|
|
333
|
+
throw new Error(`Workstream message not found: ${messageId}`)
|
|
334
|
+
}
|
|
335
|
+
return message
|
|
336
|
+
},
|
|
337
|
+
sendMessage: async ({ workstreamId, organizationId, userId, userName, messages }) => {
|
|
338
|
+
const workstreamRef = ensureRecordId(workstreamId, TABLES.WORKSTREAM)
|
|
339
|
+
const workstream = await workstreamServiceSingleton.getWorkstream(workstreamRef)
|
|
340
|
+
const routed = routeWorkstreamChatMessages(messages)
|
|
341
|
+
if (routed.kind !== 'turn') {
|
|
342
|
+
throw new Error(routed.kind === 'invalid' ? routed.message : 'Expected a user turn payload.')
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return createWorkstreamTurnStreamSingleton({
|
|
346
|
+
workstream,
|
|
347
|
+
workstreamRef,
|
|
348
|
+
orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
|
|
349
|
+
userRef: ensureRecordId(userId, TABLES.USER),
|
|
350
|
+
userName,
|
|
351
|
+
inputMessage: routed.inputMessage,
|
|
352
|
+
})
|
|
353
|
+
},
|
|
354
|
+
continueApproval: async ({ workstreamId, organizationId, userId, userName, messages }) => {
|
|
355
|
+
const workstreamRef = ensureRecordId(workstreamId, TABLES.WORKSTREAM)
|
|
356
|
+
const workstream = await workstreamServiceSingleton.getWorkstream(workstreamRef)
|
|
357
|
+
const routed = routeWorkstreamChatMessages(messages)
|
|
358
|
+
if (routed.kind !== 'approval-continuation') {
|
|
359
|
+
throw new Error(
|
|
360
|
+
routed.kind === 'invalid' ? routed.message : 'Expected approval continuation messages payload.',
|
|
361
|
+
)
|
|
362
|
+
}
|
|
293
363
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
364
|
+
return createWorkstreamApprovalContinuationStreamSingleton({
|
|
365
|
+
workstream,
|
|
366
|
+
workstreamRef,
|
|
367
|
+
orgRef: ensureRecordId(organizationId, TABLES.ORGANIZATION),
|
|
368
|
+
userRef: ensureRecordId(userId, TABLES.USER),
|
|
369
|
+
userName,
|
|
370
|
+
approvalMessages: routed.approvalMessages,
|
|
371
|
+
})
|
|
372
|
+
},
|
|
373
|
+
uploadAttachment: attachmentServiceSingleton.uploadWorkstreamAttachment.bind(attachmentServiceSingleton),
|
|
302
374
|
},
|
|
303
|
-
|
|
304
|
-
},
|
|
305
|
-
} satisfies LotaRuntime['lota']
|
|
375
|
+
} satisfies LotaRuntime['lota']
|
|
306
376
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
377
|
+
let disconnected = false
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
services: {
|
|
381
|
+
database: db,
|
|
382
|
+
redis: redisManager,
|
|
383
|
+
closeRedisConnection: async () => await redisManager.closeConnection(),
|
|
384
|
+
attachmentService: attachmentServiceSingleton,
|
|
385
|
+
documentChunkService: documentChunkServiceSingleton,
|
|
386
|
+
generatedDocumentStorageService: generatedDocumentStorageServiceSingleton,
|
|
387
|
+
memoryService: memoryServiceSingleton,
|
|
388
|
+
verifyMutatingApproval: verifyMutatingApprovalSingleton,
|
|
389
|
+
organizationService: organizationServiceSingleton,
|
|
390
|
+
organizationMemberService: organizationMemberServiceSingleton,
|
|
391
|
+
userService: userServiceSingleton,
|
|
392
|
+
recentActivityService: recentActivityServiceSingleton,
|
|
393
|
+
recentActivityTitleService: recentActivityTitleServiceSingleton,
|
|
394
|
+
socialChatHistoryService: socialChatHistoryServiceSingleton,
|
|
395
|
+
executionPlanService: executionPlanServiceSingleton,
|
|
396
|
+
workstreamMessageService: workstreamMessageServiceSingleton,
|
|
397
|
+
workstreamService: workstreamServiceSingleton,
|
|
398
|
+
workstreamTitleService: workstreamTitleServiceSingleton,
|
|
399
|
+
createWorkstreamApprovalContinuationStream: createWorkstreamApprovalContinuationStreamSingleton,
|
|
400
|
+
createWorkstreamNativeToolApprovalStream: createWorkstreamNativeToolApprovalStreamSingleton,
|
|
401
|
+
createWorkstreamTurnStream: createWorkstreamTurnStreamSingleton,
|
|
402
|
+
isApprovalContinuationRequest: isApprovalContinuationRequestSingleton,
|
|
403
|
+
runWorkstreamTurnInBackground: runWorkstreamTurnInBackgroundSingleton,
|
|
404
|
+
syncPlaybookTemplates: playbookRegistryService.syncPlaybookTemplates.bind(playbookRegistryService),
|
|
405
|
+
},
|
|
406
|
+
lota,
|
|
407
|
+
redis: {
|
|
408
|
+
manager: redisManager,
|
|
409
|
+
getConnection: () => redisManager.getConnection(),
|
|
410
|
+
getConnectionForBullMQ: () => redisManager.getConnectionForBullMQ(),
|
|
411
|
+
closeConnection: async () => await redisManager.closeConnection(),
|
|
412
|
+
},
|
|
413
|
+
workers,
|
|
414
|
+
socialChat,
|
|
415
|
+
schemaFiles,
|
|
416
|
+
contributions: { envKeys: [...new Set(contributionEnvKeys)], schemaFiles: hostContributionSchemaFiles },
|
|
417
|
+
config: runtimeConfig,
|
|
418
|
+
plugins: pluginRuntime,
|
|
419
|
+
systemExecutors,
|
|
420
|
+
async connectPluginDatabases() {
|
|
421
|
+
await connectPluginDatabases()
|
|
422
|
+
},
|
|
423
|
+
async connect() {
|
|
424
|
+
await db.connect()
|
|
425
|
+
const bunFiles = schemaFiles.map((schemaFile) =>
|
|
426
|
+
schemaFile instanceof URL ? Bun.file(schemaFile.pathname) : Bun.file(schemaFile),
|
|
427
|
+
)
|
|
428
|
+
await db.applySchema(bunFiles)
|
|
429
|
+
const schemaFingerprint = await computeSchemaFingerprint(schemaFiles)
|
|
430
|
+
await publishDatabaseBootstrap({ databaseService: db, schemaFingerprint })
|
|
431
|
+
},
|
|
432
|
+
async disconnect() {
|
|
433
|
+
if (disconnected) {
|
|
434
|
+
return
|
|
435
|
+
}
|
|
436
|
+
disconnected = true
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
await socialChat.shutdown()
|
|
440
|
+
await closeSharedSubscriber()
|
|
441
|
+
await db.disconnect()
|
|
442
|
+
await redisManager.closeConnection()
|
|
443
|
+
} finally {
|
|
444
|
+
releaseRuntimeToken(runtimeToken)
|
|
445
|
+
}
|
|
446
|
+
},
|
|
447
|
+
}
|
|
448
|
+
} catch (error) {
|
|
449
|
+
releaseRuntimeToken(runtimeToken)
|
|
450
|
+
throw error
|
|
360
451
|
}
|
|
361
452
|
}
|
|
362
453
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { toTimestamp } from '@lota-sdk/shared'
|
|
2
1
|
import type { ChatMessage } from '@lota-sdk/shared'
|
|
3
2
|
import type { BoundQuery, RecordId } from 'surrealdb'
|
|
4
3
|
import { z } from 'zod'
|
|
@@ -7,7 +6,7 @@ import type { RecordIdRef } from './record-id'
|
|
|
7
6
|
import { databaseService } from './service'
|
|
8
7
|
import type { DatabaseTable } from './tables'
|
|
9
8
|
|
|
10
|
-
export const CursorRowSchema = z.object({ createdAt: z.
|
|
9
|
+
export const CursorRowSchema = z.object({ createdAt: z.coerce.date() })
|
|
11
10
|
|
|
12
11
|
export interface MessageHistoryPage {
|
|
13
12
|
messages: ChatMessage[]
|
|
@@ -64,10 +63,8 @@ async function listRowsBefore(
|
|
|
64
63
|
throw new Error(`Cursor message not found in ${config.table}: ${params.beforeMessageId}`)
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
const cursorCreatedAt =
|
|
66
|
+
const cursorCreatedAt = cursorRow.createdAt
|
|
68
67
|
const cursorId = config.toRowId(params.parentId, params.beforeMessageId)
|
|
69
68
|
|
|
70
|
-
return
|
|
71
|
-
config.queryBefore(params.parentId, cursorCreatedAt, cursorId, params.take),
|
|
72
|
-
)
|
|
69
|
+
return databaseService.query<unknown>(config.queryBefore(params.parentId, cursorCreatedAt, cursorId, params.take))
|
|
73
70
|
}
|
package/src/db/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './base.service'
|
|
1
2
|
export * from './cursor-pagination'
|
|
2
3
|
export * from './memory'
|
|
3
4
|
export * from './memory-store'
|
|
@@ -7,4 +8,5 @@ export * from './record-id'
|
|
|
7
8
|
export * from './sdk-database'
|
|
8
9
|
export * from './service'
|
|
9
10
|
export * from './startup'
|
|
11
|
+
export * from './surreal-mutation'
|
|
10
12
|
export * from './tables'
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto'
|
|
2
|
-
|
|
3
1
|
import type { BasicSearchRow, SurrealMemoryRow } from './memory-store.rows'
|
|
4
2
|
import type { MemoryRecord, MemorySearchResult } from './memory-types'
|
|
5
3
|
import { recordIdToString } from './record-id'
|
|
@@ -114,5 +112,5 @@ export function processGraphAwareRows<T extends BasicSearchRow>(
|
|
|
114
112
|
}
|
|
115
113
|
|
|
116
114
|
export function hashContent(content: string, scopeId: string, memoryType: string): string {
|
|
117
|
-
return
|
|
115
|
+
return new Bun.CryptoHasher('sha256').update(`${scopeId}:${memoryType}:${content}`).digest('hex')
|
|
118
116
|
}
|
|
@@ -13,17 +13,17 @@ export interface SurrealMemoryRow {
|
|
|
13
13
|
importance: number
|
|
14
14
|
accessCount: number
|
|
15
15
|
needsReview: boolean
|
|
16
|
-
lastAccessedAt?: Date
|
|
17
|
-
createdAt: Date
|
|
18
|
-
updatedAt?: Date
|
|
19
|
-
validFrom: Date
|
|
20
|
-
validUntil?: Date
|
|
21
|
-
archivedAt?: Date
|
|
16
|
+
lastAccessedAt?: Date
|
|
17
|
+
createdAt: Date
|
|
18
|
+
updatedAt?: Date
|
|
19
|
+
validFrom: Date
|
|
20
|
+
validUntil?: Date
|
|
21
|
+
archivedAt?: Date
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export interface BasicSearchRow {
|
|
25
25
|
id: RecordIdInput
|
|
26
26
|
content: string
|
|
27
27
|
metadata: Record<string, unknown>
|
|
28
|
-
createdAt?: Date
|
|
28
|
+
createdAt?: Date
|
|
29
29
|
}
|