rust-kgdb 0.6.80 → 0.6.82

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.
@@ -1642,6 +1642,89 @@ class ProofDAG {
1642
1642
  )
1643
1643
  }
1644
1644
 
1645
+ /**
1646
+ * Add federation query as evidence (HyperFederate cross-database queries)
1647
+ *
1648
+ * Records federated SQL execution across KGDB + Snowflake + BigQuery as
1649
+ * provenance evidence in the proof DAG. Supports full lineage tracking
1650
+ * for cross-database queries with W3C PROV compatibility.
1651
+ *
1652
+ * @param {string} parentId - Parent node ID
1653
+ * @param {string} sql - Federated SQL query
1654
+ * @param {string[]} sources - Data sources involved (e.g., ['kgdb', 'snowflake', 'bigquery'])
1655
+ * @param {number} rowCount - Number of rows returned
1656
+ * @param {number} duration - Query duration in ms
1657
+ * @param {Object} metadata - Additional metadata (planHash, cached, etc.)
1658
+ * @returns {string} New node ID
1659
+ */
1660
+ addFederationEvidence(parentId, sql, sources, rowCount, duration, metadata = {}) {
1661
+ return this.addEvidence(
1662
+ parentId,
1663
+ `Federated query across ${sources.join(', ')} returned ${rowCount} rows in ${duration}ms`,
1664
+ {
1665
+ type: 'federation',
1666
+ sql: sql.slice(0, 500), // Truncate long queries
1667
+ sources,
1668
+ rowCount,
1669
+ duration,
1670
+ planHash: metadata.planHash,
1671
+ cached: metadata.cached || false,
1672
+ // W3C PROV compatibility
1673
+ wasGeneratedBy: 'hyperfederate:QueryExecution',
1674
+ wasDerivedFrom: sources.map(s => `hyperfederate:DataSource/${s}`)
1675
+ },
1676
+ 'FEDERATION_QUERY'
1677
+ )
1678
+ }
1679
+
1680
+ /**
1681
+ * Add virtual table creation as evidence
1682
+ *
1683
+ * @param {string} parentId - Parent node ID
1684
+ * @param {string} tableName - Virtual table name
1685
+ * @param {string} sql - SQL query that defines the virtual table
1686
+ * @param {number} rowCount - Number of rows materialized
1687
+ * @returns {string} New node ID
1688
+ */
1689
+ addVirtualTableEvidence(parentId, tableName, sql, rowCount) {
1690
+ return this.addEvidence(
1691
+ parentId,
1692
+ `Created virtual table '${tableName}' with ${rowCount} rows`,
1693
+ {
1694
+ type: 'virtual_table',
1695
+ tableName,
1696
+ sql: sql.slice(0, 500),
1697
+ rowCount,
1698
+ wasGeneratedBy: 'hyperfederate:VirtualTableCreation'
1699
+ },
1700
+ 'VIRTUAL_TABLE_CREATE'
1701
+ )
1702
+ }
1703
+
1704
+ /**
1705
+ * Add catalog registration as evidence
1706
+ *
1707
+ * @param {string} parentId - Parent node ID
1708
+ * @param {string} productName - Data product name
1709
+ * @param {string[]} sources - Data sources
1710
+ * @param {string} productId - Registered product ID
1711
+ * @returns {string} New node ID
1712
+ */
1713
+ addCatalogEvidence(parentId, productName, sources, productId) {
1714
+ return this.addEvidence(
1715
+ parentId,
1716
+ `Registered data product '${productName}' from ${sources.length} sources`,
1717
+ {
1718
+ type: 'catalog',
1719
+ productName,
1720
+ productId,
1721
+ sources,
1722
+ wasGeneratedBy: 'hyperfederate:CatalogRegistration'
1723
+ },
1724
+ 'CATALOG_REGISTER'
1725
+ )
1726
+ }
1727
+
1645
1728
  /**
1646
1729
  * Compute deterministic hash of entire proof
1647
1730
  */
@@ -1819,6 +1902,542 @@ const TOOL_REGISTRY = {
1819
1902
  output: 'Distances',
1820
1903
  description: 'Compute shortest paths from landmarks',
1821
1904
  domain: 'kg'
1905
+ },
1906
+
1907
+ // ============================================================================
1908
+ // HyperFederate Federation Tools (Category Theory: Typed Morphisms)
1909
+ // Cross-database federation: KGDB + Snowflake + BigQuery + PostgreSQL + MySQL
1910
+ // ============================================================================
1911
+
1912
+ 'federation.sql.query': {
1913
+ name: 'federation.sql.query',
1914
+ input: 'FederatedQuery',
1915
+ output: 'RecordBatch',
1916
+ description: 'Execute federated SQL across KGDB + Snowflake + BigQuery',
1917
+ domain: 'federation',
1918
+ patterns: {
1919
+ cross_join: 'SELECT kg.*, sf.* FROM graph_search(...) kg JOIN snowflake.table sf ON ...',
1920
+ three_way: 'SELECT kg.*, sf.*, bq.* FROM graph_search(...) kg JOIN ... JOIN ...'
1921
+ },
1922
+ connectors: ['kgdb', 'snowflake', 'bigquery', 'postgres', 'mysql']
1923
+ },
1924
+ 'federation.virtual.create': {
1925
+ name: 'federation.virtual.create',
1926
+ input: 'VirtualTableSpec',
1927
+ output: 'VirtualTableId',
1928
+ description: 'Create session-bound virtual table from federation query',
1929
+ domain: 'federation'
1930
+ },
1931
+ 'federation.virtual.query': {
1932
+ name: 'federation.virtual.query',
1933
+ input: 'VirtualTableQuery',
1934
+ output: 'RecordBatch',
1935
+ description: 'Query existing virtual table',
1936
+ domain: 'federation'
1937
+ },
1938
+ 'federation.catalog.list': {
1939
+ name: 'federation.catalog.list',
1940
+ input: 'CatalogFilter',
1941
+ output: 'DataProductList',
1942
+ description: 'List data products in DCAT DPROD catalog',
1943
+ domain: 'federation'
1944
+ },
1945
+ 'federation.catalog.register': {
1946
+ name: 'federation.catalog.register',
1947
+ input: 'DataProductSpec',
1948
+ output: 'DataProductId',
1949
+ description: 'Register data product in catalog',
1950
+ domain: 'federation'
1951
+ },
1952
+ 'federation.udf.call': {
1953
+ name: 'federation.udf.call',
1954
+ input: 'UdfCall',
1955
+ output: 'UdfResult',
1956
+ description: 'Call semantic UDF (similar_to, neighbors, entity_type, etc.)',
1957
+ domain: 'federation',
1958
+ udfs: ['similar_to', 'text_search', 'neighbors', 'graph_pattern', 'sparql_query', 'entity_type', 'entity_properties']
1959
+ },
1960
+ 'federation.table_function.call': {
1961
+ name: 'federation.table_function.call',
1962
+ input: 'TableFunctionCall',
1963
+ output: 'RecordBatch',
1964
+ description: 'Call table function (graph_search, vector_search, pagerank, etc.)',
1965
+ domain: 'federation',
1966
+ functions: ['graph_search', 'vector_search', 'pagerank', 'connected_components', 'shortest_paths', 'triangle_count', 'label_propagation', 'datalog_reason', 'motif_search']
1967
+ }
1968
+ }
1969
+
1970
+ // Federation tools as separate constant for easy access
1971
+ const FEDERATION_TOOLS = {
1972
+ 'federation.sql.query': TOOL_REGISTRY['federation.sql.query'],
1973
+ 'federation.virtual.create': TOOL_REGISTRY['federation.virtual.create'],
1974
+ 'federation.virtual.query': TOOL_REGISTRY['federation.virtual.query'],
1975
+ 'federation.catalog.list': TOOL_REGISTRY['federation.catalog.list'],
1976
+ 'federation.catalog.register': TOOL_REGISTRY['federation.catalog.register'],
1977
+ 'federation.udf.call': TOOL_REGISTRY['federation.udf.call'],
1978
+ 'federation.table_function.call': TOOL_REGISTRY['federation.table_function.call']
1979
+ }
1980
+
1981
+ // ============================================================================
1982
+ // RPC FEDERATION PROXY - WASM RPC proxy for HyperFederate
1983
+ // ============================================================================
1984
+
1985
+ /**
1986
+ * RpcFederationProxy - WASM RPC proxy for HyperFederate cross-database federation
1987
+ *
1988
+ * This follows the same pattern as RpcKgdbStore mentioned in index.js:
1989
+ * "NOTE: QueryMemoryStore, HybridReranker, TriggerManager moved to Rust core
1990
+ * Access via HyperAgentProxy/WASM runtime (SDK remains thin)"
1991
+ *
1992
+ * Category Theory: Proxy is a natural transformation between local and remote execution
1993
+ * Type Theory: All operations are typed morphisms (Input → Output)
1994
+ * Proof Theory: Full audit log with provenance tracking
1995
+ *
1996
+ * Supports:
1997
+ * - Cross-database SQL: KGDB + Snowflake + BigQuery + PostgreSQL + MySQL
1998
+ * - Virtual Tables: Session-bound query result materialization
1999
+ * - Data Catalog: DCAT DPROD ontology for data product registration
2000
+ * - Semantic UDFs: 7 AI-powered functions (similar_to, neighbors, etc.)
2001
+ * - Table Functions: 9 graph analytics (graph_search, pagerank, etc.)
2002
+ */
2003
+ class RpcFederationProxy {
2004
+ /**
2005
+ * Create a new RpcFederationProxy
2006
+ * @param {Object} config - Configuration options
2007
+ * @param {string} config.endpoint - HyperFederate server endpoint (default: http://localhost:30180)
2008
+ * @param {number} config.timeout - Request timeout in ms (default: 30000)
2009
+ * @param {WasmSandbox} config.sandbox - WasmSandbox for capability-based security
2010
+ * @param {Object} config.headers - Additional HTTP headers
2011
+ */
2012
+ constructor(config = {}) {
2013
+ this.endpoint = config.endpoint || 'http://localhost:30180'
2014
+ this.timeout = config.timeout || 30000
2015
+ this.headers = config.headers || {}
2016
+
2017
+ // WasmSandbox for capability-based security with fuel metering
2018
+ // Includes 'Federation' capability for cross-database operations
2019
+ this.sandbox = config.sandbox || new WasmSandbox({
2020
+ capabilities: ['ReadKG', 'ExecuteTool', 'Federation'],
2021
+ fuelLimit: 100000
2022
+ })
2023
+
2024
+ // Audit log for provenance tracking (Proof Theory)
2025
+ this.auditLog = []
2026
+
2027
+ // Session ID for virtual table isolation
2028
+ this.sessionId = config.sessionId || `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
2029
+
2030
+ // Identity for access control
2031
+ this.identityId = config.identityId || 'anonymous'
2032
+ }
2033
+
2034
+ /**
2035
+ * Execute federated SQL query across multiple data sources
2036
+ *
2037
+ * Category Theory: FederatedQuery → RecordBatch morphism
2038
+ *
2039
+ * @param {string} sql - Federated SQL query (supports graph_search, snowflake.*, bigquery.*, etc.)
2040
+ * @param {Object} options - Query options
2041
+ * @param {number} options.limit - Result limit
2042
+ * @param {number} options.timeout - Query timeout in ms
2043
+ * @returns {Promise<Object>} RecordBatch result with columns, rows, metadata
2044
+ *
2045
+ * @example
2046
+ * const result = await proxy.query(`
2047
+ * SELECT kg.person, kg.riskScore, sf.C_NAME, sf.C_ACCTBAL
2048
+ * FROM graph_search('PREFIX finance: ... SELECT ?person ?riskScore WHERE {...}') kg
2049
+ * JOIN snowflake_tpch.CUSTOMER sf ON CAST(kg.custKey AS INT) = sf.C_CUSTKEY
2050
+ * LIMIT 10
2051
+ * `)
2052
+ */
2053
+ async query(sql, options = {}) {
2054
+ // Check capability
2055
+ if (!this.sandbox.hasCapability('Federation')) {
2056
+ throw new Error('Federation capability not granted')
2057
+ }
2058
+
2059
+ // Consume fuel for operation
2060
+ this.sandbox.consumeFuel(1000)
2061
+
2062
+ const start = Date.now()
2063
+
2064
+ try {
2065
+ // RPC call to HyperFederate server
2066
+ const response = await fetch(`${this.endpoint}/api/v1/query`, {
2067
+ method: 'POST',
2068
+ headers: {
2069
+ 'Content-Type': 'application/json',
2070
+ 'X-Session-Id': this.sessionId,
2071
+ 'X-Identity-Id': this.identityId,
2072
+ ...this.headers
2073
+ },
2074
+ body: JSON.stringify({
2075
+ sql,
2076
+ limit: options.limit,
2077
+ timeout: options.timeout || this.timeout
2078
+ }),
2079
+ signal: AbortSignal.timeout(options.timeout || this.timeout)
2080
+ })
2081
+
2082
+ if (!response.ok) {
2083
+ const error = await response.text()
2084
+ throw new Error(`Federation query failed: ${error}`)
2085
+ }
2086
+
2087
+ const result = await response.json()
2088
+ const duration = Date.now() - start
2089
+
2090
+ // Log to sandbox audit trail
2091
+ this.sandbox.log('federation.sql.query', { sql: sql.slice(0, 200) }, result, 'success')
2092
+
2093
+ // Add to audit log for provenance
2094
+ this.auditLog.push({
2095
+ action: 'query',
2096
+ sql,
2097
+ duration,
2098
+ rows: result.rows?.length || 0,
2099
+ timestamp: new Date().toISOString(),
2100
+ sessionId: this.sessionId
2101
+ })
2102
+
2103
+ return {
2104
+ columns: result.columns || [],
2105
+ rows: result.rows || [],
2106
+ rowCount: result.rows?.length || 0,
2107
+ duration,
2108
+ metadata: {
2109
+ sources: result.sources || [],
2110
+ planHash: result.planHash,
2111
+ cached: result.cached || false
2112
+ }
2113
+ }
2114
+ } catch (error) {
2115
+ this.sandbox.log('federation.sql.query', { sql: sql.slice(0, 200) }, null, 'error')
2116
+ this.auditLog.push({
2117
+ action: 'query',
2118
+ sql,
2119
+ error: error.message,
2120
+ timestamp: new Date().toISOString(),
2121
+ sessionId: this.sessionId
2122
+ })
2123
+ throw error
2124
+ }
2125
+ }
2126
+
2127
+ /**
2128
+ * Create a virtual table from a federation query result
2129
+ *
2130
+ * Category Theory: VirtualTableSpec → VirtualTableId morphism
2131
+ *
2132
+ * Virtual tables are session-bound, stored as RDF triples in KGDB,
2133
+ * and support access control via shared_with and shared_with_groups.
2134
+ *
2135
+ * @param {string} name - Virtual table name
2136
+ * @param {string} sql - SQL query that defines the virtual table
2137
+ * @param {Object} options - Virtual table options
2138
+ * @param {string} options.refreshPolicy - 'on_demand' | 'ttl' | 'on_source_change'
2139
+ * @param {number} options.ttlSeconds - TTL in seconds (for 'ttl' policy)
2140
+ * @param {string[]} options.sharedWith - Identity IDs to share with
2141
+ * @param {string[]} options.sharedWithGroups - Group IDs to share with
2142
+ * @returns {Promise<Object>} Virtual table metadata
2143
+ *
2144
+ * @example
2145
+ * const vt = await proxy.createVirtualTable('high_risk_customers', `
2146
+ * SELECT kg.*, sf.C_ACCTBAL
2147
+ * FROM graph_search('...') kg
2148
+ * JOIN snowflake.CUSTOMER sf ON ...
2149
+ * WHERE kg.riskScore > 0.8
2150
+ * `, { refreshPolicy: 'on_demand', ttlSeconds: 3600 })
2151
+ */
2152
+ async createVirtualTable(name, sql, options = {}) {
2153
+ if (!this.sandbox.hasCapability('Federation')) {
2154
+ throw new Error('Federation capability not granted')
2155
+ }
2156
+
2157
+ this.sandbox.consumeFuel(500)
2158
+ const start = Date.now()
2159
+
2160
+ try {
2161
+ const response = await fetch(`${this.endpoint}/api/v1/tables`, {
2162
+ method: 'POST',
2163
+ headers: {
2164
+ 'Content-Type': 'application/json',
2165
+ 'X-Session-Id': this.sessionId,
2166
+ 'X-Identity-Id': this.identityId,
2167
+ ...this.headers
2168
+ },
2169
+ body: JSON.stringify({
2170
+ name,
2171
+ sql,
2172
+ refreshPolicy: options.refreshPolicy || 'on_demand',
2173
+ ttlSeconds: options.ttlSeconds || 3600,
2174
+ sharedWith: options.sharedWith || [],
2175
+ sharedWithGroups: options.sharedWithGroups || []
2176
+ }),
2177
+ signal: AbortSignal.timeout(this.timeout)
2178
+ })
2179
+
2180
+ if (!response.ok) {
2181
+ const error = await response.text()
2182
+ throw new Error(`Create virtual table failed: ${error}`)
2183
+ }
2184
+
2185
+ const result = await response.json()
2186
+ const duration = Date.now() - start
2187
+
2188
+ this.sandbox.log('federation.virtual.create', { name, sql: sql.slice(0, 100) }, result, 'success')
2189
+ this.auditLog.push({
2190
+ action: 'createVirtualTable',
2191
+ name,
2192
+ sql,
2193
+ duration,
2194
+ timestamp: new Date().toISOString(),
2195
+ sessionId: this.sessionId
2196
+ })
2197
+
2198
+ return {
2199
+ id: result.id,
2200
+ name: result.name || name,
2201
+ uri: result.uri,
2202
+ columns: result.columns || [],
2203
+ rowCount: result.rowCount,
2204
+ refreshPolicy: options.refreshPolicy || 'on_demand',
2205
+ createdAt: new Date().toISOString()
2206
+ }
2207
+ } catch (error) {
2208
+ this.sandbox.log('federation.virtual.create', { name }, null, 'error')
2209
+ throw error
2210
+ }
2211
+ }
2212
+
2213
+ /**
2214
+ * Query a virtual table
2215
+ *
2216
+ * @param {string} name - Virtual table name
2217
+ * @param {string} whereClauses - Optional WHERE clause conditions
2218
+ * @returns {Promise<Object>} Query result
2219
+ */
2220
+ async queryVirtualTable(name, whereClauses = '') {
2221
+ const sql = `SELECT * FROM virtual.${name}${whereClauses ? ` WHERE ${whereClauses}` : ''}`
2222
+ return this.query(sql)
2223
+ }
2224
+
2225
+ /**
2226
+ * List data products in the DCAT DPROD catalog
2227
+ *
2228
+ * Category Theory: CatalogFilter → DataProductList morphism
2229
+ *
2230
+ * @param {Object} filter - Filter options
2231
+ * @param {string} filter.owner - Filter by owner
2232
+ * @param {string[]} filter.sources - Filter by data sources
2233
+ * @param {string} filter.search - Search in name/description
2234
+ * @returns {Promise<Object[]>} List of data products
2235
+ */
2236
+ async listCatalog(filter = {}) {
2237
+ if (!this.sandbox.hasCapability('ReadKG')) {
2238
+ throw new Error('ReadKG capability not granted')
2239
+ }
2240
+
2241
+ this.sandbox.consumeFuel(100)
2242
+
2243
+ try {
2244
+ const params = new URLSearchParams()
2245
+ if (filter.owner) params.set('owner', filter.owner)
2246
+ if (filter.sources) params.set('sources', filter.sources.join(','))
2247
+ if (filter.search) params.set('search', filter.search)
2248
+
2249
+ const url = `${this.endpoint}/api/v1/catalog${params.toString() ? '?' + params.toString() : ''}`
2250
+
2251
+ const response = await fetch(url, {
2252
+ method: 'GET',
2253
+ headers: {
2254
+ 'Content-Type': 'application/json',
2255
+ 'X-Session-Id': this.sessionId,
2256
+ 'X-Identity-Id': this.identityId,
2257
+ ...this.headers
2258
+ },
2259
+ signal: AbortSignal.timeout(this.timeout)
2260
+ })
2261
+
2262
+ if (!response.ok) {
2263
+ const error = await response.text()
2264
+ throw new Error(`List catalog failed: ${error}`)
2265
+ }
2266
+
2267
+ const result = await response.json()
2268
+ this.sandbox.log('federation.catalog.list', filter, result, 'success')
2269
+
2270
+ return result.products || result
2271
+ } catch (error) {
2272
+ this.sandbox.log('federation.catalog.list', filter, null, 'error')
2273
+ throw error
2274
+ }
2275
+ }
2276
+
2277
+ /**
2278
+ * Register a data product in the DCAT DPROD catalog
2279
+ *
2280
+ * Category Theory: DataProductSpec → DataProductId morphism
2281
+ *
2282
+ * @param {Object} spec - Data product specification
2283
+ * @param {string} spec.name - Product name
2284
+ * @param {string} spec.description - Product description
2285
+ * @param {string[]} spec.sources - Data source identifiers
2286
+ * @param {string} spec.outputPort - API endpoint for querying
2287
+ * @param {Object} spec.schema - Column schema definition
2288
+ * @param {Object} spec.quality - Quality metrics (completeness, accuracy)
2289
+ * @param {string} spec.owner - Owner identity
2290
+ * @returns {Promise<Object>} Registered data product with ID
2291
+ *
2292
+ * @example
2293
+ * const product = await proxy.registerDataProduct({
2294
+ * name: 'High Risk Customer Analysis',
2295
+ * description: 'Cross-domain risk scoring combining KG + transactional data',
2296
+ * sources: ['kgdb', 'snowflake', 'bigquery'],
2297
+ * outputPort: '/api/v1/products/high-risk/query',
2298
+ * schema: { columns: [{ name: 'entity', type: 'STRING' }, ...] },
2299
+ * quality: { completeness: 0.98, accuracy: 0.95 },
2300
+ * owner: 'risk-analytics-team'
2301
+ * })
2302
+ */
2303
+ async registerDataProduct(spec) {
2304
+ if (!this.sandbox.hasCapability('Federation')) {
2305
+ throw new Error('Federation capability not granted')
2306
+ }
2307
+
2308
+ this.sandbox.consumeFuel(500)
2309
+
2310
+ try {
2311
+ const response = await fetch(`${this.endpoint}/api/v1/catalog`, {
2312
+ method: 'POST',
2313
+ headers: {
2314
+ 'Content-Type': 'application/json',
2315
+ 'X-Session-Id': this.sessionId,
2316
+ 'X-Identity-Id': this.identityId,
2317
+ ...this.headers
2318
+ },
2319
+ body: JSON.stringify(spec),
2320
+ signal: AbortSignal.timeout(this.timeout)
2321
+ })
2322
+
2323
+ if (!response.ok) {
2324
+ const error = await response.text()
2325
+ throw new Error(`Register data product failed: ${error}`)
2326
+ }
2327
+
2328
+ const result = await response.json()
2329
+ this.sandbox.log('federation.catalog.register', { name: spec.name }, result, 'success')
2330
+
2331
+ this.auditLog.push({
2332
+ action: 'registerDataProduct',
2333
+ name: spec.name,
2334
+ sources: spec.sources,
2335
+ timestamp: new Date().toISOString(),
2336
+ sessionId: this.sessionId
2337
+ })
2338
+
2339
+ return {
2340
+ id: result.id,
2341
+ uri: result.uri,
2342
+ name: spec.name,
2343
+ createdAt: new Date().toISOString()
2344
+ }
2345
+ } catch (error) {
2346
+ this.sandbox.log('federation.catalog.register', { name: spec.name }, null, 'error')
2347
+ throw error
2348
+ }
2349
+ }
2350
+
2351
+ /**
2352
+ * Call a semantic UDF (one of 7 AI-powered functions)
2353
+ *
2354
+ * Available UDFs:
2355
+ * - similar_to(entity, threshold) - Find semantically similar entities via RDF2Vec
2356
+ * - text_search(query, limit) - Semantic text search
2357
+ * - neighbors(entity, hops) - N-hop graph traversal
2358
+ * - graph_pattern(s, p, o) - Triple pattern matching
2359
+ * - sparql_query(sparql) - Inline SPARQL execution
2360
+ * - entity_type(entity) - Get RDF types
2361
+ * - entity_properties(entity) - Get all properties
2362
+ *
2363
+ * @param {string} udfName - UDF function name
2364
+ * @param {Array} args - UDF arguments
2365
+ * @returns {Promise<Object>} UDF result
2366
+ */
2367
+ async callUdf(udfName, ...args) {
2368
+ const validUdfs = ['similar_to', 'text_search', 'neighbors', 'graph_pattern', 'sparql_query', 'entity_type', 'entity_properties']
2369
+ if (!validUdfs.includes(udfName)) {
2370
+ throw new Error(`Unknown UDF: ${udfName}. Valid UDFs: ${validUdfs.join(', ')}`)
2371
+ }
2372
+
2373
+ // Build SQL with UDF call
2374
+ const argsStr = args.map(a => typeof a === 'string' ? `'${a}'` : a).join(', ')
2375
+ const sql = `SELECT ${udfName}(${argsStr}) AS result`
2376
+
2377
+ return this.query(sql)
2378
+ }
2379
+
2380
+ /**
2381
+ * Call a table function (one of 9 graph analytics functions)
2382
+ *
2383
+ * Available table functions:
2384
+ * - graph_search(sparql) - SPARQL → SQL bridge
2385
+ * - vector_search(text, k, threshold) - Semantic similarity search
2386
+ * - pagerank(sparql, damping, iterations) - PageRank centrality
2387
+ * - connected_components(sparql) - Community detection
2388
+ * - shortest_paths(src, dst, max_hops) - Path finding
2389
+ * - triangle_count(sparql) - Graph density measure
2390
+ * - label_propagation(sparql, iterations) - Community detection
2391
+ * - datalog_reason(rules) - Datalog inference
2392
+ * - motif_search(pattern) - Graph pattern matching
2393
+ *
2394
+ * @param {string} functionName - Table function name
2395
+ * @param {Array} args - Function arguments
2396
+ * @returns {Promise<Object>} RecordBatch result
2397
+ */
2398
+ async callTableFunction(functionName, ...args) {
2399
+ const validFunctions = ['graph_search', 'vector_search', 'pagerank', 'connected_components', 'shortest_paths', 'triangle_count', 'label_propagation', 'datalog_reason', 'motif_search']
2400
+ if (!validFunctions.includes(functionName)) {
2401
+ throw new Error(`Unknown table function: ${functionName}. Valid functions: ${validFunctions.join(', ')}`)
2402
+ }
2403
+
2404
+ const argsStr = args.map(a => typeof a === 'string' ? `'${a}'` : a).join(', ')
2405
+ const sql = `SELECT * FROM ${functionName}(${argsStr})`
2406
+
2407
+ return this.query(sql)
2408
+ }
2409
+
2410
+ /**
2411
+ * Get the audit log for provenance tracking
2412
+ *
2413
+ * @returns {Array<Object>} Audit log entries
2414
+ */
2415
+ getAuditLog() {
2416
+ return [...this.auditLog]
2417
+ }
2418
+
2419
+ /**
2420
+ * Clear the audit log
2421
+ */
2422
+ clearAuditLog() {
2423
+ this.auditLog = []
2424
+ }
2425
+
2426
+ /**
2427
+ * Get sandbox fuel remaining
2428
+ * @returns {number} Fuel remaining
2429
+ */
2430
+ getFuelRemaining() {
2431
+ return this.sandbox.fuel
2432
+ }
2433
+
2434
+ /**
2435
+ * Check if a capability is granted
2436
+ * @param {string} capability - Capability name
2437
+ * @returns {boolean} True if capability is granted
2438
+ */
2439
+ hasCapability(capability) {
2440
+ return this.sandbox.hasCapability(capability)
1822
2441
  }
1823
2442
  }
1824
2443
 
@@ -4845,6 +5464,13 @@ module.exports = {
4845
5464
  LLMPlanner,
4846
5465
  TOOL_REGISTRY,
4847
5466
 
5467
+ // HyperFederate (v0.7.0+) - Cross-Database Federation
5468
+ // Query across KGDB + Snowflake + BigQuery in single SQL
5469
+ // Category Theory: Tools as typed morphisms (Input → Output)
5470
+ // Proof Theory: Full lineage tracking with W3C PROV
5471
+ RpcFederationProxy, // WASM RPC proxy for federated queries
5472
+ FEDERATION_TOOLS, // 7 federation tools as typed morphisms
5473
+
4848
5474
  // Context Theory (v0.6.11+) - Type-theoretic foundations for SPARQL validation
4849
5475
  // Based on: Spivak's Ologs, Functorial Data Migration, TypeQL
4850
5476
  SchemaContext, // Γ context with classes, properties, bindings