bareloop 0.43.0 → 0.45.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/CHANGELOG.md +60 -0
- package/bareloop.context.md +53 -13
- package/package.json +2 -2
- package/src/authorflow.js +27 -12
- package/src/authoring.js +1 -1
- package/src/authorjob.js +52 -16
- package/src/authorreadout.js +12 -6
- package/src/authorrun.js +8 -2
- package/src/declaredclose.js +4 -1
- package/src/draftspend.js +20 -2
- package/src/facts.js +54 -9
- package/src/factwords.js +58 -6
- package/src/fitcheck.js +166 -0
- package/src/inputlook.js +38 -3
- package/src/job.js +1 -1
- package/src/kinds.js +5 -0
- package/src/pagedropwords.js +110 -0
- package/src/pagedry.js +125 -0
- package/src/pagemap.js +269 -0
- package/src/pagerules.js +318 -0
- package/src/panel/authorroutes.js +34 -30
- package/src/panel/authorsession.js +66 -11
- package/src/panel/index.html +469 -65
- package/src/panel/jobplan.js +14 -7
- package/src/panel/runroutes.js +46 -22
- package/src/panel/server.js +792 -28
- package/src/panel/status.js +33 -0
- package/src/panelmoney.js +29 -0
- package/src/planrun.js +53 -4
- package/src/promptregisters.js +8 -0
- package/src/replay.js +118 -7
- package/src/rubricstep.js +157 -15
- package/src/runlist.js +2 -1
- package/src/schedulewords.js +6 -3
- package/src/source.js +18 -0
- package/src/thinking.js +63 -2
- package/src/userrun.js +28 -14
- package/types/authorflow.d.ts +42 -6
- package/types/authorjob.d.ts +20 -4
- package/types/declaredclose.d.ts +2 -0
- package/types/draftspend.d.ts +27 -1
- package/types/facts.d.ts +15 -0
- package/types/factwords.d.ts +26 -3
- package/types/fitcheck.d.ts +113 -0
- package/types/inputlook.d.ts +15 -0
- package/types/kinds.d.ts +5 -0
- package/types/pagedropwords.d.ts +39 -0
- package/types/pagedry.d.ts +37 -0
- package/types/pagemap.d.ts +154 -0
- package/types/pagerules.d.ts +86 -0
- package/types/panel/authorroutes.d.ts +17 -14
- package/types/panel/authorsession.d.ts +4 -2
- package/types/panel/jobplan.d.ts +5 -2
- package/types/panel/runroutes.d.ts +2 -2
- package/types/panel/server.d.ts +156 -2
- package/types/panel/status.d.ts +51 -0
- package/types/panelmoney.d.ts +5 -0
- package/types/replay.d.ts +21 -1
- package/types/rubricstep.d.ts +62 -1
- package/types/runlist.d.ts +4 -1
- package/types/schedulewords.d.ts +4 -2
- package/types/source.d.ts +11 -0
- package/types/thinking.d.ts +39 -0
- package/types/userrun.d.ts +4 -0
package/types/authorjob.d.ts
CHANGED
|
@@ -87,19 +87,20 @@ export function refuseLockedKind(kind: string): Refusal;
|
|
|
87
87
|
* rates?: {in: number, out: number}|null, draftThinking?: 'on'|'off',
|
|
88
88
|
* onPhase?: (phase: string, data?: any) => void,
|
|
89
89
|
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string}) => void,
|
|
90
|
-
* seedFn?: Function, scoutFn?: Function, listingFn?: Function, lookFn?: Function|null,
|
|
90
|
+
* seedFn?: Function, scoutFn?: Function, listingFn?: Function, lookFn?: Function|null, fitFn?: Function|null,
|
|
91
|
+
* fitAsk?: ((question: string) => Promise<string|null>)|null, onFit?: (fit: {state: string, asks: any[], notFound: any[]}) => void,
|
|
91
92
|
* authorFn?: Function, authorOpts?: object, writeScope?: string[]|null,
|
|
92
93
|
* signerFix?: Function|any, proposeFn?: Function, compileOpts?: object,
|
|
93
94
|
* ask?: ((step: {kind: string, [k: string]: any}) => Promise<string|null>)|null,
|
|
94
|
-
* answerQuestions?: ((o: {questions: {line: number, question: string}[], dropped: {reason: string, raw: any}[], confirmed: any}) =>
|
|
95
|
-
* Promise<{jobLines: {n: number, text: string, rule?: string}[], answers: Record<string|number, any
|
|
95
|
+
* answerQuestions?: ((o: {questions: {line: number, question: string, rule?: number, source?: string, ask?: string, reading?: string}[], dropped: {reason: string, raw: any}[], confirmed: any}) =>
|
|
96
|
+
* Promise<{jobLines: {n: number, text: string, rule?: string}[], answers: Record<string|number, any>, left?: {line: number, rule: number}[]}|null>)|null,
|
|
96
97
|
* confirmGenerate?: Function|null, isRepo?: boolean,
|
|
97
98
|
* langResult?: {kind: string, candidates?: string[], [k: string]: any}|null}} o
|
|
98
99
|
* @returns {Promise<{ok: boolean, refusal: Refusal|null, verdictType: string|null,
|
|
99
100
|
* closeDecl: any, seedRef: string|null, authoring: any, judged: any, reds: Red[],
|
|
100
101
|
* stop: string|null, cost: any, interview: any, confirmed: any}>}
|
|
101
102
|
*/
|
|
102
|
-
export function authorCloseForJob({ answers, repoPath, lang, verdictType, questions, jobLines, inputs, generate, provider, seedRef, scout, listing, ceilingUsd, rates, draftThinking, writeScope, judgeModel, onPhase, onCall, seedFn, scoutFn, listingFn, lookFn, authorFn, authorOpts, signerFix, proposeFn, compileOpts, ask, confirmGenerate, isRepo, langResult, answerQuestions, }: {
|
|
103
|
+
export function authorCloseForJob({ answers, repoPath, lang, verdictType, questions, jobLines, inputs, generate, provider, seedRef, scout, listing, ceilingUsd, rates, draftThinking, writeScope, judgeModel, onPhase, onCall, seedFn, scoutFn, listingFn, lookFn, fitFn, fitAsk, onFit, authorFn, authorOpts, signerFix, proposeFn, compileOpts, ask, confirmGenerate, isRepo, langResult, answerQuestions, }: {
|
|
103
104
|
answers: Record<string | number, any>;
|
|
104
105
|
repoPath?: string | null;
|
|
105
106
|
lang: string;
|
|
@@ -137,6 +138,13 @@ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questi
|
|
|
137
138
|
scoutFn?: Function;
|
|
138
139
|
listingFn?: Function;
|
|
139
140
|
lookFn?: Function | null;
|
|
141
|
+
fitFn?: Function | null;
|
|
142
|
+
fitAsk?: ((question: string) => Promise<string | null>) | null;
|
|
143
|
+
onFit?: (fit: {
|
|
144
|
+
state: string;
|
|
145
|
+
asks: any[];
|
|
146
|
+
notFound: any[];
|
|
147
|
+
}) => void;
|
|
140
148
|
authorFn?: Function;
|
|
141
149
|
authorOpts?: object;
|
|
142
150
|
writeScope?: string[] | null;
|
|
@@ -151,6 +159,10 @@ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questi
|
|
|
151
159
|
questions: {
|
|
152
160
|
line: number;
|
|
153
161
|
question: string;
|
|
162
|
+
rule?: number;
|
|
163
|
+
source?: string;
|
|
164
|
+
ask?: string;
|
|
165
|
+
reading?: string;
|
|
154
166
|
}[];
|
|
155
167
|
dropped: {
|
|
156
168
|
reason: string;
|
|
@@ -164,6 +176,10 @@ export function authorCloseForJob({ answers, repoPath, lang, verdictType, questi
|
|
|
164
176
|
rule?: string;
|
|
165
177
|
}[];
|
|
166
178
|
answers: Record<string | number, any>;
|
|
179
|
+
left?: {
|
|
180
|
+
line: number;
|
|
181
|
+
rule: number;
|
|
182
|
+
}[];
|
|
167
183
|
} | null>) | null;
|
|
168
184
|
confirmGenerate?: Function | null;
|
|
169
185
|
isRepo?: boolean;
|
package/types/declaredclose.d.ts
CHANGED
|
@@ -118,6 +118,7 @@ export function guardNames(closeDecl: any, verdictType: string): string[];
|
|
|
118
118
|
* judgeLoop?: ((o: {system: string}) => any)|null,
|
|
119
119
|
* judgeModel?: string|null,
|
|
120
120
|
* onJudgeCost?: ((c: any) => void)|null,
|
|
121
|
+
* onRubricEvidence?: ((e: any) => void)|null,
|
|
121
122
|
* callBounds?: (() => {timeoutMs?: number, deadlineMs?: number})|null}} [opts]
|
|
122
123
|
* @returns {Promise<any>}
|
|
123
124
|
*/
|
|
@@ -138,6 +139,7 @@ export function runDeclaredStages(stages: any[], redact?: (s: string) => string,
|
|
|
138
139
|
}) => any) | null;
|
|
139
140
|
judgeModel?: string | null;
|
|
140
141
|
onJudgeCost?: ((c: any) => void) | null;
|
|
142
|
+
onRubricEvidence?: ((e: any) => void) | null;
|
|
141
143
|
callBounds?: (() => {
|
|
142
144
|
timeoutMs?: number;
|
|
143
145
|
deadlineMs?: number;
|
package/types/draftspend.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* - `step-start` {no, id, label, at}
|
|
4
4
|
* - `step-end` {no, status: 'done'|'failed', label, at} (a re-opened step writes `step-reopen` {no, at} first)
|
|
5
5
|
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway" / "can't change it" / "not confirmed")
|
|
6
|
+
* - `human` {no, source: 'confirm'|'try-3'|'look', question, answer, line?, at}: one question the person was asked and what they answered (the answer is secret-masked
|
|
7
|
+
* before it is written; the row is written only when BOTH exist, so a question nobody answered leaves no row)
|
|
6
8
|
* - `call` {no, step, label, model, thinking, thinkingSupport, thinkingStatus?, costUsd (null stays null), unpricedRounds, at}: one METERED model call
|
|
7
9
|
* (`thinking` = the tick's mode: off | on; `thinkingSupport` = bare-agent's lookup for the model: true | false | 'unverified';
|
|
8
10
|
* `thinkingStatus` = bare-agent's own verdict for the call's run: applied | unsupported | ignored | unknown, present only when thinkingMode was sent)
|
|
@@ -58,12 +60,33 @@ export function sessionDirForRow(row: {
|
|
|
58
60
|
home?: string;
|
|
59
61
|
sessionsRoot?: string;
|
|
60
62
|
}): string | null;
|
|
63
|
+
/**
|
|
64
|
+
* PRD v1.106 Part 5 Q1: one answered question as the two lines the Audit's drafting table shows under its step. ONE place owns the words.
|
|
65
|
+
* @param {{question: string, answer: string, source?: string, line?: number, at?: string}} h
|
|
66
|
+
* @returns {{question: string, answer: string, source: string, line?: number, at?: string, askedText: string, saidText: string}}
|
|
67
|
+
*/
|
|
68
|
+
export function humanRowWords(h: {
|
|
69
|
+
question: string;
|
|
70
|
+
answer: string;
|
|
71
|
+
source?: string;
|
|
72
|
+
line?: number;
|
|
73
|
+
at?: string;
|
|
74
|
+
}): {
|
|
75
|
+
question: string;
|
|
76
|
+
answer: string;
|
|
77
|
+
source: string;
|
|
78
|
+
line?: number;
|
|
79
|
+
at?: string;
|
|
80
|
+
askedText: string;
|
|
81
|
+
saidText: string;
|
|
82
|
+
};
|
|
61
83
|
/**
|
|
62
84
|
* Fold `<dir>/draft-log.jsonl` into one record per drafting step, each with its calls. A line that cannot be parsed is
|
|
63
85
|
* skipped (a torn last line must not hide the rest).
|
|
64
86
|
* @param {string} dir
|
|
65
87
|
* @returns {{no: number, id: string, label: string, status: 'running'|'done'|'failed', startedAt: string, endedAt: string|null, wallMs: number|null,
|
|
66
|
-
* calls: {label: string, model: string|null, costUsd: number|null, unpricedRounds: number, at: string}[]
|
|
88
|
+
* calls: {label: string, model: string|null, costUsd: number|null, unpricedRounds: number, at: string}[],
|
|
89
|
+
* humans: ReturnType<typeof humanRowWords>[]}[]}
|
|
67
90
|
*/
|
|
68
91
|
export function readDraftSteps(dir: string): {
|
|
69
92
|
no: number;
|
|
@@ -80,6 +103,7 @@ export function readDraftSteps(dir: string): {
|
|
|
80
103
|
unpricedRounds: number;
|
|
81
104
|
at: string;
|
|
82
105
|
}[];
|
|
106
|
+
humans: ReturnType<typeof humanRowWords>[];
|
|
83
107
|
}[];
|
|
84
108
|
/**
|
|
85
109
|
* The DRAFTING PART of a run (hamr 2026-10-06, option A): the first part of the run's views, built from the session's
|
|
@@ -109,6 +133,8 @@ export const DRAFT_LOG_FILE: "draft-log.jsonl";
|
|
|
109
133
|
* - `step-start` {no, id, label, at}
|
|
110
134
|
* - `step-end` {no, status: 'done'|'failed', label, at} (a re-opened step writes `step-reopen` {no, at} first)
|
|
111
135
|
* - `step-label` {no, label, at} (the step reads `label` from now on, status and times untouched: the thinking row's "the model thought anyway" / "can't change it" / "not confirmed")
|
|
136
|
+
* - `human` {no, source: 'confirm'|'try-3'|'look', question, answer, line?, at}: one question the person was asked and what they answered (the answer is secret-masked
|
|
137
|
+
* before it is written; the row is written only when BOTH exist, so a question nobody answered leaves no row)
|
|
112
138
|
* - `call` {no, step, label, model, thinking, thinkingSupport, thinkingStatus?, costUsd (null stays null), unpricedRounds, at}: one METERED model call
|
|
113
139
|
* (`thinking` = the tick's mode: off | on; `thinkingSupport` = bare-agent's lookup for the model: true | false | 'unverified';
|
|
114
140
|
* `thinkingStatus` = bare-agent's own verdict for the call's run: applied | unsupported | ignored | unknown, present only when thinkingMode was sent)
|
package/types/facts.d.ts
CHANGED
|
@@ -23,6 +23,14 @@ export function factClaims(part: any, results: unknown): {
|
|
|
23
23
|
quote: string;
|
|
24
24
|
values?: Record<string, string>;
|
|
25
25
|
}[];
|
|
26
|
+
/**
|
|
27
|
+
* One amount of a money fact in the fact's OWN signed forms, never a hardcoded sign: `symbolFirst` puts the currency sign before the amount
|
|
28
|
+
* ("$144") when the fact has one, else the unit after it ("144 US dollars"); not `symbolFirst` (a rule's bound) prefers the unit.
|
|
29
|
+
* @param {any} f a money fact @param {string|number} n @param {boolean} symbolFirst @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
export function moneyAs(f: any, n: string | number, symbolFirst: boolean): string;
|
|
32
|
+
/** @param {any} f a fact with a rule @returns {string} the rule in words, e.g. "at most 450 US dollars" */
|
|
33
|
+
export function ruleWords(f: any): string;
|
|
26
34
|
/**
|
|
27
35
|
* One fact as a plain row, written by code from the signed fields:
|
|
28
36
|
* `fact · price — money, at most 450 US dollars, after "Price", quoted from "Flights"`.
|
|
@@ -69,3 +77,10 @@ export const FACT_OPS: readonly string[];
|
|
|
69
77
|
export const MAX_FACTS: 10;
|
|
70
78
|
/** every field a part of class `fact` may carry (the shared ones are checked by rubricStepShapeReds) */
|
|
71
79
|
export const FACT_PART_FIELDS: readonly string[];
|
|
80
|
+
/** the limits bareguard 0.24 puts on a money fact's lists (ruling #65), enforced here first so the red is ours and plain */
|
|
81
|
+
export const MAX_CURRENCIES: 3;
|
|
82
|
+
export const MAX_UNITS: 10;
|
|
83
|
+
export const MAX_UNIT_CHARS: 100;
|
|
84
|
+
export function asList(v: unknown): string[];
|
|
85
|
+
export function moneyForms(f: any): string[];
|
|
86
|
+
export function boundOk(shape: string, v: unknown): boolean;
|
package/types/factwords.d.ts
CHANGED
|
@@ -9,16 +9,35 @@ export function countExact(source: string, words: string): number;
|
|
|
9
9
|
* @param {string} source @param {string} words @returns {number}
|
|
10
10
|
*/
|
|
11
11
|
export function countPhrase(source: string, words: string): number;
|
|
12
|
+
/**
|
|
13
|
+
* What the page-word map (src/pagemap.js) KEPT and DROPPED for one input: the sets the second proof reads. A look from the old search-and-read
|
|
14
|
+
* path has no `dropped` list, so it gives null and the label is proved against the code-made list as before.
|
|
15
|
+
* @param {{facts?: any[], dropped?: (import('./pagerules.js').Dropped & {source?: string})[]}|null|undefined} look @param {string} source
|
|
16
|
+
* @returns {{labels: Set<string>, units: Set<string>, currencies: Set<string>, words: Set<string>, dropped: Map<string, import('./pagerules.js').Dropped>}|null}
|
|
17
|
+
*/
|
|
18
|
+
export function keptSetOf(look: {
|
|
19
|
+
facts?: any[];
|
|
20
|
+
dropped?: (import("./pagerules.js").Dropped & {
|
|
21
|
+
source?: string;
|
|
22
|
+
})[];
|
|
23
|
+
} | null | undefined, source: string): {
|
|
24
|
+
labels: Set<string>;
|
|
25
|
+
units: Set<string>;
|
|
26
|
+
currencies: Set<string>;
|
|
27
|
+
words: Set<string>;
|
|
28
|
+
dropped: Map<string, import("./pagerules.js").Dropped>;
|
|
29
|
+
} | null;
|
|
12
30
|
/**
|
|
13
31
|
* The reds for ONE fact part against its frozen source text.
|
|
14
|
-
* @param {{part: any, text: string, line: number|string, scan?: import('./labelscan.js').LabelScan}} o
|
|
32
|
+
* @param {{part: any, text: string, line: number|string, scan?: import('./labelscan.js').LabelScan, kept?: ReturnType<typeof keptSetOf>}} o
|
|
15
33
|
* @returns {{code: string, detail: string}[]}
|
|
16
34
|
*/
|
|
17
|
-
export function checkFactWords({ part, text, line, scan }: {
|
|
35
|
+
export function checkFactWords({ part, text, line, scan, kept }: {
|
|
18
36
|
part: any;
|
|
19
37
|
text: string;
|
|
20
38
|
line: number | string;
|
|
21
39
|
scan?: import("./labelscan.js").LabelScan;
|
|
40
|
+
kept?: ReturnType<typeof keptSetOf>;
|
|
22
41
|
}): {
|
|
23
42
|
code: string;
|
|
24
43
|
detail: string;
|
|
@@ -27,9 +46,13 @@ export function checkFactWords({ part, text, line, scan }: {
|
|
|
27
46
|
* The reds for every fact part of a declaration. A fact part whose input text is not at hand is a red: a check whose words were never
|
|
28
47
|
* proved against the source is never signed.
|
|
29
48
|
* @param {any} declaration @param {Record<string, string>|null} texts label -> frozen text
|
|
49
|
+
* @param {{facts?: any[], dropped?: any[]}|null} [look] the page-word map's report: what it kept and dropped (null = no map, the code-made list is the proof)
|
|
30
50
|
* @returns {{code: string, path: string, detail: string}[]}
|
|
31
51
|
*/
|
|
32
|
-
export function checkDeclarationWords(declaration: any, texts: Record<string, string> | null
|
|
52
|
+
export function checkDeclarationWords(declaration: any, texts: Record<string, string> | null, look?: {
|
|
53
|
+
facts?: any[];
|
|
54
|
+
dropped?: any[];
|
|
55
|
+
} | null): {
|
|
33
56
|
code: string;
|
|
34
57
|
path: string;
|
|
35
58
|
detail: string;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the AI is told: the job lines (the numbered text only, no `~` rules) and the WHOLE text of every input under its label. Adapted from the POC
|
|
3
|
+
* call (.claude/scratch/fit-poc6/run.mjs): the asks are copied from each job line instead of hand-written.
|
|
4
|
+
* @param {{jobLines: {n: number, text: string}[], texts: Record<string, string>}} o
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function fitPrompt({ jobLines, texts }: {
|
|
8
|
+
jobLines: {
|
|
9
|
+
n: number;
|
|
10
|
+
text: string;
|
|
11
|
+
}[];
|
|
12
|
+
texts: Record<string, string>;
|
|
13
|
+
}): string;
|
|
14
|
+
/**
|
|
15
|
+
* Read the AI's reply and decide, all in code. Malformed (no repair): not JSON, another form, a line that is not a job line, an ask not copied from its own
|
|
16
|
+
* line, found not a boolean, a quote neither text nor null, or a job line with no ask. An ask is found only if `found` is true AND its quote is on a page;
|
|
17
|
+
* `found` with a quote that is not on any page (or no quote) is made up and counts as not found.
|
|
18
|
+
* @param {unknown} text the reply
|
|
19
|
+
* @param {{n: number, text: string}[]} jobLines
|
|
20
|
+
* @param {Record<string, string>} texts the frozen input texts by label
|
|
21
|
+
* @returns {{status: 'malformed'}|{status: 'ok', state: 'fits'|'ask', asks: FitAsk[], notFound: {line: number, ask: string}[]}}
|
|
22
|
+
*/
|
|
23
|
+
export function decideFit(text: unknown, jobLines: {
|
|
24
|
+
n: number;
|
|
25
|
+
text: string;
|
|
26
|
+
}[], texts: Record<string, string>): {
|
|
27
|
+
status: "malformed";
|
|
28
|
+
} | {
|
|
29
|
+
status: "ok";
|
|
30
|
+
state: "fits" | "ask";
|
|
31
|
+
asks: FitAsk[];
|
|
32
|
+
notFound: {
|
|
33
|
+
line: number;
|
|
34
|
+
ask: string;
|
|
35
|
+
}[];
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Run the fit check: one call (one retry on a malformed reply or a transport failure or a 429). Never throws on a call casualty; every failure is `absent`.
|
|
39
|
+
* @param {{jobLines: {n: number, text: string}[], texts: Record<string, string>, provider?: any, maxTokens?: number, ceilingUsd?: number|null,
|
|
40
|
+
* callTimeoutMs?: number, onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string, raw?: string}) => void,
|
|
41
|
+
* createLoop?: Function, rates?: {in: number, out: number}|null, callOptions?: Record<string, any>, sleep?: (ms: number) => Promise<void>}} o
|
|
42
|
+
* @returns {Promise<{state: 'fits'|'ask'|'absent', asks: FitAsk[], notFound: {line: number, ask: string}[], reason: string|null, cause: string|null,
|
|
43
|
+
* calls: {label: string, costUsd: number|null, unpricedRounds: number}[], budgetStop: 'cap-halt'|'pricing-red'|null}>}
|
|
44
|
+
*/
|
|
45
|
+
export function runFitCheck({ jobLines, texts, provider, maxTokens, ceilingUsd, callTimeoutMs, onCall, createLoop, rates, callOptions, sleep, }: {
|
|
46
|
+
jobLines: {
|
|
47
|
+
n: number;
|
|
48
|
+
text: string;
|
|
49
|
+
}[];
|
|
50
|
+
texts: Record<string, string>;
|
|
51
|
+
provider?: any;
|
|
52
|
+
maxTokens?: number;
|
|
53
|
+
ceilingUsd?: number | null;
|
|
54
|
+
callTimeoutMs?: number;
|
|
55
|
+
onCall?: (call: {
|
|
56
|
+
label: string;
|
|
57
|
+
costUsd: number | null;
|
|
58
|
+
unpricedRounds: number;
|
|
59
|
+
thinkingStatus?: string;
|
|
60
|
+
raw?: string;
|
|
61
|
+
}) => void;
|
|
62
|
+
createLoop?: Function;
|
|
63
|
+
rates?: {
|
|
64
|
+
in: number;
|
|
65
|
+
out: number;
|
|
66
|
+
} | null;
|
|
67
|
+
callOptions?: Record<string, any>;
|
|
68
|
+
sleep?: (ms: number) => Promise<void>;
|
|
69
|
+
}): Promise<{
|
|
70
|
+
state: "fits" | "ask" | "absent";
|
|
71
|
+
asks: FitAsk[];
|
|
72
|
+
notFound: {
|
|
73
|
+
line: number;
|
|
74
|
+
ask: string;
|
|
75
|
+
}[];
|
|
76
|
+
reason: string | null;
|
|
77
|
+
cause: string | null;
|
|
78
|
+
calls: {
|
|
79
|
+
label: string;
|
|
80
|
+
costUsd: number | null;
|
|
81
|
+
unpricedRounds: number;
|
|
82
|
+
}[];
|
|
83
|
+
budgetStop: "cap-halt" | "pricing-red" | null;
|
|
84
|
+
}>;
|
|
85
|
+
/** the label of the one paid call, as the drafting book and the progress line see it */
|
|
86
|
+
export const FIT_CALL_LABEL: "fit-check";
|
|
87
|
+
/** what the chat says when the check did not finish (drafting goes on) */
|
|
88
|
+
export const FIT_ABSENT_NOTE: "The fit check did not finish; drafting goes on.";
|
|
89
|
+
/** the answer that keeps drafting after the fit question (any case, a closing full stop allowed) */
|
|
90
|
+
export const FIT_GO_ON: "go on";
|
|
91
|
+
export function isGoOn(text: unknown): boolean;
|
|
92
|
+
export const FIT_SYSTEM: "You check whether saved web pages show what a job asks for. You never invent words: every ask must be copied from its job line and every quote must be copied from the page, character for character.";
|
|
93
|
+
export function norm(s: unknown): string;
|
|
94
|
+
export function notFoundList(notFound: {
|
|
95
|
+
line: number;
|
|
96
|
+
ask: string;
|
|
97
|
+
}[]): string;
|
|
98
|
+
export function fitQuestionText({ found, total, notFound }: {
|
|
99
|
+
found: number;
|
|
100
|
+
total: number;
|
|
101
|
+
notFound: {
|
|
102
|
+
line: number;
|
|
103
|
+
ask: string;
|
|
104
|
+
}[];
|
|
105
|
+
}): string;
|
|
106
|
+
export type FitAsk = {
|
|
107
|
+
line: number;
|
|
108
|
+
ask: string;
|
|
109
|
+
found: boolean;
|
|
110
|
+
quote: string | null;
|
|
111
|
+
madeUp: boolean;
|
|
112
|
+
ignored?: "number";
|
|
113
|
+
};
|
package/types/inputlook.d.ts
CHANGED
|
@@ -148,6 +148,12 @@ export function lookPrompt({ jobLines, labels, lists }: {
|
|
|
148
148
|
labels: string[];
|
|
149
149
|
lists: Record<string, string>;
|
|
150
150
|
}): string;
|
|
151
|
+
/**
|
|
152
|
+
* A fact the page-word map kept (src/pagerules.js `KeptFact`), as the look report carries it: a phrase fact holds its alternative
|
|
153
|
+
* phrases; any other holds its labels (the first is the primary), and a money fact its units and currencies.
|
|
154
|
+
* @param {import('./pagerules.js').KeptFact} k @param {string} source @returns {LookFact}
|
|
155
|
+
*/
|
|
156
|
+
export function lookFactOf(k: import("./pagerules.js").KeptFact, source: string): LookFact;
|
|
151
157
|
/**
|
|
152
158
|
* Turn the AI's raw report into a VERIFIED one, by code, at $0. A fact is carried only when: its shape is a real shape, its source is
|
|
153
159
|
* a real input, and its label is ON THE LIST for that input and shape (an id is resolved to its exact words). Anything else is moved
|
|
@@ -207,6 +213,9 @@ export const LOOK_REPORT_TOOL: "report_look";
|
|
|
207
213
|
/** how many hits one search returns at most, and how long a snippet or a read line is */
|
|
208
214
|
export const LOOK_MAX_HITS: 40;
|
|
209
215
|
export { LABEL_SHAPES };
|
|
216
|
+
/**
|
|
217
|
+
* `words` / `labels` / `unit` / `currency`: what the page-word map kept (idea A core)
|
|
218
|
+
*/
|
|
210
219
|
export type LookFact = {
|
|
211
220
|
line: number;
|
|
212
221
|
name: string;
|
|
@@ -220,6 +229,11 @@ export type LookFact = {
|
|
|
220
229
|
rule?: any;
|
|
221
230
|
aiProposal?: boolean;
|
|
222
231
|
forRule?: number;
|
|
232
|
+
reading?: import("./pagerules.js").Reading;
|
|
233
|
+
words?: string[];
|
|
234
|
+
labels?: string[];
|
|
235
|
+
unit?: string[];
|
|
236
|
+
currency?: string[];
|
|
223
237
|
};
|
|
224
238
|
export type LookNotFound = {
|
|
225
239
|
line: number;
|
|
@@ -234,5 +248,6 @@ export type LookReport = {
|
|
|
234
248
|
text?: string;
|
|
235
249
|
}[];
|
|
236
250
|
notFound: LookNotFound[];
|
|
251
|
+
dropped?: import("./pagerules.js").Dropped[];
|
|
237
252
|
};
|
|
238
253
|
import { LABEL_SHAPES } from './labelscan.js';
|
package/types/kinds.d.ts
CHANGED
|
@@ -645,6 +645,11 @@ export type Ctx = {
|
|
|
645
645
|
timeoutMs?: number;
|
|
646
646
|
deadlineMs?: number;
|
|
647
647
|
};
|
|
648
|
+
onRubricEvidence?: (e: {
|
|
649
|
+
step: number;
|
|
650
|
+
evidence: any[];
|
|
651
|
+
evidenceTotal?: number;
|
|
652
|
+
}) => void;
|
|
648
653
|
onStage?: (row: {
|
|
649
654
|
stage: string | null;
|
|
650
655
|
kind: string | null;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** @param {Dropped} d @returns {string} the plain sentence for one drop */
|
|
2
|
+
export function dropSentence(d: Dropped): string;
|
|
3
|
+
/**
|
|
4
|
+
* One row per fact that lost something: the sentences (one per dropped word, then the fact's own), and whether the whole fact went.
|
|
5
|
+
* @param {Dropped[]|undefined|null} dropped
|
|
6
|
+
* @returns {{line: number, rule?: number, fact: string, full: boolean, sentences: string[]}[]}
|
|
7
|
+
*/
|
|
8
|
+
export function dropRows(dropped: Dropped[] | undefined | null): {
|
|
9
|
+
line: number;
|
|
10
|
+
rule?: number;
|
|
11
|
+
fact: string;
|
|
12
|
+
full: boolean;
|
|
13
|
+
sentences: string[];
|
|
14
|
+
}[];
|
|
15
|
+
/**
|
|
16
|
+
* A row as one Not-checked line, in the person's own words: `line N: "<the ~ rule as written, or the fact's name>" — <sentences>`.
|
|
17
|
+
* @param {{line: number, rule?: number, fact: string, sentences: string[]}} row @param {any[]|null|undefined} jobLines @param {(l: any) => string[]} rulesOf
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
export function dropLine(row: {
|
|
21
|
+
line: number;
|
|
22
|
+
rule?: number;
|
|
23
|
+
fact: string;
|
|
24
|
+
sentences: string[];
|
|
25
|
+
}, jobLines: any[] | null | undefined, rulesOf: (l: any) => string[]): string;
|
|
26
|
+
/**
|
|
27
|
+
* An `s1` drop (a second fact that would read the same value as one already kept) is a NOTE when that OTHER fact is still signed: the guardrail
|
|
28
|
+
* is checked by it. With the other fact not signed, or no signed list given, the sentence stays Not checked. Every sentence of a row must qualify.
|
|
29
|
+
* @param {string} text one Not-checked line @param {string[]|null|undefined} [signed] the names of the facts the plan signs
|
|
30
|
+
* @returns {boolean} true when the line only says which written forms of a still-checked fact were not used
|
|
31
|
+
*/
|
|
32
|
+
export function isReadNote(text: string, signed?: string[] | null | undefined): boolean;
|
|
33
|
+
/** @param {string[]|null|undefined} items @param {string[]|null|undefined} [signed] names of the signed facts (see isReadNote)
|
|
34
|
+
* @returns {{notChecked: string[], readNotes: string[]}} the lines split: what is left unchecked, and how the page was read */
|
|
35
|
+
export function splitReadNotes(items: string[] | null | undefined, signed?: string[] | null | undefined): {
|
|
36
|
+
notChecked: string[];
|
|
37
|
+
readNotes: string[];
|
|
38
|
+
};
|
|
39
|
+
export type Dropped = import("./pagerules.js").Dropped;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The result lines of a kept money fact: with a label, every page line where a kept label is followed by a number (one sign between allowed);
|
|
3
|
+
* with no label (U1 moved it to a unit, e.g. "€533 total"), every line where a number is followed by a kept unit.
|
|
4
|
+
* @param {string} text @param {KeptFact} k @returns {{quote: string, value: string}[]}
|
|
5
|
+
*/
|
|
6
|
+
export function moneyResultLines(text: string, k: KeptFact): {
|
|
7
|
+
quote: string;
|
|
8
|
+
value: string;
|
|
9
|
+
}[];
|
|
10
|
+
/**
|
|
11
|
+
* Dry-read every kept money fact; drop (as `reads-no-result`) the ones whose forms read no result line. Other facts pass through untouched.
|
|
12
|
+
* @param {string} text the frozen page text @param {KeptFact[]} facts what applyPageRules kept
|
|
13
|
+
* @returns {Promise<{facts: KeptFact[], dropped: Dropped[], reads: Record<string, number>, results: Record<string, number>}>}
|
|
14
|
+
* `reads` / `results` = result lines the checker read / lines found, per fact name (for tests and reports; no verdict derives from the numbers)
|
|
15
|
+
*/
|
|
16
|
+
export function dryReadMoney(text: string, facts: KeptFact[]): Promise<{
|
|
17
|
+
facts: KeptFact[];
|
|
18
|
+
dropped: Dropped[];
|
|
19
|
+
reads: Record<string, number>;
|
|
20
|
+
results: Record<string, number>;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* The same "can it read" for PHRASE facts (hamr ruled 3a, run m10-walk-flights-3: "Rome" was on the page only in "Track prices from Madrid to
|
|
24
|
+
* Rome" switches, in none of the 18 result lines, so no result could ever say it). A kept phrase fact is read against the page's RESULT LINES =
|
|
25
|
+
* the lines the job's kept money facts read (`moneyResultLines`), each graded as an honest claim by the real `gradeStep` (quote = that line;
|
|
26
|
+
* a phrase has no value to write). A phrase that reads no result line is dropped whole as `phrase-no-result` and shows under Not checked.
|
|
27
|
+
* With no kept money fact the result lines are unknown, so phrase facts pass through untouched (nothing is guessed about what a result is).
|
|
28
|
+
* @param {string} text the frozen page text @param {KeptFact[]} facts what the money dry read kept
|
|
29
|
+
* @returns {Promise<{facts: KeptFact[], dropped: Dropped[], reads: Record<string, number>}>} `reads` = result lines that said the phrase, per fact name
|
|
30
|
+
*/
|
|
31
|
+
export function dryReadPhrases(text: string, facts: KeptFact[]): Promise<{
|
|
32
|
+
facts: KeptFact[];
|
|
33
|
+
dropped: Dropped[];
|
|
34
|
+
reads: Record<string, number>;
|
|
35
|
+
}>;
|
|
36
|
+
export type KeptFact = import("./pagerules.js").KeptFact;
|
|
37
|
+
export type Dropped = import("./pagerules.js").Dropped;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the AI is told, for ONE page input. Ported from the POC prompt: the job, the `~` rules, "a result is one item", the answer form
|
|
3
|
+
* and the shape meanings.
|
|
4
|
+
* @param {{jobLines: {n: number, text: string, rule?: string, rules?: string[]}[], label: string, text: string}} o
|
|
5
|
+
* @returns {string}
|
|
6
|
+
*/
|
|
7
|
+
export function mapPrompt({ jobLines, label, text }: {
|
|
8
|
+
jobLines: {
|
|
9
|
+
n: number;
|
|
10
|
+
text: string;
|
|
11
|
+
rule?: string;
|
|
12
|
+
rules?: string[];
|
|
13
|
+
}[];
|
|
14
|
+
label: string;
|
|
15
|
+
text: string;
|
|
16
|
+
}): string;
|
|
17
|
+
/**
|
|
18
|
+
* Read the AI's answer: ONE JSON object of the answer form, and nothing else. No repair (hamr's ruling): text that is not JSON, JSON of
|
|
19
|
+
* another form, or a fact whose shape or lists are not of the form is a malformed answer.
|
|
20
|
+
* @param {unknown} text @returns {{ok: true, mapping: import('./pagerules.js').PageMap}|{ok: false}}
|
|
21
|
+
*/
|
|
22
|
+
export function parseMapAnswer(text: unknown): {
|
|
23
|
+
ok: true;
|
|
24
|
+
mapping: import("./pagerules.js").PageMap;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Run the map: one call per page input.
|
|
30
|
+
* @param {{texts: Record<string, string>, inputs: {n: number, label: string}[], jobLines: {n: number, text: string, rule?: string, rules?: string[]}[],
|
|
31
|
+
* provider?: any, maxTokens?: number, ceilingUsd?: number|null, callTimeoutMs?: number,
|
|
32
|
+
* onCall?: (call: {label: string, costUsd: number|null, unpricedRounds: number, thinkingStatus?: string, raw?: string}) => void,
|
|
33
|
+
* createLoop?: (o: {system: string, onLlmResult: any, provider: any, rates?: {in: number, out: number}}) => any,
|
|
34
|
+
* rates?: {in: number, out: number}|null, callOptions?: Record<string, any>, sleep?: (ms: number) => Promise<void>, prove?: Function}} o
|
|
35
|
+
* @returns {Promise<{state: 'PRESENT'|'ABSENT', facts: any, reason: string|null, cause: string|null, meta: any, raw: string,
|
|
36
|
+
* raws: ReturnType<typeof scrubRaw>[], calls: {label: string, costUsd: number|null, unpricedRounds: number}[],
|
|
37
|
+
* budgetStop: 'cap-halt'|'pricing-red'|null}>}
|
|
38
|
+
*/
|
|
39
|
+
export function runPageMap({ texts, inputs, jobLines, provider, maxTokens, ceilingUsd, callTimeoutMs, onCall, createLoop, rates, callOptions, sleep, }: {
|
|
40
|
+
texts: Record<string, string>;
|
|
41
|
+
inputs: {
|
|
42
|
+
n: number;
|
|
43
|
+
label: string;
|
|
44
|
+
}[];
|
|
45
|
+
jobLines: {
|
|
46
|
+
n: number;
|
|
47
|
+
text: string;
|
|
48
|
+
rule?: string;
|
|
49
|
+
rules?: string[];
|
|
50
|
+
}[];
|
|
51
|
+
provider?: any;
|
|
52
|
+
maxTokens?: number;
|
|
53
|
+
ceilingUsd?: number | null;
|
|
54
|
+
callTimeoutMs?: number;
|
|
55
|
+
onCall?: (call: {
|
|
56
|
+
label: string;
|
|
57
|
+
costUsd: number | null;
|
|
58
|
+
unpricedRounds: number;
|
|
59
|
+
thinkingStatus?: string;
|
|
60
|
+
raw?: string;
|
|
61
|
+
}) => void;
|
|
62
|
+
createLoop?: (o: {
|
|
63
|
+
system: string;
|
|
64
|
+
onLlmResult: any;
|
|
65
|
+
provider: any;
|
|
66
|
+
rates?: {
|
|
67
|
+
in: number;
|
|
68
|
+
out: number;
|
|
69
|
+
};
|
|
70
|
+
}) => any;
|
|
71
|
+
rates?: {
|
|
72
|
+
in: number;
|
|
73
|
+
out: number;
|
|
74
|
+
} | null;
|
|
75
|
+
callOptions?: Record<string, any>;
|
|
76
|
+
sleep?: (ms: number) => Promise<void>;
|
|
77
|
+
prove?: Function;
|
|
78
|
+
}): Promise<{
|
|
79
|
+
state: "PRESENT" | "ABSENT";
|
|
80
|
+
facts: any;
|
|
81
|
+
reason: string | null;
|
|
82
|
+
cause: string | null;
|
|
83
|
+
meta: any;
|
|
84
|
+
raw: string;
|
|
85
|
+
raws: ReturnType<typeof scrubRaw>[];
|
|
86
|
+
calls: {
|
|
87
|
+
label: string;
|
|
88
|
+
costUsd: number | null;
|
|
89
|
+
unpricedRounds: number;
|
|
90
|
+
}[];
|
|
91
|
+
budgetStop: "cap-halt" | "pricing-red" | null;
|
|
92
|
+
}>;
|
|
93
|
+
/** @param {unknown} q a recorded question @returns {string|null} the reading a reading ask proposed, or null when it was another kind of question */
|
|
94
|
+
export function readingOfQuestion(q: unknown): string | null;
|
|
95
|
+
/**
|
|
96
|
+
* PRD v1.107 Part 5b ("the look reads, code asks"): the early asks CODE forces before any paid drafting, from the look's own result. Every `~` rule is
|
|
97
|
+
* one of three kinds:
|
|
98
|
+
* - PAGE: a kept page word carries it (a kept fact with `forRule` and no `reading`): no ask.
|
|
99
|
+
* - READING: a kept fact carries it with a `reading` (a limit the page cannot hold, e.g. "not a red-eye" -> departure time between 06:00 and 21:00).
|
|
100
|
+
* Asked only when a bound of the reading is NOT in the words the person wrote (the same test as `rubric-fact-unmarked`, `boundInWords`); a
|
|
101
|
+
* bound they wrote themselves is theirs and nothing is asked. `agree` writes the reading as a `~` rule in plain words (the answer text is
|
|
102
|
+
* `reading`), so the drafter is told it and the fact signs plain.
|
|
103
|
+
* - CAN'T CHECK: no kept fact carries it (PRD v1.106 Part 5 Q3 T2). `drop it` leaves it Not checked.
|
|
104
|
+
* One ask per rule text on a line; readings first, then can't-check asks, each in line order. The caller applies the machine's cap and the answer gate.
|
|
105
|
+
* @param {{facts?: {line: number, forRule?: number, name?: string, shape?: string, unit?: string[], currency?: string[], reading?: import('./pagerules.js').Reading}[]}|null|undefined} look
|
|
106
|
+
* @param {{n: number, text?: string, rule?: string, rules?: string[]}[]|null|undefined} jobLines
|
|
107
|
+
* @returns {LookAsk[]}
|
|
108
|
+
*/
|
|
109
|
+
export function askableFromLook(look: {
|
|
110
|
+
facts?: {
|
|
111
|
+
line: number;
|
|
112
|
+
forRule?: number;
|
|
113
|
+
name?: string;
|
|
114
|
+
shape?: string;
|
|
115
|
+
unit?: string[];
|
|
116
|
+
currency?: string[];
|
|
117
|
+
reading?: import("./pagerules.js").Reading;
|
|
118
|
+
}[];
|
|
119
|
+
} | null | undefined, jobLines: {
|
|
120
|
+
n: number;
|
|
121
|
+
text?: string;
|
|
122
|
+
rule?: string;
|
|
123
|
+
rules?: string[];
|
|
124
|
+
}[] | null | undefined): LookAsk[];
|
|
125
|
+
/**
|
|
126
|
+
* PRD v1.107 Part 5b: more asks than the machine's cap means the job needs a rewrite, not a questionnaire. The code-owned stop words list EVERY ask and
|
|
127
|
+
* its reading as the suggestion (no extra paid call). A secret in a rule is masked.
|
|
128
|
+
* @param {LookAsk[]} asks @returns {string}
|
|
129
|
+
*/
|
|
130
|
+
export function tooManyAsksText(asks: LookAsk[]): string;
|
|
131
|
+
/** the label of the one paid call, as the drafting book and the progress line see it */
|
|
132
|
+
export const MAP_CALL_LABEL: "page-map";
|
|
133
|
+
/** the shapes the map may name; a `place` is read by code as a phrase */
|
|
134
|
+
export const MAP_SHAPES: readonly string[];
|
|
135
|
+
export const MAP_SYSTEM: "You map a person's job to the exact words of ONE saved web page. You never grade and never invent words: every string you return must be copied from the page text, character for character.";
|
|
136
|
+
/** the plain-word stop when the answer was not readable twice (no Resume: a draft is not a run) */
|
|
137
|
+
export const MAP_UNREADABLE: "The AI's answer about the page was not readable twice. Nothing was signed.";
|
|
138
|
+
/** the answer that drops a `~` rule the page cannot check: the person types it (any case, a closing full stop allowed) */
|
|
139
|
+
export const DROP_IT: "drop it";
|
|
140
|
+
export function isDropIt(text: unknown): boolean;
|
|
141
|
+
export function isAgree(text: unknown): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* `reading` = the plain words an `agree` writes as a `~` rule (a reading ask only)
|
|
144
|
+
*/
|
|
145
|
+
export type LookAsk = {
|
|
146
|
+
line: number;
|
|
147
|
+
rule: number;
|
|
148
|
+
source: "look";
|
|
149
|
+
question: string;
|
|
150
|
+
ask: "reading" | "cant-check";
|
|
151
|
+
ruleText: string;
|
|
152
|
+
reading?: string;
|
|
153
|
+
};
|
|
154
|
+
import { scrubRaw } from './text.js';
|