@lota-sdk/core 0.4.8 → 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 +11 -12
- package/src/ai/embedding-cache.ts +96 -22
- package/src/ai-gateway/ai-gateway.ts +766 -223
- package/src/config/agent-defaults.ts +189 -75
- package/src/config/agent-types.ts +54 -4
- package/src/config/background-processing.ts +1 -1
- package/src/config/constants.ts +8 -2
- package/src/config/index.ts +0 -1
- package/src/config/logger.ts +299 -19
- package/src/config/thread-defaults.ts +40 -20
- package/src/create-runtime.ts +200 -449
- package/src/db/base.service.ts +52 -28
- package/src/db/cursor-pagination.ts +71 -30
- package/src/db/memory-query-builder.ts +2 -1
- package/src/db/memory-store.helpers.ts +4 -7
- package/src/db/memory-store.ts +868 -601
- package/src/db/memory.ts +396 -280
- package/src/db/record-id.ts +32 -10
- package/src/db/schema-fingerprint.ts +30 -12
- package/src/db/service-normalization.ts +288 -0
- package/src/db/service.ts +912 -779
- package/src/db/startup.ts +153 -68
- package/src/db/transaction-conflict.ts +15 -0
- package/src/effect/awaitable-effect.ts +96 -0
- package/src/effect/errors.ts +121 -0
- package/src/effect/helpers.ts +123 -0
- package/src/effect/index.ts +24 -0
- package/src/effect/layers.ts +238 -0
- package/src/effect/runtime-ref.ts +25 -0
- package/src/effect/runtime.ts +46 -0
- package/src/effect/services.ts +61 -0
- package/src/effect/zod.ts +43 -0
- package/src/embeddings/provider.ts +128 -83
- package/src/index.ts +48 -1
- package/src/openrouter/direct-provider.ts +11 -35
- package/src/queues/autonomous-job.queue.ts +117 -73
- package/src/queues/context-compaction.queue.ts +50 -17
- package/src/queues/delayed-node-promotion.queue.ts +46 -17
- 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 +26 -4
- package/src/queues/plan-agent-heartbeat.queue.ts +71 -24
- package/src/queues/plan-scheduler.queue.ts +97 -33
- package/src/queues/post-chat-memory.queue.ts +56 -26
- package/src/queues/queue-factory.ts +227 -59
- package/src/queues/standalone-worker.ts +39 -0
- package/src/queues/title-generation.queue.ts +45 -11
- package/src/redis/connection.ts +182 -113
- 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 +20 -0
- package/src/redis/stream-context.ts +92 -46
- package/src/runtime/agent-identity-overrides.ts +2 -2
- package/src/runtime/agent-runtime-policy.ts +5 -2
- package/src/runtime/agent-stream-helpers.ts +24 -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} +161 -94
- package/src/runtime/domain-layer.ts +192 -0
- package/src/runtime/execution-plan-visibility.ts +2 -2
- package/src/runtime/execution-plan.ts +42 -15
- package/src/runtime/graph-designer.ts +16 -4
- package/src/runtime/helper-model.ts +139 -48
- package/src/runtime/index.ts +7 -8
- package/src/runtime/indexed-repositories-policy.ts +3 -3
- package/src/runtime/{memory-block.ts → memory/memory-block.ts} +50 -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} +54 -67
- package/src/runtime/{memory-prompts-fact.ts → memory/memory-prompts-fact.ts} +2 -2
- package/src/runtime/memory/memory-scope.ts +53 -0
- package/src/runtime/plugin-resolution.ts +124 -25
- package/src/runtime/plugin-types.ts +9 -1
- package/src/runtime/post-turn-side-effects.ts +177 -130
- package/src/runtime/retrieval-adapters.ts +40 -6
- package/src/runtime/runtime-accessors.ts +92 -0
- package/src/runtime/runtime-config.ts +150 -61
- package/src/runtime/runtime-extensions.ts +23 -25
- 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 +159 -0
- package/src/runtime/{social-chat-history.ts → social-chat/social-chat-history.ts} +51 -20
- package/src/runtime/social-chat/social-chat.ts +630 -0
- package/src/runtime/specialist-runner.ts +36 -10
- package/src/runtime/team-consultation/team-consultation-orchestrator.ts +433 -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 +183 -111
- package/src/runtime/turn-lifecycle.ts +93 -27
- package/src/services/agent-activity.service.ts +287 -203
- package/src/services/agent-executor.service.ts +253 -149
- package/src/services/artifact.service.ts +231 -149
- package/src/services/attachment.service.ts +171 -115
- package/src/services/autonomous-job.service.ts +890 -491
- package/src/services/background-work.service.ts +54 -0
- package/src/services/chat-run-registry.service.ts +13 -1
- package/src/services/context-compaction.service.ts +136 -86
- package/src/services/document-chunk.service.ts +151 -88
- 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 +278 -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 +101 -168
- package/src/services/graph-full-routing.ts +193 -0
- package/src/services/index.ts +19 -21
- package/src/services/institutional-memory.service.ts +213 -125
- package/src/services/learned-skill.service.ts +368 -260
- package/src/services/memory/memory-conversation.ts +95 -0
- package/src/services/memory/memory-errors.ts +27 -0
- package/src/services/memory/memory-org-memory.ts +50 -0
- package/src/services/memory/memory-preseeded.ts +86 -0
- package/src/services/memory/memory-rerank.ts +297 -0
- package/src/services/{memory-utils.ts → memory/memory-utils.ts} +6 -5
- package/src/services/memory/memory.service.ts +674 -0
- package/src/services/memory/rerank.service.ts +201 -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 +29 -16
- package/src/services/organization-member.service.ts +120 -66
- package/src/services/organization.service.ts +153 -77
- package/src/services/ownership-dispatcher.service.ts +456 -263
- 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-approval.service.ts → plan/plan-approval.service.ts} +45 -22
- 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 +169 -0
- package/src/services/plan/plan-coordination.service.ts +181 -0
- package/src/services/plan/plan-cycle.service.ts +405 -0
- package/src/services/plan/plan-deadline.service.ts +533 -0
- package/src/services/plan/plan-event-delivery.service.ts +266 -0
- package/src/services/plan/plan-executor-context.ts +35 -0
- package/src/services/plan/plan-executor-graph.ts +522 -0
- package/src/services/plan/plan-executor-helpers.ts +307 -0
- package/src/services/plan/plan-executor-persistence.ts +209 -0
- package/src/services/plan/plan-executor.service.ts +1737 -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 +637 -0
- package/src/services/plan/plan-scheduler.service.ts +379 -0
- package/src/services/plan/plan-template.service.ts +224 -0
- package/src/services/plan/plan-transaction-events.ts +36 -0
- package/src/services/plan/plan-validator.service.ts +907 -0
- package/src/services/plan/plan-workspace.service.ts +131 -0
- package/src/services/plugin-executor.service.ts +102 -68
- package/src/services/quality-metrics.service.ts +112 -94
- package/src/services/queue-job.service.ts +288 -231
- package/src/services/recent-activity-title.service.ts +73 -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 +190 -122
- package/src/services/system-executor.service.ts +96 -61
- package/src/services/thread/thread-active-run.ts +203 -0
- package/src/services/thread/thread-bootstrap.ts +385 -0
- package/src/services/thread/thread-listing.ts +199 -0
- package/src/services/thread/thread-memory-block.ts +130 -0
- package/src/services/thread/thread-message.service.ts +379 -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 +1148 -0
- package/src/services/thread/thread-turn-streaming.ts +403 -0
- package/src/services/thread/thread-turn-tracing.ts +35 -0
- package/src/services/thread/thread-turn.ts +376 -0
- package/src/services/thread/thread.service.ts +344 -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 +334 -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 +3 -3
- package/src/system-agents/delegated-agent-factory.ts +159 -90
- package/src/system-agents/helper-agent-options.ts +1 -1
- package/src/system-agents/memory-reranker.agent.ts +3 -3
- package/src/system-agents/memory.agent.ts +3 -3
- package/src/system-agents/recent-activity-title-refiner.agent.ts +3 -3
- package/src/system-agents/regular-chat-memory-digest.agent.ts +3 -3
- package/src/system-agents/skill-extractor.agent.ts +3 -3
- package/src/system-agents/skill-manager.agent.ts +3 -3
- package/src/system-agents/thread-router.agent.ts +157 -113
- package/src/system-agents/title-generator.agent.ts +3 -3
- package/src/tools/execution-plan.tool.ts +241 -171
- package/src/tools/fetch-webpage.tool.ts +29 -18
- package/src/tools/firecrawl-client.ts +26 -6
- package/src/tools/index.ts +1 -0
- package/src/tools/memory-block.tool.ts +14 -6
- package/src/tools/plan-approval.tool.ts +57 -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 +33 -22
- package/src/tools/search.tool.ts +41 -29
- package/src/tools/team-think.tool.ts +125 -84
- package/src/tools/user-questions.tool.ts +4 -3
- package/src/tools/web-tool-shared.ts +6 -0
- package/src/utils/async.ts +25 -22
- package/src/utils/crypto.ts +21 -0
- package/src/utils/date-time.ts +40 -1
- package/src/utils/errors.ts +111 -20
- 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 +164 -52
- 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 +185 -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 +74 -31
- package/src/config/debug-logger.ts +0 -47
- package/src/config/search.ts +0 -3
- package/src/redis/connection-accessor.ts +0 -26
- package/src/runtime/agent-types.ts +0 -1
- package/src/runtime/context-compaction-runtime.ts +0 -87
- package/src/runtime/memory-scope.ts +0 -43
- 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 -914
- package/src/services/plan-agent-heartbeat.service.ts +0 -136
- package/src/services/plan-agent-query.service.ts +0 -267
- 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/rerank.service.ts +0 -156
- 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,31 +1,65 @@
|
|
|
1
1
|
import type { SandboxedJob } from 'bullmq'
|
|
2
|
+
import { Effect } from 'effect'
|
|
3
|
+
import type { Context } from 'effect'
|
|
2
4
|
|
|
3
5
|
import { serverLogger } from '../config/logger'
|
|
6
|
+
import { effectTryPromise } from '../effect/helpers'
|
|
7
|
+
import { DatabaseServiceTag, RuntimeAdaptersServiceTag, RuntimeConfigServiceTag } from '../effect/services'
|
|
4
8
|
import type { OrganizationLearningJob } from '../queues/organization-learning.queue'
|
|
9
|
+
import { LearnedSkillServiceTag } from '../services/learned-skill.service'
|
|
10
|
+
import { MemoryServiceTag } from '../services/memory/memory.service'
|
|
11
|
+
import { SocialChatHistoryServiceTag } from '../services/social-chat-history.service'
|
|
5
12
|
import { initializeSandboxedWorkerRuntime } from './bootstrap'
|
|
6
13
|
import { runRegularChatMemoryDigest } from './regular-chat-memory-digest.runner'
|
|
14
|
+
import type { RegularChatDigestServices } from './regular-chat-memory-digest.runner'
|
|
7
15
|
import { runSkillExtraction } from './skill-extraction.runner'
|
|
16
|
+
import type { SkillExtractionServices } from './skill-extraction.runner'
|
|
8
17
|
import { toSandboxedWorkerError } from './utils/sandbox-error'
|
|
9
18
|
import { createTracedWorkerProcessor } from './worker-utils'
|
|
10
19
|
|
|
11
|
-
await initializeSandboxedWorkerRuntime()
|
|
20
|
+
const runtime = await initializeSandboxedWorkerRuntime()
|
|
21
|
+
const resolve = <I, T>(tag: Context.Key<I, T>): Promise<T> => runtime.runPromise(Effect.service(tag))
|
|
22
|
+
const regularChatDigestServices: RegularChatDigestServices = {
|
|
23
|
+
databaseService: await resolve(DatabaseServiceTag),
|
|
24
|
+
memoryService: await resolve(MemoryServiceTag),
|
|
25
|
+
socialChatHistoryService: await resolve(SocialChatHistoryServiceTag),
|
|
26
|
+
runtimeAdapters: await resolve(RuntimeAdaptersServiceTag),
|
|
27
|
+
}
|
|
28
|
+
const workerRuntimeConfig = await resolve(RuntimeConfigServiceTag)
|
|
29
|
+
const skillExtractionServices: SkillExtractionServices = {
|
|
30
|
+
databaseService: await resolve(DatabaseServiceTag),
|
|
31
|
+
learnedSkillService: await resolve(LearnedSkillServiceTag),
|
|
32
|
+
socialChatHistoryService: await resolve(SocialChatHistoryServiceTag),
|
|
33
|
+
runtimeAdapters: await resolve(RuntimeAdaptersServiceTag),
|
|
34
|
+
embeddingModel: workerRuntimeConfig.aiGateway.embeddingModel,
|
|
35
|
+
openRouterApiKey: workerRuntimeConfig.aiGateway.openRouterApiKey,
|
|
36
|
+
}
|
|
12
37
|
|
|
13
38
|
// One sandboxed worker handles both organization-learning branches so the
|
|
14
39
|
// queue can dispatch digest and skill jobs without separate worker images.
|
|
15
|
-
const handler =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
40
|
+
const handler = (job: SandboxedJob<OrganizationLearningJob>) =>
|
|
41
|
+
Effect.runPromise(
|
|
42
|
+
Effect.gen(function* () {
|
|
43
|
+
if (job.data.kind === 'regular-chat-memory-digest') {
|
|
44
|
+
const digestJob = job.data
|
|
45
|
+
return yield* effectTryPromise(() => runRegularChatMemoryDigest(digestJob, regularChatDigestServices))
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const skillJob = job.data
|
|
49
|
+
return yield* effectTryPromise(() => runSkillExtraction(skillJob, skillExtractionServices))
|
|
50
|
+
}).pipe(
|
|
51
|
+
Effect.catch((error) =>
|
|
52
|
+
Effect.gen(function* () {
|
|
53
|
+
const message =
|
|
54
|
+
job.data.kind === 'regular-chat-memory-digest'
|
|
55
|
+
? 'Regular chat memory digest failed'
|
|
56
|
+
: 'Skill extraction failed'
|
|
57
|
+
const serialized = toSandboxedWorkerError(error, message)
|
|
58
|
+
serverLogger.error`${serialized.message}`
|
|
59
|
+
return yield* Effect.fail(serialized)
|
|
60
|
+
}),
|
|
61
|
+
),
|
|
62
|
+
),
|
|
63
|
+
)
|
|
30
64
|
|
|
31
65
|
export default createTracedWorkerProcessor('organization-learning', handler)
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
import { isAgentName } from '../config/agent-defaults'
|
|
2
|
-
import { compactWhitespace } from '../utils/string'
|
|
2
|
+
import { compactWhitespace, readRecord, readString } from '../utils/string'
|
|
3
|
+
import type { DigestMessage } from './utils/thread-message-query'
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
sourceId: string
|
|
7
|
-
role: 'system' | 'user' | 'assistant'
|
|
8
|
-
parts: Array<Record<string, unknown>>
|
|
9
|
-
metadata?: Record<string, unknown>
|
|
10
|
-
}
|
|
5
|
+
type DigestMessageForTranscript = Pick<DigestMessage, 'source' | 'sourceId' | 'role' | 'parts' | 'metadata'>
|
|
6
|
+
type DigestMessagePart = DigestMessageForTranscript['parts'][number]
|
|
11
7
|
|
|
12
|
-
function normalizeFilePartMetadata(part:
|
|
8
|
+
function normalizeFilePartMetadata(part: DigestMessagePart): string | null {
|
|
13
9
|
if (part.type !== 'file') return null
|
|
10
|
+
const partRecord = readRecord(part)
|
|
11
|
+
if (!partRecord) return null
|
|
14
12
|
|
|
15
|
-
const filename =
|
|
16
|
-
const mediaType =
|
|
17
|
-
const
|
|
13
|
+
const filename = readString(partRecord.filename) ?? 'attachment'
|
|
14
|
+
const mediaType = readString(partRecord.mediaType) ?? 'unknown'
|
|
15
|
+
const providerMetadata = readRecord(partRecord.providerMetadata)
|
|
16
|
+
const lotaMetadata = readRecord(providerMetadata?.lota)
|
|
17
|
+
const storageKey = readString(partRecord.storageKey) ?? readString(lotaMetadata?.attachmentStorageKey) ?? 'unknown'
|
|
18
18
|
const sizeBytes =
|
|
19
|
-
typeof
|
|
20
|
-
? Math.trunc(
|
|
19
|
+
typeof partRecord.sizeBytes === 'number' && Number.isFinite(partRecord.sizeBytes) && partRecord.sizeBytes >= 0
|
|
20
|
+
? Math.trunc(partRecord.sizeBytes)
|
|
21
21
|
: null
|
|
22
22
|
|
|
23
23
|
const sizeSegment = sizeBytes === null ? '' : `, sizeBytes=${sizeBytes}`
|
|
24
24
|
return `${filename} (${mediaType}${sizeSegment}, storageKey=${storageKey})`
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
function extractAssistantLabel(
|
|
27
|
+
function extractAssistantLabel(
|
|
28
|
+
message: DigestMessageForTranscript,
|
|
29
|
+
isKnownAgentName: (value: string) => boolean = isAgentName,
|
|
30
|
+
): string {
|
|
28
31
|
const metadataAgentId =
|
|
29
|
-
message.metadata
|
|
30
|
-
|
|
31
|
-
: ''
|
|
32
|
-
if (metadataAgentId && isAgentName(metadataAgentId)) {
|
|
32
|
+
typeof message.metadata?.agentId === 'string' ? message.metadata.agentId.trim().toLowerCase() : ''
|
|
33
|
+
if (metadataAgentId && isKnownAgentName(metadataAgentId)) {
|
|
33
34
|
return metadataAgentId
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
const metadataAgentName =
|
|
37
|
-
message.metadata && typeof message.metadata.agentName === 'string' ? message.metadata.agentName.trim() : ''
|
|
37
|
+
const metadataAgentName = typeof message.metadata?.agentName === 'string' ? message.metadata.agentName.trim() : ''
|
|
38
38
|
if (metadataAgentName) {
|
|
39
39
|
return metadataAgentName
|
|
40
40
|
}
|
|
@@ -42,12 +42,13 @@ function extractAssistantLabel(message: DigestMessageForTranscript): string {
|
|
|
42
42
|
return 'assistant'
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
export function buildDigestTranscript(params: {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
} {
|
|
45
|
+
export function buildDigestTranscript(params: {
|
|
46
|
+
messages: DigestMessageForTranscript[]
|
|
47
|
+
isKnownAgentName?: (value: string) => boolean
|
|
48
|
+
}): { transcript: string; involvedAgentNames: string[] } {
|
|
49
49
|
const lines: string[] = []
|
|
50
50
|
const involvedAgentNames = new Set<string>()
|
|
51
|
+
const isKnownAgentName = params.isKnownAgentName ?? isAgentName
|
|
51
52
|
|
|
52
53
|
for (const message of params.messages) {
|
|
53
54
|
if (message.role !== 'user' && message.role !== 'assistant') continue
|
|
@@ -70,8 +71,8 @@ export function buildDigestTranscript(params: { messages: DigestMessageForTransc
|
|
|
70
71
|
continue
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
const assistantLabel = extractAssistantLabel(message)
|
|
74
|
-
if (
|
|
74
|
+
const assistantLabel = extractAssistantLabel(message, isKnownAgentName)
|
|
75
|
+
if (isKnownAgentName(assistantLabel)) {
|
|
75
76
|
involvedAgentNames.add(assistantLabel)
|
|
76
77
|
}
|
|
77
78
|
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect'
|
|
2
|
+
import type { Context } from 'effect'
|
|
1
3
|
import { BoundQuery } from 'surrealdb'
|
|
2
4
|
import { z } from 'zod'
|
|
3
5
|
|
|
4
6
|
import { serverLogger } from '../config/logger'
|
|
5
7
|
import { ensureRecordId, recordIdToString } from '../db/record-id'
|
|
6
8
|
import type { RecordIdRef } from '../db/record-id'
|
|
7
|
-
import {
|
|
9
|
+
import type { SurrealDBService } from '../db/service'
|
|
8
10
|
import { TABLES } from '../db/tables'
|
|
11
|
+
import { effectTryPromise } from '../effect/helpers'
|
|
9
12
|
import {
|
|
10
13
|
clearRegularChatMemoryDigestDeduplicationKey,
|
|
11
14
|
enqueueRegularChatMemoryDigest,
|
|
12
15
|
} from '../queues/organization-learning.queue'
|
|
13
16
|
import type { RegularChatMemoryDigestJob } from '../queues/organization-learning.queue'
|
|
14
17
|
import { createHelperModelRuntime } from '../runtime/helper-model'
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
+
import type { LotaRuntimeAdapters, LotaRuntimeBackgroundCursor } from '../runtime/runtime-extensions'
|
|
19
|
+
import type { MemoryServiceTag } from '../services/memory/memory.service'
|
|
20
|
+
import type { SocialChatHistoryServiceTag } from '../services/social-chat-history.service'
|
|
18
21
|
import { createRegularChatMemoryDigestAgent } from '../system-agents/regular-chat-memory-digest.agent'
|
|
22
|
+
import { nowIsoDateTimeString } from '../utils/date-time'
|
|
19
23
|
import { compactWhitespace } from '../utils/string'
|
|
20
24
|
import { buildDigestTranscript, resolveWorkspaceBootstrapCutoff } from './regular-chat-memory-digest.helpers'
|
|
21
25
|
import {
|
|
@@ -24,15 +28,26 @@ import {
|
|
|
24
28
|
listThreadIdsForOrg,
|
|
25
29
|
normalizeBlock,
|
|
26
30
|
} from './utils/thread-message-query'
|
|
27
|
-
import type {
|
|
31
|
+
import type { DigestMessage } from './utils/thread-message-query'
|
|
28
32
|
|
|
29
33
|
// Onboarding extracts memory immediately inside the turn flow. This delayed
|
|
30
34
|
// runner handles the regular-chat path after onboarding so longer transcripts
|
|
31
35
|
// can be digested into durable memory and profile projections in the background.
|
|
32
36
|
const StructuredProfilePatchSchema = z.record(z.string(), z.unknown()).default({})
|
|
33
37
|
|
|
38
|
+
class MemoryDigestError extends Schema.TaggedErrorClass<MemoryDigestError>()('MemoryDigestError', {
|
|
39
|
+
message: Schema.String,
|
|
40
|
+
cause: Schema.Defect,
|
|
41
|
+
}) {}
|
|
42
|
+
|
|
34
43
|
const REGULAR_CHAT_MEMORY_DIGEST_TIMEOUT_MS = 10 * 60 * 1000
|
|
35
44
|
const WorkspaceMemoryRowSchema = z.object({ content: z.string() })
|
|
45
|
+
export interface RegularChatDigestServices {
|
|
46
|
+
databaseService: SurrealDBService
|
|
47
|
+
memoryService: Context.Service.Shape<typeof MemoryServiceTag>
|
|
48
|
+
socialChatHistoryService: Context.Service.Shape<typeof SocialChatHistoryServiceTag>
|
|
49
|
+
runtimeAdapters: LotaRuntimeAdapters
|
|
50
|
+
}
|
|
36
51
|
|
|
37
52
|
const ExtractedFactSchema = z.object({
|
|
38
53
|
content: z.string().trim().min(1),
|
|
@@ -96,109 +111,124 @@ function buildPrompt(params: {
|
|
|
96
111
|
].join('\n')
|
|
97
112
|
}
|
|
98
113
|
|
|
99
|
-
function getLastCursor(messages: DigestMessage[]):
|
|
114
|
+
function getLastCursor(messages: DigestMessage[]): LotaRuntimeBackgroundCursor | null {
|
|
100
115
|
return messages.length > 0 ? messages[messages.length - 1].cursor : null
|
|
101
116
|
}
|
|
102
117
|
|
|
103
|
-
|
|
118
|
+
function hasNewEligibleThreadMessages(params: {
|
|
119
|
+
db: SurrealDBService
|
|
104
120
|
threadIds: RecordIdRef[]
|
|
105
|
-
cursor:
|
|
121
|
+
cursor: LotaRuntimeBackgroundCursor | null
|
|
106
122
|
onboardingCutoff: Date | null
|
|
107
123
|
}): Promise<boolean> {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
124
|
+
return Effect.runPromise(
|
|
125
|
+
Effect.gen(function* () {
|
|
126
|
+
if (params.threadIds.length === 0) return false
|
|
127
|
+
|
|
128
|
+
const query: BoundQuery | null = params.cursor
|
|
129
|
+
? new BoundQuery(
|
|
130
|
+
`SELECT id, createdAt FROM ${TABLES.THREAD_MESSAGE}
|
|
131
|
+
WHERE threadId IN $threadIds
|
|
132
|
+
AND (
|
|
133
|
+
createdAt > $cursorCreatedAt
|
|
134
|
+
OR (createdAt = $cursorCreatedAt AND id > $cursorRowId)
|
|
135
|
+
)
|
|
136
|
+
ORDER BY createdAt ASC, id ASC
|
|
137
|
+
LIMIT 1`,
|
|
138
|
+
{
|
|
139
|
+
threadIds: params.threadIds,
|
|
140
|
+
cursorCreatedAt: params.cursor.createdAt,
|
|
141
|
+
cursorRowId: ensureRecordId(params.cursor.id, TABLES.THREAD_MESSAGE),
|
|
142
|
+
},
|
|
143
|
+
)
|
|
144
|
+
: params.onboardingCutoff
|
|
145
|
+
? new BoundQuery(
|
|
146
|
+
`SELECT id, createdAt FROM ${TABLES.THREAD_MESSAGE}
|
|
147
|
+
WHERE threadId IN $threadIds
|
|
148
|
+
AND createdAt > $onboardingCutoff
|
|
149
|
+
ORDER BY createdAt ASC, id ASC
|
|
150
|
+
LIMIT 1`,
|
|
151
|
+
{ threadIds: params.threadIds, onboardingCutoff: params.onboardingCutoff },
|
|
152
|
+
)
|
|
153
|
+
: null
|
|
134
154
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
155
|
+
if (!query) return false
|
|
156
|
+
const rows = yield* effectTryPromise(() => params.db.query<unknown>(query))
|
|
157
|
+
return rows.length > 0
|
|
158
|
+
}),
|
|
159
|
+
)
|
|
138
160
|
}
|
|
139
161
|
|
|
140
|
-
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
162
|
+
function loadExistingOrganizationMemories(db: SurrealDBService, orgId: string): Promise<Array<{ content: string }>> {
|
|
163
|
+
return Effect.runPromise(
|
|
164
|
+
effectTryPromise(() =>
|
|
165
|
+
db.queryMany(
|
|
166
|
+
new BoundQuery(
|
|
167
|
+
`SELECT content, createdAt, id FROM ${TABLES.MEMORY}
|
|
168
|
+
WHERE metadata.orgId = $orgId
|
|
169
|
+
AND archivedAt IS NONE
|
|
170
|
+
AND (validUntil IS NONE OR validUntil > time::now())
|
|
171
|
+
ORDER BY createdAt DESC, id DESC
|
|
172
|
+
LIMIT 250`,
|
|
173
|
+
{ orgId },
|
|
174
|
+
),
|
|
175
|
+
WorkspaceMemoryRowSchema,
|
|
176
|
+
),
|
|
150
177
|
),
|
|
151
|
-
WorkspaceMemoryRowSchema,
|
|
152
178
|
)
|
|
153
179
|
}
|
|
154
180
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return withConfiguredWorkspaceMemoryLock(orgId, async () => {
|
|
167
|
-
if (
|
|
168
|
-
!workspaceProvider.getBackgroundCursor ||
|
|
169
|
-
!workspaceProvider.setBackgroundCursor ||
|
|
170
|
-
!workspaceProvider.applyProfileProjection
|
|
171
|
-
) {
|
|
181
|
+
function runRegularChatMemoryDigestEffect(
|
|
182
|
+
services: RegularChatDigestServices,
|
|
183
|
+
orgRef: RecordIdRef,
|
|
184
|
+
orgId: string,
|
|
185
|
+
workspaceProvider: NonNullable<LotaRuntimeAdapters['workspaceProvider']>,
|
|
186
|
+
) {
|
|
187
|
+
return Effect.gen(function* () {
|
|
188
|
+
const getBackgroundCursor = workspaceProvider.getBackgroundCursor?.bind(workspaceProvider)
|
|
189
|
+
const setBackgroundCursor = workspaceProvider.setBackgroundCursor?.bind(workspaceProvider)
|
|
190
|
+
const applyProfileProjection = workspaceProvider.applyProfileProjection?.bind(workspaceProvider)
|
|
191
|
+
if (!getBackgroundCursor || !setBackgroundCursor || !applyProfileProjection) {
|
|
172
192
|
serverLogger.info`Skipping regular chat memory digest for ${orgId}: workspaceProvider background/profile methods are incomplete`
|
|
173
193
|
return { skipped: true, processedThreadMessages: 0, processedSocialMessages: 0, followUpScheduled: false }
|
|
174
194
|
}
|
|
175
195
|
|
|
176
|
-
const workspace =
|
|
177
|
-
const lifecycleState =
|
|
196
|
+
const workspace = yield* effectTryPromise(() => workspaceProvider.getWorkspace(orgRef))
|
|
197
|
+
const lifecycleState = workspaceProvider.getLifecycleState
|
|
198
|
+
? yield* effectTryPromise(() => Promise.resolve(workspaceProvider.getLifecycleState?.(workspace)))
|
|
199
|
+
: undefined
|
|
178
200
|
if (lifecycleState?.bootstrapActive ?? false) {
|
|
179
201
|
serverLogger.info`Skipping regular chat memory digest for ${orgId}: onboarding is not completed`
|
|
180
202
|
return { skipped: true, processedThreadMessages: 0, processedSocialMessages: 0, followUpScheduled: false }
|
|
181
203
|
}
|
|
182
|
-
const projectionState =
|
|
204
|
+
const projectionState = workspaceProvider.readProfileProjectionState
|
|
205
|
+
? yield* effectTryPromise(() => Promise.resolve(workspaceProvider.readProfileProjectionState?.(workspace)))
|
|
206
|
+
: undefined
|
|
183
207
|
|
|
184
|
-
const existingThreadCursor =
|
|
208
|
+
const existingThreadCursor = yield* effectTryPromise(() => getBackgroundCursor('regular-chat-digest', orgRef))
|
|
185
209
|
const threadOnboardingCutoff = resolveWorkspaceBootstrapCutoff({
|
|
186
210
|
hasExistingCursor: existingThreadCursor !== null,
|
|
187
211
|
bootstrapCompletedAt: lifecycleState?.bootstrapCompletedAt,
|
|
188
212
|
})
|
|
189
213
|
|
|
190
|
-
const threadIds =
|
|
191
|
-
const threadMessages =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
214
|
+
const threadIds = yield* effectTryPromise(() => listThreadIdsForOrg(services.databaseService, orgRef))
|
|
215
|
+
const threadMessages = yield* effectTryPromise(() =>
|
|
216
|
+
listEligibleThreadMessages({
|
|
217
|
+
db: services.databaseService,
|
|
218
|
+
threadIds,
|
|
219
|
+
cursor: existingThreadCursor,
|
|
220
|
+
onboardingCutoff: threadOnboardingCutoff,
|
|
221
|
+
}),
|
|
222
|
+
)
|
|
223
|
+
const existingSocialCursor = yield* services.socialChatHistoryService.getBackgroundCursor(
|
|
224
|
+
'regular-chat-digest',
|
|
225
|
+
orgId,
|
|
226
|
+
)
|
|
197
227
|
const socialOnboardingCutoff = resolveWorkspaceBootstrapCutoff({
|
|
198
228
|
hasExistingCursor: existingSocialCursor !== null,
|
|
199
229
|
bootstrapCompletedAt: lifecycleState?.bootstrapCompletedAt,
|
|
200
230
|
})
|
|
201
|
-
const socialMessages =
|
|
231
|
+
const socialMessages = yield* services.socialChatHistoryService.listWorkspaceMessages({
|
|
202
232
|
workspaceId: orgId,
|
|
203
233
|
cursor: existingSocialCursor,
|
|
204
234
|
onboardingCutoff: socialOnboardingCutoff,
|
|
@@ -211,38 +241,45 @@ export async function runRegularChatMemoryDigest(
|
|
|
211
241
|
|
|
212
242
|
const combinedMessages = [...threadMessages, ...socialMessages].sort(compareDigestMessageOrder)
|
|
213
243
|
const { transcript, involvedAgentNames } = buildDigestTranscript({ messages: combinedMessages })
|
|
214
|
-
const existingMemories =
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
244
|
+
const existingMemories = yield* effectTryPromise(() =>
|
|
245
|
+
loadExistingOrganizationMemories(services.databaseService, orgId),
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
const synthesis = yield* effectTryPromise(() =>
|
|
249
|
+
helperModelRuntime.generateHelperStructured({
|
|
250
|
+
tag: 'regular-chat-memory-digest',
|
|
251
|
+
createAgent: createRegularChatMemoryDigestAgent,
|
|
252
|
+
timeoutMs: REGULAR_CHAT_MEMORY_DIGEST_TIMEOUT_MS,
|
|
253
|
+
messages: [
|
|
254
|
+
{
|
|
255
|
+
role: 'user',
|
|
256
|
+
content: buildPrompt({
|
|
257
|
+
workspaceName: projectionState?.workspaceName || 'Workspace',
|
|
258
|
+
currentSummaryBlock: projectionState?.summaryBlock ?? '',
|
|
259
|
+
currentStructuredProfile: JSON.stringify(projectionState?.structuredProfile ?? {}, null, 2),
|
|
260
|
+
existingMemories: buildMemoryContext(existingMemories),
|
|
261
|
+
transcript,
|
|
262
|
+
}),
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
schema: RegularChatMemoryDigestOutputSchema,
|
|
266
|
+
}),
|
|
267
|
+
)
|
|
234
268
|
|
|
235
269
|
const summaryBlock = normalizeBlock(synthesis.summaryBlock)
|
|
236
270
|
if (!summaryBlock) {
|
|
237
|
-
|
|
271
|
+
return yield* new MemoryDigestError({
|
|
272
|
+
message: 'Regular chat memory digest returned an empty summaryBlock',
|
|
273
|
+
cause: new Error('Regular chat memory digest returned an empty summaryBlock'),
|
|
274
|
+
})
|
|
238
275
|
}
|
|
239
276
|
|
|
240
277
|
const processedThreadCursor = getLastCursor(threadMessages)
|
|
241
278
|
const processedSocialCursor = getLastCursor(socialMessages)
|
|
242
|
-
const digestRunAt =
|
|
279
|
+
const digestRunAt = nowIsoDateTimeString()
|
|
243
280
|
|
|
244
281
|
if (synthesis.facts.length > 0) {
|
|
245
|
-
|
|
282
|
+
yield* services.memoryService.addExtractedFactsToScopes({
|
|
246
283
|
orgId,
|
|
247
284
|
facts: synthesis.facts,
|
|
248
285
|
source: 'regular_chat_digest',
|
|
@@ -266,25 +303,27 @@ export async function runRegularChatMemoryDigest(
|
|
|
266
303
|
})
|
|
267
304
|
}
|
|
268
305
|
|
|
269
|
-
|
|
270
|
-
summaryBlock,
|
|
271
|
-
|
|
272
|
-
})
|
|
306
|
+
yield* effectTryPromise(() =>
|
|
307
|
+
applyProfileProjection(orgRef, { summaryBlock, structuredPatch: synthesis.structuredProfilePatch }),
|
|
308
|
+
)
|
|
273
309
|
if (processedThreadCursor) {
|
|
274
|
-
|
|
310
|
+
yield* effectTryPromise(() => setBackgroundCursor('regular-chat-digest', orgRef, processedThreadCursor))
|
|
275
311
|
}
|
|
276
312
|
if (processedSocialCursor) {
|
|
277
|
-
|
|
313
|
+
yield* services.socialChatHistoryService.setBackgroundCursor('regular-chat-digest', orgId, processedSocialCursor)
|
|
278
314
|
}
|
|
279
315
|
|
|
280
316
|
const threadBoundaryCursor = processedThreadCursor ?? existingThreadCursor
|
|
281
|
-
const hasMoreThreadMessages =
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
317
|
+
const hasMoreThreadMessages = yield* effectTryPromise(() =>
|
|
318
|
+
hasNewEligibleThreadMessages({
|
|
319
|
+
db: services.databaseService,
|
|
320
|
+
threadIds,
|
|
321
|
+
cursor: threadBoundaryCursor,
|
|
322
|
+
onboardingCutoff: threadBoundaryCursor ? null : threadOnboardingCutoff,
|
|
323
|
+
}),
|
|
324
|
+
)
|
|
286
325
|
const socialBoundaryCursor = processedSocialCursor ?? existingSocialCursor
|
|
287
|
-
const hasMoreSocialMessages =
|
|
326
|
+
const hasMoreSocialMessages = yield* services.socialChatHistoryService.hasWorkspaceMessages({
|
|
288
327
|
workspaceId: orgId,
|
|
289
328
|
cursor: socialBoundaryCursor,
|
|
290
329
|
onboardingCutoff: socialBoundaryCursor ? null : socialOnboardingCutoff,
|
|
@@ -292,8 +331,8 @@ export async function runRegularChatMemoryDigest(
|
|
|
292
331
|
|
|
293
332
|
const followUpScheduled = hasMoreThreadMessages || hasMoreSocialMessages
|
|
294
333
|
if (followUpScheduled) {
|
|
295
|
-
|
|
296
|
-
|
|
334
|
+
yield* effectTryPromise(() => clearRegularChatMemoryDigestDeduplicationKey(orgId))
|
|
335
|
+
yield* effectTryPromise(() => enqueueRegularChatMemoryDigest({ orgId }))
|
|
297
336
|
}
|
|
298
337
|
|
|
299
338
|
serverLogger.info`Regular chat memory digest completed for ${orgId}: threadMessages=${threadMessages.length}, socialMessages=${socialMessages.length}, facts=${synthesis.facts.length}, followUpScheduled=${followUpScheduled}`
|
|
@@ -306,3 +345,35 @@ export async function runRegularChatMemoryDigest(
|
|
|
306
345
|
}
|
|
307
346
|
})
|
|
308
347
|
}
|
|
348
|
+
|
|
349
|
+
export function runRegularChatMemoryDigest(
|
|
350
|
+
data: RegularChatMemoryDigestJob,
|
|
351
|
+
services: RegularChatDigestServices,
|
|
352
|
+
): Promise<RegularChatDigestRunResult> {
|
|
353
|
+
const { databaseService, memoryService, socialChatHistoryService, runtimeAdapters } = services
|
|
354
|
+
const orgRef = ensureRecordId(data.orgId, TABLES.ORGANIZATION)
|
|
355
|
+
const orgId = recordIdToString(orgRef, TABLES.ORGANIZATION)
|
|
356
|
+
const workspaceProvider = runtimeAdapters.workspaceProvider
|
|
357
|
+
if (!workspaceProvider) {
|
|
358
|
+
serverLogger.info`Skipping regular chat memory digest for ${orgId}: workspaceProvider is not configured`
|
|
359
|
+
return Promise.resolve({
|
|
360
|
+
skipped: true,
|
|
361
|
+
processedThreadMessages: 0,
|
|
362
|
+
processedSocialMessages: 0,
|
|
363
|
+
followUpScheduled: false,
|
|
364
|
+
})
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const withMemoryLock = runtimeAdapters.withWorkspaceMemoryLock
|
|
368
|
+
const runDigest = () =>
|
|
369
|
+
Effect.runPromise(
|
|
370
|
+
runRegularChatMemoryDigestEffect(
|
|
371
|
+
{ databaseService, memoryService, socialChatHistoryService, runtimeAdapters },
|
|
372
|
+
orgRef,
|
|
373
|
+
orgId,
|
|
374
|
+
workspaceProvider,
|
|
375
|
+
),
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
return withMemoryLock ? withMemoryLock(orgId, runDigest) : runDigest()
|
|
379
|
+
}
|