@wrenautomation/raven 0.10.0 → 0.12.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 +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/plans/index.d.ts +9 -2
- package/dist/plans/index.js +31 -7
- package/dist/types.d.ts +59 -2
- package/dist/types.js +30 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,7 +15,9 @@ Three calls, one record each:
|
|
|
15
15
|
| `review` | what a round came to (counts, found lines with their dates, the extractor's verdict and gap per read, the steps' gaps, the sample check, notes) | the edge: `stop`, `again` (a new round from plan) or `back` (rerun one step), with why. The budget is shown, never enforced here: the runner parks past it |
|
|
16
16
|
|
|
17
17
|
Ask kinds: `web`, `video`, `channel`, `person`, `site`. Each has a default plan file
|
|
18
|
-
(prompts, sources, budget,
|
|
18
|
+
(prompts, sources, budget, `age`: one sentence on how much a source's age counts, and `tree`: the
|
|
19
|
+
facets a round's query tree covers and `thin`, the new hits under which a try falls through to the
|
|
20
|
+
next). Copy one,
|
|
19
21
|
tune it, keep it beside your ledger (`weaver learn`): that is where a run learns. Raven never
|
|
20
22
|
loops; the runner takes the edge.
|
|
21
23
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { fill } from "./model.js";
|
|
2
2
|
export { mergeProposals, type PlanInput, plan, propose, proposePrompt } from "./plan.js";
|
|
3
|
-
export { defaultPlanFile, PLAN_KINDS } from "./plans/index.js";
|
|
3
|
+
export { ageOf, defaultPlanFile, PLAN_KINDS, TREE, treeOf } from "./plans/index.js";
|
|
4
4
|
export { renderHits, renderYield } from "./render.js";
|
|
5
5
|
export { review, reviewPrompt } from "./review.js";
|
|
6
6
|
export { dedupeHits, triage, triagePrompt } from "./triage.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { fill } from "./model.js";
|
|
2
2
|
export { mergeProposals, plan, propose, proposePrompt } from "./plan.js";
|
|
3
|
-
export { defaultPlanFile, PLAN_KINDS } from "./plans/index.js";
|
|
3
|
+
export { ageOf, defaultPlanFile, PLAN_KINDS, TREE, treeOf } from "./plans/index.js";
|
|
4
4
|
export { renderHits, renderYield } from "./render.js";
|
|
5
5
|
export { review, reviewPrompt } from "./review.js";
|
|
6
6
|
export { dedupeHits, triage, triagePrompt } from "./triage.js";
|
package/dist/plans/index.d.ts
CHANGED
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
* The default plan file per ask kind. A copy of one, tuned and stored beside a ledger, is how
|
|
3
3
|
* a run learns: the recipe changes, raven does not. `raven plans <kind>` prints one to start from.
|
|
4
4
|
*/
|
|
5
|
-
import { type AskKind, type PlanFile } from "../types.js";
|
|
5
|
+
import { type AskKind, type PlanFile, type TreeGuide } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* The five sides a researcher covers before the reads start. One tree per round; the agent
|
|
8
|
+
* fills each facet with tries, in order of what it expects to work.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TREE: TreeGuide;
|
|
6
11
|
/** The default plan file for a kind, validated, as a fresh copy. */
|
|
7
12
|
export declare function defaultPlanFile(kind: AskKind): PlanFile;
|
|
8
|
-
/** The plan file's word on age; a stored file from before version 4 takes its kind's default. Version 5: the review no longer says "at most". */
|
|
13
|
+
/** The plan file's word on age; a stored file from before version 4 takes its kind's default. Version 5: the review no longer says "at most". Version 6: `tree`, the query tree's guide. */
|
|
9
14
|
export declare const ageOf: (planFile: PlanFile) => string | undefined;
|
|
15
|
+
/** The plan file's guide for a query tree; a stored file from before version 6 takes its kind's default. */
|
|
16
|
+
export declare const treeOf: (planFile: PlanFile) => TreeGuide;
|
|
10
17
|
export declare const PLAN_KINDS: AskKind[];
|
package/dist/plans/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* The default plan file per ask kind. A copy of one, tuned and stored beside a ledger, is how
|
|
3
3
|
* a run learns: the recipe changes, raven does not. `raven plans <kind>` prints one to start from.
|
|
4
4
|
*/
|
|
5
|
-
import { PlanFile as PlanFileShape } from "../types.js";
|
|
5
|
+
import { PlanFile as PlanFileShape, } from "../types.js";
|
|
6
6
|
const SHAPE_QUERIES = `Return ONLY a JSON object, no prose, exactly this shape:
|
|
7
7
|
{"queries": [{"terms": "...", "why": "..."}]}`;
|
|
8
8
|
const SHAPE_HITS = `Return ONLY a JSON object, no prose, exactly this shape:
|
|
@@ -44,10 +44,27 @@ Checked (a sample of the kept findings, each against its document):
|
|
|
44
44
|
{checks}
|
|
45
45
|
Notes:
|
|
46
46
|
{notes}`;
|
|
47
|
+
/**
|
|
48
|
+
* The five sides a researcher covers before the reads start. One tree per round; the agent
|
|
49
|
+
* fills each facet with tries, in order of what it expects to work.
|
|
50
|
+
*/
|
|
51
|
+
export const TREE = {
|
|
52
|
+
facets: [
|
|
53
|
+
{ name: "number", why: "a figure: a rate, a price, a count, a date" },
|
|
54
|
+
{ name: "how", why: "how it is done: a method, a step list, a tool" },
|
|
55
|
+
{ name: "who", why: "who does it or buys it, in their own words" },
|
|
56
|
+
{ name: "counter", why: "the case against: what fails, who says no" },
|
|
57
|
+
{
|
|
58
|
+
name: "primary",
|
|
59
|
+
why: "the source itself: a study, a filing, a transcript, the maker's own page",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
thin: 3,
|
|
63
|
+
};
|
|
47
64
|
const web = {
|
|
48
65
|
id: "raven/web",
|
|
49
66
|
kind: "web",
|
|
50
|
-
version:
|
|
67
|
+
version: 6,
|
|
51
68
|
propose: `You plan web searches for one research ask.
|
|
52
69
|
|
|
53
70
|
${SHAPE_QUERIES}
|
|
@@ -74,12 +91,13 @@ Hits:
|
|
|
74
91
|
review: REVIEW,
|
|
75
92
|
sources: ["searxng", "exa", "google"],
|
|
76
93
|
budget: { queries: 3, reads: 6, rounds: 3, checks: 3 },
|
|
94
|
+
tree: TREE,
|
|
77
95
|
age: "Prices, tools and numbers that move: prefer the last two years. A principle or a method can be old.",
|
|
78
96
|
};
|
|
79
97
|
const video = {
|
|
80
98
|
id: "raven/video",
|
|
81
99
|
kind: "video",
|
|
82
|
-
version:
|
|
100
|
+
version: 6,
|
|
83
101
|
propose: `You plan video searches for one research ask: talks, walkthroughs, interviews and reviews on YouTube and podcast feeds.
|
|
84
102
|
|
|
85
103
|
${SHAPE_QUERIES}
|
|
@@ -106,12 +124,13 @@ Hits:
|
|
|
106
124
|
review: REVIEW,
|
|
107
125
|
sources: ["youtube", "podcasts"],
|
|
108
126
|
budget: { queries: 3, reads: 4, rounds: 2, checks: 3 },
|
|
127
|
+
tree: TREE,
|
|
109
128
|
age: "Tools and platforms: prefer the last two years. A talk on a principle can be old.",
|
|
110
129
|
};
|
|
111
130
|
const channel = {
|
|
112
131
|
id: "raven/channel",
|
|
113
132
|
kind: "channel",
|
|
114
|
-
version:
|
|
133
|
+
version: 6,
|
|
115
134
|
propose: `You plan searches that find the people and channels worth following for one research ask: creators, newsletters, podcasts, forums.
|
|
116
135
|
|
|
117
136
|
${SHAPE_QUERIES}
|
|
@@ -136,12 +155,13 @@ Hits:
|
|
|
136
155
|
review: REVIEW,
|
|
137
156
|
sources: ["searxng", "youtube", "exa"],
|
|
138
157
|
budget: { queries: 3, reads: 6, rounds: 2, checks: 3 },
|
|
158
|
+
tree: TREE,
|
|
139
159
|
age: "A channel that has not posted in the last year counts for little.",
|
|
140
160
|
};
|
|
141
161
|
const person = {
|
|
142
162
|
id: "raven/person",
|
|
143
163
|
kind: "person",
|
|
144
|
-
version:
|
|
164
|
+
version: 6,
|
|
145
165
|
propose: `You plan searches about one person or company for one research ask: what they do, what they said, what others say about them.
|
|
146
166
|
|
|
147
167
|
${SHAPE_QUERIES}
|
|
@@ -168,12 +188,13 @@ Hits:
|
|
|
168
188
|
review: REVIEW,
|
|
169
189
|
sources: ["searxng", "exa", "linkedin", "google"],
|
|
170
190
|
budget: { queries: 4, reads: 6, rounds: 2, checks: 3 },
|
|
191
|
+
tree: TREE,
|
|
171
192
|
age: "What they do now: prefer the latest pages. Their history can be old.",
|
|
172
193
|
};
|
|
173
194
|
const site = {
|
|
174
195
|
id: "raven/site",
|
|
175
196
|
kind: "site",
|
|
176
|
-
version:
|
|
197
|
+
version: 6,
|
|
177
198
|
propose: `You plan searches inside one website for one research ask. Every query runs on {site} only.
|
|
178
199
|
|
|
179
200
|
${SHAPE_QUERIES}
|
|
@@ -199,6 +220,7 @@ Hits:
|
|
|
199
220
|
review: REVIEW,
|
|
200
221
|
sources: ["sitemap", "searxng", "fetch"],
|
|
201
222
|
budget: { queries: 4, reads: 8, rounds: 2, checks: 3 },
|
|
223
|
+
tree: TREE,
|
|
202
224
|
age: "When two pages of the site disagree, the later one counts.",
|
|
203
225
|
};
|
|
204
226
|
const DEFAULTS = { web, video, channel, person, site };
|
|
@@ -206,7 +228,9 @@ const DEFAULTS = { web, video, channel, person, site };
|
|
|
206
228
|
export function defaultPlanFile(kind) {
|
|
207
229
|
return PlanFileShape.parse(structuredClone(DEFAULTS[kind]));
|
|
208
230
|
}
|
|
209
|
-
/** The plan file's word on age; a stored file from before version 4 takes its kind's default. Version 5: the review no longer says "at most". */
|
|
231
|
+
/** The plan file's word on age; a stored file from before version 4 takes its kind's default. Version 5: the review no longer says "at most". Version 6: `tree`, the query tree's guide. */
|
|
210
232
|
export const ageOf = (planFile) => planFile.age ?? DEFAULTS[planFile.kind].age;
|
|
233
|
+
/** The plan file's guide for a query tree; a stored file from before version 6 takes its kind's default. */
|
|
234
|
+
export const treeOf = (planFile) => planFile.tree ?? DEFAULTS[planFile.kind].tree;
|
|
211
235
|
export const PLAN_KINDS = Object.keys(DEFAULTS);
|
|
212
236
|
//# sourceMappingURL=index.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ export declare const Query: z.ZodObject<{
|
|
|
47
47
|
terms: z.ZodString;
|
|
48
48
|
site: z.ZodOptional<z.ZodString>;
|
|
49
49
|
why: z.ZodString;
|
|
50
|
+
facet: z.ZodOptional<z.ZodString>;
|
|
51
|
+
tier: z.ZodOptional<z.ZodNumber>;
|
|
50
52
|
from: z.ZodEnum<{
|
|
51
53
|
ai: "ai";
|
|
52
54
|
human: "human";
|
|
@@ -72,9 +74,55 @@ export declare const Proposal: z.ZodObject<{
|
|
|
72
74
|
}>;
|
|
73
75
|
terms: z.ZodString;
|
|
74
76
|
why: z.ZodString;
|
|
77
|
+
facet: z.ZodOptional<z.ZodString>;
|
|
78
|
+
tier: z.ZodOptional<z.ZodNumber>;
|
|
75
79
|
}, z.core.$strip>>;
|
|
76
80
|
}, z.core.$strip>;
|
|
77
81
|
export type Proposal = z.infer<typeof Proposal>;
|
|
82
|
+
/** One query as a leaf of the tree: what a person would type, and why. */
|
|
83
|
+
export declare const Leaf: z.ZodObject<{
|
|
84
|
+
terms: z.ZodString;
|
|
85
|
+
why: z.ZodString;
|
|
86
|
+
site: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, z.core.$strip>;
|
|
88
|
+
export type Leaf = z.infer<typeof Leaf>;
|
|
89
|
+
/**
|
|
90
|
+
* One side of the ask a researcher covers: a number, a how, a who, a counter-view, a primary
|
|
91
|
+
* source. `tries` are its alternatives in order: the first runs; the next runs only when the
|
|
92
|
+
* one before it yielded thin (fewer new hits than the guide's `thin`), or when the agent asks.
|
|
93
|
+
*/
|
|
94
|
+
export declare const Facet: z.ZodObject<{
|
|
95
|
+
name: z.ZodString;
|
|
96
|
+
why: z.ZodString;
|
|
97
|
+
tries: z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
98
|
+
terms: z.ZodString;
|
|
99
|
+
why: z.ZodString;
|
|
100
|
+
site: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.core.$strip>>>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
export type Facet = z.infer<typeof Facet>;
|
|
104
|
+
/** The fan-out for one round: the facets, each with its tries. The agent writes it; weaver runs it. */
|
|
105
|
+
export declare const QueryTree: z.ZodObject<{
|
|
106
|
+
facets: z.ZodArray<z.ZodObject<{
|
|
107
|
+
name: z.ZodString;
|
|
108
|
+
why: z.ZodString;
|
|
109
|
+
tries: z.ZodArray<z.ZodArray<z.ZodObject<{
|
|
110
|
+
terms: z.ZodString;
|
|
111
|
+
why: z.ZodString;
|
|
112
|
+
site: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, z.core.$strip>>>;
|
|
114
|
+
}, z.core.$strip>>;
|
|
115
|
+
}, z.core.$strip>;
|
|
116
|
+
export type QueryTree = z.infer<typeof QueryTree>;
|
|
117
|
+
/** The plan file's guide for a tree: the facets a tree of this kind covers, and what thin means. A guide, not a cap: a tree may add facets; one it leaves out is a warning. */
|
|
118
|
+
export declare const TreeGuide: z.ZodObject<{
|
|
119
|
+
facets: z.ZodArray<z.ZodObject<{
|
|
120
|
+
name: z.ZodString;
|
|
121
|
+
why: z.ZodString;
|
|
122
|
+
}, z.core.$strip>>;
|
|
123
|
+
thin: z.ZodNumber;
|
|
124
|
+
}, z.core.$strip>;
|
|
125
|
+
export type TreeGuide = z.infer<typeof TreeGuide>;
|
|
78
126
|
export declare const Budget: z.ZodObject<{
|
|
79
127
|
queries: z.ZodNumber;
|
|
80
128
|
reads: z.ZodNumber;
|
|
@@ -109,6 +157,13 @@ export declare const PlanFile: z.ZodObject<{
|
|
|
109
157
|
checks: z.ZodDefault<z.ZodNumber>;
|
|
110
158
|
}, z.core.$strip>;
|
|
111
159
|
age: z.ZodOptional<z.ZodString>;
|
|
160
|
+
tree: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
facets: z.ZodArray<z.ZodObject<{
|
|
162
|
+
name: z.ZodString;
|
|
163
|
+
why: z.ZodString;
|
|
164
|
+
}, z.core.$strip>>;
|
|
165
|
+
thin: z.ZodNumber;
|
|
166
|
+
}, z.core.$strip>>;
|
|
112
167
|
}, z.core.$strip>;
|
|
113
168
|
export type PlanFile = z.infer<typeof PlanFile>;
|
|
114
169
|
/** What a source, channel or proposer yielded before. Raven reads it; wren or the files ledger writes it. */
|
|
@@ -168,6 +223,8 @@ export declare const Plan: z.ZodObject<{
|
|
|
168
223
|
terms: z.ZodString;
|
|
169
224
|
site: z.ZodOptional<z.ZodString>;
|
|
170
225
|
why: z.ZodString;
|
|
226
|
+
facet: z.ZodOptional<z.ZodString>;
|
|
227
|
+
tier: z.ZodOptional<z.ZodNumber>;
|
|
171
228
|
from: z.ZodEnum<{
|
|
172
229
|
ai: "ai";
|
|
173
230
|
human: "human";
|
|
@@ -221,8 +278,8 @@ export type Triage = z.infer<typeof Triage>;
|
|
|
221
278
|
export declare const Verdict: z.ZodObject<{
|
|
222
279
|
url: z.ZodString;
|
|
223
280
|
quality: z.ZodEnum<{
|
|
224
|
-
rich: "rich";
|
|
225
281
|
thin: "thin";
|
|
282
|
+
rich: "rich";
|
|
226
283
|
off: "off";
|
|
227
284
|
empty: "empty";
|
|
228
285
|
}>;
|
|
@@ -261,8 +318,8 @@ export declare const Round: z.ZodObject<{
|
|
|
261
318
|
verdicts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
262
319
|
url: z.ZodString;
|
|
263
320
|
quality: z.ZodEnum<{
|
|
264
|
-
rich: "rich";
|
|
265
321
|
thin: "thin";
|
|
322
|
+
rich: "rich";
|
|
266
323
|
off: "off";
|
|
267
324
|
empty: "empty";
|
|
268
325
|
}>;
|
package/dist/types.js
CHANGED
|
@@ -28,6 +28,9 @@ export const Query = z.object({
|
|
|
28
28
|
site: z.string().optional(),
|
|
29
29
|
/** Why this query serves the ask: the line a reviewer reads first. */
|
|
30
30
|
why: z.string(),
|
|
31
|
+
/** The tree's facet it serves, and which try (1 = the first). Absent on a flat query. */
|
|
32
|
+
facet: z.string().optional(),
|
|
33
|
+
tier: z.number().int().positive().optional(),
|
|
31
34
|
from: From,
|
|
32
35
|
/** Model id, plan file id or a person's name. */
|
|
33
36
|
by: z.string(),
|
|
@@ -38,6 +41,31 @@ export const Proposal = z.object({
|
|
|
38
41
|
by: z.string(),
|
|
39
42
|
queries: z.array(Query.omit({ from: true, by: true })),
|
|
40
43
|
});
|
|
44
|
+
/** One query as a leaf of the tree: what a person would type, and why. */
|
|
45
|
+
export const Leaf = z.object({
|
|
46
|
+
terms: z.string().min(1),
|
|
47
|
+
why: z.string(),
|
|
48
|
+
site: z.string().optional(),
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* One side of the ask a researcher covers: a number, a how, a who, a counter-view, a primary
|
|
52
|
+
* source. `tries` are its alternatives in order: the first runs; the next runs only when the
|
|
53
|
+
* one before it yielded thin (fewer new hits than the guide's `thin`), or when the agent asks.
|
|
54
|
+
*/
|
|
55
|
+
export const Facet = z.object({
|
|
56
|
+
name: z.string().min(1),
|
|
57
|
+
/** What this facet would prove. */
|
|
58
|
+
why: z.string(),
|
|
59
|
+
tries: z.array(z.array(Leaf).min(1)).min(1),
|
|
60
|
+
});
|
|
61
|
+
/** The fan-out for one round: the facets, each with its tries. The agent writes it; weaver runs it. */
|
|
62
|
+
export const QueryTree = z.object({ facets: z.array(Facet).min(1) });
|
|
63
|
+
/** The plan file's guide for a tree: the facets a tree of this kind covers, and what thin means. A guide, not a cap: a tree may add facets; one it leaves out is a warning. */
|
|
64
|
+
export const TreeGuide = z.object({
|
|
65
|
+
facets: z.array(z.object({ name: z.string().min(1), why: z.string() })),
|
|
66
|
+
/** New hits under which a try counts as thin, so the next try runs. */
|
|
67
|
+
thin: z.number().int().nonnegative(),
|
|
68
|
+
});
|
|
41
69
|
export const Budget = z.object({
|
|
42
70
|
/** Queries per round after the merge. Human queries never count against it. */
|
|
43
71
|
queries: z.number().int().positive(),
|
|
@@ -69,6 +97,8 @@ export const PlanFile = z.object({
|
|
|
69
97
|
budget: Budget,
|
|
70
98
|
/** How much a source's age counts for this kind, one sentence: filled as `{age}`. Never a cutoff. */
|
|
71
99
|
age: z.string().optional(),
|
|
100
|
+
/** The facets a query tree of this kind covers. Absent on a file from before version 6: the kind's default. */
|
|
101
|
+
tree: TreeGuide.optional(),
|
|
72
102
|
});
|
|
73
103
|
/** What a source, channel or proposer yielded before. Raven reads it; wren or the files ledger writes it. */
|
|
74
104
|
export const YieldRow = z.object({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrenautomation/raven",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Ask in, plan out. The planner of Wren's research engine: typed queries with who proposed them and why, proposals merged into one plan under a plan file per ask kind, read-or-skip on hits, and the edge to take after a round. Pure functions and prompts; the model is injected.",
|
|
5
5
|
"license": "PolyForm-Strict-1.0.0",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"commander": "15.0.0",
|
|
34
34
|
"zod": "4.6.5",
|
|
35
|
-
"@wrenautomation/models": "0.
|
|
35
|
+
"@wrenautomation/models": "0.12.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"typecheck": "tsc --noEmit",
|