@arke-institute/sdk 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/content/index.cjs +95 -10
- package/dist/content/index.cjs.map +1 -1
- package/dist/content/index.d.cts +128 -15
- package/dist/content/index.d.ts +128 -15
- package/dist/content/index.js +95 -10
- package/dist/content/index.js.map +1 -1
- package/dist/edit/index.cjs +590 -116
- package/dist/edit/index.cjs.map +1 -1
- package/dist/edit/index.d.cts +2 -2
- package/dist/edit/index.d.ts +2 -2
- package/dist/edit/index.js +580 -116
- package/dist/edit/index.js.map +1 -1
- package/dist/errors-CT7yzKkU.d.cts +874 -0
- package/dist/errors-CT7yzKkU.d.ts +874 -0
- package/dist/graph/index.cjs +52 -58
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +84 -55
- package/dist/graph/index.d.ts +84 -55
- package/dist/graph/index.js +52 -58
- package/dist/graph/index.js.map +1 -1
- package/dist/index.cjs +796 -196
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +796 -196
- package/dist/index.js.map +1 -1
- package/dist/query/index.cjs +67 -0
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +96 -1
- package/dist/query/index.d.ts +96 -1
- package/dist/query/index.js +67 -0
- package/dist/query/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/errors-B82BMmRP.d.cts +0 -343
- package/dist/errors-B82BMmRP.d.ts +0 -343
package/dist/query/index.cjs
CHANGED
|
@@ -248,6 +248,73 @@ var QueryClient = class {
|
|
|
248
248
|
async health() {
|
|
249
249
|
return this.request("/query/health", { method: "GET" });
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Direct semantic search against the vector index.
|
|
253
|
+
*
|
|
254
|
+
* This bypasses the path query syntax and directly queries Pinecone for
|
|
255
|
+
* semantically similar entities. Useful for:
|
|
256
|
+
* - Simple semantic searches without graph traversal
|
|
257
|
+
* - Scoped searches filtered by source_pi (collection scope)
|
|
258
|
+
* - Type-filtered semantic searches
|
|
259
|
+
*
|
|
260
|
+
* For graph traversal and path-based queries, use `path()` instead.
|
|
261
|
+
*
|
|
262
|
+
* @param text - Search query text
|
|
263
|
+
* @param options - Search options (namespace, filters, top_k)
|
|
264
|
+
* @returns Matching entities with similarity scores
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```typescript
|
|
268
|
+
* // Simple semantic search
|
|
269
|
+
* const results = await query.semanticSearch('photographers from New York');
|
|
270
|
+
*
|
|
271
|
+
* // Scoped to a specific PI (collection)
|
|
272
|
+
* const scoped = await query.semanticSearch('portraits', {
|
|
273
|
+
* filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },
|
|
274
|
+
* top_k: 20,
|
|
275
|
+
* });
|
|
276
|
+
*
|
|
277
|
+
* // Filter by type
|
|
278
|
+
* const people = await query.semanticSearch('artists', {
|
|
279
|
+
* filter: { type: 'person' },
|
|
280
|
+
* });
|
|
281
|
+
*
|
|
282
|
+
* // Search across merged entities from multiple source PIs
|
|
283
|
+
* const merged = await query.semanticSearch('historical documents', {
|
|
284
|
+
* filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },
|
|
285
|
+
* });
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
async semanticSearch(text, options = {}) {
|
|
289
|
+
let pineconeFilter;
|
|
290
|
+
if (options.filter) {
|
|
291
|
+
pineconeFilter = {};
|
|
292
|
+
if (options.filter.type) {
|
|
293
|
+
const types = Array.isArray(options.filter.type) ? options.filter.type : [options.filter.type];
|
|
294
|
+
pineconeFilter.type = types.length === 1 ? { $eq: types[0] } : { $in: types };
|
|
295
|
+
}
|
|
296
|
+
if (options.filter.source_pi) {
|
|
297
|
+
const pis = Array.isArray(options.filter.source_pi) ? options.filter.source_pi : [options.filter.source_pi];
|
|
298
|
+
pineconeFilter.source_pi = pis.length === 1 ? { $eq: pis[0] } : { $in: pis };
|
|
299
|
+
}
|
|
300
|
+
if (options.filter.merged_entities_source_pis) {
|
|
301
|
+
const pis = Array.isArray(options.filter.merged_entities_source_pis) ? options.filter.merged_entities_source_pis : [options.filter.merged_entities_source_pis];
|
|
302
|
+
pineconeFilter.merged_entities_source_pis = { $in: pis };
|
|
303
|
+
}
|
|
304
|
+
if (Object.keys(pineconeFilter).length === 0) {
|
|
305
|
+
pineconeFilter = void 0;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return this.request("/query/search/semantic", {
|
|
309
|
+
method: "POST",
|
|
310
|
+
body: JSON.stringify({
|
|
311
|
+
text,
|
|
312
|
+
namespace: options.namespace,
|
|
313
|
+
filter: pineconeFilter,
|
|
314
|
+
top_k: options.top_k
|
|
315
|
+
})
|
|
316
|
+
});
|
|
317
|
+
}
|
|
251
318
|
/**
|
|
252
319
|
* Search for collections by semantic similarity.
|
|
253
320
|
*
|
package/dist/query/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/query/index.ts","../../src/query/errors.ts","../../src/query/client.ts"],"sourcesContent":["export { QueryClient, type QueryClientConfig } from './client';\nexport { QueryError } from './errors';\nexport type {\n // Request types\n LineageFilter,\n PathQueryOptions,\n NaturalQueryOptions,\n // Response types\n EnrichedContent,\n Entity,\n PathStep,\n QueryResultItem,\n LineageMetadata,\n QueryMetadata,\n QueryResult,\n TranslationInfo,\n NaturalQueryResult,\n TranslateResult,\n // Parse types\n ASTNodeType,\n EntryAST,\n FilterAST,\n HopAST,\n PathAST,\n ParseResult,\n ParseError,\n // Syntax documentation types\n EntryPointDoc,\n EdgeTypeDoc,\n VariableDepthDoc,\n FilterTypeDoc,\n ParameterDoc,\n ExampleDoc,\n SyntaxDocumentation,\n // Collection search types\n CollectionSearchOptions,\n CollectionSearchResult,\n CollectionSearchResponse,\n} from './types';\n","/**\n * Error class for query operations\n */\nexport class QueryError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'QueryError';\n }\n}\n","import { QueryError } from './errors';\nimport type {\n PathQueryOptions,\n NaturalQueryOptions,\n QueryResult,\n NaturalQueryResult,\n TranslateResult,\n ParseResult,\n ParseError,\n SyntaxDocumentation,\n CollectionSearchOptions,\n CollectionSearchResponse,\n} from './types';\n\n/**\n * Configuration for QueryClient\n */\nexport interface QueryClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /query/* endpoints.\n */\n gatewayUrl: string;\n /**\n * Optional custom fetch implementation (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\n/**\n * Client for querying the Arke knowledge graph.\n *\n * All query endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const query = new QueryClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Direct path query\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person');\n *\n * // Natural language query\n * const nlResults = await query.natural('Find photographers connected to Alice Austen');\n *\n * // Get syntax documentation\n * const syntax = await query.syntax();\n * ```\n */\nexport class QueryClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: QueryClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | undefined>) {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n return url.toString();\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n query?: Record<string, string | undefined>;\n } = {}\n ): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (options.headers) {\n Object.entries(options.headers).forEach(([k, v]) => {\n if (v !== undefined) headers.set(k, v as string);\n });\n }\n\n const response = await this.fetchImpl(url, { ...options, headers });\n\n if (response.ok) {\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n }\n\n let body: unknown;\n const text = await response.text();\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : (body as JsonBody)?.message && typeof (body as JsonBody).message === 'string'\n ? ((body as JsonBody).message as string)\n : `Request failed with status ${response.status}`;\n\n throw new QueryError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Query methods\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a path query against the knowledge graph.\n *\n * @param pathQuery - The path query string (e.g., '\"alice austen\" -[*]{,4}-> type:person')\n * @param options - Query options (k, k_explore, lineage, enrich, etc.)\n * @returns Query results with entities, paths, and metadata\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.path('\"Washington\" type:person');\n *\n * // Multi-hop traversal\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person ~ \"photographer\"');\n *\n * // With lineage filtering (collection scope)\n * const results = await query.path('\"letters\" type:document', {\n * lineage: { sourcePi: 'arke:my_collection', direction: 'descendants' },\n * k: 10,\n * });\n * ```\n */\n async path(pathQuery: string, options: PathQueryOptions = {}): Promise<QueryResult> {\n return this.request<QueryResult>('/query/path', {\n method: 'POST',\n body: JSON.stringify({\n path: pathQuery,\n ...options,\n }),\n });\n }\n\n /**\n * Execute a natural language query.\n *\n * The query is translated to a path query using an LLM, then executed.\n *\n * @param question - Natural language question\n * @param options - Query options including custom_instructions for the LLM\n * @returns Query results with translation info\n *\n * @example\n * ```typescript\n * const results = await query.natural('Find photographers connected to Alice Austen');\n * console.log('Generated query:', results.translation.path);\n * console.log('Explanation:', results.translation.explanation);\n * ```\n */\n async natural(question: string, options: NaturalQueryOptions = {}): Promise<NaturalQueryResult> {\n const { custom_instructions, ...queryOptions } = options;\n return this.request<NaturalQueryResult>('/query/natural', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions,\n ...queryOptions,\n }),\n });\n }\n\n /**\n * Translate a natural language question to a path query without executing it.\n *\n * Useful for understanding how questions are translated or for manual execution later.\n *\n * @param question - Natural language question\n * @param customInstructions - Optional additional instructions for the LLM\n * @returns Translation result with path query and explanation\n *\n * @example\n * ```typescript\n * const result = await query.translate('Who wrote letters from Philadelphia?');\n * console.log('Path query:', result.path);\n * // '\"letters\" <-[authored, wrote]- type:person -[located]-> \"Philadelphia\"'\n * ```\n */\n async translate(question: string, customInstructions?: string): Promise<TranslateResult> {\n return this.request<TranslateResult>('/query/translate', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions: customInstructions,\n }),\n });\n }\n\n /**\n * Parse and validate a path query without executing it.\n *\n * Returns the AST (Abstract Syntax Tree) if valid, or throws an error.\n *\n * @param pathQuery - The path query to parse\n * @returns Parsed AST\n * @throws QueryError if the query has syntax errors\n *\n * @example\n * ```typescript\n * try {\n * const result = await query.parse('\"test\" -[*]-> type:person');\n * console.log('Valid query, AST:', result.ast);\n * } catch (err) {\n * console.error('Invalid query:', err.message);\n * }\n * ```\n */\n async parse(pathQuery: string): Promise<ParseResult> {\n const url = this.buildUrl('/query/parse', { path: pathQuery });\n const response = await this.fetchImpl(url, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n const body = await response.json() as ParseResult | ParseError;\n\n // Check if it's an error response (parse errors return 400)\n if ('error' in body && body.error === 'Parse error') {\n throw new QueryError(\n (body as ParseError).message,\n 'PARSE_ERROR',\n { position: (body as ParseError).position }\n );\n }\n\n if (!response.ok) {\n throw new QueryError(\n (body as any).error || `Request failed with status ${response.status}`,\n 'HTTP_ERROR',\n { status: response.status, body }\n );\n }\n\n return body as ParseResult;\n }\n\n /**\n * Get the path query syntax documentation.\n *\n * Returns comprehensive documentation including entry points, edge traversal,\n * filters, examples, and constraints.\n *\n * @returns Syntax documentation\n *\n * @example\n * ```typescript\n * const syntax = await query.syntax();\n *\n * // List all entry point types\n * syntax.entryPoints.types.forEach(ep => {\n * console.log(`${ep.syntax} - ${ep.description}`);\n * });\n *\n * // Show examples\n * syntax.examples.forEach(ex => {\n * console.log(`${ex.description}: ${ex.query}`);\n * });\n * ```\n */\n async syntax(): Promise<SyntaxDocumentation> {\n return this.request<SyntaxDocumentation>('/query/syntax', {\n method: 'GET',\n });\n }\n\n /**\n * Check the health of the query service.\n *\n * @returns Health status\n */\n async health(): Promise<{ status: string; service: string; version: string }> {\n return this.request('/query/health', { method: 'GET' });\n }\n\n /**\n * Search for collections by semantic similarity.\n *\n * Searches the dedicated collections index for fast semantic matching.\n *\n * @param query - Search query text\n * @param options - Search options (limit, visibility filter)\n * @returns Matching collections with similarity scores\n *\n * @example\n * ```typescript\n * // Search for photography-related collections\n * const results = await query.searchCollections('photography');\n * console.log(results.collections[0].title);\n *\n * // Search only public collections\n * const publicResults = await query.searchCollections('history', {\n * visibility: 'public',\n * limit: 20,\n * });\n * ```\n */\n async searchCollections(\n query: string,\n options: CollectionSearchOptions = {}\n ): Promise<CollectionSearchResponse> {\n return this.request<CollectionSearchResponse>('/query/search/collections', {\n method: 'GET',\n query: {\n q: query,\n limit: options.limit?.toString(),\n visibility: options.visibility,\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/query/index.ts","../../src/query/errors.ts","../../src/query/client.ts"],"sourcesContent":["export { QueryClient, type QueryClientConfig } from './client';\nexport { QueryError } from './errors';\nexport type {\n // Request types\n LineageFilter,\n PathQueryOptions,\n NaturalQueryOptions,\n // Response types\n EnrichedContent,\n Entity,\n PathStep,\n QueryResultItem,\n LineageMetadata,\n QueryMetadata,\n QueryResult,\n TranslationInfo,\n NaturalQueryResult,\n TranslateResult,\n // Parse types\n ASTNodeType,\n EntryAST,\n FilterAST,\n HopAST,\n PathAST,\n ParseResult,\n ParseError,\n // Syntax documentation types\n EntryPointDoc,\n EdgeTypeDoc,\n VariableDepthDoc,\n FilterTypeDoc,\n ParameterDoc,\n ExampleDoc,\n SyntaxDocumentation,\n // Semantic search types\n SemanticSearchFilter,\n SemanticSearchOptions,\n SemanticSearchMetadata,\n SemanticSearchMatch,\n SemanticSearchResponse,\n // Collection search types\n CollectionSearchOptions,\n CollectionSearchResult,\n CollectionSearchResponse,\n} from './types';\n","/**\n * Error class for query operations\n */\nexport class QueryError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'QueryError';\n }\n}\n","import { QueryError } from './errors';\nimport type {\n PathQueryOptions,\n NaturalQueryOptions,\n QueryResult,\n NaturalQueryResult,\n TranslateResult,\n ParseResult,\n ParseError,\n SyntaxDocumentation,\n SemanticSearchOptions,\n SemanticSearchResponse,\n CollectionSearchOptions,\n CollectionSearchResponse,\n} from './types';\n\n/**\n * Configuration for QueryClient\n */\nexport interface QueryClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /query/* endpoints.\n */\n gatewayUrl: string;\n /**\n * Optional custom fetch implementation (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\n/**\n * Client for querying the Arke knowledge graph.\n *\n * All query endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const query = new QueryClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Direct path query\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person');\n *\n * // Natural language query\n * const nlResults = await query.natural('Find photographers connected to Alice Austen');\n *\n * // Get syntax documentation\n * const syntax = await query.syntax();\n * ```\n */\nexport class QueryClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: QueryClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | undefined>) {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n return url.toString();\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n query?: Record<string, string | undefined>;\n } = {}\n ): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (options.headers) {\n Object.entries(options.headers).forEach(([k, v]) => {\n if (v !== undefined) headers.set(k, v as string);\n });\n }\n\n const response = await this.fetchImpl(url, { ...options, headers });\n\n if (response.ok) {\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n }\n\n let body: unknown;\n const text = await response.text();\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : (body as JsonBody)?.message && typeof (body as JsonBody).message === 'string'\n ? ((body as JsonBody).message as string)\n : `Request failed with status ${response.status}`;\n\n throw new QueryError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Query methods\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a path query against the knowledge graph.\n *\n * @param pathQuery - The path query string (e.g., '\"alice austen\" -[*]{,4}-> type:person')\n * @param options - Query options (k, k_explore, lineage, enrich, etc.)\n * @returns Query results with entities, paths, and metadata\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.path('\"Washington\" type:person');\n *\n * // Multi-hop traversal\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person ~ \"photographer\"');\n *\n * // With lineage filtering (collection scope)\n * const results = await query.path('\"letters\" type:document', {\n * lineage: { sourcePi: 'arke:my_collection', direction: 'descendants' },\n * k: 10,\n * });\n * ```\n */\n async path(pathQuery: string, options: PathQueryOptions = {}): Promise<QueryResult> {\n return this.request<QueryResult>('/query/path', {\n method: 'POST',\n body: JSON.stringify({\n path: pathQuery,\n ...options,\n }),\n });\n }\n\n /**\n * Execute a natural language query.\n *\n * The query is translated to a path query using an LLM, then executed.\n *\n * @param question - Natural language question\n * @param options - Query options including custom_instructions for the LLM\n * @returns Query results with translation info\n *\n * @example\n * ```typescript\n * const results = await query.natural('Find photographers connected to Alice Austen');\n * console.log('Generated query:', results.translation.path);\n * console.log('Explanation:', results.translation.explanation);\n * ```\n */\n async natural(question: string, options: NaturalQueryOptions = {}): Promise<NaturalQueryResult> {\n const { custom_instructions, ...queryOptions } = options;\n return this.request<NaturalQueryResult>('/query/natural', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions,\n ...queryOptions,\n }),\n });\n }\n\n /**\n * Translate a natural language question to a path query without executing it.\n *\n * Useful for understanding how questions are translated or for manual execution later.\n *\n * @param question - Natural language question\n * @param customInstructions - Optional additional instructions for the LLM\n * @returns Translation result with path query and explanation\n *\n * @example\n * ```typescript\n * const result = await query.translate('Who wrote letters from Philadelphia?');\n * console.log('Path query:', result.path);\n * // '\"letters\" <-[authored, wrote]- type:person -[located]-> \"Philadelphia\"'\n * ```\n */\n async translate(question: string, customInstructions?: string): Promise<TranslateResult> {\n return this.request<TranslateResult>('/query/translate', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions: customInstructions,\n }),\n });\n }\n\n /**\n * Parse and validate a path query without executing it.\n *\n * Returns the AST (Abstract Syntax Tree) if valid, or throws an error.\n *\n * @param pathQuery - The path query to parse\n * @returns Parsed AST\n * @throws QueryError if the query has syntax errors\n *\n * @example\n * ```typescript\n * try {\n * const result = await query.parse('\"test\" -[*]-> type:person');\n * console.log('Valid query, AST:', result.ast);\n * } catch (err) {\n * console.error('Invalid query:', err.message);\n * }\n * ```\n */\n async parse(pathQuery: string): Promise<ParseResult> {\n const url = this.buildUrl('/query/parse', { path: pathQuery });\n const response = await this.fetchImpl(url, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n const body = await response.json() as ParseResult | ParseError;\n\n // Check if it's an error response (parse errors return 400)\n if ('error' in body && body.error === 'Parse error') {\n throw new QueryError(\n (body as ParseError).message,\n 'PARSE_ERROR',\n { position: (body as ParseError).position }\n );\n }\n\n if (!response.ok) {\n throw new QueryError(\n (body as any).error || `Request failed with status ${response.status}`,\n 'HTTP_ERROR',\n { status: response.status, body }\n );\n }\n\n return body as ParseResult;\n }\n\n /**\n * Get the path query syntax documentation.\n *\n * Returns comprehensive documentation including entry points, edge traversal,\n * filters, examples, and constraints.\n *\n * @returns Syntax documentation\n *\n * @example\n * ```typescript\n * const syntax = await query.syntax();\n *\n * // List all entry point types\n * syntax.entryPoints.types.forEach(ep => {\n * console.log(`${ep.syntax} - ${ep.description}`);\n * });\n *\n * // Show examples\n * syntax.examples.forEach(ex => {\n * console.log(`${ex.description}: ${ex.query}`);\n * });\n * ```\n */\n async syntax(): Promise<SyntaxDocumentation> {\n return this.request<SyntaxDocumentation>('/query/syntax', {\n method: 'GET',\n });\n }\n\n /**\n * Check the health of the query service.\n *\n * @returns Health status\n */\n async health(): Promise<{ status: string; service: string; version: string }> {\n return this.request('/query/health', { method: 'GET' });\n }\n\n /**\n * Direct semantic search against the vector index.\n *\n * This bypasses the path query syntax and directly queries Pinecone for\n * semantically similar entities. Useful for:\n * - Simple semantic searches without graph traversal\n * - Scoped searches filtered by source_pi (collection scope)\n * - Type-filtered semantic searches\n *\n * For graph traversal and path-based queries, use `path()` instead.\n *\n * @param text - Search query text\n * @param options - Search options (namespace, filters, top_k)\n * @returns Matching entities with similarity scores\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.semanticSearch('photographers from New York');\n *\n * // Scoped to a specific PI (collection)\n * const scoped = await query.semanticSearch('portraits', {\n * filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },\n * top_k: 20,\n * });\n *\n * // Filter by type\n * const people = await query.semanticSearch('artists', {\n * filter: { type: 'person' },\n * });\n *\n * // Search across merged entities from multiple source PIs\n * const merged = await query.semanticSearch('historical documents', {\n * filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },\n * });\n * ```\n */\n async semanticSearch(\n text: string,\n options: SemanticSearchOptions = {}\n ): Promise<SemanticSearchResponse> {\n // Build Pinecone-compatible filter from our typed filter\n let pineconeFilter: Record<string, unknown> | undefined;\n\n if (options.filter) {\n pineconeFilter = {};\n\n if (options.filter.type) {\n const types = Array.isArray(options.filter.type)\n ? options.filter.type\n : [options.filter.type];\n pineconeFilter.type = types.length === 1\n ? { $eq: types[0] }\n : { $in: types };\n }\n\n if (options.filter.source_pi) {\n const pis = Array.isArray(options.filter.source_pi)\n ? options.filter.source_pi\n : [options.filter.source_pi];\n pineconeFilter.source_pi = pis.length === 1\n ? { $eq: pis[0] }\n : { $in: pis };\n }\n\n if (options.filter.merged_entities_source_pis) {\n const pis = Array.isArray(options.filter.merged_entities_source_pis)\n ? options.filter.merged_entities_source_pis\n : [options.filter.merged_entities_source_pis];\n // Use $in for array field matching (any of the provided PIs)\n pineconeFilter.merged_entities_source_pis = { $in: pis };\n }\n\n // If no filters were actually set, clear the object\n if (Object.keys(pineconeFilter).length === 0) {\n pineconeFilter = undefined;\n }\n }\n\n return this.request<SemanticSearchResponse>('/query/search/semantic', {\n method: 'POST',\n body: JSON.stringify({\n text,\n namespace: options.namespace,\n filter: pineconeFilter,\n top_k: options.top_k,\n }),\n });\n }\n\n /**\n * Search for collections by semantic similarity.\n *\n * Searches the dedicated collections index for fast semantic matching.\n *\n * @param query - Search query text\n * @param options - Search options (limit, visibility filter)\n * @returns Matching collections with similarity scores\n *\n * @example\n * ```typescript\n * // Search for photography-related collections\n * const results = await query.searchCollections('photography');\n * console.log(results.collections[0].title);\n *\n * // Search only public collections\n * const publicResults = await query.searchCollections('history', {\n * visibility: 'public',\n * limit: 20,\n * });\n * ```\n */\n async searchCollections(\n query: string,\n options: CollectionSearchOptions = {}\n ): Promise<CollectionSearchResponse> {\n return this.request<CollectionSearchResponse>('/query/search/collections', {\n method: 'GET',\n query: {\n q: query,\n limit: options.limit?.toString(),\n visibility: options.visibility,\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/query/index.d.cts
CHANGED
|
@@ -316,6 +316,63 @@ interface SyntaxDocumentation {
|
|
|
316
316
|
constraints: string[];
|
|
317
317
|
errors: Record<string, string>;
|
|
318
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Filter options for semantic search
|
|
321
|
+
*/
|
|
322
|
+
interface SemanticSearchFilter {
|
|
323
|
+
/** Filter by entity type(s) */
|
|
324
|
+
type?: string | string[];
|
|
325
|
+
/** Filter by source PI(s) - scopes search to entities from specific PIs */
|
|
326
|
+
source_pi?: string | string[];
|
|
327
|
+
/** Filter by merged entity source PIs - for searching across collections */
|
|
328
|
+
merged_entities_source_pis?: string | string[];
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Options for direct semantic search
|
|
332
|
+
*/
|
|
333
|
+
interface SemanticSearchOptions {
|
|
334
|
+
/** Pinecone namespace to search (default: 'entities') */
|
|
335
|
+
namespace?: 'entities' | 'collections' | string;
|
|
336
|
+
/** Filter criteria */
|
|
337
|
+
filter?: SemanticSearchFilter;
|
|
338
|
+
/** Maximum number of results (default: 10, max: 100) */
|
|
339
|
+
top_k?: number;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Metadata returned with semantic search matches
|
|
343
|
+
*/
|
|
344
|
+
interface SemanticSearchMetadata {
|
|
345
|
+
/** Entity canonical ID */
|
|
346
|
+
canonical_id: string;
|
|
347
|
+
/** Entity label */
|
|
348
|
+
label: string;
|
|
349
|
+
/** Entity type */
|
|
350
|
+
type: string;
|
|
351
|
+
/** Entity code */
|
|
352
|
+
code?: string;
|
|
353
|
+
/** Source PI */
|
|
354
|
+
source_pi?: string;
|
|
355
|
+
/** Additional metadata fields */
|
|
356
|
+
[key: string]: unknown;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* A single match from semantic search
|
|
360
|
+
*/
|
|
361
|
+
interface SemanticSearchMatch {
|
|
362
|
+
/** Vector ID (usually canonical_id) */
|
|
363
|
+
id: string;
|
|
364
|
+
/** Similarity score (0-1, higher is more similar) */
|
|
365
|
+
score: number;
|
|
366
|
+
/** Entity metadata */
|
|
367
|
+
metadata?: SemanticSearchMetadata;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Response from semantic search
|
|
371
|
+
*/
|
|
372
|
+
interface SemanticSearchResponse {
|
|
373
|
+
/** Matching entities ordered by similarity */
|
|
374
|
+
matches: SemanticSearchMatch[];
|
|
375
|
+
}
|
|
319
376
|
/**
|
|
320
377
|
* Options for collection search
|
|
321
378
|
*/
|
|
@@ -504,6 +561,44 @@ declare class QueryClient {
|
|
|
504
561
|
service: string;
|
|
505
562
|
version: string;
|
|
506
563
|
}>;
|
|
564
|
+
/**
|
|
565
|
+
* Direct semantic search against the vector index.
|
|
566
|
+
*
|
|
567
|
+
* This bypasses the path query syntax and directly queries Pinecone for
|
|
568
|
+
* semantically similar entities. Useful for:
|
|
569
|
+
* - Simple semantic searches without graph traversal
|
|
570
|
+
* - Scoped searches filtered by source_pi (collection scope)
|
|
571
|
+
* - Type-filtered semantic searches
|
|
572
|
+
*
|
|
573
|
+
* For graph traversal and path-based queries, use `path()` instead.
|
|
574
|
+
*
|
|
575
|
+
* @param text - Search query text
|
|
576
|
+
* @param options - Search options (namespace, filters, top_k)
|
|
577
|
+
* @returns Matching entities with similarity scores
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* ```typescript
|
|
581
|
+
* // Simple semantic search
|
|
582
|
+
* const results = await query.semanticSearch('photographers from New York');
|
|
583
|
+
*
|
|
584
|
+
* // Scoped to a specific PI (collection)
|
|
585
|
+
* const scoped = await query.semanticSearch('portraits', {
|
|
586
|
+
* filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },
|
|
587
|
+
* top_k: 20,
|
|
588
|
+
* });
|
|
589
|
+
*
|
|
590
|
+
* // Filter by type
|
|
591
|
+
* const people = await query.semanticSearch('artists', {
|
|
592
|
+
* filter: { type: 'person' },
|
|
593
|
+
* });
|
|
594
|
+
*
|
|
595
|
+
* // Search across merged entities from multiple source PIs
|
|
596
|
+
* const merged = await query.semanticSearch('historical documents', {
|
|
597
|
+
* filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },
|
|
598
|
+
* });
|
|
599
|
+
* ```
|
|
600
|
+
*/
|
|
601
|
+
semanticSearch(text: string, options?: SemanticSearchOptions): Promise<SemanticSearchResponse>;
|
|
507
602
|
/**
|
|
508
603
|
* Search for collections by semantic similarity.
|
|
509
604
|
*
|
|
@@ -538,4 +633,4 @@ declare class QueryError extends Error {
|
|
|
538
633
|
constructor(message: string, code?: string, details?: unknown | undefined);
|
|
539
634
|
}
|
|
540
635
|
|
|
541
|
-
export { type ASTNodeType, type CollectionSearchOptions, type CollectionSearchResponse, type CollectionSearchResult, type EdgeTypeDoc, type EnrichedContent, type Entity, type EntryAST, type EntryPointDoc, type ExampleDoc, type FilterAST, type FilterTypeDoc, type HopAST, type LineageFilter, type LineageMetadata, type NaturalQueryOptions, type NaturalQueryResult, type ParameterDoc, type ParseError, type ParseResult, type PathAST, type PathQueryOptions, type PathStep, QueryClient, type QueryClientConfig, QueryError, type QueryMetadata, type QueryResult, type QueryResultItem, type SyntaxDocumentation, type TranslateResult, type TranslationInfo, type VariableDepthDoc };
|
|
636
|
+
export { type ASTNodeType, type CollectionSearchOptions, type CollectionSearchResponse, type CollectionSearchResult, type EdgeTypeDoc, type EnrichedContent, type Entity, type EntryAST, type EntryPointDoc, type ExampleDoc, type FilterAST, type FilterTypeDoc, type HopAST, type LineageFilter, type LineageMetadata, type NaturalQueryOptions, type NaturalQueryResult, type ParameterDoc, type ParseError, type ParseResult, type PathAST, type PathQueryOptions, type PathStep, QueryClient, type QueryClientConfig, QueryError, type QueryMetadata, type QueryResult, type QueryResultItem, type SemanticSearchFilter, type SemanticSearchMatch, type SemanticSearchMetadata, type SemanticSearchOptions, type SemanticSearchResponse, type SyntaxDocumentation, type TranslateResult, type TranslationInfo, type VariableDepthDoc };
|
package/dist/query/index.d.ts
CHANGED
|
@@ -316,6 +316,63 @@ interface SyntaxDocumentation {
|
|
|
316
316
|
constraints: string[];
|
|
317
317
|
errors: Record<string, string>;
|
|
318
318
|
}
|
|
319
|
+
/**
|
|
320
|
+
* Filter options for semantic search
|
|
321
|
+
*/
|
|
322
|
+
interface SemanticSearchFilter {
|
|
323
|
+
/** Filter by entity type(s) */
|
|
324
|
+
type?: string | string[];
|
|
325
|
+
/** Filter by source PI(s) - scopes search to entities from specific PIs */
|
|
326
|
+
source_pi?: string | string[];
|
|
327
|
+
/** Filter by merged entity source PIs - for searching across collections */
|
|
328
|
+
merged_entities_source_pis?: string | string[];
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Options for direct semantic search
|
|
332
|
+
*/
|
|
333
|
+
interface SemanticSearchOptions {
|
|
334
|
+
/** Pinecone namespace to search (default: 'entities') */
|
|
335
|
+
namespace?: 'entities' | 'collections' | string;
|
|
336
|
+
/** Filter criteria */
|
|
337
|
+
filter?: SemanticSearchFilter;
|
|
338
|
+
/** Maximum number of results (default: 10, max: 100) */
|
|
339
|
+
top_k?: number;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Metadata returned with semantic search matches
|
|
343
|
+
*/
|
|
344
|
+
interface SemanticSearchMetadata {
|
|
345
|
+
/** Entity canonical ID */
|
|
346
|
+
canonical_id: string;
|
|
347
|
+
/** Entity label */
|
|
348
|
+
label: string;
|
|
349
|
+
/** Entity type */
|
|
350
|
+
type: string;
|
|
351
|
+
/** Entity code */
|
|
352
|
+
code?: string;
|
|
353
|
+
/** Source PI */
|
|
354
|
+
source_pi?: string;
|
|
355
|
+
/** Additional metadata fields */
|
|
356
|
+
[key: string]: unknown;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* A single match from semantic search
|
|
360
|
+
*/
|
|
361
|
+
interface SemanticSearchMatch {
|
|
362
|
+
/** Vector ID (usually canonical_id) */
|
|
363
|
+
id: string;
|
|
364
|
+
/** Similarity score (0-1, higher is more similar) */
|
|
365
|
+
score: number;
|
|
366
|
+
/** Entity metadata */
|
|
367
|
+
metadata?: SemanticSearchMetadata;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Response from semantic search
|
|
371
|
+
*/
|
|
372
|
+
interface SemanticSearchResponse {
|
|
373
|
+
/** Matching entities ordered by similarity */
|
|
374
|
+
matches: SemanticSearchMatch[];
|
|
375
|
+
}
|
|
319
376
|
/**
|
|
320
377
|
* Options for collection search
|
|
321
378
|
*/
|
|
@@ -504,6 +561,44 @@ declare class QueryClient {
|
|
|
504
561
|
service: string;
|
|
505
562
|
version: string;
|
|
506
563
|
}>;
|
|
564
|
+
/**
|
|
565
|
+
* Direct semantic search against the vector index.
|
|
566
|
+
*
|
|
567
|
+
* This bypasses the path query syntax and directly queries Pinecone for
|
|
568
|
+
* semantically similar entities. Useful for:
|
|
569
|
+
* - Simple semantic searches without graph traversal
|
|
570
|
+
* - Scoped searches filtered by source_pi (collection scope)
|
|
571
|
+
* - Type-filtered semantic searches
|
|
572
|
+
*
|
|
573
|
+
* For graph traversal and path-based queries, use `path()` instead.
|
|
574
|
+
*
|
|
575
|
+
* @param text - Search query text
|
|
576
|
+
* @param options - Search options (namespace, filters, top_k)
|
|
577
|
+
* @returns Matching entities with similarity scores
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* ```typescript
|
|
581
|
+
* // Simple semantic search
|
|
582
|
+
* const results = await query.semanticSearch('photographers from New York');
|
|
583
|
+
*
|
|
584
|
+
* // Scoped to a specific PI (collection)
|
|
585
|
+
* const scoped = await query.semanticSearch('portraits', {
|
|
586
|
+
* filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },
|
|
587
|
+
* top_k: 20,
|
|
588
|
+
* });
|
|
589
|
+
*
|
|
590
|
+
* // Filter by type
|
|
591
|
+
* const people = await query.semanticSearch('artists', {
|
|
592
|
+
* filter: { type: 'person' },
|
|
593
|
+
* });
|
|
594
|
+
*
|
|
595
|
+
* // Search across merged entities from multiple source PIs
|
|
596
|
+
* const merged = await query.semanticSearch('historical documents', {
|
|
597
|
+
* filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },
|
|
598
|
+
* });
|
|
599
|
+
* ```
|
|
600
|
+
*/
|
|
601
|
+
semanticSearch(text: string, options?: SemanticSearchOptions): Promise<SemanticSearchResponse>;
|
|
507
602
|
/**
|
|
508
603
|
* Search for collections by semantic similarity.
|
|
509
604
|
*
|
|
@@ -538,4 +633,4 @@ declare class QueryError extends Error {
|
|
|
538
633
|
constructor(message: string, code?: string, details?: unknown | undefined);
|
|
539
634
|
}
|
|
540
635
|
|
|
541
|
-
export { type ASTNodeType, type CollectionSearchOptions, type CollectionSearchResponse, type CollectionSearchResult, type EdgeTypeDoc, type EnrichedContent, type Entity, type EntryAST, type EntryPointDoc, type ExampleDoc, type FilterAST, type FilterTypeDoc, type HopAST, type LineageFilter, type LineageMetadata, type NaturalQueryOptions, type NaturalQueryResult, type ParameterDoc, type ParseError, type ParseResult, type PathAST, type PathQueryOptions, type PathStep, QueryClient, type QueryClientConfig, QueryError, type QueryMetadata, type QueryResult, type QueryResultItem, type SyntaxDocumentation, type TranslateResult, type TranslationInfo, type VariableDepthDoc };
|
|
636
|
+
export { type ASTNodeType, type CollectionSearchOptions, type CollectionSearchResponse, type CollectionSearchResult, type EdgeTypeDoc, type EnrichedContent, type Entity, type EntryAST, type EntryPointDoc, type ExampleDoc, type FilterAST, type FilterTypeDoc, type HopAST, type LineageFilter, type LineageMetadata, type NaturalQueryOptions, type NaturalQueryResult, type ParameterDoc, type ParseError, type ParseResult, type PathAST, type PathQueryOptions, type PathStep, QueryClient, type QueryClientConfig, QueryError, type QueryMetadata, type QueryResult, type QueryResultItem, type SemanticSearchFilter, type SemanticSearchMatch, type SemanticSearchMetadata, type SemanticSearchOptions, type SemanticSearchResponse, type SyntaxDocumentation, type TranslateResult, type TranslationInfo, type VariableDepthDoc };
|
package/dist/query/index.js
CHANGED
|
@@ -221,6 +221,73 @@ var QueryClient = class {
|
|
|
221
221
|
async health() {
|
|
222
222
|
return this.request("/query/health", { method: "GET" });
|
|
223
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Direct semantic search against the vector index.
|
|
226
|
+
*
|
|
227
|
+
* This bypasses the path query syntax and directly queries Pinecone for
|
|
228
|
+
* semantically similar entities. Useful for:
|
|
229
|
+
* - Simple semantic searches without graph traversal
|
|
230
|
+
* - Scoped searches filtered by source_pi (collection scope)
|
|
231
|
+
* - Type-filtered semantic searches
|
|
232
|
+
*
|
|
233
|
+
* For graph traversal and path-based queries, use `path()` instead.
|
|
234
|
+
*
|
|
235
|
+
* @param text - Search query text
|
|
236
|
+
* @param options - Search options (namespace, filters, top_k)
|
|
237
|
+
* @returns Matching entities with similarity scores
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* ```typescript
|
|
241
|
+
* // Simple semantic search
|
|
242
|
+
* const results = await query.semanticSearch('photographers from New York');
|
|
243
|
+
*
|
|
244
|
+
* // Scoped to a specific PI (collection)
|
|
245
|
+
* const scoped = await query.semanticSearch('portraits', {
|
|
246
|
+
* filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },
|
|
247
|
+
* top_k: 20,
|
|
248
|
+
* });
|
|
249
|
+
*
|
|
250
|
+
* // Filter by type
|
|
251
|
+
* const people = await query.semanticSearch('artists', {
|
|
252
|
+
* filter: { type: 'person' },
|
|
253
|
+
* });
|
|
254
|
+
*
|
|
255
|
+
* // Search across merged entities from multiple source PIs
|
|
256
|
+
* const merged = await query.semanticSearch('historical documents', {
|
|
257
|
+
* filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },
|
|
258
|
+
* });
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
async semanticSearch(text, options = {}) {
|
|
262
|
+
let pineconeFilter;
|
|
263
|
+
if (options.filter) {
|
|
264
|
+
pineconeFilter = {};
|
|
265
|
+
if (options.filter.type) {
|
|
266
|
+
const types = Array.isArray(options.filter.type) ? options.filter.type : [options.filter.type];
|
|
267
|
+
pineconeFilter.type = types.length === 1 ? { $eq: types[0] } : { $in: types };
|
|
268
|
+
}
|
|
269
|
+
if (options.filter.source_pi) {
|
|
270
|
+
const pis = Array.isArray(options.filter.source_pi) ? options.filter.source_pi : [options.filter.source_pi];
|
|
271
|
+
pineconeFilter.source_pi = pis.length === 1 ? { $eq: pis[0] } : { $in: pis };
|
|
272
|
+
}
|
|
273
|
+
if (options.filter.merged_entities_source_pis) {
|
|
274
|
+
const pis = Array.isArray(options.filter.merged_entities_source_pis) ? options.filter.merged_entities_source_pis : [options.filter.merged_entities_source_pis];
|
|
275
|
+
pineconeFilter.merged_entities_source_pis = { $in: pis };
|
|
276
|
+
}
|
|
277
|
+
if (Object.keys(pineconeFilter).length === 0) {
|
|
278
|
+
pineconeFilter = void 0;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return this.request("/query/search/semantic", {
|
|
282
|
+
method: "POST",
|
|
283
|
+
body: JSON.stringify({
|
|
284
|
+
text,
|
|
285
|
+
namespace: options.namespace,
|
|
286
|
+
filter: pineconeFilter,
|
|
287
|
+
top_k: options.top_k
|
|
288
|
+
})
|
|
289
|
+
});
|
|
290
|
+
}
|
|
224
291
|
/**
|
|
225
292
|
* Search for collections by semantic similarity.
|
|
226
293
|
*
|
package/dist/query/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/query/errors.ts","../../src/query/client.ts"],"sourcesContent":["/**\n * Error class for query operations\n */\nexport class QueryError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'QueryError';\n }\n}\n","import { QueryError } from './errors';\nimport type {\n PathQueryOptions,\n NaturalQueryOptions,\n QueryResult,\n NaturalQueryResult,\n TranslateResult,\n ParseResult,\n ParseError,\n SyntaxDocumentation,\n CollectionSearchOptions,\n CollectionSearchResponse,\n} from './types';\n\n/**\n * Configuration for QueryClient\n */\nexport interface QueryClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /query/* endpoints.\n */\n gatewayUrl: string;\n /**\n * Optional custom fetch implementation (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\n/**\n * Client for querying the Arke knowledge graph.\n *\n * All query endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const query = new QueryClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Direct path query\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person');\n *\n * // Natural language query\n * const nlResults = await query.natural('Find photographers connected to Alice Austen');\n *\n * // Get syntax documentation\n * const syntax = await query.syntax();\n * ```\n */\nexport class QueryClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: QueryClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | undefined>) {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n return url.toString();\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n query?: Record<string, string | undefined>;\n } = {}\n ): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (options.headers) {\n Object.entries(options.headers).forEach(([k, v]) => {\n if (v !== undefined) headers.set(k, v as string);\n });\n }\n\n const response = await this.fetchImpl(url, { ...options, headers });\n\n if (response.ok) {\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n }\n\n let body: unknown;\n const text = await response.text();\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : (body as JsonBody)?.message && typeof (body as JsonBody).message === 'string'\n ? ((body as JsonBody).message as string)\n : `Request failed with status ${response.status}`;\n\n throw new QueryError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Query methods\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a path query against the knowledge graph.\n *\n * @param pathQuery - The path query string (e.g., '\"alice austen\" -[*]{,4}-> type:person')\n * @param options - Query options (k, k_explore, lineage, enrich, etc.)\n * @returns Query results with entities, paths, and metadata\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.path('\"Washington\" type:person');\n *\n * // Multi-hop traversal\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person ~ \"photographer\"');\n *\n * // With lineage filtering (collection scope)\n * const results = await query.path('\"letters\" type:document', {\n * lineage: { sourcePi: 'arke:my_collection', direction: 'descendants' },\n * k: 10,\n * });\n * ```\n */\n async path(pathQuery: string, options: PathQueryOptions = {}): Promise<QueryResult> {\n return this.request<QueryResult>('/query/path', {\n method: 'POST',\n body: JSON.stringify({\n path: pathQuery,\n ...options,\n }),\n });\n }\n\n /**\n * Execute a natural language query.\n *\n * The query is translated to a path query using an LLM, then executed.\n *\n * @param question - Natural language question\n * @param options - Query options including custom_instructions for the LLM\n * @returns Query results with translation info\n *\n * @example\n * ```typescript\n * const results = await query.natural('Find photographers connected to Alice Austen');\n * console.log('Generated query:', results.translation.path);\n * console.log('Explanation:', results.translation.explanation);\n * ```\n */\n async natural(question: string, options: NaturalQueryOptions = {}): Promise<NaturalQueryResult> {\n const { custom_instructions, ...queryOptions } = options;\n return this.request<NaturalQueryResult>('/query/natural', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions,\n ...queryOptions,\n }),\n });\n }\n\n /**\n * Translate a natural language question to a path query without executing it.\n *\n * Useful for understanding how questions are translated or for manual execution later.\n *\n * @param question - Natural language question\n * @param customInstructions - Optional additional instructions for the LLM\n * @returns Translation result with path query and explanation\n *\n * @example\n * ```typescript\n * const result = await query.translate('Who wrote letters from Philadelphia?');\n * console.log('Path query:', result.path);\n * // '\"letters\" <-[authored, wrote]- type:person -[located]-> \"Philadelphia\"'\n * ```\n */\n async translate(question: string, customInstructions?: string): Promise<TranslateResult> {\n return this.request<TranslateResult>('/query/translate', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions: customInstructions,\n }),\n });\n }\n\n /**\n * Parse and validate a path query without executing it.\n *\n * Returns the AST (Abstract Syntax Tree) if valid, or throws an error.\n *\n * @param pathQuery - The path query to parse\n * @returns Parsed AST\n * @throws QueryError if the query has syntax errors\n *\n * @example\n * ```typescript\n * try {\n * const result = await query.parse('\"test\" -[*]-> type:person');\n * console.log('Valid query, AST:', result.ast);\n * } catch (err) {\n * console.error('Invalid query:', err.message);\n * }\n * ```\n */\n async parse(pathQuery: string): Promise<ParseResult> {\n const url = this.buildUrl('/query/parse', { path: pathQuery });\n const response = await this.fetchImpl(url, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n const body = await response.json() as ParseResult | ParseError;\n\n // Check if it's an error response (parse errors return 400)\n if ('error' in body && body.error === 'Parse error') {\n throw new QueryError(\n (body as ParseError).message,\n 'PARSE_ERROR',\n { position: (body as ParseError).position }\n );\n }\n\n if (!response.ok) {\n throw new QueryError(\n (body as any).error || `Request failed with status ${response.status}`,\n 'HTTP_ERROR',\n { status: response.status, body }\n );\n }\n\n return body as ParseResult;\n }\n\n /**\n * Get the path query syntax documentation.\n *\n * Returns comprehensive documentation including entry points, edge traversal,\n * filters, examples, and constraints.\n *\n * @returns Syntax documentation\n *\n * @example\n * ```typescript\n * const syntax = await query.syntax();\n *\n * // List all entry point types\n * syntax.entryPoints.types.forEach(ep => {\n * console.log(`${ep.syntax} - ${ep.description}`);\n * });\n *\n * // Show examples\n * syntax.examples.forEach(ex => {\n * console.log(`${ex.description}: ${ex.query}`);\n * });\n * ```\n */\n async syntax(): Promise<SyntaxDocumentation> {\n return this.request<SyntaxDocumentation>('/query/syntax', {\n method: 'GET',\n });\n }\n\n /**\n * Check the health of the query service.\n *\n * @returns Health status\n */\n async health(): Promise<{ status: string; service: string; version: string }> {\n return this.request('/query/health', { method: 'GET' });\n }\n\n /**\n * Search for collections by semantic similarity.\n *\n * Searches the dedicated collections index for fast semantic matching.\n *\n * @param query - Search query text\n * @param options - Search options (limit, visibility filter)\n * @returns Matching collections with similarity scores\n *\n * @example\n * ```typescript\n * // Search for photography-related collections\n * const results = await query.searchCollections('photography');\n * console.log(results.collections[0].title);\n *\n * // Search only public collections\n * const publicResults = await query.searchCollections('history', {\n * visibility: 'public',\n * limit: 20,\n * });\n * ```\n */\n async searchCollections(\n query: string,\n options: CollectionSearchOptions = {}\n ): Promise<CollectionSearchResponse> {\n return this.request<CollectionSearchResponse>('/query/search/collections', {\n method: 'GET',\n query: {\n q: query,\n limit: options.limit?.toString(),\n visibility: options.visibility,\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/query/errors.ts","../../src/query/client.ts"],"sourcesContent":["/**\n * Error class for query operations\n */\nexport class QueryError extends Error {\n constructor(\n message: string,\n public code: string = 'UNKNOWN_ERROR',\n public details?: unknown\n ) {\n super(message);\n this.name = 'QueryError';\n }\n}\n","import { QueryError } from './errors';\nimport type {\n PathQueryOptions,\n NaturalQueryOptions,\n QueryResult,\n NaturalQueryResult,\n TranslateResult,\n ParseResult,\n ParseError,\n SyntaxDocumentation,\n SemanticSearchOptions,\n SemanticSearchResponse,\n CollectionSearchOptions,\n CollectionSearchResponse,\n} from './types';\n\n/**\n * Configuration for QueryClient\n */\nexport interface QueryClientConfig {\n /**\n * Gateway base URL (e.g., https://gateway.arke.institute).\n * The client will call /query/* endpoints.\n */\n gatewayUrl: string;\n /**\n * Optional custom fetch implementation (useful for testing).\n */\n fetchImpl?: typeof fetch;\n}\n\ntype JsonBody = Record<string, unknown>;\n\n/**\n * Client for querying the Arke knowledge graph.\n *\n * All query endpoints are public and do not require authentication.\n *\n * @example\n * ```typescript\n * const query = new QueryClient({\n * gatewayUrl: 'https://gateway.arke.institute',\n * });\n *\n * // Direct path query\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person');\n *\n * // Natural language query\n * const nlResults = await query.natural('Find photographers connected to Alice Austen');\n *\n * // Get syntax documentation\n * const syntax = await query.syntax();\n * ```\n */\nexport class QueryClient {\n private baseUrl: string;\n private fetchImpl: typeof fetch;\n\n constructor(config: QueryClientConfig) {\n this.baseUrl = config.gatewayUrl.replace(/\\/$/, '');\n this.fetchImpl = config.fetchImpl ?? fetch;\n }\n\n // ---------------------------------------------------------------------------\n // Request helpers\n // ---------------------------------------------------------------------------\n\n private buildUrl(path: string, query?: Record<string, string | undefined>) {\n const url = new URL(`${this.baseUrl}${path}`);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n });\n }\n return url.toString();\n }\n\n private async request<T>(\n path: string,\n options: RequestInit & {\n query?: Record<string, string | undefined>;\n } = {}\n ): Promise<T> {\n const url = this.buildUrl(path, options.query);\n const headers = new Headers({ 'Content-Type': 'application/json' });\n if (options.headers) {\n Object.entries(options.headers).forEach(([k, v]) => {\n if (v !== undefined) headers.set(k, v as string);\n });\n }\n\n const response = await this.fetchImpl(url, { ...options, headers });\n\n if (response.ok) {\n const contentType = response.headers.get('content-type') || '';\n if (contentType.includes('application/json')) {\n return (await response.json()) as T;\n }\n return (await response.text()) as unknown as T;\n }\n\n let body: unknown;\n const text = await response.text();\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n\n const message =\n (body as JsonBody)?.error && typeof (body as JsonBody).error === 'string'\n ? ((body as JsonBody).error as string)\n : (body as JsonBody)?.message && typeof (body as JsonBody).message === 'string'\n ? ((body as JsonBody).message as string)\n : `Request failed with status ${response.status}`;\n\n throw new QueryError(message, 'HTTP_ERROR', {\n status: response.status,\n body,\n });\n }\n\n // ---------------------------------------------------------------------------\n // Query methods\n // ---------------------------------------------------------------------------\n\n /**\n * Execute a path query against the knowledge graph.\n *\n * @param pathQuery - The path query string (e.g., '\"alice austen\" -[*]{,4}-> type:person')\n * @param options - Query options (k, k_explore, lineage, enrich, etc.)\n * @returns Query results with entities, paths, and metadata\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.path('\"Washington\" type:person');\n *\n * // Multi-hop traversal\n * const results = await query.path('\"alice austen\" -[*]{,4}-> type:person ~ \"photographer\"');\n *\n * // With lineage filtering (collection scope)\n * const results = await query.path('\"letters\" type:document', {\n * lineage: { sourcePi: 'arke:my_collection', direction: 'descendants' },\n * k: 10,\n * });\n * ```\n */\n async path(pathQuery: string, options: PathQueryOptions = {}): Promise<QueryResult> {\n return this.request<QueryResult>('/query/path', {\n method: 'POST',\n body: JSON.stringify({\n path: pathQuery,\n ...options,\n }),\n });\n }\n\n /**\n * Execute a natural language query.\n *\n * The query is translated to a path query using an LLM, then executed.\n *\n * @param question - Natural language question\n * @param options - Query options including custom_instructions for the LLM\n * @returns Query results with translation info\n *\n * @example\n * ```typescript\n * const results = await query.natural('Find photographers connected to Alice Austen');\n * console.log('Generated query:', results.translation.path);\n * console.log('Explanation:', results.translation.explanation);\n * ```\n */\n async natural(question: string, options: NaturalQueryOptions = {}): Promise<NaturalQueryResult> {\n const { custom_instructions, ...queryOptions } = options;\n return this.request<NaturalQueryResult>('/query/natural', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions,\n ...queryOptions,\n }),\n });\n }\n\n /**\n * Translate a natural language question to a path query without executing it.\n *\n * Useful for understanding how questions are translated or for manual execution later.\n *\n * @param question - Natural language question\n * @param customInstructions - Optional additional instructions for the LLM\n * @returns Translation result with path query and explanation\n *\n * @example\n * ```typescript\n * const result = await query.translate('Who wrote letters from Philadelphia?');\n * console.log('Path query:', result.path);\n * // '\"letters\" <-[authored, wrote]- type:person -[located]-> \"Philadelphia\"'\n * ```\n */\n async translate(question: string, customInstructions?: string): Promise<TranslateResult> {\n return this.request<TranslateResult>('/query/translate', {\n method: 'POST',\n body: JSON.stringify({\n query: question,\n custom_instructions: customInstructions,\n }),\n });\n }\n\n /**\n * Parse and validate a path query without executing it.\n *\n * Returns the AST (Abstract Syntax Tree) if valid, or throws an error.\n *\n * @param pathQuery - The path query to parse\n * @returns Parsed AST\n * @throws QueryError if the query has syntax errors\n *\n * @example\n * ```typescript\n * try {\n * const result = await query.parse('\"test\" -[*]-> type:person');\n * console.log('Valid query, AST:', result.ast);\n * } catch (err) {\n * console.error('Invalid query:', err.message);\n * }\n * ```\n */\n async parse(pathQuery: string): Promise<ParseResult> {\n const url = this.buildUrl('/query/parse', { path: pathQuery });\n const response = await this.fetchImpl(url, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json' },\n });\n\n const body = await response.json() as ParseResult | ParseError;\n\n // Check if it's an error response (parse errors return 400)\n if ('error' in body && body.error === 'Parse error') {\n throw new QueryError(\n (body as ParseError).message,\n 'PARSE_ERROR',\n { position: (body as ParseError).position }\n );\n }\n\n if (!response.ok) {\n throw new QueryError(\n (body as any).error || `Request failed with status ${response.status}`,\n 'HTTP_ERROR',\n { status: response.status, body }\n );\n }\n\n return body as ParseResult;\n }\n\n /**\n * Get the path query syntax documentation.\n *\n * Returns comprehensive documentation including entry points, edge traversal,\n * filters, examples, and constraints.\n *\n * @returns Syntax documentation\n *\n * @example\n * ```typescript\n * const syntax = await query.syntax();\n *\n * // List all entry point types\n * syntax.entryPoints.types.forEach(ep => {\n * console.log(`${ep.syntax} - ${ep.description}`);\n * });\n *\n * // Show examples\n * syntax.examples.forEach(ex => {\n * console.log(`${ex.description}: ${ex.query}`);\n * });\n * ```\n */\n async syntax(): Promise<SyntaxDocumentation> {\n return this.request<SyntaxDocumentation>('/query/syntax', {\n method: 'GET',\n });\n }\n\n /**\n * Check the health of the query service.\n *\n * @returns Health status\n */\n async health(): Promise<{ status: string; service: string; version: string }> {\n return this.request('/query/health', { method: 'GET' });\n }\n\n /**\n * Direct semantic search against the vector index.\n *\n * This bypasses the path query syntax and directly queries Pinecone for\n * semantically similar entities. Useful for:\n * - Simple semantic searches without graph traversal\n * - Scoped searches filtered by source_pi (collection scope)\n * - Type-filtered semantic searches\n *\n * For graph traversal and path-based queries, use `path()` instead.\n *\n * @param text - Search query text\n * @param options - Search options (namespace, filters, top_k)\n * @returns Matching entities with similarity scores\n *\n * @example\n * ```typescript\n * // Simple semantic search\n * const results = await query.semanticSearch('photographers from New York');\n *\n * // Scoped to a specific PI (collection)\n * const scoped = await query.semanticSearch('portraits', {\n * filter: { source_pi: '01K75HQQXNTDG7BBP7PS9AWYAN' },\n * top_k: 20,\n * });\n *\n * // Filter by type\n * const people = await query.semanticSearch('artists', {\n * filter: { type: 'person' },\n * });\n *\n * // Search across merged entities from multiple source PIs\n * const merged = await query.semanticSearch('historical documents', {\n * filter: { merged_entities_source_pis: ['pi-1', 'pi-2'] },\n * });\n * ```\n */\n async semanticSearch(\n text: string,\n options: SemanticSearchOptions = {}\n ): Promise<SemanticSearchResponse> {\n // Build Pinecone-compatible filter from our typed filter\n let pineconeFilter: Record<string, unknown> | undefined;\n\n if (options.filter) {\n pineconeFilter = {};\n\n if (options.filter.type) {\n const types = Array.isArray(options.filter.type)\n ? options.filter.type\n : [options.filter.type];\n pineconeFilter.type = types.length === 1\n ? { $eq: types[0] }\n : { $in: types };\n }\n\n if (options.filter.source_pi) {\n const pis = Array.isArray(options.filter.source_pi)\n ? options.filter.source_pi\n : [options.filter.source_pi];\n pineconeFilter.source_pi = pis.length === 1\n ? { $eq: pis[0] }\n : { $in: pis };\n }\n\n if (options.filter.merged_entities_source_pis) {\n const pis = Array.isArray(options.filter.merged_entities_source_pis)\n ? options.filter.merged_entities_source_pis\n : [options.filter.merged_entities_source_pis];\n // Use $in for array field matching (any of the provided PIs)\n pineconeFilter.merged_entities_source_pis = { $in: pis };\n }\n\n // If no filters were actually set, clear the object\n if (Object.keys(pineconeFilter).length === 0) {\n pineconeFilter = undefined;\n }\n }\n\n return this.request<SemanticSearchResponse>('/query/search/semantic', {\n method: 'POST',\n body: JSON.stringify({\n text,\n namespace: options.namespace,\n filter: pineconeFilter,\n top_k: options.top_k,\n }),\n });\n }\n\n /**\n * Search for collections by semantic similarity.\n *\n * Searches the dedicated collections index for fast semantic matching.\n *\n * @param query - Search query text\n * @param options - Search options (limit, visibility filter)\n * @returns Matching collections with similarity scores\n *\n * @example\n * ```typescript\n * // Search for photography-related collections\n * const results = await query.searchCollections('photography');\n * console.log(results.collections[0].title);\n *\n * // Search only public collections\n * const publicResults = await query.searchCollections('history', {\n * visibility: 'public',\n * limit: 20,\n * });\n * ```\n */\n async searchCollections(\n query: string,\n options: CollectionSearchOptions = {}\n ): Promise<CollectionSearchResponse> {\n return this.request<CollectionSearchResponse>('/query/search/collections', {\n method: 'GET',\n query: {\n q: query,\n limit: options.limit?.toString(),\n visibility: options.visibility,\n },\n });\n }\n}\n"],"mappings":"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","names":[]}
|