@graview/tools 0.1.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 +96 -0
- package/README.md +47 -0
- package/dist/agent/adapters.d.ts +43 -0
- package/dist/agent/adapters.d.ts.map +1 -0
- package/dist/agent/adapters.js +52 -0
- package/dist/agent/adapters.js.map +1 -0
- package/dist/agent/tools.d.ts +105 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +311 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/cli.d.ts +37 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +306 -0
- package/dist/cli.js.map +1 -0
- package/dist/conversation.d.ts +108 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +698 -0
- package/dist/conversation.js.map +1 -0
- package/dist/decide.d.ts +43 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +125 -0
- package/dist/decide.js.map +1 -0
- package/dist/derive.d.ts +84 -0
- package/dist/derive.d.ts.map +1 -0
- package/dist/derive.js +302 -0
- package/dist/derive.js.map +1 -0
- package/dist/edit.d.ts +70 -0
- package/dist/edit.d.ts.map +1 -0
- package/dist/edit.js +97 -0
- package/dist/edit.js.map +1 -0
- package/dist/figure.d.ts +53 -0
- package/dist/figure.d.ts.map +1 -0
- package/dist/figure.js +86 -0
- package/dist/figure.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/intelligence.d.ts +132 -0
- package/dist/intelligence.d.ts.map +1 -0
- package/dist/intelligence.js +463 -0
- package/dist/intelligence.js.map +1 -0
- package/dist/local.d.ts +192 -0
- package/dist/local.d.ts.map +1 -0
- package/dist/local.js +365 -0
- package/dist/local.js.map +1 -0
- package/dist/loop.d.ts +84 -0
- package/dist/loop.d.ts.map +1 -0
- package/dist/loop.js +173 -0
- package/dist/loop.js.map +1 -0
- package/dist/mcp-stdio.d.ts +38 -0
- package/dist/mcp-stdio.d.ts.map +1 -0
- package/dist/mcp-stdio.js +83 -0
- package/dist/mcp-stdio.js.map +1 -0
- package/dist/pins.d.ts +29 -0
- package/dist/pins.d.ts.map +1 -0
- package/dist/pins.js +60 -0
- package/dist/pins.js.map +1 -0
- package/dist/plan.d.ts +150 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +303 -0
- package/dist/plan.js.map +1 -0
- package/dist/providers/insight.d.ts +14 -0
- package/dist/providers/insight.d.ts.map +1 -0
- package/dist/providers/insight.js +81 -0
- package/dist/providers/insight.js.map +1 -0
- package/dist/providers/invariant.d.ts +14 -0
- package/dist/providers/invariant.d.ts.map +1 -0
- package/dist/providers/invariant.js +123 -0
- package/dist/providers/invariant.js.map +1 -0
- package/dist/providers/jev.d.ts +115 -0
- package/dist/providers/jev.d.ts.map +1 -0
- package/dist/providers/jev.js +148 -0
- package/dist/providers/jev.js.map +1 -0
- package/dist/providers/lens.d.ts +24 -0
- package/dist/providers/lens.d.ts.map +1 -0
- package/dist/providers/lens.js +36 -0
- package/dist/providers/lens.js.map +1 -0
- package/dist/providers/llm.d.ts +25 -0
- package/dist/providers/llm.d.ts.map +1 -0
- package/dist/providers/llm.js +44 -0
- package/dist/providers/llm.js.map +1 -0
- package/dist/providers/schema.d.ts +12 -0
- package/dist/providers/schema.d.ts.map +1 -0
- package/dist/providers/schema.js +508 -0
- package/dist/providers/schema.js.map +1 -0
- package/dist/providers/structure.d.ts +14 -0
- package/dist/providers/structure.d.ts.map +1 -0
- package/dist/providers/structure.js +211 -0
- package/dist/providers/structure.js.map +1 -0
- package/dist/questions.d.ts +162 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +316 -0
- package/dist/questions.js.map +1 -0
- package/dist/run.d.ts +202 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +453 -0
- package/dist/run.js.map +1 -0
- package/dist/space.d.ts +50 -0
- package/dist/space.d.ts.map +1 -0
- package/dist/space.js +55 -0
- package/dist/space.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/usage.d.ts +10 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +59 -0
- package/dist/usage.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Question } from "../questions.js";
|
|
2
|
+
/**
|
|
3
|
+
* THE PROVIDER ITSELF: one call, many questions, honest about failure.
|
|
4
|
+
*
|
|
5
|
+
* A decision provider takes one state and a MAP of typed questions and
|
|
6
|
+
* answers under the same keys — so a node's whole unset half is one
|
|
7
|
+
* request, not one per field, and a fan-out over every node of a kind is
|
|
8
|
+
* as many requests as there are nodes, never as many as there are fields.
|
|
9
|
+
*
|
|
10
|
+
* What comes back is typed by construction: a Choice is one of the names
|
|
11
|
+
* we sent, a truth is a probability, a Score is a weighted position on the
|
|
12
|
+
* levels we sent. There is no parse-and-refuse layer because there is
|
|
13
|
+
* nothing to parse.
|
|
14
|
+
*
|
|
15
|
+
* Failure is told apart by whose it is. 429 and 529 are the service busy,
|
|
16
|
+
* and are retried with backoff; 401 is the SEAT's problem — the key was
|
|
17
|
+
* refused — and is said so; 422 is OURS — we sent a malformed question —
|
|
18
|
+
* and is said so, because blaming the model for a bug in the derivation
|
|
19
|
+
* would send somebody looking in the wrong place.
|
|
20
|
+
*
|
|
21
|
+
* The key is read from the environment and travels in one header. It is
|
|
22
|
+
* never in a thrown error, never in a log line, never in the graph.
|
|
23
|
+
*/
|
|
24
|
+
export declare const JEV_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
|
|
25
|
+
export declare const JEV_MODEL = "jev-latest";
|
|
26
|
+
/** Input is metered at this rate; output is not metered at all. */
|
|
27
|
+
export declare const JEV_INPUT_USD_PER_MILLION = 0.042;
|
|
28
|
+
export type ChoiceAnswer = {
|
|
29
|
+
readonly type: "choice";
|
|
30
|
+
readonly choice: string;
|
|
31
|
+
readonly confidence: number;
|
|
32
|
+
readonly probabilities: Readonly<Record<string, number>>;
|
|
33
|
+
};
|
|
34
|
+
export type NoulAnswer = {
|
|
35
|
+
readonly type: "noul";
|
|
36
|
+
readonly noul: number;
|
|
37
|
+
};
|
|
38
|
+
export type ScoreAnswer = {
|
|
39
|
+
readonly type: "score";
|
|
40
|
+
readonly score: number;
|
|
41
|
+
readonly confidence: number;
|
|
42
|
+
readonly probabilities: Readonly<Record<string, number>>;
|
|
43
|
+
readonly legend: Readonly<Record<string, string>>;
|
|
44
|
+
};
|
|
45
|
+
export type Answer = ChoiceAnswer | NoulAnswer | ScoreAnswer;
|
|
46
|
+
export interface Usage {
|
|
47
|
+
readonly inputTokens: number;
|
|
48
|
+
readonly outputTokens: number;
|
|
49
|
+
/** Requests made, retries excluded. */
|
|
50
|
+
readonly calls: number;
|
|
51
|
+
readonly questions: number;
|
|
52
|
+
}
|
|
53
|
+
export interface Decided {
|
|
54
|
+
readonly answers: Readonly<Record<string, Answer>>;
|
|
55
|
+
/** This call's own usage. */
|
|
56
|
+
readonly usage: {
|
|
57
|
+
readonly inputTokens: number;
|
|
58
|
+
readonly outputTokens: number;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** The whole provider surface: one state, a map of questions, typed answers back. */
|
|
62
|
+
export type Decide = (state: unknown, questions: Readonly<Record<string, Question>>) => Promise<Decided>;
|
|
63
|
+
/** Whose failure it was, so a surface can say so. */
|
|
64
|
+
export type JevFailure = "seat" | "ours" | "busy" | "network" | "shape";
|
|
65
|
+
export declare class JevError extends Error {
|
|
66
|
+
readonly failure: JevFailure;
|
|
67
|
+
readonly status: number | undefined;
|
|
68
|
+
constructor(failure: JevFailure, message: string, status?: number);
|
|
69
|
+
}
|
|
70
|
+
type FetchLike = (input: string, init: {
|
|
71
|
+
method: string;
|
|
72
|
+
headers: Record<string, string>;
|
|
73
|
+
body: string;
|
|
74
|
+
signal?: AbortSignal;
|
|
75
|
+
}) => Promise<{
|
|
76
|
+
ok: boolean;
|
|
77
|
+
status: number;
|
|
78
|
+
text(): Promise<string>;
|
|
79
|
+
}>;
|
|
80
|
+
export interface JevOptions {
|
|
81
|
+
/**
|
|
82
|
+
* The key, when the call goes straight to the provider. Absent when the
|
|
83
|
+
* call goes to a bridge that holds the key itself (see `baseUrl`).
|
|
84
|
+
*/
|
|
85
|
+
readonly apiKey?: string;
|
|
86
|
+
/** Where to post. The provider itself, or a same-origin bridge. */
|
|
87
|
+
readonly baseUrl?: string;
|
|
88
|
+
readonly model?: string;
|
|
89
|
+
/** How many times a busy answer is retried before it is given up on. */
|
|
90
|
+
readonly retries?: number;
|
|
91
|
+
/** Injectable: how long to wait before retry `n` (1-based), in ms. */
|
|
92
|
+
readonly backoffMs?: (attempt: number) => number;
|
|
93
|
+
/** Injectable for tests. */
|
|
94
|
+
readonly fetch?: FetchLike;
|
|
95
|
+
readonly sleep?: (ms: number) => Promise<void>;
|
|
96
|
+
/** Told after every completed request, with the running total. */
|
|
97
|
+
readonly onUsage?: (usage: Usage) => void;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The key, from the environment: TYPESAFE_API_KEY is the documented name;
|
|
101
|
+
* JEV_API_KEY is accepted for the person who set it before reading the
|
|
102
|
+
* docs. In a browser there is no environment, and this answers undefined —
|
|
103
|
+
* which is what makes a bridge the right door there.
|
|
104
|
+
*/
|
|
105
|
+
export declare function jevKeyFromEnvironment(env?: Readonly<Record<string, string | undefined>> | undefined): string | undefined;
|
|
106
|
+
/** What a number of input tokens costs, in dollars. Output is free. */
|
|
107
|
+
export declare function jevCostUsd(inputTokens: number): number;
|
|
108
|
+
/**
|
|
109
|
+
* One Decide from one key (or one bridge). Retries are the service's busy
|
|
110
|
+
* answers only — 429, 529 — with backoff; everything else is said once,
|
|
111
|
+
* with whose failure it was, and never with the key in it.
|
|
112
|
+
*/
|
|
113
|
+
export declare function jevDecide(options?: JevOptions): Decide;
|
|
114
|
+
export {};
|
|
115
|
+
//# sourceMappingURL=jev.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.d.ts","sourceRoot":"","sources":["../../src/providers/jev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PROVIDER ITSELF: one call, many questions, honest about failure.
|
|
3
|
+
*
|
|
4
|
+
* A decision provider takes one state and a MAP of typed questions and
|
|
5
|
+
* answers under the same keys — so a node's whole unset half is one
|
|
6
|
+
* request, not one per field, and a fan-out over every node of a kind is
|
|
7
|
+
* as many requests as there are nodes, never as many as there are fields.
|
|
8
|
+
*
|
|
9
|
+
* What comes back is typed by construction: a Choice is one of the names
|
|
10
|
+
* we sent, a truth is a probability, a Score is a weighted position on the
|
|
11
|
+
* levels we sent. There is no parse-and-refuse layer because there is
|
|
12
|
+
* nothing to parse.
|
|
13
|
+
*
|
|
14
|
+
* Failure is told apart by whose it is. 429 and 529 are the service busy,
|
|
15
|
+
* and are retried with backoff; 401 is the SEAT's problem — the key was
|
|
16
|
+
* refused — and is said so; 422 is OURS — we sent a malformed question —
|
|
17
|
+
* and is said so, because blaming the model for a bug in the derivation
|
|
18
|
+
* would send somebody looking in the wrong place.
|
|
19
|
+
*
|
|
20
|
+
* The key is read from the environment and travels in one header. It is
|
|
21
|
+
* never in a thrown error, never in a log line, never in the graph.
|
|
22
|
+
*/
|
|
23
|
+
export const JEV_ENDPOINT = "https://api.typesafe.ai/v1/systemone";
|
|
24
|
+
export const JEV_MODEL = "jev-latest";
|
|
25
|
+
/** Input is metered at this rate; output is not metered at all. */
|
|
26
|
+
export const JEV_INPUT_USD_PER_MILLION = 0.042;
|
|
27
|
+
export class JevError extends Error {
|
|
28
|
+
failure;
|
|
29
|
+
status;
|
|
30
|
+
constructor(failure, message, status) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "JevError";
|
|
33
|
+
this.failure = failure;
|
|
34
|
+
this.status = status;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The key, from the environment: TYPESAFE_API_KEY is the documented name;
|
|
39
|
+
* JEV_API_KEY is accepted for the person who set it before reading the
|
|
40
|
+
* docs. In a browser there is no environment, and this answers undefined —
|
|
41
|
+
* which is what makes a bridge the right door there.
|
|
42
|
+
*/
|
|
43
|
+
export function jevKeyFromEnvironment(env = globalThis.process?.env) {
|
|
44
|
+
const key = env?.["TYPESAFE_API_KEY"] || env?.["JEV_API_KEY"];
|
|
45
|
+
return key && key.length > 0 ? key : undefined;
|
|
46
|
+
}
|
|
47
|
+
/** What a number of input tokens costs, in dollars. Output is free. */
|
|
48
|
+
export function jevCostUsd(inputTokens) {
|
|
49
|
+
return (inputTokens / 1_000_000) * JEV_INPUT_USD_PER_MILLION;
|
|
50
|
+
}
|
|
51
|
+
const isAnswer = (value) => {
|
|
52
|
+
if (typeof value !== "object" || value === null)
|
|
53
|
+
return false;
|
|
54
|
+
const answer = value;
|
|
55
|
+
switch (answer.type) {
|
|
56
|
+
case "choice":
|
|
57
|
+
return typeof answer.choice === "string";
|
|
58
|
+
case "noul":
|
|
59
|
+
return typeof answer.noul === "number";
|
|
60
|
+
case "score":
|
|
61
|
+
return typeof answer.score === "number";
|
|
62
|
+
default:
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* One Decide from one key (or one bridge). Retries are the service's busy
|
|
68
|
+
* answers only — 429, 529 — with backoff; everything else is said once,
|
|
69
|
+
* with whose failure it was, and never with the key in it.
|
|
70
|
+
*/
|
|
71
|
+
export function jevDecide(options = {}) {
|
|
72
|
+
const call = options.fetch ?? globalThis.fetch;
|
|
73
|
+
const url = options.baseUrl ?? JEV_ENDPOINT;
|
|
74
|
+
const retries = options.retries ?? 3;
|
|
75
|
+
const backoff = options.backoffMs ?? ((attempt) => 400 * 2 ** (attempt - 1));
|
|
76
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
77
|
+
const total = { inputTokens: 0, outputTokens: 0, calls: 0, questions: 0 };
|
|
78
|
+
return async (state, questions) => {
|
|
79
|
+
const asked = Object.keys(questions).length;
|
|
80
|
+
if (asked === 0)
|
|
81
|
+
return { answers: {}, usage: { inputTokens: 0, outputTokens: 0 } };
|
|
82
|
+
const body = JSON.stringify({ model: options.model ?? JEV_MODEL, state, questions });
|
|
83
|
+
const headers = { "content-type": "application/json" };
|
|
84
|
+
if (options.apiKey)
|
|
85
|
+
headers["authorization"] = `Bearer ${options.apiKey}`;
|
|
86
|
+
for (let attempt = 0;; attempt++) {
|
|
87
|
+
let response;
|
|
88
|
+
try {
|
|
89
|
+
response = await call(url, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers,
|
|
92
|
+
body,
|
|
93
|
+
...(typeof AbortSignal !== "undefined" && "timeout" in AbortSignal ? { signal: AbortSignal.timeout(60_000) } : {}),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
throw new JevError("network", `The decision provider could not be reached: ${error instanceof Error ? error.message : String(error)}`);
|
|
98
|
+
}
|
|
99
|
+
if (response.status === 429 || response.status === 529) {
|
|
100
|
+
if (attempt < retries) {
|
|
101
|
+
await sleep(backoff(attempt + 1));
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
throw new JevError("busy", `The decision provider is ${response.status === 429 ? "rate-limiting" : "overloaded"} and stayed so through ${retries} retries.`, response.status);
|
|
105
|
+
}
|
|
106
|
+
if (response.status === 401 || response.status === 403) {
|
|
107
|
+
throw new JevError("seat", "The decision provider refused the key. That is a seat problem — check TYPESAFE_API_KEY — not the model's.", response.status);
|
|
108
|
+
}
|
|
109
|
+
if (response.status === 422) {
|
|
110
|
+
const said = (await response.text()).slice(0, 240);
|
|
111
|
+
throw new JevError("ours", `The decision provider could not read a question we sent. That is our bug, not the model's: ${said}`, 422);
|
|
112
|
+
}
|
|
113
|
+
if (!response.ok) {
|
|
114
|
+
throw new JevError("network", `The decision provider answered ${response.status}: ${(await response.text()).slice(0, 160)}`, response.status);
|
|
115
|
+
}
|
|
116
|
+
let parsed;
|
|
117
|
+
try {
|
|
118
|
+
parsed = JSON.parse(await response.text());
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
throw new JevError("shape", "The decision provider answered in a shape that is not JSON.");
|
|
122
|
+
}
|
|
123
|
+
if (typeof parsed.error === "string") {
|
|
124
|
+
throw new JevError("network", `The decision provider said: ${parsed.error}`, response.status);
|
|
125
|
+
}
|
|
126
|
+
const answers = {};
|
|
127
|
+
for (const [key, value] of Object.entries(parsed.answers ?? {})) {
|
|
128
|
+
if (!(key in questions))
|
|
129
|
+
continue;
|
|
130
|
+
if (!isAnswer(value))
|
|
131
|
+
throw new JevError("shape", `The answer to "${key}" is not a typed answer.`);
|
|
132
|
+
answers[key] = value;
|
|
133
|
+
}
|
|
134
|
+
for (const key of Object.keys(questions)) {
|
|
135
|
+
if (!(key in answers))
|
|
136
|
+
throw new JevError("shape", `No answer came back for "${key}".`);
|
|
137
|
+
}
|
|
138
|
+
const usage = { inputTokens: parsed.usage?.input_tokens ?? 0, outputTokens: parsed.usage?.output_tokens ?? 0 };
|
|
139
|
+
total.inputTokens += usage.inputTokens;
|
|
140
|
+
total.outputTokens += usage.outputTokens;
|
|
141
|
+
total.calls += 1;
|
|
142
|
+
total.questions += asked;
|
|
143
|
+
options.onUsage?.({ ...total });
|
|
144
|
+
return { answers, usage };
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=jev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jev.js","sourceRoot":"","sources":["../../src/providers/jev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AnySchema, NodeOfSchema } from "@graview/core";
|
|
2
|
+
import type { AffordanceProvider } from "../types.js";
|
|
3
|
+
export interface LensAction<S extends AnySchema> {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly mutation: string;
|
|
7
|
+
/** Whether this lens can do anything with the given selection. */
|
|
8
|
+
readonly applies: (nodes: readonly NodeOfSchema<S>[]) => boolean;
|
|
9
|
+
readonly args: (nodes: readonly NodeOfSchema<S>[]) => Readonly<Record<string, unknown>>;
|
|
10
|
+
readonly why?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* What the ACTIVE lens can do with this selection — collapse, align, group.
|
|
14
|
+
*
|
|
15
|
+
* A lens is a way of looking, so its actions belong to the looking rather
|
|
16
|
+
* than to the schema: "collapse this week" means nothing outside a timeline.
|
|
17
|
+
* Registering them here keeps them in the same ranked set as everything else,
|
|
18
|
+
* so the interface never has two competing action surfaces.
|
|
19
|
+
*/
|
|
20
|
+
export declare function lensProvider<S extends AnySchema>(lens: {
|
|
21
|
+
name: string;
|
|
22
|
+
actions: readonly LensAction<S>[];
|
|
23
|
+
}): AffordanceProvider<S>;
|
|
24
|
+
//# sourceMappingURL=lens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens.d.ts","sourceRoot":"","sources":["../../src/providers/lens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAIlE,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,SAAS;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC;IACjE,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAC9C,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;CAAE,GACxD,kBAAkB,CAAC,CAAC,CAAC,CAuBvB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const LENS_SCORE = 55;
|
|
2
|
+
/**
|
|
3
|
+
* What the ACTIVE lens can do with this selection — collapse, align, group.
|
|
4
|
+
*
|
|
5
|
+
* A lens is a way of looking, so its actions belong to the looking rather
|
|
6
|
+
* than to the schema: "collapse this week" means nothing outside a timeline.
|
|
7
|
+
* Registering them here keeps them in the same ranked set as everything else,
|
|
8
|
+
* so the interface never has two competing action surfaces.
|
|
9
|
+
*/
|
|
10
|
+
export function lensProvider(lens) {
|
|
11
|
+
return {
|
|
12
|
+
name: "lens",
|
|
13
|
+
derive({ nodes }) {
|
|
14
|
+
if (nodes.length === 0)
|
|
15
|
+
return {};
|
|
16
|
+
const affordances = [];
|
|
17
|
+
for (const action of lens.actions) {
|
|
18
|
+
if (!action.applies(nodes))
|
|
19
|
+
continue;
|
|
20
|
+
affordances.push({
|
|
21
|
+
id: `lens:${lens.name}:${action.id}`,
|
|
22
|
+
label: action.label,
|
|
23
|
+
provider: "lens",
|
|
24
|
+
mutation: action.mutation,
|
|
25
|
+
args: action.args(nodes),
|
|
26
|
+
open: [],
|
|
27
|
+
score: LENS_SCORE,
|
|
28
|
+
why: action.why ?? `the ${lens.name} lens can do this here`,
|
|
29
|
+
nodeIds: nodes.map((node) => node.id),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return { affordances };
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=lens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lens.js","sourceRoot":"","sources":["../../src/providers/lens.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,GAAG,EAAE,CAAC;AAYtB;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAyD;IAEzD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,MAAM,CAAC,EAAE,KAAK,EAAE;YACd,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAClC,MAAM,WAAW,GAAiB,EAAE,CAAC;YACrC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;oBAAE,SAAS;gBACrC,WAAW,CAAC,IAAI,CAAC;oBACf,EAAE,EAAE,QAAQ,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,EAAE;oBACpC,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,QAAQ,EAAE,MAAM;oBAChB,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;oBACxB,IAAI,EAAE,EAAE;oBACR,KAAK,EAAE,UAAU;oBACjB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,IAAI,wBAAwB;oBAC3D,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;iBACtC,CAAC,CAAC;YACL,CAAC;YACD,OAAO,EAAE,WAAW,EAAE,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AnySchema } from "@graview/core";
|
|
2
|
+
import type { Affordance, DeriveContext } from "../types.js";
|
|
3
|
+
export interface LlmProposal {
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly mutation: string;
|
|
6
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
7
|
+
readonly why: string;
|
|
8
|
+
}
|
|
9
|
+
export interface LlmProvider<S extends AnySchema> {
|
|
10
|
+
propose(context: DeriveContext<S>): Promise<readonly LlmProposal[]>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The LLM is ONE affordance provider, and an optional one — not the
|
|
14
|
+
* mechanism. It runs last, only when the schema, the invariants and the
|
|
15
|
+
* structure of the graph came up short, and everything it returns is checked
|
|
16
|
+
* against the same schema and invariants as everything else.
|
|
17
|
+
*
|
|
18
|
+
* Nothing here talks to a model. An app injects one, which keeps the whole
|
|
19
|
+
* tools package headless and testable, and keeps "no LLM configured" an
|
|
20
|
+
* ordinary state rather than a degraded one.
|
|
21
|
+
*/
|
|
22
|
+
export declare function deriveWithLlm<S extends AnySchema>(provider: LlmProvider<S>, context: DeriveContext<S>, existing: readonly Affordance[], options?: {
|
|
23
|
+
minimum?: number;
|
|
24
|
+
}): Promise<Affordance[]>;
|
|
25
|
+
//# sourceMappingURL=llm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.d.ts","sourceRoot":"","sources":["../../src/providers/llm.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,SAAS;IAC9C,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAC;CACrE;AAID;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,CAAC,SAAS,SAAS,EACrD,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EACzB,QAAQ,EAAE,SAAS,UAAU,EAAE,EAC/B,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GACjC,OAAO,CAAC,UAAU,EAAE,CAAC,CA8BvB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const LLM_SCORE = 20;
|
|
2
|
+
/**
|
|
3
|
+
* The LLM is ONE affordance provider, and an optional one — not the
|
|
4
|
+
* mechanism. It runs last, only when the schema, the invariants and the
|
|
5
|
+
* structure of the graph came up short, and everything it returns is checked
|
|
6
|
+
* against the same schema and invariants as everything else.
|
|
7
|
+
*
|
|
8
|
+
* Nothing here talks to a model. An app injects one, which keeps the whole
|
|
9
|
+
* tools package headless and testable, and keeps "no LLM configured" an
|
|
10
|
+
* ordinary state rather than a degraded one.
|
|
11
|
+
*/
|
|
12
|
+
export async function deriveWithLlm(provider, context, existing, options = {}) {
|
|
13
|
+
const minimum = options.minimum ?? 3;
|
|
14
|
+
if (existing.length >= minimum)
|
|
15
|
+
return [];
|
|
16
|
+
const proposals = await provider.propose(context);
|
|
17
|
+
const affordances = [];
|
|
18
|
+
proposals.forEach((proposal, index) => {
|
|
19
|
+
// A proposal naming a mutation that does not exist is a hallucination,
|
|
20
|
+
// and it stops here rather than reaching the interface.
|
|
21
|
+
let known = true;
|
|
22
|
+
try {
|
|
23
|
+
context.store.mutation(proposal.mutation);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
known = false;
|
|
27
|
+
}
|
|
28
|
+
if (!known)
|
|
29
|
+
return;
|
|
30
|
+
affordances.push({
|
|
31
|
+
id: `llm:${index}`,
|
|
32
|
+
label: proposal.label,
|
|
33
|
+
provider: "llm",
|
|
34
|
+
mutation: proposal.mutation,
|
|
35
|
+
args: proposal.args,
|
|
36
|
+
open: [],
|
|
37
|
+
score: LLM_SCORE - index,
|
|
38
|
+
why: proposal.why,
|
|
39
|
+
nodeIds: context.selection,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return affordances;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=llm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm.js","sourceRoot":"","sources":["../../src/providers/llm.ts"],"names":[],"mappings":"AAcA,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAwB,EACxB,OAAyB,EACzB,QAA+B,EAC/B,UAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IACrC,IAAI,QAAQ,CAAC,MAAM,IAAI,OAAO;QAAE,OAAO,EAAE,CAAC;IAE1C,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,WAAW,GAAiB,EAAE,CAAC;IACrC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;QACpC,uEAAuE;QACvE,wDAAwD;QACxD,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,OAAO;QAEnB,WAAW,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,OAAO,KAAK,EAAE;YAClB,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,SAAS,GAAG,KAAK;YACxB,GAAG,EAAE,QAAQ,CAAC,GAAG;YACjB,OAAO,EAAE,OAAO,CAAC,SAAS;SAC3B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type AnySchema } from "@graview/core";
|
|
2
|
+
import type { AffordanceProvider } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Which typed mutations are legal across the WHOLE selection.
|
|
5
|
+
*
|
|
6
|
+
* The declaration already says which kinds a mutation acts on and which
|
|
7
|
+
* argument the subject binds to, so "all three selected nodes are duties, and
|
|
8
|
+
* reassign acts on duties" is a fact the schema can answer — no per-selection
|
|
9
|
+
* code, and a new node kind gets its affordances the moment it is declared.
|
|
10
|
+
*/
|
|
11
|
+
export declare function schemaProvider<S extends AnySchema>(): AffordanceProvider<S>;
|
|
12
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/providers/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6D,KAAK,SAAS,EAAc,MAAM,eAAe,CAAC;AACtH,OAAO,KAAK,EAAc,kBAAkB,EAA8B,MAAM,aAAa,CAAC;AAI9F;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,KAAK,kBAAkB,CAAC,CAAC,CAAC,CAye3E"}
|