@lota-sdk/core 0.1.11 → 0.1.12

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 (95) hide show
  1. package/package.json +2 -87
  2. package/src/ai/index.ts +3 -0
  3. package/src/bifrost/index.ts +1 -0
  4. package/src/config/agent-defaults.ts +30 -7
  5. package/src/config/constants.ts +0 -9
  6. package/src/config/debug-logger.ts +43 -0
  7. package/src/config/index.ts +5 -0
  8. package/src/config/model-constants.ts +0 -3
  9. package/src/config/workstream-defaults.ts +4 -0
  10. package/src/db/cursor-pagination.ts +2 -2
  11. package/src/db/index.ts +10 -0
  12. package/src/db/memory.ts +9 -15
  13. package/src/document/index.ts +2 -0
  14. package/src/document/parsing.ts +0 -25
  15. package/src/embeddings/provider.ts +17 -8
  16. package/src/index.ts +15 -505
  17. package/src/queues/index.ts +10 -0
  18. package/src/redis/connection-accessor.ts +26 -0
  19. package/src/redis/connection.ts +1 -1
  20. package/src/redis/index.ts +9 -25
  21. package/src/redis/org-memory-lock.ts +1 -1
  22. package/src/redis/redis-lease-lock.ts +1 -1
  23. package/src/redis/stream-context.ts +12 -2
  24. package/src/runtime/agent-runtime-policy.ts +9 -5
  25. package/src/runtime/agent-stream-helpers.ts +6 -3
  26. package/src/runtime/agent-types.ts +1 -5
  27. package/src/runtime/approval-continuation.ts +9 -1
  28. package/src/runtime/chat-attachments.ts +1 -1
  29. package/src/runtime/chat-request-routing.ts +1 -1
  30. package/src/runtime/context-compaction-runtime.ts +2 -2
  31. package/src/runtime/context-compaction.ts +1 -1
  32. package/src/runtime/execution-plan.ts +1 -1
  33. package/src/runtime/index.ts +26 -0
  34. package/src/runtime/indexed-repositories-policy.ts +10 -10
  35. package/src/runtime/memory-pipeline.ts +0 -2
  36. package/src/runtime/runtime-config.ts +238 -0
  37. package/src/runtime/runtime-extensions.ts +3 -2
  38. package/src/runtime/runtime-worker-registry.ts +47 -0
  39. package/src/runtime/team-consultation-orchestrator.ts +9 -6
  40. package/src/runtime/team-consultation-prompts.ts +3 -2
  41. package/src/runtime/turn-lifecycle.ts +1 -1
  42. package/src/runtime/workstream-chat-helpers.ts +0 -54
  43. package/src/runtime/workstream-routing-policy.ts +3 -7
  44. package/src/runtime.ts +387 -0
  45. package/src/services/chat-attachments.service.ts +1 -1
  46. package/src/services/context-compaction.service.ts +1 -1
  47. package/src/services/execution-plan.service.ts +14 -16
  48. package/src/services/index.ts +14 -0
  49. package/src/services/learned-skill.service.ts +80 -37
  50. package/src/services/memory.service.ts +5 -4
  51. package/src/services/mutating-approval.service.ts +1 -1
  52. package/src/services/organization-member.service.ts +1 -1
  53. package/src/services/organization.service.ts +1 -1
  54. package/src/services/plan-approval.service.ts +2 -2
  55. package/src/services/plan-artifact.service.ts +2 -3
  56. package/src/services/plan-builder.service.ts +1 -1
  57. package/src/services/plan-checkpoint.service.ts +2 -2
  58. package/src/services/plan-compiler.service.ts +2 -2
  59. package/src/services/plan-executor.service.ts +10 -9
  60. package/src/services/plan-run.service.ts +2 -2
  61. package/src/services/plan-validator.service.ts +4 -4
  62. package/src/services/recent-activity-title.service.ts +1 -1
  63. package/src/services/recent-activity.service.ts +14 -16
  64. package/src/services/user.service.ts +2 -2
  65. package/src/services/workstream-message.service.ts +2 -3
  66. package/src/services/workstream-title.service.ts +1 -1
  67. package/src/services/workstream-turn-preparation.ts +105 -50
  68. package/src/services/workstream-turn.ts +14 -1
  69. package/src/services/workstream.service.ts +9 -9
  70. package/src/storage/attachment-parser.ts +1 -1
  71. package/src/storage/attachment-storage.service.ts +11 -10
  72. package/src/storage/generated-document-storage.service.ts +7 -6
  73. package/src/storage/index.ts +10 -0
  74. package/src/system-agents/delegated-agent-factory.ts +78 -29
  75. package/src/system-agents/index.ts +4 -0
  76. package/src/system-agents/recent-activity-title-refiner.agent.ts +38 -3
  77. package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
  78. package/src/system-agents/skill-extractor.agent.ts +1 -1
  79. package/src/system-agents/skill-manager.agent.ts +2 -4
  80. package/src/tools/execution-plan.tool.ts +2 -2
  81. package/src/tools/firecrawl-client.ts +2 -2
  82. package/src/tools/index.ts +12 -0
  83. package/src/tools/research-topic.tool.ts +1 -1
  84. package/src/tools/team-think.tool.ts +1 -1
  85. package/src/tools/user-questions.tool.ts +2 -2
  86. package/src/utils/index.ts +6 -0
  87. package/src/workers/bootstrap.ts +8 -16
  88. package/src/workers/index.ts +7 -0
  89. package/src/workers/regular-chat-memory-digest.runner.ts +1 -1
  90. package/src/workers/skill-extraction.runner.ts +1 -1
  91. package/src/workers/utils/{repo-indexer-chunker.ts → file-section-chunker.ts} +23 -52
  92. package/src/workers/utils/repo-structure-extractor.ts +2 -5
  93. package/src/workers/utils/repomix-file-sections.ts +42 -0
  94. package/src/config/env-shapes.ts +0 -121
  95. package/src/runtime/agent-contract.ts +0 -1
@@ -1,19 +1,28 @@
1
- import { recordIdStringSchema } from '@lota-sdk/shared/schemas/common'
1
+ import { recordIdStringSchema } from '@lota-sdk/shared'
2
2
  import { BoundQuery } from 'surrealdb'
3
3
  import { z } from 'zod'
4
4
 
5
5
  import { renderLearnedSkillInstructions } from '../ai/definitions'
6
+ import { lotaDebugLogger } from '../config/debug-logger'
6
7
  import { serverLogger } from '../config/logger'
7
8
  import { ensureRecordId } from '../db/record-id'
8
9
  import { databaseService } from '../db/service'
9
10
  import { TABLES } from '../db/tables'
10
11
  import { getDefaultEmbeddings } from '../embeddings/provider'
12
+ import { getRedisConnection } from '../redis'
11
13
 
12
14
  const embeddings = getDefaultEmbeddings()
13
15
 
14
16
  const PROMOTION_MIN_USES = 5
15
17
  const PROMOTION_MIN_SUCCESS_RATE = 0.6
16
18
 
19
+ const SKILL_EXISTS_TTL_SECONDS = 120
20
+ const SKILL_EXISTS_KEY_PREFIX = 'skill-exists'
21
+
22
+ function skillExistsKey(orgId: string, agentId: string): string {
23
+ return `${SKILL_EXISTS_KEY_PREFIX}:${orgId}:${agentId}`
24
+ }
25
+
17
26
  const LearnedSkillRowSchema = z.object({
18
27
  id: recordIdStringSchema,
19
28
  name: z.string(),
@@ -51,7 +60,7 @@ const SearchResultRowSchema = z.object({
51
60
 
52
61
  type SearchResultRow = z.infer<typeof SearchResultRowSchema>
53
62
 
54
- export interface CreateLearnedSkillInput {
63
+ interface CreateLearnedSkillInput {
55
64
  name: string
56
65
  description: string
57
66
  instructions: string
@@ -66,7 +75,7 @@ export interface CreateLearnedSkillInput {
66
75
  hash: string
67
76
  }
68
77
 
69
- export interface UpdateLearnedSkillInput {
78
+ interface UpdateLearnedSkillInput {
70
79
  name?: string
71
80
  description?: string
72
81
  instructions?: string
@@ -80,7 +89,7 @@ export interface UpdateLearnedSkillInput {
80
89
  supersedes?: string
81
90
  }
82
91
 
83
- export interface RetrieveForTurnParams {
92
+ interface RetrieveForTurnParams {
84
93
  orgId: string
85
94
  agentId: string
86
95
  query: string
@@ -107,7 +116,9 @@ class LearnedSkillService {
107
116
  hash: input.hash,
108
117
  }
109
118
 
110
- return databaseService.create(TABLES.LEARNED_SKILL, data, LearnedSkillRowSchema)
119
+ const result = await databaseService.create(TABLES.LEARNED_SKILL, data, LearnedSkillRowSchema)
120
+ await this.invalidateSkillExistsCache(input.organizationId, input.agentId)
121
+ return result
111
122
  }
112
123
 
113
124
  async update(skillId: string, input: UpdateLearnedSkillInput): Promise<LearnedSkillRow> {
@@ -133,12 +144,16 @@ class LearnedSkillService {
133
144
 
134
145
  async archive(skillId: string): Promise<void> {
135
146
  const ref = ensureRecordId(skillId, TABLES.LEARNED_SKILL)
147
+ const skill = await this.getById(skillId)
136
148
  await databaseService.update(
137
149
  TABLES.LEARNED_SKILL,
138
150
  ref,
139
151
  { status: 'archived', archivedAt: new Date().toISOString(), updatedAt: new Date().toISOString() },
140
152
  LearnedSkillRowSchema,
141
153
  )
154
+ if (skill) {
155
+ await this.invalidateSkillExistsCache(String(skill.organizationId), skill.agentId ?? null)
156
+ }
142
157
  }
143
158
 
144
159
  async getById(skillId: string): Promise<LearnedSkillRow | null> {
@@ -149,27 +164,60 @@ class LearnedSkillService {
149
164
  )
150
165
  }
151
166
 
167
+ private async hasSkillsForAgent(orgId: string, agentId: string): Promise<boolean> {
168
+ const redis = getRedisConnection()
169
+ const key = skillExistsKey(orgId, agentId)
170
+
171
+ const cached = await redis.get(key)
172
+ if (cached !== null) return cached === '1'
173
+
174
+ const orgRef = ensureRecordId(orgId, TABLES.ORGANIZATION)
175
+ const rows = await databaseService.query<{ id: unknown }>(
176
+ new BoundQuery(
177
+ `SELECT id FROM ${TABLES.LEARNED_SKILL}
178
+ WHERE organizationId = $orgRef
179
+ AND status IN ['learned', 'verified', 'promoted']
180
+ AND archivedAt IS NONE
181
+ AND (agentId IS NONE OR agentId = $agentId)
182
+ LIMIT 1`,
183
+ { orgRef, agentId },
184
+ ),
185
+ )
186
+
187
+ const exists = rows.length > 0
188
+ await redis.set(key, exists ? '1' : '0', 'EX', SKILL_EXISTS_TTL_SECONDS)
189
+ return exists
190
+ }
191
+
192
+ private async invalidateSkillExistsCache(orgId: string, agentId: string | null): Promise<void> {
193
+ const redis = getRedisConnection()
194
+ const pattern = `${SKILL_EXISTS_KEY_PREFIX}:${orgId}:*`
195
+ const keys = await redis.keys(pattern)
196
+ if (keys.length > 0) {
197
+ await redis.del(...keys)
198
+ }
199
+ // Also set the specific key if we know a skill was just created
200
+ if (agentId) {
201
+ await redis.set(skillExistsKey(orgId, agentId), '1', 'EX', SKILL_EXISTS_TTL_SECONDS)
202
+ }
203
+ }
204
+
152
205
  async searchForTurn(params: RetrieveForTurnParams): Promise<SearchResultRow[]> {
153
- const orgRef = ensureRecordId(params.orgId, TABLES.ORGANIZATION)
206
+ const timer = lotaDebugLogger.timer('learned-skills')
207
+
208
+ const hasSkills = await this.hasSkillsForAgent(params.orgId, params.agentId)
209
+ if (!hasSkills) {
210
+ lotaDebugLogger.step('learned-skills: skipped — no skills for org+agent')
211
+ return []
212
+ }
213
+ timer.step('has-skills-check')
214
+
154
215
  const queryEmbedding = await embeddings.embedQuery(params.query)
216
+ timer.step('embed-query')
155
217
  if (queryEmbedding.length === 0) return []
156
218
 
157
- const candidateLimit = params.limit * 4
219
+ const orgRef = ensureRecordId(params.orgId, TABLES.ORGANIZATION)
158
220
  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
221
  SELECT
174
222
  type::string(id) AS id,
175
223
  name,
@@ -178,9 +226,13 @@ class LearnedSkillService {
178
226
  confidence,
179
227
  vector::similarity::cosine(embedding, $embedding) AS similarity
180
228
  FROM ${TABLES.LEARNED_SKILL}
181
- WHERE id IN $candidateRows.id
229
+ WHERE organizationId = $organizationId
230
+ AND status IN ['learned', 'verified', 'promoted']
231
+ AND archivedAt IS NONE
232
+ AND confidence >= $minConfidence
233
+ AND (agentId IS NONE OR agentId = $agentId)
234
+ AND embedding <|${params.limit}|> $embedding
182
235
  ORDER BY similarity DESC
183
- LIMIT $limit
184
236
  `
185
237
 
186
238
  const rows = await databaseService.query<unknown>(
@@ -189,9 +241,9 @@ class LearnedSkillService {
189
241
  embedding: queryEmbedding,
190
242
  agentId: params.agentId,
191
243
  minConfidence: params.minConfidence,
192
- limit: params.limit,
193
244
  }),
194
245
  )
246
+ timer.step('knn-query')
195
247
 
196
248
  return rows.map((row) => SearchResultRowSchema.parse(row)).filter((row) => row.similarity >= 0.3)
197
249
  }
@@ -253,24 +305,15 @@ class LearnedSkillService {
253
305
  if (descEmbedding.length === 0) return null
254
306
 
255
307
  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
308
  SELECT *,
269
309
  type::string(id) AS id,
270
310
  type::string(organizationId) AS organizationId,
271
311
  vector::similarity::cosine(embedding, $embedding) AS similarity
272
312
  FROM ${TABLES.LEARNED_SKILL}
273
- WHERE id IN $candidateRows.id
313
+ WHERE organizationId = $organizationId
314
+ AND status IN ['learned', 'verified', 'promoted']
315
+ AND archivedAt IS NONE
316
+ AND embedding <|3|> $embedding
274
317
  ORDER BY similarity DESC
275
318
  LIMIT 1
276
319
  `
@@ -1,7 +1,6 @@
1
1
  import { z } from 'zod'
2
2
 
3
3
  import { agentRoster } from '../config/agent-defaults'
4
- import { env } from '../config/env-shapes'
5
4
  import { aiLogger } from '../config/logger'
6
5
  import { Memory } from '../db/memory'
7
6
  import { isUniqueIndexConflict } from '../db/memory-store.helpers'
@@ -24,6 +23,7 @@ import {
24
23
  executeScopedRetrieval,
25
24
  scopedRetrievalToMap,
26
25
  } from '../runtime/retrieval-adapters'
26
+ import { getRuntimeConfig } from '../runtime/runtime-config'
27
27
  import { createMemoryRerankerAgent, memoryRerankerPrompt } from '../system-agents/memory-reranker.agent'
28
28
  import { createOrgMemoryAgent, orgMemoryPrompt } from '../system-agents/memory.agent'
29
29
  import { assessMemoryImportance, clampMemoryImportance } from './memory-assessment.service'
@@ -304,7 +304,7 @@ class MemoryService {
304
304
  scopeId: string
305
305
  memoryType: MemoryType
306
306
  }): Promise<string> {
307
- const limit = env.MEMORY_SEARCH_K
307
+ const limit = getRuntimeConfig().memory.searchK
308
308
  const candidateLimit = getCandidateLimit(limit)
309
309
 
310
310
  const candidates = await memory.searchCandidates(query, { scopeId, limit: candidateLimit, memoryType })
@@ -362,7 +362,8 @@ class MemoryService {
362
362
  aiLogger.info`[MEMORY_DEBUG] searchOrganizationMemoriesRaw - orgId: "${orgId}", scopeId: "${orgScopeId}"`
363
363
  const memory = this.getOrgMemory(orgId)
364
364
  const fastMode = options?.fastMode ?? true
365
- const limit = options?.limit ?? (fastMode ? Math.min(env.MEMORY_SEARCH_K, 4) : env.MEMORY_SEARCH_K)
365
+ const searchK = getRuntimeConfig().memory.searchK
366
+ const limit = options?.limit ?? (fastMode ? Math.min(searchK, 4) : searchK)
366
367
 
367
368
  try {
368
369
  const candidates = await memory.searchCandidates(query, {
@@ -489,7 +490,7 @@ class MemoryService {
489
490
  fastMode?: boolean
490
491
  allowMultiScopeRerank?: boolean
491
492
  }): Promise<string> {
492
- const limit = Math.min(env.MEMORY_SEARCH_K, MAX_MEMORY_RESULTS_PER_SCOPE)
493
+ const limit = Math.min(getRuntimeConfig().memory.searchK, MAX_MEMORY_RESULTS_PER_SCOPE)
493
494
  const candidateLimit = fastMode ? limit : getCandidateLimit(limit)
494
495
  const orgScopeId = scopeId(ORG_SCOPE_PREFIX, orgId)
495
496
  const orgMemory = this.getOrgMemory(orgId)
@@ -6,7 +6,7 @@ import { workstreamMessageService } from './workstream-message.service'
6
6
 
7
7
  const APPROVAL_VERIFICATION_MESSAGE_WINDOW = 20
8
8
 
9
- export type VerifyMutatingApproval = (params: {
9
+ type VerifyMutatingApproval = (params: {
10
10
  workstreamId: string
11
11
  approvalReason: string
12
12
  approvalToken: string
@@ -1,4 +1,4 @@
1
- import { recordIdStringSchema } from '@lota-sdk/shared/schemas/common'
1
+ import { recordIdStringSchema } from '@lota-sdk/shared'
2
2
  import { z } from 'zod'
3
3
 
4
4
  import { BaseService } from '../db/base.service'
@@ -1,4 +1,4 @@
1
- import { recordIdStringSchema } from '@lota-sdk/shared/schemas/common'
1
+ import { recordIdStringSchema } from '@lota-sdk/shared'
2
2
  import { z } from 'zod'
3
3
 
4
4
  import { BaseService } from '../db/base.service'
@@ -1,5 +1,5 @@
1
- import { PlanApprovalSchema } from '@lota-sdk/shared/schemas/execution-plan'
2
- import type { PlanApprovalRecord, PlanApprovalStatus } from '@lota-sdk/shared/schemas/execution-plan'
1
+ import { PlanApprovalSchema } from '@lota-sdk/shared'
2
+ import type { PlanApprovalRecord, PlanApprovalStatus } from '@lota-sdk/shared'
3
3
  import { RecordId } from 'surrealdb'
4
4
 
5
5
  import type { RecordIdInput } from '../db/record-id'
@@ -1,6 +1,5 @@
1
- import { PlanArtifactSchema } from '@lota-sdk/shared/schemas/execution-plan'
2
- import type { PlanArtifactRecord } from '@lota-sdk/shared/schemas/execution-plan'
3
- import type { PlanArtifactSubmission } from '@lota-sdk/shared/schemas/tools'
1
+ import { PlanArtifactSchema } from '@lota-sdk/shared'
2
+ import type { PlanArtifactRecord, PlanArtifactSubmission } from '@lota-sdk/shared'
4
3
  import { RecordId } from 'surrealdb'
5
4
 
6
5
  import type { RecordIdInput } from '../db/record-id'
@@ -1,4 +1,4 @@
1
- import type { PlanDraft } from '@lota-sdk/shared/schemas/execution-plan'
1
+ import type { PlanDraft } from '@lota-sdk/shared'
2
2
 
3
3
  function buildImplicitLinearEdges(draft: PlanDraft) {
4
4
  if (draft.edges.length > 0 || draft.nodes.length <= 1) {
@@ -1,5 +1,5 @@
1
- import { PlanCheckpointSchema } from '@lota-sdk/shared/schemas/execution-plan'
2
- import type { PlanCheckpointRecord, PlanRunStatus } from '@lota-sdk/shared/schemas/execution-plan'
1
+ import { PlanCheckpointSchema } from '@lota-sdk/shared'
2
+ import type { PlanCheckpointRecord, PlanRunStatus } from '@lota-sdk/shared'
3
3
  import { RecordId } from 'surrealdb'
4
4
 
5
5
  import type { RecordIdInput } from '../db/record-id'
@@ -1,4 +1,4 @@
1
- import type { PlanDraft, PlanNodeSpec, PlanNodeSpecRecord } from '@lota-sdk/shared/schemas/execution-plan'
1
+ import type { PlanDraft, PlanNodeSpec, PlanNodeSpecRecord } from '@lota-sdk/shared'
2
2
 
3
3
  import { planValidatorService } from './plan-validator.service'
4
4
 
@@ -9,7 +9,7 @@ export interface CompiledPlanNode {
9
9
  downstreamNodeIds: string[]
10
10
  }
11
11
 
12
- export interface CompiledPlanDraft {
12
+ interface CompiledPlanDraft {
13
13
  draft: PlanDraft
14
14
  nodes: CompiledPlanNode[]
15
15
  }
@@ -1,23 +1,24 @@
1
- import {
2
- PlanEventSchema,
3
- PlanNodeAttemptSchema,
4
- PlanNodeRunSchema,
5
- PlanRunSchema,
6
- PlanValidationIssueSchema,
7
- } from '@lota-sdk/shared/schemas/execution-plan'
8
1
  import type {
2
+ ExecutionPlanToolResultData,
9
3
  PlanEventRecord,
10
4
  PlanEventType,
11
5
  PlanFailureAction,
12
6
  PlanFailureClass,
7
+ PlanNodeResultSubmission,
13
8
  PlanNodeRunRecord,
14
9
  PlanNodeSpecRecord,
15
10
  PlanRunRecord,
16
11
  PlanSpecRecord,
17
12
  PlanValidationIssueRecord,
18
13
  SerializableExecutionPlan,
19
- } from '@lota-sdk/shared/schemas/execution-plan'
20
- import type { ExecutionPlanToolResultData, PlanNodeResultSubmission } from '@lota-sdk/shared/schemas/tools'
14
+ } from '@lota-sdk/shared'
15
+ import {
16
+ PlanEventSchema,
17
+ PlanNodeAttemptSchema,
18
+ PlanNodeRunSchema,
19
+ PlanRunSchema,
20
+ PlanValidationIssueSchema,
21
+ } from '@lota-sdk/shared'
21
22
  import { RecordId } from 'surrealdb'
22
23
 
23
24
  import type { RecordIdInput } from '../db/record-id'
@@ -9,7 +9,7 @@ import {
9
9
  PlanRunSchema,
10
10
  PlanSpecSchema,
11
11
  PlanValidationIssueSchema,
12
- } from '@lota-sdk/shared/schemas/execution-plan'
12
+ } from '@lota-sdk/shared'
13
13
  import type {
14
14
  PlanApprovalRecord,
15
15
  PlanArtifactRecord,
@@ -29,7 +29,7 @@ import type {
29
29
  SerializablePlanEvent,
30
30
  SerializablePlanNode,
31
31
  SerializablePlanValidationIssue,
32
- } from '@lota-sdk/shared/schemas/execution-plan'
32
+ } from '@lota-sdk/shared'
33
33
 
34
34
  import type { RecordIdInput } from '../db/record-id'
35
35
  import { ensureRecordId, recordIdToString } from '../db/record-id'
@@ -3,10 +3,10 @@ import type {
3
3
  PlanDataSchema,
4
4
  PlanDraft,
5
5
  PlanFailureClass,
6
+ PlanNodeResultSubmission,
6
7
  PlanNodeSpec,
7
8
  PlanValidationIssueSeverity,
8
- } from '@lota-sdk/shared/schemas/execution-plan'
9
- import type { PlanNodeResultSubmission } from '@lota-sdk/shared/schemas/tools'
9
+ } from '@lota-sdk/shared'
10
10
 
11
11
  const STRUCTURAL_NODE_TYPES = new Set(['switch', 'join'])
12
12
  const HUMAN_NODE_TYPES = new Set(['human-input', 'human-approval', 'human-review-edit', 'human-decision'])
@@ -19,12 +19,12 @@ export interface PlanValidationIssueInput {
19
19
  nodeId?: string
20
20
  }
21
21
 
22
- export interface DraftValidationResult {
22
+ interface DraftValidationResult {
23
23
  blocking: PlanValidationIssueInput[]
24
24
  warnings: PlanValidationIssueInput[]
25
25
  }
26
26
 
27
- export interface NodeResultValidationResult {
27
+ interface NodeResultValidationResult {
28
28
  blocking: PlanValidationIssueInput[]
29
29
  warnings: PlanValidationIssueInput[]
30
30
  failureClass: PlanFailureClass | null
@@ -58,7 +58,7 @@ class RecentActivityTitleService {
58
58
  }),
59
59
  )
60
60
  if (
61
- !recentActivityService.isChiefTitleUseful({
61
+ !recentActivityService.isAgentTitleUseful({
62
62
  currentTitle: candidate.title,
63
63
  systemTitle: candidate.systemTitle,
64
64
  candidateTitle: refinedTitle,
@@ -8,13 +8,13 @@ import {
8
8
  RecentActivitySchema,
9
9
  RecentActivitySourceSchema,
10
10
  RecentActivityTitleSourceSchema,
11
- } from '@lota-sdk/shared/schemas/recent-activity'
11
+ } from '@lota-sdk/shared'
12
12
  import type {
13
13
  RecentActivity,
14
14
  RecentActivityEvent,
15
15
  RecentActivityEventInput,
16
16
  RecentActivitySource,
17
- } from '@lota-sdk/shared/schemas/recent-activity'
17
+ } from '@lota-sdk/shared'
18
18
  import { RecordId } from 'surrealdb'
19
19
  import { z } from 'zod'
20
20
 
@@ -83,18 +83,16 @@ function buildDeterministicRecordId(table: string, key: string): RecordId {
83
83
  return new RecordId(table, digest)
84
84
  }
85
85
 
86
- function shouldKeepExistingChiefTitle(existing: RecentActivityRow | null): boolean {
87
- return existing?.titleSource === 'chief' && compactWhitespace(existing.title).length > 0
86
+ function shouldKeepExistingAgentTitle(existing: RecentActivityRow | null): boolean {
87
+ return existing?.titleSource === 'agent' && compactWhitespace(existing.title).length > 0
88
88
  }
89
89
 
90
90
  function buildRecentActivityAreaKey(
91
- row: Pick<RecentActivityRow, 'deepLink' | 'kind' | 'mergeKey' | 'metadata'>,
91
+ row: Pick<RecentActivityRow, 'targetKind' | 'targetId' | 'kind' | 'mergeKey' | 'metadata'>,
92
92
  ): string {
93
- const target = row.deepLink.search
94
-
95
- if (target.docId) return `document:${target.docId}`
96
- if (target.chat) return `workstream:${target.chat}`
97
- if (target.agent) return `agent:${target.agent}`
93
+ if (row.targetId) {
94
+ return `${row.targetKind}:${row.targetId}`
95
+ }
98
96
 
99
97
  const normalizedWebsiteUrl = row.metadata?.normalizedWebsiteUrl
100
98
  if (row.kind === 'website-intelligence.viewed' && normalizedWebsiteUrl) {
@@ -230,8 +228,8 @@ class RecentActivityService {
230
228
  { mutation: 'merge' },
231
229
  )
232
230
 
233
- const keepExistingChiefTitle = shouldKeepExistingChiefTitle(existingRecent)
234
- const visibleTitle = keepExistingChiefTitle && existingRecent ? existingRecent.title : parsedEvent.title
231
+ const keepExistingAgentTitle = shouldKeepExistingAgentTitle(existingRecent)
232
+ const visibleTitle = keepExistingAgentTitle && existingRecent ? existingRecent.title : parsedEvent.title
235
233
  const recentRow = await databaseService.upsert(
236
234
  TABLES.RECENT_ACTIVITY,
237
235
  recentRecordId,
@@ -244,7 +242,7 @@ class RecentActivityService {
244
242
  targetId: parsedEvent.targetId,
245
243
  title: visibleTitle,
246
244
  systemTitle: parsedEvent.title,
247
- titleSource: keepExistingChiefTitle ? 'chief' : 'system',
245
+ titleSource: keepExistingAgentTitle ? 'agent' : 'system',
248
246
  sourceLabel: parsedEvent.sourceLabel,
249
247
  deepLink: parsedEvent.deepLink,
250
248
  metadata: parsedEvent.metadata,
@@ -326,7 +324,7 @@ class RecentActivityService {
326
324
  const updated = await databaseService.update(
327
325
  TABLES.RECENT_ACTIVITY,
328
326
  activityRef,
329
- { title: nextTitle, titleSource: 'chief', titleRefinedAt: new Date() },
327
+ { title: nextTitle, titleSource: 'agent', titleRefinedAt: new Date() },
330
328
  RecentActivityRowSchema,
331
329
  { mutation: 'merge' },
332
330
  )
@@ -365,7 +363,7 @@ class RecentActivityService {
365
363
  return activity.titleSource === 'system'
366
364
  }
367
365
 
368
- isChiefTitleUseful(params: { currentTitle: string; systemTitle: string; candidateTitle: string }): boolean {
366
+ isAgentTitleUseful(params: { currentTitle: string; systemTitle: string; candidateTitle: string }): boolean {
369
367
  const candidate = compactWhitespace(params.candidateTitle)
370
368
  if (!candidate) return false
371
369
 
@@ -385,7 +383,7 @@ class RecentActivityService {
385
383
  'follow up',
386
384
  'conversation',
387
385
  'chat',
388
- 'chief task',
386
+ 'agent task',
389
387
  'recent activity',
390
388
  'workstream update',
391
389
  ])
@@ -1,5 +1,5 @@
1
- import type { SdkUser, SdkUserRecord } from '@lota-sdk/shared/schemas/user'
2
- import { sdkUserRecordSchema, sdkUserSchema } from '@lota-sdk/shared/schemas/user'
1
+ import type { SdkUser, SdkUserRecord } from '@lota-sdk/shared'
2
+ import { sdkUserRecordSchema, sdkUserSchema } from '@lota-sdk/shared'
3
3
 
4
4
  import { BaseService } from '../db/base.service'
5
5
  import { ensureRecordId, recordIdToString } from '../db/record-id'
@@ -1,6 +1,5 @@
1
- import { toTimestamp, withCreatedAtMetadata } from '@lota-sdk/shared/runtime/chat-message-metadata'
2
- import { parseRowMetadata } from '@lota-sdk/shared/schemas/chat-message'
3
- import type { ChatMessage } from '@lota-sdk/shared/schemas/chat-message'
1
+ import { parseRowMetadata, toTimestamp, withCreatedAtMetadata } from '@lota-sdk/shared'
2
+ import type { ChatMessage } from '@lota-sdk/shared'
4
3
  import { RecordId, surql } from 'surrealdb'
5
4
  import { z } from 'zod'
6
5
 
@@ -1,4 +1,4 @@
1
- import { WORKSTREAM } from '@lota-sdk/shared/constants/workstream'
1
+ import { WORKSTREAM } from '@lota-sdk/shared'
2
2
 
3
3
  import { chatLogger } from '../config/logger'
4
4
  import type { RecordIdRef } from '../db/record-id'