mindgraph 0.7.0 → 0.8.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Shuruheel Ahamed
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -130,6 +130,27 @@ const { job_id } = await graph.runSynthesis(project.uid);
130
130
  const job = await graph.getJob(job_id);
131
131
  ```
132
132
 
133
+ ### Operational Ontology (Layer 7)
134
+
135
+ Define typed domain objects (Customer, Order, Contract…) as a semantic contract and either **bind them to a SQL database** or extract them from documents — fused onto one object. Connecting a database (credentials/sync) is done in the dashboard; the SDK proposes/reviews schemas, queries, and lists the generated agent read tools.
136
+
137
+ | Method | Description |
138
+ |--------|-------------|
139
+ | `proposeOntologySchema(req)` | Draft a schema from a description (+ optional sample docs); returns `{ schema_id, job_id }` |
140
+ | `activateOntologySchema(id)` / `getOntologySchema(id)` / `listOntologySchemas()` | Schema lifecycle |
141
+ | `listOntologyProposals(opts?)` / `approveOntologyProposal(id)` / `rejectOntologyProposal(id)` | Review extracted-object proposals |
142
+ | `queryOntology({ query, include_cognitive_context })` | Typed retrieval with the cognitive overlay fused in |
143
+ | `listOntologyTools()` | The generated read-tool manifest (`search_/get_/summarize_<obj>`) the MCP server renders |
144
+
145
+ ```typescript
146
+ const { schema_id } = await graph.proposeOntologySchema({ description: "Clients, orders, contracts." });
147
+ await graph.activateOntologySchema(schema_id);
148
+ const { tools } = await graph.listOntologyTools();
149
+ const ctx = await graph.queryOntology({ query: "Which customers are a churn risk?", include_cognitive_context: true });
150
+ ```
151
+
152
+ See the [Operational Ontology](https://mindgraph.cloud/docs/ontology) and [Connect a database](https://mindgraph.cloud/docs/connect) docs.
153
+
133
154
  ### CRUD
134
155
 
135
156
  | Method | Description |
package/dist/index.d.mts CHANGED
@@ -357,7 +357,17 @@ interface RetrieveRequest {
357
357
  * Retrieval action. Note: `"semantic"` requires a configured embedding
358
358
  * provider on the server; for semantic search use `retrieveContext()` instead.
359
359
  */
360
- action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "layer" | "recent";
360
+ action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "preferences" | "layer" | "recent";
361
+ /**
362
+ * Required for `"text"`, `"semantic"`, `"hybrid"`. Optional for
363
+ * `"preferences"`: with a `query` you get topic-relevant preferences (the
364
+ * semantic leg bridges low lexical overlap — e.g. "suggest a hotel"
365
+ * surfaces a stored "loved the rooftop pool"); without one you get all
366
+ * preferences, most salient first. Either way the result is a
367
+ * `SearchResult[]` (score = relevance with a query, salience without).
368
+ * Use `"preferences"` for advice/recommendation requests so answers
369
+ * reflect what the user likes.
370
+ */
361
371
  query?: string;
362
372
  k?: number;
363
373
  threshold?: number;
@@ -373,6 +383,16 @@ interface RetrieveRequest {
373
383
  * servers ignore the field.
374
384
  */
375
385
  explain?: boolean;
386
+ /**
387
+ * `recent` action only: restrict to nodes created at/after this unix
388
+ * timestamp (seconds). Filters by INGESTION time, not event time.
389
+ */
390
+ created_after?: number;
391
+ /**
392
+ * `recent` action only: restrict to nodes created at/before this unix
393
+ * timestamp (seconds). Filters by INGESTION time, not event time.
394
+ */
395
+ created_before?: number;
376
396
  }
377
397
  interface TraverseRequest {
378
398
  action: "chain" | "neighborhood" | "path" | "subgraph";
@@ -399,6 +419,16 @@ interface EvolveRequest {
399
419
  version?: number;
400
420
  agent_id?: string;
401
421
  }
422
+ /**
423
+ * Maps a 1-based page number to the **UTF-8 byte offset** where that page begins
424
+ * in `content`. `char_start` is a byte offset, NOT a codepoint count — count
425
+ * UTF-8 bytes (`new TextEncoder().encode(s).length`), not `s.length`, or pages
426
+ * will be wrong for any non-ASCII document.
427
+ */
428
+ interface PageOffset {
429
+ page: number;
430
+ char_start: number;
431
+ }
402
432
  interface IngestChunkRequest {
403
433
  content: string;
404
434
  chunk_type?: string;
@@ -437,10 +467,20 @@ interface IngestDocumentRequest {
437
467
  citation_count?: number;
438
468
  arxiv_id?: string;
439
469
  language?: string;
470
+ /** Per-page character offsets into `content`, used to map extractions back to source pages. */
471
+ page_offsets?: PageOffset[];
472
+ /** Total number of pages in the source document. */
473
+ page_count?: number;
474
+ /** MIME type of the original source (e.g. "application/pdf"). */
475
+ mime_type?: string;
476
+ /** Re-ingest even if a document with the same content was already ingested. */
477
+ force_reingest?: boolean;
440
478
  }
441
479
  interface IngestDocumentResponse {
442
480
  job_id: string;
443
481
  document_uid: string;
482
+ /** True when the document was recognized as a duplicate and ingestion was skipped. */
483
+ deduplicated?: boolean;
444
484
  }
445
485
  interface IngestSessionRequest {
446
486
  content: string;
@@ -478,6 +518,47 @@ interface ListArticlesResponse {
478
518
  total: number;
479
519
  has_more: boolean;
480
520
  }
521
+ /**
522
+ * Citation provenance for a graph node: the source chunk span(s) the node was
523
+ * extracted from. Annotated onto retrieve-context graph nodes via `source_chunks`.
524
+ */
525
+ interface SourceChunk {
526
+ chunk_uid: string;
527
+ /** UTF-8 byte offset into the chunk where the source span starts. */
528
+ char_start: number | null;
529
+ /** UTF-8 byte offset into the chunk where the source span ends. */
530
+ char_end: number | null;
531
+ /** 1-based page number where the span starts (null if no page map). */
532
+ page_start: number | null;
533
+ /** 1-based page number where the span ends (null if no page map). */
534
+ page_end: number | null;
535
+ /** The verbatim source span (when matched), else null. */
536
+ quote: string | null;
537
+ /**
538
+ * Web-Annotation-style selector object pinning the node to its source span,
539
+ * or null when no confident match. `start`/`end` are chunk-relative UTF-8 byte
540
+ * offsets; `exact` is the durable quote; `prefix`/`suffix` give re-anchoring context.
541
+ */
542
+ anchor: TextSelector | null;
543
+ }
544
+ /** A Web-Annotation quote+position selector (see `SourceChunk.anchor`). */
545
+ interface TextSelector {
546
+ exact: string;
547
+ prefix: string;
548
+ suffix: string;
549
+ start: number;
550
+ end: number;
551
+ }
552
+ /**
553
+ * Per-agent stance on a Claim: which agent asserts it and with what certainty.
554
+ * Annotated onto retrieve-context graph nodes (Claim nodes) via `believed_by`.
555
+ */
556
+ interface BelievedBy {
557
+ agent_uid: string;
558
+ agent_label: string;
559
+ /** The asserting agent's certainty in the claim, or null if unspecified. */
560
+ confidence: number | null;
561
+ }
481
562
  interface RetrieveContextResponse {
482
563
  articles?: ArticleResult[];
483
564
  chunks?: {
@@ -494,6 +575,8 @@ interface RetrieveContextResponse {
494
575
  uid: string;
495
576
  title: string;
496
577
  }[];
578
+ source_chunks?: SourceChunk[];
579
+ believed_by?: BelievedBy[];
497
580
  })[];
498
581
  edges: Record<string, unknown>[];
499
582
  };
@@ -674,6 +757,63 @@ interface FieldDefinition {
674
757
  array_item_type?: string;
675
758
  extraction_hint?: string;
676
759
  }
760
+ /**
761
+ * Datasource binding for an object type — the "semantic contract" mapping it to
762
+ * an external system (SQL today). Null/absent = extracted or authored.
763
+ * See docs/plans/layer7-semantic-contract.md §2.
764
+ */
765
+ interface ObjectBacking {
766
+ kind: "sql";
767
+ /** MDO-ready list; exactly one source is supported today. */
768
+ sources: SqlBackingSource[];
769
+ /** Identity key, resolved via an indexed source_pk at sync time. */
770
+ primary_key: string;
771
+ title_field?: string;
772
+ sync?: BackingSync;
773
+ }
774
+ interface SqlBackingSource {
775
+ /** FK into external_connections — credentials live in secrets, never here. */
776
+ connection_ref: string;
777
+ table: string;
778
+ /** Join/identity key within this source. */
779
+ key: string;
780
+ filter?: BackingFilter;
781
+ /** object field name -> binding. Each field is owned by exactly one source. */
782
+ field_map: Record<string, FieldBinding>;
783
+ }
784
+ interface FieldBinding {
785
+ column: string;
786
+ /** indexed = projected/embedded/searchable; live = fetched on demand, never stored. */
787
+ mode?: "indexed" | "live";
788
+ }
789
+ /** Structured predicate (column op value) — never raw SQL. */
790
+ interface BackingFilter {
791
+ column: string;
792
+ op: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "is_null" | "not_null";
793
+ value?: unknown;
794
+ }
795
+ interface BackingSync {
796
+ mode?: "incremental" | "full";
797
+ cursor_column?: string;
798
+ deleted_at_column?: string;
799
+ /** null = manual "Sync now"; cron later. */
800
+ schedule?: string | null;
801
+ }
802
+ /** Datasource binding for a relation type (FK column or M:M join table). */
803
+ type RelationBacking = {
804
+ kind: "sql_fk";
805
+ connection_ref: string;
806
+ fk_table: string;
807
+ fk_column: string;
808
+ /** `table.column` the FK references (the other side's PK). */
809
+ references: string;
810
+ } | {
811
+ kind: "sql_join_table";
812
+ connection_ref: string;
813
+ table: string;
814
+ from_column: string;
815
+ to_column: string;
816
+ };
677
817
  interface OntologySchema {
678
818
  id: string;
679
819
  org_id: string;
@@ -706,6 +846,8 @@ interface OntologyObjectType {
706
846
  extraction_hints?: string | null;
707
847
  default_confidence: number;
708
848
  review_policy: "always" | "low_confidence" | "never";
849
+ /** Datasource binding (null = extracted/authored). */
850
+ backing?: ObjectBacking | null;
709
851
  status: "active" | "deprecated" | "archived";
710
852
  version: number;
711
853
  created_at: string;
@@ -727,6 +869,8 @@ interface OntologyRelationType {
727
869
  fields_json: FieldDefinition[];
728
870
  extraction_hints?: string | null;
729
871
  review_policy: "always" | "low_confidence" | "never";
872
+ /** Datasource binding (null = extracted/authored). */
873
+ backing?: RelationBacking | null;
730
874
  status: "active" | "deprecated" | "archived";
731
875
  version: number;
732
876
  created_at: string;
@@ -736,6 +880,16 @@ interface OntologySchemaDetail extends OntologySchema {
736
880
  object_types: OntologyObjectType[];
737
881
  relation_types: OntologyRelationType[];
738
882
  }
883
+ /** A generated read-only tool descriptor (from `listOntologyTools`). */
884
+ interface OntologyToolDescriptor {
885
+ name: string;
886
+ description: string;
887
+ schema_id: string;
888
+ object_type: string;
889
+ /** "search" | "object" | "object_context" */
890
+ maps_to: string;
891
+ input_schema: Record<string, unknown>;
892
+ }
739
893
  interface CreateOntologySchemaRequest {
740
894
  name: string;
741
895
  description?: string;
@@ -756,6 +910,8 @@ interface OntologyObjectTypeInput {
756
910
  extraction_hints?: string;
757
911
  default_confidence?: number;
758
912
  review_policy?: "always" | "low_confidence" | "never";
913
+ /** Bind this object type to an external source (SQL). Omit for extracted/authored. */
914
+ backing?: ObjectBacking | null;
759
915
  }
760
916
  interface OntologyRelationTypeInput {
761
917
  name: string;
@@ -770,6 +926,8 @@ interface OntologyRelationTypeInput {
770
926
  fields?: FieldDefinition[];
771
927
  extraction_hints?: string;
772
928
  review_policy?: "always" | "low_confidence" | "never";
929
+ /** Bind this relation to an FK column or M:M join table. Both endpoints must be sql-mapped. */
930
+ backing?: RelationBacking | null;
773
931
  }
774
932
  /** Status: pending | approved | approval_required | rejected | applied | apply_failed. */
775
933
  interface OntologyProposal {
@@ -1175,6 +1333,10 @@ declare class MindGraph {
1175
1333
  documents_processed: number;
1176
1334
  node_source_pairs_added: number;
1177
1335
  }>;
1336
+ /** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
1337
+ backfillAnchors(): Promise<{
1338
+ job_id: string;
1339
+ }>;
1178
1340
  listJobs(): Promise<Job[]>;
1179
1341
  getJob(id: string): Promise<Job>;
1180
1342
  cancelJob(id: string): Promise<unknown>;
@@ -1305,6 +1467,15 @@ declare class MindGraph {
1305
1467
  }[];
1306
1468
  }>;
1307
1469
  queryOntology(req: OntologyQueryRequest): Promise<OntologyQueryResponse>;
1470
+ /**
1471
+ * Read-only agent tool descriptors generated from the active ontology
1472
+ * schema(s). Each maps to a generic `/ontology` read endpoint with
1473
+ * `object_type` bound. Used by the MCP server to expose typed per-object
1474
+ * tools (`search_customers`, `summarize_customer`, …).
1475
+ */
1476
+ listOntologyTools(): Promise<{
1477
+ tools: OntologyToolDescriptor[];
1478
+ }>;
1308
1479
  getDomainObject(uid: string): Promise<DomainObject>;
1309
1480
  getDomainObjectContext(uid: string, depth?: number): Promise<OntologyQueryResponse>;
1310
1481
  getDomainObjectHistory(uid: string): Promise<{
@@ -1346,4 +1517,4 @@ declare class MindGraph {
1346
1517
  }>;
1347
1518
  }
1348
1519
 
1349
- export { type AnalogyCandidate, type ArgumentRequest, type ArticleResult, type BatchRequest, type CaptureRequest, type ClaimHub, type ClearResponse, type ClusterClaimSample, type ClusteredClaimHub, type CommitmentRequest, type ConceptCluster, type DecayRequest, type DeliberationRequest, type DialecticalPair, type DistillRequest, type DocumentRef, type EnrichedSearchResponse, type EntityBridge, type EntityRequest, type EpistemicCounts, type EventProps, type EvolveRequest, type ExecutionRequest, type GovernanceRequest, type GraphEdge, type GraphNode, type IngestChunkRequest, type IngestChunkResponse, type IngestDocumentRequest, type IngestDocumentResponse, type IngestSessionRequest, type InquiryRequest, type Job, type ListArticlesResponse, type MemoryConfigRequest, MindGraph, type MindGraphConfig, MindGraphError, type NationProps, type OrganizationProps, type PathStep, type PersonProps, type PlaceProps, type PlanRequest, type ProcedureRequest, type PurgeRequest, type RankedClaimHub, type RetrieveContextRequest, type RetrieveContextResponse, type RetrieveRequest, type RiskRequest, type SearchChunk, type SearchResult, type SessionRequest, type SignalsQuery, type SignalsResponse, type StructureRequest, type SynthesisJobResponse, type TheorySupportGap, type TraverseRequest };
1520
+ export { type AnalogyCandidate, type ArgumentRequest, type ArticleResult, type BatchRequest, type BelievedBy, type CaptureRequest, type ClaimHub, type ClearResponse, type ClusterClaimSample, type ClusteredClaimHub, type CommitmentRequest, type ConceptCluster, type DecayRequest, type DeliberationRequest, type DialecticalPair, type DistillRequest, type DocumentRef, type EnrichedSearchResponse, type EntityBridge, type EntityRequest, type EpistemicCounts, type EventProps, type EvolveRequest, type ExecutionRequest, type GovernanceRequest, type GraphEdge, type GraphNode, type IngestChunkRequest, type IngestChunkResponse, type IngestDocumentRequest, type IngestDocumentResponse, type IngestSessionRequest, type InquiryRequest, type Job, type ListArticlesResponse, type MemoryConfigRequest, MindGraph, type MindGraphConfig, MindGraphError, type NationProps, type OrganizationProps, type PathStep, type PersonProps, type PlaceProps, type PlanRequest, type ProcedureRequest, type PurgeRequest, type RankedClaimHub, type RetrieveContextRequest, type RetrieveContextResponse, type RetrieveRequest, type RiskRequest, type SearchChunk, type SearchResult, type SessionRequest, type SignalsQuery, type SignalsResponse, type SourceChunk, type StructureRequest, type SynthesisJobResponse, type TextSelector, type TheorySupportGap, type TraverseRequest };
package/dist/index.d.ts CHANGED
@@ -357,7 +357,17 @@ interface RetrieveRequest {
357
357
  * Retrieval action. Note: `"semantic"` requires a configured embedding
358
358
  * provider on the server; for semantic search use `retrieveContext()` instead.
359
359
  */
360
- action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "layer" | "recent";
360
+ action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "preferences" | "layer" | "recent";
361
+ /**
362
+ * Required for `"text"`, `"semantic"`, `"hybrid"`. Optional for
363
+ * `"preferences"`: with a `query` you get topic-relevant preferences (the
364
+ * semantic leg bridges low lexical overlap — e.g. "suggest a hotel"
365
+ * surfaces a stored "loved the rooftop pool"); without one you get all
366
+ * preferences, most salient first. Either way the result is a
367
+ * `SearchResult[]` (score = relevance with a query, salience without).
368
+ * Use `"preferences"` for advice/recommendation requests so answers
369
+ * reflect what the user likes.
370
+ */
361
371
  query?: string;
362
372
  k?: number;
363
373
  threshold?: number;
@@ -373,6 +383,16 @@ interface RetrieveRequest {
373
383
  * servers ignore the field.
374
384
  */
375
385
  explain?: boolean;
386
+ /**
387
+ * `recent` action only: restrict to nodes created at/after this unix
388
+ * timestamp (seconds). Filters by INGESTION time, not event time.
389
+ */
390
+ created_after?: number;
391
+ /**
392
+ * `recent` action only: restrict to nodes created at/before this unix
393
+ * timestamp (seconds). Filters by INGESTION time, not event time.
394
+ */
395
+ created_before?: number;
376
396
  }
377
397
  interface TraverseRequest {
378
398
  action: "chain" | "neighborhood" | "path" | "subgraph";
@@ -399,6 +419,16 @@ interface EvolveRequest {
399
419
  version?: number;
400
420
  agent_id?: string;
401
421
  }
422
+ /**
423
+ * Maps a 1-based page number to the **UTF-8 byte offset** where that page begins
424
+ * in `content`. `char_start` is a byte offset, NOT a codepoint count — count
425
+ * UTF-8 bytes (`new TextEncoder().encode(s).length`), not `s.length`, or pages
426
+ * will be wrong for any non-ASCII document.
427
+ */
428
+ interface PageOffset {
429
+ page: number;
430
+ char_start: number;
431
+ }
402
432
  interface IngestChunkRequest {
403
433
  content: string;
404
434
  chunk_type?: string;
@@ -437,10 +467,20 @@ interface IngestDocumentRequest {
437
467
  citation_count?: number;
438
468
  arxiv_id?: string;
439
469
  language?: string;
470
+ /** Per-page character offsets into `content`, used to map extractions back to source pages. */
471
+ page_offsets?: PageOffset[];
472
+ /** Total number of pages in the source document. */
473
+ page_count?: number;
474
+ /** MIME type of the original source (e.g. "application/pdf"). */
475
+ mime_type?: string;
476
+ /** Re-ingest even if a document with the same content was already ingested. */
477
+ force_reingest?: boolean;
440
478
  }
441
479
  interface IngestDocumentResponse {
442
480
  job_id: string;
443
481
  document_uid: string;
482
+ /** True when the document was recognized as a duplicate and ingestion was skipped. */
483
+ deduplicated?: boolean;
444
484
  }
445
485
  interface IngestSessionRequest {
446
486
  content: string;
@@ -478,6 +518,47 @@ interface ListArticlesResponse {
478
518
  total: number;
479
519
  has_more: boolean;
480
520
  }
521
+ /**
522
+ * Citation provenance for a graph node: the source chunk span(s) the node was
523
+ * extracted from. Annotated onto retrieve-context graph nodes via `source_chunks`.
524
+ */
525
+ interface SourceChunk {
526
+ chunk_uid: string;
527
+ /** UTF-8 byte offset into the chunk where the source span starts. */
528
+ char_start: number | null;
529
+ /** UTF-8 byte offset into the chunk where the source span ends. */
530
+ char_end: number | null;
531
+ /** 1-based page number where the span starts (null if no page map). */
532
+ page_start: number | null;
533
+ /** 1-based page number where the span ends (null if no page map). */
534
+ page_end: number | null;
535
+ /** The verbatim source span (when matched), else null. */
536
+ quote: string | null;
537
+ /**
538
+ * Web-Annotation-style selector object pinning the node to its source span,
539
+ * or null when no confident match. `start`/`end` are chunk-relative UTF-8 byte
540
+ * offsets; `exact` is the durable quote; `prefix`/`suffix` give re-anchoring context.
541
+ */
542
+ anchor: TextSelector | null;
543
+ }
544
+ /** A Web-Annotation quote+position selector (see `SourceChunk.anchor`). */
545
+ interface TextSelector {
546
+ exact: string;
547
+ prefix: string;
548
+ suffix: string;
549
+ start: number;
550
+ end: number;
551
+ }
552
+ /**
553
+ * Per-agent stance on a Claim: which agent asserts it and with what certainty.
554
+ * Annotated onto retrieve-context graph nodes (Claim nodes) via `believed_by`.
555
+ */
556
+ interface BelievedBy {
557
+ agent_uid: string;
558
+ agent_label: string;
559
+ /** The asserting agent's certainty in the claim, or null if unspecified. */
560
+ confidence: number | null;
561
+ }
481
562
  interface RetrieveContextResponse {
482
563
  articles?: ArticleResult[];
483
564
  chunks?: {
@@ -494,6 +575,8 @@ interface RetrieveContextResponse {
494
575
  uid: string;
495
576
  title: string;
496
577
  }[];
578
+ source_chunks?: SourceChunk[];
579
+ believed_by?: BelievedBy[];
497
580
  })[];
498
581
  edges: Record<string, unknown>[];
499
582
  };
@@ -674,6 +757,63 @@ interface FieldDefinition {
674
757
  array_item_type?: string;
675
758
  extraction_hint?: string;
676
759
  }
760
+ /**
761
+ * Datasource binding for an object type — the "semantic contract" mapping it to
762
+ * an external system (SQL today). Null/absent = extracted or authored.
763
+ * See docs/plans/layer7-semantic-contract.md §2.
764
+ */
765
+ interface ObjectBacking {
766
+ kind: "sql";
767
+ /** MDO-ready list; exactly one source is supported today. */
768
+ sources: SqlBackingSource[];
769
+ /** Identity key, resolved via an indexed source_pk at sync time. */
770
+ primary_key: string;
771
+ title_field?: string;
772
+ sync?: BackingSync;
773
+ }
774
+ interface SqlBackingSource {
775
+ /** FK into external_connections — credentials live in secrets, never here. */
776
+ connection_ref: string;
777
+ table: string;
778
+ /** Join/identity key within this source. */
779
+ key: string;
780
+ filter?: BackingFilter;
781
+ /** object field name -> binding. Each field is owned by exactly one source. */
782
+ field_map: Record<string, FieldBinding>;
783
+ }
784
+ interface FieldBinding {
785
+ column: string;
786
+ /** indexed = projected/embedded/searchable; live = fetched on demand, never stored. */
787
+ mode?: "indexed" | "live";
788
+ }
789
+ /** Structured predicate (column op value) — never raw SQL. */
790
+ interface BackingFilter {
791
+ column: string;
792
+ op: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "is_null" | "not_null";
793
+ value?: unknown;
794
+ }
795
+ interface BackingSync {
796
+ mode?: "incremental" | "full";
797
+ cursor_column?: string;
798
+ deleted_at_column?: string;
799
+ /** null = manual "Sync now"; cron later. */
800
+ schedule?: string | null;
801
+ }
802
+ /** Datasource binding for a relation type (FK column or M:M join table). */
803
+ type RelationBacking = {
804
+ kind: "sql_fk";
805
+ connection_ref: string;
806
+ fk_table: string;
807
+ fk_column: string;
808
+ /** `table.column` the FK references (the other side's PK). */
809
+ references: string;
810
+ } | {
811
+ kind: "sql_join_table";
812
+ connection_ref: string;
813
+ table: string;
814
+ from_column: string;
815
+ to_column: string;
816
+ };
677
817
  interface OntologySchema {
678
818
  id: string;
679
819
  org_id: string;
@@ -706,6 +846,8 @@ interface OntologyObjectType {
706
846
  extraction_hints?: string | null;
707
847
  default_confidence: number;
708
848
  review_policy: "always" | "low_confidence" | "never";
849
+ /** Datasource binding (null = extracted/authored). */
850
+ backing?: ObjectBacking | null;
709
851
  status: "active" | "deprecated" | "archived";
710
852
  version: number;
711
853
  created_at: string;
@@ -727,6 +869,8 @@ interface OntologyRelationType {
727
869
  fields_json: FieldDefinition[];
728
870
  extraction_hints?: string | null;
729
871
  review_policy: "always" | "low_confidence" | "never";
872
+ /** Datasource binding (null = extracted/authored). */
873
+ backing?: RelationBacking | null;
730
874
  status: "active" | "deprecated" | "archived";
731
875
  version: number;
732
876
  created_at: string;
@@ -736,6 +880,16 @@ interface OntologySchemaDetail extends OntologySchema {
736
880
  object_types: OntologyObjectType[];
737
881
  relation_types: OntologyRelationType[];
738
882
  }
883
+ /** A generated read-only tool descriptor (from `listOntologyTools`). */
884
+ interface OntologyToolDescriptor {
885
+ name: string;
886
+ description: string;
887
+ schema_id: string;
888
+ object_type: string;
889
+ /** "search" | "object" | "object_context" */
890
+ maps_to: string;
891
+ input_schema: Record<string, unknown>;
892
+ }
739
893
  interface CreateOntologySchemaRequest {
740
894
  name: string;
741
895
  description?: string;
@@ -756,6 +910,8 @@ interface OntologyObjectTypeInput {
756
910
  extraction_hints?: string;
757
911
  default_confidence?: number;
758
912
  review_policy?: "always" | "low_confidence" | "never";
913
+ /** Bind this object type to an external source (SQL). Omit for extracted/authored. */
914
+ backing?: ObjectBacking | null;
759
915
  }
760
916
  interface OntologyRelationTypeInput {
761
917
  name: string;
@@ -770,6 +926,8 @@ interface OntologyRelationTypeInput {
770
926
  fields?: FieldDefinition[];
771
927
  extraction_hints?: string;
772
928
  review_policy?: "always" | "low_confidence" | "never";
929
+ /** Bind this relation to an FK column or M:M join table. Both endpoints must be sql-mapped. */
930
+ backing?: RelationBacking | null;
773
931
  }
774
932
  /** Status: pending | approved | approval_required | rejected | applied | apply_failed. */
775
933
  interface OntologyProposal {
@@ -1175,6 +1333,10 @@ declare class MindGraph {
1175
1333
  documents_processed: number;
1176
1334
  node_source_pairs_added: number;
1177
1335
  }>;
1336
+ /** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
1337
+ backfillAnchors(): Promise<{
1338
+ job_id: string;
1339
+ }>;
1178
1340
  listJobs(): Promise<Job[]>;
1179
1341
  getJob(id: string): Promise<Job>;
1180
1342
  cancelJob(id: string): Promise<unknown>;
@@ -1305,6 +1467,15 @@ declare class MindGraph {
1305
1467
  }[];
1306
1468
  }>;
1307
1469
  queryOntology(req: OntologyQueryRequest): Promise<OntologyQueryResponse>;
1470
+ /**
1471
+ * Read-only agent tool descriptors generated from the active ontology
1472
+ * schema(s). Each maps to a generic `/ontology` read endpoint with
1473
+ * `object_type` bound. Used by the MCP server to expose typed per-object
1474
+ * tools (`search_customers`, `summarize_customer`, …).
1475
+ */
1476
+ listOntologyTools(): Promise<{
1477
+ tools: OntologyToolDescriptor[];
1478
+ }>;
1308
1479
  getDomainObject(uid: string): Promise<DomainObject>;
1309
1480
  getDomainObjectContext(uid: string, depth?: number): Promise<OntologyQueryResponse>;
1310
1481
  getDomainObjectHistory(uid: string): Promise<{
@@ -1346,4 +1517,4 @@ declare class MindGraph {
1346
1517
  }>;
1347
1518
  }
1348
1519
 
1349
- export { type AnalogyCandidate, type ArgumentRequest, type ArticleResult, type BatchRequest, type CaptureRequest, type ClaimHub, type ClearResponse, type ClusterClaimSample, type ClusteredClaimHub, type CommitmentRequest, type ConceptCluster, type DecayRequest, type DeliberationRequest, type DialecticalPair, type DistillRequest, type DocumentRef, type EnrichedSearchResponse, type EntityBridge, type EntityRequest, type EpistemicCounts, type EventProps, type EvolveRequest, type ExecutionRequest, type GovernanceRequest, type GraphEdge, type GraphNode, type IngestChunkRequest, type IngestChunkResponse, type IngestDocumentRequest, type IngestDocumentResponse, type IngestSessionRequest, type InquiryRequest, type Job, type ListArticlesResponse, type MemoryConfigRequest, MindGraph, type MindGraphConfig, MindGraphError, type NationProps, type OrganizationProps, type PathStep, type PersonProps, type PlaceProps, type PlanRequest, type ProcedureRequest, type PurgeRequest, type RankedClaimHub, type RetrieveContextRequest, type RetrieveContextResponse, type RetrieveRequest, type RiskRequest, type SearchChunk, type SearchResult, type SessionRequest, type SignalsQuery, type SignalsResponse, type StructureRequest, type SynthesisJobResponse, type TheorySupportGap, type TraverseRequest };
1520
+ export { type AnalogyCandidate, type ArgumentRequest, type ArticleResult, type BatchRequest, type BelievedBy, type CaptureRequest, type ClaimHub, type ClearResponse, type ClusterClaimSample, type ClusteredClaimHub, type CommitmentRequest, type ConceptCluster, type DecayRequest, type DeliberationRequest, type DialecticalPair, type DistillRequest, type DocumentRef, type EnrichedSearchResponse, type EntityBridge, type EntityRequest, type EpistemicCounts, type EventProps, type EvolveRequest, type ExecutionRequest, type GovernanceRequest, type GraphEdge, type GraphNode, type IngestChunkRequest, type IngestChunkResponse, type IngestDocumentRequest, type IngestDocumentResponse, type IngestSessionRequest, type InquiryRequest, type Job, type ListArticlesResponse, type MemoryConfigRequest, MindGraph, type MindGraphConfig, MindGraphError, type NationProps, type OrganizationProps, type PathStep, type PersonProps, type PlaceProps, type PlanRequest, type ProcedureRequest, type PurgeRequest, type RankedClaimHub, type RetrieveContextRequest, type RetrieveContextResponse, type RetrieveRequest, type RiskRequest, type SearchChunk, type SearchResult, type SessionRequest, type SignalsQuery, type SignalsResponse, type SourceChunk, type StructureRequest, type SynthesisJobResponse, type TextSelector, type TheorySupportGap, type TraverseRequest };
package/dist/index.js CHANGED
@@ -559,6 +559,10 @@ var MindGraph = class {
559
559
  async backfillNodeSources() {
560
560
  return this.post("/backfill/node-sources", {});
561
561
  }
562
+ /** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
563
+ async backfillAnchors() {
564
+ return this.post("/backfill/anchors", {});
565
+ }
562
566
  async listJobs() {
563
567
  return this.get("/jobs");
564
568
  }
@@ -752,6 +756,15 @@ var MindGraph = class {
752
756
  async queryOntology(req) {
753
757
  return this.post("/ontology/query", req);
754
758
  }
759
+ /**
760
+ * Read-only agent tool descriptors generated from the active ontology
761
+ * schema(s). Each maps to a generic `/ontology` read endpoint with
762
+ * `object_type` bound. Used by the MCP server to expose typed per-object
763
+ * tools (`search_customers`, `summarize_customer`, …).
764
+ */
765
+ async listOntologyTools() {
766
+ return this.get("/v1/ontology/tools");
767
+ }
755
768
  async getDomainObject(uid) {
756
769
  return this.get(`/ontology/object/${uid}`);
757
770
  }
package/dist/index.mjs CHANGED
@@ -532,6 +532,10 @@ var MindGraph = class {
532
532
  async backfillNodeSources() {
533
533
  return this.post("/backfill/node-sources", {});
534
534
  }
535
+ /** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
536
+ async backfillAnchors() {
537
+ return this.post("/backfill/anchors", {});
538
+ }
535
539
  async listJobs() {
536
540
  return this.get("/jobs");
537
541
  }
@@ -725,6 +729,15 @@ var MindGraph = class {
725
729
  async queryOntology(req) {
726
730
  return this.post("/ontology/query", req);
727
731
  }
732
+ /**
733
+ * Read-only agent tool descriptors generated from the active ontology
734
+ * schema(s). Each maps to a generic `/ontology` read endpoint with
735
+ * `object_type` bound. Used by the MCP server to expose typed per-object
736
+ * tools (`search_customers`, `summarize_customer`, …).
737
+ */
738
+ async listOntologyTools() {
739
+ return this.get("/v1/ontology/tools");
740
+ }
728
741
  async getDomainObject(uid) {
729
742
  return this.get(`/ontology/object/${uid}`);
730
743
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindgraph",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "TypeScript client for the MindGraph Cloud API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -9,7 +9,9 @@
9
9
  "scripts": {
10
10
  "build": "tsup src/index.ts --format cjs,esm --dts",
11
11
  "lint": "tsc --noEmit",
12
- "test": "vitest run"
12
+ "test": "vitest run",
13
+ "test:offline": "vitest run src/offline.test.ts",
14
+ "test:e2e": "vitest run src/integration.test.ts"
13
15
  },
14
16
  "keywords": ["mindgraph", "knowledge-graph", "cognitive", "ai", "agent"],
15
17
  "license": "MIT",