@spendgraph/workflows 0.3.2 → 0.4.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/README.md +9 -3
- package/SIGNALS.md +104 -0
- package/dist/noesis/execute/spend.d.ts +5 -1
- package/dist/noesis/execute/spend.js +26 -11
- package/dist/noesis/index.d.ts +1 -1
- package/dist/noesis/route.d.ts +3 -4
- package/dist/noesis/route.js +1 -9
- package/dist/noesis/run/run.js +1 -2
- package/dist/noesis/run/stages/index.d.ts +0 -1
- package/dist/noesis/run/stages/index.js +0 -1
- package/dist/noesis/types.d.ts +1 -13
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ result.route; // which of the four it earned
|
|
|
24
24
|
purpose: the prompt client pulls the stored wording and records what the call
|
|
25
25
|
cost, and the model client makes it.
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## Three routes, chosen in code
|
|
28
28
|
|
|
29
29
|
Stage 0 is a router prompt that returns five signals — difficulty, stakes,
|
|
30
30
|
confidence, ambiguity, tool need — and never a route. `routeFor` in
|
|
@@ -34,7 +34,6 @@ an eval run without touching a prompt.
|
|
|
34
34
|
| route | what it runs | when |
|
|
35
35
|
| --- | --- | --- |
|
|
36
36
|
| `direct` | 6C alone | easy, unambiguous, already known |
|
|
37
|
-
| `retrieve` | one tool call, then 6C | easy and unambiguous, but the answer is elsewhere |
|
|
38
37
|
| `standard` | frame, split, plan, execute, check, close | everything in between |
|
|
39
38
|
| `full` | standard plus four audits | high stakes, expert difficulty, or real ambiguity |
|
|
40
39
|
|
|
@@ -115,6 +114,7 @@ result.usage.inputTokens; // the model side
|
|
|
115
114
|
result.usage.byModel["claude-sonnet-4-6"];
|
|
116
115
|
|
|
117
116
|
result.usage.tools.calls; // the tool side
|
|
117
|
+
result.usage.tools.failed; // and what did not come back
|
|
118
118
|
result.usage.tools.costMicros; // where a tool priced itself
|
|
119
119
|
result.usage.tools.byTool.web_search; // tokens, keyed by the tool that ran
|
|
120
120
|
```
|
|
@@ -123,6 +123,12 @@ Bill both or you undercharge every run that touched the web: `web_search`
|
|
|
123
123
|
reports Perplexity's four token counts and `deep_recall` reports micro-USD,
|
|
124
124
|
and stage 4 records zero tokens of its own.
|
|
125
125
|
|
|
126
|
+
## The signals
|
|
127
|
+
|
|
128
|
+
Stage 0 estimates five numbers and never a route; [SIGNALS.md](./SIGNALS.md) is the
|
|
129
|
+
prompt block that produces them, kept here because the authoritative copy is a
|
|
130
|
+
versioned prompt on the server that nothing in this repository can gate.
|
|
131
|
+
|
|
126
132
|
## The ledger
|
|
127
133
|
|
|
128
134
|
Every stage files its result, its rollouts and its tokens in one place. That
|
|
@@ -200,7 +206,7 @@ exercised against the server:
|
|
|
200
206
|
produced its evidence.
|
|
201
207
|
|
|
202
208
|
`examples/` runs each route against the real prompts for a few pennies. Start
|
|
203
|
-
with `
|
|
209
|
+
with `05-standard.mjs`: it is the cheapest that looks anything up, and it exercises triage, the
|
|
204
210
|
dispatcher, the ledger and 6C. The routes that look something up need one of
|
|
205
211
|
the two lookups configured — `LOCUSGRAPH_AGENT_SECRET` for `deep_recall`, or
|
|
206
212
|
`PERPLEXITY_API_KEY` for `web_search` — and say so rather than half-running.
|
package/SIGNALS.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# SIGNALS
|
|
2
|
+
|
|
3
|
+
Stage 0 estimates five numbers about a request. `routeFor` turns them into a
|
|
4
|
+
route. This file is the copy of that prompt block that lives in the repository —
|
|
5
|
+
the authoritative one is a stored, versioned prompt on the spendgraph server
|
|
6
|
+
(`triage-router-v1-81c2cc`), which nothing here can gate. A revision promoted
|
|
7
|
+
there takes effect on every consumer without a deploy, so a change made and not
|
|
8
|
+
recorded here is a change nobody can find later.
|
|
9
|
+
|
|
10
|
+
## What each signal is for
|
|
11
|
+
|
|
12
|
+
| signal | what it measures | who reads it |
|
|
13
|
+
| --- | --- | --- |
|
|
14
|
+
| `difficulty` | how hard the task is for a strong model | `routeFor` — hard and unsure buys `full` |
|
|
15
|
+
| `stakes` | blast radius if the answer is wrong | `routeFor` — high or critical buys `full` and the red team |
|
|
16
|
+
| `confidence` | whether the model already knows the answer | `routeFor` — under 0.7 leaves `direct` |
|
|
17
|
+
| `ambiguity` | how underspecified the **wording** is | `routeFor` — 0.6 and over buys `full` |
|
|
18
|
+
| `tool_need` | whether an external tool is required | `routeFor` — 0.3 and over leaves `direct` |
|
|
19
|
+
|
|
20
|
+
The prompt is told it does not choose the route, and it never sees the tool bus.
|
|
21
|
+
`tool_need` says a tool is wanted and never which one: stage 2 decides that, per
|
|
22
|
+
sub-question, and stage 4 dispatches what it named.
|
|
23
|
+
|
|
24
|
+
## The block, as promoted
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Estimate the following five signals for the request. Judge each independently.
|
|
28
|
+
|
|
29
|
+
1. difficulty — how hard the task is for a strong LLM with standard tools. Choose ONE: trivial | easy | medium | hard | expert | research
|
|
30
|
+
|
|
31
|
+
2. stakes — blast radius if the answer is wrong: how costly the error is and how reversible. Judge by consequence, not by topic (the same arithmetic is low stakes in homework, critical inside a medication dose). Choose ONE:
|
|
32
|
+
- low: an error is easily noticed and costless to redo
|
|
33
|
+
- medium: an error wastes real time or money but is recoverable
|
|
34
|
+
- high: an error causes significant harm, cost, or exposure (legal, medical, security, production infrastructure)
|
|
35
|
+
- critical: an error is irreversible or endangers safety, funds, or a live incident
|
|
36
|
+
|
|
37
|
+
3. confidence — probability from 0.00 to 1.00 that you already know enough to answer correctly without external information or extended reasoning. This is a calibrated estimate and will be scored against outcomes; do not inflate it.
|
|
38
|
+
|
|
39
|
+
4. ambiguity — how underspecified the request is, from 0.00 to 1.00. Anchors: 0.00 = fully specified; 0.10 = minor wording issues only; 0.30 = one material unknown; 0.60 = a key referent cannot be resolved (location, entity, requirement); 0.90 = the intent itself is unclear.
|
|
40
|
+
|
|
41
|
+
This signal measures the WORDING, never your access to the answer. Two consequences, and both affect ambiguity alone — judge confidence and tool_need exactly as you otherwise would:
|
|
42
|
+
|
|
43
|
+
- A request is not ambiguous because you lack the data to answer it. If the wording is clear and the missing piece is information you would look up — the user's own notes, a repository, a live price — score 0.10 or below and let tool_need carry the gap. "What is my current workout split?" is fully specified.
|
|
44
|
+
- A request about your own capabilities or about this conversation is fully specified even though it names no external task; score 0.10 or below. This does not extend to content the user has stored: what is in their knowledge base is a lookup like any other.
|
|
45
|
+
|
|
46
|
+
5. tool_need — probability from 0.00 to 1.00 that external tools (search, retrieval, code execution, APIs, live data) are required for a correct answer.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Why item 4 says all that
|
|
50
|
+
|
|
51
|
+
Both clauses are there because a live run cost real money without them.
|
|
52
|
+
|
|
53
|
+
**"What can you do for me?"** scored 0.90 ambiguity and took `full`: sixteen
|
|
54
|
+
stages and 96k tokens to describe the assistant. The anchors read "names no
|
|
55
|
+
task" as "intent unclear", and nothing distinguished the two.
|
|
56
|
+
|
|
57
|
+
The first fix said a request about *"you, this assistant, or the conversation"*
|
|
58
|
+
is fully specified. That was too wide. **"What is inside my knowledge base?"**
|
|
59
|
+
then scored `tool_need: 0` and took `direct` — the model reported it already
|
|
60
|
+
knew what the user had stored, and answered from nothing. Worse than expensive:
|
|
61
|
+
wrong.
|
|
62
|
+
|
|
63
|
+
**"What is my current workout split?"** scored 1.00 ambiguity and took `full`.
|
|
64
|
+
The model could not resolve *which* split, so it called the question unclear —
|
|
65
|
+
but the question is perfectly clear and the gap is data. That is `tool_need`,
|
|
66
|
+
which it scored 0.90 at the same time. Every question about the user's own
|
|
67
|
+
stored knowledge — the whole point of a knowledge-base product — was buying the
|
|
68
|
+
most expensive route.
|
|
69
|
+
|
|
70
|
+
Hence the framing the block now leads with: ambiguity is about the **wording**,
|
|
71
|
+
and the two clauses say so explicitly rather than by example alone.
|
|
72
|
+
|
|
73
|
+
## What it does not fix
|
|
74
|
+
|
|
75
|
+
**"Which version of vitest is this repo pinned to?"** still scores ~0.70 and
|
|
76
|
+
takes `full`. The model reads "this repo" as a referent it cannot resolve, which
|
|
77
|
+
is fair when the question arrives with no session context. Inside a real chat it
|
|
78
|
+
has that context. Tuning the wording until this one passes standalone would fit
|
|
79
|
+
the prompt to a test rig rather than to the product.
|
|
80
|
+
|
|
81
|
+
## Testing a revision
|
|
82
|
+
|
|
83
|
+
`evals/dataset/routing.json` gates `routeFor`, not this prompt — every row
|
|
84
|
+
supplies hand-labelled estimates, so a prompt change passes it unchanged. The
|
|
85
|
+
only way to check a revision is to run it:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
node examples/triage/01-triage.mjs # QUESTION=… for your own
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The five that matter, and what they should produce:
|
|
92
|
+
|
|
93
|
+
| question | expected |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| What can you do for me? | ambiguity ≤ 0.10 → `direct` |
|
|
96
|
+
| What is inside my knowledge base? | tool_need high → `standard` |
|
|
97
|
+
| What is my current workout split? | ambiguity ≤ 0.10, tool_need high → `standard` |
|
|
98
|
+
| Make our agent better. | ambiguity ~0.85 → `full` |
|
|
99
|
+
| Should we migrate every production workload onto one provider? | `full` |
|
|
100
|
+
|
|
101
|
+
The fourth is the control. It also names no task, and it must keep taking `full`
|
|
102
|
+
— it names a task and withholds the success criterion, which is what 3B and 3C
|
|
103
|
+
exist for. A revision that makes chit-chat cheap by making that one cheap too
|
|
104
|
+
has broken the thing the long route is for.
|
|
@@ -4,12 +4,16 @@ import type { SubQuestionTool } from "../producers/decompose/index.js";
|
|
|
4
4
|
export interface ToolSpend {
|
|
5
5
|
/** Tool calls that ran, whether or not the tool priced itself. */
|
|
6
6
|
calls: number;
|
|
7
|
+
/** Calls that failed or were skipped. Counted, because a summary that
|
|
8
|
+
* reported only what worked would read as a healthy run. */
|
|
9
|
+
failed: number;
|
|
7
10
|
/** Summed where a tool priced itself. Undefined where none did. */
|
|
8
11
|
costMicros?: number;
|
|
9
12
|
byTool: Record<string, ToolUsage>;
|
|
10
13
|
}
|
|
11
14
|
export interface ToolUsage {
|
|
12
15
|
calls: number;
|
|
16
|
+
failed: number;
|
|
13
17
|
model?: string;
|
|
14
18
|
inputTokens: number;
|
|
15
19
|
outputTokens: number;
|
|
@@ -25,7 +29,7 @@ export declare const NO_TOOL_SPEND: ToolSpend;
|
|
|
25
29
|
* reports Perplexity's four token counts, `deep_recall` reports micro-USD. Both
|
|
26
30
|
* are read where present and nothing is invented where absent.
|
|
27
31
|
*/
|
|
28
|
-
export declare function readToolUsage(result: unknown): Omit<ToolUsage, "calls"> | null;
|
|
32
|
+
export declare function readToolUsage(result: unknown): Omit<ToolUsage, "calls" | "failed"> | null;
|
|
29
33
|
/**
|
|
30
34
|
* Every tool call in one execution, summed under the tool that actually ran.
|
|
31
35
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const NO_TOOL_SPEND = { calls: 0, byTool: {} };
|
|
1
|
+
export const NO_TOOL_SPEND = { calls: 0, failed: 0, byTool: {} };
|
|
2
2
|
const numberAt = (source, field) => {
|
|
3
3
|
const value = source[field];
|
|
4
4
|
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
@@ -24,23 +24,32 @@ export function readToolUsage(result) {
|
|
|
24
24
|
export function toolSpendOf(answers, wiring = {}) {
|
|
25
25
|
const byTool = {};
|
|
26
26
|
let calls = 0;
|
|
27
|
+
let failed = 0;
|
|
27
28
|
let costMicros;
|
|
29
|
+
const blank = () => ({
|
|
30
|
+
calls: 0,
|
|
31
|
+
failed: 0,
|
|
32
|
+
inputTokens: 0,
|
|
33
|
+
outputTokens: 0,
|
|
34
|
+
citationTokens: 0,
|
|
35
|
+
reasoningTokens: 0,
|
|
36
|
+
});
|
|
28
37
|
for (const answer of answers) {
|
|
38
|
+
const named = wiring[answer.tool]?.name ?? answer.tool;
|
|
29
39
|
if (answer.status === "answered")
|
|
30
40
|
calls++;
|
|
41
|
+
else {
|
|
42
|
+
failed++;
|
|
43
|
+
byTool[named] = { ...(byTool[named] ?? blank()), failed: (byTool[named]?.failed ?? 0) + 1 };
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
31
46
|
const one = readToolUsage(answer.result);
|
|
32
47
|
if (!one)
|
|
33
48
|
continue;
|
|
34
|
-
const
|
|
35
|
-
const prior = byTool[named] ?? {
|
|
36
|
-
calls: 0,
|
|
37
|
-
inputTokens: 0,
|
|
38
|
-
outputTokens: 0,
|
|
39
|
-
citationTokens: 0,
|
|
40
|
-
reasoningTokens: 0,
|
|
41
|
-
};
|
|
49
|
+
const prior = byTool[named] ?? blank();
|
|
42
50
|
const merged = {
|
|
43
51
|
calls: prior.calls + 1,
|
|
52
|
+
failed: prior.failed,
|
|
44
53
|
inputTokens: prior.inputTokens + one.inputTokens,
|
|
45
54
|
outputTokens: prior.outputTokens + one.outputTokens,
|
|
46
55
|
citationTokens: prior.citationTokens + one.citationTokens,
|
|
@@ -53,7 +62,7 @@ export function toolSpendOf(answers, wiring = {}) {
|
|
|
53
62
|
}
|
|
54
63
|
byTool[named] = merged;
|
|
55
64
|
}
|
|
56
|
-
return { calls, byTool, ...(costMicros !== undefined ? { costMicros } : {}) };
|
|
65
|
+
return { calls, failed, byTool, ...(costMicros !== undefined ? { costMicros } : {}) };
|
|
57
66
|
}
|
|
58
67
|
export function addToolSpend(a, b) {
|
|
59
68
|
const byTool = { ...a.byTool };
|
|
@@ -62,6 +71,7 @@ export function addToolSpend(a, b) {
|
|
|
62
71
|
byTool[tool] = prior
|
|
63
72
|
? {
|
|
64
73
|
calls: prior.calls + one.calls,
|
|
74
|
+
failed: prior.failed + one.failed,
|
|
65
75
|
inputTokens: prior.inputTokens + one.inputTokens,
|
|
66
76
|
outputTokens: prior.outputTokens + one.outputTokens,
|
|
67
77
|
citationTokens: prior.citationTokens + one.citationTokens,
|
|
@@ -76,7 +86,12 @@ export function addToolSpend(a, b) {
|
|
|
76
86
|
const costMicros = a.costMicros !== undefined || b.costMicros !== undefined
|
|
77
87
|
? (a.costMicros ?? 0) + (b.costMicros ?? 0)
|
|
78
88
|
: undefined;
|
|
79
|
-
return {
|
|
89
|
+
return {
|
|
90
|
+
calls: a.calls + b.calls,
|
|
91
|
+
failed: a.failed + b.failed,
|
|
92
|
+
byTool,
|
|
93
|
+
...(costMicros !== undefined ? { costMicros } : {}),
|
|
94
|
+
};
|
|
80
95
|
}
|
|
81
96
|
export function recorded(execution) {
|
|
82
97
|
return {
|
package/dist/noesis/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export { dropPoint, parseStage, resumeAt } from "./run/redo.js";
|
|
|
45
45
|
export { STAGE_OF_SLUG } from "./slugs.js";
|
|
46
46
|
export type { StageOptions, StageOutcome } from "./stage.js";
|
|
47
47
|
export { runStage, StageReplyError } from "./stage.js";
|
|
48
|
-
export type { Ask, AskedOfYou, NoesisOptions, NoesisResult,
|
|
48
|
+
export type { Ask, AskedOfYou, NoesisOptions, NoesisResult, Route, Routing, RunUsage, Status, VerifyOptions, } from "./types.js";
|
|
49
49
|
export type { PartialUsage, Usage } from "./usage.js";
|
|
50
50
|
export { addUsage, billableTokens, NO_USAGE, spend, usageOf } from "./usage.js";
|
|
51
51
|
export type { Checked, Verification } from "./verify/index.js";
|
package/dist/noesis/route.d.ts
CHANGED
|
@@ -21,9 +21,8 @@ import type { Routing, TriageEstimates } from "./index.js";
|
|
|
21
21
|
* exist for, and it takes `full` below the ambiguity bar that would catch it on
|
|
22
22
|
* its own.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* cheaper than planning it, and likelier to be right.
|
|
24
|
+
* A clear question that still needs a tool takes `standard`: stage 2 is the only
|
|
25
|
+
* stage that decides which tool a sub-question wants, and a route that skipped
|
|
26
|
+
* it had to guess. Guessing sent every world-fact lookup at the knowledge base.
|
|
28
27
|
*/
|
|
29
28
|
export declare function routeFor(estimates: TriageEstimates): Routing;
|
package/dist/noesis/route.js
CHANGED
|
@@ -4,17 +4,12 @@ const CONFIDENT = 0.7;
|
|
|
4
4
|
const NEEDS_TOOLS = 0.3;
|
|
5
5
|
const VAGUE = 0.5;
|
|
6
6
|
const UNSURE = 0.5;
|
|
7
|
-
const NEARLY = 0.6;
|
|
8
7
|
const HARD = new Set(["expert", "research"]);
|
|
9
8
|
const EASY = new Set(["trivial", "easy"]);
|
|
10
9
|
const SERIOUS = new Set(["high", "critical"]);
|
|
11
10
|
export function routeFor(estimates) {
|
|
12
11
|
const redTeam = SERIOUS.has(estimates.stakes);
|
|
13
12
|
const clear = EASY.has(estimates.difficulty) && estimates.ambiguity < CLEAR;
|
|
14
|
-
const lookup = clear && estimates.tool_need >= NEEDS_TOOLS;
|
|
15
|
-
if (lookup && estimates.stakes !== "critical") {
|
|
16
|
-
return { route: "retrieve", redTeam, reason: `a lookup — tool_need is ${estimates.tool_need}` };
|
|
17
|
-
}
|
|
18
13
|
if (redTeam) {
|
|
19
14
|
return { route: "full", redTeam, reason: `stakes are ${estimates.stakes}` };
|
|
20
15
|
}
|
|
@@ -32,11 +27,8 @@ export function routeFor(estimates) {
|
|
|
32
27
|
reason: `ambiguity ${estimates.ambiguity} with confidence ${estimates.confidence}`,
|
|
33
28
|
};
|
|
34
29
|
}
|
|
35
|
-
if (clear && estimates.confidence >= CONFIDENT) {
|
|
30
|
+
if (clear && estimates.confidence >= CONFIDENT && estimates.tool_need < NEEDS_TOOLS) {
|
|
36
31
|
return { route: "direct", redTeam, reason: `${estimates.difficulty} and already known` };
|
|
37
32
|
}
|
|
38
|
-
if (clear && estimates.confidence >= NEARLY) {
|
|
39
|
-
return { route: "retrieve", redTeam, reason: `${estimates.difficulty} but not certain` };
|
|
40
|
-
}
|
|
41
33
|
return { route: "standard", redTeam, reason: "neither trivial nor serious" };
|
|
42
34
|
}
|
package/dist/noesis/run/run.js
CHANGED
|
@@ -2,7 +2,7 @@ import { route } from "@spendgraph/harness";
|
|
|
2
2
|
import { emitter } from "../events.js";
|
|
3
3
|
import { notBuilt } from "./errors.js";
|
|
4
4
|
import { finish } from "./result.js";
|
|
5
|
-
import { classifyStage, directStage, fullStage,
|
|
5
|
+
import { classifyStage, directStage, fullStage, standardStage, } from "./stages/index.js";
|
|
6
6
|
import { newRunState } from "./state.js";
|
|
7
7
|
const DEFAULT_MAX_RETRIES = 5;
|
|
8
8
|
const watched = (opts, emit) => ({
|
|
@@ -32,7 +32,6 @@ export async function run(client, llm, question, options = {}) {
|
|
|
32
32
|
classify: classifyStage(client, llm, question, opts, state),
|
|
33
33
|
routes: {
|
|
34
34
|
direct: directStage(client, llm, question, opts, state),
|
|
35
|
-
retrieve: retrieveStage(client, llm, question, opts, state),
|
|
36
35
|
standard: standardStage(client, llm, question, opts, state),
|
|
37
36
|
full: fullStage(client, llm, question, opts, state),
|
|
38
37
|
},
|
package/dist/noesis/types.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { ToolBus } from "@spendgraph/tools";
|
|
|
2
2
|
import type { ToolSpend } from "./execute/spend.js";
|
|
3
3
|
import type { Asked } from "./context.js";
|
|
4
4
|
import type { NoesisEvent } from "./events.js";
|
|
5
|
-
import type { SubQuestionTool } from "./producers/decompose/index.js";
|
|
6
5
|
import type { AnswerOptions, AnswerResult } from "./producers/toulmin/index.js";
|
|
7
6
|
import type { TriageEstimates, TriageInput, TriageOptions } from "./router/triage/index.js";
|
|
8
7
|
import type { Escalation, StageKey, StageUsage } from "./run/ledger.js";
|
|
@@ -14,7 +13,7 @@ import type { Usage } from "./usage.js";
|
|
|
14
13
|
* Derived in code from the triage estimates, which is what the router prompt
|
|
15
14
|
* itself says: it returns signals and never a route.
|
|
16
15
|
*/
|
|
17
|
-
export type Route = "direct" | "
|
|
16
|
+
export type Route = "direct" | "standard" | "full";
|
|
18
17
|
/** What the estimates decide, before any of it is acted on. */
|
|
19
18
|
export interface Routing {
|
|
20
19
|
route: Route;
|
|
@@ -39,16 +38,6 @@ export interface AskedOfYou {
|
|
|
39
38
|
/** Why it says so. */
|
|
40
39
|
reason: string;
|
|
41
40
|
}
|
|
42
|
-
export interface RetrieveOptions {
|
|
43
|
-
/**
|
|
44
|
-
* What a lookup reaches for. Default `"deeprecall"`.
|
|
45
|
-
*
|
|
46
|
-
* Triage says how much a question needs a tool and never which one, so the
|
|
47
|
-
* route picks. The enum is ordered cheapest first and the knowledge base
|
|
48
|
-
* comes before the open web, which is the same preference.
|
|
49
|
-
*/
|
|
50
|
-
tool?: SubQuestionTool;
|
|
51
|
-
}
|
|
52
41
|
export interface VerifyOptions {
|
|
53
42
|
/**
|
|
54
43
|
* The confidence a blind check has to reach before it settles a claim.
|
|
@@ -108,7 +97,6 @@ export interface NoesisOptions {
|
|
|
108
97
|
* person. Default 5, counted across every gate together.
|
|
109
98
|
*/
|
|
110
99
|
maxRetries?: number;
|
|
111
|
-
retrieve?: RetrieveOptions;
|
|
112
100
|
/** How the blind checks in stage 5 are read. */
|
|
113
101
|
verify?: VerifyOptions;
|
|
114
102
|
answer?: AnswerOptions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spendgraph/workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Ready-made workflows assembled from the spendgraph packages.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,13 +30,14 @@
|
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"dist",
|
|
33
|
+
"SIGNALS.md",
|
|
33
34
|
"README.md"
|
|
34
35
|
],
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@spendgraph/harness": "^0.
|
|
37
|
-
"@spendgraph/llms": "^0.
|
|
38
|
-
"@spendgraph/prompt": "^0.
|
|
39
|
-
"@spendgraph/tools": "^0.
|
|
37
|
+
"@spendgraph/harness": "^0.4.0",
|
|
38
|
+
"@spendgraph/llms": "^0.4.0",
|
|
39
|
+
"@spendgraph/prompt": "^0.4.0",
|
|
40
|
+
"@spendgraph/tools": "^0.4.0"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
43
|
"build": "tsc -p tsconfig.json --emitDeclarationOnly && tsc -p tsconfig.json --declaration false --removeComments",
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@locusgraph/client": "^0.8.1",
|
|
50
|
-
"@spendgraph/evals": "^0.
|
|
51
|
+
"@spendgraph/evals": "^0.4.0",
|
|
51
52
|
"typescript": "^5"
|
|
52
53
|
},
|
|
53
54
|
"engines": {
|