@carlonicora/nestjs-neo4jsonapi 2.3.0 → 2.4.0
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/dist/agents/common/usage-attribution.d.ts +218 -0
- package/dist/agents/common/usage-attribution.d.ts.map +1 -0
- package/dist/agents/common/usage-attribution.js +235 -0
- package/dist/agents/common/usage-attribution.js.map +1 -0
- package/dist/agents/community.summariser/services/community.summariser.service.d.ts.map +1 -1
- package/dist/agents/community.summariser/services/community.summariser.service.js +13 -1
- package/dist/agents/community.summariser/services/community.summariser.service.js.map +1 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts +24 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts.map +1 -1
- package/dist/agents/contextualiser/contexts/contextualiser.context.js +32 -0
- package/dist/agents/contextualiser/contexts/contextualiser.context.js.map +1 -1
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts +7 -0
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts.map +1 -1
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.js +5 -0
- package/dist/agents/contextualiser/factories/contextualiser.context.factory.js.map +1 -1
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/chunk.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js +15 -0
- package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js +11 -0
- package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/question.refiner.node.service.js.map +1 -1
- package/dist/agents/contextualiser/nodes/rational.node.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/nodes/rational.node.service.js +4 -0
- package/dist/agents/contextualiser/nodes/rational.node.service.js.map +1 -1
- package/dist/agents/contextualiser/services/contextualiser.service.d.ts +7 -0
- package/dist/agents/contextualiser/services/contextualiser.service.d.ts.map +1 -1
- package/dist/agents/contextualiser/services/contextualiser.service.js +17 -5
- package/dist/agents/contextualiser/services/contextualiser.service.js.map +1 -1
- package/dist/agents/drift/contexts/drift.context.d.ts +25 -1
- package/dist/agents/drift/contexts/drift.context.d.ts.map +1 -1
- package/dist/agents/drift/contexts/drift.context.js +32 -0
- package/dist/agents/drift/contexts/drift.context.js.map +1 -1
- package/dist/agents/drift/nodes/followup.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/followup.node.service.js +4 -0
- package/dist/agents/drift/nodes/followup.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/hyde.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/hyde.node.service.js +9 -1
- package/dist/agents/drift/nodes/hyde.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/primer.answer.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/primer.answer.node.service.js +4 -0
- package/dist/agents/drift/nodes/primer.answer.node.service.js.map +1 -1
- package/dist/agents/drift/nodes/synthesis.node.service.d.ts.map +1 -1
- package/dist/agents/drift/nodes/synthesis.node.service.js +4 -0
- package/dist/agents/drift/nodes/synthesis.node.service.js.map +1 -1
- package/dist/agents/drift/services/drift.search.service.d.ts +9 -0
- package/dist/agents/drift/services/drift.search.service.d.ts.map +1 -1
- package/dist/agents/drift/services/drift.search.service.js +22 -5
- package/dist/agents/drift/services/drift.search.service.js.map +1 -1
- package/dist/agents/graph/services/graph.search.service.d.ts.map +1 -1
- package/dist/agents/graph/services/graph.search.service.js +10 -1
- package/dist/agents/graph/services/graph.search.service.js.map +1 -1
- package/dist/agents/graph/tools/tool.factory.d.ts +6 -0
- package/dist/agents/graph/tools/tool.factory.d.ts.map +1 -1
- package/dist/agents/graph/tools/tool.factory.js.map +1 -1
- package/dist/agents/index.d.ts +7 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +13 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/operator/contexts/operator.context.d.ts +37 -1
- package/dist/agents/operator/contexts/operator.context.d.ts.map +1 -1
- package/dist/agents/operator/contexts/operator.context.js +8 -0
- package/dist/agents/operator/contexts/operator.context.js.map +1 -1
- package/dist/agents/operator/interfaces/operator.tool.interface.d.ts +8 -0
- package/dist/agents/operator/interfaces/operator.tool.interface.d.ts.map +1 -1
- package/dist/agents/operator/interfaces/operator.tool.interface.js.map +1 -1
- package/dist/agents/operator/services/operator.service.d.ts +8 -0
- package/dist/agents/operator/services/operator.service.d.ts.map +1 -1
- package/dist/agents/operator/services/operator.service.js +29 -0
- package/dist/agents/operator/services/operator.service.js.map +1 -1
- package/dist/agents/operator/tools/operator.tool.registry.d.ts.map +1 -1
- package/dist/agents/operator/tools/operator.tool.registry.js +2 -1
- package/dist/agents/operator/tools/operator.tool.registry.js.map +1 -1
- package/dist/agents/operator/tools/search-communities.tool.d.ts +8 -2
- package/dist/agents/operator/tools/search-communities.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-communities.tool.js +16 -4
- package/dist/agents/operator/tools/search-communities.tool.js.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.js +5 -0
- package/dist/agents/operator/tools/search-documents.tool.js.map +1 -1
- package/dist/agents/responder/contexts/responder.context.d.ts +31 -0
- package/dist/agents/responder/contexts/responder.context.d.ts.map +1 -1
- package/dist/agents/responder/contexts/responder.context.js +8 -0
- package/dist/agents/responder/contexts/responder.context.js.map +1 -1
- package/dist/agents/responder/factories/responder.context.factory.d.ts +4 -0
- package/dist/agents/responder/factories/responder.context.factory.d.ts.map +1 -1
- package/dist/agents/responder/factories/responder.context.factory.js +2 -0
- package/dist/agents/responder/factories/responder.context.factory.js.map +1 -1
- package/dist/agents/responder/nodes/graph.node.service.d.ts +6 -0
- package/dist/agents/responder/nodes/graph.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/graph.node.service.js +20 -0
- package/dist/agents/responder/nodes/graph.node.service.js.map +1 -1
- package/dist/agents/responder/nodes/planner.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/planner.node.service.js +9 -0
- package/dist/agents/responder/nodes/planner.node.service.js.map +1 -1
- package/dist/agents/responder/nodes/responder.answer.node.service.d.ts.map +1 -1
- package/dist/agents/responder/nodes/responder.answer.node.service.js +9 -0
- package/dist/agents/responder/nodes/responder.answer.node.service.js.map +1 -1
- package/dist/agents/responder/services/responder.service.d.ts +16 -0
- package/dist/agents/responder/services/responder.service.d.ts.map +1 -1
- package/dist/agents/responder/services/responder.service.js +29 -5
- package/dist/agents/responder/services/responder.service.js.map +1 -1
- package/dist/agents/summariser/services/summariser.service.d.ts +7 -0
- package/dist/agents/summariser/services/summariser.service.d.ts.map +1 -1
- package/dist/agents/summariser/services/summariser.service.js +15 -3
- package/dist/agents/summariser/services/summariser.service.js.map +1 -1
- package/dist/common/helpers/index.d.ts +1 -0
- package/dist/common/helpers/index.d.ts.map +1 -1
- package/dist/common/helpers/index.js +1 -0
- package/dist/common/helpers/index.js.map +1 -1
- package/dist/common/helpers/map-with-concurrency.d.ts +23 -0
- package/dist/common/helpers/map-with-concurrency.d.ts.map +1 -0
- package/dist/common/helpers/map-with-concurrency.js +60 -0
- package/dist/common/helpers/map-with-concurrency.js.map +1 -0
- package/dist/common/tokens.d.ts +2 -1
- package/dist/common/tokens.d.ts.map +1 -1
- package/dist/common/tokens.js +2 -1
- package/dist/common/tokens.js.map +1 -1
- package/dist/config/base.config.d.ts +19 -0
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +30 -3
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/interfaces/config.ai.interface.d.ts +10 -1
- package/dist/config/interfaces/config.ai.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.chunk.queues.interface.d.ts +13 -0
- package/dist/config/interfaces/config.chunk.queues.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.credits.interface.d.ts +1 -1
- package/dist/core/blocknote/services/blocknote.service.d.ts.map +1 -1
- package/dist/core/blocknote/services/blocknote.service.js +7 -0
- package/dist/core/blocknote/services/blocknote.service.js.map +1 -1
- package/dist/core/llm/services/audio.llm.service.d.ts +70 -1
- package/dist/core/llm/services/audio.llm.service.d.ts.map +1 -1
- package/dist/core/llm/services/audio.llm.service.js +118 -3
- package/dist/core/llm/services/audio.llm.service.js.map +1 -1
- package/dist/core/llm/services/document-ai.service.d.ts +6 -0
- package/dist/core/llm/services/document-ai.service.d.ts.map +1 -1
- package/dist/core/llm/services/document-ai.service.js +1 -0
- package/dist/core/llm/services/document-ai.service.js.map +1 -1
- package/dist/core/llm/services/embedder.service.d.ts +105 -0
- package/dist/core/llm/services/embedder.service.d.ts.map +1 -1
- package/dist/core/llm/services/embedder.service.js +237 -7
- package/dist/core/llm/services/embedder.service.js.map +1 -1
- package/dist/core/llm/services/llm.service.d.ts +103 -6
- package/dist/core/llm/services/llm.service.d.ts.map +1 -1
- package/dist/core/llm/services/llm.service.js +570 -148
- package/dist/core/llm/services/llm.service.js.map +1 -1
- package/dist/core/llm/services/model.service.d.ts +25 -0
- package/dist/core/llm/services/model.service.d.ts.map +1 -1
- package/dist/core/llm/services/model.service.js +76 -4
- package/dist/core/llm/services/model.service.js.map +1 -1
- package/dist/core/llm/utils/repair-truncated-json.d.ts +29 -0
- package/dist/core/llm/utils/repair-truncated-json.d.ts.map +1 -0
- package/dist/core/llm/utils/repair-truncated-json.js +111 -0
- package/dist/core/llm/utils/repair-truncated-json.js.map +1 -0
- package/dist/foundations/assistant/services/assistant.service.d.ts.map +1 -1
- package/dist/foundations/assistant/services/assistant.service.js +12 -0
- package/dist/foundations/assistant/services/assistant.service.js.map +1 -1
- package/dist/foundations/atomicfact/services/atomicfact.service.d.ts +7 -0
- package/dist/foundations/atomicfact/services/atomicfact.service.d.ts.map +1 -1
- package/dist/foundations/atomicfact/services/atomicfact.service.js +6 -0
- package/dist/foundations/atomicfact/services/atomicfact.service.js.map +1 -1
- package/dist/foundations/chunk/processors/chunk.processor.d.ts.map +1 -1
- package/dist/foundations/chunk/processors/chunk.processor.js +7 -1
- package/dist/foundations/chunk/processors/chunk.processor.js.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts +90 -2
- package/dist/foundations/chunk/repositories/chunk.repository.d.ts.map +1 -1
- package/dist/foundations/chunk/repositories/chunk.repository.js +205 -31
- package/dist/foundations/chunk/repositories/chunk.repository.js.map +1 -1
- package/dist/foundations/chunk/services/chunk.service.d.ts.map +1 -1
- package/dist/foundations/chunk/services/chunk.service.js +50 -1
- package/dist/foundations/chunk/services/chunk.service.js.map +1 -1
- package/dist/foundations/chunker/chunker.module.d.ts.map +1 -1
- package/dist/foundations/chunker/chunker.module.js +4 -1
- package/dist/foundations/chunker/chunker.module.js.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.d.ts +57 -1
- package/dist/foundations/chunker/services/chunker.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/chunker.service.js +207 -16
- package/dist/foundations/chunker/services/chunker.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/pdf.service.d.ts +42 -1
- package/dist/foundations/chunker/services/types/pdf.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/pdf.service.js +111 -22
- package/dist/foundations/chunker/services/types/pdf.service.js.map +1 -1
- package/dist/foundations/chunker/services/types/semanticsplitter.service.d.ts.map +1 -1
- package/dist/foundations/chunker/services/types/semanticsplitter.service.js +24 -3
- package/dist/foundations/chunker/services/types/semanticsplitter.service.js.map +1 -1
- package/dist/foundations/company/repositories/company.repository.d.ts +1 -1
- package/dist/foundations/company/repositories/company.repository.d.ts.map +1 -1
- package/dist/foundations/company/repositories/company.repository.js +31 -14
- package/dist/foundations/company/repositories/company.repository.js.map +1 -1
- package/dist/foundations/how-to/processors/how-to.processor.d.ts.map +1 -1
- package/dist/foundations/how-to/processors/how-to.processor.js +20 -7
- package/dist/foundations/how-to/processors/how-to.processor.js.map +1 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts +25 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts.map +1 -1
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.js +38 -2
- package/dist/foundations/keyconcept/repositories/keyconcept.repository.js.map +1 -1
- package/dist/foundations/keyconcept/services/keyconcept.service.d.ts +5 -0
- package/dist/foundations/keyconcept/services/keyconcept.service.d.ts.map +1 -1
- package/dist/foundations/keyconcept/services/keyconcept.service.js +4 -0
- package/dist/foundations/keyconcept/services/keyconcept.service.js.map +1 -1
- package/dist/foundations/tokenusage/entities/tokenusage.js +1 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts +4 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts.map +1 -1
- package/dist/foundations/tokenusage/enums/tokenusage.type.js +3 -0
- package/dist/foundations/tokenusage/enums/tokenusage.type.js.map +1 -1
- package/dist/foundations/tokenusage/repositories/tokenusage.admin.repository.js +3 -3
- package/dist/foundations/tokenusage/repositories/tokenusage.repository.js +2 -2
- package/dist/foundations/tokenusage/services/tokenusage.service.d.ts +6 -1
- package/dist/foundations/tokenusage/services/tokenusage.service.d.ts.map +1 -1
- package/dist/foundations/tokenusage/services/tokenusage.service.js +7 -2
- package/dist/foundations/tokenusage/services/tokenusage.service.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { DataLimits } from "../../common/types/data.limits";
|
|
2
|
+
import { EmbedderAttribution } from "../../core/llm/services/embedder.service";
|
|
3
|
+
/**
|
|
4
|
+
* Cost attribution for one assistant LLM call, in the exact shape
|
|
5
|
+
* `LLMService.call` / `LLMService.callStep` accept.
|
|
6
|
+
*
|
|
7
|
+
* The agents carry their run scope as a JSON:API TYPE (`"campaigns"`), but a
|
|
8
|
+
* TokenUsage record's `USED_FOR` edge is matched on the Neo4j LABEL
|
|
9
|
+
* (`"Campaign"`). Passing the type through verbatim writes a record whose edge
|
|
10
|
+
* matches nothing — it looks attributed and silently bills against no entity.
|
|
11
|
+
* The registry is the only mapping that stays correct as entities are added, so
|
|
12
|
+
* every assistant call site goes through this one translation.
|
|
13
|
+
*/
|
|
14
|
+
export interface ScopeAttribution {
|
|
15
|
+
tokenUsageType: string;
|
|
16
|
+
relationshipId?: string;
|
|
17
|
+
relationshipType?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* JSON:API type ("campaigns") to Neo4j label ("Campaign"); undefined when the
|
|
21
|
+
* type is absent or unregistered.
|
|
22
|
+
*
|
|
23
|
+
* A MISS IS LOUD. An unresolvable type would otherwise leave `relationshipType`
|
|
24
|
+
* undefined while `relationshipId` is set, and `persistUsage` skips silently on
|
|
25
|
+
* exactly that shape — the "looks attributed, records nothing" failure this
|
|
26
|
+
* helper exists to prevent. The caller also falls back to the thread, so a miss
|
|
27
|
+
* degrades to a coarser attribution rather than to no billing at all.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveScopeLabel(scopeType?: string): string | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* Builds the attribution triple for one assistant call. Spread into the LLM call
|
|
32
|
+
* params so no site can apply half of it.
|
|
33
|
+
*
|
|
34
|
+
* Precedence:
|
|
35
|
+
* 1. the run's SCOPE ROOT (a campaign) — the most useful unit of spend, used
|
|
36
|
+
* whenever the turn has one AND its label is known. `scopeLabel` is the
|
|
37
|
+
* label the caller already resolved (the catalog carries `rootLabel`
|
|
38
|
+
* alongside `rootType`); the registry lookup is the fallback for callers
|
|
39
|
+
* that only have the JSON:API type.
|
|
40
|
+
* 2. the ASSISTANT THREAD itself — every turn has one, whatever the thread is
|
|
41
|
+
* bound to, so an unscoped turn still bills instead of running free.
|
|
42
|
+
* 3. nothing — only when the caller supplied neither, in which case
|
|
43
|
+
* `persistUsage` skips the record.
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildScopeAttribution(params: {
|
|
46
|
+
tokenUsageType: string;
|
|
47
|
+
scopeId?: string;
|
|
48
|
+
scopeType?: string;
|
|
49
|
+
/** Neo4j label of the scope root, when the caller already knows it. */
|
|
50
|
+
scopeLabel?: string;
|
|
51
|
+
/** Id of the `Assistant` (thread) node this turn belongs to. */
|
|
52
|
+
assistantId?: string;
|
|
53
|
+
}): ScopeAttribution;
|
|
54
|
+
/**
|
|
55
|
+
* The caller's cost attribution, carried through a SUB-AGENT's graph state.
|
|
56
|
+
*
|
|
57
|
+
* The contextualiser and DRIFT are never invoked on their own behalf: another
|
|
58
|
+
* agent calls them, and that agent's ledger entry is the one the spend belongs
|
|
59
|
+
* to. So they own no `TokenUsageType` value of their own and name no entity of
|
|
60
|
+
* their own — they carry the caller's, verbatim, and apply it at every LLM call
|
|
61
|
+
* they make.
|
|
62
|
+
*
|
|
63
|
+
* EVERY FIELD IS OPTIONAL. A direct library consumer that supplies none still
|
|
64
|
+
* runs; its calls simply record nothing (`persistUsage` skips a record with no
|
|
65
|
+
* relationship), exactly like every other unattributed path in the package.
|
|
66
|
+
*/
|
|
67
|
+
export interface CallerAttributionState {
|
|
68
|
+
/**
|
|
69
|
+
* Ledger category of the CALLING agent (e.g. `TokenUsageType.Responder`).
|
|
70
|
+
* Absent = the library default (`text_generation`); a sub-agent never
|
|
71
|
+
* substitutes an identity of its own here.
|
|
72
|
+
*/
|
|
73
|
+
tokenUsageType?: string;
|
|
74
|
+
/** Id of the caller's scope-root node. Absent = the caller ran unscoped. */
|
|
75
|
+
scopeId?: string;
|
|
76
|
+
/** JSON:API type of that scope root, e.g. "campaigns". */
|
|
77
|
+
scopeType?: string;
|
|
78
|
+
/** Neo4j label of that scope root, e.g. "Campaign". */
|
|
79
|
+
scopeLabel?: string;
|
|
80
|
+
/** Id of the caller's `Assistant` (thread) node — the unscoped fallback. */
|
|
81
|
+
assistantId?: string;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Packs a CALLING agent's own attribution into the shape its sub-agents accept.
|
|
85
|
+
*
|
|
86
|
+
* `source` is whatever the caller already holds — its graph state, or the
|
|
87
|
+
* per-turn tool context — both of which carry the scope triple and the thread
|
|
88
|
+
* id under these exact names. `tokenUsageType` is always the caller's own; a
|
|
89
|
+
* sub-agent must never appear in the ledger under a category of its own.
|
|
90
|
+
*/
|
|
91
|
+
export declare function buildCallerAttribution(params: {
|
|
92
|
+
tokenUsageType: string;
|
|
93
|
+
source?: {
|
|
94
|
+
scopeId?: string;
|
|
95
|
+
scopeType?: string;
|
|
96
|
+
scopeLabel?: string;
|
|
97
|
+
assistantId?: string;
|
|
98
|
+
};
|
|
99
|
+
}): CallerAttributionState;
|
|
100
|
+
/**
|
|
101
|
+
* What a caller actually handed a sub-agent, so the sub-agent can log
|
|
102
|
+
* PROPORTIONATELY. These are three different situations and only one of them is
|
|
103
|
+
* a fault:
|
|
104
|
+
*
|
|
105
|
+
* - `"billable"` — an entity the usage record can point at. Nothing to say.
|
|
106
|
+
* - `"none"` — the caller named NO entity at all. This is LEGITIMATE and
|
|
107
|
+
* permanent for some callers: an MCP tool call has no scope root and no
|
|
108
|
+
* assistant thread (`McpUserContext` carries only userId/companyId/
|
|
109
|
+
* userModuleIds), and a direct library consumer need not attribute anything.
|
|
110
|
+
* Nothing is recorded, nothing is wrong, and warning here would mean a
|
|
111
|
+
* warning on EVERY MCP `search_documents` call forever.
|
|
112
|
+
* - `"unresolvable"` — the caller DID name something, but it cannot become a
|
|
113
|
+
* `USED_FOR` edge (a `scopeType` no model claims, a `scopeId` with no label,
|
|
114
|
+
* a `scopeLabel` with no id). That IS a fault: it looks attributed and bills
|
|
115
|
+
* nothing, which is the exact failure this whole helper exists to prevent.
|
|
116
|
+
*
|
|
117
|
+
* `tokenUsageType` deliberately does NOT count as "named something": every
|
|
118
|
+
* caller supplies a category unconditionally (`buildCallerAttribution` always
|
|
119
|
+
* sets it), so counting it would collapse `"none"` into `"unresolvable"` and
|
|
120
|
+
* bring the spam straight back.
|
|
121
|
+
*
|
|
122
|
+
* The registry is only consulted once something was named, so the `"none"` path
|
|
123
|
+
* costs nothing and cannot emit `resolveScopeLabel`'s own warning.
|
|
124
|
+
*/
|
|
125
|
+
export declare function classifyCallerAttribution(state?: CallerAttributionState): "billable" | "none" | "unresolvable";
|
|
126
|
+
/**
|
|
127
|
+
* Attribution for one LLM call made by a SUB-AGENT, derived entirely from the
|
|
128
|
+
* caller's. Spread into the LLM call params — always last — so no site can
|
|
129
|
+
* apply half of it.
|
|
130
|
+
*
|
|
131
|
+
* Identical precedence to {@link buildScopeAttribution} (scope root → assistant
|
|
132
|
+
* thread → nothing); the only addition is the `tokenUsageType` default, which
|
|
133
|
+
* is the LIBRARY's default rather than any sub-agent name. Inventing
|
|
134
|
+
* `"contextualiser"` / `"drift"` here would split one agent's spend across
|
|
135
|
+
* ledger categories the app never asked for.
|
|
136
|
+
*/
|
|
137
|
+
export declare function buildInheritedAttribution(state?: CallerAttributionState): ScopeAttribution;
|
|
138
|
+
/**
|
|
139
|
+
* Attribution for one EMBEDDING call (`EmbedderService.vectoriseText` /
|
|
140
|
+
* `vectoriseTextBatch`), or `undefined` when the caller holds no entity to bill
|
|
141
|
+
* it to — `EmbedderService.persistUsage` then skips the record entirely rather
|
|
142
|
+
* than writing one whose `USED_FOR` edge matches nothing.
|
|
143
|
+
*
|
|
144
|
+
* `entityIdentifier` is whatever the call site happens to hold: a Neo4j LABEL
|
|
145
|
+
* ("Npc"), a JSON:API type ("npcs"), or a nodeName. `modelRegistry.resolveModel`
|
|
146
|
+
* accepts all three and yields the label the `USED_FOR` edge is matched on —
|
|
147
|
+
* the same translation `resolveScopeLabel` performs for LLM calls.
|
|
148
|
+
*
|
|
149
|
+
* DIFFERENCE FROM `resolveScopeLabel`: an unresolvable identifier FALLS BACK to
|
|
150
|
+
* itself instead of dropping the attribution. That is safe at the INGESTION call
|
|
151
|
+
* sites, which already interpolate the same value into Cypher as a label
|
|
152
|
+
* (`MATCH (nodeType:${params.nodeType} {id: $nodeId})`), so an identifier the
|
|
153
|
+
* registry does not know is still a valid label there — and if it were not, that
|
|
154
|
+
* Cypher would have matched nothing and there would be no chunk to embed.
|
|
155
|
+
* Dropping it would silently lose a real, attributable cost.
|
|
156
|
+
*
|
|
157
|
+
* IT IS NOT SAFE AT THE QUERY-TIME CALL SITES. `GraphSearchService.tierSemantic`
|
|
158
|
+
* passes `scopeType` — always a JSON:API type — and `buildRetrievalAttribution`
|
|
159
|
+
* passes `contentType`, which is whichever of the two the caller set (narr8 sets
|
|
160
|
+
* a JSON:API type; the contextualiser's own chunk-vector node compares it
|
|
161
|
+
* against the LABEL "Conversation"). Either way an UNRESOLVED value is written
|
|
162
|
+
* verbatim into `MATCH (relEntity:${relationshipType} {id: $relationshipId})`
|
|
163
|
+
* and matches nothing — precisely the failure this helper exists to prevent.
|
|
164
|
+
* Every such input is registry-registered today, so the fallback is latent
|
|
165
|
+
* rather than live, which is why it WARNS rather than throws: the warning names
|
|
166
|
+
* the identifier so the regression is visible the moment it appears, instead of
|
|
167
|
+
* surfacing as a TokenUsage row with no `USED_FOR` edge.
|
|
168
|
+
*/
|
|
169
|
+
export declare function buildEmbedderAttribution(params: {
|
|
170
|
+
/** Id of the node the spend is billed against. */
|
|
171
|
+
entityId?: string;
|
|
172
|
+
/** Neo4j label, JSON:API type or nodeName of that node. */
|
|
173
|
+
entityIdentifier?: string;
|
|
174
|
+
/** Overrides the recorder's default (`TokenUsageType.Embedding`). */
|
|
175
|
+
tokenUsageType?: string;
|
|
176
|
+
}): EmbedderAttribution | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* Attribution for an EMBEDDING made by a SUB-AGENT, derived from the caller's
|
|
179
|
+
* attribution through the SAME precedence chain as
|
|
180
|
+
* {@link buildInheritedAttribution} (scope root → assistant thread → nothing),
|
|
181
|
+
* so a turn's LLM spend and its embedding spend always land on one entity.
|
|
182
|
+
*
|
|
183
|
+
* `tokenUsageType` is deliberately omitted: the recorder's own default
|
|
184
|
+
* (`embedding`) classifies the OPERATION, and it is not the sub-agent inventing
|
|
185
|
+
* an identity — the caller's identity is already expressed by the entity the
|
|
186
|
+
* record points at.
|
|
187
|
+
*/
|
|
188
|
+
export declare function buildInheritedEmbedderAttribution(state?: CallerAttributionState): EmbedderAttribution | undefined;
|
|
189
|
+
/**
|
|
190
|
+
* Attribution for a QUERY-time (retrieval) embedding — the contextualiser
|
|
191
|
+
* embedding the user's question to search chunks / key concepts.
|
|
192
|
+
*
|
|
193
|
+
* A search has no entity of its own, so it is billed to the SCOPE BEING
|
|
194
|
+
* SEARCHED, in the order the retrieval itself narrows:
|
|
195
|
+
* 1. the CALLER's scope root, when the contextualiser was invoked by another
|
|
196
|
+
* agent that confined the whole turn to one (`scope`). It is the widest
|
|
197
|
+
* honest unit of spend and the same entity that agent's own LLM calls bill,
|
|
198
|
+
* so a turn is not split across two ledger targets;
|
|
199
|
+
* 2. the content the run is bound to (`contentId` + `contentType`, a JSON:API
|
|
200
|
+
* type resolved to its label) — the retrieval scope the caller passes in;
|
|
201
|
+
* 3. help mode's single HowTo (`dataLimits.limitToHowToId`), which is the only
|
|
202
|
+
* scope a help-mode run has;
|
|
203
|
+
* 4. nothing — an unbound, non-help run genuinely searches the whole company,
|
|
204
|
+
* so there is no honest entity to name and `persistUsage` skips the record
|
|
205
|
+
* rather than inventing one.
|
|
206
|
+
*
|
|
207
|
+
* `dataLimits.howToMode` on its own carries NO id, so it deliberately does not
|
|
208
|
+
* produce an attribution: guessing one would write a `USED_FOR` edge that
|
|
209
|
+
* matches nothing.
|
|
210
|
+
*/
|
|
211
|
+
export declare function buildRetrievalAttribution(params: {
|
|
212
|
+
contentId?: string;
|
|
213
|
+
contentType?: string;
|
|
214
|
+
dataLimits?: DataLimits;
|
|
215
|
+
/** The calling agent's attribution, when this retrieval runs inside another agent's turn. */
|
|
216
|
+
scope?: CallerAttributionState;
|
|
217
|
+
}): EmbedderAttribution | undefined;
|
|
218
|
+
//# sourceMappingURL=usage-attribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-attribution.d.ts","sourceRoot":"","sources":["../../../src/agents/common/usage-attribution.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAO/E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUxE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,gBAAgB,CAenB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9F,GAAG,sBAAsB,CAQzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,CAAC,EAAE,sBAAsB,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,CAI9G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,CAAC,EAAE,sBAAsB,GAAG,gBAAgB,CAQ1F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,mBAAmB,GAAG,SAAS,CAelC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iCAAiC,CAAC,KAAK,CAAC,EAAE,sBAAsB,GAAG,mBAAmB,GAAG,SAAS,CAIjH;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,6FAA6F;IAC7F,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC,GAAG,mBAAmB,GAAG,SAAS,CAelC"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveScopeLabel = resolveScopeLabel;
|
|
4
|
+
exports.buildScopeAttribution = buildScopeAttribution;
|
|
5
|
+
exports.buildCallerAttribution = buildCallerAttribution;
|
|
6
|
+
exports.classifyCallerAttribution = classifyCallerAttribution;
|
|
7
|
+
exports.buildInheritedAttribution = buildInheritedAttribution;
|
|
8
|
+
exports.buildEmbedderAttribution = buildEmbedderAttribution;
|
|
9
|
+
exports.buildInheritedEmbedderAttribution = buildInheritedEmbedderAttribution;
|
|
10
|
+
exports.buildRetrievalAttribution = buildRetrievalAttribution;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const registry_1 = require("../../common/registries/registry");
|
|
13
|
+
const assistant_meta_1 = require("../../foundations/assistant/entities/assistant.meta");
|
|
14
|
+
const how_to_meta_1 = require("../../foundations/how-to/entities/how-to.meta");
|
|
15
|
+
const tokenusage_type_1 = require("../../foundations/tokenusage/enums/tokenusage.type");
|
|
16
|
+
const logger = new common_1.Logger("UsageAttribution");
|
|
17
|
+
/**
|
|
18
|
+
* JSON:API type ("campaigns") to Neo4j label ("Campaign"); undefined when the
|
|
19
|
+
* type is absent or unregistered.
|
|
20
|
+
*
|
|
21
|
+
* A MISS IS LOUD. An unresolvable type would otherwise leave `relationshipType`
|
|
22
|
+
* undefined while `relationshipId` is set, and `persistUsage` skips silently on
|
|
23
|
+
* exactly that shape — the "looks attributed, records nothing" failure this
|
|
24
|
+
* helper exists to prevent. The caller also falls back to the thread, so a miss
|
|
25
|
+
* degrades to a coarser attribution rather than to no billing at all.
|
|
26
|
+
*/
|
|
27
|
+
function resolveScopeLabel(scopeType) {
|
|
28
|
+
if (!scopeType)
|
|
29
|
+
return undefined;
|
|
30
|
+
const labelName = registry_1.modelRegistry.resolveModel(scopeType)?.labelName;
|
|
31
|
+
if (!labelName) {
|
|
32
|
+
logger.warn(`scopeType "${scopeType}" resolves to no registered model — cannot translate it to a Neo4j label. ` +
|
|
33
|
+
`Falling back to thread-level attribution for this call.`);
|
|
34
|
+
}
|
|
35
|
+
return labelName;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Builds the attribution triple for one assistant call. Spread into the LLM call
|
|
39
|
+
* params so no site can apply half of it.
|
|
40
|
+
*
|
|
41
|
+
* Precedence:
|
|
42
|
+
* 1. the run's SCOPE ROOT (a campaign) — the most useful unit of spend, used
|
|
43
|
+
* whenever the turn has one AND its label is known. `scopeLabel` is the
|
|
44
|
+
* label the caller already resolved (the catalog carries `rootLabel`
|
|
45
|
+
* alongside `rootType`); the registry lookup is the fallback for callers
|
|
46
|
+
* that only have the JSON:API type.
|
|
47
|
+
* 2. the ASSISTANT THREAD itself — every turn has one, whatever the thread is
|
|
48
|
+
* bound to, so an unscoped turn still bills instead of running free.
|
|
49
|
+
* 3. nothing — only when the caller supplied neither, in which case
|
|
50
|
+
* `persistUsage` skips the record.
|
|
51
|
+
*/
|
|
52
|
+
function buildScopeAttribution(params) {
|
|
53
|
+
const scopeLabel = params.scopeId ? (params.scopeLabel ?? resolveScopeLabel(params.scopeType)) : undefined;
|
|
54
|
+
if (params.scopeId && scopeLabel) {
|
|
55
|
+
return { tokenUsageType: params.tokenUsageType, relationshipId: params.scopeId, relationshipType: scopeLabel };
|
|
56
|
+
}
|
|
57
|
+
if (params.assistantId) {
|
|
58
|
+
return {
|
|
59
|
+
tokenUsageType: params.tokenUsageType,
|
|
60
|
+
relationshipId: params.assistantId,
|
|
61
|
+
relationshipType: assistant_meta_1.assistantMeta.labelName,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return { tokenUsageType: params.tokenUsageType };
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Packs a CALLING agent's own attribution into the shape its sub-agents accept.
|
|
68
|
+
*
|
|
69
|
+
* `source` is whatever the caller already holds — its graph state, or the
|
|
70
|
+
* per-turn tool context — both of which carry the scope triple and the thread
|
|
71
|
+
* id under these exact names. `tokenUsageType` is always the caller's own; a
|
|
72
|
+
* sub-agent must never appear in the ledger under a category of its own.
|
|
73
|
+
*/
|
|
74
|
+
function buildCallerAttribution(params) {
|
|
75
|
+
return {
|
|
76
|
+
tokenUsageType: params.tokenUsageType,
|
|
77
|
+
scopeId: params.source?.scopeId,
|
|
78
|
+
scopeType: params.source?.scopeType,
|
|
79
|
+
scopeLabel: params.source?.scopeLabel,
|
|
80
|
+
assistantId: params.source?.assistantId,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* What a caller actually handed a sub-agent, so the sub-agent can log
|
|
85
|
+
* PROPORTIONATELY. These are three different situations and only one of them is
|
|
86
|
+
* a fault:
|
|
87
|
+
*
|
|
88
|
+
* - `"billable"` — an entity the usage record can point at. Nothing to say.
|
|
89
|
+
* - `"none"` — the caller named NO entity at all. This is LEGITIMATE and
|
|
90
|
+
* permanent for some callers: an MCP tool call has no scope root and no
|
|
91
|
+
* assistant thread (`McpUserContext` carries only userId/companyId/
|
|
92
|
+
* userModuleIds), and a direct library consumer need not attribute anything.
|
|
93
|
+
* Nothing is recorded, nothing is wrong, and warning here would mean a
|
|
94
|
+
* warning on EVERY MCP `search_documents` call forever.
|
|
95
|
+
* - `"unresolvable"` — the caller DID name something, but it cannot become a
|
|
96
|
+
* `USED_FOR` edge (a `scopeType` no model claims, a `scopeId` with no label,
|
|
97
|
+
* a `scopeLabel` with no id). That IS a fault: it looks attributed and bills
|
|
98
|
+
* nothing, which is the exact failure this whole helper exists to prevent.
|
|
99
|
+
*
|
|
100
|
+
* `tokenUsageType` deliberately does NOT count as "named something": every
|
|
101
|
+
* caller supplies a category unconditionally (`buildCallerAttribution` always
|
|
102
|
+
* sets it), so counting it would collapse `"none"` into `"unresolvable"` and
|
|
103
|
+
* bring the spam straight back.
|
|
104
|
+
*
|
|
105
|
+
* The registry is only consulted once something was named, so the `"none"` path
|
|
106
|
+
* costs nothing and cannot emit `resolveScopeLabel`'s own warning.
|
|
107
|
+
*/
|
|
108
|
+
function classifyCallerAttribution(state) {
|
|
109
|
+
const namedSomething = !!(state?.scopeId || state?.scopeType || state?.scopeLabel || state?.assistantId);
|
|
110
|
+
if (!namedSomething)
|
|
111
|
+
return "none";
|
|
112
|
+
return buildInheritedAttribution(state).relationshipId ? "billable" : "unresolvable";
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Attribution for one LLM call made by a SUB-AGENT, derived entirely from the
|
|
116
|
+
* caller's. Spread into the LLM call params — always last — so no site can
|
|
117
|
+
* apply half of it.
|
|
118
|
+
*
|
|
119
|
+
* Identical precedence to {@link buildScopeAttribution} (scope root → assistant
|
|
120
|
+
* thread → nothing); the only addition is the `tokenUsageType` default, which
|
|
121
|
+
* is the LIBRARY's default rather than any sub-agent name. Inventing
|
|
122
|
+
* `"contextualiser"` / `"drift"` here would split one agent's spend across
|
|
123
|
+
* ledger categories the app never asked for.
|
|
124
|
+
*/
|
|
125
|
+
function buildInheritedAttribution(state) {
|
|
126
|
+
return buildScopeAttribution({
|
|
127
|
+
tokenUsageType: state?.tokenUsageType ?? tokenusage_type_1.TokenUsageType.TextGeneration,
|
|
128
|
+
scopeId: state?.scopeId,
|
|
129
|
+
scopeType: state?.scopeType,
|
|
130
|
+
scopeLabel: state?.scopeLabel,
|
|
131
|
+
assistantId: state?.assistantId,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Attribution for one EMBEDDING call (`EmbedderService.vectoriseText` /
|
|
136
|
+
* `vectoriseTextBatch`), or `undefined` when the caller holds no entity to bill
|
|
137
|
+
* it to — `EmbedderService.persistUsage` then skips the record entirely rather
|
|
138
|
+
* than writing one whose `USED_FOR` edge matches nothing.
|
|
139
|
+
*
|
|
140
|
+
* `entityIdentifier` is whatever the call site happens to hold: a Neo4j LABEL
|
|
141
|
+
* ("Npc"), a JSON:API type ("npcs"), or a nodeName. `modelRegistry.resolveModel`
|
|
142
|
+
* accepts all three and yields the label the `USED_FOR` edge is matched on —
|
|
143
|
+
* the same translation `resolveScopeLabel` performs for LLM calls.
|
|
144
|
+
*
|
|
145
|
+
* DIFFERENCE FROM `resolveScopeLabel`: an unresolvable identifier FALLS BACK to
|
|
146
|
+
* itself instead of dropping the attribution. That is safe at the INGESTION call
|
|
147
|
+
* sites, which already interpolate the same value into Cypher as a label
|
|
148
|
+
* (`MATCH (nodeType:${params.nodeType} {id: $nodeId})`), so an identifier the
|
|
149
|
+
* registry does not know is still a valid label there — and if it were not, that
|
|
150
|
+
* Cypher would have matched nothing and there would be no chunk to embed.
|
|
151
|
+
* Dropping it would silently lose a real, attributable cost.
|
|
152
|
+
*
|
|
153
|
+
* IT IS NOT SAFE AT THE QUERY-TIME CALL SITES. `GraphSearchService.tierSemantic`
|
|
154
|
+
* passes `scopeType` — always a JSON:API type — and `buildRetrievalAttribution`
|
|
155
|
+
* passes `contentType`, which is whichever of the two the caller set (narr8 sets
|
|
156
|
+
* a JSON:API type; the contextualiser's own chunk-vector node compares it
|
|
157
|
+
* against the LABEL "Conversation"). Either way an UNRESOLVED value is written
|
|
158
|
+
* verbatim into `MATCH (relEntity:${relationshipType} {id: $relationshipId})`
|
|
159
|
+
* and matches nothing — precisely the failure this helper exists to prevent.
|
|
160
|
+
* Every such input is registry-registered today, so the fallback is latent
|
|
161
|
+
* rather than live, which is why it WARNS rather than throws: the warning names
|
|
162
|
+
* the identifier so the regression is visible the moment it appears, instead of
|
|
163
|
+
* surfacing as a TokenUsage row with no `USED_FOR` edge.
|
|
164
|
+
*/
|
|
165
|
+
function buildEmbedderAttribution(params) {
|
|
166
|
+
if (!params.entityId || !params.entityIdentifier)
|
|
167
|
+
return undefined;
|
|
168
|
+
const resolved = registry_1.modelRegistry.resolveModel(params.entityIdentifier)?.labelName;
|
|
169
|
+
if (!resolved) {
|
|
170
|
+
logger.warn(`entityIdentifier "${params.entityIdentifier}" resolves to no registered model — using it verbatim as the ` +
|
|
171
|
+
`Neo4j label for this usage record. Correct if it already IS a label; if it is a JSON:API type, the ` +
|
|
172
|
+
`record's USED_FOR edge will match nothing and the spend will be billed against no entity.`);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
relationshipId: params.entityId,
|
|
176
|
+
relationshipType: resolved ?? params.entityIdentifier,
|
|
177
|
+
...(params.tokenUsageType ? { tokenUsageType: params.tokenUsageType } : {}),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Attribution for an EMBEDDING made by a SUB-AGENT, derived from the caller's
|
|
182
|
+
* attribution through the SAME precedence chain as
|
|
183
|
+
* {@link buildInheritedAttribution} (scope root → assistant thread → nothing),
|
|
184
|
+
* so a turn's LLM spend and its embedding spend always land on one entity.
|
|
185
|
+
*
|
|
186
|
+
* `tokenUsageType` is deliberately omitted: the recorder's own default
|
|
187
|
+
* (`embedding`) classifies the OPERATION, and it is not the sub-agent inventing
|
|
188
|
+
* an identity — the caller's identity is already expressed by the entity the
|
|
189
|
+
* record points at.
|
|
190
|
+
*/
|
|
191
|
+
function buildInheritedEmbedderAttribution(state) {
|
|
192
|
+
const { relationshipId, relationshipType } = buildInheritedAttribution(state);
|
|
193
|
+
if (!relationshipId || !relationshipType)
|
|
194
|
+
return undefined;
|
|
195
|
+
return { relationshipId, relationshipType };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Attribution for a QUERY-time (retrieval) embedding — the contextualiser
|
|
199
|
+
* embedding the user's question to search chunks / key concepts.
|
|
200
|
+
*
|
|
201
|
+
* A search has no entity of its own, so it is billed to the SCOPE BEING
|
|
202
|
+
* SEARCHED, in the order the retrieval itself narrows:
|
|
203
|
+
* 1. the CALLER's scope root, when the contextualiser was invoked by another
|
|
204
|
+
* agent that confined the whole turn to one (`scope`). It is the widest
|
|
205
|
+
* honest unit of spend and the same entity that agent's own LLM calls bill,
|
|
206
|
+
* so a turn is not split across two ledger targets;
|
|
207
|
+
* 2. the content the run is bound to (`contentId` + `contentType`, a JSON:API
|
|
208
|
+
* type resolved to its label) — the retrieval scope the caller passes in;
|
|
209
|
+
* 3. help mode's single HowTo (`dataLimits.limitToHowToId`), which is the only
|
|
210
|
+
* scope a help-mode run has;
|
|
211
|
+
* 4. nothing — an unbound, non-help run genuinely searches the whole company,
|
|
212
|
+
* so there is no honest entity to name and `persistUsage` skips the record
|
|
213
|
+
* rather than inventing one.
|
|
214
|
+
*
|
|
215
|
+
* `dataLimits.howToMode` on its own carries NO id, so it deliberately does not
|
|
216
|
+
* produce an attribution: guessing one would write a `USED_FOR` edge that
|
|
217
|
+
* matches nothing.
|
|
218
|
+
*/
|
|
219
|
+
function buildRetrievalAttribution(params) {
|
|
220
|
+
const inherited = buildInheritedEmbedderAttribution(params.scope);
|
|
221
|
+
if (inherited)
|
|
222
|
+
return inherited;
|
|
223
|
+
const content = buildEmbedderAttribution({ entityId: params.contentId, entityIdentifier: params.contentType });
|
|
224
|
+
if (content)
|
|
225
|
+
return content;
|
|
226
|
+
// Built directly rather than via `buildEmbedderAttribution`: `howToMeta.labelName`
|
|
227
|
+
// IS the Neo4j label, so there is nothing to resolve, and routing it through the
|
|
228
|
+
// registry would emit that helper's unresolved-identifier warning whenever the
|
|
229
|
+
// HowTo model happens not to be registered — a false alarm.
|
|
230
|
+
const howToId = params.dataLimits?.limitToHowToId;
|
|
231
|
+
if (howToId)
|
|
232
|
+
return { relationshipId: howToId, relationshipType: how_to_meta_1.howToMeta.labelName };
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=usage-attribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage-attribution.js","sourceRoot":"","sources":["../../../src/agents/common/usage-attribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"community.summariser.service.d.ts","sourceRoot":"","sources":["../../../../src/agents/community.summariser/services/community.summariser.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAA0B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,0DAA0D,CAAC;
|
|
1
|
+
{"version":3,"file":"community.summariser.service.d.ts","sourceRoot":"","sources":["../../../../src/agents/community.summariser/services/community.summariser.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAA0B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,0DAA0D,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAGvG,eAAO,MAAM,MAAM,ozCA6BlB,CAAC;AAmBF,qBACa,0BAA0B;IAInC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAPhC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAGnB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,aAAa,CAAC,mBAAmB,CAAC;IAMpE;;OAEG;IACG,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7D;;OAEG;IACG,eAAe,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CA4E3D"}
|
|
@@ -16,7 +16,9 @@ const zod_1 = require("zod");
|
|
|
16
16
|
const core_1 = require("../../../core");
|
|
17
17
|
const llm_service_1 = require("../../../core/llm/services/llm.service");
|
|
18
18
|
const logging_service_1 = require("../../../core/logging/services/logging.service");
|
|
19
|
+
const community_meta_1 = require("../../../foundations/community/entities/community.meta");
|
|
19
20
|
const community_repository_1 = require("../../../foundations/community/repositories/community.repository");
|
|
21
|
+
const tokenusage_type_1 = require("../../../foundations/tokenusage/enums/tokenusage.type");
|
|
20
22
|
exports.prompt = `
|
|
21
23
|
You are an expert knowledge analyst tasked with summarizing a community of related entities from a knowledge graph.
|
|
22
24
|
|
|
@@ -120,10 +122,20 @@ let CommunitySummariserService = class CommunitySummariserService {
|
|
|
120
122
|
outputSchema,
|
|
121
123
|
systemPrompts: [this.systemPrompt],
|
|
122
124
|
temperature: 0.3,
|
|
125
|
+
tokenUsageType: tokenusage_type_1.TokenUsageType.CommunitySummariser,
|
|
126
|
+
relationshipId: community.id,
|
|
127
|
+
relationshipType: community_meta_1.communityMeta.labelName,
|
|
123
128
|
});
|
|
124
|
-
// Generate embedding for the summary
|
|
129
|
+
// Generate embedding for the summary. Same ledger category as the call above so one
|
|
130
|
+
// community's summary reads as one cost; billed against the community itself — this
|
|
131
|
+
// agent is cron-driven with no calling agent to inherit attribution from.
|
|
125
132
|
const embedding = await this.embedderService.vectoriseText({
|
|
126
133
|
text: `${llmResponse.title}\n\n${llmResponse.summary}`,
|
|
134
|
+
attribution: {
|
|
135
|
+
relationshipId: community.id,
|
|
136
|
+
relationshipType: community_meta_1.communityMeta.labelName,
|
|
137
|
+
tokenUsageType: tokenusage_type_1.TokenUsageType.CommunitySummariser,
|
|
138
|
+
},
|
|
127
139
|
});
|
|
128
140
|
// Update the community with summary and embedding
|
|
129
141
|
await this.communityRepository.updateSummary({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"community.summariser.service.js","sourceRoot":"","sources":["../../../../src/agents/community.summariser/services/community.summariser.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAA+C;AAC/C,6BAAwB;AAExB,wCAAgD;AAChD,wEAAoE;AACpE,oFAAmF;AAEnF,2GAAuG;
|
|
1
|
+
{"version":3,"file":"community.summariser.service.js","sourceRoot":"","sources":["../../../../src/agents/community.summariser/services/community.summariser.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { DataLimits } from "../../../common/types/data.limits";
|
|
2
|
+
import { CallerAttributionState } from "../../common/usage-attribution";
|
|
2
3
|
export declare const ContextualiserContext: import("@langchain/langgraph").AnnotationRoot<{
|
|
3
4
|
companyId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
5
|
+
/** Ledger category of the CALLING agent, e.g. `TokenUsageType.Responder`. */
|
|
6
|
+
tokenUsageType: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
7
|
+
/** Id of the caller's scope-root node. Absent = the caller ran unscoped. */
|
|
8
|
+
scopeId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
9
|
+
/** JSON:API type of the caller's scope root, e.g. "campaigns". */
|
|
10
|
+
scopeType: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
11
|
+
/** Neo4j label of the caller's scope root, e.g. "Campaign". */
|
|
12
|
+
scopeLabel: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
13
|
+
/** Id of the caller's `Assistant` (thread) node — the unscoped fallback. */
|
|
14
|
+
assistantId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
4
15
|
contentId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
5
16
|
contentType: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
6
17
|
hops: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
|
|
@@ -271,5 +282,17 @@ export declare const ContextualiserContext: import("@langchain/langgraph").Annot
|
|
|
271
282
|
};
|
|
272
283
|
}>>, unknown>;
|
|
273
284
|
}>;
|
|
274
|
-
|
|
285
|
+
/**
|
|
286
|
+
* LangGraph's `StateType` makes EVERY channel a required property, so adding a
|
|
287
|
+
* channel to the root above would add a required key to this published type and
|
|
288
|
+
* break any consumer that builds a state literal. The attribution channels are
|
|
289
|
+
* therefore re-declared through {@link CallerAttributionState}, where they are
|
|
290
|
+
* optional — the state still carries them, existing literals still compile.
|
|
291
|
+
*
|
|
292
|
+
* {@link ContextualiserGraphState} is the un-widened shape LangGraph itself
|
|
293
|
+
* hands to a node callback; the graph wiring uses it so the callback signatures
|
|
294
|
+
* still match `StateGraph`'s required-property view.
|
|
295
|
+
*/
|
|
296
|
+
export type ContextualiserGraphState = typeof ContextualiserContext.State;
|
|
297
|
+
export type ContextualiserContextState = Omit<ContextualiserGraphState, keyof CallerAttributionState> & CallerAttributionState;
|
|
275
298
|
//# sourceMappingURL=contextualiser.context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contextualiser.context.d.ts","sourceRoot":"","sources":["../../../../src/agents/contextualiser/contexts/contextualiser.context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"contextualiser.context.d.ts","sourceRoot":"","sources":["../../../../src/agents/contextualiser/contexts/contextualiser.context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAExE,eAAO,MAAM,qBAAqB;;IAYhC,6EAA6E;;IAK7E,4EAA4E;;IAK5E,kEAAkE;;IAKlE,+DAA+D;;IAK/D,4EAA4E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0L5E,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,wBAAwB,GAAG,OAAO,qBAAqB,CAAC,KAAK,CAAC;AAE1E,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,wBAAwB,EAAE,MAAM,sBAAsB,CAAC,GACnG,sBAAsB,CAAC"}
|
|
@@ -7,6 +7,38 @@ exports.ContextualiserContext = langgraph_1.Annotation.Root({
|
|
|
7
7
|
default: () => undefined,
|
|
8
8
|
reducer: (current) => current,
|
|
9
9
|
}),
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Cost attribution INHERITED from the calling agent. The contextualiser is a
|
|
12
|
+
// sub-agent: it never bills on its own behalf, so it carries the caller's
|
|
13
|
+
// ledger category and the caller's entity and applies them at every LLM call
|
|
14
|
+
// it makes. All four are absent when a consumer drives the contextualiser
|
|
15
|
+
// directly without attribution — its spend is then simply not recorded.
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/** Ledger category of the CALLING agent, e.g. `TokenUsageType.Responder`. */
|
|
18
|
+
tokenUsageType: (0, langgraph_1.Annotation)({
|
|
19
|
+
default: () => undefined,
|
|
20
|
+
reducer: (current, update) => update ?? current,
|
|
21
|
+
}),
|
|
22
|
+
/** Id of the caller's scope-root node. Absent = the caller ran unscoped. */
|
|
23
|
+
scopeId: (0, langgraph_1.Annotation)({
|
|
24
|
+
default: () => undefined,
|
|
25
|
+
reducer: (current, update) => update ?? current,
|
|
26
|
+
}),
|
|
27
|
+
/** JSON:API type of the caller's scope root, e.g. "campaigns". */
|
|
28
|
+
scopeType: (0, langgraph_1.Annotation)({
|
|
29
|
+
default: () => undefined,
|
|
30
|
+
reducer: (current, update) => update ?? current,
|
|
31
|
+
}),
|
|
32
|
+
/** Neo4j label of the caller's scope root, e.g. "Campaign". */
|
|
33
|
+
scopeLabel: (0, langgraph_1.Annotation)({
|
|
34
|
+
default: () => undefined,
|
|
35
|
+
reducer: (current, update) => update ?? current,
|
|
36
|
+
}),
|
|
37
|
+
/** Id of the caller's `Assistant` (thread) node — the unscoped fallback. */
|
|
38
|
+
assistantId: (0, langgraph_1.Annotation)({
|
|
39
|
+
default: () => undefined,
|
|
40
|
+
reducer: (current, update) => update ?? current,
|
|
41
|
+
}),
|
|
10
42
|
contentId: (0, langgraph_1.Annotation)({
|
|
11
43
|
default: () => undefined,
|
|
12
44
|
reducer: (current) => current,
|