@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,34 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect'
|
|
1
2
|
import { z } from 'zod'
|
|
2
3
|
|
|
3
|
-
import {
|
|
4
|
-
import { compactWhitespace } from '
|
|
4
|
+
import { nowDate } from '../../utils/date-time'
|
|
5
|
+
import { compactWhitespace } from '../../utils/string'
|
|
6
|
+
|
|
7
|
+
export class MemoryBlockCompactError extends Schema.TaggedErrorClass<MemoryBlockCompactError>()(
|
|
8
|
+
'MemoryBlockCompactError',
|
|
9
|
+
{ message: Schema.String, cause: Schema.Defect },
|
|
10
|
+
) {}
|
|
5
11
|
|
|
6
12
|
function escapeRegex(value: string): string {
|
|
7
13
|
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
8
14
|
}
|
|
9
15
|
|
|
10
16
|
function normalizeMemoryBlockRole(role: string): string {
|
|
11
|
-
const canonicalRole = resolveAgentNameAlias(role)
|
|
12
|
-
if (canonicalRole) return canonicalRole
|
|
13
17
|
return role.trim().toLowerCase()
|
|
14
18
|
}
|
|
15
19
|
|
|
20
|
+
function toLabelAlias(role: string): string {
|
|
21
|
+
const trimmed = role.trim()
|
|
22
|
+
if (!trimmed) return ''
|
|
23
|
+
return trimmed.length === 1 ? trimmed.toUpperCase() : `${trimmed[0].toUpperCase()}${trimmed.slice(1).toLowerCase()}`
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
function getMemoryBlockRoleAliases(role: string): string[] {
|
|
17
27
|
const normalizedRole = role.trim()
|
|
18
28
|
if (!normalizedRole) return []
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return [
|
|
24
|
-
normalizedRole,
|
|
25
|
-
canonicalRole,
|
|
26
|
-
agentDisplayNames[canonicalRole],
|
|
27
|
-
agentShortDisplayNames[canonicalRole],
|
|
28
|
-
].filter((value): value is string => typeof value === 'string' && value.trim().length > 0)
|
|
29
|
+
return [normalizedRole, normalizedRole.toLowerCase(), toLabelAlias(normalizedRole)].filter(
|
|
30
|
+
(value): value is string => typeof value === 'string' && value.trim().length > 0,
|
|
31
|
+
)
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
function createLabelPrefixRegex(labelRoles: readonly string[]): RegExp | null {
|
|
@@ -59,7 +62,10 @@ export interface CompactMemoryBlockEntriesParams {
|
|
|
59
62
|
entries: MemoryBlockEntry[]
|
|
60
63
|
triggerEntries: number
|
|
61
64
|
chunkEntries: number
|
|
62
|
-
compact: (params: {
|
|
65
|
+
compact: (params: {
|
|
66
|
+
previousSummary: string
|
|
67
|
+
newEntriesText: string
|
|
68
|
+
}) => PromiseLike<string> | Effect.Effect<string, MemoryBlockCompactError>
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
export interface CompactMemoryBlockEntriesResult {
|
|
@@ -102,29 +108,37 @@ function toMemoryBlockEntriesSource(entries: Array<{ role: string; content: stri
|
|
|
102
108
|
return entries.map((entry) => `${entry.role}: ${entry.content}`).join('\n')
|
|
103
109
|
}
|
|
104
110
|
|
|
105
|
-
export
|
|
111
|
+
export function compactMemoryBlockEntries(
|
|
106
112
|
params: CompactMemoryBlockEntriesParams,
|
|
107
|
-
):
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
): Effect.Effect<CompactMemoryBlockEntriesResult, MemoryBlockCompactError> {
|
|
114
|
+
return Effect.gen(function* () {
|
|
115
|
+
let summary = typeof params.previousSummary === 'string' ? params.previousSummary.trim() : ''
|
|
116
|
+
let entries = [...params.entries]
|
|
117
|
+
let compacted = false
|
|
118
|
+
|
|
119
|
+
while (entries.length >= params.triggerEntries) {
|
|
120
|
+
const chunk = entries.slice(0, params.chunkEntries)
|
|
121
|
+
const compactParams = { previousSummary: summary, newEntriesText: toMemoryBlockEntriesSource(chunk) }
|
|
122
|
+
const value = params.compact(compactParams)
|
|
123
|
+
const raw = yield* Effect.isEffect(value)
|
|
124
|
+
? value
|
|
125
|
+
: Effect.tryPromise({
|
|
126
|
+
try: () => Promise.resolve(value),
|
|
127
|
+
catch: (cause) => new MemoryBlockCompactError({ message: 'compact callback failed', cause }),
|
|
128
|
+
})
|
|
129
|
+
const nextSummary = raw.trim()
|
|
130
|
+
|
|
131
|
+
if (!nextSummary) {
|
|
132
|
+
break
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
summary = nextSummary
|
|
136
|
+
entries = entries.slice(params.chunkEntries)
|
|
137
|
+
compacted = true
|
|
120
138
|
}
|
|
121
139
|
|
|
122
|
-
summary
|
|
123
|
-
|
|
124
|
-
compacted = true
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return { compacted, summary, entries }
|
|
140
|
+
return { compacted, summary, entries }
|
|
141
|
+
})
|
|
128
142
|
}
|
|
129
143
|
|
|
130
144
|
export function prepareMemoryBlockAppend(params: PrepareMemoryBlockAppendParams): PrepareMemoryBlockAppendResult {
|
|
@@ -158,7 +172,7 @@ export interface CreateMemoryBlockRuntimeOptions {
|
|
|
158
172
|
export function createMemoryBlockRuntime(options: CreateMemoryBlockRuntimeOptions = {}): MemoryBlockRuntime {
|
|
159
173
|
const labelPrefixRegex = createLabelPrefixRegex(options.labelRoles ?? [])
|
|
160
174
|
const memoryBlockMaxChars = options.maxChars ?? 400
|
|
161
|
-
const now = options.now ??
|
|
175
|
+
const now = options.now ?? nowDate
|
|
162
176
|
|
|
163
177
|
const normalizeMemoryBlockEntry = (entry: string): string => {
|
|
164
178
|
const normalizedLines = entry
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getBackgroundProcessingConfig, shouldRunAtFrequency } from '
|
|
1
|
+
import { getBackgroundProcessingConfig, shouldRunAtFrequency } from '../../config/background-processing'
|
|
2
2
|
|
|
3
3
|
export function shouldEnqueueOnboardingPostChatMemory(params: {
|
|
4
4
|
onboardingActive: boolean
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Match } from 'effect'
|
|
2
|
+
|
|
3
|
+
import { clampImportance, compactWhitespace } from '../../utils/string'
|
|
2
4
|
|
|
3
5
|
const SCORE_WEIGHTS = {
|
|
4
6
|
durability: { core: 0.35, standard: 0.2, weak: 0.05 },
|
|
@@ -123,20 +125,17 @@ function scoreFact<T extends MemoryFactInput>(fact: T): number {
|
|
|
123
125
|
const durability = fact.durability ?? 'standard'
|
|
124
126
|
const type = fact.type ?? 'fact'
|
|
125
127
|
|
|
126
|
-
const durabilityWeight =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
: type === 'preference'
|
|
138
|
-
? SCORE_WEIGHTS.type.preference
|
|
139
|
-
: SCORE_WEIGHTS.type.default
|
|
128
|
+
const durabilityWeight = Match.value(durability).pipe(
|
|
129
|
+
Match.when('core', () => SCORE_WEIGHTS.durability.core),
|
|
130
|
+
Match.when('standard', () => SCORE_WEIGHTS.durability.standard),
|
|
131
|
+
Match.orElse(() => SCORE_WEIGHTS.durability.weak),
|
|
132
|
+
)
|
|
133
|
+
const typeWeight = Match.value(type).pipe(
|
|
134
|
+
Match.when('decision', () => SCORE_WEIGHTS.type.decision),
|
|
135
|
+
Match.when('fact', () => SCORE_WEIGHTS.type.fact),
|
|
136
|
+
Match.when('preference', () => SCORE_WEIGHTS.type.preference),
|
|
137
|
+
Match.orElse(() => SCORE_WEIGHTS.type.default),
|
|
138
|
+
)
|
|
140
139
|
const lengthWeight =
|
|
141
140
|
Math.min(fact.content.length, SCORE_WEIGHTS.maxContentLength) / SCORE_WEIGHTS.maxContentLength / 10
|
|
142
141
|
|
|
@@ -340,61 +339,49 @@ export function compileMemoryUpdatesFromDelta(params: {
|
|
|
340
339
|
deleteSet.add(invalidateId)
|
|
341
340
|
}
|
|
342
341
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
342
|
+
const nextUpdates = Match.value(item.classification).pipe(
|
|
343
|
+
Match.when('duplicate', (): MemoryUpdateItemLike[] => {
|
|
344
|
+
const targetId = item.targetMemoryIds[0]
|
|
345
|
+
if (targetId) {
|
|
346
|
+
return [{ id: targetId, text: existingById.get(targetId) ?? item.fact, event: 'NONE' }]
|
|
347
|
+
}
|
|
348
|
+
return [{ id: `noop_${item.index}`, text: item.fact, event: 'NONE' }]
|
|
349
|
+
}),
|
|
350
|
+
Match.when('enriches', (): MemoryUpdateItemLike[] => {
|
|
351
|
+
const targetId = item.targetMemoryIds[0]
|
|
352
|
+
if (targetId) {
|
|
353
|
+
const relations = buildRelations(item, 'new').filter((relation) => relation.memoryId !== targetId)
|
|
354
|
+
return [
|
|
355
|
+
{
|
|
356
|
+
id: targetId,
|
|
357
|
+
text: item.fact,
|
|
358
|
+
event: 'UPDATE',
|
|
359
|
+
oldMemory: existingById.get(targetId),
|
|
360
|
+
...(relations.length > 0 ? { relatesTo: relations } : {}),
|
|
361
|
+
},
|
|
362
|
+
]
|
|
363
|
+
}
|
|
366
364
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
365
|
+
const addId = addIdByFactIndex.get(item.index) ?? nextAddId()
|
|
366
|
+
const relations = buildRelations(item, 'new')
|
|
367
|
+
return [{ id: addId, text: item.fact, event: 'ADD', ...(relations.length > 0 ? { relatesTo: relations } : {}) }]
|
|
368
|
+
}),
|
|
369
|
+
Match.whenOr('supersedes', 'contradicts', (classification): MemoryUpdateItemLike[] => {
|
|
370
|
+
const addId = addIdByFactIndex.get(item.index) ?? nextAddId()
|
|
371
|
+
const relations = buildRelations(item, classification)
|
|
372
|
+
return [{ id: addId, text: item.fact, event: 'ADD', ...(relations.length > 0 ? { relatesTo: relations } : {}) }]
|
|
373
|
+
}),
|
|
374
|
+
Match.when('new', (): MemoryUpdateItemLike[] => {
|
|
375
|
+
const addId = addIdByFactIndex.get(item.index) ?? nextAddId()
|
|
376
|
+
const relations = buildRelations(item, 'new')
|
|
377
|
+
return [{ id: addId, text: item.fact, event: 'ADD', ...(relations.length > 0 ? { relatesTo: relations } : {}) }]
|
|
378
|
+
}),
|
|
379
|
+
Match.exhaustive,
|
|
380
|
+
)
|
|
377
381
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
const relations = buildRelations(item, item.classification)
|
|
381
|
-
updates.push({
|
|
382
|
-
id: addId,
|
|
383
|
-
text: item.fact,
|
|
384
|
-
event: 'ADD',
|
|
385
|
-
...(relations.length > 0 ? { relatesTo: relations } : {}),
|
|
386
|
-
})
|
|
387
|
-
continue
|
|
382
|
+
for (const update of nextUpdates) {
|
|
383
|
+
updates.push(update)
|
|
388
384
|
}
|
|
389
|
-
|
|
390
|
-
const addId = addIdByFactIndex.get(item.index) ?? nextAddId()
|
|
391
|
-
const relations = buildRelations(item, 'new')
|
|
392
|
-
updates.push({
|
|
393
|
-
id: addId,
|
|
394
|
-
text: item.fact,
|
|
395
|
-
event: 'ADD',
|
|
396
|
-
...(relations.length > 0 ? { relatesTo: relations } : {}),
|
|
397
|
-
})
|
|
398
385
|
}
|
|
399
386
|
|
|
400
387
|
const preservedRelationTargetIds = new Set<string>()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatUtcPromptDate } from '
|
|
1
|
+
import { formatUtcPromptDate, nowDate } from '../../utils/date-time'
|
|
2
2
|
|
|
3
3
|
export function getFactRetrievalMessages(
|
|
4
4
|
parsedMessages: string,
|
|
@@ -56,7 +56,7 @@ Hard rules:
|
|
|
56
56
|
- Prefer returning fewer items. If uncertain, return an empty list.
|
|
57
57
|
- Max ${maxFacts} facts.
|
|
58
58
|
|
|
59
|
-
Today's date is ${formatUtcPromptDate(
|
|
59
|
+
Today's date is ${formatUtcPromptDate(nowDate())}.
|
|
60
60
|
${baseInstructions}`
|
|
61
61
|
|
|
62
62
|
const userPrompt = `Conversation:\n${parsedMessages}`
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect'
|
|
2
|
+
|
|
3
|
+
export const ORG_SCOPE_PREFIX = 'org'
|
|
4
|
+
|
|
5
|
+
const SCOPE_ID_MAX_LENGTH = 255
|
|
6
|
+
const SCOPE_PREFIX_REGEX = /^[a-z][a-z0-9_]*$/
|
|
7
|
+
|
|
8
|
+
export class MemoryScopeError extends Schema.TaggedErrorClass<MemoryScopeError>()('MemoryScopeError', {
|
|
9
|
+
message: Schema.String,
|
|
10
|
+
}) {}
|
|
11
|
+
|
|
12
|
+
function stripRecordPrefix(id: string): Effect.Effect<string, MemoryScopeError> {
|
|
13
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
14
|
+
return Effect.fail(new MemoryScopeError({ message: 'id must be a non-empty string' }))
|
|
15
|
+
}
|
|
16
|
+
const [, ...rest] = id.split(':')
|
|
17
|
+
return Effect.succeed(rest.length > 0 ? rest.join(':') : id)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function scopeId(prefix: string, id: string): Effect.Effect<string, MemoryScopeError> {
|
|
21
|
+
return Effect.gen(function* () {
|
|
22
|
+
if (typeof prefix !== 'string' || prefix.length === 0) {
|
|
23
|
+
return yield* new MemoryScopeError({ message: 'prefix must be a non-empty string' })
|
|
24
|
+
}
|
|
25
|
+
if (!SCOPE_PREFIX_REGEX.test(prefix)) {
|
|
26
|
+
return yield* new MemoryScopeError({ message: `Invalid scope prefix: ${prefix}` })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const stripped = yield* stripRecordPrefix(id)
|
|
30
|
+
const scoped = `${prefix}:${stripped}`
|
|
31
|
+
if (scoped.length > SCOPE_ID_MAX_LENGTH) {
|
|
32
|
+
return yield* new MemoryScopeError({ message: 'scopeId exceeds maximum length' })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return scoped
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function agentScopeId(orgId: string, agentName: string): Effect.Effect<string, MemoryScopeError> {
|
|
40
|
+
return Effect.gen(function* () {
|
|
41
|
+
if (typeof agentName !== 'string' || agentName.trim().length === 0) {
|
|
42
|
+
return yield* new MemoryScopeError({ message: 'agentName must be a non-empty string' })
|
|
43
|
+
}
|
|
44
|
+
const strippedOrgId = yield* stripRecordPrefix(orgId)
|
|
45
|
+
const scoped = `agent:${strippedOrgId}:${agentName.trim()}`
|
|
46
|
+
|
|
47
|
+
if (scoped.length > SCOPE_ID_MAX_LENGTH) {
|
|
48
|
+
return yield* new MemoryScopeError({ message: 'scopeId exceeds maximum length' })
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return scoped
|
|
52
|
+
})
|
|
53
|
+
}
|
|
@@ -1,36 +1,135 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Schema, Effect } from 'effect'
|
|
2
|
+
|
|
3
|
+
import { getPluginRuntime } from '../config/agent-defaults'
|
|
4
|
+
import type { RecordIdRef } from '../db/record-id'
|
|
2
5
|
import type { LotaRuntimeIndexedRepositoriesContext } from './runtime-extensions'
|
|
3
6
|
import { getRuntimeAdapters } from './runtime-extensions'
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
9
|
+
return typeof value === 'object' && value !== null
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
class PluginResolutionError extends Schema.TaggedErrorClass<PluginResolutionError>()('PluginResolutionError', {
|
|
13
|
+
stage: Schema.Literals([
|
|
14
|
+
'configuration',
|
|
15
|
+
'linear-installation',
|
|
16
|
+
'github-installation',
|
|
17
|
+
'indexed-repositories-context',
|
|
18
|
+
]),
|
|
19
|
+
message: Schema.String,
|
|
20
|
+
cause: Schema.Defect,
|
|
21
|
+
}) {}
|
|
22
|
+
|
|
23
|
+
function toPluginResolutionError(stage: PluginResolutionError['stage'], cause: unknown): PluginResolutionError {
|
|
24
|
+
return new PluginResolutionError({ stage, message: cause instanceof Error ? cause.message : String(cause), cause })
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readFunctionEffect(
|
|
28
|
+
value: unknown,
|
|
29
|
+
errorMessage: string,
|
|
30
|
+
): Effect.Effect<(...args: unknown[]) => PromiseLike<unknown>, PluginResolutionError> {
|
|
31
|
+
if (typeof value !== 'function') {
|
|
32
|
+
return Effect.fail(new PluginResolutionError({ stage: 'configuration', message: errorMessage, cause: undefined }))
|
|
15
33
|
}
|
|
16
34
|
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
35
|
+
return Effect.succeed(value as (...args: unknown[]) => PromiseLike<unknown>)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function configError(message: string): PluginResolutionError {
|
|
39
|
+
return new PluginResolutionError({ stage: 'configuration', message, cause: undefined })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function requireRecord(value: unknown, message: string): Effect.Effect<Record<string, unknown>, PluginResolutionError> {
|
|
43
|
+
return isRecord(value) ? Effect.succeed(value) : Effect.fail(configError(message))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function resolvePluginServiceEffect(
|
|
47
|
+
pluginName: string,
|
|
48
|
+
serviceName: string,
|
|
49
|
+
methodName: string,
|
|
50
|
+
): Effect.Effect<(...args: unknown[]) => PromiseLike<unknown>, PluginResolutionError> {
|
|
51
|
+
return Effect.fromNullishOr(getPluginRuntime()).pipe(
|
|
52
|
+
Effect.mapError(() => configError(`Plugin runtime is not configured. Missing "${pluginName}" integration.`)),
|
|
53
|
+
Effect.flatMap((pluginRuntime) =>
|
|
54
|
+
requireRecord(pluginRuntime[pluginName], `Plugin "${pluginName}" is not configured in the current runtime.`),
|
|
55
|
+
),
|
|
56
|
+
Effect.flatMap((plugin) =>
|
|
57
|
+
requireRecord(plugin.services, `Plugin "${pluginName}" does not expose a services registry.`),
|
|
58
|
+
),
|
|
59
|
+
Effect.flatMap((services) =>
|
|
60
|
+
requireRecord(services[serviceName], `Plugin "${pluginName}" service "${serviceName}" is not configured.`).pipe(
|
|
61
|
+
Effect.flatMap((service) =>
|
|
62
|
+
readFunctionEffect(
|
|
63
|
+
service[methodName],
|
|
64
|
+
`Plugin "${pluginName}" service "${serviceName}" is missing method "${methodName}".`,
|
|
65
|
+
).pipe(
|
|
66
|
+
Effect.map(
|
|
67
|
+
(method) =>
|
|
68
|
+
(...args: unknown[]) =>
|
|
69
|
+
Reflect.apply(method, service, args),
|
|
70
|
+
),
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
),
|
|
74
|
+
),
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function tryResolvePluginServiceEffect(
|
|
79
|
+
pluginName: string,
|
|
80
|
+
serviceName: string,
|
|
81
|
+
methodName: string,
|
|
82
|
+
): Effect.Effect<((...args: unknown[]) => PromiseLike<unknown>) | void, never, never> {
|
|
83
|
+
return Effect.catch(resolvePluginServiceEffect(pluginName, serviceName, methodName), () => Effect.void)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function getLinearInstallationByOrgId(organizationId: RecordIdRef): Promise<unknown> {
|
|
87
|
+
return Effect.runPromise(
|
|
88
|
+
Effect.gen(function* () {
|
|
89
|
+
const fn = yield* tryResolvePluginServiceEffect('linear', 'linearService', 'getInstallationByOrgId')
|
|
90
|
+
if (!fn) return null
|
|
91
|
+
return yield* Effect.tryPromise({
|
|
92
|
+
try: () => fn(organizationId),
|
|
93
|
+
catch: (cause) => toPluginResolutionError('linear-installation', cause),
|
|
94
|
+
})
|
|
95
|
+
}),
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function getGithubInstallationForOrganization(organizationId: string): Promise<unknown> {
|
|
100
|
+
return Effect.runPromise(
|
|
101
|
+
Effect.gen(function* () {
|
|
102
|
+
const fn = yield* tryResolvePluginServiceEffect('github', 'githubService', 'getInstallationForOrganization')
|
|
103
|
+
if (!fn) return null
|
|
104
|
+
return yield* Effect.tryPromise({
|
|
105
|
+
try: () => fn(organizationId),
|
|
106
|
+
catch: (cause) => toPluginResolutionError('github-installation', cause),
|
|
107
|
+
})
|
|
108
|
+
}),
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const EMPTY_INDEXED_REPO_CONTEXT: LotaRuntimeIndexedRepositoriesContext = {
|
|
113
|
+
provideRepoTool: false,
|
|
114
|
+
defaultSectionsByAgent: {},
|
|
115
|
+
context: '',
|
|
20
116
|
}
|
|
21
117
|
|
|
22
|
-
export
|
|
118
|
+
export function buildIndexedRepositoriesContext(
|
|
23
119
|
organizationId: string,
|
|
24
120
|
): Promise<LotaRuntimeIndexedRepositoriesContext> {
|
|
25
121
|
const buildContext = getRuntimeAdapters().buildIndexedRepositoriesContext
|
|
26
|
-
if (!buildContext)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
122
|
+
if (!buildContext) return Promise.resolve(EMPTY_INDEXED_REPO_CONTEXT)
|
|
123
|
+
return Effect.runPromise(
|
|
124
|
+
Effect.tryPromise({
|
|
125
|
+
try: () => buildContext(organizationId),
|
|
126
|
+
catch: (cause) => toPluginResolutionError('indexed-repositories-context', cause),
|
|
127
|
+
}).pipe(
|
|
128
|
+
Effect.map((result) => ({
|
|
129
|
+
provideRepoTool: result.provideRepoTool,
|
|
130
|
+
defaultSectionsByAgent: result.defaultSectionsByAgent,
|
|
131
|
+
context: result.context ?? '',
|
|
132
|
+
})),
|
|
133
|
+
),
|
|
134
|
+
)
|
|
36
135
|
}
|
|
@@ -33,7 +33,15 @@ export interface SystemNodeExecutor {
|
|
|
33
33
|
executeNode(params: PluginNodeExecutionParams): Promise<PlanNodeResult>
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export interface
|
|
36
|
+
export interface PluginLifecycleServices {
|
|
37
|
+
connectDatabase?(): Promise<void>
|
|
38
|
+
disconnectDatabase?(): Promise<void>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface LotaPlugin<
|
|
42
|
+
TServices extends Record<string, unknown> = Record<string, unknown>,
|
|
43
|
+
TTools = Record<string, unknown>,
|
|
44
|
+
> {
|
|
37
45
|
services: TServices
|
|
38
46
|
nodeExecutor?: PluginNodeExecutor
|
|
39
47
|
tools?: TTools
|