@digital-science-dsl/dimensions-analytics-mcp 0.5.3 → 1.0.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 (218) hide show
  1. package/CHANGELOG.md +2 -58
  2. package/README.md +1 -5
  3. package/dist/client/deployment-config.d.ts +20 -2
  4. package/dist/client/deployment-config.d.ts.map +1 -1
  5. package/dist/client/deployment-config.js +26 -2
  6. package/dist/client/deployment-config.js.map +1 -1
  7. package/dist/client/internal-dsl-client.d.ts +1 -1
  8. package/dist/client/internal-dsl-client.d.ts.map +1 -1
  9. package/dist/client/internal-dsl-client.js +2 -5
  10. package/dist/client/internal-dsl-client.js.map +1 -1
  11. package/dist/dsl/create-client.d.ts +1 -1
  12. package/dist/dsl/create-client.js +1 -1
  13. package/dist/dsl/fluent-query-builder.d.ts +1 -1
  14. package/dist/dsl/fluent-query-builder.js +1 -1
  15. package/dist/dsl/schema/cache.d.ts +2 -2
  16. package/dist/dsl/schema/cache.d.ts.map +1 -1
  17. package/dist/dsl/schema/cache.js +8 -14
  18. package/dist/dsl/schema/cache.js.map +1 -1
  19. package/dist/dsl/schema/load.d.ts +0 -1
  20. package/dist/dsl/schema/load.d.ts.map +1 -1
  21. package/dist/dsl/schema/load.js +1 -3
  22. package/dist/dsl/schema/load.js.map +1 -1
  23. package/dist/mcp/tools/schema.d.ts +0 -2
  24. package/dist/mcp/tools/schema.d.ts.map +1 -1
  25. package/dist/mcp/tools/schema.js.map +1 -1
  26. package/dist/mcp/utils.d.ts +0 -4
  27. package/dist/mcp/utils.d.ts.map +1 -1
  28. package/dist/mcp/utils.js +0 -7
  29. package/dist/mcp/utils.js.map +1 -1
  30. package/package.json +1 -1
  31. package/src/client/deployment-config.ts +39 -2
  32. package/src/client/internal-dsl-client.ts +2 -6
  33. package/src/dsl/create-client.ts +1 -1
  34. package/src/dsl/fluent-query-builder.ts +1 -1
  35. package/src/dsl/schema/cache.ts +8 -13
  36. package/src/dsl/schema/load.ts +1 -4
  37. package/src/mcp/tools/schema.ts +0 -3
  38. package/src/mcp/utils.ts +0 -12
  39. package/test/client/deployment-config.test.ts +25 -1
  40. package/test/client/http-client.test.ts +2 -2
  41. package/test/client/internal-dsl-client.test.ts +3 -0
  42. package/test/dsl/schema/cache.test.ts +2 -4
  43. package/test/helpers/tool-test-harness.ts +2 -19
  44. package/test/middleware/field-aliases.test.ts +1 -1
  45. package/test/tools/analytics.test.ts +2 -2
  46. package/tsconfig.tsbuildinfo +1 -1
  47. package/dist/examples/dsl-examples.d.ts +0 -11
  48. package/dist/examples/dsl-examples.d.ts.map +0 -1
  49. package/dist/examples/dsl-examples.js +0 -49
  50. package/dist/examples/dsl-examples.js.map +0 -1
  51. package/dist/examples/usage-scenarios.d.ts +0 -22
  52. package/dist/examples/usage-scenarios.d.ts.map +0 -1
  53. package/dist/examples/usage-scenarios.js +0 -173
  54. package/dist/examples/usage-scenarios.js.map +0 -1
  55. package/dist/funder-org-names.d.ts +0 -12
  56. package/dist/funder-org-names.d.ts.map +0 -1
  57. package/dist/funder-org-names.js +0 -30
  58. package/dist/funder-org-names.js.map +0 -1
  59. package/dist/http.d.ts +0 -29
  60. package/dist/http.d.ts.map +0 -1
  61. package/dist/http.js +0 -173
  62. package/dist/http.js.map +0 -1
  63. package/dist/kwq/build-query.d.ts +0 -26
  64. package/dist/kwq/build-query.d.ts.map +0 -1
  65. package/dist/kwq/build-query.js +0 -37
  66. package/dist/kwq/build-query.js.map +0 -1
  67. package/dist/kwq/concept-groups.d.ts +0 -49
  68. package/dist/kwq/concept-groups.d.ts.map +0 -1
  69. package/dist/kwq/concept-groups.js +0 -55
  70. package/dist/kwq/concept-groups.js.map +0 -1
  71. package/dist/kwq/dsl-assembler.d.ts +0 -28
  72. package/dist/kwq/dsl-assembler.d.ts.map +0 -1
  73. package/dist/kwq/dsl-assembler.js +0 -124
  74. package/dist/kwq/dsl-assembler.js.map +0 -1
  75. package/dist/kwq/ensemble.d.ts +0 -38
  76. package/dist/kwq/ensemble.d.ts.map +0 -1
  77. package/dist/kwq/ensemble.js +0 -107
  78. package/dist/kwq/ensemble.js.map +0 -1
  79. package/dist/kwq/index.d.ts +0 -16
  80. package/dist/kwq/index.d.ts.map +0 -1
  81. package/dist/kwq/index.js +0 -14
  82. package/dist/kwq/index.js.map +0 -1
  83. package/dist/kwq/types.d.ts +0 -120
  84. package/dist/kwq/types.d.ts.map +0 -1
  85. package/dist/kwq/types.js +0 -11
  86. package/dist/kwq/types.js.map +0 -1
  87. package/dist/lambda.d.ts +0 -10
  88. package/dist/lambda.d.ts.map +0 -1
  89. package/dist/lambda.js +0 -4
  90. package/dist/lambda.js.map +0 -1
  91. package/dist/mcp/tools/concept-profile.d.ts +0 -14
  92. package/dist/mcp/tools/concept-profile.d.ts.map +0 -1
  93. package/dist/mcp/tools/concept-profile.js +0 -130
  94. package/dist/mcp/tools/concept-profile.js.map +0 -1
  95. package/dist/mcp/tools/dataset-profile.d.ts +0 -15
  96. package/dist/mcp/tools/dataset-profile.d.ts.map +0 -1
  97. package/dist/mcp/tools/dataset-profile.js +0 -194
  98. package/dist/mcp/tools/dataset-profile.js.map +0 -1
  99. package/dist/mcp/tools/impact-chain.d.ts +0 -15
  100. package/dist/mcp/tools/impact-chain.d.ts.map +0 -1
  101. package/dist/mcp/tools/impact-chain.js +0 -96
  102. package/dist/mcp/tools/impact-chain.js.map +0 -1
  103. package/dist/mcp/tools/kwq.d.ts +0 -19
  104. package/dist/mcp/tools/kwq.d.ts.map +0 -1
  105. package/dist/mcp/tools/kwq.js +0 -156
  106. package/dist/mcp/tools/kwq.js.map +0 -1
  107. package/dist/mcp/tools/policy-profile.d.ts +0 -15
  108. package/dist/mcp/tools/policy-profile.d.ts.map +0 -1
  109. package/dist/mcp/tools/policy-profile.js +0 -174
  110. package/dist/mcp/tools/policy-profile.js.map +0 -1
  111. package/dist/mcp/tools/profile.d.ts +0 -14
  112. package/dist/mcp/tools/profile.d.ts.map +0 -1
  113. package/dist/mcp/tools/profile.js +0 -349
  114. package/dist/mcp/tools/profile.js.map +0 -1
  115. package/dist/middleware/field-aliases.d.ts +0 -97
  116. package/dist/middleware/field-aliases.d.ts.map +0 -1
  117. package/dist/middleware/field-aliases.js +0 -208
  118. package/dist/middleware/field-aliases.js.map +0 -1
  119. package/dist/resources/schema.d.ts +0 -13
  120. package/dist/resources/schema.d.ts.map +0 -1
  121. package/dist/resources/schema.js +0 -204
  122. package/dist/resources/schema.js.map +0 -1
  123. package/dist/schema/context.d.ts +0 -10
  124. package/dist/schema/context.d.ts.map +0 -1
  125. package/dist/schema/context.js +0 -6
  126. package/dist/schema/context.js.map +0 -1
  127. package/dist/schema/index.d.ts +0 -9
  128. package/dist/schema/index.d.ts.map +0 -1
  129. package/dist/schema/index.js +0 -6
  130. package/dist/schema/index.js.map +0 -1
  131. package/dist/schema/load.d.ts +0 -43
  132. package/dist/schema/load.d.ts.map +0 -1
  133. package/dist/schema/load.js +0 -139
  134. package/dist/schema/load.js.map +0 -1
  135. package/dist/schema/store.d.ts +0 -112
  136. package/dist/schema/store.d.ts.map +0 -1
  137. package/dist/schema/store.js +0 -173
  138. package/dist/schema/store.js.map +0 -1
  139. package/dist/schema/structured-entities.d.ts +0 -21
  140. package/dist/schema/structured-entities.d.ts.map +0 -1
  141. package/dist/schema/structured-entities.js +0 -39
  142. package/dist/schema/structured-entities.js.map +0 -1
  143. package/dist/schema/types.d.ts +0 -36
  144. package/dist/schema/types.d.ts.map +0 -1
  145. package/dist/schema/types.js +0 -6
  146. package/dist/schema/types.js.map +0 -1
  147. package/dist/server.d.ts +0 -57
  148. package/dist/server.d.ts.map +0 -1
  149. package/dist/server.js +0 -144
  150. package/dist/server.js.map +0 -1
  151. package/dist/telemetry.d.ts +0 -172
  152. package/dist/telemetry.d.ts.map +0 -1
  153. package/dist/telemetry.js +0 -233
  154. package/dist/telemetry.js.map +0 -1
  155. package/dist/tools/analytics-filters.d.ts +0 -18
  156. package/dist/tools/analytics-filters.d.ts.map +0 -1
  157. package/dist/tools/analytics-filters.js +0 -35
  158. package/dist/tools/analytics-filters.js.map +0 -1
  159. package/dist/tools/analytics.d.ts +0 -16
  160. package/dist/tools/analytics.d.ts.map +0 -1
  161. package/dist/tools/analytics.js +0 -381
  162. package/dist/tools/analytics.js.map +0 -1
  163. package/dist/tools/concept-profile.d.ts +0 -14
  164. package/dist/tools/concept-profile.d.ts.map +0 -1
  165. package/dist/tools/concept-profile.js +0 -130
  166. package/dist/tools/concept-profile.js.map +0 -1
  167. package/dist/tools/dataset-profile.d.ts +0 -15
  168. package/dist/tools/dataset-profile.d.ts.map +0 -1
  169. package/dist/tools/dataset-profile.js +0 -194
  170. package/dist/tools/dataset-profile.js.map +0 -1
  171. package/dist/tools/functions.d.ts +0 -14
  172. package/dist/tools/functions.d.ts.map +0 -1
  173. package/dist/tools/functions.js +0 -294
  174. package/dist/tools/functions.js.map +0 -1
  175. package/dist/tools/impact-chain.d.ts +0 -15
  176. package/dist/tools/impact-chain.d.ts.map +0 -1
  177. package/dist/tools/impact-chain.js +0 -96
  178. package/dist/tools/impact-chain.js.map +0 -1
  179. package/dist/tools/kwq.d.ts +0 -19
  180. package/dist/tools/kwq.d.ts.map +0 -1
  181. package/dist/tools/kwq.js +0 -156
  182. package/dist/tools/kwq.js.map +0 -1
  183. package/dist/tools/lookup.d.ts +0 -14
  184. package/dist/tools/lookup.d.ts.map +0 -1
  185. package/dist/tools/lookup.js +0 -213
  186. package/dist/tools/lookup.js.map +0 -1
  187. package/dist/tools/policy-profile.d.ts +0 -15
  188. package/dist/tools/policy-profile.d.ts.map +0 -1
  189. package/dist/tools/policy-profile.js +0 -174
  190. package/dist/tools/policy-profile.js.map +0 -1
  191. package/dist/tools/profile.d.ts +0 -14
  192. package/dist/tools/profile.d.ts.map +0 -1
  193. package/dist/tools/profile.js +0 -349
  194. package/dist/tools/profile.js.map +0 -1
  195. package/dist/tools/query.d.ts +0 -16
  196. package/dist/tools/query.d.ts.map +0 -1
  197. package/dist/tools/query.js +0 -53
  198. package/dist/tools/query.js.map +0 -1
  199. package/dist/tools/schema.d.ts +0 -23
  200. package/dist/tools/schema.d.ts.map +0 -1
  201. package/dist/tools/schema.js +0 -124
  202. package/dist/tools/schema.js.map +0 -1
  203. package/dist/tools/search-entity-metadata.d.ts +0 -18
  204. package/dist/tools/search-entity-metadata.d.ts.map +0 -1
  205. package/dist/tools/search-entity-metadata.js +0 -221
  206. package/dist/tools/search-entity-metadata.js.map +0 -1
  207. package/dist/tools/search.d.ts +0 -23
  208. package/dist/tools/search.d.ts.map +0 -1
  209. package/dist/tools/search.js +0 -110
  210. package/dist/tools/search.js.map +0 -1
  211. package/dist/tools/solr-fields.d.ts +0 -39
  212. package/dist/tools/solr-fields.d.ts.map +0 -1
  213. package/dist/tools/solr-fields.js +0 -40
  214. package/dist/tools/solr-fields.js.map +0 -1
  215. package/dist/utils.d.ts +0 -70
  216. package/dist/utils.d.ts.map +0 -1
  217. package/dist/utils.js +0 -104
  218. package/dist/utils.js.map +0 -1
package/dist/http.js DELETED
@@ -1,173 +0,0 @@
1
- /**
2
- * HTTP entry point for the Dimensions MCP server.
3
- *
4
- * Callers authenticate with their Dimensions API key — the same credential
5
- * used for DSL API requests. Pass it on each `/mcp` POST as:
6
- *
7
- * - `Authorization: Bearer <dimensions-api-key>`, or
8
- * - `X-Dimensions-Api-Key: <dimensions-api-key>`
9
- *
10
- * The server exchanges the key for a JWT via Dimensions `auth.json` and
11
- * forwards queries upstream; keys are not stored server-side.
12
- * @module mcp/http
13
- */
14
- import { createHash, randomUUID } from "node:crypto";
15
- import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
16
- import { Hono } from "hono";
17
- import { html, raw } from "hono/html";
18
- import pkg from "../package.json";
19
- import { createMcpServerAsync } from "./server.js";
20
- import { getCachedSchemaStore } from "./schema/index.js";
21
- import { createTelemetry, initMixpanelClient } from "./telemetry.js";
22
- /** Shared Mixpanel client. Opt-in via `MIXPANEL_TOKEN`. */
23
- const MIXPANEL_CLIENT = initMixpanelClient(process.env.MIXPANEL_TOKEN, process.env.MIXPANEL_HOST);
24
- /** Optional stage label attached to telemetry events. */
25
- const TELEMETRY_STAGE = process.env.SST_STAGE;
26
- /** Public URL of this deployment (for setup page snippets only). */
27
- const MCP_PUBLIC_URL = (process.env.MCP_PUBLIC_URL ?? "").replace(/\/$/, "");
28
- /**
29
- * Extracts a Dimensions API key from request headers.
30
- * @param authorization - Raw Authorization header value
31
- * @param dimensionsApiKey - Raw X-Dimensions-Api-Key header value
32
- * @returns API key or null when missing
33
- */
34
- export function extractDimensionsApiKey(authorization, dimensionsApiKey) {
35
- const bearer = authorization ?? "";
36
- if (bearer.startsWith("Bearer ")) {
37
- const token = bearer.slice("Bearer ".length).trim();
38
- if (token.length > 0)
39
- return token;
40
- }
41
- const headerKey = dimensionsApiKey?.trim();
42
- if (headerKey && headerKey.length > 0)
43
- return headerKey;
44
- return null;
45
- }
46
- /**
47
- * Derives a stable, non-reversible telemetry distinct id from an API key.
48
- * @param apiKey - Dimensions API key
49
- * @returns Hex prefix of SHA-256 hash
50
- */
51
- export function telemetryDistinctId(apiKey) {
52
- return createHash("sha256").update(apiKey).digest("hex").slice(0, 16);
53
- }
54
- function wwwAuthenticate() {
55
- return 'Bearer realm="Dimensions API key required"';
56
- }
57
- export const app = new Hono();
58
- app.get("/health", (c) => {
59
- const store = getCachedSchemaStore();
60
- if (!store) {
61
- return c.json({ ok: true, schemaLoaded: false });
62
- }
63
- const stats = store.stats();
64
- return c.json({
65
- ok: true,
66
- schemaLoaded: true,
67
- dslVersion: stats.dslVersion,
68
- sourceCount: stats.sourceCount,
69
- schemaLoadedAt: stats.schemaLoadedAt,
70
- });
71
- });
72
- app.get("/", (c) => {
73
- const mcpUrl = MCP_PUBLIC_URL || new URL("/mcp", c.req.url).href;
74
- return c.html(html `<!doctype html>
75
- <html lang="en">
76
- <head>
77
- <meta charset="utf-8" />
78
- <meta name="viewport" content="width=device-width, initial-scale=1" />
79
- <title>Dimensions MCP Server — Setup</title>
80
- <style>
81
- *{box-sizing:border-box;margin:0;padding:0}
82
- body{font-family:system-ui,-apple-system,sans-serif;max-width:640px;margin:2rem auto;padding:0 1rem;color:#1a1a1a;line-height:1.5}
83
- h1{font-size:1.4rem;margin-bottom:.25rem}
84
- p.sub{color:#666;margin-bottom:1.5rem;font-size:.9rem}
85
- .note{font-size:.85rem;color:#444;margin-bottom:1.5rem;padding:.75rem 1rem;background:#f3f6fb;border-left:3px solid #2563eb;border-radius:3px}
86
- pre{background:#f5f5f5;padding:1rem;border-radius:4px;overflow-x:auto;font-size:.8rem;line-height:1.6;white-space:pre-wrap;word-break:break-all;border:1px solid #e5e7eb}
87
- h2{font-size:.95rem;margin:1.5rem 0 .5rem;color:#444}
88
- ol{padding-left:1.25rem;font-size:.85rem;color:#444}
89
- ol li{margin-bottom:.35rem}
90
- code.inline{background:#eef1f5;padding:.1rem .35rem;border-radius:3px;font-size:.8rem}
91
- </style>
92
- </head>
93
- <body>
94
- <h1>Dimensions MCP Server</h1>
95
- <p class="sub">Connect your AI assistant using your Dimensions API key.</p>
96
-
97
- <div class="note">
98
- <b>Your key stays yours.</b> Send it on each MCP request as
99
- <code class="inline">Authorization: Bearer &lt;api-key&gt;</code> or
100
- <code class="inline">X-Dimensions-Api-Key</code>. The server uses it
101
- only to call Dimensions DSL endpoints — same auth flow as the REST API.
102
- </div>
103
-
104
- <h2>Endpoint</h2>
105
- <pre>${raw(mcpUrl)}</pre>
106
-
107
- <h2>Local stdio (recommended for single-user setups)</h2>
108
- <pre>${raw(JSON.stringify({
109
- mcpServers: {
110
- dimensions: {
111
- command: "dimensions-mcp",
112
- env: { DIMENSIONS_API_KEY: "your-dimensions-api-key" },
113
- },
114
- },
115
- }, null, 2))}</pre>
116
-
117
- <h2>HTTP clients</h2>
118
- <ol>
119
- <li>Configure your MCP client to POST to the endpoint above.</li>
120
- <li>Set <code class="inline">Authorization: Bearer &lt;your-api-key&gt;</code> on each request.</li>
121
- <li>Obtain a key from your Dimensions account team if you do not have one.</li>
122
- </ol>
123
- </body>
124
- </html>`);
125
- });
126
- app.all("/mcp", async (c) => {
127
- if (c.req.method === "GET") {
128
- return c.text("Method Not Allowed", 405, { Allow: "POST" });
129
- }
130
- const apiKey = extractDimensionsApiKey(c.req.header("Authorization"), c.req.header("X-Dimensions-Api-Key"));
131
- if (!apiKey) {
132
- return c.text("Dimensions API key required", 401, {
133
- "WWW-Authenticate": wwwAuthenticate(),
134
- });
135
- }
136
- let telemetry;
137
- if (MIXPANEL_CLIENT) {
138
- telemetry = createTelemetry({
139
- client: MIXPANEL_CLIENT,
140
- distinctId: telemetryDistinctId(apiKey),
141
- transport: "http",
142
- serverVersion: pkg.version,
143
- stage: TELEMETRY_STAGE,
144
- requestId: randomUUID(),
145
- });
146
- }
147
- const { server } = await createMcpServerAsync({
148
- apiKey,
149
- baseUrl: process.env.DIMENSIONS_BASE_URL,
150
- telemetry,
151
- });
152
- const transport = new WebStandardStreamableHTTPServerTransport({
153
- sessionIdGenerator: undefined,
154
- enableJsonResponse: true,
155
- });
156
- try {
157
- await server.connect(transport);
158
- return await transport.handleRequest(c.req.raw);
159
- }
160
- finally {
161
- if (telemetry) {
162
- try {
163
- await telemetry.flush();
164
- }
165
- catch {
166
- // telemetry must never affect the caller's response
167
- }
168
- }
169
- await transport.close();
170
- await server.close();
171
- }
172
- });
173
- //# sourceMappingURL=http.js.map
package/dist/http.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- /**
2
- * Structured DSL construction for keyword queries (no AST).
3
- *
4
- * @module build-query
5
- */
6
- import type { BuildResult, QuerySpec, SearchExpr } from "./types.js";
7
- /**
8
- * Build a Dimensions DSL query from a structured specification.
9
- *
10
- * @example
11
- * ```typescript
12
- * const result = buildQuery({
13
- * entity: "publications",
14
- * search: { and: [{ or: ["cancer", "oncology"] }, "immune checkpoint"] },
15
- * exclude: "animal model",
16
- * filters: [{ field: "year", op: ">=", value: 2020 }],
17
- * fields: ["id", "title", "doi", "times_cited"],
18
- * limit: 100,
19
- * });
20
- * console.log(result.dsl);
21
- * ```
22
- */
23
- export declare function buildQuery(spec: QuerySpec): BuildResult;
24
- /** @deprecated Use {@link buildSearchClause} — kept for tests and backward compatibility. */
25
- export declare function buildSearchNode(expr: SearchExpr, defaultIndex: string | null): string;
26
- //# sourceMappingURL=build-query.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-query.d.ts","sourceRoot":"","sources":["../../src/kwq/build-query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,CAUvD;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAErF"}
@@ -1,37 +0,0 @@
1
- /**
2
- * Structured DSL construction for keyword queries (no AST).
3
- *
4
- * @module build-query
5
- */
6
- import { assembleQueryDsl, buildSearchClause, querySpecComplexity } from "./dsl-assembler.js";
7
- /**
8
- * Build a Dimensions DSL query from a structured specification.
9
- *
10
- * @example
11
- * ```typescript
12
- * const result = buildQuery({
13
- * entity: "publications",
14
- * search: { and: [{ or: ["cancer", "oncology"] }, "immune checkpoint"] },
15
- * exclude: "animal model",
16
- * filters: [{ field: "year", op: ">=", value: 2020 }],
17
- * fields: ["id", "title", "doi", "times_cited"],
18
- * limit: 100,
19
- * });
20
- * console.log(result.dsl);
21
- * ```
22
- */
23
- export function buildQuery(spec) {
24
- const dsl = assembleQueryDsl(spec);
25
- const validation = { _tag: "valid", warnings: [] };
26
- return {
27
- dsl,
28
- validation,
29
- description: dsl,
30
- complexity: querySpecComplexity(spec),
31
- };
32
- }
33
- /** @deprecated Use {@link buildSearchClause} — kept for tests and backward compatibility. */
34
- export function buildSearchNode(expr, defaultIndex) {
35
- return buildSearchClause(expr, defaultIndex);
36
- }
37
- //# sourceMappingURL=build-query.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-query.js","sourceRoot":"","sources":["../../src/kwq/build-query.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,IAAe;IACxC,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,OAAgB,EAAE,QAAQ,EAAE,EAAW,EAAE,CAAC;IAErE,OAAO;QACL,GAAG;QACH,UAAU;QACV,WAAW,EAAE,GAAG;QAChB,UAAU,EAAE,mBAAmB,CAAC,IAAI,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,eAAe,CAAC,IAAgB,EAAE,YAA2B;IAC3E,OAAO,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC"}
@@ -1,49 +0,0 @@
1
- /**
2
- * Converts concept groups (include/exclude term clusters) to a QuerySpec.
3
- *
4
- * Extracted from `apps/mcp/src/tools/kwq.ts` so both MCP tools and skills
5
- * can import from one source.
6
- *
7
- * @module concept-groups
8
- */
9
- import type { QuerySpec } from "./types.js";
10
- /**
11
- * A group of synonym terms with a role (include or exclude).
12
- *
13
- * - **include**: group's terms are OR'd together, then AND'd with other include groups
14
- * - **exclude**: group's terms are flattened into a single OR and negated (NOT)
15
- */
16
- export interface ConceptGroup {
17
- readonly terms: string[];
18
- readonly role: "include" | "exclude";
19
- }
20
- /**
21
- * Input for {@link conceptGroupsToQuerySpec}.
22
- */
23
- export interface ConceptGroupsInput {
24
- readonly entity: string;
25
- readonly concept_groups?: readonly ConceptGroup[];
26
- readonly search_json?: string;
27
- readonly index?: string;
28
- readonly filters?: ReadonlyArray<{
29
- field: string;
30
- op: string;
31
- value: unknown;
32
- }>;
33
- readonly fields?: readonly string[];
34
- readonly sort_by?: string;
35
- readonly sort_order?: string;
36
- readonly limit?: number;
37
- readonly skip?: number;
38
- }
39
- /**
40
- * Converts concept groups (or raw search JSON) to a {@link QuerySpec}.
41
- *
42
- * Include groups: each group's terms OR'd, groups AND'd together.
43
- * Exclude groups: all terms flattened into a single OR, negated.
44
- *
45
- * @param input - Concept groups and query parameters
46
- * @returns A fully-formed QuerySpec ready for `buildQuery()`
47
- */
48
- export declare function conceptGroupsToQuerySpec(input: ConceptGroupsInput): QuerySpec;
49
- //# sourceMappingURL=concept-groups.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"concept-groups.d.ts","sourceRoot":"","sources":["../../src/kwq/concept-groups.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AAExD;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAClD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAyC7E"}
@@ -1,55 +0,0 @@
1
- /**
2
- * Converts concept groups (include/exclude term clusters) to a QuerySpec.
3
- *
4
- * Extracted from `apps/mcp/src/tools/kwq.ts` so both MCP tools and skills
5
- * can import from one source.
6
- *
7
- * @module concept-groups
8
- */
9
- /**
10
- * Converts concept groups (or raw search JSON) to a {@link QuerySpec}.
11
- *
12
- * Include groups: each group's terms OR'd, groups AND'd together.
13
- * Exclude groups: all terms flattened into a single OR, negated.
14
- *
15
- * @param input - Concept groups and query parameters
16
- * @returns A fully-formed QuerySpec ready for `buildQuery()`
17
- */
18
- export function conceptGroupsToQuerySpec(input) {
19
- let search;
20
- let exclude;
21
- if (input.search_json) {
22
- search = JSON.parse(input.search_json);
23
- }
24
- else if (input.concept_groups) {
25
- const includeGroups = input.concept_groups.filter((g) => g.role === "include");
26
- const excludeGroups = input.concept_groups.filter((g) => g.role === "exclude");
27
- // Build include expression: each group's terms OR'd, groups AND'd
28
- if (includeGroups.length > 0) {
29
- const includeExprs = includeGroups.map((g) => g.terms.length === 1 ? g.terms[0] : { or: g.terms });
30
- search = includeExprs.length === 1 ? includeExprs[0] : { and: includeExprs };
31
- }
32
- // Build exclude expression: all exclude terms flattened into a single OR
33
- if (excludeGroups.length > 0) {
34
- const excludeTerms = excludeGroups.flatMap((g) => g.terms);
35
- exclude = excludeTerms.length === 1 ? excludeTerms[0] : { or: excludeTerms };
36
- }
37
- }
38
- return {
39
- entity: input.entity,
40
- search,
41
- exclude,
42
- index: input.index,
43
- filters: input.filters?.map((f) => ({
44
- field: f.field,
45
- op: f.op,
46
- value: f.value,
47
- })),
48
- fields: input.fields,
49
- sortBy: input.sort_by,
50
- sortOrder: input.sort_order,
51
- limit: input.limit,
52
- skip: input.skip,
53
- };
54
- }
55
- //# sourceMappingURL=concept-groups.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"concept-groups.js","sourceRoot":"","sources":["../../src/kwq/concept-groups.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+BH;;;;;;;;GAQG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAyB;IAChE,IAAI,MAA8B,CAAC;IACnC,IAAI,OAA+B,CAAC;IAEpC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAe,CAAC;IACvD,CAAC;SAAM,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QAChC,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAC/E,MAAM,aAAa,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QAE/E,kEAAkE;QAClE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,YAAY,GAAiB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACzD,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CACpD,CAAC;YACF,MAAM,GAAG,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;QAC/E,CAAC;QAED,yEAAyE;QACzE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;YAC3D,OAAO,GAAG,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAA6B;QAC3C,MAAM;QACN,OAAO;QACP,KAAK,EAAE,KAAK,CAAC,KAA2B;QACxC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,EAAE,EAAE,CAAC,CAAC,EAAuD;YAC7D,KAAK,EAAE,CAAC,CAAC,KAAgE;SAC1E,CAAC,CAAC;QACH,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,OAAO;QACrB,SAAS,EAAE,KAAK,CAAC,UAAoC;QACrD,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC;AACJ,CAAC"}
@@ -1,28 +0,0 @@
1
- /**
2
- * Assembles Dimensions DSL query strings from structured specs (no AST).
3
- * @module dsl-assembler
4
- */
5
- import type { QuerySpec, SearchExpr } from "./types.js";
6
- /**
7
- * Emits a `for "..."` clause (with optional index) from a search expression.
8
- * @param expr - Search expression tree
9
- * @param defaultIndex - Default index for string leaves
10
- * @returns DSL search fragment (without leading `search`)
11
- */
12
- export declare function buildSearchClause(expr: SearchExpr, defaultIndex: string | null): string;
13
- /**
14
- * Builds a full DSL query string from a {@link QuerySpec}.
15
- * @param spec - Structured query specification
16
- * @returns DSL source text
17
- */
18
- export declare function assembleQueryDsl(spec: QuerySpec): string;
19
- /**
20
- * Lightweight complexity metrics for a query spec.
21
- * @param spec - Query specification
22
- */
23
- export declare function querySpecComplexity(spec: QuerySpec): {
24
- readonly filterCount: number;
25
- readonly hasExclusion: boolean;
26
- readonly hasSearch: boolean;
27
- };
28
- //# sourceMappingURL=dsl-assembler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dsl-assembler.d.ts","sourceRoot":"","sources":["../../src/kwq/dsl-assembler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAc,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAcpE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CA6BvF;AA6BD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAuCxD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAMA"}
@@ -1,124 +0,0 @@
1
- /**
2
- * Assembles Dimensions DSL query strings from structured specs (no AST).
3
- * @module dsl-assembler
4
- */
5
- import { escapeDslString } from "../dsl/index.js";
6
- /** Default search index label when none is set. */
7
- const DEFAULT_INDEX = "full_data";
8
- function quoteDsl(text) {
9
- return `"${escapeDslString(text)}"`;
10
- }
11
- function indexPrefix(index) {
12
- if (!index || index === DEFAULT_INDEX)
13
- return "";
14
- return `in ${index} `;
15
- }
16
- /**
17
- * Emits a `for "..."` clause (with optional index) from a search expression.
18
- * @param expr - Search expression tree
19
- * @param defaultIndex - Default index for string leaves
20
- * @returns DSL search fragment (without leading `search`)
21
- */
22
- export function buildSearchClause(expr, defaultIndex) {
23
- if (typeof expr === "string") {
24
- return `${indexPrefix(defaultIndex)}for ${quoteDsl(expr)}`;
25
- }
26
- if ("term" in expr) {
27
- const idx = expr.index ?? defaultIndex;
28
- return `${indexPrefix(idx)}for ${quoteDsl(expr.term)}`;
29
- }
30
- if ("and" in expr) {
31
- if (expr.and.length === 0) {
32
- throw new Error("AND expression must have at least one child");
33
- }
34
- const parts = expr.and.map((child) => buildSearchClause(child, defaultIndex));
35
- if (parts.length === 1)
36
- return parts[0];
37
- return parts.map((p) => wrapSearch(p, "or")).join(" and ");
38
- }
39
- if ("or" in expr) {
40
- if (expr.or.length === 0) {
41
- throw new Error("OR expression must have at least one child");
42
- }
43
- const parts = expr.or.map((child) => buildSearchClause(child, defaultIndex));
44
- if (parts.length === 1)
45
- return parts[0];
46
- return `(${parts.join(" or ")})`;
47
- }
48
- throw new Error("Invalid SearchExpr: must be string, { term }, { and }, or { or }");
49
- }
50
- function wrapSearch(clause, childOp) {
51
- if (childOp === "or" && clause.includes(" or ")) {
52
- return `(${clause})`;
53
- }
54
- return clause;
55
- }
56
- function formatFilterValue(value) {
57
- if (typeof value === "string") {
58
- return quoteDsl(value);
59
- }
60
- if (typeof value === "number") {
61
- return String(value);
62
- }
63
- if (Array.isArray(value) && value.length > 0) {
64
- if (typeof value[0] === "string") {
65
- return `[${value.map(quoteDsl).join(", ")}]`;
66
- }
67
- return `[${value.join(", ")}]`;
68
- }
69
- return "[]";
70
- }
71
- function formatFilter(filter) {
72
- return `${filter.field} ${filter.op} ${formatFilterValue(filter.value)}`;
73
- }
74
- /**
75
- * Builds a full DSL query string from a {@link QuerySpec}.
76
- * @param spec - Structured query specification
77
- * @returns DSL source text
78
- */
79
- export function assembleQueryDsl(spec) {
80
- const parts = [`search ${spec.entity}`];
81
- let searchPart = "";
82
- if (spec.search) {
83
- searchPart = buildSearchClause(spec.search, spec.index ?? null);
84
- }
85
- if (spec.exclude) {
86
- const excludePart = buildSearchClause(spec.exclude, spec.index ?? null);
87
- if (searchPart) {
88
- searchPart = `${searchPart} not ${excludePart}`;
89
- }
90
- }
91
- if (searchPart) {
92
- parts.push(searchPart);
93
- }
94
- if (spec.filters?.length) {
95
- parts.push(`where ${spec.filters.map(formatFilter).join(" and ")}`);
96
- }
97
- const returnParts = [`return ${spec.entity}`];
98
- if (spec.fields?.length) {
99
- returnParts[0] = `return ${spec.entity}[${spec.fields.join(" + ")}]`;
100
- }
101
- if (spec.sortBy) {
102
- returnParts.push(`sort by ${spec.sortBy} ${spec.sortOrder ?? "desc"}`);
103
- }
104
- if (spec.limit !== undefined) {
105
- returnParts.push(`limit ${spec.limit}`);
106
- }
107
- if (spec.skip !== undefined && spec.skip > 0) {
108
- returnParts.push(`skip ${spec.skip}`);
109
- }
110
- parts.push(returnParts.join(" "));
111
- return parts.join(" ");
112
- }
113
- /**
114
- * Lightweight complexity metrics for a query spec.
115
- * @param spec - Query specification
116
- */
117
- export function querySpecComplexity(spec) {
118
- return {
119
- filterCount: spec.filters?.length ?? 0,
120
- hasExclusion: spec.exclude !== undefined,
121
- hasSearch: spec.search !== undefined,
122
- };
123
- }
124
- //# sourceMappingURL=dsl-assembler.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dsl-assembler.js","sourceRoot":"","sources":["../../src/kwq/dsl-assembler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,mDAAmD;AACnD,MAAM,aAAa,GAAG,WAAW,CAAC;AAElC,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;AACtC,CAAC;AAED,SAAS,WAAW,CAAC,KAAgC;IACnD,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,aAAa;QAAE,OAAO,EAAE,CAAC;IACjD,OAAO,MAAM,KAAK,GAAG,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAgB,EAAE,YAA2B;IAC7E,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7D,CAAC;IAED,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC;QACvC,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACzD,CAAC;IAED,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;QAC9E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QACjB,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,UAAU,CAAC,MAAc,EAAE,OAAqB;IACvD,IAAI,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,MAAM,GAAG,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,iBAAiB,CAAC,KAA0B;IACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7C,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,IAAK,KAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC7D,CAAC;QACD,OAAO,IAAK,KAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC/C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,MAAkB;IACtC,OAAO,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,EAAE,IAAI,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAe;IAC9C,MAAM,KAAK,GAAa,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAElD,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;QACxE,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,GAAG,GAAG,UAAU,QAAQ,WAAW,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,WAAW,GAAa,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QACxB,WAAW,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;IACvE,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,WAAW,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC7C,WAAW,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAe;IAKjD,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QACtC,YAAY,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS;QACxC,SAAS,EAAE,IAAI,CAAC,MAAM,KAAK,SAAS;KACrC,CAAC;AACJ,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * Ring 4: RRF (Reciprocal Rank Fusion) ensemble.
3
- *
4
- * Executes multiple QuerySpecs in parallel, merges results using RRF scoring,
5
- * and returns a fused ranking. Pure function — no LLM dependency.
6
- *
7
- * @module ensemble
8
- */
9
- import type { EnsembleResult, QuerySpec } from "./types.js";
10
- /**
11
- * Execute multiple query specs and fuse results using Reciprocal Rank Fusion.
12
- *
13
- * RRF score for a document `d` across N ranked lists:
14
- * score(d) = Σ 1/(k + rank_i(d))
15
- * where rank_i is the 0-based position in list i.
16
- *
17
- * @param execute - Executes a DSL string and returns the raw API response.
18
- * In MCP context: `(dsl) => client.rawQuery(dsl)`.
19
- * @param specs - Query specifications to build, execute, and fuse.
20
- * @param options - Optional k (default 60) and limit (default 100).
21
- *
22
- * @example
23
- * ```typescript
24
- * const result = await ensembleQueries(
25
- * (dsl) => client.rawQuery(dsl),
26
- * [
27
- * { entity: "publications", search: "quantum networking" },
28
- * { entity: "publications", search: "quantum key distribution" },
29
- * ],
30
- * );
31
- * // result.items: [{ id: "pub.123", rrfScore: 0.033, ... }, ...]
32
- * ```
33
- */
34
- export declare function ensembleQueries(execute: (dsl: string) => Promise<Record<string, unknown>>, specs: readonly QuerySpec[], options?: {
35
- k?: number;
36
- limit?: number;
37
- }): Promise<EnsembleResult>;
38
- //# sourceMappingURL=ensemble.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ensemble.d.ts","sourceRoot":"","sources":["../../src/kwq/ensemble.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAgB,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK1E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC1D,KAAK,EAAE,SAAS,SAAS,EAAE,EAC3B,OAAO,CAAC,EAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvC,OAAO,CAAC,cAAc,CAAC,CAoFzB"}