@lota-sdk/core 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/infrastructure/schema/00_identity.surql +0 -2
- package/infrastructure/schema/01_memory.surql +1 -1
- package/infrastructure/schema/02_execution_plan.surql +62 -1
- package/infrastructure/schema/03_learned_skill.surql +1 -1
- package/infrastructure/schema/06_playbook.surql +25 -0
- package/infrastructure/schema/07_institutional_memory.surql +13 -0
- package/infrastructure/schema/08_quality_metrics.surql +17 -0
- package/package.json +8 -7
- package/src/ai/definitions.ts +80 -2
- package/src/ai/index.ts +0 -2
- package/src/bifrost/bifrost.ts +2 -7
- package/src/config/agent-defaults.ts +31 -21
- package/src/config/agent-types.ts +11 -0
- package/src/config/constants.ts +2 -14
- package/src/config/debug-logger.ts +5 -1
- package/src/config/index.ts +3 -0
- package/src/config/model-constants.ts +16 -34
- package/src/config/search.ts +1 -15
- package/src/create-runtime.ts +244 -178
- package/src/db/cursor-pagination.ts +3 -6
- package/src/db/index.ts +2 -0
- package/src/db/memory-store.rows.ts +7 -7
- package/src/db/memory-store.ts +14 -18
- package/src/db/memory.ts +13 -13
- package/src/db/service.ts +153 -79
- package/src/db/startup.ts +6 -10
- package/src/db/surreal-mutation.ts +43 -0
- package/src/db/tables.ts +7 -0
- package/src/db/workstream-message-row.ts +15 -0
- package/src/embeddings/provider.ts +1 -1
- package/src/queues/context-compaction.queue.ts +15 -46
- package/src/queues/delayed-node-promotion.queue.ts +41 -0
- package/src/queues/index.ts +3 -0
- package/src/queues/memory-consolidation.queue.ts +16 -51
- package/src/queues/plan-scheduler.queue.ts +97 -0
- package/src/queues/post-chat-memory.queue.ts +15 -56
- package/src/queues/queue-factory.ts +100 -0
- package/src/queues/recent-activity-title-refinement.queue.ts +15 -50
- package/src/queues/regular-chat-memory-digest.queue.ts +16 -52
- package/src/queues/skill-extraction.queue.ts +15 -47
- package/src/queues/workstream-title-generation.queue.ts +15 -47
- package/src/redis/connection.ts +6 -0
- package/src/redis/index.ts +1 -1
- package/src/redis/stream-context.ts +11 -0
- package/src/runtime/agent-runtime-policy.ts +106 -21
- package/src/runtime/approval-continuation.ts +12 -6
- package/src/runtime/context-compaction-runtime.ts +1 -1
- package/src/runtime/context-compaction.ts +22 -60
- package/src/runtime/execution-plan.ts +22 -18
- package/src/runtime/graph-designer.ts +15 -0
- package/src/runtime/helper-model.ts +9 -197
- package/src/runtime/index.ts +2 -0
- package/src/runtime/llm-content.ts +1 -1
- package/src/runtime/memory-block.ts +9 -11
- package/src/runtime/memory-pipeline.ts +6 -9
- package/src/runtime/plugin-resolution.ts +35 -0
- package/src/runtime/plugin-types.ts +72 -0
- package/src/runtime/retrieval-adapters.ts +1 -1
- package/src/runtime/runtime-config.ts +25 -12
- package/src/runtime/runtime-extensions.ts +2 -2
- package/src/runtime/runtime-worker-registry.ts +6 -0
- package/src/runtime/team-consultation-orchestrator.ts +45 -28
- package/src/runtime/team-consultation-prompts.ts +11 -2
- package/src/runtime/title-helpers.ts +2 -4
- package/src/runtime/workstream-chat-helpers.ts +1 -1
- package/src/services/adaptive-playbook.service.ts +152 -0
- package/src/services/agent-executor.service.ts +293 -0
- package/src/services/artifact-provenance.service.ts +172 -0
- package/src/services/attachment.service.ts +6 -11
- package/src/services/context-compaction.service.ts +72 -55
- package/src/services/context-enrichment.service.ts +33 -0
- package/src/services/coordination-registry.service.ts +117 -0
- package/src/services/document-chunk.service.ts +1 -1
- package/src/services/domain-agent-executor.service.ts +71 -0
- package/src/services/execution-plan.service.ts +269 -50
- package/src/services/feedback-loop.service.ts +96 -0
- package/src/services/global-orchestrator.service.ts +148 -0
- package/src/services/index.ts +26 -0
- package/src/services/institutional-memory.service.ts +145 -0
- package/src/services/learned-skill.service.ts +24 -5
- package/src/services/memory-assessment.service.ts +3 -2
- package/src/services/memory-utils.ts +3 -8
- package/src/services/memory.service.ts +42 -59
- package/src/services/monitoring-window.service.ts +86 -0
- package/src/services/mutating-approval.service.ts +1 -1
- package/src/services/node-workspace.service.ts +155 -0
- package/src/services/notification.service.ts +39 -0
- package/src/services/organization-member.service.ts +11 -4
- package/src/services/organization.service.ts +5 -5
- package/src/services/ownership-dispatcher.service.ts +403 -0
- package/src/services/plan-approval.service.ts +1 -1
- package/src/services/plan-builder.service.ts +1 -0
- package/src/services/plan-checkpoint.service.ts +30 -2
- package/src/services/plan-compiler.service.ts +5 -0
- package/src/services/plan-coordination.service.ts +152 -0
- package/src/services/plan-cycle.service.ts +284 -0
- package/src/services/plan-deadline.service.ts +287 -0
- package/src/services/plan-executor.service.ts +384 -40
- package/src/services/plan-run.service.ts +41 -7
- package/src/services/plan-scheduler.service.ts +240 -0
- package/src/services/plan-template.service.ts +117 -0
- package/src/services/plan-validator.service.ts +84 -2
- package/src/services/plan-workspace.service.ts +83 -0
- package/src/services/playbook-registry.service.ts +67 -0
- package/src/services/plugin-executor.service.ts +103 -0
- package/src/services/quality-metrics.service.ts +132 -0
- package/src/services/recent-activity.service.ts +27 -31
- package/src/services/skill-resolver.service.ts +19 -0
- package/src/services/system-executor.service.ts +105 -0
- package/src/services/workstream-message.service.ts +12 -34
- package/src/services/workstream-plan-registry.service.ts +22 -0
- package/src/services/workstream-title.service.ts +3 -1
- package/src/services/workstream-turn-preparation.service.ts +34 -66
- package/src/services/workstream.service.ts +33 -55
- package/src/services/workstream.types.ts +9 -9
- package/src/services/write-intent-validator.service.ts +81 -0
- package/src/storage/attachment-parser.ts +1 -1
- package/src/storage/attachment-utils.ts +1 -1
- package/src/storage/generated-document-storage.service.ts +3 -2
- package/src/system-agents/delegated-agent-factory.ts +2 -0
- package/src/tools/execution-plan.tool.ts +17 -23
- package/src/tools/index.ts +0 -1
- package/src/tools/team-think.tool.ts +6 -4
- package/src/utils/async.ts +2 -1
- package/src/utils/date-time.ts +4 -32
- package/src/utils/env.ts +8 -0
- package/src/utils/errors.ts +42 -10
- package/src/utils/index.ts +9 -0
- package/src/utils/string.ts +114 -1
- package/src/workers/index.ts +1 -0
- package/src/workers/regular-chat-memory-digest.runner.ts +2 -2
- package/src/workers/skill-extraction.runner.ts +1 -1
- package/src/workers/utils/file-section-chunker.ts +2 -1
- package/src/workers/utils/repomix-file-sections.ts +2 -2
- package/src/workers/utils/sandbox-error.ts +11 -2
- package/src/workers/utils/workstream-message-query.ts +11 -20
- package/src/workers/worker-utils.ts +2 -2
- package/src/tools/log-hello-world.tool.ts +0 -17
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ContextEnrichment } from '@lota-sdk/shared'
|
|
2
|
+
|
|
3
|
+
import { serverLogger } from '../config/logger'
|
|
4
|
+
import { getRuntimeConfig } from '../runtime/runtime-config'
|
|
5
|
+
|
|
6
|
+
class ContextEnrichmentService {
|
|
7
|
+
async enrichForPlanCreation(params: { objective: string; organizationId: string }): Promise<ContextEnrichment[]> {
|
|
8
|
+
const pluginRuntime = getRuntimeConfig().pluginRuntime ?? {}
|
|
9
|
+
const enrichers = Object.values(pluginRuntime).flatMap((plugin) => plugin.contextEnrichers ?? [])
|
|
10
|
+
|
|
11
|
+
if (enrichers.length === 0) return []
|
|
12
|
+
|
|
13
|
+
const results = await Promise.allSettled(
|
|
14
|
+
enrichers.map((enricher) =>
|
|
15
|
+
enricher.enrich({ objective: params.objective, organizationId: params.organizationId }),
|
|
16
|
+
),
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
const enrichments: ContextEnrichment[] = []
|
|
20
|
+
for (let i = 0; i < results.length; i++) {
|
|
21
|
+
const result = results[i]
|
|
22
|
+
if (result.status === 'fulfilled') {
|
|
23
|
+
enrichments.push({ domain: enrichers[i].domain, data: result.value.data, confidence: result.value.confidence })
|
|
24
|
+
} else {
|
|
25
|
+
serverLogger.warn`Context enricher "${enrichers[i].domain}" failed: ${result.reason}`
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return enrichments.sort((a, b) => b.confidence - a.confidence)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const contextEnrichmentService = new ContextEnrichmentService()
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { SignalDeclaration } from '@lota-sdk/shared'
|
|
2
|
+
|
|
3
|
+
import { serverLogger } from '../config/logger'
|
|
4
|
+
import type { LotaPlugin } from '../runtime/plugin-types'
|
|
5
|
+
import { getRuntimeConfig } from '../runtime/runtime-config'
|
|
6
|
+
import type { PlanValidationIssueInput } from './plan-validator.service'
|
|
7
|
+
|
|
8
|
+
export interface EmittedSignal {
|
|
9
|
+
signal: string
|
|
10
|
+
payload: unknown
|
|
11
|
+
sourcePlugin: string
|
|
12
|
+
consumers: string[]
|
|
13
|
+
emittedAt: Date
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const MAX_EMITTED_SIGNALS = 1000
|
|
17
|
+
|
|
18
|
+
class CoordinationRegistryService {
|
|
19
|
+
private producers = new Map<string, string[]>()
|
|
20
|
+
private consumers = new Map<string, string[]>()
|
|
21
|
+
private _emittedSignals: EmittedSignal[] = []
|
|
22
|
+
|
|
23
|
+
register(pluginRef: string, signals: SignalDeclaration[]): void {
|
|
24
|
+
for (const signal of signals) {
|
|
25
|
+
if (signal.direction === 'produces') {
|
|
26
|
+
const existing = this.producers.get(signal.signalName) ?? []
|
|
27
|
+
existing.push(pluginRef)
|
|
28
|
+
this.producers.set(signal.signalName, existing)
|
|
29
|
+
} else {
|
|
30
|
+
const existing = this.consumers.get(signal.signalName) ?? []
|
|
31
|
+
existing.push(pluginRef)
|
|
32
|
+
this.consumers.set(signal.signalName, existing)
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async emit(signal: string, payload: unknown, sourcePlugin: string): Promise<void> {
|
|
38
|
+
const consumers = this.consumers.get(signal) ?? []
|
|
39
|
+
|
|
40
|
+
this._emittedSignals.push({ signal, payload, sourcePlugin, consumers: [...consumers], emittedAt: new Date() })
|
|
41
|
+
if (this._emittedSignals.length > MAX_EMITTED_SIGNALS) {
|
|
42
|
+
this._emittedSignals.shift()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
serverLogger.debug(
|
|
46
|
+
`Signal "${signal}" emitted by "${sourcePlugin}" — ${consumers.length} consumer(s): ${consumers.join(', ') || 'none'}`,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
if (consumers.length === 0) return
|
|
50
|
+
|
|
51
|
+
let pluginRuntime: Record<string, unknown> = {}
|
|
52
|
+
try {
|
|
53
|
+
pluginRuntime = getRuntimeConfig().pluginRuntime ?? {}
|
|
54
|
+
} catch {
|
|
55
|
+
// Runtime not yet configured — skip plugin dispatch
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
for (const consumerRef of consumers) {
|
|
59
|
+
const plugin = pluginRuntime[consumerRef] as LotaPlugin | undefined
|
|
60
|
+
if (plugin?.onSignal) {
|
|
61
|
+
try {
|
|
62
|
+
await plugin.onSignal(signal, payload, sourcePlugin)
|
|
63
|
+
} catch (error) {
|
|
64
|
+
serverLogger.warn`Signal handler for "${consumerRef}" failed on signal "${signal}": ${error}`
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
getEmittedSignals(signalName?: string): EmittedSignal[] {
|
|
71
|
+
if (!signalName) return [...this._emittedSignals]
|
|
72
|
+
return this._emittedSignals.filter((entry) => entry.signal === signalName)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
getProducers(signalName: string): string[] {
|
|
76
|
+
return this.producers.get(signalName) ?? []
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
getConsumers(signalName: string): string[] {
|
|
80
|
+
return this.consumers.get(signalName) ?? []
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
validate(): PlanValidationIssueInput[] {
|
|
84
|
+
const issues: PlanValidationIssueInput[] = []
|
|
85
|
+
|
|
86
|
+
for (const [signalName] of this.producers) {
|
|
87
|
+
if ((this.consumers.get(signalName) ?? []).length === 0) {
|
|
88
|
+
issues.push({
|
|
89
|
+
severity: 'warning',
|
|
90
|
+
code: 'signal_no_consumer',
|
|
91
|
+
message: `Signal "${signalName}" is produced but has no consumers.`,
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
for (const [signalName] of this.consumers) {
|
|
97
|
+
if ((this.producers.get(signalName) ?? []).length === 0) {
|
|
98
|
+
issues.push({
|
|
99
|
+
severity: 'warning',
|
|
100
|
+
code: 'signal_no_producer',
|
|
101
|
+
message: `Signal "${signalName}" is consumed but has no producers.`,
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return issues
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Reset internal state. Intended for testing. */
|
|
110
|
+
_reset(): void {
|
|
111
|
+
this.producers.clear()
|
|
112
|
+
this.consumers.clear()
|
|
113
|
+
this._emittedSignals = []
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const coordinationRegistryService = new CoordinationRegistryService()
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { OwnershipDispatchContext, PlanArtifactSubmission, PlanNodeResult, PlanNodeSpec } from '@lota-sdk/shared'
|
|
2
|
+
|
|
3
|
+
import type { LotaPlugin, PluginDomainAgentDefinition } from '../runtime/plugin-types'
|
|
4
|
+
import { getRuntimeConfig } from '../runtime/runtime-config'
|
|
5
|
+
import type { PlanValidationIssueInput } from './plan-validator.service'
|
|
6
|
+
|
|
7
|
+
class DomainAgentExecutorService {
|
|
8
|
+
private registry = new Map<string, { pluginRef: string; definition: PluginDomainAgentDefinition }>()
|
|
9
|
+
|
|
10
|
+
configure(pluginRuntime: Record<string, LotaPlugin>): void {
|
|
11
|
+
this.registry.clear()
|
|
12
|
+
for (const [pluginRef, plugin] of Object.entries(pluginRuntime)) {
|
|
13
|
+
if (plugin.domainAgents) {
|
|
14
|
+
for (const def of plugin.domainAgents) {
|
|
15
|
+
this.registry.set(def.agentId, { pluginRef, definition: def })
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
hasAgent(agentId: string): boolean {
|
|
22
|
+
return this.registry.has(agentId)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
validateOwner(agentId: string, nodeId: string): PlanValidationIssueInput[] {
|
|
26
|
+
if (!this.registry.has(agentId)) {
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
severity: 'blocking',
|
|
30
|
+
code: 'domain_agent_missing',
|
|
31
|
+
message: `Node "${nodeId}" references unknown domain agent "${agentId}".`,
|
|
32
|
+
nodeId,
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
return []
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async executeNode(params: {
|
|
40
|
+
nodeSpec: PlanNodeSpec
|
|
41
|
+
resolvedInput: Record<string, unknown>
|
|
42
|
+
inputArtifacts: PlanArtifactSubmission[]
|
|
43
|
+
context: OwnershipDispatchContext
|
|
44
|
+
}): Promise<PlanNodeResult> {
|
|
45
|
+
const entry = this.registry.get(params.nodeSpec.owner.ref)
|
|
46
|
+
if (!entry) {
|
|
47
|
+
throw new Error(`Domain agent "${params.nodeSpec.owner.ref}" not registered.`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const plugin = (getRuntimeConfig().pluginRuntime as Record<string, LotaPlugin | undefined> | undefined)?.[
|
|
51
|
+
entry.pluginRef
|
|
52
|
+
]
|
|
53
|
+
if (!plugin?.nodeExecutor) {
|
|
54
|
+
throw new Error(`Plugin "${entry.pluginRef}" does not have a nodeExecutor.`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return plugin.nodeExecutor.executeNode({
|
|
58
|
+
operation: `domain-agent:${entry.definition.agentId}`,
|
|
59
|
+
nodeSpec: params.nodeSpec,
|
|
60
|
+
inputs: params.resolvedInput,
|
|
61
|
+
context: {
|
|
62
|
+
organizationId: params.context.organizationId,
|
|
63
|
+
workstreamId: params.context.workstreamId,
|
|
64
|
+
planId: params.context.planId,
|
|
65
|
+
nodeId: params.context.nodeId,
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const domainAgentExecutorService = new DomainAgentExecutorService()
|