@lota-sdk/core 0.1.5 → 0.1.7

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.
Files changed (36) hide show
  1. package/infrastructure/schema/00_identity.surql +26 -0
  2. package/infrastructure/schema/00_workstream.surql +8 -0
  3. package/infrastructure/schema/05_recent_activity.surql +48 -0
  4. package/package.json +4 -3
  5. package/src/ai/embedding-cache.ts +48 -0
  6. package/src/config/background-processing.ts +33 -0
  7. package/src/config/env-shapes.ts +0 -1
  8. package/src/config/model-constants.ts +4 -0
  9. package/src/db/memory-store.ts +110 -19
  10. package/src/db/memory-types.ts +11 -0
  11. package/src/db/memory.ts +11 -1
  12. package/src/db/schema-fingerprint.ts +21 -0
  13. package/src/db/sdk-database.ts +1 -0
  14. package/src/db/service.ts +0 -4
  15. package/src/db/tables.ts +1 -1
  16. package/src/index.ts +207 -10
  17. package/src/queues/memory-consolidation.queue.ts +6 -0
  18. package/src/queues/workstream-title-generation.queue.ts +69 -0
  19. package/src/runtime/agent-types.ts +5 -22
  20. package/src/runtime/helper-model.ts +9 -2
  21. package/src/runtime/memory-digest-policy.ts +30 -2
  22. package/src/runtime/skill-extraction-policy.ts +9 -2
  23. package/src/services/memory.service.ts +35 -0
  24. package/src/services/organization-member.service.ts +114 -0
  25. package/src/services/organization.service.ts +117 -0
  26. package/src/services/user.service.ts +56 -0
  27. package/src/services/workstream-title.service.ts +25 -35
  28. package/src/services/workstream-turn-preparation.ts +37 -10
  29. package/src/services/workstream-turn.ts +2 -0
  30. package/src/services/workstream.service.ts +61 -1
  31. package/src/services/workstream.types.ts +3 -0
  32. package/src/system-agents/title-generator.agent.ts +5 -5
  33. package/src/tools/research-topic.tool.ts +5 -1
  34. package/src/utils/sse-keepalive.ts +40 -0
  35. package/src/workers/bootstrap.ts +26 -1
  36. package/src/workers/memory-consolidation.worker.ts +1 -9
@@ -0,0 +1,40 @@
1
+ const KEEPALIVE_COMMENT = new TextEncoder().encode(': keepalive\n\n')
2
+ const DEFAULT_KEEPALIVE_INTERVAL_MS = 20_000
3
+
4
+ /**
5
+ * Wraps an SSE Response body with periodic keepalive comments.
6
+ * SSE comments (`: keepalive\n\n`) are ignored by standard SSE parsers,
7
+ * so no client changes are needed.
8
+ */
9
+ export function wrapResponseWithKeepalive(response: Response, intervalMs = DEFAULT_KEEPALIVE_INTERVAL_MS): Response {
10
+ const body = response.body
11
+ if (!body) return response
12
+
13
+ let intervalHandle: ReturnType<typeof setInterval> | null = null
14
+
15
+ const transformed = body.pipeThrough(
16
+ new TransformStream<Uint8Array, Uint8Array>({
17
+ start(controller) {
18
+ intervalHandle = setInterval(() => {
19
+ try {
20
+ controller.enqueue(KEEPALIVE_COMMENT)
21
+ } catch {
22
+ if (intervalHandle) clearInterval(intervalHandle)
23
+ }
24
+ }, intervalMs)
25
+ },
26
+ transform(chunk, controller) {
27
+ controller.enqueue(chunk)
28
+ },
29
+ flush() {
30
+ if (intervalHandle) clearInterval(intervalHandle)
31
+ },
32
+ }),
33
+ )
34
+
35
+ return new Response(transformed, {
36
+ headers: response.headers,
37
+ status: response.status,
38
+ statusText: response.statusText,
39
+ })
40
+ }
@@ -1,8 +1,31 @@
1
1
  import { configureLogger, serverLogger } from '../config/logger'
2
- import { databaseService } from '../db/service'
2
+ import { LOTA_SDK_DATABASE_NAME } from '../db/sdk-database'
3
+ import { SurrealDBService, databaseService, setDatabaseService } from '../db/service'
3
4
  import { connectWithStartupRetry, waitForDatabaseBootstrap } from '../db/startup'
4
5
  import { getConfiguredPluginDatabaseConnector } from '../runtime/runtime-extensions'
5
6
 
7
+ /**
8
+ * Sandboxed BullMQ workers run in separate child processes where createLotaRuntime
9
+ * was never called, so the global databaseService proxy has no backing instance.
10
+ * Create one from env vars so the proxy resolves.
11
+ */
12
+ function getRequiredEnv(key: string): string {
13
+ const value = process.env[key]
14
+ if (!value) throw new Error(`Missing required env var: ${key}`)
15
+ return value
16
+ }
17
+
18
+ function ensureDatabaseServiceConfigured(): void {
19
+ const db = new SurrealDBService({
20
+ url: getRequiredEnv('SURREALDB_URL'),
21
+ namespace: getRequiredEnv('SURREALDB_NAMESPACE'),
22
+ database: LOTA_SDK_DATABASE_NAME,
23
+ username: process.env.SURREALDB_USER,
24
+ password: process.env.SURREALDB_PASSWORD,
25
+ })
26
+ setDatabaseService(db)
27
+ }
28
+
6
29
  let sandboxedWorkerRuntimePromise: Promise<void> | null = null
7
30
 
8
31
  export async function initializeSandboxedWorkerRuntime(): Promise<void> {
@@ -14,6 +37,8 @@ export async function initializeSandboxedWorkerRuntime(): Promise<void> {
14
37
  sandboxedWorkerRuntimePromise = (async () => {
15
38
  await configureLogger()
16
39
 
40
+ ensureDatabaseServiceConfigured()
41
+
17
42
  await connectWithStartupRetry({
18
43
  connect: () => databaseService.connect(),
19
44
  label: 'sandboxed worker AI database runtime',
@@ -276,13 +276,6 @@ async function cleanupOrphanedRelations(): Promise<number> {
276
276
  return result[0]?.count ?? 0
277
277
  }
278
278
 
279
- async function pruneOldOrgActions(): Promise<number> {
280
- const result = await databaseService.query<{ count: number }>(
281
- new BoundQuery(`DELETE ${TABLES.ORG_ACTION} WHERE createdAt < time::now() - 90d RETURN count() AS count`),
282
- )
283
- return result[0]?.count ?? 0
284
- }
285
-
286
279
  const handler = async (job: SandboxedJob<MemoryConsolidationJob>) => {
287
280
  const targetScope = job.data.scopeId
288
281
 
@@ -305,9 +298,8 @@ const handler = async (job: SandboxedJob<MemoryConsolidationJob>) => {
305
298
  const collapsed = await collapseSupersedeCh()
306
299
  const decayed = await decayImportance()
307
300
  const orphaned = await cleanupOrphanedRelations()
308
- const prunedActions = await pruneOldOrgActions()
309
301
 
310
- serverLogger.info`Memory consolidation complete (merged: ${totalMerged}, pruned: ${pruned}, collapsed: ${collapsed}, decayed: ${decayed}, orphaned relations: ${orphaned}, pruned actions: ${prunedActions})`
302
+ serverLogger.info`Memory consolidation complete (merged: ${totalMerged}, pruned: ${pruned}, collapsed: ${collapsed}, decayed: ${decayed}, orphaned relations: ${orphaned})`
311
303
  } catch (error) {
312
304
  const serialized = toSandboxedWorkerError(error, 'Memory consolidation job failed')
313
305
  serverLogger.error`${serialized.message}`