@carlonicora/nestjs-neo4jsonapi 2.3.1 → 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.
Files changed (216) hide show
  1. package/dist/agents/common/usage-attribution.d.ts +218 -0
  2. package/dist/agents/common/usage-attribution.d.ts.map +1 -0
  3. package/dist/agents/common/usage-attribution.js +235 -0
  4. package/dist/agents/common/usage-attribution.js.map +1 -0
  5. package/dist/agents/community.summariser/services/community.summariser.service.d.ts.map +1 -1
  6. package/dist/agents/community.summariser/services/community.summariser.service.js +13 -1
  7. package/dist/agents/community.summariser/services/community.summariser.service.js.map +1 -1
  8. package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts +24 -1
  9. package/dist/agents/contextualiser/contexts/contextualiser.context.d.ts.map +1 -1
  10. package/dist/agents/contextualiser/contexts/contextualiser.context.js +32 -0
  11. package/dist/agents/contextualiser/contexts/contextualiser.context.js.map +1 -1
  12. package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts +7 -0
  13. package/dist/agents/contextualiser/factories/contextualiser.context.factory.d.ts.map +1 -1
  14. package/dist/agents/contextualiser/factories/contextualiser.context.factory.js +5 -0
  15. package/dist/agents/contextualiser/factories/contextualiser.context.factory.js.map +1 -1
  16. package/dist/agents/contextualiser/nodes/atomicfacts.node.service.d.ts.map +1 -1
  17. package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js +4 -0
  18. package/dist/agents/contextualiser/nodes/atomicfacts.node.service.js.map +1 -1
  19. package/dist/agents/contextualiser/nodes/chunk.node.service.d.ts.map +1 -1
  20. package/dist/agents/contextualiser/nodes/chunk.node.service.js +4 -0
  21. package/dist/agents/contextualiser/nodes/chunk.node.service.js.map +1 -1
  22. package/dist/agents/contextualiser/nodes/chunk.vector.node.service.d.ts.map +1 -1
  23. package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js +15 -0
  24. package/dist/agents/contextualiser/nodes/chunk.vector.node.service.js.map +1 -1
  25. package/dist/agents/contextualiser/nodes/keyconcepts.node.service.d.ts.map +1 -1
  26. package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js +11 -0
  27. package/dist/agents/contextualiser/nodes/keyconcepts.node.service.js.map +1 -1
  28. package/dist/agents/contextualiser/nodes/question.refiner.node.service.d.ts.map +1 -1
  29. package/dist/agents/contextualiser/nodes/question.refiner.node.service.js +4 -0
  30. package/dist/agents/contextualiser/nodes/question.refiner.node.service.js.map +1 -1
  31. package/dist/agents/contextualiser/nodes/rational.node.service.d.ts.map +1 -1
  32. package/dist/agents/contextualiser/nodes/rational.node.service.js +4 -0
  33. package/dist/agents/contextualiser/nodes/rational.node.service.js.map +1 -1
  34. package/dist/agents/contextualiser/services/contextualiser.service.d.ts +7 -0
  35. package/dist/agents/contextualiser/services/contextualiser.service.d.ts.map +1 -1
  36. package/dist/agents/contextualiser/services/contextualiser.service.js +17 -5
  37. package/dist/agents/contextualiser/services/contextualiser.service.js.map +1 -1
  38. package/dist/agents/drift/contexts/drift.context.d.ts +25 -1
  39. package/dist/agents/drift/contexts/drift.context.d.ts.map +1 -1
  40. package/dist/agents/drift/contexts/drift.context.js +32 -0
  41. package/dist/agents/drift/contexts/drift.context.js.map +1 -1
  42. package/dist/agents/drift/nodes/followup.node.service.d.ts.map +1 -1
  43. package/dist/agents/drift/nodes/followup.node.service.js +4 -0
  44. package/dist/agents/drift/nodes/followup.node.service.js.map +1 -1
  45. package/dist/agents/drift/nodes/hyde.node.service.d.ts.map +1 -1
  46. package/dist/agents/drift/nodes/hyde.node.service.js +9 -1
  47. package/dist/agents/drift/nodes/hyde.node.service.js.map +1 -1
  48. package/dist/agents/drift/nodes/primer.answer.node.service.d.ts.map +1 -1
  49. package/dist/agents/drift/nodes/primer.answer.node.service.js +4 -0
  50. package/dist/agents/drift/nodes/primer.answer.node.service.js.map +1 -1
  51. package/dist/agents/drift/nodes/synthesis.node.service.d.ts.map +1 -1
  52. package/dist/agents/drift/nodes/synthesis.node.service.js +4 -0
  53. package/dist/agents/drift/nodes/synthesis.node.service.js.map +1 -1
  54. package/dist/agents/drift/services/drift.search.service.d.ts +9 -0
  55. package/dist/agents/drift/services/drift.search.service.d.ts.map +1 -1
  56. package/dist/agents/drift/services/drift.search.service.js +22 -5
  57. package/dist/agents/drift/services/drift.search.service.js.map +1 -1
  58. package/dist/agents/graph/services/graph.search.service.d.ts.map +1 -1
  59. package/dist/agents/graph/services/graph.search.service.js +10 -1
  60. package/dist/agents/graph/services/graph.search.service.js.map +1 -1
  61. package/dist/agents/graph/tools/tool.factory.d.ts +6 -0
  62. package/dist/agents/graph/tools/tool.factory.d.ts.map +1 -1
  63. package/dist/agents/graph/tools/tool.factory.js.map +1 -1
  64. package/dist/agents/index.d.ts +1 -0
  65. package/dist/agents/index.d.ts.map +1 -1
  66. package/dist/agents/index.js.map +1 -1
  67. package/dist/agents/operator/contexts/operator.context.d.ts +37 -1
  68. package/dist/agents/operator/contexts/operator.context.d.ts.map +1 -1
  69. package/dist/agents/operator/contexts/operator.context.js +8 -0
  70. package/dist/agents/operator/contexts/operator.context.js.map +1 -1
  71. package/dist/agents/operator/interfaces/operator.tool.interface.d.ts +8 -0
  72. package/dist/agents/operator/interfaces/operator.tool.interface.d.ts.map +1 -1
  73. package/dist/agents/operator/interfaces/operator.tool.interface.js.map +1 -1
  74. package/dist/agents/operator/services/operator.service.d.ts +8 -0
  75. package/dist/agents/operator/services/operator.service.d.ts.map +1 -1
  76. package/dist/agents/operator/services/operator.service.js +29 -0
  77. package/dist/agents/operator/services/operator.service.js.map +1 -1
  78. package/dist/agents/operator/tools/operator.tool.registry.d.ts.map +1 -1
  79. package/dist/agents/operator/tools/operator.tool.registry.js +2 -1
  80. package/dist/agents/operator/tools/operator.tool.registry.js.map +1 -1
  81. package/dist/agents/operator/tools/search-communities.tool.d.ts +8 -2
  82. package/dist/agents/operator/tools/search-communities.tool.d.ts.map +1 -1
  83. package/dist/agents/operator/tools/search-communities.tool.js +16 -4
  84. package/dist/agents/operator/tools/search-communities.tool.js.map +1 -1
  85. package/dist/agents/operator/tools/search-documents.tool.d.ts.map +1 -1
  86. package/dist/agents/operator/tools/search-documents.tool.js +5 -0
  87. package/dist/agents/operator/tools/search-documents.tool.js.map +1 -1
  88. package/dist/agents/responder/contexts/responder.context.d.ts +31 -0
  89. package/dist/agents/responder/contexts/responder.context.d.ts.map +1 -1
  90. package/dist/agents/responder/contexts/responder.context.js +8 -0
  91. package/dist/agents/responder/contexts/responder.context.js.map +1 -1
  92. package/dist/agents/responder/factories/responder.context.factory.d.ts +4 -0
  93. package/dist/agents/responder/factories/responder.context.factory.d.ts.map +1 -1
  94. package/dist/agents/responder/factories/responder.context.factory.js +2 -0
  95. package/dist/agents/responder/factories/responder.context.factory.js.map +1 -1
  96. package/dist/agents/responder/nodes/graph.node.service.d.ts +6 -0
  97. package/dist/agents/responder/nodes/graph.node.service.d.ts.map +1 -1
  98. package/dist/agents/responder/nodes/graph.node.service.js +20 -0
  99. package/dist/agents/responder/nodes/graph.node.service.js.map +1 -1
  100. package/dist/agents/responder/nodes/planner.node.service.d.ts.map +1 -1
  101. package/dist/agents/responder/nodes/planner.node.service.js +9 -0
  102. package/dist/agents/responder/nodes/planner.node.service.js.map +1 -1
  103. package/dist/agents/responder/nodes/responder.answer.node.service.d.ts.map +1 -1
  104. package/dist/agents/responder/nodes/responder.answer.node.service.js +9 -0
  105. package/dist/agents/responder/nodes/responder.answer.node.service.js.map +1 -1
  106. package/dist/agents/responder/services/responder.service.d.ts +16 -0
  107. package/dist/agents/responder/services/responder.service.d.ts.map +1 -1
  108. package/dist/agents/responder/services/responder.service.js +29 -5
  109. package/dist/agents/responder/services/responder.service.js.map +1 -1
  110. package/dist/agents/summariser/services/summariser.service.d.ts +7 -0
  111. package/dist/agents/summariser/services/summariser.service.d.ts.map +1 -1
  112. package/dist/agents/summariser/services/summariser.service.js +15 -3
  113. package/dist/agents/summariser/services/summariser.service.js.map +1 -1
  114. package/dist/common/helpers/index.d.ts +1 -0
  115. package/dist/common/helpers/index.d.ts.map +1 -1
  116. package/dist/common/helpers/index.js +1 -0
  117. package/dist/common/helpers/index.js.map +1 -1
  118. package/dist/common/helpers/map-with-concurrency.d.ts +23 -0
  119. package/dist/common/helpers/map-with-concurrency.d.ts.map +1 -0
  120. package/dist/common/helpers/map-with-concurrency.js +60 -0
  121. package/dist/common/helpers/map-with-concurrency.js.map +1 -0
  122. package/dist/common/tokens.d.ts +2 -1
  123. package/dist/common/tokens.d.ts.map +1 -1
  124. package/dist/common/tokens.js +2 -1
  125. package/dist/common/tokens.js.map +1 -1
  126. package/dist/config/base.config.d.ts +19 -0
  127. package/dist/config/base.config.d.ts.map +1 -1
  128. package/dist/config/base.config.js +30 -3
  129. package/dist/config/base.config.js.map +1 -1
  130. package/dist/config/interfaces/config.ai.interface.d.ts +10 -1
  131. package/dist/config/interfaces/config.ai.interface.d.ts.map +1 -1
  132. package/dist/config/interfaces/config.chunk.queues.interface.d.ts +13 -0
  133. package/dist/config/interfaces/config.chunk.queues.interface.d.ts.map +1 -1
  134. package/dist/config/interfaces/config.credits.interface.d.ts +1 -1
  135. package/dist/core/llm/services/audio.llm.service.d.ts +70 -1
  136. package/dist/core/llm/services/audio.llm.service.d.ts.map +1 -1
  137. package/dist/core/llm/services/audio.llm.service.js +118 -3
  138. package/dist/core/llm/services/audio.llm.service.js.map +1 -1
  139. package/dist/core/llm/services/document-ai.service.d.ts +6 -0
  140. package/dist/core/llm/services/document-ai.service.d.ts.map +1 -1
  141. package/dist/core/llm/services/document-ai.service.js +1 -0
  142. package/dist/core/llm/services/document-ai.service.js.map +1 -1
  143. package/dist/core/llm/services/embedder.service.d.ts +105 -0
  144. package/dist/core/llm/services/embedder.service.d.ts.map +1 -1
  145. package/dist/core/llm/services/embedder.service.js +237 -7
  146. package/dist/core/llm/services/embedder.service.js.map +1 -1
  147. package/dist/core/llm/services/llm.service.d.ts +103 -6
  148. package/dist/core/llm/services/llm.service.d.ts.map +1 -1
  149. package/dist/core/llm/services/llm.service.js +570 -148
  150. package/dist/core/llm/services/llm.service.js.map +1 -1
  151. package/dist/core/llm/services/model.service.d.ts +25 -0
  152. package/dist/core/llm/services/model.service.d.ts.map +1 -1
  153. package/dist/core/llm/services/model.service.js +76 -4
  154. package/dist/core/llm/services/model.service.js.map +1 -1
  155. package/dist/core/llm/utils/repair-truncated-json.d.ts +29 -0
  156. package/dist/core/llm/utils/repair-truncated-json.d.ts.map +1 -0
  157. package/dist/core/llm/utils/repair-truncated-json.js +111 -0
  158. package/dist/core/llm/utils/repair-truncated-json.js.map +1 -0
  159. package/dist/foundations/assistant/services/assistant.service.d.ts.map +1 -1
  160. package/dist/foundations/assistant/services/assistant.service.js +12 -0
  161. package/dist/foundations/assistant/services/assistant.service.js.map +1 -1
  162. package/dist/foundations/atomicfact/services/atomicfact.service.d.ts +7 -0
  163. package/dist/foundations/atomicfact/services/atomicfact.service.d.ts.map +1 -1
  164. package/dist/foundations/atomicfact/services/atomicfact.service.js +6 -0
  165. package/dist/foundations/atomicfact/services/atomicfact.service.js.map +1 -1
  166. package/dist/foundations/chunk/processors/chunk.processor.d.ts.map +1 -1
  167. package/dist/foundations/chunk/processors/chunk.processor.js +7 -1
  168. package/dist/foundations/chunk/processors/chunk.processor.js.map +1 -1
  169. package/dist/foundations/chunk/repositories/chunk.repository.d.ts +90 -2
  170. package/dist/foundations/chunk/repositories/chunk.repository.d.ts.map +1 -1
  171. package/dist/foundations/chunk/repositories/chunk.repository.js +205 -31
  172. package/dist/foundations/chunk/repositories/chunk.repository.js.map +1 -1
  173. package/dist/foundations/chunk/services/chunk.service.d.ts.map +1 -1
  174. package/dist/foundations/chunk/services/chunk.service.js +50 -1
  175. package/dist/foundations/chunk/services/chunk.service.js.map +1 -1
  176. package/dist/foundations/chunker/chunker.module.d.ts.map +1 -1
  177. package/dist/foundations/chunker/chunker.module.js +4 -1
  178. package/dist/foundations/chunker/chunker.module.js.map +1 -1
  179. package/dist/foundations/chunker/services/chunker.service.d.ts +57 -1
  180. package/dist/foundations/chunker/services/chunker.service.d.ts.map +1 -1
  181. package/dist/foundations/chunker/services/chunker.service.js +207 -16
  182. package/dist/foundations/chunker/services/chunker.service.js.map +1 -1
  183. package/dist/foundations/chunker/services/types/pdf.service.d.ts +42 -1
  184. package/dist/foundations/chunker/services/types/pdf.service.d.ts.map +1 -1
  185. package/dist/foundations/chunker/services/types/pdf.service.js +111 -22
  186. package/dist/foundations/chunker/services/types/pdf.service.js.map +1 -1
  187. package/dist/foundations/chunker/services/types/semanticsplitter.service.d.ts.map +1 -1
  188. package/dist/foundations/chunker/services/types/semanticsplitter.service.js +24 -3
  189. package/dist/foundations/chunker/services/types/semanticsplitter.service.js.map +1 -1
  190. package/dist/foundations/company/repositories/company.repository.d.ts +1 -1
  191. package/dist/foundations/company/repositories/company.repository.d.ts.map +1 -1
  192. package/dist/foundations/company/repositories/company.repository.js +31 -14
  193. package/dist/foundations/company/repositories/company.repository.js.map +1 -1
  194. package/dist/foundations/how-to/processors/how-to.processor.d.ts.map +1 -1
  195. package/dist/foundations/how-to/processors/how-to.processor.js +20 -7
  196. package/dist/foundations/how-to/processors/how-to.processor.js.map +1 -1
  197. package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts +25 -1
  198. package/dist/foundations/keyconcept/repositories/keyconcept.repository.d.ts.map +1 -1
  199. package/dist/foundations/keyconcept/repositories/keyconcept.repository.js +38 -2
  200. package/dist/foundations/keyconcept/repositories/keyconcept.repository.js.map +1 -1
  201. package/dist/foundations/keyconcept/services/keyconcept.service.d.ts +5 -0
  202. package/dist/foundations/keyconcept/services/keyconcept.service.d.ts.map +1 -1
  203. package/dist/foundations/keyconcept/services/keyconcept.service.js +4 -0
  204. package/dist/foundations/keyconcept/services/keyconcept.service.js.map +1 -1
  205. package/dist/foundations/tokenusage/entities/tokenusage.js +1 -1
  206. package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts +4 -1
  207. package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts.map +1 -1
  208. package/dist/foundations/tokenusage/enums/tokenusage.type.js +3 -0
  209. package/dist/foundations/tokenusage/enums/tokenusage.type.js.map +1 -1
  210. package/dist/foundations/tokenusage/repositories/tokenusage.admin.repository.js +3 -3
  211. package/dist/foundations/tokenusage/repositories/tokenusage.repository.js +2 -2
  212. package/dist/foundations/tokenusage/services/tokenusage.service.d.ts +6 -1
  213. package/dist/foundations/tokenusage/services/tokenusage.service.d.ts.map +1 -1
  214. package/dist/foundations/tokenusage/services/tokenusage.service.js +7 -2
  215. package/dist/foundations/tokenusage/services/tokenusage.service.js.map +1 -1
  216. 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;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kEAAkE,CAAC;AAEvG,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;CAkE3D"}
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;AAE1F,QAAA,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BrB,CAAC;AAEF,MAAM,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qEAAqE,CAAC;IACjG,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IACpF,MAAM,EAAE,OAAC;SACN,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,CAAC,2EAA2E,CAAC;CACzF,CAAC,CAAC;AAEH,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3B,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;IAC1F,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IAC5E,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IAClF,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;CACzE,CAAC,CAAC;AAGI,IAAM,0BAA0B,GAAhC,MAAM,0BAA0B;IAGrC,YACmB,UAAsB,EACtB,eAAgC,EAChC,mBAAwC,EACxC,MAAyB,EACzB,aAAiD;QAJjD,eAAU,GAAV,UAAU,CAAY;QACtB,oBAAe,GAAf,eAAe,CAAiB;QAChC,wBAAmB,GAAnB,mBAAmB,CAAqB;QACxC,WAAM,GAAN,MAAM,CAAmB;QACzB,kBAAa,GAAb,aAAa,CAAoC;QAElE,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAyB,SAAS,CAAC,CAAC;QAC1E,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,mBAAmB,IAAI,cAAM,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,mBAAmB,CAAC,WAAmB;QAC3C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,WAAW,sBAAsB,EAAE,4BAA4B,CAAC,CAAC;YAC/F,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,SAAoB;QACxC,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,oCAAoC,SAAS,CAAC,EAAE,YAAY,SAAS,CAAC,KAAK,GAAG,EAC9E,4BAA4B,CAC7B,CAAC;QAEF,6CAA6C;QAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAEnF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,SAAS,CAAC,EAAE,2BAA2B,EAAE,4BAA4B,CAAC,CAAC;YACrG,OAAO;QACT,CAAC;QAED,sCAAsC;QACtC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,uBAAuB,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAE3F,0BAA0B;QAC1B,MAAM,YAAY,GAAG,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,KAAK,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC;QAC/B,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,+BAA+B;QAC/B,MAAM,iBAAiB,GACrB,aAAa,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,WAAW,QAAQ,CAAC,CAAC,WAAW,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACtG,CAAC,CAAC,4CAA4C,CAAC;QAEnD,+BAA+B;QAC/B,MAAM,WAAW,GAAgC;YAC/C,QAAQ,EAAE,YAAY;YACtB,aAAa,EAAE,iBAAiB;YAChC,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,WAAW,EAAE,OAAO,CAAC,MAAM;SAC5B,CAAC;QAEF,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAA+B;YAC3E,WAAW;YACX,WAAW;YACX,YAAY;YACZ,aAAa,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;YAClC,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QAEH,qCAAqC;QACrC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC;YACzD,IAAI,EAAE,GAAG,WAAW,CAAC,KAAK,OAAO,WAAW,CAAC,OAAO,EAAE;SACvD,CAAC,CAAC;QAEH,kDAAkD;QAClD,MAAM,IAAI,CAAC,mBAAmB,CAAC,aAAa,CAAC;YAC3C,WAAW,EAAE,SAAS,CAAC,EAAE;YACzB,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC;YACxC,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;SACvC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,mCAAmC,SAAS,CAAC,EAAE,MAAM,WAAW,CAAC,KAAK,cAAc,WAAW,CAAC,MAAM,GAAG,EACzG,4BAA4B,CAC7B,CAAC;IACJ,CAAC;CACF,CAAA;AA/FY,gEAA0B;qCAA1B,0BAA0B;IADtC,IAAA,mBAAU,GAAE;qCAKoB,wBAAU;QACL,sBAAe;QACX,0CAAmB;QAChC,mCAAiB;QACV,sBAAa;GARpC,0BAA0B,CA+FtC"}
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
- export type ContextualiserContextState = typeof ContextualiserContext.State;
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;AAE/D,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0LhC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,OAAO,qBAAqB,CAAC,KAAK,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,