@wrenautomation/raven 0.7.0 → 0.8.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 +2 -2
- package/dist/app/cli.js +1 -0
- package/dist/plan.js +2 -1
- package/dist/plans/index.d.ts +2 -0
- package/dist/plans/index.js +27 -14
- package/dist/render.d.ts +4 -0
- package/dist/render.js +4 -0
- package/dist/review.js +5 -2
- package/dist/triage.js +4 -2
- package/dist/types.d.ts +12 -1
- package/dist/types.js +12 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,10 +12,10 @@ Three calls, one record each:
|
|
|
12
12
|
|---|---|---|
|
|
13
13
|
| `plan` | an ask (text, kind, what is known, what the person says: `steer`, rendered first in every prompt), proposals from people or other models, yield rows from earlier runs | a `Plan`: typed queries, each with `why`, `from` (ai or human) and `by` (model id, plan file or person), the sources it may use, the budget, and a snapshot of what raven was given |
|
|
14
14
|
| `triage` | hits as a source shows them for free (title, channel, length, date, snippet, which sources returned it) | read or skip per hit; the model writes a why on a read only (a skip's is fixed text); the read budget caps it |
|
|
15
|
-
| `review` | what a round came to (counts, found lines, the extractor's verdict and gap per read, notes) | the edge: `stop`, `again` (a new round from plan) or `back` (rerun one step), with why |
|
|
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 |
|
|
16
16
|
|
|
17
17
|
Ask kinds: `web`, `video`, `channel`, `person`, `site`. Each has a default plan file
|
|
18
|
-
(prompts, sources, budget). Copy one, tune it, keep it beside your ledger: that is where a run
|
|
18
|
+
(prompts, sources, budget, and `age`: one sentence on how much a source's age counts). Copy one, tune it, keep it beside your ledger: that is where a run
|
|
19
19
|
learns. Raven never loops; the runner takes the edge.
|
|
20
20
|
|
|
21
21
|
## CLI
|
package/dist/app/cli.js
CHANGED
package/dist/plan.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fill } from "./model.js";
|
|
2
2
|
import { defaultPlanFile } from "./plans/index.js";
|
|
3
|
-
import { lines, renderSteer, renderYield } from "./render.js";
|
|
3
|
+
import { lines, renderOpen, renderSteer, renderYield } from "./render.js";
|
|
4
4
|
import { z, } from "./types.js";
|
|
5
5
|
const ProposalAnswer = z.object({
|
|
6
6
|
queries: z.array(z.object({ terms: z.string(), why: z.string(), site: z.string().optional() })),
|
|
@@ -12,6 +12,7 @@ export function proposePrompt(ask, planFile, yieldRows, now) {
|
|
|
12
12
|
ask: ask.text,
|
|
13
13
|
site: ask.site ?? "",
|
|
14
14
|
steer: renderSteer(ask.steer),
|
|
15
|
+
open: renderOpen(ask.open),
|
|
15
16
|
known: lines(ask.known),
|
|
16
17
|
yield: renderYield(yieldRows),
|
|
17
18
|
});
|
package/dist/plans/index.d.ts
CHANGED
|
@@ -5,4 +5,6 @@
|
|
|
5
5
|
import { type AskKind, type PlanFile } from "../types.js";
|
|
6
6
|
/** The default plan file for a kind, validated, as a fresh copy. */
|
|
7
7
|
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. */
|
|
9
|
+
export declare const ageOf: (planFile: PlanFile) => string | undefined;
|
|
8
10
|
export declare const PLAN_KINDS: AskKind[];
|
package/dist/plans/index.js
CHANGED
|
@@ -11,14 +11,14 @@ const SHAPE_EDGE = `Return ONLY a JSON object, no prose, exactly this shape:
|
|
|
11
11
|
{"next": "stop", "why": "..."}
|
|
12
12
|
where "next" is "stop", "again" (a new round from plan) or "back" (rerun one step of this round, named in "to": "plan", "fetch", "triage", "read" or "extract").`;
|
|
13
13
|
const CONTEXT = `Ask: {ask}
|
|
14
|
-
{steer}Known already (look past these):
|
|
14
|
+
{steer}{open}Known already (look past these):
|
|
15
15
|
{known}
|
|
16
16
|
What yielded before (hits, reads, proposed, kept):
|
|
17
17
|
{yield}`;
|
|
18
18
|
const TRIAGE_RULES = `- One entry per hit, with its url as given. Mark "read": true for at most {n}.
|
|
19
19
|
- Read a hit when what it shows for free (title, snippet, channel, length, date) says it holds what the ask needs and is not known already.
|
|
20
20
|
- A hit returned by more than one source is a good sign, not a duplicate.
|
|
21
|
-
- "why" on a read only: one short line a person reads to agree or not. A skip has no "why"
|
|
21
|
+
- "why" on a read only: one short line a person reads to agree or not. A skip has no "why".{age}`;
|
|
22
22
|
const REVIEW = `You decide what happens after one round of research.
|
|
23
23
|
|
|
24
24
|
${SHAPE_EDGE}
|
|
@@ -28,20 +28,26 @@ Rules:
|
|
|
28
28
|
- "again" when the ask is still open and new queries could find more. The gaps say what is missing; say what to look for next in "why".
|
|
29
29
|
- "again" too when the reads were mostly "thin" or "off": the queries found the wrong pages, so plan different ones.
|
|
30
30
|
- "back" when one step of this round failed for a reason a rerun fixes (a source was down, reads timed out). Name the step in "to".
|
|
31
|
-
-
|
|
31
|
+
- The gaps are what a step or the person said this round lacks: a query with no new hits, a page no source could open. Weigh them like the verdicts.
|
|
32
|
+
- A check that failed means a finding's quote does not back it, and the finding was dropped. Many failed checks mean the reads were poor: say so in "why".{age}
|
|
33
|
+
- "why" is one short line a person reads to agree or not. On "again" it is what the next plan reads first.
|
|
32
34
|
|
|
33
35
|
Ask: {ask}
|
|
34
36
|
{steer}Round {round} of at most {rounds}. Hits {hits}, reads {reads}, findings proposed {proposed}, kept {kept}.
|
|
35
|
-
Found:
|
|
37
|
+
Found (the source's date in brackets when it gives one):
|
|
36
38
|
{found}
|
|
37
39
|
Read (quality: rich, thin, off or empty; then the gap, what the ask still lacks):
|
|
38
40
|
{verdicts}
|
|
41
|
+
Gaps (the step or the person, then what is missing):
|
|
42
|
+
{gaps}
|
|
43
|
+
Checked (a sample of the kept findings, each against its document):
|
|
44
|
+
{checks}
|
|
39
45
|
Notes:
|
|
40
46
|
{notes}`;
|
|
41
47
|
const web = {
|
|
42
48
|
id: "raven/web",
|
|
43
49
|
kind: "web",
|
|
44
|
-
version:
|
|
50
|
+
version: 4,
|
|
45
51
|
propose: `You plan web searches for one research ask.
|
|
46
52
|
|
|
47
53
|
${SHAPE_QUERIES}
|
|
@@ -67,12 +73,13 @@ Hits:
|
|
|
67
73
|
{hits}`,
|
|
68
74
|
review: REVIEW,
|
|
69
75
|
sources: ["searxng", "exa", "google"],
|
|
70
|
-
budget: { queries: 3, reads: 6, rounds: 3 },
|
|
76
|
+
budget: { queries: 3, reads: 6, rounds: 3, checks: 3 },
|
|
77
|
+
age: "Prices, tools and numbers that move: prefer the last two years. A principle or a method can be old.",
|
|
71
78
|
};
|
|
72
79
|
const video = {
|
|
73
80
|
id: "raven/video",
|
|
74
81
|
kind: "video",
|
|
75
|
-
version:
|
|
82
|
+
version: 4,
|
|
76
83
|
propose: `You plan video searches for one research ask: talks, walkthroughs, interviews and reviews on YouTube and podcast feeds.
|
|
77
84
|
|
|
78
85
|
${SHAPE_QUERIES}
|
|
@@ -98,12 +105,13 @@ Hits:
|
|
|
98
105
|
{hits}`,
|
|
99
106
|
review: REVIEW,
|
|
100
107
|
sources: ["youtube", "podcasts"],
|
|
101
|
-
budget: { queries: 3, reads: 4, rounds: 2 },
|
|
108
|
+
budget: { queries: 3, reads: 4, rounds: 2, checks: 3 },
|
|
109
|
+
age: "Tools and platforms: prefer the last two years. A talk on a principle can be old.",
|
|
102
110
|
};
|
|
103
111
|
const channel = {
|
|
104
112
|
id: "raven/channel",
|
|
105
113
|
kind: "channel",
|
|
106
|
-
version:
|
|
114
|
+
version: 4,
|
|
107
115
|
propose: `You plan searches that find the people and channels worth following for one research ask: creators, newsletters, podcasts, forums.
|
|
108
116
|
|
|
109
117
|
${SHAPE_QUERIES}
|
|
@@ -127,12 +135,13 @@ Hits:
|
|
|
127
135
|
{hits}`,
|
|
128
136
|
review: REVIEW,
|
|
129
137
|
sources: ["searxng", "youtube", "exa"],
|
|
130
|
-
budget: { queries: 3, reads: 6, rounds: 2 },
|
|
138
|
+
budget: { queries: 3, reads: 6, rounds: 2, checks: 3 },
|
|
139
|
+
age: "A channel that has not posted in the last year counts for little.",
|
|
131
140
|
};
|
|
132
141
|
const person = {
|
|
133
142
|
id: "raven/person",
|
|
134
143
|
kind: "person",
|
|
135
|
-
version:
|
|
144
|
+
version: 4,
|
|
136
145
|
propose: `You plan searches about one person or company for one research ask: what they do, what they said, what others say about them.
|
|
137
146
|
|
|
138
147
|
${SHAPE_QUERIES}
|
|
@@ -158,12 +167,13 @@ Hits:
|
|
|
158
167
|
{hits}`,
|
|
159
168
|
review: REVIEW,
|
|
160
169
|
sources: ["searxng", "exa", "linkedin", "google"],
|
|
161
|
-
budget: { queries: 4, reads: 6, rounds: 2 },
|
|
170
|
+
budget: { queries: 4, reads: 6, rounds: 2, checks: 3 },
|
|
171
|
+
age: "What they do now: prefer the latest pages. Their history can be old.",
|
|
162
172
|
};
|
|
163
173
|
const site = {
|
|
164
174
|
id: "raven/site",
|
|
165
175
|
kind: "site",
|
|
166
|
-
version:
|
|
176
|
+
version: 4,
|
|
167
177
|
propose: `You plan searches inside one website for one research ask. Every query runs on {site} only.
|
|
168
178
|
|
|
169
179
|
${SHAPE_QUERIES}
|
|
@@ -188,12 +198,15 @@ Hits:
|
|
|
188
198
|
{hits}`,
|
|
189
199
|
review: REVIEW,
|
|
190
200
|
sources: ["sitemap", "searxng", "fetch"],
|
|
191
|
-
budget: { queries: 4, reads: 8, rounds: 2 },
|
|
201
|
+
budget: { queries: 4, reads: 8, rounds: 2, checks: 3 },
|
|
202
|
+
age: "When two pages of the site disagree, the later one counts.",
|
|
192
203
|
};
|
|
193
204
|
const DEFAULTS = { web, video, channel, person, site };
|
|
194
205
|
/** The default plan file for a kind, validated, as a fresh copy. */
|
|
195
206
|
export function defaultPlanFile(kind) {
|
|
196
207
|
return PlanFileShape.parse(structuredClone(DEFAULTS[kind]));
|
|
197
208
|
}
|
|
209
|
+
/** The plan file's word on age; a stored file from before version 4 takes its kind's default. */
|
|
210
|
+
export const ageOf = (planFile) => planFile.age ?? DEFAULTS[planFile.kind].age;
|
|
198
211
|
export const PLAN_KINDS = Object.keys(DEFAULTS);
|
|
199
212
|
//# sourceMappingURL=index.js.map
|
package/dist/render.d.ts
CHANGED
|
@@ -3,6 +3,10 @@ import type { HitView, YieldRow } from "./types.js";
|
|
|
3
3
|
export declare const lines: (xs: readonly string[], none?: string) => string;
|
|
4
4
|
/** "The person says:" and their lines, or nothing: a prompt pays for the heading only when there is one. */
|
|
5
5
|
export declare const renderSteer: (steer: readonly string[] | undefined) => string;
|
|
6
|
+
/** What the last round left open, under its heading, or nothing. */
|
|
7
|
+
export declare const renderOpen: (open: readonly string[] | undefined) => string;
|
|
8
|
+
/** The plan file's word on age as one more rule line, or nothing. */
|
|
9
|
+
export declare const renderAge: (age: string | undefined) => string;
|
|
6
10
|
/** One line per row, the keys it has first: `source=exa channel=... hits=12 reads=4 proposed=9 kept=3`. */
|
|
7
11
|
export declare function renderYield(rows: readonly YieldRow[]): string;
|
|
8
12
|
/** Numbered, one hit per line, only the fields it has. */
|
package/dist/render.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export const lines = (xs, none = "(nothing)") => xs.length ? xs.map((x) => `- ${x}`).join("\n") : none;
|
|
2
2
|
/** "The person says:" and their lines, or nothing: a prompt pays for the heading only when there is one. */
|
|
3
3
|
export const renderSteer = (steer) => steer?.length ? `The person says:\n${lines(steer)}\n` : "";
|
|
4
|
+
/** What the last round left open, under its heading, or nothing. */
|
|
5
|
+
export const renderOpen = (open) => open?.length ? `The last round left open (plan for these first):\n${lines(open)}\n` : "";
|
|
6
|
+
/** The plan file's word on age as one more rule line, or nothing. */
|
|
7
|
+
export const renderAge = (age) => (age ? `\n- Age: ${age}` : "");
|
|
4
8
|
/** One line per row, the keys it has first: `source=exa channel=... hits=12 reads=4 proposed=9 kept=3`. */
|
|
5
9
|
export function renderYield(rows) {
|
|
6
10
|
if (!rows.length)
|
package/dist/review.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fill } from "./model.js";
|
|
2
|
-
import { defaultPlanFile } from "./plans/index.js";
|
|
3
|
-
import { lines, renderSteer } from "./render.js";
|
|
2
|
+
import { ageOf, defaultPlanFile } from "./plans/index.js";
|
|
3
|
+
import { lines, renderAge, renderSteer } from "./render.js";
|
|
4
4
|
import { Step, z } from "./types.js";
|
|
5
5
|
const EdgeAnswer = z.object({
|
|
6
6
|
next: z.enum(["stop", "again", "back"]),
|
|
@@ -20,6 +20,9 @@ export function reviewPrompt(round, planFile) {
|
|
|
20
20
|
kept: String(round.kept),
|
|
21
21
|
found: lines(round.found),
|
|
22
22
|
notes: lines(round.notes, "(none)"),
|
|
23
|
+
gaps: lines(round.gaps, "(none)"),
|
|
24
|
+
checks: lines(round.checks, "(none)"),
|
|
25
|
+
age: renderAge(ageOf(planFile)),
|
|
23
26
|
verdicts: lines(round.verdicts.map(verdictLine), "(none)"),
|
|
24
27
|
});
|
|
25
28
|
}
|
package/dist/triage.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fill } from "./model.js";
|
|
2
|
-
import { defaultPlanFile } from "./plans/index.js";
|
|
3
|
-
import { lines, renderHits, renderSteer, renderYield } from "./render.js";
|
|
2
|
+
import { ageOf, defaultPlanFile } from "./plans/index.js";
|
|
3
|
+
import { lines, renderAge, renderHits, renderOpen, renderSteer, renderYield } from "./render.js";
|
|
4
4
|
import { HitView, z, } from "./types.js";
|
|
5
5
|
const TriageAnswer = z.object({
|
|
6
6
|
hits: z.array(z.object({ url: z.string(), read: z.boolean(), why: z.string().nullable().optional() })),
|
|
@@ -33,6 +33,8 @@ export function triagePrompt(hits, plan, planFile, yieldRows) {
|
|
|
33
33
|
ask: plan.ask.text,
|
|
34
34
|
site: plan.ask.site ?? "",
|
|
35
35
|
steer: renderSteer(plan.ask.steer),
|
|
36
|
+
open: renderOpen(plan.ask.open),
|
|
37
|
+
age: renderAge(ageOf(planFile)),
|
|
36
38
|
known: lines(plan.ask.known),
|
|
37
39
|
yield: renderYield(yieldRows),
|
|
38
40
|
hits: renderHits(hits),
|
package/dist/types.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare const Ask: z.ZodObject<{
|
|
|
31
31
|
}>;
|
|
32
32
|
known: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
33
33
|
steer: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
34
|
+
open: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
34
35
|
site: z.ZodOptional<z.ZodString>;
|
|
35
36
|
}, z.core.$strip>;
|
|
36
37
|
export type Ask = z.infer<typeof Ask>;
|
|
@@ -78,12 +79,14 @@ export declare const Budget: z.ZodObject<{
|
|
|
78
79
|
queries: z.ZodNumber;
|
|
79
80
|
reads: z.ZodNumber;
|
|
80
81
|
rounds: z.ZodNumber;
|
|
82
|
+
checks: z.ZodDefault<z.ZodNumber>;
|
|
81
83
|
}, z.core.$strip>;
|
|
82
84
|
export type Budget = z.infer<typeof Budget>;
|
|
83
85
|
/**
|
|
84
86
|
* The recipe for one ask kind: the prompts, the sources it may use, the budget. Versioned and
|
|
85
87
|
* tuned like an SOP, stored beside the ledger. `{name}` marks in a prompt are filled from the
|
|
86
|
-
* ask: `{ask}`, `{known}`, `{yield}`, `{n}`, `{year}`, `{site}
|
|
88
|
+
* ask: `{ask}`, `{known}`, `{yield}`, `{n}`, `{year}`, `{site}`, `{open}`, `{age}`; the review's
|
|
89
|
+
* also `{gaps}` and `{checks}`.
|
|
87
90
|
*/
|
|
88
91
|
export declare const PlanFile: z.ZodObject<{
|
|
89
92
|
id: z.ZodString;
|
|
@@ -103,7 +106,9 @@ export declare const PlanFile: z.ZodObject<{
|
|
|
103
106
|
queries: z.ZodNumber;
|
|
104
107
|
reads: z.ZodNumber;
|
|
105
108
|
rounds: z.ZodNumber;
|
|
109
|
+
checks: z.ZodDefault<z.ZodNumber>;
|
|
106
110
|
}, z.core.$strip>;
|
|
111
|
+
age: z.ZodOptional<z.ZodString>;
|
|
107
112
|
}, z.core.$strip>;
|
|
108
113
|
export type PlanFile = z.infer<typeof PlanFile>;
|
|
109
114
|
/** What a source, channel or proposer yielded before. Raven reads it; wren or the files ledger writes it. */
|
|
@@ -148,6 +153,7 @@ export declare const Plan: z.ZodObject<{
|
|
|
148
153
|
}>;
|
|
149
154
|
known: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
150
155
|
steer: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
156
|
+
open: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
151
157
|
site: z.ZodOptional<z.ZodString>;
|
|
152
158
|
}, z.core.$strip>;
|
|
153
159
|
round: z.ZodNumber;
|
|
@@ -173,6 +179,7 @@ export declare const Plan: z.ZodObject<{
|
|
|
173
179
|
queries: z.ZodNumber;
|
|
174
180
|
reads: z.ZodNumber;
|
|
175
181
|
rounds: z.ZodNumber;
|
|
182
|
+
checks: z.ZodDefault<z.ZodNumber>;
|
|
176
183
|
}, z.core.$strip>;
|
|
177
184
|
snapshot: z.ZodObject<{
|
|
178
185
|
at: z.ZodString;
|
|
@@ -235,6 +242,7 @@ export declare const Round: z.ZodObject<{
|
|
|
235
242
|
}>;
|
|
236
243
|
known: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
237
244
|
steer: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
245
|
+
open: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
238
246
|
site: z.ZodOptional<z.ZodString>;
|
|
239
247
|
}, z.core.$strip>;
|
|
240
248
|
round: z.ZodNumber;
|
|
@@ -242,6 +250,7 @@ export declare const Round: z.ZodObject<{
|
|
|
242
250
|
queries: z.ZodNumber;
|
|
243
251
|
reads: z.ZodNumber;
|
|
244
252
|
rounds: z.ZodNumber;
|
|
253
|
+
checks: z.ZodDefault<z.ZodNumber>;
|
|
245
254
|
}, z.core.$strip>;
|
|
246
255
|
hits: z.ZodNumber;
|
|
247
256
|
reads: z.ZodNumber;
|
|
@@ -259,6 +268,8 @@ export declare const Round: z.ZodObject<{
|
|
|
259
268
|
}>;
|
|
260
269
|
gap: z.ZodOptional<z.ZodString>;
|
|
261
270
|
}, z.core.$strip>>>;
|
|
271
|
+
gaps: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
272
|
+
checks: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
262
273
|
}, z.core.$strip>;
|
|
263
274
|
export type Round = z.infer<typeof Round>;
|
|
264
275
|
export declare const Step: z.ZodEnum<{
|
package/dist/types.js
CHANGED
|
@@ -16,6 +16,8 @@ export const Ask = z.object({
|
|
|
16
16
|
known: z.array(z.string()).default([]),
|
|
17
17
|
/** What the person said along the way, one line each: every prompt renders it first. */
|
|
18
18
|
steer: z.array(z.string()).default([]),
|
|
19
|
+
/** What the last round left open, one line each: its review's why, its gaps. The planner looks there first. */
|
|
20
|
+
open: z.array(z.string()).default([]),
|
|
19
21
|
/** Only for kind `site`, or when a query must stay on one host. */
|
|
20
22
|
site: z.string().optional(),
|
|
21
23
|
});
|
|
@@ -43,11 +45,14 @@ export const Budget = z.object({
|
|
|
43
45
|
reads: z.number().int().positive(),
|
|
44
46
|
/** Rounds before `review` must stop. */
|
|
45
47
|
rounds: z.number().int().positive(),
|
|
48
|
+
/** Kept findings per round that a model checks against their document: a sample spread across the documents. 0: none. */
|
|
49
|
+
checks: z.number().int().nonnegative().default(3),
|
|
46
50
|
});
|
|
47
51
|
/**
|
|
48
52
|
* The recipe for one ask kind: the prompts, the sources it may use, the budget. Versioned and
|
|
49
53
|
* tuned like an SOP, stored beside the ledger. `{name}` marks in a prompt are filled from the
|
|
50
|
-
* ask: `{ask}`, `{known}`, `{yield}`, `{n}`, `{year}`, `{site}
|
|
54
|
+
* ask: `{ask}`, `{known}`, `{yield}`, `{n}`, `{year}`, `{site}`, `{open}`, `{age}`; the review's
|
|
55
|
+
* also `{gaps}` and `{checks}`.
|
|
51
56
|
*/
|
|
52
57
|
export const PlanFile = z.object({
|
|
53
58
|
id: z.string().min(1),
|
|
@@ -62,6 +67,8 @@ export const PlanFile = z.object({
|
|
|
62
67
|
/** Source names a run may use, in order of preference. A run can narrow the list, never widen it. */
|
|
63
68
|
sources: z.array(z.string()),
|
|
64
69
|
budget: Budget,
|
|
70
|
+
/** How much a source's age counts for this kind, one sentence: filled as `{age}`. Never a cutoff. */
|
|
71
|
+
age: z.string().optional(),
|
|
65
72
|
});
|
|
66
73
|
/** What a source, channel or proposer yielded before. Raven reads it; wren or the files ledger writes it. */
|
|
67
74
|
export const YieldRow = z.object({
|
|
@@ -131,6 +138,10 @@ export const Round = z.object({
|
|
|
131
138
|
notes: z.array(z.string()).default([]),
|
|
132
139
|
/** The extractor's verdict on each document read this round: the planner sees what the reads were worth. */
|
|
133
140
|
verdicts: z.array(Verdict).default([]),
|
|
141
|
+
/** What a step or a person said the round lacks, one line each, the step or the person first. */
|
|
142
|
+
gaps: z.array(z.string()).default([]),
|
|
143
|
+
/** The sample check: whether each checked finding's quote backs it, one line each. */
|
|
144
|
+
checks: z.array(z.string()).default([]),
|
|
134
145
|
});
|
|
135
146
|
export const Step = z.enum(["plan", "fetch", "triage", "read", "extract"]);
|
|
136
147
|
/** The edge out of a round. `again` is a new round from `plan`; `back` reruns one step of this round. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrenautomation/raven",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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-Shield-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.8.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"typecheck": "tsc --noEmit",
|