@lota-sdk/core 0.2.3 → 0.3.0

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 (102) hide show
  1. package/infrastructure/schema/00_identity.surql +2 -2
  2. package/infrastructure/schema/00_thread.surql +75 -0
  3. package/infrastructure/schema/02_execution_plan.surql +10 -11
  4. package/infrastructure/schema/10_autonomous_job.surql +3 -3
  5. package/package.json +2 -2
  6. package/src/ai/definitions.ts +1 -1
  7. package/src/config/agent-defaults.ts +5 -5
  8. package/src/config/index.ts +1 -1
  9. package/src/config/thread-defaults.ts +72 -0
  10. package/src/create-runtime.ts +89 -93
  11. package/src/db/tables.ts +3 -3
  12. package/src/db/{workstream-message-row.ts → thread-message-row.ts} +3 -3
  13. package/src/queues/context-compaction.queue.ts +6 -6
  14. package/src/queues/plan-agent-heartbeat.queue.ts +3 -3
  15. package/src/queues/post-chat-memory.queue.ts +1 -1
  16. package/src/queues/title-generation.queue.ts +10 -13
  17. package/src/redis/index.ts +1 -1
  18. package/src/redis/stream-context.ts +1 -1
  19. package/src/runtime/agent-identity-overrides.ts +1 -1
  20. package/src/runtime/agent-runtime-policy.ts +19 -21
  21. package/src/runtime/chat-request-routing.ts +1 -1
  22. package/src/runtime/context-compaction-constants.ts +1 -1
  23. package/src/runtime/context-compaction.ts +1 -1
  24. package/src/runtime/execution-plan.ts +1 -1
  25. package/src/runtime/index.ts +1 -1
  26. package/src/runtime/memory-digest-policy.ts +1 -1
  27. package/src/runtime/plugin-types.ts +1 -1
  28. package/src/runtime/post-turn-side-effects.ts +35 -35
  29. package/src/runtime/runtime-config.ts +12 -12
  30. package/src/runtime/runtime-extensions.ts +11 -11
  31. package/src/runtime/social-chat-agent-runner.ts +3 -3
  32. package/src/runtime/social-chat-history.ts +1 -1
  33. package/src/runtime/social-chat.ts +6 -6
  34. package/src/runtime/team-consultation-orchestrator.ts +1 -1
  35. package/src/runtime/{workstream-chat-helpers.ts → thread-chat-helpers.ts} +7 -7
  36. package/src/runtime/{workstream-plan-turn.ts → thread-plan-turn.ts} +11 -17
  37. package/src/runtime/{workstream-turn-context.ts → thread-turn-context.ts} +10 -10
  38. package/src/services/agent-activity.service.ts +39 -44
  39. package/src/services/agent-executor.service.ts +17 -19
  40. package/src/services/attachment.service.ts +4 -8
  41. package/src/services/autonomous-job.service.ts +29 -28
  42. package/src/services/context-compaction.service.ts +19 -29
  43. package/src/services/execution-plan.service.ts +58 -70
  44. package/src/services/global-orchestrator.service.ts +5 -5
  45. package/src/services/index.ts +6 -6
  46. package/src/services/memory.service.ts +1 -1
  47. package/src/services/monitoring-window.service.ts +2 -2
  48. package/src/services/mutating-approval.service.ts +7 -10
  49. package/src/services/node-workspace.service.ts +8 -7
  50. package/src/services/notification.service.ts +1 -1
  51. package/src/services/organization.service.ts +9 -9
  52. package/src/services/ownership-dispatcher.service.ts +13 -19
  53. package/src/services/plan-agent-heartbeat.service.ts +13 -13
  54. package/src/services/plan-agent-query.service.ts +7 -7
  55. package/src/services/plan-artifact.service.ts +1 -2
  56. package/src/services/plan-coordination.service.ts +4 -4
  57. package/src/services/plan-cycle.service.ts +7 -7
  58. package/src/services/plan-deadline.service.ts +4 -4
  59. package/src/services/plan-event-delivery.service.ts +8 -12
  60. package/src/services/plan-executor.service.ts +16 -37
  61. package/src/services/plan-run-data.ts +27 -8
  62. package/src/services/plan-run.service.ts +7 -9
  63. package/src/services/plan-scheduler.service.ts +4 -4
  64. package/src/services/plan-template.service.ts +2 -2
  65. package/src/services/plan-validator.service.ts +0 -11
  66. package/src/services/plugin-executor.service.ts +1 -1
  67. package/src/services/queue-job.service.ts +1 -1
  68. package/src/services/recent-activity-title.service.ts +1 -1
  69. package/src/services/recent-activity.service.ts +4 -4
  70. package/src/services/system-executor.service.ts +2 -2
  71. package/src/services/{workstream-message.service.ts → thread-message.service.ts} +72 -76
  72. package/src/services/thread-plan-registry.service.ts +22 -0
  73. package/src/services/thread-title.service.ts +39 -0
  74. package/src/services/{workstream-turn-preparation.service.ts → thread-turn-preparation.service.ts} +131 -143
  75. package/src/services/{workstream-turn.ts → thread-turn.ts} +27 -31
  76. package/src/services/thread.service.ts +707 -0
  77. package/src/services/thread.types.ts +17 -0
  78. package/src/storage/attachment-storage.service.ts +4 -4
  79. package/src/system-agents/index.ts +1 -1
  80. package/src/system-agents/memory.agent.ts +1 -1
  81. package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -2
  82. package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
  83. package/src/system-agents/researcher.agent.ts +3 -3
  84. package/src/system-agents/{workstream-router.agent.ts → thread-router.agent.ts} +21 -21
  85. package/src/system-agents/title-generator.agent.ts +8 -8
  86. package/src/tools/execution-plan.tool.ts +39 -40
  87. package/src/tools/memory-block.tool.ts +4 -4
  88. package/src/tools/research-topic.tool.ts +1 -0
  89. package/src/tools/search-web.tool.ts +1 -1
  90. package/src/tools/search.tool.ts +4 -4
  91. package/src/tools/team-think.tool.ts +9 -9
  92. package/src/workers/regular-chat-memory-digest.helpers.ts +1 -1
  93. package/src/workers/regular-chat-memory-digest.runner.ts +43 -43
  94. package/src/workers/skill-extraction.runner.ts +9 -13
  95. package/src/workers/utils/{workstream-message-query.ts → thread-message-query.ts} +21 -21
  96. package/infrastructure/schema/00_workstream.surql +0 -64
  97. package/src/config/workstream-defaults.ts +0 -72
  98. package/src/services/workstream-plan-registry.service.ts +0 -22
  99. package/src/services/workstream-title.service.ts +0 -42
  100. package/src/services/workstream.service.ts +0 -803
  101. package/src/services/workstream.types.ts +0 -17
  102. /package/src/services/{workstream-constants.ts → thread-constants.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  DEFINE TABLE IF NOT EXISTS organization SCHEMAFULL;
2
2
  DEFINE FIELD IF NOT EXISTS name ON TABLE organization TYPE string;
3
- DEFINE FIELD IF NOT EXISTS regularChatDigestLastWorkstreamCursorCreatedAt ON TABLE organization TYPE option<datetime>;
4
- DEFINE FIELD IF NOT EXISTS regularChatDigestLastWorkstreamCursorId ON TABLE organization TYPE option<string>;
3
+ DEFINE FIELD IF NOT EXISTS regularChatDigestLastThreadCursorCreatedAt ON TABLE organization TYPE option<datetime>;
4
+ DEFINE FIELD IF NOT EXISTS regularChatDigestLastThreadCursorId ON TABLE organization TYPE option<string>;
5
5
  DEFINE FIELD IF NOT EXISTS skillExtractionLastCursorId ON TABLE organization TYPE option<string>;
6
6
  DEFINE FIELD IF NOT EXISTS skillExtractionLastCursorCreatedAt ON TABLE organization TYPE option<datetime>;
7
7
  DEFINE FIELD IF NOT EXISTS createdAt ON TABLE organization TYPE datetime DEFAULT time::now() READONLY;
@@ -0,0 +1,75 @@
1
+ DEFINE TABLE thread SCHEMAFULL;
2
+
3
+ DEFINE FIELD organizationId ON thread TYPE record<organization>;
4
+ DEFINE FIELD userId ON thread TYPE record<user>;
5
+ DEFINE FIELD type ON thread TYPE string
6
+ ASSERT $value IN ['default', 'topic', 'thread', 'group']
7
+ DEFAULT 'group';
8
+ DEFINE FIELD agentId ON thread TYPE option<string>;
9
+ DEFINE FIELD threadType ON thread TYPE option<string>;
10
+ DEFINE FIELD members ON thread TYPE option<array<string>> DEFAULT [];
11
+ DEFINE FIELD title ON thread TYPE option<string>;
12
+ DEFINE FIELD nameGenerated ON thread TYPE bool DEFAULT false;
13
+ DEFINE FIELD status ON thread TYPE string
14
+ ASSERT $value IN ['active', 'archived']
15
+ DEFAULT 'active';
16
+ DEFINE FIELD activeRunId ON thread TYPE option<string>;
17
+ DEFINE FIELD activeStreamId ON thread TYPE option<string>;
18
+ DEFINE FIELD memoryBlock ON thread TYPE option<string>;
19
+ DEFINE FIELD memoryBlockSummary ON thread TYPE option<string>;
20
+ DEFINE FIELD compactionSummary ON thread TYPE option<string>;
21
+ DEFINE FIELD lastCompactedMessageId ON thread TYPE option<string>;
22
+ DEFINE FIELD isCompacting ON thread TYPE bool DEFAULT false;
23
+ DEFINE FIELD turnCount ON thread TYPE int DEFAULT 0;
24
+ DEFINE FIELD createdAt ON thread TYPE datetime DEFAULT time::now();
25
+ DEFINE FIELD updatedAt ON thread TYPE datetime DEFAULT time::now() VALUE time::now();
26
+
27
+ DEFINE INDEX threadDefaultUniqueIdx ON thread
28
+ FIELDS userId, organizationId, agentId
29
+ WHERE type = 'default' UNIQUE;
30
+
31
+ DEFINE INDEX threadThreadUniqueIdx ON thread
32
+ FIELDS userId, organizationId, threadType
33
+ WHERE type = 'thread' UNIQUE;
34
+
35
+ DEFINE INDEX threadOrgIdx ON thread FIELDS organizationId;
36
+ DEFINE INDEX threadUserIdx ON thread FIELDS userId;
37
+ DEFINE INDEX threadUserOrgTypeUpdatedIdx ON thread
38
+ FIELDS userId, organizationId, type, updatedAt;
39
+ DEFINE INDEX threadUserOrgStatusTypeUpdatedIdx ON thread
40
+ FIELDS userId, organizationId, status, type, updatedAt;
41
+
42
+ # Thread Message table (AI SDK UIMessage persistence).
43
+ # parts uses OVERWRITE on the wildcard to override the implicit non-FLEXIBLE
44
+ # definition that array<object> creates — this is the only way to allow
45
+ # arbitrary nested object shapes inside the array on SCHEMAFULL tables.
46
+ DEFINE TABLE threadMessage SCHEMAFULL;
47
+ DEFINE FIELD threadId ON TABLE threadMessage TYPE record<thread> REFERENCE ON DELETE CASCADE;
48
+ DEFINE FIELD messageId ON TABLE threadMessage TYPE string;
49
+ DEFINE FIELD role ON TABLE threadMessage TYPE string;
50
+ DEFINE FIELD parts ON TABLE threadMessage TYPE array<object> FLEXIBLE;
51
+ DEFINE FIELD OVERWRITE parts.* ON TABLE threadMessage TYPE object FLEXIBLE;
52
+ DEFINE FIELD metadata ON TABLE threadMessage TYPE option<object> FLEXIBLE;
53
+ DEFINE FIELD createdAt ON TABLE threadMessage TYPE datetime DEFAULT time::now() READONLY;
54
+ DEFINE FIELD updatedAt ON TABLE threadMessage TYPE datetime VALUE time::now();
55
+
56
+ DEFINE INDEX threadMessageThreadIdx ON TABLE threadMessage COLUMNS threadId;
57
+ DEFINE INDEX threadMessageThreadCreatedIdx ON TABLE threadMessage COLUMNS threadId, createdAt;
58
+ DEFINE INDEX threadMessageThreadMessageUniqueIdx ON TABLE threadMessage COLUMNS threadId, messageId UNIQUE;
59
+
60
+ # Thread attachments.
61
+ DEFINE TABLE threadAttachment SCHEMAFULL;
62
+ DEFINE FIELD threadId ON TABLE threadAttachment TYPE record<thread> REFERENCE ON DELETE CASCADE;
63
+ DEFINE FIELD messageId ON TABLE threadAttachment TYPE record<threadMessage> REFERENCE ON DELETE CASCADE;
64
+ DEFINE FIELD attachmentType ON TABLE threadAttachment TYPE string;
65
+ DEFINE FIELD name ON TABLE threadAttachment TYPE string;
66
+ DEFINE FIELD contentType ON TABLE threadAttachment TYPE string;
67
+ DEFINE FIELD storageKey ON TABLE threadAttachment TYPE option<string>;
68
+ DEFINE FIELD sizeBytes ON TABLE threadAttachment TYPE option<int>;
69
+ DEFINE FIELD url ON TABLE threadAttachment TYPE option<string>;
70
+ DEFINE FIELD createdAt ON TABLE threadAttachment TYPE datetime DEFAULT time::now() READONLY;
71
+ DEFINE FIELD updatedAt ON TABLE threadAttachment TYPE datetime VALUE time::now();
72
+
73
+ DEFINE INDEX threadAttachmentThreadIdx ON TABLE threadAttachment COLUMNS threadId;
74
+ DEFINE INDEX threadAttachmentMessageIdx ON TABLE threadAttachment COLUMNS messageId;
75
+ DEFINE INDEX threadAttachmentThreadMessageIdx ON TABLE threadAttachment COLUMNS threadId, messageId;
@@ -2,7 +2,7 @@
2
2
 
3
3
  DEFINE TABLE IF NOT EXISTS planSpec SCHEMAFULL;
4
4
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE planSpec TYPE record<organization>;
5
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE planSpec TYPE record<workstream> REFERENCE ON DELETE CASCADE;
5
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE planSpec TYPE record<thread> REFERENCE ON DELETE CASCADE;
6
6
  DEFINE FIELD IF NOT EXISTS title ON TABLE planSpec TYPE string;
7
7
  DEFINE FIELD IF NOT EXISTS objective ON TABLE planSpec TYPE string;
8
8
  DEFINE FIELD IF NOT EXISTS version ON TABLE planSpec TYPE int;
@@ -29,8 +29,8 @@ DEFINE FIELD IF NOT EXISTS updatedAt ON TABLE planSpec TYPE datetime VALUE time:
29
29
  DEFINE FIELD IF NOT EXISTS compiledAt ON TABLE planSpec TYPE option<datetime>;
30
30
 
31
31
  DEFINE INDEX IF NOT EXISTS planSpecOrgIdx ON TABLE planSpec COLUMNS organizationId;
32
- DEFINE INDEX IF NOT EXISTS planSpecWorkstreamIdx ON TABLE planSpec COLUMNS workstreamId;
33
- DEFINE INDEX IF NOT EXISTS planSpecWorkstreamStatusIdx ON TABLE planSpec COLUMNS workstreamId, status;
32
+ DEFINE INDEX IF NOT EXISTS planSpecThreadIdx ON TABLE planSpec COLUMNS threadId;
33
+ DEFINE INDEX IF NOT EXISTS planSpecThreadStatusIdx ON TABLE planSpec COLUMNS threadId, status;
34
34
 
35
35
  DEFINE TABLE IF NOT EXISTS planNodeSpec SCHEMAFULL;
36
36
  DEFINE FIELD IF NOT EXISTS planSpecId ON TABLE planNodeSpec TYPE record<planSpec> REFERENCE ON DELETE CASCADE;
@@ -85,7 +85,7 @@ DEFINE INDEX IF NOT EXISTS planNodeSpecPlanPositionIdx ON TABLE planNodeSpec COL
85
85
  DEFINE TABLE IF NOT EXISTS planRun SCHEMAFULL;
86
86
  DEFINE FIELD IF NOT EXISTS planSpecId ON TABLE planRun TYPE record<planSpec> REFERENCE ON DELETE CASCADE;
87
87
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE planRun TYPE record<organization>;
88
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE planRun TYPE record<workstream> REFERENCE ON DELETE CASCADE;
88
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE planRun TYPE record<thread> REFERENCE ON DELETE CASCADE;
89
89
  DEFINE FIELD IF NOT EXISTS leadAgentId ON TABLE planRun TYPE string;
90
90
  DEFINE FIELD IF NOT EXISTS status ON TABLE planRun TYPE string;
91
91
  DEFINE FIELD IF NOT EXISTS currentNodeId ON TABLE planRun TYPE option<string>;
@@ -102,8 +102,8 @@ DEFINE FIELD IF NOT EXISTS startedAt ON TABLE planRun TYPE option<datetime>;
102
102
  DEFINE FIELD IF NOT EXISTS completedAt ON TABLE planRun TYPE option<datetime>;
103
103
 
104
104
  DEFINE INDEX IF NOT EXISTS planRunOrgIdx ON TABLE planRun COLUMNS organizationId;
105
- DEFINE INDEX IF NOT EXISTS planRunWorkstreamIdx ON TABLE planRun COLUMNS workstreamId;
106
- DEFINE INDEX IF NOT EXISTS planRunWorkstreamStatusIdx ON TABLE planRun COLUMNS workstreamId, status;
105
+ DEFINE INDEX IF NOT EXISTS planRunThreadIdx ON TABLE planRun COLUMNS threadId;
106
+ DEFINE INDEX IF NOT EXISTS planRunThreadStatusIdx ON TABLE planRun COLUMNS threadId, status;
107
107
  DEFINE INDEX IF NOT EXISTS planRunSpecIdx ON TABLE planRun COLUMNS planSpecId;
108
108
 
109
109
  DEFINE TABLE IF NOT EXISTS planNodeRun SCHEMAFULL;
@@ -116,7 +116,6 @@ DEFINE FIELD IF NOT EXISTS retryCount ON TABLE planNodeRun TYPE int DEFAULT 0;
116
116
  DEFINE FIELD IF NOT EXISTS resolvedInput ON TABLE planNodeRun TYPE option<object> FLEXIBLE;
117
117
  DEFINE FIELD IF NOT EXISTS latestStructuredOutput ON TABLE planNodeRun TYPE option<object> FLEXIBLE;
118
118
  DEFINE FIELD IF NOT EXISTS latestNotes ON TABLE planNodeRun TYPE option<string>;
119
- DEFINE FIELD IF NOT EXISTS handoffContext ON TABLE planNodeRun TYPE option<object> FLEXIBLE;
120
119
  DEFINE FIELD IF NOT EXISTS latestAttemptId ON TABLE planNodeRun TYPE option<record<planNodeAttempt>>;
121
120
  DEFINE FIELD IF NOT EXISTS blockedReason ON TABLE planNodeRun TYPE option<string>;
122
121
  DEFINE FIELD IF NOT EXISTS failureClass ON TABLE planNodeRun TYPE option<string>;
@@ -232,7 +231,7 @@ DEFINE INDEX IF NOT EXISTS planEventRunTimeIdx ON TABLE planEvent COLUMNS runId,
232
231
 
233
232
  DEFINE TABLE IF NOT EXISTS planSchedule SCHEMAFULL;
234
233
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE planSchedule TYPE record<organization>;
235
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE planSchedule TYPE record<workstream> REFERENCE ON DELETE CASCADE;
234
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE planSchedule TYPE record<thread> REFERENCE ON DELETE CASCADE;
236
235
  DEFINE FIELD IF NOT EXISTS planSpecId ON TABLE planSchedule TYPE option<record<planSpec>>;
237
236
  DEFINE FIELD IF NOT EXISTS runId ON TABLE planSchedule TYPE option<record<planRun>>;
238
237
  DEFINE FIELD IF NOT EXISTS nodeId ON TABLE planSchedule TYPE option<string>;
@@ -245,7 +244,7 @@ DEFINE FIELD IF NOT EXISTS createdAt ON TABLE planSchedule TYPE datetime DEFAULT
245
244
  DEFINE FIELD IF NOT EXISTS updatedAt ON TABLE planSchedule TYPE datetime VALUE time::now();
246
245
  DEFINE INDEX IF NOT EXISTS planScheduleStatusIdx ON TABLE planSchedule COLUMNS status;
247
246
  DEFINE INDEX IF NOT EXISTS planScheduleNextFireIdx ON TABLE planSchedule COLUMNS status, nextFireAt;
248
- DEFINE INDEX IF NOT EXISTS planScheduleWorkstreamIdx ON TABLE planSchedule COLUMNS workstreamId;
247
+ DEFINE INDEX IF NOT EXISTS planScheduleThreadIdx ON TABLE planSchedule COLUMNS threadId;
249
248
 
250
249
  DEFINE TABLE IF NOT EXISTS planTemplate SCHEMAFULL;
251
250
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE planTemplate TYPE record<organization>;
@@ -262,7 +261,7 @@ DEFINE INDEX IF NOT EXISTS planTemplateOrgNameIdx ON TABLE planTemplate COLUMNS
262
261
 
263
262
  DEFINE TABLE IF NOT EXISTS planCycle SCHEMAFULL;
264
263
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE planCycle TYPE record<organization>;
265
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE planCycle TYPE record<workstream> REFERENCE ON DELETE CASCADE;
264
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE planCycle TYPE record<thread> REFERENCE ON DELETE CASCADE;
266
265
  DEFINE FIELD IF NOT EXISTS templateId ON TABLE planCycle TYPE record<planTemplate>;
267
266
  DEFINE FIELD IF NOT EXISTS name ON TABLE planCycle TYPE string;
268
267
  DEFINE FIELD IF NOT EXISTS schedule ON TABLE planCycle TYPE object FLEXIBLE;
@@ -273,5 +272,5 @@ DEFINE FIELD IF NOT EXISTS currentRunId ON TABLE planCycle TYPE option<record<pl
273
272
  DEFINE FIELD IF NOT EXISTS scheduleId ON TABLE planCycle TYPE option<record<planSchedule>>;
274
273
  DEFINE FIELD IF NOT EXISTS createdAt ON TABLE planCycle TYPE datetime DEFAULT time::now() READONLY;
275
274
  DEFINE FIELD IF NOT EXISTS updatedAt ON TABLE planCycle TYPE datetime VALUE time::now();
276
- DEFINE INDEX IF NOT EXISTS planCycleWorkstreamIdx ON TABLE planCycle COLUMNS workstreamId;
275
+ DEFINE INDEX IF NOT EXISTS planCycleThreadIdx ON TABLE planCycle COLUMNS threadId;
277
276
  DEFINE INDEX IF NOT EXISTS planCycleStatusIdx ON TABLE planCycle COLUMNS status;
@@ -2,7 +2,7 @@ DEFINE TABLE IF NOT EXISTS autonomousJob SCHEMAFULL;
2
2
  DEFINE FIELD IF NOT EXISTS organizationId ON TABLE autonomousJob TYPE record<organization>;
3
3
  DEFINE FIELD IF NOT EXISTS ownerUserId ON TABLE autonomousJob TYPE record<user>;
4
4
  DEFINE FIELD IF NOT EXISTS ownerUserName ON TABLE autonomousJob TYPE option<string>;
5
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE autonomousJob TYPE record<workstream> REFERENCE ON DELETE CASCADE;
5
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE autonomousJob TYPE record<thread> REFERENCE ON DELETE CASCADE;
6
6
  DEFINE FIELD IF NOT EXISTS agentId ON TABLE autonomousJob TYPE string;
7
7
  DEFINE FIELD IF NOT EXISTS title ON TABLE autonomousJob TYPE string;
8
8
  DEFINE FIELD IF NOT EXISTS prompt ON TABLE autonomousJob TYPE string;
@@ -20,12 +20,12 @@ DEFINE FIELD IF NOT EXISTS createdAt ON TABLE autonomousJob TYPE datetime DEFAUL
20
20
  DEFINE FIELD IF NOT EXISTS updatedAt ON TABLE autonomousJob TYPE datetime VALUE time::now();
21
21
 
22
22
  DEFINE INDEX IF NOT EXISTS autonomousJobOrgStatusIdx ON TABLE autonomousJob COLUMNS organizationId, status;
23
- DEFINE INDEX IF NOT EXISTS autonomousJobWorkstreamIdx ON TABLE autonomousJob COLUMNS workstreamId;
23
+ DEFINE INDEX IF NOT EXISTS autonomousJobThreadIdx ON TABLE autonomousJob COLUMNS threadId;
24
24
  DEFINE INDEX IF NOT EXISTS autonomousJobOwnerIdx ON TABLE autonomousJob COLUMNS ownerUserId;
25
25
 
26
26
  DEFINE TABLE IF NOT EXISTS autonomousJobRun SCHEMAFULL;
27
27
  DEFINE FIELD IF NOT EXISTS autonomousJobId ON TABLE autonomousJobRun TYPE record<autonomousJob> REFERENCE ON DELETE CASCADE;
28
- DEFINE FIELD IF NOT EXISTS workstreamId ON TABLE autonomousJobRun TYPE record<workstream> REFERENCE ON DELETE CASCADE;
28
+ DEFINE FIELD IF NOT EXISTS threadId ON TABLE autonomousJobRun TYPE record<thread> REFERENCE ON DELETE CASCADE;
29
29
  DEFINE FIELD IF NOT EXISTS queueJobId ON TABLE autonomousJobRun TYPE option<record<queueJob>>;
30
30
  DEFINE FIELD IF NOT EXISTS status ON TABLE autonomousJobRun TYPE string;
31
31
  DEFINE FIELD IF NOT EXISTS inputMessageId ON TABLE autonomousJobRun TYPE option<string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lota-sdk/core",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -32,7 +32,7 @@
32
32
  "@chat-adapter/slack": "^4.23.0",
33
33
  "@chat-adapter/state-ioredis": "^4.23.0",
34
34
  "@logtape/logtape": "^2.0.5",
35
- "@lota-sdk/shared": "0.2.3",
35
+ "@lota-sdk/shared": "0.3.0",
36
36
  "@mendable/firecrawl-js": "^4.18.1",
37
37
  "@surrealdb/node": "^3.0.3",
38
38
  "ai": "^6.0.145",
@@ -129,7 +129,7 @@ Use this skill for any Lota SDK task that changes SurrealQL schema files, DB ser
129
129
 
130
130
  <schema-rules>
131
131
  - Default schema files to \`IF NOT EXISTS\`. Do not add migration DML, compatibility branches, or fallback logic.
132
- - Avoid \`OVERWRITE\` unless SurrealDB itself requires a specific wildcard exception on a fresh database shape, such as \`workstreamMessage.parts.*\` or \`planSpec.contextEnrichments.*\`.
132
+ - Avoid \`OVERWRITE\` unless SurrealDB itself requires a specific wildcard exception on a fresh database shape, such as \`threadMessage.parts.*\` or \`planSpec.contextEnrichments.*\`.
133
133
  - Treat the database as fresh. Replace incorrect definitions directly instead of layering migrations.
134
134
  - Let SurrealDB own \`updatedAt\` when the schema uses \`VALUE time::now()\`. Do not write that field from application code.
135
135
  - Keep flexible object fields explicit, for example \`TYPE option<object> FLEXIBLE\` or \`TYPE array<object> FLEXIBLE\`.
@@ -17,7 +17,7 @@ export let agentRoster: readonly string[] = []
17
17
  export let leadAgentId = ''
18
18
  export let teamConsultParticipants: readonly string[] = []
19
19
 
20
- export interface CoreWorkstreamProfile {
20
+ export interface CoreThreadProfile {
21
21
  config: { coreType: string; agentId: string; title: string }
22
22
  members: readonly string[]
23
23
  tools: readonly string[]
@@ -25,7 +25,7 @@ export interface CoreWorkstreamProfile {
25
25
  instructions: string
26
26
  }
27
27
 
28
- export let getCoreWorkstreamProfile: (coreType: string) => CoreWorkstreamProfile = (_coreType) => ({
28
+ export let getCoreThreadProfile: (coreType: string) => CoreThreadProfile = (_coreType) => ({
29
29
  config: { coreType: _coreType, agentId: '', title: '' },
30
30
  members: [],
31
31
  tools: [],
@@ -41,7 +41,7 @@ export function configureAgents(config: {
41
41
  descriptions?: Record<string, string>
42
42
  routerModelId?: string
43
43
  teamConsultParticipants: readonly string[]
44
- getCoreWorkstreamProfile?: (coreType: string) => CoreWorkstreamProfile
44
+ getCoreThreadProfile?: (coreType: string) => CoreThreadProfile
45
45
  }): void {
46
46
  if (!config.roster.includes(config.leadAgentId)) {
47
47
  throw new Error(`Lead agent "${config.leadAgentId}" must be present in the configured roster.`)
@@ -54,8 +54,8 @@ export function configureAgents(config: {
54
54
  agentDescriptions = config.descriptions ?? {}
55
55
  routerModelId = config.routerModelId
56
56
  teamConsultParticipants = config.teamConsultParticipants
57
- if (config.getCoreWorkstreamProfile) {
58
- getCoreWorkstreamProfile = config.getCoreWorkstreamProfile
57
+ if (config.getCoreThreadProfile) {
58
+ getCoreThreadProfile = config.getCoreThreadProfile
59
59
  }
60
60
  _agentRosterSet = null
61
61
  _aliasMap = null
@@ -5,4 +5,4 @@ export * from './constants'
5
5
  export * from './logger'
6
6
  export * from './model-constants'
7
7
  export * from './search'
8
- export * from './workstream-defaults'
8
+ export * from './thread-defaults'
@@ -0,0 +1,72 @@
1
+ export interface ThreadBootstrapWelcomeConfig {
2
+ defaultAgentId: string
3
+ buildMessageText: (params: { userName?: string | null }) => string
4
+ }
5
+
6
+ export interface LotaThreadBootstrapConfig {
7
+ onboardingDefaultAgents?: readonly string[]
8
+ completedDefaultAgents?: readonly string[]
9
+ threadTypesAfterOnboarding?: readonly string[]
10
+ ensureDefaultGroupOnCompleted?: boolean
11
+ onboardingWelcome?: ThreadBootstrapWelcomeConfig
12
+ }
13
+
14
+ export interface LotaThreadConfig {
15
+ bootstrap?: LotaThreadBootstrapConfig
16
+ }
17
+
18
+ interface ResolvedThreadBootstrapConfig {
19
+ onboardingDefaultAgents: readonly string[]
20
+ completedDefaultAgents: readonly string[]
21
+ threadTypesAfterOnboarding: readonly string[]
22
+ ensureDefaultGroupOnCompleted: boolean
23
+ onboardingWelcome?: ThreadBootstrapWelcomeConfig
24
+ }
25
+
26
+ const DEFAULT_THREAD_BOOTSTRAP_CONFIG: ResolvedThreadBootstrapConfig = {
27
+ onboardingDefaultAgents: [],
28
+ completedDefaultAgents: [],
29
+ threadTypesAfterOnboarding: [],
30
+ ensureDefaultGroupOnCompleted: true,
31
+ }
32
+
33
+ let resolvedThreadBootstrapConfig: ResolvedThreadBootstrapConfig = DEFAULT_THREAD_BOOTSTRAP_CONFIG
34
+
35
+ function withDedupedStrings(values: readonly string[]): string[] {
36
+ const seen = new Set<string>()
37
+ const deduped: string[] = []
38
+
39
+ for (const value of values) {
40
+ const normalized = value.trim()
41
+ if (!normalized || seen.has(normalized)) continue
42
+ seen.add(normalized)
43
+ deduped.push(normalized)
44
+ }
45
+
46
+ return deduped
47
+ }
48
+
49
+ export function configureThreads(params: { agentRoster: readonly string[]; config?: LotaThreadConfig }): void {
50
+ const bootstrap = params.config?.bootstrap
51
+ const onboardingWelcome = bootstrap?.onboardingWelcome
52
+ const onboardingDefaultAgents = withDedupedStrings([
53
+ ...(bootstrap?.onboardingDefaultAgents ?? params.agentRoster),
54
+ ...(onboardingWelcome ? [onboardingWelcome.defaultAgentId] : []),
55
+ ])
56
+
57
+ resolvedThreadBootstrapConfig = {
58
+ onboardingDefaultAgents,
59
+ completedDefaultAgents: withDedupedStrings(bootstrap?.completedDefaultAgents ?? params.agentRoster),
60
+ threadTypesAfterOnboarding: withDedupedStrings(bootstrap?.threadTypesAfterOnboarding ?? []),
61
+ ensureDefaultGroupOnCompleted: bootstrap?.ensureDefaultGroupOnCompleted ?? true,
62
+ ...(onboardingWelcome ? { onboardingWelcome } : {}),
63
+ }
64
+ }
65
+
66
+ export function getThreadBootstrapConfig(): ResolvedThreadBootstrapConfig {
67
+ return resolvedThreadBootstrapConfig
68
+ }
69
+
70
+ export function resolveOnboardingOwnerAgentId(defaultLeadAgentId: string): string {
71
+ return resolvedThreadBootstrapConfig.onboardingWelcome?.defaultAgentId ?? defaultLeadAgentId
72
+ }