@kortexya/reasoninglayer 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
  };
8
8
 
9
9
  // src/config.ts
10
- var SDK_VERSION = "1.2.0";
10
+ var SDK_VERSION = "1.3.0";
11
11
  function resolveConfig(config) {
12
12
  if (!config.baseUrl) {
13
13
  throw new Error("ClientConfig.baseUrl is required");
@@ -1064,6 +1064,20 @@ var Sorts = class {
1064
1064
  format: "json",
1065
1065
  ...params
1066
1066
  });
1067
+ /**
1068
+ * No description
1069
+ *
1070
+ * @tags sorts
1071
+ * @name SearchSortsByName
1072
+ * @request GET:/api/v1/sorts/search
1073
+ */
1074
+ searchSortsByName = (query, params = {}) => this.http.request({
1075
+ path: `/api/v1/sorts/search`,
1076
+ method: "GET",
1077
+ query,
1078
+ format: "json",
1079
+ ...params
1080
+ });
1067
1081
  /**
1068
1082
  * @description Similarity is symmetric: ∼(s₁, s₂) = ∼(s₂, s₁) Degree must be in [0, 1] range.
1069
1083
  *
@@ -1503,6 +1517,24 @@ var Inference = class {
1503
1517
  format: "json",
1504
1518
  ...params
1505
1519
  });
1520
+ /**
1521
+ * @description Phase 2 v2 entry point for retraction: 1. Removes each term from PG + in-memory stores via [`HomoiconicTermService::remove_term`](osfkb_application::services::HomoiconicTermService::remove_term). 2. When `state.use_plan_engine` is on, submits a single [`DeltaEvent::Retract`](osfkb_application::services::dataflow::DeltaEvent::Retract) to the per-tenant supervisor so the Backward/Forward backward chase decrements every dependent derived fact's `proof_count` (and deletes those whose count reaches zero). Symmetric to [`bulk_add_terms`]; idempotent (term ids absent from the working memory are silently skipped — same shape as [`delete_term`] returning 404, except in the bulk path the missing ids simply don't appear in `removed_term_ids`). Best-effort supervisor enqueue: a supervisor failure does NOT fail the 2xx response — the persist path has succeeded and a future bootstrap can recover any missed retraction. # Mid-batch error handling If `remove_term` fails for a term partway through the batch, the handler **stops accumulating successes**, runs cache invalidation for the prefix that did succeed, submits a single [`DeltaEvent::Retract`](osfkb_application::services::dataflow::DeltaEvent::Retract) covering that prefix, and **then** surfaces the error. This keeps the supervisor and the in-memory caches in sync with the actual store state — a leaked Retract event would orphan derived facts whose only antecedent is now removed, which is a critical correctness violation. # Authorization Requires `X-Tenant-Id` header. The `term_ids` are resolved against that tenant's working memory only — cross-tenant retraction is impossible by construction (the per-tenant `HomoiconicTermService` only sees its own tenant's terms).
1522
+ *
1523
+ * @tags inference
1524
+ * @name BulkRetractTerms
1525
+ * @summary Bulk-retract terms from the working memory.
1526
+ * @request POST:/api/v1/inference/facts/bulk-retract
1527
+ * @secure
1528
+ */
1529
+ bulkRetractTerms = (data, params = {}) => this.http.request({
1530
+ path: `/api/v1/inference/facts/bulk-retract`,
1531
+ method: "POST",
1532
+ body: data,
1533
+ secure: true,
1534
+ type: "application/json" /* Json */,
1535
+ format: "json",
1536
+ ...params
1537
+ });
1506
1538
  /**
1507
1539
  * @description # DEPRECATED This endpoint is deprecated. Use `DELETE /api/v1/terms/{term_id}` for individual terms. # TRUE HOMOICONIC API # Authorization Requires X-Tenant-Id header.
1508
1540
  *
@@ -7795,6 +7827,34 @@ var Admin = class {
7795
7827
  format: "json",
7796
7828
  ...params
7797
7829
  });
7830
+ /**
7831
+ * @description Truncates the derived_facts table for the given tenant and queues a BootstrapAll event covering every analyzed rule. Asynchronous: returns the queue depth and current materialization LSN, not the final state. Concurrent rebuilds for the same tenant are rejected with 409 (per-tenant mutex). Full operational runbook (prerequisites, timings, monitoring, failure recovery, known limitations) lives in .claude/SUB_MS_FORWARD_CHAINING_STATUS.md, section 'Operator runbook — derived-facts rebuild'.
7832
+ *
7833
+ * @tags admin
7834
+ * @name RebuildDerivedFacts
7835
+ * @summary Rebuild derived facts for a tenant
7836
+ * @request POST:/api/v1/admin/derived-facts/rebuild/{tenant_id}
7837
+ */
7838
+ rebuildDerivedFacts = (tenantId, params = {}) => this.http.request({
7839
+ path: `/api/v1/admin/derived-facts/rebuild/${tenantId}`,
7840
+ method: "POST",
7841
+ format: "json",
7842
+ ...params
7843
+ });
7844
+ /**
7845
+ * @description Returns event-processing counters (submitted/processed/failed/in-flight), the materialization LSN, the last handler error (if any, truncated to 512 chars), the per-tenant materialization sentinel, the current derived-facts row count, and a racy hint about whether a rebuild is in flight. Intended for operator dashboards; the supervisor itself does not depend on this endpoint.
7846
+ *
7847
+ * @tags admin
7848
+ * @name SupervisorStatus
7849
+ * @summary Get per-tenant supervisor + materialization status
7850
+ * @request GET:/api/v1/admin/derived-facts/status/{tenant_id}
7851
+ */
7852
+ supervisorStatus = (tenantId, params = {}) => this.http.request({
7853
+ path: `/api/v1/admin/derived-facts/status/${tenantId}`,
7854
+ method: "GET",
7855
+ format: "json",
7856
+ ...params
7857
+ });
7798
7858
  };
7799
7859
 
7800
7860
  // src/api-spec/generated/ImageExtraction.ts
@@ -20664,17 +20724,17 @@ function compileLinearExpression(expression, varRefs, nextVar) {
20664
20724
  const termResults = [];
20665
20725
  for (const [varName, coefficient] of Object.entries(expression)) {
20666
20726
  if (coefficient === 0) continue;
20667
- const varRef = varRefs[varName];
20668
- if (!varRef) continue;
20727
+ const varRef2 = varRefs[varName];
20728
+ if (!varRef2) continue;
20669
20729
  if (coefficient === 1) {
20670
- termResults.push(varRef);
20730
+ termResults.push(varRef2);
20671
20731
  } else {
20672
20732
  const resultVar = { name: nextVar() };
20673
20733
  antecedents.push({
20674
20734
  sortName: "real_times_constraint",
20675
20735
  features: {
20676
20736
  coefficient: numericTerm(coefficient),
20677
- variable: varRef,
20737
+ variable: varRef2,
20678
20738
  result: resultVar
20679
20739
  }
20680
20740
  });
@@ -23785,6 +23845,229 @@ function allen(relation, intervalA, intervalBTermId) {
23785
23845
  };
23786
23846
  }
23787
23847
 
23848
+ // src/builders/flow.ts
23849
+ function nodeVar(name) {
23850
+ const sanitized = name.replace(/[^A-Za-z0-9_]/g, "_");
23851
+ return { name: `?N_${sanitized}` };
23852
+ }
23853
+ function varRef(name) {
23854
+ return { name };
23855
+ }
23856
+ function freshVar(prefix, counter) {
23857
+ const name = `?${prefix}${counter.n}`;
23858
+ counter.n += 1;
23859
+ return name;
23860
+ }
23861
+ function normaliseEdge(e) {
23862
+ if (Array.isArray(e)) {
23863
+ const [from, to, cap, options] = e;
23864
+ return { from, to, cap, ...options ?? {} };
23865
+ }
23866
+ return e;
23867
+ }
23868
+ function buildEdges(edges, counter) {
23869
+ const edgeTerms = [];
23870
+ const edgeFlows = [];
23871
+ for (const raw of edges) {
23872
+ const e = normaliseEdge(raw);
23873
+ const flowVar = e.flow ?? freshVar("F", counter);
23874
+ edgeFlows.push({ from: e.from, to: e.to, var: flowVar });
23875
+ const features = {
23876
+ src: nodeVar(e.from),
23877
+ dst: nodeVar(e.to),
23878
+ cap: e.cap,
23879
+ flow: varRef(flowVar)
23880
+ };
23881
+ if (e.cost != null) features.cost = e.cost;
23882
+ if (e.label != null) features.label = e.label;
23883
+ edgeTerms.push(psi("flow_edge_constraint", features));
23884
+ }
23885
+ return { edgeTerms, edgeFlows };
23886
+ }
23887
+ function solveTerm(source, sink) {
23888
+ return psi("flow_solve_constraint", {
23889
+ source: nodeVar(source),
23890
+ sink: nodeVar(sink)
23891
+ });
23892
+ }
23893
+ var Flow = {
23894
+ /**
23895
+ * Build a max-flow problem.
23896
+ *
23897
+ * Emits one `flow_edge_constraint` per edge, one
23898
+ * `flow_max_constraint` with the requested output binding, and a
23899
+ * `flow_solve_constraint` trigger. Returns the constraint terms
23900
+ * plus the names of every output variable.
23901
+ */
23902
+ maxFlow(input) {
23903
+ const counter = { n: 0 };
23904
+ const { edgeTerms, edgeFlows } = buildEdges(input.edges, counter);
23905
+ const flowValue = input.flowValue ?? freshVar("V_flow", counter);
23906
+ const constraints = [
23907
+ ...edgeTerms,
23908
+ psi("flow_max_constraint", {
23909
+ source: nodeVar(input.source),
23910
+ sink: nodeVar(input.sink),
23911
+ flow_value: varRef(flowValue)
23912
+ }),
23913
+ solveTerm(input.source, input.sink)
23914
+ ];
23915
+ return { constraints, vars: { flowValue, edgeFlows } };
23916
+ },
23917
+ /**
23918
+ * Build a min-cut problem.
23919
+ *
23920
+ * Emits `flow_min_cut_constraint` and binds `cut_value`,
23921
+ * `cut_edges`, `source_side`, `sink_side` to the requested
23922
+ * variable names (auto-generated when omitted).
23923
+ */
23924
+ minCut(input) {
23925
+ const counter = { n: 0 };
23926
+ const { edgeTerms, edgeFlows } = buildEdges(input.edges, counter);
23927
+ const cutValue = input.cutValue ?? freshVar("CutValue", counter);
23928
+ const cutEdges = input.cutEdges ?? freshVar("CutEdges", counter);
23929
+ const sourceSide = input.sourceSide ?? freshVar("SrcSide", counter);
23930
+ const sinkSide = input.sinkSide ?? freshVar("SnkSide", counter);
23931
+ const constraints = [
23932
+ ...edgeTerms,
23933
+ psi("flow_min_cut_constraint", {
23934
+ source: nodeVar(input.source),
23935
+ sink: nodeVar(input.sink),
23936
+ cut_value: varRef(cutValue),
23937
+ cut_edges: varRef(cutEdges),
23938
+ source_side: varRef(sourceSide),
23939
+ sink_side: varRef(sinkSide)
23940
+ }),
23941
+ solveTerm(input.source, input.sink)
23942
+ ];
23943
+ return {
23944
+ constraints,
23945
+ vars: { cutValue, cutEdges, sourceSide, sinkSide, edgeFlows }
23946
+ };
23947
+ },
23948
+ /**
23949
+ * Build a min-cost-max-flow problem. Per-edge `cost` is required
23950
+ * for the optimisation to be meaningful (defaults to 0 if absent).
23951
+ */
23952
+ minCostMaxFlow(input) {
23953
+ const counter = { n: 0 };
23954
+ const { edgeTerms, edgeFlows } = buildEdges(input.edges, counter);
23955
+ const flowValue = input.flowValue ?? freshVar("V_flow", counter);
23956
+ const totalCost = input.totalCost ?? freshVar("Cost", counter);
23957
+ const constraints = [
23958
+ ...edgeTerms,
23959
+ psi("flow_min_cost_max_flow_constraint", {
23960
+ source: nodeVar(input.source),
23961
+ sink: nodeVar(input.sink),
23962
+ flow_value: varRef(flowValue),
23963
+ total_cost: varRef(totalCost)
23964
+ }),
23965
+ solveTerm(input.source, input.sink)
23966
+ ];
23967
+ return { constraints, vars: { flowValue, totalCost, edgeFlows } };
23968
+ },
23969
+ /**
23970
+ * Build a Dulmage-Mendelsohn edge-classification problem.
23971
+ *
23972
+ * Each edge is classified as `"always"`, `"never"`, or
23973
+ * `"sometimes"` used across the space of all max flows (or all
23974
+ * min-cost max flows when `optimal: true`).
23975
+ */
23976
+ classifyEdges(input) {
23977
+ const counter = { n: 0 };
23978
+ const { edgeTerms, edgeFlows } = buildEdges(input.edges, counter);
23979
+ const classifications = input.classifications ?? freshVar("Classes", counter);
23980
+ const objectiveFeatures = {
23981
+ source: nodeVar(input.source),
23982
+ sink: nodeVar(input.sink),
23983
+ classifications: varRef(classifications)
23984
+ };
23985
+ if (input.optimal) objectiveFeatures.optimal = true;
23986
+ const constraints = [
23987
+ ...edgeTerms,
23988
+ psi("flow_classify_edges_constraint", objectiveFeatures),
23989
+ solveTerm(input.source, input.sink)
23990
+ ];
23991
+ return { constraints, vars: { classifications, edgeFlows } };
23992
+ },
23993
+ /** Low-level: build a single `flow_edge_constraint` psi-term. */
23994
+ edge(from, to, cap, options = {}) {
23995
+ const features = {
23996
+ src: nodeVar(from),
23997
+ dst: nodeVar(to),
23998
+ cap
23999
+ };
24000
+ if (options.flow) features.flow = varRef(options.flow);
24001
+ if (options.cost != null) features.cost = options.cost;
24002
+ if (options.label != null) features.label = options.label;
24003
+ return psi("flow_edge_constraint", features);
24004
+ },
24005
+ /** Low-level: build a single `flow_solve_constraint` psi-term. */
24006
+ solve(source, sink) {
24007
+ return solveTerm(source, sink);
24008
+ },
24009
+ /**
24010
+ * Low-level: build a single `flow_max_constraint` psi-term.
24011
+ *
24012
+ * @example
24013
+ * ```typescript
24014
+ * const constraints = [
24015
+ * Flow.edge('s', 'a', 10),
24016
+ * Flow.edge('a', 't', 10),
24017
+ * Flow.maxObjective({ source: 's', sink: 't', flowValue: '?V' }),
24018
+ * Flow.solve('s', 't'),
24019
+ * ];
24020
+ * ```
24021
+ */
24022
+ maxObjective(opts) {
24023
+ return psi("flow_max_constraint", {
24024
+ source: nodeVar(opts.source),
24025
+ sink: nodeVar(opts.sink),
24026
+ flow_value: varRef(opts.flowValue)
24027
+ });
24028
+ },
24029
+ /** Low-level: build a single `flow_min_cut_constraint` psi-term. */
24030
+ minCutObjective(opts) {
24031
+ return psi("flow_min_cut_constraint", {
24032
+ source: nodeVar(opts.source),
24033
+ sink: nodeVar(opts.sink),
24034
+ cut_value: varRef(opts.cutValue),
24035
+ cut_edges: varRef(opts.cutEdges),
24036
+ source_side: varRef(opts.sourceSide),
24037
+ sink_side: varRef(opts.sinkSide)
24038
+ });
24039
+ },
24040
+ /** Low-level: build a single `flow_min_cost_max_flow_constraint` psi-term. */
24041
+ minCostMaxFlowObjective(opts) {
24042
+ return psi("flow_min_cost_max_flow_constraint", {
24043
+ source: nodeVar(opts.source),
24044
+ sink: nodeVar(opts.sink),
24045
+ flow_value: varRef(opts.flowValue),
24046
+ total_cost: varRef(opts.totalCost)
24047
+ });
24048
+ },
24049
+ /** Low-level: build a single `flow_classify_edges_constraint` psi-term. */
24050
+ classifyEdgesObjective(opts) {
24051
+ const features = {
24052
+ source: nodeVar(opts.source),
24053
+ sink: nodeVar(opts.sink),
24054
+ classifications: varRef(opts.classifications)
24055
+ };
24056
+ if (opts.optimal) features.optimal = true;
24057
+ return psi("flow_classify_edges_constraint", features);
24058
+ },
24059
+ /**
24060
+ * Low-level: get the node-variable reference used to identify a
24061
+ * node name in goals built by this builder. Exposed so callers
24062
+ * composing constraints by hand can refer to the same logical node
24063
+ * the high-level helpers would produce — e.g., to add a feature
24064
+ * test on the same node term inside the same goal.
24065
+ */
24066
+ node(name) {
24067
+ return nodeVar(name);
24068
+ }
24069
+ };
24070
+
23788
24071
  // src/utils/discrimination.ts
23789
24072
  var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23790
24073
  function isUuid(s) {
@@ -23831,6 +24114,7 @@ exports.Conversation = conversation_exports;
23831
24114
  exports.Discovery = discovery_exports;
23832
24115
  exports.Execution = execution_exports;
23833
24116
  exports.Extract = extract_exports;
24117
+ exports.Flow = Flow;
23834
24118
  exports.FlowNetworks = flow_networks_exports;
23835
24119
  exports.ForbiddenError = ForbiddenError;
23836
24120
  exports.Functions = functions_exports;