@lota-sdk/core 0.1.5

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 (153) hide show
  1. package/infrastructure/schema/00_workstream.surql +55 -0
  2. package/infrastructure/schema/01_memory.surql +47 -0
  3. package/infrastructure/schema/02_execution_plan.surql +62 -0
  4. package/infrastructure/schema/03_learned_skill.surql +32 -0
  5. package/infrastructure/schema/04_runtime_bootstrap.surql +8 -0
  6. package/package.json +128 -0
  7. package/src/ai/definitions.ts +308 -0
  8. package/src/bifrost/bifrost.ts +256 -0
  9. package/src/config/agent-defaults.ts +99 -0
  10. package/src/config/constants.ts +33 -0
  11. package/src/config/env-shapes.ts +122 -0
  12. package/src/config/logger.ts +29 -0
  13. package/src/config/model-constants.ts +31 -0
  14. package/src/config/search.ts +17 -0
  15. package/src/config/workstream-defaults.ts +68 -0
  16. package/src/db/base.service.ts +55 -0
  17. package/src/db/cursor-pagination.ts +73 -0
  18. package/src/db/memory-query-builder.ts +207 -0
  19. package/src/db/memory-store.helpers.ts +118 -0
  20. package/src/db/memory-store.rows.ts +29 -0
  21. package/src/db/memory-store.ts +974 -0
  22. package/src/db/memory-types.ts +193 -0
  23. package/src/db/memory.ts +505 -0
  24. package/src/db/record-id.ts +78 -0
  25. package/src/db/service.ts +932 -0
  26. package/src/db/startup.ts +152 -0
  27. package/src/db/tables.ts +20 -0
  28. package/src/document/org-document-chunking.ts +224 -0
  29. package/src/document/parsing.ts +40 -0
  30. package/src/embeddings/provider.ts +76 -0
  31. package/src/index.ts +302 -0
  32. package/src/queues/context-compaction.queue.ts +82 -0
  33. package/src/queues/document-processor.queue.ts +118 -0
  34. package/src/queues/memory-consolidation.queue.ts +65 -0
  35. package/src/queues/post-chat-memory.queue.ts +128 -0
  36. package/src/queues/recent-activity-title-refinement.queue.ts +69 -0
  37. package/src/queues/regular-chat-memory-digest.config.ts +12 -0
  38. package/src/queues/regular-chat-memory-digest.queue.ts +73 -0
  39. package/src/queues/skill-extraction.config.ts +9 -0
  40. package/src/queues/skill-extraction.queue.ts +62 -0
  41. package/src/redis/connection.ts +176 -0
  42. package/src/redis/index.ts +30 -0
  43. package/src/redis/org-memory-lock.ts +43 -0
  44. package/src/redis/redis-lease-lock.ts +158 -0
  45. package/src/runtime/agent-contract.ts +1 -0
  46. package/src/runtime/agent-prompt-context.ts +119 -0
  47. package/src/runtime/agent-runtime-policy.ts +192 -0
  48. package/src/runtime/agent-stream-helpers.ts +117 -0
  49. package/src/runtime/agent-types.ts +22 -0
  50. package/src/runtime/approval-continuation.ts +16 -0
  51. package/src/runtime/chat-attachments.ts +46 -0
  52. package/src/runtime/chat-message.ts +10 -0
  53. package/src/runtime/chat-request-routing.ts +21 -0
  54. package/src/runtime/chat-run-orchestration.ts +25 -0
  55. package/src/runtime/chat-run-registry.ts +20 -0
  56. package/src/runtime/chat-types.ts +18 -0
  57. package/src/runtime/context-compaction-constants.ts +11 -0
  58. package/src/runtime/context-compaction-runtime.ts +86 -0
  59. package/src/runtime/context-compaction.ts +909 -0
  60. package/src/runtime/execution-plan.ts +59 -0
  61. package/src/runtime/helper-model.ts +405 -0
  62. package/src/runtime/indexed-repositories-policy.ts +28 -0
  63. package/src/runtime/instruction-sections.ts +8 -0
  64. package/src/runtime/llm-content.ts +71 -0
  65. package/src/runtime/memory-block.ts +264 -0
  66. package/src/runtime/memory-digest-policy.ts +14 -0
  67. package/src/runtime/memory-format.ts +8 -0
  68. package/src/runtime/memory-pipeline.ts +570 -0
  69. package/src/runtime/memory-prompts-fact.ts +47 -0
  70. package/src/runtime/memory-prompts-parse.ts +3 -0
  71. package/src/runtime/memory-prompts-update.ts +37 -0
  72. package/src/runtime/memory-scope.ts +43 -0
  73. package/src/runtime/plugin-types.ts +10 -0
  74. package/src/runtime/retrieval-adapters.ts +25 -0
  75. package/src/runtime/retrieval-pipeline.ts +3 -0
  76. package/src/runtime/runtime-extensions.ts +154 -0
  77. package/src/runtime/skill-extraction-policy.ts +3 -0
  78. package/src/runtime/team-consultation-orchestrator.ts +245 -0
  79. package/src/runtime/team-consultation-prompts.ts +32 -0
  80. package/src/runtime/title-helpers.ts +12 -0
  81. package/src/runtime/turn-lifecycle.ts +28 -0
  82. package/src/runtime/workstream-chat-helpers.ts +187 -0
  83. package/src/runtime/workstream-routing-policy.ts +301 -0
  84. package/src/runtime/workstream-state.ts +261 -0
  85. package/src/services/attachment.service.ts +159 -0
  86. package/src/services/chat-attachments.service.ts +17 -0
  87. package/src/services/chat-run-registry.service.ts +3 -0
  88. package/src/services/context-compaction-runtime.ts +13 -0
  89. package/src/services/context-compaction.service.ts +115 -0
  90. package/src/services/document-chunk.service.ts +141 -0
  91. package/src/services/execution-plan.service.ts +890 -0
  92. package/src/services/learned-skill.service.ts +328 -0
  93. package/src/services/memory-assessment.service.ts +43 -0
  94. package/src/services/memory.service.ts +807 -0
  95. package/src/services/memory.utils.ts +84 -0
  96. package/src/services/mutating-approval.service.ts +110 -0
  97. package/src/services/recent-activity-title.service.ts +74 -0
  98. package/src/services/recent-activity.service.ts +397 -0
  99. package/src/services/workstream-change-tracker.service.ts +313 -0
  100. package/src/services/workstream-message.service.ts +283 -0
  101. package/src/services/workstream-title.service.ts +58 -0
  102. package/src/services/workstream-turn-preparation.ts +1340 -0
  103. package/src/services/workstream-turn.ts +37 -0
  104. package/src/services/workstream.service.ts +854 -0
  105. package/src/services/workstream.types.ts +118 -0
  106. package/src/storage/attachment-parser.ts +101 -0
  107. package/src/storage/attachment-storage.service.ts +391 -0
  108. package/src/storage/attachments.types.ts +11 -0
  109. package/src/storage/attachments.utils.ts +58 -0
  110. package/src/storage/generated-document-storage.service.ts +55 -0
  111. package/src/system-agents/agent-result.ts +27 -0
  112. package/src/system-agents/context-compacter.agent.ts +46 -0
  113. package/src/system-agents/delegated-agent-factory.ts +177 -0
  114. package/src/system-agents/helper-agent-options.ts +20 -0
  115. package/src/system-agents/memory-reranker.agent.ts +38 -0
  116. package/src/system-agents/memory.agent.ts +58 -0
  117. package/src/system-agents/recent-activity-title-refiner.agent.ts +53 -0
  118. package/src/system-agents/regular-chat-memory-digest.agent.ts +75 -0
  119. package/src/system-agents/researcher.agent.ts +34 -0
  120. package/src/system-agents/skill-extractor.agent.ts +88 -0
  121. package/src/system-agents/skill-manager.agent.ts +80 -0
  122. package/src/system-agents/title-generator.agent.ts +42 -0
  123. package/src/system-agents/workstream-tracker.agent.ts +58 -0
  124. package/src/tools/execution-plan.tool.ts +163 -0
  125. package/src/tools/fetch-webpage.tool.ts +132 -0
  126. package/src/tools/firecrawl-client.ts +12 -0
  127. package/src/tools/memory-block.tool.ts +55 -0
  128. package/src/tools/read-file-parts.tool.ts +80 -0
  129. package/src/tools/remember-memory.tool.ts +85 -0
  130. package/src/tools/research-topic.tool.ts +15 -0
  131. package/src/tools/search-tools.ts +55 -0
  132. package/src/tools/search-web.tool.ts +175 -0
  133. package/src/tools/team-think.tool.ts +125 -0
  134. package/src/tools/tool-contract.ts +21 -0
  135. package/src/tools/user-questions.tool.ts +18 -0
  136. package/src/utils/async.ts +50 -0
  137. package/src/utils/date-time.ts +34 -0
  138. package/src/utils/error.ts +10 -0
  139. package/src/utils/errors.ts +28 -0
  140. package/src/utils/hono-error-handler.ts +71 -0
  141. package/src/utils/string.ts +51 -0
  142. package/src/workers/bootstrap.ts +44 -0
  143. package/src/workers/memory-consolidation.worker.ts +318 -0
  144. package/src/workers/regular-chat-memory-digest.helpers.ts +100 -0
  145. package/src/workers/regular-chat-memory-digest.runner.ts +363 -0
  146. package/src/workers/regular-chat-memory-digest.worker.ts +22 -0
  147. package/src/workers/skill-extraction.runner.ts +331 -0
  148. package/src/workers/skill-extraction.worker.ts +22 -0
  149. package/src/workers/utils/repo-indexer-chunker.ts +331 -0
  150. package/src/workers/utils/repo-structure-extractor.ts +645 -0
  151. package/src/workers/utils/repomix-process-concurrency.ts +65 -0
  152. package/src/workers/utils/sandbox-error.ts +5 -0
  153. package/src/workers/worker-utils.ts +182 -0
@@ -0,0 +1,328 @@
1
+ import { recordIdStringSchema } from '@lota-sdk/shared/schemas/common'
2
+ import { BoundQuery } from 'surrealdb'
3
+ import { z } from 'zod'
4
+
5
+ import { renderLearnedSkillInstructions } from '../ai/definitions'
6
+ import { serverLogger } from '../config/logger'
7
+ import { ensureRecordId } from '../db/record-id'
8
+ import { databaseService } from '../db/service'
9
+ import { TABLES } from '../db/tables'
10
+ import { createDefaultEmbeddings } from '../embeddings/provider'
11
+
12
+ const embeddings = createDefaultEmbeddings()
13
+
14
+ const PROMOTION_MIN_USES = 5
15
+ const PROMOTION_MIN_SUCCESS_RATE = 0.6
16
+
17
+ const LearnedSkillRowSchema = z.object({
18
+ id: recordIdStringSchema,
19
+ name: z.string(),
20
+ description: z.string(),
21
+ instructions: z.string(),
22
+ triggers: z.array(z.string()).default([]),
23
+ tags: z.array(z.string()).default([]),
24
+ examples: z.array(z.string()).default([]),
25
+ version: z.number().int().default(1),
26
+ sourceType: z.string(),
27
+ organizationId: recordIdStringSchema,
28
+ agentId: z.string().optional(),
29
+ status: z.enum(['learned', 'verified', 'promoted', 'archived']).default('learned'),
30
+ confidence: z.number().min(0).max(1).default(0.5),
31
+ usageCount: z.number().int().default(0),
32
+ successCount: z.number().int().default(0),
33
+ supersedes: recordIdStringSchema.optional(),
34
+ hash: z.string(),
35
+ createdAt: z.coerce.date(),
36
+ updatedAt: z.coerce.date().optional(),
37
+ lastUsedAt: z.coerce.date().optional(),
38
+ archivedAt: z.coerce.date().optional(),
39
+ })
40
+
41
+ type LearnedSkillRow = z.infer<typeof LearnedSkillRowSchema>
42
+
43
+ const SearchResultRowSchema = z.object({
44
+ id: z.string(),
45
+ name: z.string(),
46
+ description: z.string(),
47
+ instructions: z.string(),
48
+ confidence: z.number(),
49
+ similarity: z.number(),
50
+ })
51
+
52
+ type SearchResultRow = z.infer<typeof SearchResultRowSchema>
53
+
54
+ export interface CreateLearnedSkillInput {
55
+ name: string
56
+ description: string
57
+ instructions: string
58
+ triggers: string[]
59
+ tags: string[]
60
+ examples: string[]
61
+ sourceType: string
62
+ organizationId: string
63
+ agentId: string | null
64
+ confidence: number
65
+ embedding: number[]
66
+ hash: string
67
+ }
68
+
69
+ export interface UpdateLearnedSkillInput {
70
+ name?: string
71
+ description?: string
72
+ instructions?: string
73
+ triggers?: string[]
74
+ tags?: string[]
75
+ examples?: string[]
76
+ confidence?: number
77
+ version?: number
78
+ embedding?: number[]
79
+ hash?: string
80
+ supersedes?: string
81
+ }
82
+
83
+ export interface RetrieveForTurnParams {
84
+ orgId: string
85
+ agentId: string
86
+ query: string
87
+ limit: number
88
+ minConfidence: number
89
+ }
90
+
91
+ class LearnedSkillService {
92
+ async create(input: CreateLearnedSkillInput): Promise<LearnedSkillRow> {
93
+ const orgRef = ensureRecordId(input.organizationId, TABLES.ORGANIZATION)
94
+
95
+ const data: Record<string, unknown> = {
96
+ name: input.name,
97
+ description: input.description,
98
+ instructions: input.instructions,
99
+ triggers: input.triggers,
100
+ tags: input.tags,
101
+ examples: input.examples,
102
+ sourceType: input.sourceType,
103
+ organizationId: orgRef,
104
+ agentId: input.agentId,
105
+ confidence: input.confidence,
106
+ embedding: input.embedding,
107
+ hash: input.hash,
108
+ }
109
+
110
+ return databaseService.create(TABLES.LEARNED_SKILL, data, LearnedSkillRowSchema)
111
+ }
112
+
113
+ async update(skillId: string, input: UpdateLearnedSkillInput): Promise<LearnedSkillRow> {
114
+ const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
115
+ const data: Record<string, unknown> = { updatedAt: new Date().toISOString() }
116
+
117
+ if (input.name !== undefined) data.name = input.name
118
+ if (input.description !== undefined) data.description = input.description
119
+ if (input.instructions !== undefined) data.instructions = input.instructions
120
+ if (input.triggers !== undefined) data.triggers = input.triggers
121
+ if (input.tags !== undefined) data.tags = input.tags
122
+ if (input.examples !== undefined) data.examples = input.examples
123
+ if (input.confidence !== undefined) data.confidence = input.confidence
124
+ if (input.version !== undefined) data.version = input.version
125
+ if (input.embedding !== undefined) data.embedding = input.embedding
126
+ if (input.hash !== undefined) data.hash = input.hash
127
+ if (input.supersedes !== undefined) data.supersedes = ensureRecordId(input.supersedes, TABLES.LEARNED_SKILL)
128
+
129
+ const updated = await databaseService.update(TABLES.LEARNED_SKILL, ref, data, LearnedSkillRowSchema)
130
+ if (!updated) throw new Error(`Learned skill ${skillId} not found`)
131
+ return updated
132
+ }
133
+
134
+ async archive(skillId: string): Promise<void> {
135
+ const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
136
+ await databaseService.update(
137
+ TABLES.LEARNED_SKILL,
138
+ ref,
139
+ { status: 'archived', archivedAt: new Date().toISOString(), updatedAt: new Date().toISOString() },
140
+ LearnedSkillRowSchema,
141
+ )
142
+ }
143
+
144
+ async getById(skillId: string): Promise<LearnedSkillRow | null> {
145
+ return databaseService.findOne(
146
+ TABLES.LEARNED_SKILL,
147
+ { id: ensureRecordId(skillId, TABLES.LEARNED_SKILL) },
148
+ LearnedSkillRowSchema,
149
+ )
150
+ }
151
+
152
+ async searchForTurn(params: RetrieveForTurnParams): Promise<SearchResultRow[]> {
153
+ const orgRef = ensureRecordId(params.orgId, TABLES.ORGANIZATION)
154
+ const queryEmbedding = await embeddings.embedQuery(params.query)
155
+ if (queryEmbedding.length === 0) return []
156
+
157
+ const candidateLimit = params.limit * 4
158
+ const sql = `
159
+ LET $candidateRows = (
160
+ SELECT
161
+ id,
162
+ vector::distance::knn() AS distance
163
+ FROM ${TABLES.LEARNED_SKILL}
164
+ WHERE organizationId = $organizationId
165
+ AND status IN ['learned', 'verified', 'promoted']
166
+ AND archivedAt IS NONE
167
+ AND confidence >= $minConfidence
168
+ AND (agentId IS NONE OR agentId = $agentId)
169
+ AND embedding <|${candidateLimit}|> $embedding
170
+ ORDER BY distance ASC
171
+ );
172
+
173
+ SELECT
174
+ type::string(id) AS id,
175
+ name,
176
+ description,
177
+ instructions,
178
+ confidence,
179
+ vector::similarity::cosine(embedding, $embedding) AS similarity
180
+ FROM ${TABLES.LEARNED_SKILL}
181
+ WHERE id IN $candidateRows.id
182
+ ORDER BY similarity DESC
183
+ LIMIT $limit
184
+ `
185
+
186
+ const rows = await databaseService.query<unknown>(
187
+ new BoundQuery(sql, {
188
+ organizationId: orgRef,
189
+ embedding: queryEmbedding,
190
+ agentId: params.agentId,
191
+ minConfidence: params.minConfidence,
192
+ limit: params.limit,
193
+ }),
194
+ )
195
+
196
+ return rows.map((row) => SearchResultRowSchema.parse(row)).filter((row) => row.similarity >= 0.3)
197
+ }
198
+
199
+ async retrieveForTurn(params: RetrieveForTurnParams): Promise<string | undefined> {
200
+ const results = await this.searchForTurn(params)
201
+ if (results.length === 0) return undefined
202
+
203
+ for (const result of results) {
204
+ void this.recordUsage(result.id).catch((error) => {
205
+ serverLogger.warn`Failed to record learned skill usage for ${result.id}: ${error}`
206
+ })
207
+ }
208
+
209
+ const section = renderLearnedSkillInstructions(
210
+ results.map((row) => ({ name: row.name, instructions: row.instructions })),
211
+ )
212
+ return section || undefined
213
+ }
214
+
215
+ async recordUsage(skillId: string): Promise<void> {
216
+ const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
217
+ await databaseService.query<unknown>(
218
+ new BoundQuery(`UPDATE ${TABLES.LEARNED_SKILL} SET usageCount += 1, lastUsedAt = time::now() WHERE id = $id`, {
219
+ id: ref,
220
+ }),
221
+ )
222
+ }
223
+
224
+ async recordSuccess(skillId: string): Promise<void> {
225
+ const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
226
+ await databaseService.query<unknown>(
227
+ new BoundQuery(`UPDATE ${TABLES.LEARNED_SKILL} SET successCount += 1 WHERE id = $id`, { id: ref }),
228
+ )
229
+ }
230
+
231
+ async promoteIfEligible(skillId: string): Promise<boolean> {
232
+ const skill = await this.getById(skillId)
233
+ if (!skill) return false
234
+ if (skill.status !== 'learned') return false
235
+ if (skill.usageCount < PROMOTION_MIN_USES) return false
236
+
237
+ const successRate = skill.successCount / skill.usageCount
238
+ if (successRate < PROMOTION_MIN_SUCCESS_RATE) return false
239
+
240
+ const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
241
+ await databaseService.update(
242
+ TABLES.LEARNED_SKILL,
243
+ ref,
244
+ { status: 'verified', confidence: Math.min(skill.confidence + 0.1, 1.0), updatedAt: new Date().toISOString() },
245
+ LearnedSkillRowSchema,
246
+ )
247
+ return true
248
+ }
249
+
250
+ async findMostSimilar(orgId: string, description: string): Promise<LearnedSkillRow | null> {
251
+ const orgRef = ensureRecordId(orgId, TABLES.ORGANIZATION)
252
+ const descEmbedding = await embeddings.embedQuery(description)
253
+ if (descEmbedding.length === 0) return null
254
+
255
+ const sql = `
256
+ LET $candidateRows = (
257
+ SELECT
258
+ id,
259
+ vector::distance::knn() AS distance
260
+ FROM ${TABLES.LEARNED_SKILL}
261
+ WHERE organizationId = $organizationId
262
+ AND status IN ['learned', 'verified', 'promoted']
263
+ AND archivedAt IS NONE
264
+ AND embedding <|3|> $embedding
265
+ ORDER BY distance ASC
266
+ );
267
+
268
+ SELECT *,
269
+ type::string(id) AS id,
270
+ type::string(organizationId) AS organizationId,
271
+ vector::similarity::cosine(embedding, $embedding) AS similarity
272
+ FROM ${TABLES.LEARNED_SKILL}
273
+ WHERE id IN $candidateRows.id
274
+ ORDER BY similarity DESC
275
+ LIMIT 1
276
+ `
277
+
278
+ const rows = await databaseService.query<unknown>(
279
+ new BoundQuery(sql, { organizationId: orgRef, embedding: descEmbedding }),
280
+ )
281
+
282
+ if (rows.length === 0) return null
283
+ return LearnedSkillRowSchema.parse(rows[0])
284
+ }
285
+
286
+ async listForOrg(orgId: string): Promise<LearnedSkillRow[]> {
287
+ const orgRef = ensureRecordId(orgId, TABLES.ORGANIZATION)
288
+ return databaseService.queryMany(
289
+ new BoundQuery(
290
+ `SELECT *, type::string(id) AS id, type::string(organizationId) AS organizationId
291
+ FROM ${TABLES.LEARNED_SKILL}
292
+ WHERE organizationId = $organizationId
293
+ AND status IN ['learned', 'verified', 'promoted']
294
+ AND archivedAt IS NONE
295
+ ORDER BY createdAt DESC`,
296
+ { organizationId: orgRef },
297
+ ),
298
+ LearnedSkillRowSchema,
299
+ )
300
+ }
301
+
302
+ generateHash(description: string, instructions: string): string {
303
+ const hasher = new Bun.CryptoHasher('sha256')
304
+ hasher.update(description.trim().toLowerCase())
305
+ hasher.update(instructions.trim().toLowerCase())
306
+ return hasher.digest('hex')
307
+ }
308
+
309
+ async findByHash(orgId: string, hash: string): Promise<LearnedSkillRow | null> {
310
+ const orgRef = ensureRecordId(orgId, TABLES.ORGANIZATION)
311
+ const rows = await databaseService.queryMany(
312
+ new BoundQuery(
313
+ `SELECT *, type::string(id) AS id, type::string(organizationId) AS organizationId
314
+ FROM ${TABLES.LEARNED_SKILL}
315
+ WHERE organizationId = $organizationId
316
+ AND hash = $hash
317
+ AND status IN ['learned', 'verified', 'promoted']
318
+ AND archivedAt IS NONE
319
+ LIMIT 1`,
320
+ { organizationId: orgRef, hash },
321
+ ),
322
+ LearnedSkillRowSchema,
323
+ )
324
+ return rows[0] ?? null
325
+ }
326
+ }
327
+
328
+ export const learnedSkillService = new LearnedSkillService()
@@ -0,0 +1,43 @@
1
+ import type { z } from 'zod'
2
+
3
+ import { MemoryImportanceAssessmentSchema } from '../db/memory-types'
4
+ import { createHelperModelRuntime } from '../runtime/helper-model'
5
+ import { createOrgMemoryAgent } from '../system-agents/memory.agent'
6
+
7
+ type MemoryImportanceAssessment = z.infer<typeof MemoryImportanceAssessmentSchema>
8
+ const MEMORY_IMPORTANCE_ASSESSMENT_TIMEOUT_MS = 10 * 60 * 1000
9
+ const helperModelRuntime = createHelperModelRuntime()
10
+
11
+ export function clampMemoryImportance(value: number): number {
12
+ return Math.max(0.2, Math.min(0.95, value))
13
+ }
14
+
15
+ export async function assessMemoryImportance(params: {
16
+ content: string
17
+ targetScope: 'agent' | 'global'
18
+ tag?: string
19
+ }): Promise<MemoryImportanceAssessment> {
20
+ const prompt = [
21
+ 'Assess whether this memory should be persisted in long-term memory.',
22
+ `targetScope: ${params.targetScope}`,
23
+ `memory: ${params.content}`,
24
+ '',
25
+ 'Rules:',
26
+ '- importance: number between 0 and 1 for long-term usefulness.',
27
+ '- durability: core|standard|ephemeral.',
28
+ '- classification: durable|transient|uncertain.',
29
+ '- rationale: short and concrete.',
30
+ '',
31
+ 'The caller enforces a structured output schema.',
32
+ 'Return only schema fields.',
33
+ ].join('\n')
34
+
35
+ return await helperModelRuntime.generateHelperStructured({
36
+ tag: params.tag ?? 'memory-importance-assessment',
37
+ createAgent: createOrgMemoryAgent,
38
+ systemPrompt: 'You are a strict long-term memory quality assessor for an AI agent.',
39
+ messages: [{ role: 'user', content: prompt }],
40
+ schema: MemoryImportanceAssessmentSchema,
41
+ timeoutMs: MEMORY_IMPORTANCE_ASSESSMENT_TIMEOUT_MS,
42
+ })
43
+ }