@lota-sdk/core 0.4.9 → 0.4.10
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 +2 -2
- package/src/ai/embedding-cache.ts +3 -1
- package/src/ai-gateway/ai-gateway.ts +38 -10
- package/src/config/agent-defaults.ts +22 -9
- package/src/config/agent-types.ts +1 -1
- package/src/config/background-processing.ts +1 -1
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +20 -7
- package/src/config/thread-defaults.ts +12 -4
- package/src/create-runtime.ts +69 -656
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.ts +29 -20
- package/src/db/memory.ts +188 -195
- package/src/db/service-normalization.ts +97 -64
- package/src/db/service.ts +706 -538
- package/src/db/startup.ts +30 -19
- package/src/effect/awaitable-effect.ts +46 -37
- package/src/effect/helpers.ts +30 -5
- package/src/effect/index.ts +7 -5
- package/src/effect/layers.ts +82 -72
- package/src/effect/runtime.ts +18 -3
- package/src/effect/services.ts +15 -11
- package/src/embeddings/provider.ts +65 -66
- package/src/index.ts +13 -11
- package/src/queues/autonomous-job.queue.ts +59 -71
- package/src/queues/context-compaction.queue.ts +6 -18
- package/src/queues/delayed-node-promotion.queue.ts +9 -17
- package/src/queues/organization-learning.queue.ts +17 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +23 -20
- package/src/queues/plan-scheduler.queue.ts +6 -18
- package/src/queues/post-chat-memory.queue.ts +6 -18
- package/src/queues/queue-factory.ts +128 -50
- package/src/queues/title-generation.queue.ts +6 -17
- package/src/redis/connection.ts +181 -164
- package/src/redis/runtime-connection.ts +13 -3
- package/src/redis/stream-context.ts +17 -9
- package/src/runtime/agent-runtime-policy.ts +1 -1
- package/src/runtime/agent-stream-helpers.ts +15 -11
- package/src/runtime/chat-run-orchestration.ts +1 -1
- package/src/runtime/context-compaction/context-compaction-runtime.ts +1 -1
- package/src/runtime/context-compaction/context-compaction.ts +126 -82
- package/src/runtime/domain-layer.ts +192 -0
- package/src/runtime/graph-designer.ts +15 -7
- package/src/runtime/helper-model.ts +8 -4
- package/src/runtime/index.ts +0 -1
- package/src/runtime/memory/memory-block.ts +19 -9
- package/src/runtime/memory/memory-pipeline.ts +53 -66
- package/src/runtime/memory/memory-scope.ts +33 -29
- package/src/runtime/plugin-resolution.ts +33 -54
- package/src/runtime/post-turn-side-effects.ts +6 -26
- package/src/runtime/retrieval-adapters.ts +4 -4
- package/src/runtime/runtime-accessors.ts +92 -0
- package/src/runtime/runtime-config.ts +3 -3
- package/src/runtime/runtime-extensions.ts +20 -9
- package/src/runtime/runtime-lifecycle.ts +124 -0
- package/src/runtime/runtime-services.ts +386 -0
- package/src/runtime/runtime-token.ts +47 -0
- package/src/runtime/social-chat/social-chat-agent-runner.ts +7 -5
- package/src/runtime/social-chat/social-chat-history.ts +21 -12
- package/src/runtime/social-chat/social-chat.ts +401 -365
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +58 -52
- package/src/runtime/thread-turn-context.ts +21 -27
- package/src/services/agent-activity.service.ts +1 -1
- package/src/services/agent-executor.service.ts +179 -187
- package/src/services/artifact.service.ts +10 -5
- package/src/services/attachment.service.ts +35 -1
- package/src/services/autonomous-job.service.ts +58 -56
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +3 -1
- package/src/services/context-compaction.service.ts +1 -1
- package/src/services/document-chunk.service.ts +8 -17
- package/src/services/execution-plan/execution-plan-graph.ts +74 -52
- package/src/services/execution-plan/execution-plan.service.ts +1 -1
- package/src/services/feedback-loop.service.ts +1 -1
- package/src/services/global-orchestrator.service.ts +33 -10
- package/src/services/graph-full-routing.ts +44 -33
- package/src/services/index.ts +1 -0
- package/src/services/institutional-memory.service.ts +8 -17
- package/src/services/learned-skill.service.ts +38 -35
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +14 -3
- package/src/services/memory/memory-preseeded.ts +10 -4
- package/src/services/memory/memory-utils.ts +2 -1
- package/src/services/memory/memory.service.ts +26 -44
- package/src/services/memory/rerank.service.ts +3 -11
- package/src/services/monitoring-window.service.ts +1 -1
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +2 -2
- package/src/services/notification.service.ts +16 -4
- package/src/services/organization-member.service.ts +1 -1
- package/src/services/organization.service.ts +34 -51
- package/src/services/ownership-dispatcher.service.ts +132 -90
- package/src/services/plan/plan-agent-heartbeat.service.ts +1 -1
- package/src/services/plan/plan-agent-query.service.ts +1 -1
- package/src/services/plan/plan-approval.service.ts +52 -48
- package/src/services/plan/plan-artifact.service.ts +2 -2
- package/src/services/plan/plan-builder.service.ts +2 -2
- package/src/services/plan/plan-checkpoint.service.ts +1 -1
- package/src/services/plan/plan-compiler.service.ts +1 -1
- package/src/services/plan/plan-completion-side-effects.ts +18 -24
- package/src/services/plan/plan-coordination.service.ts +1 -1
- package/src/services/plan/plan-cycle.service.ts +171 -164
- package/src/services/plan/plan-deadline.service.ts +290 -304
- package/src/services/plan/plan-event-delivery.service.ts +44 -39
- package/src/services/plan/plan-executor-graph.ts +114 -67
- package/src/services/plan/plan-executor-helpers.ts +60 -75
- package/src/services/plan/plan-executor.service.ts +550 -467
- package/src/services/plan/plan-run.service.ts +12 -19
- package/src/services/plan/plan-scheduler.service.ts +27 -33
- package/src/services/plan/plan-template.service.ts +1 -1
- package/src/services/plan/plan-transaction-events.ts +8 -5
- package/src/services/plan/plan-validator.service.ts +1 -1
- package/src/services/plan/plan-workspace.service.ts +17 -11
- package/src/services/plugin-executor.service.ts +26 -21
- package/src/services/quality-metrics.service.ts +1 -1
- package/src/services/queue-job.service.ts +8 -17
- package/src/services/recent-activity-title.service.ts +17 -9
- package/src/services/recent-activity.service.ts +1 -1
- package/src/services/skill-resolver.service.ts +1 -1
- package/src/services/social-chat-history.service.ts +37 -20
- package/src/services/system-executor.service.ts +25 -20
- package/src/services/thread/thread-bootstrap.ts +26 -10
- package/src/services/thread/thread-listing.ts +2 -1
- package/src/services/thread/thread-memory-block.ts +18 -5
- package/src/services/thread/thread-message.service.ts +24 -8
- package/src/services/thread/thread-title.service.ts +1 -1
- package/src/services/thread/thread-turn-execution.ts +1 -1
- package/src/services/thread/thread-turn-preparation.service.ts +18 -16
- package/src/services/thread/thread-turn-streaming.ts +12 -11
- package/src/services/thread/thread-turn.ts +43 -10
- package/src/services/thread/thread.service.ts +11 -2
- package/src/services/user.service.ts +1 -1
- package/src/services/write-intent-validator.service.ts +1 -1
- package/src/storage/attachment-storage.service.ts +7 -4
- package/src/storage/generated-document-storage.service.ts +1 -1
- package/src/system-agents/context-compaction.agent.ts +1 -1
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +1 -1
- package/src/system-agents/memory.agent.ts +1 -1
- package/src/system-agents/recent-activity-title-refiner.agent.ts +1 -1
- package/src/system-agents/regular-chat-memory-digest.agent.ts +1 -1
- package/src/system-agents/skill-extractor.agent.ts +1 -1
- package/src/system-agents/skill-manager.agent.ts +1 -1
- package/src/system-agents/title-generator.agent.ts +1 -1
- package/src/tools/execution-plan.tool.ts +28 -17
- package/src/tools/fetch-webpage.tool.ts +20 -13
- package/src/tools/firecrawl-client.ts +13 -3
- package/src/tools/plan-approval.tool.ts +9 -1
- package/src/tools/search-web.tool.ts +16 -9
- package/src/tools/team-think.tool.ts +2 -2
- package/src/utils/async.ts +15 -6
- package/src/utils/errors.ts +27 -15
- package/src/workers/bootstrap.ts +25 -48
- package/src/workers/organization-learning.worker.ts +1 -1
- package/src/workers/regular-chat-memory-digest.runner.ts +25 -15
- package/src/workers/worker-utils.ts +20 -2
- package/src/config/search.ts +0 -3
- package/src/runtime/agent-types.ts +0 -1
|
@@ -10,8 +10,8 @@ import type { ChatMessage, ConsultSpecialistArgs } from '@lota-sdk/shared'
|
|
|
10
10
|
import { tool as createTool } from 'ai'
|
|
11
11
|
import { Chat, ConsoleLogger } from 'chat'
|
|
12
12
|
import type { Message, Thread, WebhookOptions } from 'chat'
|
|
13
|
-
import type { Context } from 'effect'
|
|
14
|
-
import {
|
|
13
|
+
import type { Context, Cause } from 'effect'
|
|
14
|
+
import { Clock, Effect, Schema } from 'effect'
|
|
15
15
|
|
|
16
16
|
import { getAgentDisplayNames, getTeamConsultParticipants } from '../../config/agent-defaults'
|
|
17
17
|
import { aiLogger } from '../../config/logger'
|
|
@@ -23,7 +23,7 @@ import { enqueueRegularChatMemoryDigest, enqueueSkillExtraction } from '../../qu
|
|
|
23
23
|
import { enqueuePostChatMemory } from '../../queues/post-chat-memory.queue'
|
|
24
24
|
import type { LearnedSkillServiceTag } from '../../services/learned-skill.service'
|
|
25
25
|
import type { MemoryServiceTag } from '../../services/memory/memory.service'
|
|
26
|
-
import type { makeSocialChatHistoryService } from '../../services/social-chat-history.service'
|
|
26
|
+
import type { SocialChatHistoryError, makeSocialChatHistoryService } from '../../services/social-chat-history.service'
|
|
27
27
|
import { safeEnqueue } from '../../utils/async'
|
|
28
28
|
import { buildAgentPromptContext } from '../agent-prompt-context'
|
|
29
29
|
import { createServerRunAbortController } from '../agent-stream-helpers'
|
|
@@ -60,6 +60,11 @@ export interface SocialChatRuntimeServices {
|
|
|
60
60
|
socialChatHistoryService: ReturnType<typeof makeSocialChatHistoryService>
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
class SocialChatServiceError extends Schema.TaggedErrorClass<SocialChatServiceError>()('SocialChatServiceError', {
|
|
64
|
+
message: Schema.String,
|
|
65
|
+
cause: Schema.optional(Schema.Defect),
|
|
66
|
+
}) {}
|
|
67
|
+
|
|
63
68
|
const DEFAULT_SOCIAL_CHAT_AGENT_ID = 'socialChat'
|
|
64
69
|
const DEFAULT_SOCIAL_CHAT_AGENT_DISPLAY_NAME = 'Lota'
|
|
65
70
|
const DEFAULT_SOCIAL_CHAT_STATE_PREFIX = 'lota:social:chat-sdk'
|
|
@@ -192,384 +197,415 @@ export function createSocialChatRuntime(params: {
|
|
|
192
197
|
const handleMessage = (
|
|
193
198
|
thread: Thread,
|
|
194
199
|
incomingMessage: Message,
|
|
195
|
-
): Effect.Effect<
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
authorName: messageContext.authorName,
|
|
221
|
-
}),
|
|
222
|
-
)
|
|
223
|
-
const workspaceIdString = recordIdToString(resolvedContext.workspaceId, TABLES.ORGANIZATION)
|
|
224
|
-
const userIdString = recordIdToString(resolvedContext.userId, TABLES.USER)
|
|
225
|
-
aiLogger.info`Slack social-chat context resolved: workspaceId=${workspaceIdString}, userId=${userIdString}`
|
|
226
|
-
|
|
227
|
-
const threadMessages = yield* effectTryPromise(() => collectThreadMessages(thread, incomingMessage))
|
|
228
|
-
const normalizedMessages = threadMessages
|
|
229
|
-
.map((message) =>
|
|
230
|
-
normalizeSocialHistoryMessage({
|
|
231
|
-
workspaceId: workspaceIdString,
|
|
200
|
+
): Effect.Effect<
|
|
201
|
+
void,
|
|
202
|
+
Cause.UnknownError | ForbiddenError | SocialChatHistoryError | SocialChatServiceError,
|
|
203
|
+
never
|
|
204
|
+
> =>
|
|
205
|
+
Effect.scoped(
|
|
206
|
+
Effect.gen(function* () {
|
|
207
|
+
const { memoryService, learnedSkillService, socialChatHistoryService } = params.services
|
|
208
|
+
const currentContext = yield* Effect.context()
|
|
209
|
+
const runPromiseWithCurrentContext = Effect.runPromiseWith(currentContext)
|
|
210
|
+
const rawSlackMessage = incomingMessage.raw as { channel?: unknown } | undefined
|
|
211
|
+
const channelId = toOptionalTrimmedString(rawSlackMessage?.channel) ?? thread.channelId
|
|
212
|
+
const messageContext: SlackSocialMessageContext = {
|
|
213
|
+
channelId,
|
|
214
|
+
threadId: thread.id,
|
|
215
|
+
messageId: incomingMessage.id,
|
|
216
|
+
text: incomingMessage.text.trim(),
|
|
217
|
+
authorId: toOptionalTrimmedString(incomingMessage.author.userId) ?? undefined,
|
|
218
|
+
authorName: readSlackAuthorName(incomingMessage),
|
|
219
|
+
}
|
|
220
|
+
aiLogger.debug`Slack social-chat message received: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}, messageId=${messageContext.messageId}, author=${messageContext.authorName ?? 'unknown'}, textLength=${messageContext.text.length}`
|
|
221
|
+
|
|
222
|
+
const resolvedContext = yield* effectTryMaybeAsync(() =>
|
|
223
|
+
socialChatConfig.resolveContext({
|
|
224
|
+
platform: 'slack',
|
|
232
225
|
channelId: messageContext.channelId,
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
226
|
+
threadId: messageContext.threadId,
|
|
227
|
+
messageId: messageContext.messageId,
|
|
228
|
+
text: messageContext.text,
|
|
229
|
+
authorId: messageContext.authorId,
|
|
230
|
+
authorName: messageContext.authorName,
|
|
236
231
|
}),
|
|
237
232
|
)
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const getWorkspace = workspaceProvider?.getWorkspace
|
|
253
|
-
? workspaceProvider.getWorkspace.bind(workspaceProvider)
|
|
254
|
-
: undefined
|
|
255
|
-
const getLifecycleState = workspaceProvider?.getLifecycleState
|
|
256
|
-
? workspaceProvider.getLifecycleState.bind(workspaceProvider)
|
|
257
|
-
: undefined
|
|
258
|
-
const readProfileProjectionState = workspaceProvider?.readProfileProjectionState
|
|
259
|
-
? workspaceProvider.readProfileProjectionState.bind(workspaceProvider)
|
|
260
|
-
: undefined
|
|
261
|
-
const listRecentDomainEvents = workspaceProvider?.listRecentDomainEvents
|
|
262
|
-
? workspaceProvider.listRecentDomainEvents.bind(workspaceProvider)
|
|
263
|
-
: undefined
|
|
264
|
-
const buildPromptSummary = workspaceProvider?.buildPromptSummary
|
|
265
|
-
? workspaceProvider.buildPromptSummary.bind(workspaceProvider)
|
|
266
|
-
: undefined
|
|
267
|
-
const buildRetrievedKnowledgeSection = workspaceProvider?.buildRetrievedKnowledgeSection
|
|
268
|
-
? workspaceProvider.buildRetrievedKnowledgeSection.bind(workspaceProvider)
|
|
269
|
-
: undefined
|
|
270
|
-
const getConsultParticipants = socialChatConfig.getConsultParticipants
|
|
271
|
-
|
|
272
|
-
const workspace = getWorkspace ? yield* effectTryMaybeAsync(() => getWorkspace(resolvedContext.workspaceId)) : {}
|
|
273
|
-
const lifecycleState = getLifecycleState
|
|
274
|
-
? yield* effectTryMaybeAsync(() => getLifecycleState(workspace))
|
|
275
|
-
: undefined
|
|
276
|
-
const workspaceProfileState = readProfileProjectionState
|
|
277
|
-
? yield* effectTryMaybeAsync(() => readProfileProjectionState(workspace))
|
|
278
|
-
: undefined
|
|
279
|
-
const recentDomainEvents = listRecentDomainEvents
|
|
280
|
-
? yield* effectTryMaybeAsync(() => listRecentDomainEvents(resolvedContext.workspaceId, 5))
|
|
281
|
-
: ([] as Array<Record<string, unknown>>)
|
|
282
|
-
const promptSummary = buildPromptSummary
|
|
283
|
-
? yield* effectTryMaybeAsync(() => buildPromptSummary(resolvedContext.workspaceId)).pipe(
|
|
284
|
-
Effect.orElseSucceed(() => undefined),
|
|
233
|
+
const workspaceIdString = recordIdToString(resolvedContext.workspaceId, TABLES.ORGANIZATION)
|
|
234
|
+
const userIdString = recordIdToString(resolvedContext.userId, TABLES.USER)
|
|
235
|
+
aiLogger.debug`Slack social-chat context resolved: workspaceId=${workspaceIdString}, userId=${userIdString}`
|
|
236
|
+
|
|
237
|
+
const threadMessages = yield* effectTryPromise(() => collectThreadMessages(thread, incomingMessage))
|
|
238
|
+
const normalizedMessages = threadMessages
|
|
239
|
+
.map((message) =>
|
|
240
|
+
normalizeSocialHistoryMessage({
|
|
241
|
+
workspaceId: workspaceIdString,
|
|
242
|
+
channelId: messageContext.channelId,
|
|
243
|
+
agentId: socialAgentId,
|
|
244
|
+
agentDisplayName: socialAgentDisplayName,
|
|
245
|
+
message,
|
|
246
|
+
}),
|
|
285
247
|
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
248
|
+
.filter((message): message is NonNullable<typeof message> => message !== null)
|
|
249
|
+
yield* socialChatHistoryService.upsertMessages(normalizedMessages)
|
|
250
|
+
|
|
251
|
+
const historyBeforeReply = yield* socialChatHistoryService.listThreadMessages({
|
|
252
|
+
workspaceId: workspaceIdString,
|
|
253
|
+
threadId: messageContext.threadId,
|
|
254
|
+
})
|
|
255
|
+
const currentUserMessage =
|
|
256
|
+
historyBeforeReply.find((message) => message.messageId === incomingMessage.id) ?? historyBeforeReply.at(-1)
|
|
257
|
+
const priorHistory = currentUserMessage
|
|
258
|
+
? historyBeforeReply.filter((message) => message.cursor.id !== currentUserMessage.cursor.id)
|
|
259
|
+
: historyBeforeReply
|
|
260
|
+
|
|
261
|
+
const workspaceProvider = getRuntimeAdapters().workspaceProvider
|
|
262
|
+
const getWorkspace = workspaceProvider?.getWorkspace
|
|
263
|
+
? workspaceProvider.getWorkspace.bind(workspaceProvider)
|
|
264
|
+
: undefined
|
|
265
|
+
const getLifecycleState = workspaceProvider?.getLifecycleState
|
|
266
|
+
? workspaceProvider.getLifecycleState.bind(workspaceProvider)
|
|
267
|
+
: undefined
|
|
268
|
+
const readProfileProjectionState = workspaceProvider?.readProfileProjectionState
|
|
269
|
+
? workspaceProvider.readProfileProjectionState.bind(workspaceProvider)
|
|
270
|
+
: undefined
|
|
271
|
+
const listRecentDomainEvents = workspaceProvider?.listRecentDomainEvents
|
|
272
|
+
? workspaceProvider.listRecentDomainEvents.bind(workspaceProvider)
|
|
273
|
+
: undefined
|
|
274
|
+
const buildPromptSummary = workspaceProvider?.buildPromptSummary
|
|
275
|
+
? workspaceProvider.buildPromptSummary.bind(workspaceProvider)
|
|
276
|
+
: undefined
|
|
277
|
+
const buildRetrievedKnowledgeSection = workspaceProvider?.buildRetrievedKnowledgeSection
|
|
278
|
+
? workspaceProvider.buildRetrievedKnowledgeSection.bind(workspaceProvider)
|
|
279
|
+
: undefined
|
|
280
|
+
const getConsultParticipants = socialChatConfig.getConsultParticipants
|
|
281
|
+
|
|
282
|
+
const workspace = getWorkspace
|
|
283
|
+
? yield* effectTryMaybeAsync(() => getWorkspace(resolvedContext.workspaceId))
|
|
284
|
+
: {}
|
|
285
|
+
const lifecycleState = getLifecycleState
|
|
286
|
+
? yield* effectTryMaybeAsync(() => getLifecycleState(workspace))
|
|
287
|
+
: undefined
|
|
288
|
+
const workspaceProfileState = readProfileProjectionState
|
|
289
|
+
? yield* effectTryMaybeAsync(() => readProfileProjectionState(workspace))
|
|
290
|
+
: undefined
|
|
291
|
+
const recentDomainEvents = listRecentDomainEvents
|
|
292
|
+
? yield* effectTryMaybeAsync(() => listRecentDomainEvents(resolvedContext.workspaceId, 5))
|
|
293
|
+
: ([] as Array<Record<string, unknown>>)
|
|
294
|
+
const promptSummary = buildPromptSummary
|
|
295
|
+
? yield* effectTryMaybeAsync(() => buildPromptSummary(resolvedContext.workspaceId)).pipe(
|
|
296
|
+
Effect.orElseSucceed(() => undefined),
|
|
297
|
+
)
|
|
298
|
+
: undefined
|
|
299
|
+
|
|
300
|
+
const promptContext = buildAgentPromptContext({
|
|
301
|
+
workspaceName:
|
|
302
|
+
workspaceProfileState?.workspaceName ??
|
|
303
|
+
toOptionalTrimmedString((workspace as { name?: unknown }).name) ??
|
|
304
|
+
undefined,
|
|
305
|
+
summaryBlock: workspaceProfileState?.summaryBlock,
|
|
306
|
+
promptSummary,
|
|
307
|
+
userName: messageContext.authorName,
|
|
308
|
+
recentDomainEvents,
|
|
309
|
+
})
|
|
310
|
+
const retrievedKnowledgeSection =
|
|
311
|
+
lifecycleState?.bootstrapActive || messageContext.text.length === 0
|
|
312
|
+
? undefined
|
|
313
|
+
: buildRetrievedKnowledgeSection
|
|
314
|
+
? yield* effectTryMaybeAsync(() =>
|
|
315
|
+
buildRetrievedKnowledgeSection({
|
|
316
|
+
workspaceId: workspaceIdString,
|
|
317
|
+
userId: userIdString,
|
|
318
|
+
query: messageContext.text,
|
|
319
|
+
}),
|
|
320
|
+
)
|
|
321
|
+
: undefined
|
|
322
|
+
|
|
323
|
+
const preSeededMemoriesSection = yield* memoryService
|
|
324
|
+
.getTopMemories({ orgId: workspaceIdString, agentName: socialAgentId, limit: PRESEEDED_MEMORY_LOOKUP_LIMIT })
|
|
325
|
+
.pipe(
|
|
326
|
+
Effect.mapError(
|
|
327
|
+
(cause) =>
|
|
328
|
+
new SocialChatServiceError({
|
|
329
|
+
message: `Failed to load pre-seeded memories for ${socialAgentId}.`,
|
|
330
|
+
cause,
|
|
307
331
|
}),
|
|
308
|
-
|
|
309
|
-
: undefined
|
|
310
|
-
|
|
311
|
-
const preSeededMemoriesSection = yield* memoryService
|
|
312
|
-
.getTopMemories({ orgId: workspaceIdString, agentName: socialAgentId, limit: PRESEEDED_MEMORY_LOOKUP_LIMIT })
|
|
313
|
-
.pipe(Effect.mapError((cause) => new Cause.UnknownError(cause)))
|
|
314
|
-
const learnedSkillsSection = lifecycleState?.bootstrapActive
|
|
315
|
-
? undefined
|
|
316
|
-
: yield* learnedSkillService
|
|
317
|
-
.retrieveForTurn({
|
|
318
|
-
orgId: workspaceIdString,
|
|
319
|
-
agentId: socialAgentId,
|
|
320
|
-
query: messageContext.text,
|
|
321
|
-
limit: 3,
|
|
322
|
-
minConfidence: 0.6,
|
|
323
|
-
})
|
|
324
|
-
.pipe(Effect.orElseSucceed(() => undefined))
|
|
325
|
-
|
|
326
|
-
let memoryBlock = ''
|
|
327
|
-
const consultedAgents = getConsultParticipants
|
|
328
|
-
? yield* effectTryMaybeAsync(() =>
|
|
329
|
-
getConsultParticipants({ workspaceId: resolvedContext.workspaceId, workspaceIdString, platform: 'slack' }),
|
|
332
|
+
),
|
|
330
333
|
)
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
334
|
+
const learnedSkillsSection = lifecycleState?.bootstrapActive
|
|
335
|
+
? undefined
|
|
336
|
+
: yield* learnedSkillService
|
|
337
|
+
.retrieveForTurn({
|
|
338
|
+
orgId: workspaceIdString,
|
|
339
|
+
agentId: socialAgentId,
|
|
340
|
+
query: messageContext.text,
|
|
341
|
+
limit: 3,
|
|
342
|
+
minConfidence: 0.6,
|
|
343
|
+
})
|
|
344
|
+
.pipe(Effect.orElseSucceed(() => undefined))
|
|
345
|
+
|
|
346
|
+
let memoryBlock = ''
|
|
347
|
+
const consultedAgents = getConsultParticipants
|
|
348
|
+
? yield* effectTryMaybeAsync(() =>
|
|
349
|
+
getConsultParticipants({
|
|
350
|
+
workspaceId: resolvedContext.workspaceId,
|
|
351
|
+
workspaceIdString,
|
|
352
|
+
platform: 'slack',
|
|
353
|
+
}),
|
|
354
|
+
)
|
|
355
|
+
: [...getTeamConsultParticipants()]
|
|
356
|
+
const consultParticipants = [...new Set(consultedAgents)].filter((agentId) => agentId !== socialAgentId)
|
|
357
|
+
const executedToolNames: string[] = []
|
|
358
|
+
|
|
359
|
+
const baseTools = withLoggedSocialToolSet(
|
|
360
|
+
yield* effectTryMaybeAsync(() =>
|
|
361
|
+
socialChatConfig.buildAgentTools(
|
|
362
|
+
buildBuildToolsParams({
|
|
363
|
+
agentId: socialAgentId,
|
|
364
|
+
context: resolvedContext,
|
|
365
|
+
workspaceIdString,
|
|
366
|
+
userIdString,
|
|
367
|
+
messageContext,
|
|
368
|
+
memoryBlock,
|
|
369
|
+
onAppendMemoryBlock: (value: string) => {
|
|
370
|
+
memoryBlock = value
|
|
371
|
+
},
|
|
372
|
+
}),
|
|
373
|
+
),
|
|
349
374
|
),
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
workspaceIdString,
|
|
386
|
-
userIdString,
|
|
387
|
-
messageContext,
|
|
388
|
-
memoryBlock: currentMemoryBlock,
|
|
389
|
-
onAppendMemoryBlock,
|
|
390
|
-
}),
|
|
391
|
-
),
|
|
392
|
-
)
|
|
393
|
-
|
|
394
|
-
return withLoggedSocialToolSet(tools, {
|
|
395
|
-
agentId,
|
|
396
|
-
channelId: messageContext.channelId,
|
|
397
|
-
threadId: messageContext.threadId,
|
|
398
|
-
executedToolNames,
|
|
399
|
-
})
|
|
400
|
-
}),
|
|
401
|
-
),
|
|
402
|
-
run: ({ tools }) =>
|
|
403
|
-
runPromiseWithCurrentContext(
|
|
404
|
-
Effect.gen(function* () {
|
|
405
|
-
const specialistPreSeededMemories = yield* memoryService
|
|
406
|
-
.getTopMemories({
|
|
407
|
-
orgId: workspaceIdString,
|
|
408
|
-
agentName: agentId,
|
|
409
|
-
limit: PRESEEDED_MEMORY_LOOKUP_LIMIT,
|
|
410
|
-
})
|
|
411
|
-
.pipe(Effect.mapError((cause) => new Cause.UnknownError(cause)))
|
|
412
|
-
const specialistLearnedSkills = lifecycleState?.bootstrapActive
|
|
413
|
-
? undefined
|
|
414
|
-
: yield* learnedSkillService
|
|
415
|
-
.retrieveForTurn({
|
|
416
|
-
orgId: workspaceIdString,
|
|
375
|
+
{
|
|
376
|
+
agentId: socialAgentId,
|
|
377
|
+
channelId: messageContext.channelId,
|
|
378
|
+
threadId: messageContext.threadId,
|
|
379
|
+
executedToolNames,
|
|
380
|
+
},
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
const transcript = buildSocialChatThreadTranscript(historyBeforeReply)
|
|
384
|
+
const runAbort = yield* Effect.acquireRelease(
|
|
385
|
+
Effect.sync(() => createServerRunAbortController()),
|
|
386
|
+
(controller) => Effect.sync(() => controller.dispose()),
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
const consultSpecialistTool = createTool({
|
|
390
|
+
description: 'Consult one specialist teammate for targeted guidance before replying to the user.',
|
|
391
|
+
inputSchema: ConsultSpecialistArgsSchema,
|
|
392
|
+
execute: ({ agentId, task }: ConsultSpecialistArgs) =>
|
|
393
|
+
runPromiseWithCurrentContext(
|
|
394
|
+
Effect.gen(function* () {
|
|
395
|
+
if (!consultParticipants.includes(agentId)) {
|
|
396
|
+
return yield* new ForbiddenError({
|
|
397
|
+
message: `Agent "${agentId}" is not an allowed social-chat specialist.`,
|
|
398
|
+
})
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const { result: specialistRun } = yield* effectTryMaybeAsync(() =>
|
|
402
|
+
runSpecialistSession({
|
|
403
|
+
initialMemoryBlock: '',
|
|
404
|
+
buildTools: ({ memoryBlock: currentMemoryBlock, onAppendMemoryBlock }) =>
|
|
405
|
+
runPromiseWithCurrentContext(
|
|
406
|
+
Effect.gen(function* () {
|
|
407
|
+
const tools = yield* effectTryMaybeAsync(() =>
|
|
408
|
+
socialChatConfig.buildAgentTools(
|
|
409
|
+
buildBuildToolsParams({
|
|
417
410
|
agentId,
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
411
|
+
context: resolvedContext,
|
|
412
|
+
workspaceIdString,
|
|
413
|
+
userIdString,
|
|
414
|
+
messageContext,
|
|
415
|
+
memoryBlock: currentMemoryBlock,
|
|
416
|
+
onAppendMemoryBlock,
|
|
417
|
+
}),
|
|
418
|
+
),
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
return withLoggedSocialToolSet(tools, {
|
|
426
422
|
agentId,
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
423
|
+
channelId: messageContext.channelId,
|
|
424
|
+
threadId: messageContext.threadId,
|
|
425
|
+
executedToolNames,
|
|
426
|
+
})
|
|
427
|
+
}),
|
|
428
|
+
),
|
|
429
|
+
run: ({ tools }) =>
|
|
430
|
+
runPromiseWithCurrentContext(
|
|
431
|
+
Effect.gen(function* () {
|
|
432
|
+
const specialistPreSeededMemories = yield* memoryService
|
|
433
|
+
.getTopMemories({
|
|
434
|
+
orgId: workspaceIdString,
|
|
435
|
+
agentName: agentId,
|
|
436
|
+
limit: PRESEEDED_MEMORY_LOOKUP_LIMIT,
|
|
437
|
+
})
|
|
438
|
+
.pipe(
|
|
439
|
+
Effect.mapError(
|
|
440
|
+
(cause) =>
|
|
441
|
+
new SocialChatServiceError({
|
|
442
|
+
message: `Failed to load pre-seeded memories for specialist ${agentId}.`,
|
|
443
|
+
cause,
|
|
444
|
+
}),
|
|
445
|
+
),
|
|
446
|
+
)
|
|
447
|
+
const specialistLearnedSkills = lifecycleState?.bootstrapActive
|
|
448
|
+
? undefined
|
|
449
|
+
: yield* learnedSkillService
|
|
450
|
+
.retrieveForTurn({
|
|
451
|
+
orgId: workspaceIdString,
|
|
452
|
+
agentId,
|
|
453
|
+
query: task,
|
|
454
|
+
limit: 3,
|
|
455
|
+
minConfidence: 0.6,
|
|
456
|
+
})
|
|
457
|
+
.pipe(Effect.orElseSucceed(() => undefined))
|
|
458
|
+
|
|
459
|
+
return yield* effectTryPromise(() =>
|
|
460
|
+
runSocialAgentTurn({
|
|
461
|
+
agentId,
|
|
462
|
+
mode: 'fixedThreadMode',
|
|
463
|
+
threadType: 'group',
|
|
464
|
+
onboardingActive: lifecycleState?.bootstrapActive ?? false,
|
|
465
|
+
linearInstalled: false,
|
|
466
|
+
systemWorkspaceDetails: promptContext.systemWorkspaceDetails,
|
|
467
|
+
preSeededMemoriesSection: specialistPreSeededMemories,
|
|
468
|
+
retrievedKnowledgeSection,
|
|
469
|
+
learnedSkillsSection: specialistLearnedSkills,
|
|
470
|
+
userMessageText: task,
|
|
471
|
+
additionalInstructionSections: [
|
|
472
|
+
`You are supporting ${socialAgentDisplayName} in a Slack social-chat thread. Stay within your role.`,
|
|
473
|
+
],
|
|
474
|
+
tools,
|
|
475
|
+
prompt: buildSpecialistSocialChatPrompt({
|
|
476
|
+
requesterName: socialAgentDisplayName,
|
|
477
|
+
agentName: getAgentDisplayName(agentId),
|
|
478
|
+
task,
|
|
479
|
+
transcript,
|
|
480
|
+
}),
|
|
481
|
+
abortSignal: runAbort.signal,
|
|
445
482
|
}),
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
483
|
+
)
|
|
484
|
+
}),
|
|
485
|
+
),
|
|
486
|
+
}),
|
|
487
|
+
)
|
|
488
|
+
const text = specialistRun.text
|
|
489
|
+
const createdAt = yield* Clock.currentTimeMillis
|
|
490
|
+
|
|
491
|
+
return createAssistantMessage({ agentId, agentName: getAgentDisplayName(agentId), text, createdAt })
|
|
492
|
+
}),
|
|
493
|
+
),
|
|
494
|
+
toModelOutput: ({ output }) => {
|
|
495
|
+
const message = output
|
|
496
|
+
const agentName =
|
|
497
|
+
typeof message.metadata?.agentName === 'string' && message.metadata.agentName.trim().length > 0
|
|
498
|
+
? message.metadata.agentName.trim()
|
|
499
|
+
: 'Specialist'
|
|
500
|
+
const summary = extractMessageText(message).trim()
|
|
501
|
+
return {
|
|
502
|
+
type: 'text',
|
|
503
|
+
value: summary ? `${agentName}: ${summary}` : `${agentName} completed the requested task.`,
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
yield* effectTryPromise(() => thread.startTyping('Thinking...')).pipe(Effect.orElseSucceed(() => undefined))
|
|
509
|
+
aiLogger.debug`Slack social-chat generating reply: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}`
|
|
510
|
+
const leadRun = yield* effectTryPromise(() =>
|
|
511
|
+
runSocialAgentTurn({
|
|
512
|
+
agentId: socialAgentId,
|
|
513
|
+
mode: 'threadMode',
|
|
514
|
+
threadType: 'group',
|
|
515
|
+
onboardingActive: lifecycleState?.bootstrapActive ?? false,
|
|
516
|
+
linearInstalled: false,
|
|
517
|
+
systemWorkspaceDetails: promptContext.systemWorkspaceDetails,
|
|
518
|
+
preSeededMemoriesSection,
|
|
519
|
+
retrievedKnowledgeSection,
|
|
520
|
+
learnedSkillsSection,
|
|
521
|
+
userMessageText: messageContext.text,
|
|
522
|
+
additionalInstructionSections: [buildSocialChatIdentitySection(socialAgentDisplayName)],
|
|
523
|
+
tools: { ...baseTools, [CONSULT_SPECIALIST_TOOL_NAME]: consultSpecialistTool },
|
|
524
|
+
prompt: buildLeadSocialChatPrompt({
|
|
525
|
+
agentDisplayName: socialAgentDisplayName,
|
|
526
|
+
channelId: messageContext.channelId,
|
|
527
|
+
threadId: messageContext.threadId,
|
|
528
|
+
transcript,
|
|
529
|
+
latestUserMessage: messageContext.text,
|
|
530
|
+
latestAuthorName: messageContext.authorName,
|
|
457
531
|
}),
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
},
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
yield* effectTryPromise(() => thread.startTyping('Thinking...')).pipe(Effect.orElseSucceed(() => undefined))
|
|
474
|
-
aiLogger.info`Slack social-chat generating reply: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}`
|
|
475
|
-
const leadRun = yield* effectTryPromise(() =>
|
|
476
|
-
runSocialAgentTurn({
|
|
532
|
+
abortSignal: runAbort.signal,
|
|
533
|
+
}),
|
|
534
|
+
)
|
|
535
|
+
const responseText = leadRun.text
|
|
536
|
+
|
|
537
|
+
const replyMarkdown = buildSlackSocialReplyMarkdown({ replyMarkdown: responseText, executedToolNames })
|
|
538
|
+
const sentMessage = yield* effectTryPromise(() => thread.post({ markdown: replyMarkdown }))
|
|
539
|
+
aiLogger.debug`Slack social-chat reply posted: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}, replyMessageId=${sentMessage.id}`
|
|
540
|
+
const normalizedResponse = normalizeSocialHistoryMessage({
|
|
541
|
+
workspaceId: workspaceIdString,
|
|
542
|
+
channelId: messageContext.channelId,
|
|
477
543
|
agentId: socialAgentId,
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
544
|
+
agentDisplayName: socialAgentDisplayName,
|
|
545
|
+
message: sentMessage,
|
|
546
|
+
textOverride: responseText,
|
|
547
|
+
})
|
|
548
|
+
if (normalizedResponse) {
|
|
549
|
+
yield* socialChatHistoryService.upsertMessages([normalizedResponse])
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
const priorHistoryMessages = toHistoryMessages(priorHistory)
|
|
553
|
+
const agentMessages = normalizedResponse ? buildAgentHistoryMessages([normalizedResponse]) : []
|
|
554
|
+
if (messageContext.text && agentMessages.length > 0) {
|
|
555
|
+
yield* effectTryPromise(() =>
|
|
556
|
+
safeEnqueue(
|
|
557
|
+
() =>
|
|
558
|
+
enqueuePostChatMemory(
|
|
559
|
+
{
|
|
560
|
+
orgId: workspaceIdString,
|
|
561
|
+
threadId: `social:slack:${messageContext.threadId}`,
|
|
562
|
+
sourceId: createSocialChatCursorId({
|
|
563
|
+
workspaceId: workspaceIdString,
|
|
564
|
+
threadId: messageContext.threadId,
|
|
565
|
+
messageId: messageContext.messageId,
|
|
566
|
+
}),
|
|
567
|
+
userMessage: messageContext.text,
|
|
568
|
+
historyMessages: priorHistoryMessages,
|
|
569
|
+
agentMessages,
|
|
570
|
+
memoryBlock: memoryBlock.trim() ? memoryBlock : undefined,
|
|
571
|
+
source: 'social_chat',
|
|
572
|
+
sourceMetadata: {
|
|
573
|
+
platform: 'slack',
|
|
574
|
+
channelId: messageContext.channelId,
|
|
575
|
+
threadId: messageContext.threadId,
|
|
576
|
+
messageId: messageContext.messageId,
|
|
577
|
+
authorId: messageContext.authorId,
|
|
578
|
+
authorName: messageContext.authorName,
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
dedupeKey: createSocialMemoryDedupeKey({
|
|
583
|
+
workspaceId: workspaceIdString,
|
|
584
|
+
threadId: messageContext.threadId,
|
|
585
|
+
messageId: messageContext.messageId,
|
|
586
|
+
}),
|
|
587
|
+
},
|
|
588
|
+
),
|
|
589
|
+
{ operationName: 'social post-chat memory extraction enqueue' },
|
|
590
|
+
),
|
|
591
|
+
)
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
yield* effectTryPromise(() =>
|
|
595
|
+
safeEnqueue(() => enqueueRegularChatMemoryDigest({ orgId: workspaceIdString }), {
|
|
596
|
+
operationName: 'social regular chat memory digest enqueue',
|
|
496
597
|
}),
|
|
497
|
-
|
|
498
|
-
}),
|
|
499
|
-
)
|
|
500
|
-
const responseText = leadRun.text
|
|
501
|
-
|
|
502
|
-
const replyMarkdown = buildSlackSocialReplyMarkdown({ replyMarkdown: responseText, executedToolNames })
|
|
503
|
-
const sentMessage = yield* effectTryPromise(() => thread.post({ markdown: replyMarkdown }))
|
|
504
|
-
aiLogger.info`Slack social-chat reply posted: channelId=${messageContext.channelId}, threadId=${messageContext.threadId}, replyMessageId=${sentMessage.id}`
|
|
505
|
-
const normalizedResponse = normalizeSocialHistoryMessage({
|
|
506
|
-
workspaceId: workspaceIdString,
|
|
507
|
-
channelId: messageContext.channelId,
|
|
508
|
-
agentId: socialAgentId,
|
|
509
|
-
agentDisplayName: socialAgentDisplayName,
|
|
510
|
-
message: sentMessage,
|
|
511
|
-
textOverride: responseText,
|
|
512
|
-
})
|
|
513
|
-
if (normalizedResponse) {
|
|
514
|
-
yield* socialChatHistoryService.upsertMessages([normalizedResponse])
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
const priorHistoryMessages = toHistoryMessages(priorHistory)
|
|
518
|
-
const agentMessages = normalizedResponse ? buildAgentHistoryMessages([normalizedResponse]) : []
|
|
519
|
-
if (messageContext.text && agentMessages.length > 0) {
|
|
598
|
+
)
|
|
520
599
|
yield* effectTryPromise(() =>
|
|
521
|
-
safeEnqueue(
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
{
|
|
525
|
-
orgId: workspaceIdString,
|
|
526
|
-
threadId: `social:slack:${messageContext.threadId}`,
|
|
527
|
-
sourceId: createSocialChatCursorId({
|
|
528
|
-
workspaceId: workspaceIdString,
|
|
529
|
-
threadId: messageContext.threadId,
|
|
530
|
-
messageId: messageContext.messageId,
|
|
531
|
-
}),
|
|
532
|
-
userMessage: messageContext.text,
|
|
533
|
-
historyMessages: priorHistoryMessages,
|
|
534
|
-
agentMessages,
|
|
535
|
-
memoryBlock: memoryBlock.trim() ? memoryBlock : undefined,
|
|
536
|
-
source: 'social_chat',
|
|
537
|
-
sourceMetadata: {
|
|
538
|
-
platform: 'slack',
|
|
539
|
-
channelId: messageContext.channelId,
|
|
540
|
-
threadId: messageContext.threadId,
|
|
541
|
-
messageId: messageContext.messageId,
|
|
542
|
-
authorId: messageContext.authorId,
|
|
543
|
-
authorName: messageContext.authorName,
|
|
544
|
-
},
|
|
545
|
-
},
|
|
546
|
-
{
|
|
547
|
-
dedupeKey: createSocialMemoryDedupeKey({
|
|
548
|
-
workspaceId: workspaceIdString,
|
|
549
|
-
threadId: messageContext.threadId,
|
|
550
|
-
messageId: messageContext.messageId,
|
|
551
|
-
}),
|
|
552
|
-
},
|
|
553
|
-
),
|
|
554
|
-
{ operationName: 'social post-chat memory extraction enqueue' },
|
|
555
|
-
),
|
|
600
|
+
safeEnqueue(() => enqueueSkillExtraction({ orgId: workspaceIdString }), {
|
|
601
|
+
operationName: 'social skill extraction enqueue',
|
|
602
|
+
}),
|
|
556
603
|
)
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
yield* effectTryPromise(() =>
|
|
560
|
-
safeEnqueue(() => enqueueRegularChatMemoryDigest({ orgId: workspaceIdString }), {
|
|
561
|
-
operationName: 'social regular chat memory digest enqueue',
|
|
562
|
-
}),
|
|
563
|
-
)
|
|
564
|
-
yield* effectTryPromise(() =>
|
|
565
|
-
safeEnqueue(() => enqueueSkillExtraction({ orgId: workspaceIdString }), {
|
|
566
|
-
operationName: 'social skill extraction enqueue',
|
|
567
|
-
}),
|
|
568
|
-
)
|
|
569
|
-
})
|
|
604
|
+
}),
|
|
605
|
+
)
|
|
570
606
|
|
|
571
607
|
chat.onNewMention((thread, message) => {
|
|
572
|
-
aiLogger.
|
|
608
|
+
aiLogger.debug`Slack social-chat new mention received: threadId=${thread.id}, messageId=${message.id}`
|
|
573
609
|
return Effect.runPromise(
|
|
574
610
|
Effect.gen(function* () {
|
|
575
611
|
yield* effectTryPromise(() => thread.subscribe())
|
|
@@ -578,7 +614,7 @@ export function createSocialChatRuntime(params: {
|
|
|
578
614
|
)
|
|
579
615
|
})
|
|
580
616
|
chat.onSubscribedMessage((thread, message) => {
|
|
581
|
-
aiLogger.
|
|
617
|
+
aiLogger.debug`Slack social-chat subscribed thread message received: threadId=${thread.id}, messageId=${message.id}`
|
|
582
618
|
return Effect.runPromise(handleMessage(thread, message))
|
|
583
619
|
})
|
|
584
620
|
|