@lota-sdk/core 0.4.7 → 0.4.9
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/package.json +11 -12
- package/src/ai/embedding-cache.ts +94 -22
- package/src/ai-gateway/ai-gateway.ts +738 -223
- package/src/config/agent-defaults.ts +176 -75
- package/src/config/agent-types.ts +54 -4
- package/src/config/constants.ts +8 -2
- package/src/config/logger.ts +286 -19
- package/src/config/model-constants.ts +1 -0
- package/src/config/thread-defaults.ts +33 -21
- package/src/create-runtime.ts +725 -383
- package/src/db/base.service.ts +52 -28
- package/src/db/cursor-pagination.ts +71 -30
- package/src/db/memory-store.helpers.ts +4 -7
- package/src/db/memory-store.ts +856 -598
- package/src/db/memory.ts +398 -275
- package/src/db/record-id.ts +32 -10
- package/src/db/schema-fingerprint.ts +30 -12
- package/src/db/service-normalization.ts +255 -0
- package/src/db/service.ts +726 -761
- package/src/db/startup.ts +140 -66
- package/src/db/transaction-conflict.ts +15 -0
- package/src/effect/awaitable-effect.ts +87 -0
- package/src/effect/errors.ts +121 -0
- package/src/effect/helpers.ts +98 -0
- package/src/effect/index.ts +22 -0
- package/src/effect/layers.ts +228 -0
- package/src/effect/runtime-ref.ts +25 -0
- package/src/effect/runtime.ts +31 -0
- package/src/effect/services.ts +57 -0
- package/src/effect/zod.ts +43 -0
- package/src/embeddings/provider.ts +122 -71
- package/src/index.ts +46 -1
- package/src/openrouter/direct-provider.ts +29 -0
- package/src/queues/autonomous-job.queue.ts +130 -74
- package/src/queues/context-compaction.queue.ts +60 -15
- package/src/queues/delayed-node-promotion.queue.ts +52 -15
- package/src/queues/document-processor.queue.ts +52 -77
- package/src/queues/memory-consolidation.queue.ts +47 -32
- package/src/queues/organization-learning.queue.ts +13 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +65 -21
- package/src/queues/plan-scheduler.queue.ts +107 -31
- package/src/queues/post-chat-memory.queue.ts +66 -24
- package/src/queues/queue-factory.ts +142 -52
- package/src/queues/standalone-worker.ts +39 -0
- package/src/queues/title-generation.queue.ts +54 -9
- package/src/redis/connection.ts +84 -32
- package/src/redis/index.ts +6 -8
- package/src/redis/org-memory-lock.ts +60 -27
- package/src/redis/redis-lease-lock.ts +200 -121
- package/src/redis/runtime-connection.ts +10 -0
- package/src/redis/stream-context.ts +84 -46
- package/src/runtime/agent-identity-overrides.ts +2 -2
- package/src/runtime/agent-runtime-policy.ts +4 -1
- package/src/runtime/agent-stream-helpers.ts +20 -9
- package/src/runtime/chat-run-orchestration.ts +102 -19
- package/src/runtime/chat-run-registry.ts +36 -2
- package/src/runtime/context-compaction/context-compaction-runtime.ts +107 -0
- package/src/runtime/{context-compaction.ts → context-compaction/context-compaction.ts} +114 -91
- package/src/runtime/execution-plan-visibility.ts +2 -2
- package/src/runtime/execution-plan.ts +42 -15
- package/src/runtime/graph-designer.ts +11 -7
- package/src/runtime/helper-model.ts +135 -48
- package/src/runtime/index.ts +7 -7
- package/src/runtime/indexed-repositories-policy.ts +3 -3
- package/src/runtime/{memory-block.ts → memory/memory-block.ts} +40 -36
- package/src/runtime/{memory-digest-policy.ts → memory/memory-digest-policy.ts} +1 -1
- package/src/runtime/{memory-pipeline.ts → memory/memory-pipeline.ts} +1 -1
- package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
- package/src/runtime/{memory-scope.ts → memory/memory-scope.ts} +12 -6
- package/src/runtime/plugin-resolution.ts +144 -24
- package/src/runtime/plugin-types.ts +9 -1
- package/src/runtime/post-turn-side-effects.ts +197 -130
- package/src/runtime/retrieval-adapters.ts +38 -4
- package/src/runtime/runtime-config.ts +165 -61
- package/src/runtime/runtime-extensions.ts +21 -34
- package/src/runtime/social-chat/social-chat-agent-runner.ts +157 -0
- package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +42 -20
- package/src/runtime/social-chat/social-chat.ts +594 -0
- package/src/runtime/specialist-runner.ts +36 -10
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +427 -0
- package/src/runtime/{team-consultation-prompts.ts → team-consultation/team-consultation-prompts.ts} +6 -2
- package/src/runtime/thread-chat-helpers.ts +2 -2
- package/src/runtime/thread-plan-turn.ts +2 -1
- package/src/runtime/thread-turn-context.ts +172 -94
- package/src/runtime/turn-lifecycle.ts +93 -27
- package/src/services/agent-activity.service.ts +287 -203
- package/src/services/agent-executor.service.ts +329 -217
- package/src/services/artifact.service.ts +225 -148
- package/src/services/attachment.service.ts +137 -115
- package/src/services/autonomous-job.service.ts +888 -491
- package/src/services/chat-run-registry.service.ts +11 -1
- package/src/services/context-compaction.service.ts +136 -86
- package/src/services/document-chunk.service.ts +162 -90
- package/src/services/execution-plan/execution-plan-approval.ts +26 -0
- package/src/services/execution-plan/execution-plan-context.ts +29 -0
- package/src/services/execution-plan/execution-plan-graph.ts +256 -0
- package/src/services/execution-plan/execution-plan-schedule.ts +84 -0
- package/src/services/execution-plan/execution-plan-spec.ts +75 -0
- package/src/services/execution-plan/execution-plan.service.ts +1041 -0
- package/src/services/feedback-loop.service.ts +132 -76
- package/src/services/global-orchestrator.service.ts +80 -170
- package/src/services/graph-full-routing.ts +182 -0
- package/src/services/index.ts +18 -20
- package/src/services/institutional-memory.service.ts +220 -123
- package/src/services/learned-skill.service.ts +364 -259
- package/src/services/memory/memory-conversation.ts +95 -0
- package/src/services/memory/memory-org-memory.ts +39 -0
- package/src/services/memory/memory-preseeded.ts +80 -0
- package/src/services/memory/memory-rerank.ts +297 -0
- package/src/services/{memory-utils.ts → memory/memory-utils.ts} +5 -5
- package/src/services/memory/memory.service.ts +692 -0
- package/src/services/memory/rerank.service.ts +209 -0
- package/src/services/monitoring-window.service.ts +92 -70
- package/src/services/mutating-approval.service.ts +62 -53
- package/src/services/node-workspace.service.ts +141 -98
- package/src/services/notification.service.ts +17 -16
- package/src/services/organization-member.service.ts +120 -66
- package/src/services/organization.service.ts +144 -51
- package/src/services/ownership-dispatcher.service.ts +415 -264
- package/src/services/plan/plan-agent-heartbeat.service.ts +234 -0
- package/src/services/plan/plan-agent-query.service.ts +322 -0
- package/src/services/plan/plan-approval.service.ts +102 -0
- package/src/services/plan/plan-artifact.service.ts +60 -0
- package/src/services/plan/plan-builder.service.ts +76 -0
- package/src/services/plan/plan-checkpoint.service.ts +103 -0
- package/src/services/{plan-compiler.service.ts → plan/plan-compiler.service.ts} +26 -9
- package/src/services/plan/plan-completion-side-effects.ts +175 -0
- package/src/services/plan/plan-coordination.service.ts +181 -0
- package/src/services/plan/plan-cycle.service.ts +398 -0
- package/src/services/plan/plan-deadline.service.ts +547 -0
- package/src/services/plan/plan-event-delivery.service.ts +261 -0
- package/src/services/plan/plan-executor-context.ts +35 -0
- package/src/services/plan/plan-executor-graph.ts +475 -0
- package/src/services/plan/plan-executor-helpers.ts +322 -0
- package/src/services/plan/plan-executor-persistence.ts +209 -0
- package/src/services/plan/plan-executor.service.ts +1654 -0
- package/src/services/{plan-helpers.ts → plan/plan-helpers.ts} +1 -1
- package/src/services/{plan-run-data.ts → plan/plan-run-data.ts} +4 -4
- package/src/services/plan/plan-run-serialization.ts +15 -0
- package/src/services/plan/plan-run.service.ts +644 -0
- package/src/services/plan/plan-scheduler.service.ts +385 -0
- package/src/services/plan/plan-template.service.ts +224 -0
- package/src/services/plan/plan-transaction-events.ts +33 -0
- package/src/services/plan/plan-validator.service.ts +907 -0
- package/src/services/plan/plan-workspace.service.ts +125 -0
- package/src/services/plugin-executor.service.ts +97 -68
- package/src/services/quality-metrics.service.ts +112 -94
- package/src/services/queue-job.service.ts +296 -230
- package/src/services/recent-activity-title.service.ts +65 -36
- package/src/services/recent-activity.service.ts +274 -259
- package/src/services/skill-resolver.service.ts +38 -12
- package/src/services/social-chat-history.service.ts +176 -125
- package/src/services/system-executor.service.ts +91 -61
- package/src/services/thread/thread-active-run.ts +203 -0
- package/src/services/thread/thread-bootstrap.ts +369 -0
- package/src/services/thread/thread-listing.ts +198 -0
- package/src/services/thread/thread-memory-block.ts +117 -0
- package/src/services/thread/thread-message.service.ts +363 -0
- package/src/services/thread/thread-record-store.ts +155 -0
- package/src/services/thread/thread-title.service.ts +74 -0
- package/src/services/thread/thread-turn-execution.ts +280 -0
- package/src/services/thread/thread-turn-message-context.ts +73 -0
- package/src/services/thread/thread-turn-preparation.service.ts +1146 -0
- package/src/services/thread/thread-turn-streaming.ts +402 -0
- package/src/services/thread/thread-turn-tracing.ts +35 -0
- package/src/services/thread/thread-turn.ts +343 -0
- package/src/services/thread/thread.service.ts +335 -0
- package/src/services/user.service.ts +82 -32
- package/src/services/write-intent-validator.service.ts +63 -51
- package/src/storage/attachment-parser.ts +69 -27
- package/src/storage/attachment-storage.service.ts +331 -275
- package/src/storage/generated-document-storage.service.ts +66 -34
- package/src/system-agents/agent-result.ts +3 -1
- package/src/system-agents/context-compaction.agent.ts +2 -2
- package/src/system-agents/delegated-agent-factory.ts +159 -90
- package/src/system-agents/memory-reranker.agent.ts +2 -2
- package/src/system-agents/memory.agent.ts +2 -2
- package/src/system-agents/recent-activity-title-refiner.agent.ts +2 -2
- package/src/system-agents/regular-chat-memory-digest.agent.ts +2 -2
- package/src/system-agents/skill-extractor.agent.ts +2 -2
- package/src/system-agents/skill-manager.agent.ts +2 -2
- package/src/system-agents/thread-router.agent.ts +157 -113
- package/src/system-agents/title-generator.agent.ts +2 -2
- package/src/tools/execution-plan.tool.ts +220 -161
- package/src/tools/fetch-webpage.tool.ts +21 -17
- package/src/tools/firecrawl-client.ts +16 -6
- package/src/tools/index.ts +1 -0
- package/src/tools/memory-block.tool.ts +14 -6
- package/src/tools/plan-approval.tool.ts +49 -47
- package/src/tools/read-file-parts.tool.ts +44 -33
- package/src/tools/remember-memory.tool.ts +65 -45
- package/src/tools/search-web.tool.ts +26 -22
- package/src/tools/search.tool.ts +41 -29
- package/src/tools/team-think.tool.ts +124 -83
- package/src/tools/user-questions.tool.ts +4 -3
- package/src/tools/web-tool-shared.ts +6 -0
- package/src/utils/async.ts +17 -23
- package/src/utils/crypto.ts +21 -0
- package/src/utils/date-time.ts +40 -1
- package/src/utils/errors.ts +95 -16
- package/src/utils/hono-error-handler.ts +24 -39
- package/src/utils/index.ts +2 -1
- package/src/utils/null-proto-record.ts +41 -0
- package/src/utils/sse-keepalive.ts +124 -21
- package/src/workers/bootstrap.ts +186 -51
- package/src/workers/memory-consolidation.worker.ts +325 -237
- package/src/workers/organization-learning.worker.ts +50 -16
- package/src/workers/regular-chat-memory-digest.helpers.ts +28 -27
- package/src/workers/regular-chat-memory-digest.runner.ts +175 -114
- package/src/workers/skill-extraction.runner.ts +176 -93
- package/src/workers/utils/file-section-chunker.ts +8 -10
- package/src/workers/utils/repo-structure-extractor.ts +349 -260
- package/src/workers/utils/repomix-file-sections.ts +2 -2
- package/src/workers/utils/thread-message-query.ts +97 -38
- package/src/workers/worker-utils.ts +56 -31
- package/src/config/debug-logger.ts +0 -47
- package/src/redis/connection-accessor.ts +0 -26
- package/src/runtime/context-compaction-runtime.ts +0 -87
- package/src/runtime/social-chat-agent-runner.ts +0 -118
- package/src/runtime/social-chat.ts +0 -516
- package/src/runtime/team-consultation-orchestrator.ts +0 -272
- package/src/services/adaptive-playbook.service.ts +0 -152
- package/src/services/artifact-provenance.service.ts +0 -172
- package/src/services/chat-attachments.service.ts +0 -17
- package/src/services/context-compaction-runtime.singleton.ts +0 -13
- package/src/services/execution-plan.service.ts +0 -1118
- package/src/services/memory.service.ts +0 -844
- package/src/services/plan-agent-heartbeat.service.ts +0 -136
- package/src/services/plan-agent-query.service.ts +0 -267
- package/src/services/plan-approval.service.ts +0 -83
- package/src/services/plan-artifact.service.ts +0 -50
- package/src/services/plan-builder.service.ts +0 -67
- package/src/services/plan-checkpoint.service.ts +0 -81
- package/src/services/plan-completion-side-effects.ts +0 -80
- package/src/services/plan-coordination.service.ts +0 -157
- package/src/services/plan-cycle.service.ts +0 -284
- package/src/services/plan-deadline.service.ts +0 -430
- package/src/services/plan-event-delivery.service.ts +0 -166
- package/src/services/plan-executor.service.ts +0 -1950
- package/src/services/plan-run.service.ts +0 -515
- package/src/services/plan-scheduler.service.ts +0 -240
- package/src/services/plan-template.service.ts +0 -177
- package/src/services/plan-validator.service.ts +0 -818
- package/src/services/plan-workspace.service.ts +0 -83
- package/src/services/thread-message.service.ts +0 -275
- package/src/services/thread-plan-registry.service.ts +0 -22
- package/src/services/thread-title.service.ts +0 -39
- package/src/services/thread-turn-preparation.service.ts +0 -1147
- package/src/services/thread-turn.ts +0 -172
- package/src/services/thread.service.ts +0 -869
- package/src/utils/env.ts +0 -8
- /package/src/runtime/{context-compaction-constants.ts → context-compaction/context-compaction-constants.ts} +0 -0
- /package/src/runtime/{memory-format.ts → memory/memory-format.ts} +0 -0
- /package/src/runtime/{memory-prompts-parse.ts → memory/memory-prompts-parse.ts} +0 -0
- /package/src/runtime/{memory-prompts-update.ts → memory/memory-prompts-update.ts} +0 -0
- /package/src/runtime/{social-chat-prompts.ts → social-chat/social-chat-prompts.ts} +0 -0
- /package/src/services/{plan-node-spec.ts → plan/plan-node-spec.ts} +0 -0
- /package/src/services/{thread-constants.ts → thread/thread-constants.ts} +0 -0
- /package/src/services/{thread.types.ts → thread/thread.types.ts} +0 -0
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { ToolSet } from 'ai'
|
|
2
|
+
import { Config, ConfigProvider, Effect, Option, Redacted } from 'effect'
|
|
2
3
|
import { z } from 'zod'
|
|
3
4
|
|
|
4
5
|
import type { CoreThreadProfile } from '../config/agent-defaults'
|
|
5
6
|
import type { AgentFactory, AgentRuntimeConfigProvider, AgentToolBuilder } from '../config/agent-types'
|
|
7
|
+
import { DEFAULT_AI_GATEWAY_URL } from '../config/constants'
|
|
8
|
+
import { OPENROUTER_FAST_RERANK_MODEL_ID } from '../config/model-constants'
|
|
6
9
|
import type { LotaThreadConfig, ThreadBootstrapWelcomeConfig } from '../config/thread-defaults'
|
|
7
10
|
import type { RecordIdRef } from '../db/record-id'
|
|
11
|
+
import { getCurrentRuntime } from '../effect/runtime-ref'
|
|
12
|
+
import { RuntimeConfigServiceTag } from '../effect/services'
|
|
8
13
|
import type { NotificationService } from '../services/notification.service'
|
|
9
14
|
import { isRecord } from '../utils/string'
|
|
10
15
|
import type { GraphDesigner } from './graph-designer'
|
|
@@ -13,6 +18,11 @@ import type { LotaRuntimeAdapters, LotaRuntimeTurnHooks } from './runtime-extens
|
|
|
13
18
|
import type { LotaRuntimeWorkerExtensions } from './runtime-worker-registry'
|
|
14
19
|
|
|
15
20
|
const logLevelValues = ['trace', 'debug', 'info', 'warning', 'error', 'fatal'] as const
|
|
21
|
+
const nonEmptyStringSchema = z.string().trim().min(1)
|
|
22
|
+
const stringRecordSchema = z.record(z.string(), z.string())
|
|
23
|
+
function objectRecordSchema<T extends object>() {
|
|
24
|
+
return z.custom<T>(isRecord)
|
|
25
|
+
}
|
|
16
26
|
|
|
17
27
|
function isStringOrUrl(value: unknown): value is string | URL {
|
|
18
28
|
return typeof value === 'string' || value instanceof URL
|
|
@@ -22,26 +32,14 @@ function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
|
|
|
22
32
|
return typeof value === 'function'
|
|
23
33
|
}
|
|
24
34
|
|
|
25
|
-
function
|
|
26
|
-
return isRecord(value)
|
|
35
|
+
function isToolSet(value: unknown): value is ToolSet {
|
|
36
|
+
return isRecord(value)
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
function isAgentFactoryRegistry(value: unknown): value is AgentFactory {
|
|
30
40
|
return isRecord(value) && Object.values(value).every((entry) => typeof entry === 'function')
|
|
31
41
|
}
|
|
32
42
|
|
|
33
|
-
function isPluginRuntimeRecord(value: unknown): value is Record<string, LotaPlugin> {
|
|
34
|
-
return isRecord(value)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function isSystemExecutorRecord(value: unknown): value is Record<string, SystemNodeExecutor> {
|
|
38
|
-
return isRecord(value)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function isToolProviderRecord(value: unknown): value is Record<string, unknown> {
|
|
42
|
-
return isRecord(value)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
43
|
function isNotificationService(value: unknown): value is NotificationService {
|
|
46
44
|
return isRecord(value) && isFunction(value.notify) && isFunction(value.remind) && isFunction(value.escalate)
|
|
47
45
|
}
|
|
@@ -145,7 +143,7 @@ function isSocialChatConfig(value: unknown): value is LotaRuntimeSocialChatConfi
|
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
const threadBootstrapWelcomeConfigSchema = z.object({
|
|
148
|
-
defaultAgentId:
|
|
146
|
+
defaultAgentId: nonEmptyStringSchema,
|
|
149
147
|
buildMessageText: z.custom<ThreadBootstrapWelcomeConfig['buildMessageText']>(isFunction, {
|
|
150
148
|
error: 'onboardingWelcome.buildMessageText must be a function',
|
|
151
149
|
}),
|
|
@@ -155,9 +153,9 @@ const threadConfigSchema = z
|
|
|
155
153
|
.object({
|
|
156
154
|
bootstrap: z
|
|
157
155
|
.object({
|
|
158
|
-
onboardingDefaultAgents: z.array(
|
|
159
|
-
completedDefaultAgents: z.array(
|
|
160
|
-
threadTypesAfterOnboarding: z.array(
|
|
156
|
+
onboardingDefaultAgents: z.array(nonEmptyStringSchema).optional(),
|
|
157
|
+
completedDefaultAgents: z.array(nonEmptyStringSchema).optional(),
|
|
158
|
+
threadTypesAfterOnboarding: z.array(nonEmptyStringSchema).optional(),
|
|
161
159
|
ensureDefaultGroupOnCompleted: z.boolean().optional(),
|
|
162
160
|
onboardingWelcome: threadBootstrapWelcomeConfigSchema.optional(),
|
|
163
161
|
})
|
|
@@ -168,19 +166,13 @@ const threadConfigSchema = z
|
|
|
168
166
|
|
|
169
167
|
const agentsConfigSchema = z
|
|
170
168
|
.object({
|
|
171
|
-
roster: z.array(
|
|
172
|
-
leadAgentId:
|
|
173
|
-
displayNames:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.optional(),
|
|
179
|
-
descriptions: z
|
|
180
|
-
.custom<Record<string, string>>(isStringRecord, { error: 'agents.descriptions must be a string record' })
|
|
181
|
-
.optional(),
|
|
182
|
-
routerModelId: z.string().trim().min(1).optional(),
|
|
183
|
-
teamConsultParticipants: z.array(z.string().trim().min(1)),
|
|
169
|
+
roster: z.array(nonEmptyStringSchema).min(1),
|
|
170
|
+
leadAgentId: nonEmptyStringSchema,
|
|
171
|
+
displayNames: stringRecordSchema,
|
|
172
|
+
shortDisplayNames: stringRecordSchema.optional(),
|
|
173
|
+
descriptions: stringRecordSchema.optional(),
|
|
174
|
+
routerModelId: nonEmptyStringSchema.optional(),
|
|
175
|
+
teamConsultParticipants: z.array(nonEmptyStringSchema),
|
|
184
176
|
getCoreThreadProfile: z
|
|
185
177
|
.custom<(coreType: string) => CoreThreadProfile>(isFunction, {
|
|
186
178
|
error: 'agents.getCoreThreadProfile must be a function',
|
|
@@ -216,25 +208,30 @@ const agentsConfigSchema = z
|
|
|
216
208
|
}
|
|
217
209
|
})
|
|
218
210
|
|
|
211
|
+
export const MemoryRerankerStrategySchema = z.enum(['helper-model', 'rerank'])
|
|
212
|
+
export type MemoryRerankerStrategy = z.infer<typeof MemoryRerankerStrategySchema>
|
|
213
|
+
|
|
219
214
|
export const LotaRuntimeConfigSchema = z.object({
|
|
220
215
|
database: z.object({
|
|
221
|
-
url:
|
|
222
|
-
namespace:
|
|
223
|
-
username:
|
|
224
|
-
password:
|
|
216
|
+
url: nonEmptyStringSchema,
|
|
217
|
+
namespace: nonEmptyStringSchema,
|
|
218
|
+
username: nonEmptyStringSchema,
|
|
219
|
+
password: nonEmptyStringSchema,
|
|
225
220
|
}),
|
|
226
|
-
redis: z.object({ url:
|
|
221
|
+
redis: z.object({ url: nonEmptyStringSchema }),
|
|
227
222
|
aiGateway: z.object({
|
|
228
|
-
url:
|
|
229
|
-
key:
|
|
230
|
-
embeddingModel:
|
|
223
|
+
url: nonEmptyStringSchema,
|
|
224
|
+
key: nonEmptyStringSchema,
|
|
225
|
+
embeddingModel: nonEmptyStringSchema.default('openai/text-embedding-3-small'),
|
|
226
|
+
openRouterApiKey: nonEmptyStringSchema.optional(),
|
|
227
|
+
maxConcurrency: z.coerce.number().int().positive().default(8),
|
|
231
228
|
}),
|
|
232
229
|
s3: z.object({
|
|
233
|
-
endpoint:
|
|
234
|
-
bucket:
|
|
235
|
-
region:
|
|
236
|
-
accessKeyId:
|
|
237
|
-
secretAccessKey:
|
|
230
|
+
endpoint: nonEmptyStringSchema,
|
|
231
|
+
bucket: nonEmptyStringSchema,
|
|
232
|
+
region: nonEmptyStringSchema.default('garage'),
|
|
233
|
+
accessKeyId: nonEmptyStringSchema,
|
|
234
|
+
secretAccessKey: nonEmptyStringSchema,
|
|
238
235
|
attachmentUrlExpiresIn: z.coerce.number().positive().default(1800),
|
|
239
236
|
}),
|
|
240
237
|
firecrawl: z.object({
|
|
@@ -250,20 +247,36 @@ export const LotaRuntimeConfigSchema = z.object({
|
|
|
250
247
|
.object({
|
|
251
248
|
searchK: z.coerce.number().int().positive().default(6),
|
|
252
249
|
embeddingCacheTtlSeconds: z.coerce.number().int().positive().default(7200),
|
|
250
|
+
rerankerStrategy: MemoryRerankerStrategySchema.default('rerank'),
|
|
251
|
+
rerankerModelId: z.string().trim().min(1).default(OPENROUTER_FAST_RERANK_MODEL_ID),
|
|
253
252
|
})
|
|
254
|
-
.default({
|
|
253
|
+
.default({
|
|
254
|
+
searchK: 6,
|
|
255
|
+
embeddingCacheTtlSeconds: 7200,
|
|
256
|
+
rerankerStrategy: 'rerank',
|
|
257
|
+
rerankerModelId: OPENROUTER_FAST_RERANK_MODEL_ID,
|
|
258
|
+
}),
|
|
255
259
|
threads: threadConfigSchema.default({}),
|
|
256
260
|
agents: agentsConfigSchema,
|
|
257
|
-
toolProviders: z.custom<
|
|
261
|
+
toolProviders: z.custom<ToolSet>(isToolSet, { error: 'toolProviders must be a tool registry object' }).optional(),
|
|
258
262
|
extraSchemaFiles: z.array(z.custom<string | URL>(isStringOrUrl)).optional(),
|
|
259
263
|
extraWorkers: z.custom<LotaRuntimeWorkerExtensions>(isWorkerExtensionRecord).optional(),
|
|
260
|
-
pluginRuntime:
|
|
261
|
-
systemExecutors:
|
|
264
|
+
pluginRuntime: objectRecordSchema<Record<string, LotaPlugin>>().optional(),
|
|
265
|
+
systemExecutors: objectRecordSchema<Record<string, SystemNodeExecutor>>().optional(),
|
|
262
266
|
notificationService: z.custom<NotificationService>(isNotificationService).optional(),
|
|
263
|
-
runtimeAdapters:
|
|
264
|
-
turnHooks:
|
|
267
|
+
runtimeAdapters: objectRecordSchema<LotaRuntimeAdapters>().optional(),
|
|
268
|
+
turnHooks: objectRecordSchema<LotaRuntimeTurnHooks>().optional(),
|
|
265
269
|
graphDesigner: z.custom<GraphDesigner>(isGraphDesigner).optional(),
|
|
266
270
|
socialChat: z.custom<LotaRuntimeSocialChatConfig>(isSocialChatConfig).optional(),
|
|
271
|
+
observability: z
|
|
272
|
+
.object({
|
|
273
|
+
otlpBaseUrl: nonEmptyStringSchema.optional(),
|
|
274
|
+
otlpHeaders: stringRecordSchema.optional(),
|
|
275
|
+
serviceName: nonEmptyStringSchema.default('lota-sdk'),
|
|
276
|
+
serviceVersion: nonEmptyStringSchema.optional(),
|
|
277
|
+
devToolsUrl: nonEmptyStringSchema.optional(),
|
|
278
|
+
})
|
|
279
|
+
.default({ serviceName: 'lota-sdk' }),
|
|
267
280
|
})
|
|
268
281
|
|
|
269
282
|
export type LotaRuntimeConfig = z.input<typeof LotaRuntimeConfigSchema>
|
|
@@ -288,6 +301,8 @@ export const LOTA_RUNTIME_ENV_KEYS = Object.freeze([
|
|
|
288
301
|
'AI_GATEWAY_URL',
|
|
289
302
|
'AI_GATEWAY_KEY',
|
|
290
303
|
'AI_EMBEDDING_MODEL',
|
|
304
|
+
'OPENROUTER_API_KEY',
|
|
305
|
+
'AI_GATEWAY_MAX_CONCURRENCY',
|
|
291
306
|
'S3_ENDPOINT',
|
|
292
307
|
'S3_BUCKET',
|
|
293
308
|
'S3_REGION',
|
|
@@ -298,28 +313,117 @@ export const LOTA_RUNTIME_ENV_KEYS = Object.freeze([
|
|
|
298
313
|
'FIRECRAWL_API_BASE_URL',
|
|
299
314
|
'LOG_LEVEL',
|
|
300
315
|
'MEMORY_SEARCH_K',
|
|
316
|
+
'MEMORY_RERANKER_STRATEGY',
|
|
317
|
+
'MEMORY_RERANKER_MODEL_ID',
|
|
318
|
+
'OTLP_BASE_URL',
|
|
319
|
+
'OTLP_SERVICE_NAME',
|
|
320
|
+
'OTLP_SERVICE_VERSION',
|
|
321
|
+
'DEVTOOLS_URL',
|
|
301
322
|
])
|
|
302
323
|
|
|
303
|
-
let runtimeConfig: ResolvedLotaRuntimeConfig | null = null
|
|
304
|
-
|
|
305
324
|
export function parseLotaRuntimeConfig(config: LotaRuntimeConfig): ResolvedLotaRuntimeConfig {
|
|
306
325
|
return LotaRuntimeConfigSchema.parse(config)
|
|
307
326
|
}
|
|
308
327
|
|
|
309
|
-
export function
|
|
310
|
-
|
|
328
|
+
export function parseWorkerBootstrapEnv(env: Record<string, string | undefined>): WorkerBootstrapEnv {
|
|
329
|
+
return WORKER_BOOTSTRAP_ENV_SCHEMA.parse(env)
|
|
311
330
|
}
|
|
312
331
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
332
|
+
const runtimeEnvironmentConfig = Config.all({
|
|
333
|
+
surrealdbUrl: Config.string('SURREALDB_URL'),
|
|
334
|
+
surrealdbNamespace: Config.string('SURREALDB_NAMESPACE'),
|
|
335
|
+
surrealdbUser: Config.string('SURREALDB_USER'),
|
|
336
|
+
surrealdbPassword: Config.redacted('SURREALDB_PASSWORD'),
|
|
337
|
+
redisUrl: Config.string('REDIS_URL'),
|
|
338
|
+
aiGatewayUrl: Config.string('AI_GATEWAY_URL').pipe(Config.withDefault(DEFAULT_AI_GATEWAY_URL)),
|
|
339
|
+
aiGatewayKey: Config.redacted('AI_GATEWAY_KEY'),
|
|
340
|
+
aiEmbeddingModel: Config.string('AI_EMBEDDING_MODEL').pipe(Config.withDefault('openai/text-embedding-3-small')),
|
|
341
|
+
openRouterApiKey: Config.redacted('OPENROUTER_API_KEY').pipe(Config.option),
|
|
342
|
+
aiGatewayMaxConcurrency: Config.number('AI_GATEWAY_MAX_CONCURRENCY').pipe(Config.withDefault(8)),
|
|
343
|
+
s3Endpoint: Config.string('S3_ENDPOINT'),
|
|
344
|
+
s3Bucket: Config.string('S3_BUCKET'),
|
|
345
|
+
s3Region: Config.string('S3_REGION').pipe(Config.withDefault('garage')),
|
|
346
|
+
s3AccessKeyId: Config.redacted('S3_ACCESS_KEY_ID'),
|
|
347
|
+
s3SecretAccessKey: Config.redacted('S3_SECRET_ACCESS_KEY'),
|
|
348
|
+
attachmentUrlExpiresIn: Config.number('ATTACHMENT_URL_EXPIRES_IN').pipe(Config.withDefault(1800)),
|
|
349
|
+
firecrawlApiKey: Config.redacted('FIRECRAWL_API_KEY'),
|
|
350
|
+
firecrawlApiBaseUrl: Config.string('FIRECRAWL_API_BASE_URL').pipe(Config.option),
|
|
351
|
+
logLevel: Config.string('LOG_LEVEL').pipe(Config.withDefault('info')),
|
|
352
|
+
memorySearchK: Config.number('MEMORY_SEARCH_K').pipe(Config.withDefault(6)),
|
|
353
|
+
memoryRerankerStrategy: Config.string('MEMORY_RERANKER_STRATEGY').pipe(Config.withDefault('rerank')),
|
|
354
|
+
memoryRerankerModelId: Config.string('MEMORY_RERANKER_MODEL_ID').pipe(
|
|
355
|
+
Config.withDefault(OPENROUTER_FAST_RERANK_MODEL_ID),
|
|
356
|
+
),
|
|
357
|
+
otlpBaseUrl: Config.string('OTLP_BASE_URL').pipe(Config.option),
|
|
358
|
+
otlpServiceName: Config.string('OTLP_SERVICE_NAME').pipe(Config.withDefault('lota-sdk')),
|
|
359
|
+
otlpServiceVersion: Config.string('OTLP_SERVICE_VERSION').pipe(Config.option),
|
|
360
|
+
devToolsUrl: Config.string('DEVTOOLS_URL').pipe(Config.option),
|
|
361
|
+
})
|
|
317
362
|
|
|
318
|
-
|
|
363
|
+
export type LotaRuntimeEnvironmentOverrides = Omit<
|
|
364
|
+
LotaRuntimeConfig,
|
|
365
|
+
'database' | 'redis' | 'aiGateway' | 's3' | 'firecrawl' | 'logging' | 'memory'
|
|
366
|
+
> & { logging?: LotaRuntimeConfig['logging']; memory?: LotaRuntimeConfig['memory'] }
|
|
367
|
+
|
|
368
|
+
export function loadLotaRuntimeConfigFromEnv(
|
|
369
|
+
overrides: LotaRuntimeEnvironmentOverrides,
|
|
370
|
+
options: { configProvider?: ConfigProvider.ConfigProvider } = {},
|
|
371
|
+
) {
|
|
372
|
+
return runtimeEnvironmentConfig
|
|
373
|
+
.parse(options.configProvider ?? ConfigProvider.fromEnv())
|
|
374
|
+
.pipe(
|
|
375
|
+
Effect.map((env) =>
|
|
376
|
+
parseLotaRuntimeConfig({
|
|
377
|
+
...overrides,
|
|
378
|
+
database: {
|
|
379
|
+
url: env.surrealdbUrl,
|
|
380
|
+
namespace: env.surrealdbNamespace,
|
|
381
|
+
username: env.surrealdbUser,
|
|
382
|
+
password: Redacted.value(env.surrealdbPassword),
|
|
383
|
+
},
|
|
384
|
+
redis: { url: env.redisUrl },
|
|
385
|
+
aiGateway: {
|
|
386
|
+
url: env.aiGatewayUrl,
|
|
387
|
+
key: Redacted.value(env.aiGatewayKey),
|
|
388
|
+
embeddingModel: env.aiEmbeddingModel,
|
|
389
|
+
maxConcurrency: env.aiGatewayMaxConcurrency,
|
|
390
|
+
...(Option.isSome(env.openRouterApiKey)
|
|
391
|
+
? { openRouterApiKey: Redacted.value(env.openRouterApiKey.value) }
|
|
392
|
+
: {}),
|
|
393
|
+
},
|
|
394
|
+
s3: {
|
|
395
|
+
endpoint: env.s3Endpoint,
|
|
396
|
+
bucket: env.s3Bucket,
|
|
397
|
+
region: env.s3Region,
|
|
398
|
+
accessKeyId: Redacted.value(env.s3AccessKeyId),
|
|
399
|
+
secretAccessKey: Redacted.value(env.s3SecretAccessKey),
|
|
400
|
+
attachmentUrlExpiresIn: env.attachmentUrlExpiresIn,
|
|
401
|
+
},
|
|
402
|
+
firecrawl: {
|
|
403
|
+
apiKey: Redacted.value(env.firecrawlApiKey),
|
|
404
|
+
...(Option.isSome(env.firecrawlApiBaseUrl) ? { apiBaseUrl: env.firecrawlApiBaseUrl.value } : {}),
|
|
405
|
+
},
|
|
406
|
+
logging: overrides.logging ?? { level: env.logLevel as (typeof logLevelValues)[number] },
|
|
407
|
+
memory: {
|
|
408
|
+
searchK: env.memorySearchK,
|
|
409
|
+
rerankerStrategy: env.memoryRerankerStrategy as MemoryRerankerStrategy,
|
|
410
|
+
rerankerModelId: env.memoryRerankerModelId,
|
|
411
|
+
...overrides.memory,
|
|
412
|
+
},
|
|
413
|
+
observability: {
|
|
414
|
+
serviceName: env.otlpServiceName,
|
|
415
|
+
...(Option.isSome(env.otlpBaseUrl) ? { otlpBaseUrl: env.otlpBaseUrl.value } : {}),
|
|
416
|
+
...(Option.isSome(env.otlpServiceVersion) ? { serviceVersion: env.otlpServiceVersion.value } : {}),
|
|
417
|
+
...(Option.isSome(env.devToolsUrl) ? { devToolsUrl: env.devToolsUrl.value } : {}),
|
|
418
|
+
...overrides.observability,
|
|
419
|
+
},
|
|
420
|
+
}),
|
|
421
|
+
),
|
|
422
|
+
)
|
|
319
423
|
}
|
|
320
424
|
|
|
321
|
-
export function
|
|
322
|
-
return
|
|
425
|
+
export function getRuntimeConfig(): ResolvedLotaRuntimeConfig {
|
|
426
|
+
return getCurrentRuntime().runSync(Effect.service(RuntimeConfigServiceTag))
|
|
323
427
|
}
|
|
324
428
|
|
|
325
429
|
export type { LotaThreadConfig }
|
|
@@ -6,8 +6,17 @@ import type {
|
|
|
6
6
|
PlanSpecRecord,
|
|
7
7
|
} from '@lota-sdk/shared'
|
|
8
8
|
import type { ToolSet } from 'ai'
|
|
9
|
+
import { Effect } from 'effect'
|
|
10
|
+
import type { Context } from 'effect'
|
|
9
11
|
|
|
10
12
|
import type { RecordIdRef } from '../db/record-id'
|
|
13
|
+
import { getCurrentRuntime } from '../effect/runtime-ref'
|
|
14
|
+
import {
|
|
15
|
+
RuntimeAdaptersServiceTag,
|
|
16
|
+
RuntimeWorkerExtensionsServiceTag,
|
|
17
|
+
ToolProvidersServiceTag,
|
|
18
|
+
TurnHooksServiceTag,
|
|
19
|
+
} from '../effect/services'
|
|
11
20
|
import type { ReadableUploadMetadata } from '../storage/attachment-types'
|
|
12
21
|
import type { LotaRuntimeWorkerExtensions } from './runtime-worker-registry'
|
|
13
22
|
|
|
@@ -193,54 +202,32 @@ export interface LotaRuntimeAdapters {
|
|
|
193
202
|
withWorkspaceMemoryLock?: <T>(workspaceId: string, fn: () => Promise<T>) => Promise<T>
|
|
194
203
|
}
|
|
195
204
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
turnHooks: LotaRuntimeTurnHooks
|
|
199
|
-
toolProviders: ToolSet
|
|
200
|
-
extraWorkers: LotaRuntimeWorkerExtensions
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const EMPTY_TOOLS = {} as ToolSet
|
|
204
|
-
|
|
205
|
-
let runtimeExtensionsState: RuntimeExtensionsState = {
|
|
206
|
-
adapters: {},
|
|
207
|
-
turnHooks: {},
|
|
208
|
-
toolProviders: EMPTY_TOOLS,
|
|
209
|
-
extraWorkers: {},
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export function configureRuntimeExtensions(params: {
|
|
213
|
-
adapters?: LotaRuntimeAdapters
|
|
214
|
-
turnHooks?: LotaRuntimeTurnHooks
|
|
215
|
-
toolProviders?: ToolSet
|
|
216
|
-
extraWorkers?: LotaRuntimeWorkerExtensions
|
|
217
|
-
}): void {
|
|
218
|
-
runtimeExtensionsState = {
|
|
219
|
-
adapters: params.adapters ?? {},
|
|
220
|
-
turnHooks: params.turnHooks ?? {},
|
|
221
|
-
toolProviders: params.toolProviders ?? EMPTY_TOOLS,
|
|
222
|
-
extraWorkers: params.extraWorkers ?? {},
|
|
223
|
-
}
|
|
205
|
+
function resolveFromRuntime<I, T>(tag: Context.Key<I, T>): T {
|
|
206
|
+
return getCurrentRuntime().runSync(Effect.service(tag))
|
|
224
207
|
}
|
|
225
208
|
|
|
226
209
|
export function getRuntimeAdapters(): LotaRuntimeAdapters {
|
|
227
|
-
return
|
|
210
|
+
return resolveFromRuntime(RuntimeAdaptersServiceTag)
|
|
228
211
|
}
|
|
229
212
|
|
|
230
213
|
export function getTurnHooks(): LotaRuntimeTurnHooks {
|
|
231
|
-
return
|
|
214
|
+
return resolveFromRuntime(TurnHooksServiceTag)
|
|
232
215
|
}
|
|
233
216
|
|
|
234
217
|
export function getToolProviders(): ToolSet {
|
|
235
|
-
return
|
|
218
|
+
return resolveFromRuntime(ToolProvidersServiceTag)
|
|
236
219
|
}
|
|
237
220
|
|
|
238
221
|
export function getConfiguredPluginDatabaseConnector(): (() => Promise<void>) | undefined {
|
|
239
|
-
return
|
|
222
|
+
return getRuntimeAdapters().connectPluginDatabases
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export function getExtraWorkers(): LotaRuntimeWorkerExtensions {
|
|
226
|
+
return resolveFromRuntime(RuntimeWorkerExtensionsServiceTag)
|
|
240
227
|
}
|
|
241
228
|
|
|
242
|
-
export
|
|
243
|
-
const adapter =
|
|
229
|
+
export function withConfiguredWorkspaceMemoryLock<T>(workspaceId: string, fn: () => Promise<T>): Promise<T> {
|
|
230
|
+
const adapter = getRuntimeAdapters().withWorkspaceMemoryLock
|
|
244
231
|
if (!adapter) {
|
|
245
232
|
return fn()
|
|
246
233
|
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { stepCountIs } from 'ai'
|
|
2
|
+
import type { ToolSet } from 'ai'
|
|
3
|
+
import { Schema, Effect } from 'effect'
|
|
4
|
+
|
|
5
|
+
import { getAgentRuntimeConfig, getResolvedAgentFactoryConfig } from '../../config/agent-defaults'
|
|
6
|
+
import { aiLogger } from '../../config/logger'
|
|
7
|
+
|
|
8
|
+
interface ExecutableToolDefinition {
|
|
9
|
+
execute: (...args: unknown[]) => Promise<unknown>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class SocialChatAgentRunnerError extends Schema.TaggedErrorClass<SocialChatAgentRunnerError>()(
|
|
13
|
+
'SocialChatAgentRunnerError',
|
|
14
|
+
{ message: Schema.String, cause: Schema.optional(Schema.Defect) },
|
|
15
|
+
) {}
|
|
16
|
+
|
|
17
|
+
const SOCIAL_CHAT_RETRIEVAL_TOOL_NAMES = [
|
|
18
|
+
'memorySearch',
|
|
19
|
+
'conversationSearch',
|
|
20
|
+
'queryKnowledge',
|
|
21
|
+
'researchTopic',
|
|
22
|
+
'searchWeb',
|
|
23
|
+
'fetchWebpage',
|
|
24
|
+
'inspectWebsite',
|
|
25
|
+
] as const
|
|
26
|
+
|
|
27
|
+
export function withLoggedSocialToolSet(
|
|
28
|
+
tools: ToolSet,
|
|
29
|
+
params: { agentId: string; channelId: string; threadId: string; executedToolNames: string[] },
|
|
30
|
+
): ToolSet {
|
|
31
|
+
return Object.fromEntries(
|
|
32
|
+
Object.entries(tools).map(([toolName, toolDefinition]) => {
|
|
33
|
+
if (
|
|
34
|
+
typeof toolDefinition !== 'object' ||
|
|
35
|
+
!('execute' in toolDefinition) ||
|
|
36
|
+
typeof toolDefinition.execute !== 'function'
|
|
37
|
+
) {
|
|
38
|
+
return [toolName, toolDefinition]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const executableTool = toolDefinition as typeof toolDefinition & ExecutableToolDefinition
|
|
42
|
+
return [
|
|
43
|
+
toolName,
|
|
44
|
+
{
|
|
45
|
+
...toolDefinition,
|
|
46
|
+
execute: (...args: unknown[]): Promise<unknown> =>
|
|
47
|
+
Effect.runPromise(
|
|
48
|
+
Effect.gen(function* () {
|
|
49
|
+
aiLogger.info`Slack social-chat tool start: agentId=${params.agentId}, tool=${toolName}, channelId=${params.channelId}, threadId=${params.threadId}`
|
|
50
|
+
const result: unknown = yield* Effect.tryPromise({
|
|
51
|
+
try: () => executableTool.execute(...args),
|
|
52
|
+
catch: (error: unknown) => new SocialChatAgentRunnerError({ message: String(error), cause: error }),
|
|
53
|
+
})
|
|
54
|
+
params.executedToolNames.push(toolName)
|
|
55
|
+
aiLogger.info`Slack social-chat tool finish: agentId=${params.agentId}, tool=${toolName}, channelId=${params.channelId}, threadId=${params.threadId}`
|
|
56
|
+
return result
|
|
57
|
+
}).pipe(
|
|
58
|
+
Effect.tapError((error) =>
|
|
59
|
+
Effect.sync(() => {
|
|
60
|
+
aiLogger.warn`Slack social-chat tool failed: agentId=${params.agentId}, tool=${toolName}, channelId=${params.channelId}, threadId=${params.threadId}, error=${error}`
|
|
61
|
+
}),
|
|
62
|
+
),
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
}),
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function runSocialAgentTurnEffect(params: {
|
|
72
|
+
agentId: string
|
|
73
|
+
mode: 'fixedThreadMode' | 'threadMode'
|
|
74
|
+
threadType: 'group'
|
|
75
|
+
onboardingActive: boolean
|
|
76
|
+
linearInstalled: boolean
|
|
77
|
+
systemWorkspaceDetails?: string
|
|
78
|
+
preSeededMemoriesSection?: string
|
|
79
|
+
retrievedKnowledgeSection?: string
|
|
80
|
+
learnedSkillsSection?: string
|
|
81
|
+
userMessageText?: string
|
|
82
|
+
additionalInstructionSections?: string[]
|
|
83
|
+
prompt: string
|
|
84
|
+
tools: ToolSet
|
|
85
|
+
abortSignal: AbortSignal
|
|
86
|
+
}): Effect.Effect<{ text: string; displayName: string }, SocialChatAgentRunnerError> {
|
|
87
|
+
return Effect.gen(function* () {
|
|
88
|
+
const runtimeConfig = getAgentRuntimeConfig({
|
|
89
|
+
agentId: params.agentId,
|
|
90
|
+
threadType: params.threadType,
|
|
91
|
+
mode: params.mode,
|
|
92
|
+
onboardingActive: params.onboardingActive,
|
|
93
|
+
linearInstalled: params.linearInstalled,
|
|
94
|
+
systemWorkspaceDetails: params.systemWorkspaceDetails,
|
|
95
|
+
preSeededMemoriesSection: params.preSeededMemoriesSection,
|
|
96
|
+
retrievedKnowledgeSection: params.retrievedKnowledgeSection,
|
|
97
|
+
learnedSkillsSection: params.learnedSkillsSection,
|
|
98
|
+
userMessageText: params.userMessageText,
|
|
99
|
+
ruleOptions: {
|
|
100
|
+
includeMemr3Rule: SOCIAL_CHAT_RETRIEVAL_TOOL_NAMES.some((toolName) => toolName in params.tools),
|
|
101
|
+
includeDomainReasoningFallbackRule: params.agentId === 'cpo' || params.agentId === 'mentor',
|
|
102
|
+
},
|
|
103
|
+
additionalInstructionSections: params.additionalInstructionSections,
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
const agentFactoryEntry = getResolvedAgentFactoryConfig().createAgent[runtimeConfig.id]
|
|
107
|
+
if (typeof agentFactoryEntry !== 'function') {
|
|
108
|
+
return yield* new SocialChatAgentRunnerError({
|
|
109
|
+
message: `Social chat agent factory is not configured for ${runtimeConfig.id}`,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
const agentFactory = agentFactoryEntry
|
|
113
|
+
|
|
114
|
+
const agent = agentFactory({
|
|
115
|
+
mode: params.mode,
|
|
116
|
+
tools: params.tools,
|
|
117
|
+
extraInstructions: runtimeConfig.extraInstructions,
|
|
118
|
+
stopWhen: [stepCountIs(runtimeConfig.maxSteps)],
|
|
119
|
+
})
|
|
120
|
+
const response = yield* Effect.promise(() =>
|
|
121
|
+
agent.generate({ prompt: params.prompt, abortSignal: params.abortSignal }),
|
|
122
|
+
)
|
|
123
|
+
const text = response.text.trim()
|
|
124
|
+
if (!text) {
|
|
125
|
+
return yield* new SocialChatAgentRunnerError({
|
|
126
|
+
message: `Social chat agent ${params.agentId} returned an empty response.`,
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
text,
|
|
132
|
+
displayName:
|
|
133
|
+
typeof runtimeConfig.displayName === 'string' && runtimeConfig.displayName.trim()
|
|
134
|
+
? runtimeConfig.displayName.trim()
|
|
135
|
+
: params.agentId,
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function runSocialAgentTurn(params: {
|
|
141
|
+
agentId: string
|
|
142
|
+
mode: 'fixedThreadMode' | 'threadMode'
|
|
143
|
+
threadType: 'group'
|
|
144
|
+
onboardingActive: boolean
|
|
145
|
+
linearInstalled: boolean
|
|
146
|
+
systemWorkspaceDetails?: string
|
|
147
|
+
preSeededMemoriesSection?: string
|
|
148
|
+
retrievedKnowledgeSection?: string
|
|
149
|
+
learnedSkillsSection?: string
|
|
150
|
+
userMessageText?: string
|
|
151
|
+
additionalInstructionSections?: string[]
|
|
152
|
+
prompt: string
|
|
153
|
+
tools: ToolSet
|
|
154
|
+
abortSignal: AbortSignal
|
|
155
|
+
}): Promise<{ text: string; displayName: string }> {
|
|
156
|
+
return Effect.runPromise(runSocialAgentTurnEffect(params))
|
|
157
|
+
}
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { stripSlackToolExecutionNoticeMarkdown } from '@lota-sdk/shared'
|
|
2
2
|
import type { Message, Thread } from 'chat'
|
|
3
|
+
import { Schema, Effect } from 'effect'
|
|
3
4
|
|
|
4
|
-
import type {
|
|
5
|
-
|
|
5
|
+
import type {
|
|
6
|
+
SocialChatHistoryMessage,
|
|
7
|
+
SocialChatHistoryMetadata,
|
|
8
|
+
SocialChatHistoryPart,
|
|
9
|
+
} from '../../services/social-chat-history.service'
|
|
10
|
+
import { toHistoryMessages, toOptionalTrimmedString } from '../thread-chat-helpers'
|
|
11
|
+
|
|
12
|
+
class SocialChatHistoryError extends Schema.TaggedErrorClass<SocialChatHistoryError>()('SocialChatHistoryError', {
|
|
13
|
+
message: Schema.String,
|
|
14
|
+
cause: Schema.optional(Schema.Defect),
|
|
15
|
+
}) {}
|
|
6
16
|
|
|
7
17
|
export function readSlackAuthorName(message: Message): string | undefined {
|
|
8
18
|
return (
|
|
@@ -14,13 +24,9 @@ export function readSlackAuthorName(message: Message): string | undefined {
|
|
|
14
24
|
}
|
|
15
25
|
|
|
16
26
|
export function buildSocialChatThreadTranscript(
|
|
17
|
-
messages:
|
|
18
|
-
role: 'user' | 'assistant'
|
|
19
|
-
parts: Array<Record<string, unknown>>
|
|
20
|
-
metadata?: Record<string, unknown>
|
|
21
|
-
}>,
|
|
27
|
+
messages: ReadonlyArray<Pick<SocialChatHistoryMessage, 'role' | 'parts' | 'metadata'>>,
|
|
22
28
|
): string {
|
|
23
|
-
const historyMessages = toHistoryMessages(messages)
|
|
29
|
+
const historyMessages = toHistoryMessages([...messages])
|
|
24
30
|
if (historyMessages.length === 0) return 'No prior thread history.'
|
|
25
31
|
|
|
26
32
|
return historyMessages
|
|
@@ -58,11 +64,11 @@ export function normalizeSocialHistoryMessage(params: {
|
|
|
58
64
|
mediaType: attachment.mimeType ?? 'application/octet-stream',
|
|
59
65
|
sizeBytes: typeof attachment.size === 'number' ? attachment.size : null,
|
|
60
66
|
storageKey: attachment.url ?? 'external',
|
|
61
|
-
}))
|
|
67
|
+
})) satisfies SocialChatHistoryPart[]
|
|
62
68
|
const parts = [...(text ? [{ type: 'text', text }] : []), ...fileParts]
|
|
63
69
|
if (parts.length === 0) return null
|
|
64
70
|
|
|
65
|
-
const metadata:
|
|
71
|
+
const metadata: SocialChatHistoryMetadata = {
|
|
66
72
|
platform: 'slack',
|
|
67
73
|
channelId: params.channelId,
|
|
68
74
|
threadId: params.message.threadId,
|
|
@@ -97,14 +103,30 @@ export function normalizeSocialHistoryMessage(params: {
|
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
105
|
|
|
100
|
-
export
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
export function collectThreadMessages(thread: Thread, incomingMessage: Message): Promise<Message[]> {
|
|
107
|
+
return Effect.runPromise(
|
|
108
|
+
Effect.catch(
|
|
109
|
+
Effect.gen(function* () {
|
|
110
|
+
const collected: Message[] = []
|
|
111
|
+
const iterator = thread.allMessages[Symbol.asyncIterator]()
|
|
112
|
+
|
|
113
|
+
for (;;) {
|
|
114
|
+
const next = yield* Effect.tryPromise({
|
|
115
|
+
try: () => iterator.next(),
|
|
116
|
+
catch: (error: unknown) =>
|
|
117
|
+
new SocialChatHistoryError({ message: 'Failed to read thread messages', cause: error }),
|
|
118
|
+
})
|
|
119
|
+
if (next.done) break
|
|
120
|
+
collected.push(next.value)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return collected.length > 0
|
|
124
|
+
? collected
|
|
125
|
+
: thread.recentMessages.length > 0
|
|
126
|
+
? [...thread.recentMessages]
|
|
127
|
+
: [incomingMessage]
|
|
128
|
+
}),
|
|
129
|
+
() => Effect.succeed(thread.recentMessages.length > 0 ? [...thread.recentMessages] : [incomingMessage]),
|
|
130
|
+
),
|
|
131
|
+
)
|
|
110
132
|
}
|