@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.
- package/infrastructure/schema/00_identity.surql +26 -0
- package/infrastructure/schema/00_workstream.surql +8 -0
- package/infrastructure/schema/05_recent_activity.surql +48 -0
- package/package.json +4 -3
- package/src/ai/embedding-cache.ts +48 -0
- package/src/config/background-processing.ts +33 -0
- package/src/config/env-shapes.ts +0 -1
- package/src/config/model-constants.ts +4 -0
- package/src/db/memory-store.ts +110 -19
- package/src/db/memory-types.ts +11 -0
- package/src/db/memory.ts +11 -1
- package/src/db/schema-fingerprint.ts +21 -0
- package/src/db/sdk-database.ts +1 -0
- package/src/db/service.ts +0 -4
- package/src/db/tables.ts +1 -1
- package/src/index.ts +207 -10
- package/src/queues/memory-consolidation.queue.ts +6 -0
- package/src/queues/workstream-title-generation.queue.ts +69 -0
- package/src/runtime/agent-types.ts +5 -22
- package/src/runtime/helper-model.ts +9 -2
- package/src/runtime/memory-digest-policy.ts +30 -2
- package/src/runtime/skill-extraction-policy.ts +9 -2
- package/src/services/memory.service.ts +35 -0
- package/src/services/organization-member.service.ts +114 -0
- package/src/services/organization.service.ts +117 -0
- package/src/services/user.service.ts +56 -0
- package/src/services/workstream-title.service.ts +25 -35
- package/src/services/workstream-turn-preparation.ts +37 -10
- package/src/services/workstream-turn.ts +2 -0
- package/src/services/workstream.service.ts +61 -1
- package/src/services/workstream.types.ts +3 -0
- package/src/system-agents/title-generator.agent.ts +5 -5
- package/src/tools/research-topic.tool.ts +5 -1
- package/src/utils/sse-keepalive.ts +40 -0
- package/src/workers/bootstrap.ts +26 -1
- 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
|
+
}
|
package/src/workers/bootstrap.ts
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
import { configureLogger, serverLogger } from '../config/logger'
|
|
2
|
-
import {
|
|
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}
|
|
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}`
|