@causari/mcp-server 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +87 -0
- package/LICENSE +6 -0
- package/NOTICE +38 -15
- package/README.md +141 -50
- package/dist/{chunk-R5UFW6H7.js → chunk-P2UAUQ4G.js} +2 -1
- package/dist/cli.d.ts +18 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -13
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -209
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -10
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +68 -0
- package/dist/server.js.map +1 -0
- package/dist/smoke.d.ts +6 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +168 -135
- package/dist/smoke.js.map +1 -0
- package/dist/tools.d.ts +27 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +306 -0
- package/dist/tools.js.map +1 -0
- package/dist/validate.d.ts +53 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +126 -0
- package/dist/validate.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/dist/worker.d.ts +25 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +261 -0
- package/dist/worker.js.map +1 -0
- package/package.json +11 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,209 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Causal Knowledge Graph — Core Types
|
|
5
|
-
*
|
|
6
|
-
* Schema version 1.0.
|
|
7
|
-
*
|
|
8
|
-
* Three core entities:
|
|
9
|
-
* - CKGEvent: a node on the timeline (something that happened or will happen)
|
|
10
|
-
* - CausalLink: a directed edge between two events with relationship type + confidence
|
|
11
|
-
* - Insight: a derived pattern that links similar causal chains across time
|
|
12
|
-
*/
|
|
13
|
-
type Domain = 'technology' | 'humanities' | 'systems' | 'science' | 'economy' | 'geopolitics' | 'philosophy' | 'environment' | 'culture' | 'health' | 'other';
|
|
14
|
-
type Precision = 'millennium' | 'century' | 'decade' | 'year' | 'month' | 'day';
|
|
15
|
-
type CausalRelationship = 'caused' | 'enabled' | 'accelerated' | 'delayed' | 'prevented' | 'inspired';
|
|
16
|
-
type Scope = 'world' | 'personal' | 'org';
|
|
17
|
-
type SourceType = 'wikipedia' | 'wikidata' | 'academic' | 'news' | 'user' | 'ai-inferred' | 'demo-seed';
|
|
18
|
-
interface Source {
|
|
19
|
-
type: SourceType;
|
|
20
|
-
url?: string;
|
|
21
|
-
citation?: string;
|
|
22
|
-
/** 0-1 reliability score */
|
|
23
|
-
reliability: number;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* A node on the timeline. Can be historical (yearNum < 0 for BCE), present, or future.
|
|
27
|
-
*/
|
|
28
|
-
interface CKGEvent {
|
|
29
|
-
/** Stable identifier, kebab-case. e.g. "industrial-revolution" */
|
|
30
|
-
id: string;
|
|
31
|
-
/** Short display name */
|
|
32
|
-
title: string;
|
|
33
|
-
/** Longer description — explains what happened and why it matters */
|
|
34
|
-
description: string;
|
|
35
|
-
/**
|
|
36
|
-
* Numeric year. Negative = BCE. Use Number.POSITIVE_INFINITY for omega (heat death of universe).
|
|
37
|
-
* For sub-year precision, use timestamp field.
|
|
38
|
-
*/
|
|
39
|
-
yearNum: number;
|
|
40
|
-
/**
|
|
41
|
-
* Display label for the year. e.g. "1969", "-3500", "70k BCE", "∞"
|
|
42
|
-
*/
|
|
43
|
-
yearLabel: string;
|
|
44
|
-
/** Optional Unix epoch in ms for sub-year precision (post-1970 events) */
|
|
45
|
-
timestamp?: number;
|
|
46
|
-
/** Granularity of yearNum — controls UI rendering and query bucketing */
|
|
47
|
-
precision: Precision;
|
|
48
|
-
/** Knowledge domains this event belongs to */
|
|
49
|
-
domains: Domain[];
|
|
50
|
-
/**
|
|
51
|
-
* 0-1, weighted by causal connections + cultural significance.
|
|
52
|
-
* Used to filter for major events when zoomed out or when minImpact is set.
|
|
53
|
-
*/
|
|
54
|
-
impactScore: number;
|
|
55
|
-
/** Evidence for this event's existence and properties */
|
|
56
|
-
sources: Source[];
|
|
57
|
-
/** Optional Wikidata Q-id for entity linking */
|
|
58
|
-
wikidataId?: string;
|
|
59
|
-
/** Tier scope — controls visibility */
|
|
60
|
-
scope: Scope;
|
|
61
|
-
/** For org-scoped events: tenant identifier */
|
|
62
|
-
orgId?: string;
|
|
63
|
-
/** For personal-scoped events: user identifier */
|
|
64
|
-
userId?: string;
|
|
65
|
-
/**
|
|
66
|
-
* Free-form tags for search and filtering.
|
|
67
|
-
* Examples: ["AI", "watershed", "infrastructure"]
|
|
68
|
-
*/
|
|
69
|
-
tags: string[];
|
|
70
|
-
/**
|
|
71
|
-
* Confidence score for forecasted/predicted events. 0-1.
|
|
72
|
-
* Undefined = certain (historical fact).
|
|
73
|
-
*/
|
|
74
|
-
forecastConfidence?: number;
|
|
75
|
-
/** Reasoning trace for forecasted events */
|
|
76
|
-
forecastReasoning?: string;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Directed causal edge between two events.
|
|
80
|
-
*/
|
|
81
|
-
interface CausalLink {
|
|
82
|
-
id: string;
|
|
83
|
-
/** Cause event id */
|
|
84
|
-
fromEvent: string;
|
|
85
|
-
/** Effect event id */
|
|
86
|
-
toEvent: string;
|
|
87
|
-
relationship: CausalRelationship;
|
|
88
|
-
/** 0-1 confidence in this causal claim */
|
|
89
|
-
confidence: number;
|
|
90
|
-
/**
|
|
91
|
-
* Human-readable explanation of WHY this link exists.
|
|
92
|
-
* e.g. "Steam power required iron-working precision developed in the prior century"
|
|
93
|
-
*/
|
|
94
|
-
evidence: string;
|
|
95
|
-
sources: Source[];
|
|
96
|
-
/** Attribution — where this link came from */
|
|
97
|
-
contributedBy: 'system' | 'ai-inferred' | 'community' | 'expert' | string;
|
|
98
|
-
/** Has this link been validated by community/expert review? */
|
|
99
|
-
validated: boolean;
|
|
100
|
-
/** Optional tenant scoping for org links */
|
|
101
|
-
scope: Scope;
|
|
102
|
-
orgId?: string;
|
|
103
|
-
userId?: string;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* A derived pattern recognised across multiple causal chains.
|
|
107
|
-
*
|
|
108
|
-
* Example: "Information democratization cycle" — the pattern observed in
|
|
109
|
-
* Gutenberg→Reformation, Internet→Arab Spring, LLMs→? .
|
|
110
|
-
*/
|
|
111
|
-
interface Insight {
|
|
112
|
-
id: string;
|
|
113
|
-
/** Short pattern name */
|
|
114
|
-
pattern: string;
|
|
115
|
-
/** Longer description of the pattern */
|
|
116
|
-
description: string;
|
|
117
|
-
/** Causal links that demonstrate this pattern */
|
|
118
|
-
instances: string[];
|
|
119
|
-
/** 0-1 — how useful is this pattern for prediction? */
|
|
120
|
-
predictiveValue: number;
|
|
121
|
-
/** Optional contextual domains where this pattern applies */
|
|
122
|
-
domains: Domain[];
|
|
123
|
-
contributedBy: 'system' | 'ai-inferred' | 'community' | 'expert' | string;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Aggregate snapshot of CKG state — what an MCP query returns when caller asks for graph stats.
|
|
127
|
-
*/
|
|
128
|
-
interface CKGStats {
|
|
129
|
-
eventCount: number;
|
|
130
|
-
causalLinkCount: number;
|
|
131
|
-
insightCount: number;
|
|
132
|
-
domains: Record<Domain, number>;
|
|
133
|
-
scope: Scope;
|
|
134
|
-
lastUpdated: string;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* In-memory CKG store. Indexes events and links for fast traversal.
|
|
139
|
-
*
|
|
140
|
-
* For MVP this is in-memory only. Future: back with Cloudflare D1 or Postgres.
|
|
141
|
-
* The Store interface stays the same; only the implementation swaps.
|
|
142
|
-
*/
|
|
143
|
-
|
|
144
|
-
declare class CKGStore {
|
|
145
|
-
private events;
|
|
146
|
-
private links;
|
|
147
|
-
private insights;
|
|
148
|
-
private outgoing;
|
|
149
|
-
private incoming;
|
|
150
|
-
constructor(seed?: {
|
|
151
|
-
events?: CKGEvent[];
|
|
152
|
-
causalLinks?: CausalLink[];
|
|
153
|
-
insights?: Insight[];
|
|
154
|
-
});
|
|
155
|
-
addEvent(e: CKGEvent): void;
|
|
156
|
-
addLink(l: CausalLink): void;
|
|
157
|
-
addInsight(i: Insight): void;
|
|
158
|
-
getEvent(id: string): CKGEvent | undefined;
|
|
159
|
-
getLink(id: string): CausalLink | undefined;
|
|
160
|
-
getInsight(id: string): Insight | undefined;
|
|
161
|
-
/**
|
|
162
|
-
* All outgoing causal links from a given event (this event as cause).
|
|
163
|
-
* Filtered by minConfidence if provided.
|
|
164
|
-
*/
|
|
165
|
-
outgoingFrom(eventId: string, minConfidence?: number): CausalLink[];
|
|
166
|
-
/**
|
|
167
|
-
* All incoming causal links into a given event (this event as effect).
|
|
168
|
-
*/
|
|
169
|
-
incomingTo(eventId: string, minConfidence?: number): CausalLink[];
|
|
170
|
-
allEvents(): CKGEvent[];
|
|
171
|
-
allLinks(): CausalLink[];
|
|
172
|
-
allInsights(): Insight[];
|
|
173
|
-
stats(scope?: Scope): CKGStats;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Causari MCP Server core.
|
|
178
|
-
*
|
|
179
|
-
* Wires CKGStore + tool handlers to the MCP protocol. Transport-agnostic;
|
|
180
|
-
* cli.ts attaches the stdio transport.
|
|
181
|
-
*/
|
|
182
|
-
|
|
183
|
-
declare function createCausariServer(opts?: {
|
|
184
|
-
store?: CKGStore;
|
|
185
|
-
}): Server;
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* MCP tool definitions for Causari.
|
|
189
|
-
*
|
|
190
|
-
* Each tool wraps a CKG query function and shapes the result for LLM consumption.
|
|
191
|
-
* Output shape priorities:
|
|
192
|
-
* 1. Token-efficient — drop redundant fields
|
|
193
|
-
* 2. Self-explanatory — include relationship + evidence so LLM doesn't need to re-query
|
|
194
|
-
* 3. Calibrated — surface confidence + sources so LLM can communicate uncertainty
|
|
195
|
-
*/
|
|
196
|
-
|
|
197
|
-
interface ToolDef {
|
|
198
|
-
name: string;
|
|
199
|
-
description: string;
|
|
200
|
-
inputSchema: {
|
|
201
|
-
type: 'object';
|
|
202
|
-
properties: Record<string, unknown>;
|
|
203
|
-
required?: string[];
|
|
204
|
-
};
|
|
205
|
-
handler: (args: Record<string, unknown>, store: CKGStore) => unknown;
|
|
206
|
-
}
|
|
207
|
-
declare const ALL_TOOLS: ToolDef[];
|
|
208
|
-
|
|
209
|
-
export { ALL_TOOLS, createCausariServer };
|
|
1
|
+
export { createCausariServer } from './server.js';
|
|
2
|
+
export { ALL_TOOLS } from './tools.js';
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
ALL_TOOLS
|
|
6
|
-
} from "./chunk-7XWPOH6R.js";
|
|
7
|
-
export {
|
|
8
|
-
ALL_TOOLS,
|
|
9
|
-
createCausariServer
|
|
10
|
-
};
|
|
1
|
+
export { createCausariServer } from './server.js';
|
|
2
|
+
export { ALL_TOOLS } from './tools.js';
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Causari MCP Server core.
|
|
3
|
+
*
|
|
4
|
+
* Wires CKGStore + tool handlers to the MCP protocol. Transport-agnostic;
|
|
5
|
+
* cli.ts attaches the stdio transport.
|
|
6
|
+
*/
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { CKGStore } from '@causari/ckg';
|
|
9
|
+
export declare function createCausariServer(opts?: {
|
|
10
|
+
store?: CKGStore;
|
|
11
|
+
pack?: string;
|
|
12
|
+
}): Server;
|
|
13
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAKnE,OAAO,EAAE,QAAQ,EAAqC,MAAM,cAAc,CAAC;AAK3E,wBAAgB,mBAAmB,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CA8D1F"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Causari MCP Server core.
|
|
3
|
+
*
|
|
4
|
+
* Wires CKGStore + tool handlers to the MCP protocol. Transport-agnostic;
|
|
5
|
+
* cli.ts attaches the stdio transport.
|
|
6
|
+
*/
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import { CKGStore, loadSeed, loadPack, mergeSeedData } from '@causari/ckg';
|
|
10
|
+
import { ALL_TOOLS } from './tools.js';
|
|
11
|
+
import { ValidationError } from './validate.js';
|
|
12
|
+
import { VERSION, SERVER_NAME } from './version.js';
|
|
13
|
+
export function createCausariServer(opts = {}) {
|
|
14
|
+
// Default surface = computing-only core CKG (ADR-0015). A pack is OPT-IN: when
|
|
15
|
+
// `pack` is set, its themed graph is merged on top of the core so agents can
|
|
16
|
+
// query it through the same five tools. Unknown ids throw (loud, not silent).
|
|
17
|
+
const store = opts.store ??
|
|
18
|
+
new CKGStore(opts.pack ? mergeSeedData(loadSeed(), loadPack(opts.pack)) : loadSeed());
|
|
19
|
+
const server = new Server({
|
|
20
|
+
name: SERVER_NAME,
|
|
21
|
+
version: VERSION,
|
|
22
|
+
}, {
|
|
23
|
+
capabilities: {
|
|
24
|
+
tools: {},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
28
|
+
tools: ALL_TOOLS.map((t) => ({
|
|
29
|
+
name: t.name,
|
|
30
|
+
description: t.description,
|
|
31
|
+
inputSchema: t.inputSchema,
|
|
32
|
+
})),
|
|
33
|
+
}));
|
|
34
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
35
|
+
const tool = ALL_TOOLS.find((t) => t.name === request.params.name);
|
|
36
|
+
if (!tool) {
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{ type: 'text', text: `Unknown tool: ${request.params.name}` },
|
|
40
|
+
],
|
|
41
|
+
isError: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const result = tool.handler(request.params.arguments ?? {}, store);
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
// ValidationError is the caller's fault (bad args) — surface the message verbatim
|
|
52
|
+
// so the agent can correct and retry. Other errors are internal.
|
|
53
|
+
if (err instanceof ValidationError) {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: 'text', text: `Invalid arguments: ${err.message}` }],
|
|
56
|
+
isError: true,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: 'text', text: `Tool error: ${message}` }],
|
|
62
|
+
isError: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return server;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CAAC,OAA4C,EAAE;IAChF,+EAA+E;IAC/E,6EAA6E;IAC7E,8EAA8E;IAC9E,MAAM,KAAK,GACT,IAAI,CAAC,KAAK;QACV,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAExF,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,OAAO;KACjB,EACD;QACE,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;SACV;KACF,CACF,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE;iBAC/D;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACnE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kFAAkF;YAClF,iEAAiE;YACjE,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;oBACtE,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,OAAO,EAAE,EAAE,CAAC;gBAC3D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/smoke.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke.d.ts","sourceRoot":"","sources":["../src/smoke.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
package/dist/smoke.js
CHANGED
|
@@ -1,143 +1,176 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Smoke test — verifies the 5 tool handlers return sensible results
|
|
3
|
+
* against the seed CKG data. Run: node dist/smoke.js
|
|
4
|
+
*/
|
|
5
|
+
import { CKGStore, loadSeed } from '@causari/ckg';
|
|
6
|
+
import { ALL_TOOLS } from './tools.js';
|
|
7
|
+
const store = new CKGStore(loadSeed());
|
|
8
|
+
const stats = store.stats();
|
|
9
|
+
console.log('CKG stats:', stats);
|
|
10
|
+
const tests = [
|
|
11
|
+
{
|
|
12
|
+
tool: 'query_events',
|
|
13
|
+
args: { query: 'printing', limit: 5 },
|
|
14
|
+
expect: (r) => r.events?.length > 0 && r.events[0].id === 'printing'
|
|
15
|
+
? null
|
|
16
|
+
: `expected printing event, got ${JSON.stringify(r.events?.[0])}`,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
tool: 'query_events',
|
|
20
|
+
args: { yearFrom: 1900, yearTo: 2000, minImpact: 0.85 },
|
|
21
|
+
expect: (r) => r.events?.every((e) => e.yearNum >= 1900 && e.yearNum <= 2000 && e.impactScore >= 0.85)
|
|
22
|
+
? null
|
|
23
|
+
: 'year/impact filter failed',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
tool: 'query_events',
|
|
27
|
+
args: { domains: ['technology'], minImpact: 0.9 },
|
|
28
|
+
expect: (r) => r.events?.every((e) => e.domains.includes('technology') && e.impactScore >= 0.9)
|
|
29
|
+
? null
|
|
30
|
+
: 'domain/impact filter failed',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
tool: 'causal_chain',
|
|
34
|
+
args: { event: 'printing', direction: 'effects', depth: 2 },
|
|
35
|
+
expect: (r) => {
|
|
36
|
+
if (r.error)
|
|
37
|
+
return `unexpected error: ${r.error}`;
|
|
38
|
+
if (r.root.id !== 'printing')
|
|
39
|
+
return `wrong root: ${r.root.id}`;
|
|
40
|
+
const titles = r.effects.map((e) => e.id);
|
|
41
|
+
// printing → rena, printing → indus
|
|
42
|
+
if (!titles.includes('rena'))
|
|
43
|
+
return `missing rena in effects: ${titles.join(',')}`;
|
|
44
|
+
return null;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
tool: 'causal_chain',
|
|
49
|
+
args: { event: 'transformer', direction: 'causes', depth: 3 },
|
|
50
|
+
expect: (r) => {
|
|
51
|
+
if (r.error)
|
|
52
|
+
return `unexpected error: ${r.error}`;
|
|
53
|
+
if (r.root.id !== 'transformer')
|
|
54
|
+
return `wrong root: ${r.root.id}`;
|
|
55
|
+
const ids = r.causes.map((c) => c.id);
|
|
56
|
+
// transformer ← turing_m, dna_disc, iphone (depth 1)
|
|
57
|
+
if (!ids.includes('turing_m'))
|
|
58
|
+
return `missing turing_m: ${ids.join(',')}`;
|
|
59
|
+
return null;
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
tool: 'causal_chain',
|
|
64
|
+
args: { event: 'industrial', direction: 'both', depth: 2 },
|
|
65
|
+
expect: (r) => {
|
|
66
|
+
if (r.error)
|
|
67
|
+
return `unexpected error: ${r.error}`;
|
|
68
|
+
if (r.root.id !== 'indus')
|
|
69
|
+
return `title fuzzy match should resolve "industrial" → indus, got: ${r.root.id}`;
|
|
70
|
+
return null;
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
tool: 'causal_chain',
|
|
75
|
+
args: { event: 'nonexistent_xyz' },
|
|
76
|
+
expect: (r) => (r.error ? null : 'expected error for nonexistent event'),
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
tool: 'historical_resonance',
|
|
80
|
+
args: { situation: 'rapid democratization of knowledge through new technology' },
|
|
81
|
+
expect: (r) => {
|
|
82
|
+
if (!r.matches || r.matches.length === 0)
|
|
83
|
+
return 'expected at least 1 match';
|
|
84
|
+
// Should match info-democratization pattern
|
|
85
|
+
const found = r.matches.find((m) => m.pattern.toLowerCase().includes('democratization'));
|
|
86
|
+
return found ? null : `expected democratization pattern, got: ${r.matches.map((m) => m.pattern).join(', ')}`;
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
tool: 'predict_scenarios',
|
|
91
|
+
args: {
|
|
92
|
+
conditions: ['AI capabilities accelerating', 'open-source models improving'],
|
|
93
|
+
horizon: 2040,
|
|
94
|
+
domains: ['technology'],
|
|
95
|
+
},
|
|
96
|
+
expect: (r) => {
|
|
97
|
+
if (!r.scenarios || r.scenarios.length === 0)
|
|
98
|
+
return 'expected at least 1 scenario';
|
|
99
|
+
if (!r.scenarios.every((s) => typeof s.probability === 'number'))
|
|
100
|
+
return 'scenarios missing probability';
|
|
101
|
+
return null;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
// Regression: a plausible condition that lexically matches no forecast-event
|
|
106
|
+
// text must still fall back to the horizon/domain set, not return empty.
|
|
107
|
+
tool: 'predict_scenarios',
|
|
108
|
+
args: { conditions: ['AI capability accelerating'], domains: ['technology'] },
|
|
109
|
+
expect: (r) => r.scenarios?.length > 0
|
|
110
|
+
? null
|
|
111
|
+
: 'expected non-empty scenarios via horizon/domain fallback when conditions do not lexically match',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
tool: 'org_knowledge',
|
|
115
|
+
args: { query: 'database decisions', orgId: 'demo-org-no-data' },
|
|
116
|
+
expect: (r) => (r.available === false ? null : 'expected available=false for empty org'),
|
|
117
|
+
},
|
|
118
|
+
// ── AI history extension (events-ai-history.ts) ──────────────────────
|
|
119
|
+
{
|
|
120
|
+
tool: 'query_events',
|
|
121
|
+
args: { query: 'chatgpt', limit: 3 },
|
|
122
|
+
expect: (r) => r.events?.some((e) => e.id === 'chatgpt')
|
|
123
|
+
? null
|
|
124
|
+
: `expected chatgpt in results, got: ${r.events?.map((e) => e.id).join(',')}`,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
tool: 'causal_chain',
|
|
128
|
+
args: { event: 'chatgpt', direction: 'causes', depth: 4 },
|
|
129
|
+
expect: (r) => {
|
|
130
|
+
if (r.error)
|
|
131
|
+
return `unexpected error: ${r.error}`;
|
|
132
|
+
const ids = r.causes.map((c) => c.id);
|
|
133
|
+
// chatgpt ← gpt3 ← gpt2 ← transformer ← alexnet
|
|
134
|
+
if (!ids.includes('gpt3'))
|
|
135
|
+
return `missing gpt3: ${ids.join(',')}`;
|
|
136
|
+
if (!ids.includes('transformer'))
|
|
137
|
+
return `missing transformer: ${ids.join(',')}`;
|
|
138
|
+
return null;
|
|
139
|
+
},
|
|
78
140
|
},
|
|
79
|
-
expect: (r) => {
|
|
80
|
-
if (!r.scenarios || r.scenarios.length === 0) return "expected at least 1 scenario";
|
|
81
|
-
if (!r.scenarios.every((s) => typeof s.probability === "number")) return "scenarios missing probability";
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
tool: "org_knowledge",
|
|
87
|
-
args: { query: "database decisions", orgId: "demo-org-no-data" },
|
|
88
|
-
expect: (r) => r.available === false ? null : "expected available=false for empty org"
|
|
89
|
-
},
|
|
90
|
-
// ── AI history extension (events-ai-history.ts) ──────────────────────
|
|
91
|
-
{
|
|
92
|
-
tool: "query_events",
|
|
93
|
-
args: { query: "chatgpt", limit: 3 },
|
|
94
|
-
expect: (r) => r.events?.some((e) => e.id === "chatgpt") ? null : `expected chatgpt in results, got: ${r.events?.map((e) => e.id).join(",")}`
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
tool: "causal_chain",
|
|
98
|
-
args: { event: "chatgpt", direction: "causes", depth: 4 },
|
|
99
|
-
expect: (r) => {
|
|
100
|
-
if (r.error) return `unexpected error: ${r.error}`;
|
|
101
|
-
const ids = r.causes.map((c) => c.id);
|
|
102
|
-
if (!ids.includes("gpt3")) return `missing gpt3: ${ids.join(",")}`;
|
|
103
|
-
if (!ids.includes("transformer")) return `missing transformer: ${ids.join(",")}`;
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
141
|
];
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
let passed = 0;
|
|
143
|
+
let failed = 0;
|
|
144
|
+
const failures = [];
|
|
111
145
|
for (const t of tests) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
const tool = ALL_TOOLS.find((x) => x.name === t.tool);
|
|
147
|
+
if (!tool) {
|
|
148
|
+
failures.push(`Unknown tool ${t.tool}`);
|
|
149
|
+
failed++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const result = tool.handler(t.args, store);
|
|
153
|
+
const err = t.expect(result);
|
|
154
|
+
if (err) {
|
|
155
|
+
failed++;
|
|
156
|
+
failures.push(`[${t.tool}] ${JSON.stringify(t.args)}\n → ${err}`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
passed++;
|
|
160
|
+
}
|
|
127
161
|
}
|
|
128
|
-
console.log(
|
|
129
|
-
=== Smoke test ===`);
|
|
162
|
+
console.log(`\n=== Smoke test ===`);
|
|
130
163
|
console.log(`PASS: ${passed}/${tests.length}`);
|
|
131
164
|
if (failed > 0) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
165
|
+
console.log(`FAIL: ${failed}`);
|
|
166
|
+
failures.forEach((f) => console.log(` ${f}`));
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
console.log('All tests passed.');
|
|
137
171
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
store
|
|
142
|
-
);
|
|
172
|
+
// Print one full sample so we can eyeball the LLM-facing format
|
|
173
|
+
console.log('\n=== Sample causal_chain output ===');
|
|
174
|
+
const sample = ALL_TOOLS.find((t) => t.name === 'causal_chain').handler({ event: 'transformer', direction: 'causes', depth: 2 }, store);
|
|
143
175
|
console.log(JSON.stringify(sample, null, 2));
|
|
176
|
+
//# sourceMappingURL=smoke.js.map
|