mindgraph 0.7.0 → 0.9.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 +21 -0
- package/README.md +21 -0
- package/dist/index.d.mts +182 -3
- package/dist/index.d.ts +182 -3
- package/dist/index.js +13 -0
- package/dist/index.mjs +13 -0
- package/package.json +4 -2
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
|
@@ -81,12 +81,20 @@ interface EnrichedSearchResponse {
|
|
|
81
81
|
chunks: SearchChunk[];
|
|
82
82
|
}
|
|
83
83
|
interface PathStep {
|
|
84
|
-
|
|
84
|
+
node_uid: string;
|
|
85
85
|
label: string;
|
|
86
86
|
node_type: string;
|
|
87
87
|
edge_type: string | null;
|
|
88
88
|
depth: number;
|
|
89
89
|
parent_uid: string | null;
|
|
90
|
+
/** Min-plus cost of the returned BFS path from the start node
|
|
91
|
+
* (sum of -ln(weight), weights clamped to (1e-9, 1]); cost of the path
|
|
92
|
+
* the traversal returned, not the cheapest path. 0 at the start node. */
|
|
93
|
+
path_cost?: number;
|
|
94
|
+
/** Product of edge confidences along the returned BFS path (clamped to
|
|
95
|
+
* (1e-9, 1]); a ranking signal, not a calibrated probability. 1 at the
|
|
96
|
+
* start node. */
|
|
97
|
+
path_confidence?: number;
|
|
90
98
|
}
|
|
91
99
|
interface PersonProps {
|
|
92
100
|
canonical_name: string;
|
|
@@ -357,7 +365,17 @@ interface RetrieveRequest {
|
|
|
357
365
|
* Retrieval action. Note: `"semantic"` requires a configured embedding
|
|
358
366
|
* provider on the server; for semantic search use `retrieveContext()` instead.
|
|
359
367
|
*/
|
|
360
|
-
action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "layer" | "recent";
|
|
368
|
+
action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "preferences" | "layer" | "recent";
|
|
369
|
+
/**
|
|
370
|
+
* Required for `"text"`, `"semantic"`, `"hybrid"`. Optional for
|
|
371
|
+
* `"preferences"`: with a `query` you get topic-relevant preferences (the
|
|
372
|
+
* semantic leg bridges low lexical overlap — e.g. "suggest a hotel"
|
|
373
|
+
* surfaces a stored "loved the rooftop pool"); without one you get all
|
|
374
|
+
* preferences, most salient first. Either way the result is a
|
|
375
|
+
* `SearchResult[]` (score = relevance with a query, salience without).
|
|
376
|
+
* Use `"preferences"` for advice/recommendation requests so answers
|
|
377
|
+
* reflect what the user likes.
|
|
378
|
+
*/
|
|
361
379
|
query?: string;
|
|
362
380
|
k?: number;
|
|
363
381
|
threshold?: number;
|
|
@@ -373,6 +391,16 @@ interface RetrieveRequest {
|
|
|
373
391
|
* servers ignore the field.
|
|
374
392
|
*/
|
|
375
393
|
explain?: boolean;
|
|
394
|
+
/**
|
|
395
|
+
* `recent` action only: restrict to nodes created at/after this unix
|
|
396
|
+
* timestamp (seconds). Filters by INGESTION time, not event time.
|
|
397
|
+
*/
|
|
398
|
+
created_after?: number;
|
|
399
|
+
/**
|
|
400
|
+
* `recent` action only: restrict to nodes created at/before this unix
|
|
401
|
+
* timestamp (seconds). Filters by INGESTION time, not event time.
|
|
402
|
+
*/
|
|
403
|
+
created_before?: number;
|
|
376
404
|
}
|
|
377
405
|
interface TraverseRequest {
|
|
378
406
|
action: "chain" | "neighborhood" | "path" | "subgraph";
|
|
@@ -399,6 +427,16 @@ interface EvolveRequest {
|
|
|
399
427
|
version?: number;
|
|
400
428
|
agent_id?: string;
|
|
401
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Maps a 1-based page number to the **UTF-8 byte offset** where that page begins
|
|
432
|
+
* in `content`. `char_start` is a byte offset, NOT a codepoint count — count
|
|
433
|
+
* UTF-8 bytes (`new TextEncoder().encode(s).length`), not `s.length`, or pages
|
|
434
|
+
* will be wrong for any non-ASCII document.
|
|
435
|
+
*/
|
|
436
|
+
interface PageOffset {
|
|
437
|
+
page: number;
|
|
438
|
+
char_start: number;
|
|
439
|
+
}
|
|
402
440
|
interface IngestChunkRequest {
|
|
403
441
|
content: string;
|
|
404
442
|
chunk_type?: string;
|
|
@@ -437,10 +475,20 @@ interface IngestDocumentRequest {
|
|
|
437
475
|
citation_count?: number;
|
|
438
476
|
arxiv_id?: string;
|
|
439
477
|
language?: string;
|
|
478
|
+
/** Per-page character offsets into `content`, used to map extractions back to source pages. */
|
|
479
|
+
page_offsets?: PageOffset[];
|
|
480
|
+
/** Total number of pages in the source document. */
|
|
481
|
+
page_count?: number;
|
|
482
|
+
/** MIME type of the original source (e.g. "application/pdf"). */
|
|
483
|
+
mime_type?: string;
|
|
484
|
+
/** Re-ingest even if a document with the same content was already ingested. */
|
|
485
|
+
force_reingest?: boolean;
|
|
440
486
|
}
|
|
441
487
|
interface IngestDocumentResponse {
|
|
442
488
|
job_id: string;
|
|
443
489
|
document_uid: string;
|
|
490
|
+
/** True when the document was recognized as a duplicate and ingestion was skipped. */
|
|
491
|
+
deduplicated?: boolean;
|
|
444
492
|
}
|
|
445
493
|
interface IngestSessionRequest {
|
|
446
494
|
content: string;
|
|
@@ -478,6 +526,47 @@ interface ListArticlesResponse {
|
|
|
478
526
|
total: number;
|
|
479
527
|
has_more: boolean;
|
|
480
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Citation provenance for a graph node: the source chunk span(s) the node was
|
|
531
|
+
* extracted from. Annotated onto retrieve-context graph nodes via `source_chunks`.
|
|
532
|
+
*/
|
|
533
|
+
interface SourceChunk {
|
|
534
|
+
chunk_uid: string;
|
|
535
|
+
/** UTF-8 byte offset into the chunk where the source span starts. */
|
|
536
|
+
char_start: number | null;
|
|
537
|
+
/** UTF-8 byte offset into the chunk where the source span ends. */
|
|
538
|
+
char_end: number | null;
|
|
539
|
+
/** 1-based page number where the span starts (null if no page map). */
|
|
540
|
+
page_start: number | null;
|
|
541
|
+
/** 1-based page number where the span ends (null if no page map). */
|
|
542
|
+
page_end: number | null;
|
|
543
|
+
/** The verbatim source span (when matched), else null. */
|
|
544
|
+
quote: string | null;
|
|
545
|
+
/**
|
|
546
|
+
* Web-Annotation-style selector object pinning the node to its source span,
|
|
547
|
+
* or null when no confident match. `start`/`end` are chunk-relative UTF-8 byte
|
|
548
|
+
* offsets; `exact` is the durable quote; `prefix`/`suffix` give re-anchoring context.
|
|
549
|
+
*/
|
|
550
|
+
anchor: TextSelector | null;
|
|
551
|
+
}
|
|
552
|
+
/** A Web-Annotation quote+position selector (see `SourceChunk.anchor`). */
|
|
553
|
+
interface TextSelector {
|
|
554
|
+
exact: string;
|
|
555
|
+
prefix: string;
|
|
556
|
+
suffix: string;
|
|
557
|
+
start: number;
|
|
558
|
+
end: number;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Per-agent stance on a Claim: which agent asserts it and with what certainty.
|
|
562
|
+
* Annotated onto retrieve-context graph nodes (Claim nodes) via `believed_by`.
|
|
563
|
+
*/
|
|
564
|
+
interface BelievedBy {
|
|
565
|
+
agent_uid: string;
|
|
566
|
+
agent_label: string;
|
|
567
|
+
/** The asserting agent's certainty in the claim, or null if unspecified. */
|
|
568
|
+
confidence: number | null;
|
|
569
|
+
}
|
|
481
570
|
interface RetrieveContextResponse {
|
|
482
571
|
articles?: ArticleResult[];
|
|
483
572
|
chunks?: {
|
|
@@ -494,6 +583,8 @@ interface RetrieveContextResponse {
|
|
|
494
583
|
uid: string;
|
|
495
584
|
title: string;
|
|
496
585
|
}[];
|
|
586
|
+
source_chunks?: SourceChunk[];
|
|
587
|
+
believed_by?: BelievedBy[];
|
|
497
588
|
})[];
|
|
498
589
|
edges: Record<string, unknown>[];
|
|
499
590
|
};
|
|
@@ -674,6 +765,63 @@ interface FieldDefinition {
|
|
|
674
765
|
array_item_type?: string;
|
|
675
766
|
extraction_hint?: string;
|
|
676
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Datasource binding for an object type — the "semantic contract" mapping it to
|
|
770
|
+
* an external system (SQL today). Null/absent = extracted or authored.
|
|
771
|
+
* See docs/plans/layer7-semantic-contract.md §2.
|
|
772
|
+
*/
|
|
773
|
+
interface ObjectBacking {
|
|
774
|
+
kind: "sql";
|
|
775
|
+
/** MDO-ready list; exactly one source is supported today. */
|
|
776
|
+
sources: SqlBackingSource[];
|
|
777
|
+
/** Identity key, resolved via an indexed source_pk at sync time. */
|
|
778
|
+
primary_key: string;
|
|
779
|
+
title_field?: string;
|
|
780
|
+
sync?: BackingSync;
|
|
781
|
+
}
|
|
782
|
+
interface SqlBackingSource {
|
|
783
|
+
/** FK into external_connections — credentials live in secrets, never here. */
|
|
784
|
+
connection_ref: string;
|
|
785
|
+
table: string;
|
|
786
|
+
/** Join/identity key within this source. */
|
|
787
|
+
key: string;
|
|
788
|
+
filter?: BackingFilter;
|
|
789
|
+
/** object field name -> binding. Each field is owned by exactly one source. */
|
|
790
|
+
field_map: Record<string, FieldBinding>;
|
|
791
|
+
}
|
|
792
|
+
interface FieldBinding {
|
|
793
|
+
column: string;
|
|
794
|
+
/** indexed = projected/embedded/searchable; live = fetched on demand, never stored. */
|
|
795
|
+
mode?: "indexed" | "live";
|
|
796
|
+
}
|
|
797
|
+
/** Structured predicate (column op value) — never raw SQL. */
|
|
798
|
+
interface BackingFilter {
|
|
799
|
+
column: string;
|
|
800
|
+
op: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "is_null" | "not_null";
|
|
801
|
+
value?: unknown;
|
|
802
|
+
}
|
|
803
|
+
interface BackingSync {
|
|
804
|
+
mode?: "incremental" | "full";
|
|
805
|
+
cursor_column?: string;
|
|
806
|
+
deleted_at_column?: string;
|
|
807
|
+
/** null = manual "Sync now"; cron later. */
|
|
808
|
+
schedule?: string | null;
|
|
809
|
+
}
|
|
810
|
+
/** Datasource binding for a relation type (FK column or M:M join table). */
|
|
811
|
+
type RelationBacking = {
|
|
812
|
+
kind: "sql_fk";
|
|
813
|
+
connection_ref: string;
|
|
814
|
+
fk_table: string;
|
|
815
|
+
fk_column: string;
|
|
816
|
+
/** `table.column` the FK references (the other side's PK). */
|
|
817
|
+
references: string;
|
|
818
|
+
} | {
|
|
819
|
+
kind: "sql_join_table";
|
|
820
|
+
connection_ref: string;
|
|
821
|
+
table: string;
|
|
822
|
+
from_column: string;
|
|
823
|
+
to_column: string;
|
|
824
|
+
};
|
|
677
825
|
interface OntologySchema {
|
|
678
826
|
id: string;
|
|
679
827
|
org_id: string;
|
|
@@ -706,6 +854,8 @@ interface OntologyObjectType {
|
|
|
706
854
|
extraction_hints?: string | null;
|
|
707
855
|
default_confidence: number;
|
|
708
856
|
review_policy: "always" | "low_confidence" | "never";
|
|
857
|
+
/** Datasource binding (null = extracted/authored). */
|
|
858
|
+
backing?: ObjectBacking | null;
|
|
709
859
|
status: "active" | "deprecated" | "archived";
|
|
710
860
|
version: number;
|
|
711
861
|
created_at: string;
|
|
@@ -727,6 +877,8 @@ interface OntologyRelationType {
|
|
|
727
877
|
fields_json: FieldDefinition[];
|
|
728
878
|
extraction_hints?: string | null;
|
|
729
879
|
review_policy: "always" | "low_confidence" | "never";
|
|
880
|
+
/** Datasource binding (null = extracted/authored). */
|
|
881
|
+
backing?: RelationBacking | null;
|
|
730
882
|
status: "active" | "deprecated" | "archived";
|
|
731
883
|
version: number;
|
|
732
884
|
created_at: string;
|
|
@@ -736,6 +888,16 @@ interface OntologySchemaDetail extends OntologySchema {
|
|
|
736
888
|
object_types: OntologyObjectType[];
|
|
737
889
|
relation_types: OntologyRelationType[];
|
|
738
890
|
}
|
|
891
|
+
/** A generated read-only tool descriptor (from `listOntologyTools`). */
|
|
892
|
+
interface OntologyToolDescriptor {
|
|
893
|
+
name: string;
|
|
894
|
+
description: string;
|
|
895
|
+
schema_id: string;
|
|
896
|
+
object_type: string;
|
|
897
|
+
/** "search" | "object" | "object_context" */
|
|
898
|
+
maps_to: string;
|
|
899
|
+
input_schema: Record<string, unknown>;
|
|
900
|
+
}
|
|
739
901
|
interface CreateOntologySchemaRequest {
|
|
740
902
|
name: string;
|
|
741
903
|
description?: string;
|
|
@@ -756,6 +918,8 @@ interface OntologyObjectTypeInput {
|
|
|
756
918
|
extraction_hints?: string;
|
|
757
919
|
default_confidence?: number;
|
|
758
920
|
review_policy?: "always" | "low_confidence" | "never";
|
|
921
|
+
/** Bind this object type to an external source (SQL). Omit for extracted/authored. */
|
|
922
|
+
backing?: ObjectBacking | null;
|
|
759
923
|
}
|
|
760
924
|
interface OntologyRelationTypeInput {
|
|
761
925
|
name: string;
|
|
@@ -770,6 +934,8 @@ interface OntologyRelationTypeInput {
|
|
|
770
934
|
fields?: FieldDefinition[];
|
|
771
935
|
extraction_hints?: string;
|
|
772
936
|
review_policy?: "always" | "low_confidence" | "never";
|
|
937
|
+
/** Bind this relation to an FK column or M:M join table. Both endpoints must be sql-mapped. */
|
|
938
|
+
backing?: RelationBacking | null;
|
|
773
939
|
}
|
|
774
940
|
/** Status: pending | approved | approval_required | rejected | applied | apply_failed. */
|
|
775
941
|
interface OntologyProposal {
|
|
@@ -1175,6 +1341,10 @@ declare class MindGraph {
|
|
|
1175
1341
|
documents_processed: number;
|
|
1176
1342
|
node_source_pairs_added: number;
|
|
1177
1343
|
}>;
|
|
1344
|
+
/** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
|
|
1345
|
+
backfillAnchors(): Promise<{
|
|
1346
|
+
job_id: string;
|
|
1347
|
+
}>;
|
|
1178
1348
|
listJobs(): Promise<Job[]>;
|
|
1179
1349
|
getJob(id: string): Promise<Job>;
|
|
1180
1350
|
cancelJob(id: string): Promise<unknown>;
|
|
@@ -1305,6 +1475,15 @@ declare class MindGraph {
|
|
|
1305
1475
|
}[];
|
|
1306
1476
|
}>;
|
|
1307
1477
|
queryOntology(req: OntologyQueryRequest): Promise<OntologyQueryResponse>;
|
|
1478
|
+
/**
|
|
1479
|
+
* Read-only agent tool descriptors generated from the active ontology
|
|
1480
|
+
* schema(s). Each maps to a generic `/ontology` read endpoint with
|
|
1481
|
+
* `object_type` bound. Used by the MCP server to expose typed per-object
|
|
1482
|
+
* tools (`search_customers`, `summarize_customer`, …).
|
|
1483
|
+
*/
|
|
1484
|
+
listOntologyTools(): Promise<{
|
|
1485
|
+
tools: OntologyToolDescriptor[];
|
|
1486
|
+
}>;
|
|
1308
1487
|
getDomainObject(uid: string): Promise<DomainObject>;
|
|
1309
1488
|
getDomainObjectContext(uid: string, depth?: number): Promise<OntologyQueryResponse>;
|
|
1310
1489
|
getDomainObjectHistory(uid: string): Promise<{
|
|
@@ -1346,4 +1525,4 @@ declare class MindGraph {
|
|
|
1346
1525
|
}>;
|
|
1347
1526
|
}
|
|
1348
1527
|
|
|
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 };
|
|
1528
|
+
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
|
@@ -81,12 +81,20 @@ interface EnrichedSearchResponse {
|
|
|
81
81
|
chunks: SearchChunk[];
|
|
82
82
|
}
|
|
83
83
|
interface PathStep {
|
|
84
|
-
|
|
84
|
+
node_uid: string;
|
|
85
85
|
label: string;
|
|
86
86
|
node_type: string;
|
|
87
87
|
edge_type: string | null;
|
|
88
88
|
depth: number;
|
|
89
89
|
parent_uid: string | null;
|
|
90
|
+
/** Min-plus cost of the returned BFS path from the start node
|
|
91
|
+
* (sum of -ln(weight), weights clamped to (1e-9, 1]); cost of the path
|
|
92
|
+
* the traversal returned, not the cheapest path. 0 at the start node. */
|
|
93
|
+
path_cost?: number;
|
|
94
|
+
/** Product of edge confidences along the returned BFS path (clamped to
|
|
95
|
+
* (1e-9, 1]); a ranking signal, not a calibrated probability. 1 at the
|
|
96
|
+
* start node. */
|
|
97
|
+
path_confidence?: number;
|
|
90
98
|
}
|
|
91
99
|
interface PersonProps {
|
|
92
100
|
canonical_name: string;
|
|
@@ -357,7 +365,17 @@ interface RetrieveRequest {
|
|
|
357
365
|
* Retrieval action. Note: `"semantic"` requires a configured embedding
|
|
358
366
|
* provider on the server; for semantic search use `retrieveContext()` instead.
|
|
359
367
|
*/
|
|
360
|
-
action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "layer" | "recent";
|
|
368
|
+
action: "text" | "semantic" | "hybrid" | "active_goals" | "open_questions" | "weak_claims" | "pending_approvals" | "unresolved_contradictions" | "preferences" | "layer" | "recent";
|
|
369
|
+
/**
|
|
370
|
+
* Required for `"text"`, `"semantic"`, `"hybrid"`. Optional for
|
|
371
|
+
* `"preferences"`: with a `query` you get topic-relevant preferences (the
|
|
372
|
+
* semantic leg bridges low lexical overlap — e.g. "suggest a hotel"
|
|
373
|
+
* surfaces a stored "loved the rooftop pool"); without one you get all
|
|
374
|
+
* preferences, most salient first. Either way the result is a
|
|
375
|
+
* `SearchResult[]` (score = relevance with a query, salience without).
|
|
376
|
+
* Use `"preferences"` for advice/recommendation requests so answers
|
|
377
|
+
* reflect what the user likes.
|
|
378
|
+
*/
|
|
361
379
|
query?: string;
|
|
362
380
|
k?: number;
|
|
363
381
|
threshold?: number;
|
|
@@ -373,6 +391,16 @@ interface RetrieveRequest {
|
|
|
373
391
|
* servers ignore the field.
|
|
374
392
|
*/
|
|
375
393
|
explain?: boolean;
|
|
394
|
+
/**
|
|
395
|
+
* `recent` action only: restrict to nodes created at/after this unix
|
|
396
|
+
* timestamp (seconds). Filters by INGESTION time, not event time.
|
|
397
|
+
*/
|
|
398
|
+
created_after?: number;
|
|
399
|
+
/**
|
|
400
|
+
* `recent` action only: restrict to nodes created at/before this unix
|
|
401
|
+
* timestamp (seconds). Filters by INGESTION time, not event time.
|
|
402
|
+
*/
|
|
403
|
+
created_before?: number;
|
|
376
404
|
}
|
|
377
405
|
interface TraverseRequest {
|
|
378
406
|
action: "chain" | "neighborhood" | "path" | "subgraph";
|
|
@@ -399,6 +427,16 @@ interface EvolveRequest {
|
|
|
399
427
|
version?: number;
|
|
400
428
|
agent_id?: string;
|
|
401
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Maps a 1-based page number to the **UTF-8 byte offset** where that page begins
|
|
432
|
+
* in `content`. `char_start` is a byte offset, NOT a codepoint count — count
|
|
433
|
+
* UTF-8 bytes (`new TextEncoder().encode(s).length`), not `s.length`, or pages
|
|
434
|
+
* will be wrong for any non-ASCII document.
|
|
435
|
+
*/
|
|
436
|
+
interface PageOffset {
|
|
437
|
+
page: number;
|
|
438
|
+
char_start: number;
|
|
439
|
+
}
|
|
402
440
|
interface IngestChunkRequest {
|
|
403
441
|
content: string;
|
|
404
442
|
chunk_type?: string;
|
|
@@ -437,10 +475,20 @@ interface IngestDocumentRequest {
|
|
|
437
475
|
citation_count?: number;
|
|
438
476
|
arxiv_id?: string;
|
|
439
477
|
language?: string;
|
|
478
|
+
/** Per-page character offsets into `content`, used to map extractions back to source pages. */
|
|
479
|
+
page_offsets?: PageOffset[];
|
|
480
|
+
/** Total number of pages in the source document. */
|
|
481
|
+
page_count?: number;
|
|
482
|
+
/** MIME type of the original source (e.g. "application/pdf"). */
|
|
483
|
+
mime_type?: string;
|
|
484
|
+
/** Re-ingest even if a document with the same content was already ingested. */
|
|
485
|
+
force_reingest?: boolean;
|
|
440
486
|
}
|
|
441
487
|
interface IngestDocumentResponse {
|
|
442
488
|
job_id: string;
|
|
443
489
|
document_uid: string;
|
|
490
|
+
/** True when the document was recognized as a duplicate and ingestion was skipped. */
|
|
491
|
+
deduplicated?: boolean;
|
|
444
492
|
}
|
|
445
493
|
interface IngestSessionRequest {
|
|
446
494
|
content: string;
|
|
@@ -478,6 +526,47 @@ interface ListArticlesResponse {
|
|
|
478
526
|
total: number;
|
|
479
527
|
has_more: boolean;
|
|
480
528
|
}
|
|
529
|
+
/**
|
|
530
|
+
* Citation provenance for a graph node: the source chunk span(s) the node was
|
|
531
|
+
* extracted from. Annotated onto retrieve-context graph nodes via `source_chunks`.
|
|
532
|
+
*/
|
|
533
|
+
interface SourceChunk {
|
|
534
|
+
chunk_uid: string;
|
|
535
|
+
/** UTF-8 byte offset into the chunk where the source span starts. */
|
|
536
|
+
char_start: number | null;
|
|
537
|
+
/** UTF-8 byte offset into the chunk where the source span ends. */
|
|
538
|
+
char_end: number | null;
|
|
539
|
+
/** 1-based page number where the span starts (null if no page map). */
|
|
540
|
+
page_start: number | null;
|
|
541
|
+
/** 1-based page number where the span ends (null if no page map). */
|
|
542
|
+
page_end: number | null;
|
|
543
|
+
/** The verbatim source span (when matched), else null. */
|
|
544
|
+
quote: string | null;
|
|
545
|
+
/**
|
|
546
|
+
* Web-Annotation-style selector object pinning the node to its source span,
|
|
547
|
+
* or null when no confident match. `start`/`end` are chunk-relative UTF-8 byte
|
|
548
|
+
* offsets; `exact` is the durable quote; `prefix`/`suffix` give re-anchoring context.
|
|
549
|
+
*/
|
|
550
|
+
anchor: TextSelector | null;
|
|
551
|
+
}
|
|
552
|
+
/** A Web-Annotation quote+position selector (see `SourceChunk.anchor`). */
|
|
553
|
+
interface TextSelector {
|
|
554
|
+
exact: string;
|
|
555
|
+
prefix: string;
|
|
556
|
+
suffix: string;
|
|
557
|
+
start: number;
|
|
558
|
+
end: number;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Per-agent stance on a Claim: which agent asserts it and with what certainty.
|
|
562
|
+
* Annotated onto retrieve-context graph nodes (Claim nodes) via `believed_by`.
|
|
563
|
+
*/
|
|
564
|
+
interface BelievedBy {
|
|
565
|
+
agent_uid: string;
|
|
566
|
+
agent_label: string;
|
|
567
|
+
/** The asserting agent's certainty in the claim, or null if unspecified. */
|
|
568
|
+
confidence: number | null;
|
|
569
|
+
}
|
|
481
570
|
interface RetrieveContextResponse {
|
|
482
571
|
articles?: ArticleResult[];
|
|
483
572
|
chunks?: {
|
|
@@ -494,6 +583,8 @@ interface RetrieveContextResponse {
|
|
|
494
583
|
uid: string;
|
|
495
584
|
title: string;
|
|
496
585
|
}[];
|
|
586
|
+
source_chunks?: SourceChunk[];
|
|
587
|
+
believed_by?: BelievedBy[];
|
|
497
588
|
})[];
|
|
498
589
|
edges: Record<string, unknown>[];
|
|
499
590
|
};
|
|
@@ -674,6 +765,63 @@ interface FieldDefinition {
|
|
|
674
765
|
array_item_type?: string;
|
|
675
766
|
extraction_hint?: string;
|
|
676
767
|
}
|
|
768
|
+
/**
|
|
769
|
+
* Datasource binding for an object type — the "semantic contract" mapping it to
|
|
770
|
+
* an external system (SQL today). Null/absent = extracted or authored.
|
|
771
|
+
* See docs/plans/layer7-semantic-contract.md §2.
|
|
772
|
+
*/
|
|
773
|
+
interface ObjectBacking {
|
|
774
|
+
kind: "sql";
|
|
775
|
+
/** MDO-ready list; exactly one source is supported today. */
|
|
776
|
+
sources: SqlBackingSource[];
|
|
777
|
+
/** Identity key, resolved via an indexed source_pk at sync time. */
|
|
778
|
+
primary_key: string;
|
|
779
|
+
title_field?: string;
|
|
780
|
+
sync?: BackingSync;
|
|
781
|
+
}
|
|
782
|
+
interface SqlBackingSource {
|
|
783
|
+
/** FK into external_connections — credentials live in secrets, never here. */
|
|
784
|
+
connection_ref: string;
|
|
785
|
+
table: string;
|
|
786
|
+
/** Join/identity key within this source. */
|
|
787
|
+
key: string;
|
|
788
|
+
filter?: BackingFilter;
|
|
789
|
+
/** object field name -> binding. Each field is owned by exactly one source. */
|
|
790
|
+
field_map: Record<string, FieldBinding>;
|
|
791
|
+
}
|
|
792
|
+
interface FieldBinding {
|
|
793
|
+
column: string;
|
|
794
|
+
/** indexed = projected/embedded/searchable; live = fetched on demand, never stored. */
|
|
795
|
+
mode?: "indexed" | "live";
|
|
796
|
+
}
|
|
797
|
+
/** Structured predicate (column op value) — never raw SQL. */
|
|
798
|
+
interface BackingFilter {
|
|
799
|
+
column: string;
|
|
800
|
+
op: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "like" | "is_null" | "not_null";
|
|
801
|
+
value?: unknown;
|
|
802
|
+
}
|
|
803
|
+
interface BackingSync {
|
|
804
|
+
mode?: "incremental" | "full";
|
|
805
|
+
cursor_column?: string;
|
|
806
|
+
deleted_at_column?: string;
|
|
807
|
+
/** null = manual "Sync now"; cron later. */
|
|
808
|
+
schedule?: string | null;
|
|
809
|
+
}
|
|
810
|
+
/** Datasource binding for a relation type (FK column or M:M join table). */
|
|
811
|
+
type RelationBacking = {
|
|
812
|
+
kind: "sql_fk";
|
|
813
|
+
connection_ref: string;
|
|
814
|
+
fk_table: string;
|
|
815
|
+
fk_column: string;
|
|
816
|
+
/** `table.column` the FK references (the other side's PK). */
|
|
817
|
+
references: string;
|
|
818
|
+
} | {
|
|
819
|
+
kind: "sql_join_table";
|
|
820
|
+
connection_ref: string;
|
|
821
|
+
table: string;
|
|
822
|
+
from_column: string;
|
|
823
|
+
to_column: string;
|
|
824
|
+
};
|
|
677
825
|
interface OntologySchema {
|
|
678
826
|
id: string;
|
|
679
827
|
org_id: string;
|
|
@@ -706,6 +854,8 @@ interface OntologyObjectType {
|
|
|
706
854
|
extraction_hints?: string | null;
|
|
707
855
|
default_confidence: number;
|
|
708
856
|
review_policy: "always" | "low_confidence" | "never";
|
|
857
|
+
/** Datasource binding (null = extracted/authored). */
|
|
858
|
+
backing?: ObjectBacking | null;
|
|
709
859
|
status: "active" | "deprecated" | "archived";
|
|
710
860
|
version: number;
|
|
711
861
|
created_at: string;
|
|
@@ -727,6 +877,8 @@ interface OntologyRelationType {
|
|
|
727
877
|
fields_json: FieldDefinition[];
|
|
728
878
|
extraction_hints?: string | null;
|
|
729
879
|
review_policy: "always" | "low_confidence" | "never";
|
|
880
|
+
/** Datasource binding (null = extracted/authored). */
|
|
881
|
+
backing?: RelationBacking | null;
|
|
730
882
|
status: "active" | "deprecated" | "archived";
|
|
731
883
|
version: number;
|
|
732
884
|
created_at: string;
|
|
@@ -736,6 +888,16 @@ interface OntologySchemaDetail extends OntologySchema {
|
|
|
736
888
|
object_types: OntologyObjectType[];
|
|
737
889
|
relation_types: OntologyRelationType[];
|
|
738
890
|
}
|
|
891
|
+
/** A generated read-only tool descriptor (from `listOntologyTools`). */
|
|
892
|
+
interface OntologyToolDescriptor {
|
|
893
|
+
name: string;
|
|
894
|
+
description: string;
|
|
895
|
+
schema_id: string;
|
|
896
|
+
object_type: string;
|
|
897
|
+
/** "search" | "object" | "object_context" */
|
|
898
|
+
maps_to: string;
|
|
899
|
+
input_schema: Record<string, unknown>;
|
|
900
|
+
}
|
|
739
901
|
interface CreateOntologySchemaRequest {
|
|
740
902
|
name: string;
|
|
741
903
|
description?: string;
|
|
@@ -756,6 +918,8 @@ interface OntologyObjectTypeInput {
|
|
|
756
918
|
extraction_hints?: string;
|
|
757
919
|
default_confidence?: number;
|
|
758
920
|
review_policy?: "always" | "low_confidence" | "never";
|
|
921
|
+
/** Bind this object type to an external source (SQL). Omit for extracted/authored. */
|
|
922
|
+
backing?: ObjectBacking | null;
|
|
759
923
|
}
|
|
760
924
|
interface OntologyRelationTypeInput {
|
|
761
925
|
name: string;
|
|
@@ -770,6 +934,8 @@ interface OntologyRelationTypeInput {
|
|
|
770
934
|
fields?: FieldDefinition[];
|
|
771
935
|
extraction_hints?: string;
|
|
772
936
|
review_policy?: "always" | "low_confidence" | "never";
|
|
937
|
+
/** Bind this relation to an FK column or M:M join table. Both endpoints must be sql-mapped. */
|
|
938
|
+
backing?: RelationBacking | null;
|
|
773
939
|
}
|
|
774
940
|
/** Status: pending | approved | approval_required | rejected | applied | apply_failed. */
|
|
775
941
|
interface OntologyProposal {
|
|
@@ -1175,6 +1341,10 @@ declare class MindGraph {
|
|
|
1175
1341
|
documents_processed: number;
|
|
1176
1342
|
node_source_pairs_added: number;
|
|
1177
1343
|
}>;
|
|
1344
|
+
/** Backfill citation anchors (source_chunks spans) for existing graphs. Returns a background job id. */
|
|
1345
|
+
backfillAnchors(): Promise<{
|
|
1346
|
+
job_id: string;
|
|
1347
|
+
}>;
|
|
1178
1348
|
listJobs(): Promise<Job[]>;
|
|
1179
1349
|
getJob(id: string): Promise<Job>;
|
|
1180
1350
|
cancelJob(id: string): Promise<unknown>;
|
|
@@ -1305,6 +1475,15 @@ declare class MindGraph {
|
|
|
1305
1475
|
}[];
|
|
1306
1476
|
}>;
|
|
1307
1477
|
queryOntology(req: OntologyQueryRequest): Promise<OntologyQueryResponse>;
|
|
1478
|
+
/**
|
|
1479
|
+
* Read-only agent tool descriptors generated from the active ontology
|
|
1480
|
+
* schema(s). Each maps to a generic `/ontology` read endpoint with
|
|
1481
|
+
* `object_type` bound. Used by the MCP server to expose typed per-object
|
|
1482
|
+
* tools (`search_customers`, `summarize_customer`, …).
|
|
1483
|
+
*/
|
|
1484
|
+
listOntologyTools(): Promise<{
|
|
1485
|
+
tools: OntologyToolDescriptor[];
|
|
1486
|
+
}>;
|
|
1308
1487
|
getDomainObject(uid: string): Promise<DomainObject>;
|
|
1309
1488
|
getDomainObjectContext(uid: string, depth?: number): Promise<OntologyQueryResponse>;
|
|
1310
1489
|
getDomainObjectHistory(uid: string): Promise<{
|
|
@@ -1346,4 +1525,4 @@ declare class MindGraph {
|
|
|
1346
1525
|
}>;
|
|
1347
1526
|
}
|
|
1348
1527
|
|
|
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 };
|
|
1528
|
+
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.
|
|
3
|
+
"version": "0.9.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",
|