@lota-sdk/core 0.4.0 → 0.4.2
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/02_execution_plan.surql +30 -0
- package/package.json +2 -2
- package/src/create-runtime.ts +29 -1
- package/src/db/tables.ts +1 -0
- package/src/queues/autonomous-job.queue.ts +31 -20
- package/src/queues/document-processor.queue.ts +13 -9
- package/src/queues/memory-consolidation.queue.ts +14 -9
- package/src/queues/queue-factory.ts +13 -9
- package/src/runtime/agent-runtime-policy.ts +2 -0
- package/src/runtime/thread-chat-helpers.ts +54 -0
- package/src/services/artifact.service.ts +371 -0
- package/src/services/autonomous-job.service.ts +16 -12
- package/src/services/execution-plan.service.ts +4 -13
- package/src/services/index.ts +1 -0
- package/src/services/ownership-dispatcher.service.ts +4 -0
- package/src/services/plan-artifact.service.ts +7 -1
- package/src/services/plan-coordination.service.ts +23 -18
- package/src/services/plan-executor.service.ts +360 -294
- package/src/services/plan-run.service.ts +4 -0
- package/src/services/plan-template.service.ts +57 -2
- package/src/services/plan-validator.service.ts +1 -1
- package/src/services/queue-job.service.ts +180 -134
- package/src/services/thread-turn-preparation.service.ts +36 -8
- package/src/services/thread-turn.ts +4 -0
- package/src/storage/generated-document-storage.service.ts +8 -0
- package/src/tools/execution-plan.tool.ts +43 -15
- package/src/workers/worker-utils.ts +10 -2
|
@@ -146,6 +146,34 @@ DEFINE INDEX IF NOT EXISTS planNodeAttemptRunIdx ON TABLE planNodeAttempt COLUMN
|
|
|
146
146
|
DEFINE INDEX IF NOT EXISTS planNodeAttemptNodeRunIdx ON TABLE planNodeAttempt COLUMNS nodeRunId;
|
|
147
147
|
DEFINE INDEX IF NOT EXISTS planNodeAttemptRunNodeIdx ON TABLE planNodeAttempt COLUMNS runId, nodeId;
|
|
148
148
|
|
|
149
|
+
DEFINE TABLE IF NOT EXISTS artifact SCHEMAFULL;
|
|
150
|
+
DEFINE FIELD IF NOT EXISTS organizationId ON TABLE artifact TYPE record<organization>;
|
|
151
|
+
DEFINE FIELD IF NOT EXISTS authorAgentId ON TABLE artifact TYPE string;
|
|
152
|
+
DEFINE FIELD IF NOT EXISTS title ON TABLE artifact TYPE string;
|
|
153
|
+
DEFINE FIELD IF NOT EXISTS artifactKind ON TABLE artifact TYPE string;
|
|
154
|
+
DEFINE FIELD IF NOT EXISTS templateId ON TABLE artifact TYPE string;
|
|
155
|
+
DEFINE FIELD IF NOT EXISTS canonicalKey ON TABLE artifact TYPE string;
|
|
156
|
+
DEFINE FIELD IF NOT EXISTS version ON TABLE artifact TYPE int;
|
|
157
|
+
DEFINE FIELD IF NOT EXISTS status ON TABLE artifact TYPE string;
|
|
158
|
+
DEFINE FIELD IF NOT EXISTS supersededBy ON TABLE artifact TYPE option<record<artifact>>;
|
|
159
|
+
DEFINE FIELD IF NOT EXISTS storageKey ON TABLE artifact TYPE string;
|
|
160
|
+
DEFINE FIELD IF NOT EXISTS description ON TABLE artifact TYPE option<string>;
|
|
161
|
+
DEFINE FIELD IF NOT EXISTS tags ON TABLE artifact TYPE array DEFAULT [];
|
|
162
|
+
DEFINE FIELD IF NOT EXISTS references ON TABLE artifact TYPE array DEFAULT [];
|
|
163
|
+
DEFINE FIELD IF NOT EXISTS references.* ON TABLE artifact TYPE object FLEXIBLE;
|
|
164
|
+
DEFINE FIELD IF NOT EXISTS references.*.uri ON TABLE artifact TYPE string;
|
|
165
|
+
DEFINE FIELD IF NOT EXISTS references.*.targetType ON TABLE artifact TYPE string;
|
|
166
|
+
DEFINE FIELD IF NOT EXISTS references.*.targetId ON TABLE artifact TYPE string;
|
|
167
|
+
DEFINE FIELD IF NOT EXISTS sourceThreadId ON TABLE artifact TYPE option<record<thread>>;
|
|
168
|
+
DEFINE FIELD IF NOT EXISTS sourcePlanRunId ON TABLE artifact TYPE option<record<planRun>>;
|
|
169
|
+
DEFINE FIELD IF NOT EXISTS sourcePlanNodeId ON TABLE artifact TYPE option<string>;
|
|
170
|
+
DEFINE FIELD IF NOT EXISTS createdAt ON TABLE artifact TYPE datetime DEFAULT time::now() READONLY;
|
|
171
|
+
DEFINE FIELD IF NOT EXISTS updatedAt ON TABLE artifact TYPE datetime VALUE time::now();
|
|
172
|
+
|
|
173
|
+
DEFINE INDEX IF NOT EXISTS artifactOrgCanonicalVersionIdx ON TABLE artifact COLUMNS organizationId, canonicalKey, version UNIQUE;
|
|
174
|
+
DEFINE INDEX IF NOT EXISTS artifactOrgCanonicalStatusIdx ON TABLE artifact COLUMNS organizationId, canonicalKey, status;
|
|
175
|
+
DEFINE INDEX IF NOT EXISTS artifactOrgStatusUpdatedIdx ON TABLE artifact COLUMNS organizationId, status, updatedAt;
|
|
176
|
+
|
|
149
177
|
DEFINE TABLE IF NOT EXISTS planArtifact SCHEMAFULL;
|
|
150
178
|
DEFINE FIELD IF NOT EXISTS runId ON TABLE planArtifact TYPE record<planRun> REFERENCE ON DELETE CASCADE;
|
|
151
179
|
DEFINE FIELD IF NOT EXISTS nodeId ON TABLE planArtifact TYPE string;
|
|
@@ -155,7 +183,9 @@ DEFINE FIELD IF NOT EXISTS kind ON TABLE planArtifact TYPE string;
|
|
|
155
183
|
DEFINE FIELD IF NOT EXISTS pointer ON TABLE planArtifact TYPE string;
|
|
156
184
|
DEFINE FIELD IF NOT EXISTS schemaRef ON TABLE planArtifact TYPE option<string>;
|
|
157
185
|
DEFINE FIELD IF NOT EXISTS description ON TABLE planArtifact TYPE option<string>;
|
|
186
|
+
DEFINE FIELD IF NOT EXISTS content ON TABLE planArtifact TYPE option<string>;
|
|
158
187
|
DEFINE FIELD IF NOT EXISTS payload ON TABLE planArtifact TYPE option<object> FLEXIBLE;
|
|
188
|
+
DEFINE FIELD IF NOT EXISTS publishedArtifactId ON TABLE planArtifact TYPE option<record<artifact>>;
|
|
159
189
|
DEFINE FIELD IF NOT EXISTS createdAt ON TABLE planArtifact TYPE datetime DEFAULT time::now() READONLY;
|
|
160
190
|
|
|
161
191
|
DEFINE INDEX IF NOT EXISTS planArtifactRunIdx ON TABLE planArtifact COLUMNS runId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lota-sdk/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
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.4.
|
|
35
|
+
"@lota-sdk/shared": "0.4.2",
|
|
36
36
|
"@mendable/firecrawl-js": "^4.18.1",
|
|
37
37
|
"@surrealdb/node": "^3.0.3",
|
|
38
38
|
"ai": "^6.0.145",
|
package/src/create-runtime.ts
CHANGED
|
@@ -29,6 +29,8 @@ import type { LotaRuntimeSocialChat } from './runtime/social-chat'
|
|
|
29
29
|
import { createSocialChatRuntime } from './runtime/social-chat'
|
|
30
30
|
import type { agentActivityService } from './services/agent-activity.service'
|
|
31
31
|
import { agentActivityService as agentActivityServiceSingleton } from './services/agent-activity.service'
|
|
32
|
+
import type { artifactService } from './services/artifact.service'
|
|
33
|
+
import { artifactService as artifactServiceSingleton } from './services/artifact.service'
|
|
32
34
|
import type { attachmentService } from './services/attachment.service'
|
|
33
35
|
import { attachmentService as attachmentServiceSingleton } from './services/attachment.service'
|
|
34
36
|
import type { autonomousJobService } from './services/autonomous-job.service'
|
|
@@ -46,8 +48,18 @@ import type { organizationMemberService } from './services/organization-member.s
|
|
|
46
48
|
import { organizationMemberService as organizationMemberServiceSingleton } from './services/organization-member.service'
|
|
47
49
|
import type { organizationService } from './services/organization.service'
|
|
48
50
|
import { organizationService as organizationServiceSingleton } from './services/organization.service'
|
|
51
|
+
import type { planAgentHeartbeatService } from './services/plan-agent-heartbeat.service'
|
|
52
|
+
import { planAgentHeartbeatService as planAgentHeartbeatServiceSingleton } from './services/plan-agent-heartbeat.service'
|
|
49
53
|
import type { planAgentQueryService } from './services/plan-agent-query.service'
|
|
50
54
|
import { planAgentQueryService as planAgentQueryServiceSingleton } from './services/plan-agent-query.service'
|
|
55
|
+
import type { planCoordinationService } from './services/plan-coordination.service'
|
|
56
|
+
import { planCoordinationService as planCoordinationServiceSingleton } from './services/plan-coordination.service'
|
|
57
|
+
import type { planCycleService } from './services/plan-cycle.service'
|
|
58
|
+
import { planCycleService as planCycleServiceSingleton } from './services/plan-cycle.service'
|
|
59
|
+
import type { planSchedulerService } from './services/plan-scheduler.service'
|
|
60
|
+
import { planSchedulerService as planSchedulerServiceSingleton } from './services/plan-scheduler.service'
|
|
61
|
+
import type { planTemplateService } from './services/plan-template.service'
|
|
62
|
+
import { planTemplateService as planTemplateServiceSingleton } from './services/plan-template.service'
|
|
51
63
|
import type { recentActivityTitleService } from './services/recent-activity-title.service'
|
|
52
64
|
import { recentActivityTitleService as recentActivityTitleServiceSingleton } from './services/recent-activity-title.service'
|
|
53
65
|
import type { recentActivityService } from './services/recent-activity.service'
|
|
@@ -117,6 +129,7 @@ export interface LotaRuntime {
|
|
|
117
129
|
redis: RedisConnectionManager
|
|
118
130
|
closeRedisConnection: () => Promise<void>
|
|
119
131
|
agentActivityService: typeof agentActivityService
|
|
132
|
+
artifactService: typeof artifactService
|
|
120
133
|
attachmentService: typeof attachmentService
|
|
121
134
|
autonomousJobService: typeof autonomousJobService
|
|
122
135
|
documentChunkService: typeof documentChunkService
|
|
@@ -130,7 +143,12 @@ export interface LotaRuntime {
|
|
|
130
143
|
recentActivityTitleService: typeof recentActivityTitleService
|
|
131
144
|
socialChatHistoryService: typeof socialChatHistoryServiceSingleton
|
|
132
145
|
executionPlanService: typeof executionPlanService
|
|
146
|
+
planTemplateService: typeof planTemplateService
|
|
147
|
+
planCoordinationService: typeof planCoordinationService
|
|
148
|
+
planSchedulerService: typeof planSchedulerService
|
|
149
|
+
planAgentHeartbeatService: typeof planAgentHeartbeatService
|
|
133
150
|
planAgentQueryService: typeof planAgentQueryService
|
|
151
|
+
planCycleService: typeof planCycleService
|
|
134
152
|
threadMessageService: typeof threadMessageService
|
|
135
153
|
threadService: typeof threadService
|
|
136
154
|
threadTitleService: typeof threadTitleService
|
|
@@ -276,8 +294,12 @@ export async function createLotaRuntime(config: LotaRuntimeConfig): Promise<Lota
|
|
|
276
294
|
}
|
|
277
295
|
|
|
278
296
|
const pluginContributions = Object.values(pluginRuntime).map((plugin) => plugin.contributions)
|
|
279
|
-
const schemaFiles = [...getBuiltInSchemaFiles(), ...(runtimeConfig.extraSchemaFiles ?? [])]
|
|
280
297
|
const hostContributionSchemaFiles = pluginContributions.flatMap((plugin) => plugin.schemaFiles)
|
|
298
|
+
const schemaFiles = [
|
|
299
|
+
...getBuiltInSchemaFiles(),
|
|
300
|
+
...(runtimeConfig.extraSchemaFiles ?? []),
|
|
301
|
+
...hostContributionSchemaFiles,
|
|
302
|
+
]
|
|
281
303
|
const contributionEnvKeys = [...LOTA_RUNTIME_ENV_KEYS, ...pluginContributions.flatMap((plugin) => plugin.envKeys)]
|
|
282
304
|
const connectPluginDatabases = createPluginDatabaseConnector(pluginRuntime)
|
|
283
305
|
const workers = buildRuntimeWorkerRegistry(runtimeConfig.extraWorkers)
|
|
@@ -377,6 +399,7 @@ export async function createLotaRuntime(config: LotaRuntimeConfig): Promise<Lota
|
|
|
377
399
|
redis: redisManager,
|
|
378
400
|
closeRedisConnection: async () => await redisManager.closeConnection(),
|
|
379
401
|
agentActivityService: agentActivityServiceSingleton,
|
|
402
|
+
artifactService: artifactServiceSingleton,
|
|
380
403
|
attachmentService: attachmentServiceSingleton,
|
|
381
404
|
autonomousJobService: autonomousJobServiceSingleton,
|
|
382
405
|
documentChunkService: documentChunkServiceSingleton,
|
|
@@ -390,7 +413,12 @@ export async function createLotaRuntime(config: LotaRuntimeConfig): Promise<Lota
|
|
|
390
413
|
recentActivityTitleService: recentActivityTitleServiceSingleton,
|
|
391
414
|
socialChatHistoryService: socialChatHistoryServiceSingleton,
|
|
392
415
|
executionPlanService: executionPlanServiceSingleton,
|
|
416
|
+
planTemplateService: planTemplateServiceSingleton,
|
|
417
|
+
planCoordinationService: planCoordinationServiceSingleton,
|
|
418
|
+
planSchedulerService: planSchedulerServiceSingleton,
|
|
419
|
+
planAgentHeartbeatService: planAgentHeartbeatServiceSingleton,
|
|
393
420
|
planAgentQueryService: planAgentQueryServiceSingleton,
|
|
421
|
+
planCycleService: planCycleServiceSingleton,
|
|
394
422
|
threadMessageService: threadMessageServiceSingleton,
|
|
395
423
|
threadService: threadServiceSingleton,
|
|
396
424
|
threadTitleService: threadTitleServiceSingleton,
|
package/src/db/tables.ts
CHANGED
|
@@ -13,6 +13,7 @@ export const TABLES = {
|
|
|
13
13
|
PLAN_NODE_RUN: 'planNodeRun',
|
|
14
14
|
PLAN_NODE_ATTEMPT: 'planNodeAttempt',
|
|
15
15
|
PLAN_ARTIFACT: 'planArtifact',
|
|
16
|
+
ARTIFACT: 'artifact',
|
|
16
17
|
PLAN_APPROVAL: 'planApproval',
|
|
17
18
|
PLAN_CHECKPOINT: 'planCheckpoint',
|
|
18
19
|
PLAN_VALIDATION_ISSUE: 'planValidationIssue',
|
|
@@ -48,7 +48,7 @@ export async function enqueueAutonomousJobRun(params: {
|
|
|
48
48
|
payload: AutonomousJobQueuePayload
|
|
49
49
|
delayMs?: number
|
|
50
50
|
jobId?: string
|
|
51
|
-
}): Promise<{ bullmqJobId: string; queueJobId
|
|
51
|
+
}): Promise<{ bullmqJobId: string; queueJobId?: string }> {
|
|
52
52
|
const queuedJob = await autonomousJobQueue
|
|
53
53
|
.getQueue()
|
|
54
54
|
.add('run-autonomous-job', params.payload, {
|
|
@@ -56,17 +56,24 @@ export async function enqueueAutonomousJobRun(params: {
|
|
|
56
56
|
...(params.jobId ? { jobId: params.jobId } : {}),
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
const bullmqJobId = String(queuedJob.id)
|
|
60
|
+
let queueJobId: string | undefined
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
queueJobId = await queueJobService.recordEnqueued({
|
|
64
|
+
queueName: AUTONOMOUS_JOB_QUEUE,
|
|
65
|
+
id: queuedJob.id,
|
|
66
|
+
name: queuedJob.name,
|
|
67
|
+
data: queuedJob.data,
|
|
68
|
+
opts: queuedJob.opts,
|
|
69
|
+
attemptsMade: queuedJob.attemptsMade,
|
|
70
|
+
timestamp: queuedJob.timestamp,
|
|
71
|
+
})
|
|
72
|
+
} catch (error) {
|
|
73
|
+
serverLogger.error`Failed to persist queued job metadata (queue=${AUTONOMOUS_JOB_QUEUE}, job=${queuedJob.id}): ${error}`
|
|
74
|
+
}
|
|
68
75
|
|
|
69
|
-
return { bullmqJobId
|
|
76
|
+
return { bullmqJobId, queueJobId }
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
export async function upsertAutonomousJobScheduler(params: {
|
|
@@ -83,15 +90,19 @@ export async function upsertAutonomousJobScheduler(params: {
|
|
|
83
90
|
opts: DEFAULT_AUTONOMOUS_JOB_OPTIONS,
|
|
84
91
|
})
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
try {
|
|
94
|
+
await queueJobService.recordEnqueued({
|
|
95
|
+
queueName: AUTONOMOUS_JOB_QUEUE,
|
|
96
|
+
id: queuedJob.id,
|
|
97
|
+
name: queuedJob.name,
|
|
98
|
+
data: queuedJob.data,
|
|
99
|
+
opts: queuedJob.opts,
|
|
100
|
+
attemptsMade: queuedJob.attemptsMade,
|
|
101
|
+
timestamp: queuedJob.timestamp,
|
|
102
|
+
})
|
|
103
|
+
} catch (error) {
|
|
104
|
+
serverLogger.error`Failed to persist queued job metadata (queue=${AUTONOMOUS_JOB_QUEUE}, job=${queuedJob.id}): ${error}`
|
|
105
|
+
}
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
export async function removeAutonomousJobScheduler(autonomousJobId: string): Promise<void> {
|
|
@@ -98,15 +98,19 @@ export function createDocumentProcessorQueueRuntime<TJob extends DocumentProcess
|
|
|
98
98
|
return {
|
|
99
99
|
enqueue: async (job) => {
|
|
100
100
|
const queuedJob = await getQueue().add(jobName, toQueueData(job), { jobId: buildDocumentProcessorJobId(job) })
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
try {
|
|
102
|
+
await queueJobService.recordEnqueued({
|
|
103
|
+
queueName,
|
|
104
|
+
id: queuedJob.id,
|
|
105
|
+
name: queuedJob.name,
|
|
106
|
+
data: queuedJob.data,
|
|
107
|
+
opts: queuedJob.opts,
|
|
108
|
+
attemptsMade: queuedJob.attemptsMade,
|
|
109
|
+
timestamp: queuedJob.timestamp,
|
|
110
|
+
})
|
|
111
|
+
} catch (error) {
|
|
112
|
+
params.logger.error`Failed to persist queued job metadata (queue=${queueName}, job=${queuedJob.id}): ${error}`
|
|
113
|
+
}
|
|
110
114
|
},
|
|
111
115
|
startWorker: (options = {}) => {
|
|
112
116
|
const { registerSignals = import.meta.main } = options
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { serverLogger } from '../config/logger'
|
|
1
2
|
import { queueJobService } from '../services/queue-job.service'
|
|
2
3
|
import { getWorkerPath, LONG_JOB_LOCK_DURATION_MS, LOW_JOB_RETENTION } from '../workers/worker-utils'
|
|
3
4
|
import { createQueueFactory } from './queue-factory'
|
|
@@ -36,15 +37,19 @@ export async function scheduleRecurringConsolidation() {
|
|
|
36
37
|
},
|
|
37
38
|
)
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
try {
|
|
41
|
+
await queueJobService.recordEnqueued({
|
|
42
|
+
queueName: 'memory-consolidation',
|
|
43
|
+
id: queuedJob.id,
|
|
44
|
+
name: queuedJob.name,
|
|
45
|
+
data: queuedJob.data,
|
|
46
|
+
opts: queuedJob.opts,
|
|
47
|
+
attemptsMade: queuedJob.attemptsMade,
|
|
48
|
+
timestamp: queuedJob.timestamp,
|
|
49
|
+
})
|
|
50
|
+
} catch (error) {
|
|
51
|
+
serverLogger.error`Failed to persist queued job metadata (queue=memory-consolidation, job=${queuedJob.id}): ${error}`
|
|
52
|
+
}
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
export const startMemoryConsolidationWorker = memoryConsolidation.startWorker
|
|
@@ -85,15 +85,19 @@ export function createQueueFactory<TJob>(config: QueueFactoryConfig<TJob>): Queu
|
|
|
85
85
|
|
|
86
86
|
const enqueue = async (job: TJob, options?: JobsOptions): Promise<void> => {
|
|
87
87
|
const queuedJob = await getQueue().add(jobName, toData(job), options)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
try {
|
|
89
|
+
await queueJobService.recordEnqueued({
|
|
90
|
+
queueName: config.name,
|
|
91
|
+
id: queuedJob.id,
|
|
92
|
+
name: queuedJob.name,
|
|
93
|
+
data: queuedJob.data,
|
|
94
|
+
opts: queuedJob.opts,
|
|
95
|
+
attemptsMade: queuedJob.attemptsMade,
|
|
96
|
+
timestamp: queuedJob.timestamp,
|
|
97
|
+
})
|
|
98
|
+
} catch (error) {
|
|
99
|
+
serverLogger.error`Failed to persist queued job metadata (queue=${config.name}, job=${queuedJob.id}): ${error}`
|
|
100
|
+
}
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
const startWorker = (options: { registerSignals?: boolean } = {}): WorkerHandle => {
|
|
@@ -74,7 +74,9 @@ function buildOwnershipDispatchArtifactPayload(artifacts: PlanArtifactSubmission
|
|
|
74
74
|
name: artifact.name,
|
|
75
75
|
kind: artifact.kind,
|
|
76
76
|
...(artifact.description ? { description: artifact.description } : {}),
|
|
77
|
+
...(artifact.content !== undefined ? { content: artifact.content } : {}),
|
|
77
78
|
...(artifact.payload !== undefined ? { payload: artifact.payload } : {}),
|
|
79
|
+
...(artifact.publishedArtifactId ? { publishedArtifactId: artifact.publishedArtifactId } : {}),
|
|
78
80
|
}))
|
|
79
81
|
}
|
|
80
82
|
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { toTimestamp } from '@lota-sdk/shared'
|
|
2
|
+
import type { ChatMessage } from '@lota-sdk/shared'
|
|
3
|
+
|
|
1
4
|
import { agentDisplayNames, resolveAgentNameAlias } from '../config/agent-defaults'
|
|
2
5
|
import type { ChatMessageLike, ReadableUploadMetadataLike } from './chat-types'
|
|
3
6
|
|
|
@@ -142,3 +145,54 @@ export function collectToolOutputErrors(params: {
|
|
|
142
145
|
|
|
143
146
|
return errors
|
|
144
147
|
}
|
|
148
|
+
|
|
149
|
+
export function collectCompletedConsultTeamMessages(params: { responseMessage: ChatMessageLike }): ChatMessage[] {
|
|
150
|
+
const messagesById = new Map<string, ChatMessage>()
|
|
151
|
+
|
|
152
|
+
for (const part of params.responseMessage.parts) {
|
|
153
|
+
if (typeof part !== 'object') continue
|
|
154
|
+
if (part.type !== 'tool-consultTeam') continue
|
|
155
|
+
|
|
156
|
+
const toolPart = part as Record<string, unknown>
|
|
157
|
+
if (toolPart.state !== 'output-available') continue
|
|
158
|
+
|
|
159
|
+
const output = asRecord(toolPart.output)
|
|
160
|
+
const responses = output?.responses
|
|
161
|
+
if (!Array.isArray(responses)) continue
|
|
162
|
+
|
|
163
|
+
for (const response of responses) {
|
|
164
|
+
const responseRecord = asRecord(response)
|
|
165
|
+
if (!responseRecord || responseRecord.status !== 'complete') continue
|
|
166
|
+
|
|
167
|
+
const messageRecord = asRecord(responseRecord.message)
|
|
168
|
+
if (!messageRecord || messageRecord.role !== 'assistant') continue
|
|
169
|
+
|
|
170
|
+
const id = readOptionalString(messageRecord.id)
|
|
171
|
+
if (!id) continue
|
|
172
|
+
|
|
173
|
+
const rawParts = Array.isArray(messageRecord.parts)
|
|
174
|
+
? messageRecord.parts.map((item) => structuredClone(item) as Record<string, unknown>)
|
|
175
|
+
: []
|
|
176
|
+
if (rawParts.length === 0) continue
|
|
177
|
+
|
|
178
|
+
const responseAgentId = readOptionalString(responseRecord.agentId)
|
|
179
|
+
const responseAgentName = readOptionalString(responseRecord.agentName)
|
|
180
|
+
const metadata = {
|
|
181
|
+
...asRecord(messageRecord.metadata),
|
|
182
|
+
...(responseAgentId ? { agentId: responseAgentId } : {}),
|
|
183
|
+
...(responseAgentName ? { agentName: responseAgentName } : {}),
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
messagesById.set(id, { id, role: 'assistant', parts: rawParts as ChatMessage['parts'], metadata })
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return [...messagesById.values()].sort((left, right) => {
|
|
191
|
+
const leftCreatedAt = toTimestamp(left.metadata?.createdAt) ?? Number.MAX_SAFE_INTEGER
|
|
192
|
+
const rightCreatedAt = toTimestamp(right.metadata?.createdAt) ?? Number.MAX_SAFE_INTEGER
|
|
193
|
+
if (leftCreatedAt !== rightCreatedAt) {
|
|
194
|
+
return leftCreatedAt - rightCreatedAt
|
|
195
|
+
}
|
|
196
|
+
return left.id.localeCompare(right.id)
|
|
197
|
+
})
|
|
198
|
+
}
|