@garygentry/system1-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +13 -0
- package/dist/config/consent.d.ts +11 -0
- package/dist/config/consent.d.ts.map +1 -0
- package/dist/config/consent.js +33 -0
- package/dist/config/consent.js.map +1 -0
- package/dist/config/load.d.ts +64 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +216 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/session.d.ts +31 -0
- package/dist/config/session.d.ts.map +1 -0
- package/dist/config/session.js +36 -0
- package/dist/config/session.js.map +1 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +64 -0
- package/dist/config.js.map +1 -0
- package/dist/decide.d.ts +57 -0
- package/dist/decide.d.ts.map +1 -0
- package/dist/decide.js +87 -0
- package/dist/decide.js.map +1 -0
- package/dist/egress/exclude.d.ts +24 -0
- package/dist/egress/exclude.d.ts.map +1 -0
- package/dist/egress/exclude.js +60 -0
- package/dist/egress/exclude.js.map +1 -0
- package/dist/egress/scrub.d.ts +12 -0
- package/dist/egress/scrub.d.ts.map +1 -0
- package/dist/egress/scrub.js +84 -0
- package/dist/egress/scrub.js.map +1 -0
- package/dist/egress/size.d.ts +16 -0
- package/dist/egress/size.d.ts.map +1 -0
- package/dist/egress/size.js +25 -0
- package/dist/egress/size.js.map +1 -0
- package/dist/errors.d.ts +44 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +23 -0
- package/dist/errors.js.map +1 -0
- package/dist/fixtures/store.d.ts +34 -0
- package/dist/fixtures/store.d.ts.map +1 -0
- package/dist/fixtures/store.js +74 -0
- package/dist/fixtures/store.js.map +1 -0
- package/dist/index.d.ts +59 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/model/answers.d.ts +38 -0
- package/dist/model/answers.d.ts.map +1 -0
- package/dist/model/answers.js +48 -0
- package/dist/model/answers.js.map +1 -0
- package/dist/model/profiles.d.ts +39 -0
- package/dist/model/profiles.d.ts.map +1 -0
- package/dist/model/profiles.js +42 -0
- package/dist/model/profiles.js.map +1 -0
- package/dist/model/types.d.ts +107 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +17 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validate.d.ts +17 -0
- package/dist/model/validate.d.ts.map +1 -0
- package/dist/model/validate.js +151 -0
- package/dist/model/validate.js.map +1 -0
- package/dist/ping.d.ts +30 -0
- package/dist/ping.d.ts.map +1 -0
- package/dist/ping.js +50 -0
- package/dist/ping.js.map +1 -0
- package/dist/prepare.d.ts +39 -0
- package/dist/prepare.d.ts.map +1 -0
- package/dist/prepare.js +84 -0
- package/dist/prepare.js.map +1 -0
- package/dist/project/project.d.ts +64 -0
- package/dist/project/project.d.ts.map +1 -0
- package/dist/project/project.js +144 -0
- package/dist/project/project.js.map +1 -0
- package/dist/run/budget.d.ts +20 -0
- package/dist/run/budget.d.ts.map +1 -0
- package/dist/run/budget.js +31 -0
- package/dist/run/budget.js.map +1 -0
- package/dist/run/pool.d.ts +16 -0
- package/dist/run/pool.d.ts.map +1 -0
- package/dist/run/pool.js +35 -0
- package/dist/run/pool.js.map +1 -0
- package/dist/run/spend.d.ts +34 -0
- package/dist/run/spend.d.ts.map +1 -0
- package/dist/run/spend.js +55 -0
- package/dist/run/spend.js.map +1 -0
- package/dist/sources/read.d.ts +40 -0
- package/dist/sources/read.d.ts.map +1 -0
- package/dist/sources/read.js +294 -0
- package/dist/sources/read.js.map +1 -0
- package/dist/sources/types.d.ts +79 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +2 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/spec/expect.d.ts +39 -0
- package/dist/spec/expect.d.ts.map +1 -0
- package/dist/spec/expect.js +95 -0
- package/dist/spec/expect.js.map +1 -0
- package/dist/spec/spec.d.ts +90 -0
- package/dist/spec/spec.d.ts.map +1 -0
- package/dist/spec/spec.js +252 -0
- package/dist/spec/spec.js.map +1 -0
- package/dist/split/split.d.ts +33 -0
- package/dist/split/split.d.ts.map +1 -0
- package/dist/split/split.js +116 -0
- package/dist/split/split.js.map +1 -0
- package/dist/testdata/index.d.ts +5 -0
- package/dist/testdata/index.d.ts.map +1 -0
- package/dist/testdata/index.js +6 -0
- package/dist/testdata/index.js.map +1 -0
- package/dist/testkit/fake-model.d.ts +14 -0
- package/dist/testkit/fake-model.d.ts.map +1 -0
- package/dist/testkit/fake-model.js +57 -0
- package/dist/testkit/fake-model.js.map +1 -0
- package/dist/testkit/tmp.d.ts +6 -0
- package/dist/testkit/tmp.d.ts.map +1 -0
- package/dist/testkit/tmp.js +46 -0
- package/dist/testkit/tmp.js.map +1 -0
- package/dist/tools/ask.d.ts +32 -0
- package/dist/tools/ask.d.ts.map +1 -0
- package/dist/tools/ask.js +59 -0
- package/dist/tools/ask.js.map +1 -0
- package/dist/tools/context.d.ts +52 -0
- package/dist/tools/context.d.ts.map +1 -0
- package/dist/tools/context.js +130 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/doctor.d.ts +37 -0
- package/dist/tools/doctor.d.ts.map +1 -0
- package/dist/tools/doctor.js +203 -0
- package/dist/tools/doctor.js.map +1 -0
- package/dist/tools/many.d.ts +74 -0
- package/dist/tools/many.d.ts.map +1 -0
- package/dist/tools/many.js +141 -0
- package/dist/tools/many.js.map +1 -0
- package/dist/tools/schemas.d.ts +293 -0
- package/dist/tools/schemas.d.ts.map +1 -0
- package/dist/tools/schemas.js +112 -0
- package/dist/tools/schemas.js.map +1 -0
- package/dist/tools/spec-check.d.ts +48 -0
- package/dist/tools/spec-check.d.ts.map +1 -0
- package/dist/tools/spec-check.js +164 -0
- package/dist/tools/spec-check.js.map +1 -0
- package/dist/tools/usage.d.ts +11 -0
- package/dist/tools/usage.d.ts.map +1 -0
- package/dist/tools/usage.js +27 -0
- package/dist/tools/usage.js.map +1 -0
- package/dist/transport/openrouter.d.ts +38 -0
- package/dist/transport/openrouter.d.ts.map +1 -0
- package/dist/transport/openrouter.js +89 -0
- package/dist/transport/openrouter.js.map +1 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/dist/wiring.d.ts +30 -0
- package/dist/wiring.d.ts.map +1 -0
- package/dist/wiring.js +31 -0
- package/dist/wiring.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { assertConsent } from "../config/consent.js";
|
|
2
|
+
import { allProfiles } from "../config/load.js";
|
|
3
|
+
import { DecisionsError, isDecisionsError } from "../errors.js";
|
|
4
|
+
import { resolveProfile } from "../model/profiles.js";
|
|
5
|
+
import { prepare } from "../prepare.js";
|
|
6
|
+
import { checkBudget, project } from "../run/budget.js";
|
|
7
|
+
import { sumUsage } from "../run/spend.js";
|
|
8
|
+
import { parseFileRef } from "../sources/read.js";
|
|
9
|
+
import { describeExpectation, meets, parseExpect } from "../spec/expect.js";
|
|
10
|
+
import { assertExamples, exampleFileProblem, loadSpec } from "../spec/spec.js";
|
|
11
|
+
import { parseSplit } from "../split/split.js";
|
|
12
|
+
import { checkInput, deciderFor } from "./context.js";
|
|
13
|
+
import { summariseSkipped } from "./many.js";
|
|
14
|
+
/**
|
|
15
|
+
* Run a spec's examples and compare each against its `expect`. Replay by
|
|
16
|
+
* default: this is an offline regression test for a spec and the fixtures
|
|
17
|
+
* committed beside it. `mode: "record"` captures fresh answers.
|
|
18
|
+
*
|
|
19
|
+
* A mismatch is a result (`passed: false`), not an error. Errors are reserved
|
|
20
|
+
* for a spec that cannot be checked: no examples, or answers never recorded.
|
|
21
|
+
*/
|
|
22
|
+
export async function runSpecCheck(ctx, rawInput) {
|
|
23
|
+
const input = checkInput("spec-check", rawInput);
|
|
24
|
+
const spec = loadSpec(input.spec, ctx.specDirs, ctx.cwd);
|
|
25
|
+
const examples = spec.examples ?? [];
|
|
26
|
+
if (examples.length === 0) {
|
|
27
|
+
throw new DecisionsError("invalid-request", `Spec "${spec.name}" has no examples to check. Add some under examples: (id, state or file, expect).`);
|
|
28
|
+
}
|
|
29
|
+
// Structural problems (a bad expect, a duplicate id) make the spec
|
|
30
|
+
// uncheckable. A problem with one example's file only withholds that one.
|
|
31
|
+
assertExamples(spec);
|
|
32
|
+
const profile = resolveProfile(input.model ?? ctx.config.model, allProfiles(ctx.config));
|
|
33
|
+
const root = ctx.config.repoRoot;
|
|
34
|
+
const prepared = [];
|
|
35
|
+
for (const example of examples) {
|
|
36
|
+
const expect = example.expect ? parseExpect(example.expect, spec.questions, example.id) : {};
|
|
37
|
+
const refused = example.file !== undefined ? exampleFileProblem(example.file, root) : undefined;
|
|
38
|
+
if (refused) {
|
|
39
|
+
prepared.push({ id: example.id, expect, reason: `${example.file} ${refused}` });
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const source = example.file !== undefined
|
|
43
|
+
? { kind: "file", ...parseFileRef(example.file) }
|
|
44
|
+
: {
|
|
45
|
+
kind: "text",
|
|
46
|
+
// A structured state is sent as its JSON text.
|
|
47
|
+
text: typeof example.state === "string" ? example.state : JSON.stringify(example.state),
|
|
48
|
+
id: example.id,
|
|
49
|
+
};
|
|
50
|
+
try {
|
|
51
|
+
const prep = await prepare({
|
|
52
|
+
sources: [source],
|
|
53
|
+
split: parseSplit("file"),
|
|
54
|
+
questions: spec.questions,
|
|
55
|
+
profile,
|
|
56
|
+
cwd: root,
|
|
57
|
+
exclude: ctx.config.egress.exclude,
|
|
58
|
+
});
|
|
59
|
+
const [item, ...rest] = prep.items;
|
|
60
|
+
const why = prep.skipped[0];
|
|
61
|
+
prepared.push(item && rest.length === 0
|
|
62
|
+
? { id: example.id, expect, prep }
|
|
63
|
+
: {
|
|
64
|
+
id: example.id,
|
|
65
|
+
expect,
|
|
66
|
+
reason: why ? `${why.path} ${why.reason}` : `gave ${prep.items.length} states, not 1`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// An oversized or unreadable example is that example's problem, not the run's.
|
|
71
|
+
if (!isDecisionsError(error) || !["state-too-large", "source-error"].includes(error.code)) {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
prepared.push({ id: example.id, expect, reason: error.message.split("\n")[0] });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const decider = deciderFor(ctx, profile, input.mode ?? "replay");
|
|
78
|
+
if (decider.mode !== "replay") {
|
|
79
|
+
assertConsent(ctx.config.egress.consent, root);
|
|
80
|
+
const tokens = prepared.flatMap((p) => (p.prep ? [p.prep.projection.estimatedInputTokens] : []));
|
|
81
|
+
checkBudget(project(profile, tokens), ctx.config.budget, input.confirm ?? false);
|
|
82
|
+
}
|
|
83
|
+
const results = [];
|
|
84
|
+
const usages = [];
|
|
85
|
+
let misses = 0;
|
|
86
|
+
for (const { id, expect, prep, reason } of prepared) {
|
|
87
|
+
const item = prep?.items[0];
|
|
88
|
+
if (!prep || !item) {
|
|
89
|
+
results.push({ id, status: "withheld", reason: reason ?? "not sent" });
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const r = await decider.decide({
|
|
94
|
+
state: item.state,
|
|
95
|
+
questions: spec.questions,
|
|
96
|
+
namespace: spec.name,
|
|
97
|
+
});
|
|
98
|
+
usages.push(r.usage);
|
|
99
|
+
results.push(judge(id, r.answers, r.undecided, expect));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
if (isDecisionsError(error) && error.code === "replay-miss") {
|
|
103
|
+
misses += 1;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (misses > 0) {
|
|
110
|
+
throw new DecisionsError("replay-miss", `${misses} of ${examples.length} examples of "${spec.name}" have no recorded answer. Record them with \`decide spec check ${spec.name} --live\` (needs a key and repo consent).`, { misses });
|
|
111
|
+
}
|
|
112
|
+
const counts = {
|
|
113
|
+
examples: results.length,
|
|
114
|
+
pass: 0,
|
|
115
|
+
fail: 0,
|
|
116
|
+
undecided: 0,
|
|
117
|
+
captured: 0,
|
|
118
|
+
withheld: 0,
|
|
119
|
+
};
|
|
120
|
+
for (const r of results)
|
|
121
|
+
counts[r.status] += 1;
|
|
122
|
+
return {
|
|
123
|
+
spec: spec.name,
|
|
124
|
+
file: spec.file,
|
|
125
|
+
model: profile.id,
|
|
126
|
+
source: decider.mode === "replay" ? "replay" : "live",
|
|
127
|
+
passed: counts.fail === 0 && counts.undecided === 0 && counts.withheld === 0,
|
|
128
|
+
counts,
|
|
129
|
+
examples: results,
|
|
130
|
+
usage: sumUsage(usages),
|
|
131
|
+
skipped: summariseSkipped(prepared.flatMap((p) => p.prep?.skipped ?? [])),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function judge(id, answers, flat, expect) {
|
|
135
|
+
const entries = Object.entries(expect);
|
|
136
|
+
if (entries.length === 0) {
|
|
137
|
+
return { id, status: "captured", answers, ...(flat.length ? { undecided: flat } : {}) };
|
|
138
|
+
}
|
|
139
|
+
const failures = [];
|
|
140
|
+
const undecided = [];
|
|
141
|
+
for (const [question, expectation] of entries) {
|
|
142
|
+
const answer = answers[question];
|
|
143
|
+
const isFlat = flat.includes(question);
|
|
144
|
+
if (expectation.kind === "undecided") {
|
|
145
|
+
if (!isFlat)
|
|
146
|
+
failures.push({ question, expected: "undecided" });
|
|
147
|
+
}
|
|
148
|
+
else if (isFlat) {
|
|
149
|
+
undecided.push(question);
|
|
150
|
+
}
|
|
151
|
+
else if (!answer || !meets(question, answer, expectation)) {
|
|
152
|
+
failures.push({ question, expected: describeExpectation(expectation) });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const status = failures.length ? "fail" : undecided.length ? "undecided" : "pass";
|
|
156
|
+
return {
|
|
157
|
+
id,
|
|
158
|
+
status,
|
|
159
|
+
answers,
|
|
160
|
+
...(failures.length ? { failures } : {}),
|
|
161
|
+
...(undecided.length ? { undecided } : {}),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=spec-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-check.js","sourceRoot":"","sources":["../../src/tools/spec-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SpendSummary } from "../run/spend.js";
|
|
2
|
+
import { type ToolContext } from "./context.js";
|
|
3
|
+
export interface UsageResult extends SpendSummary {
|
|
4
|
+
/** Every figure is measured from upstream `usage` blocks. */
|
|
5
|
+
basis: "measured";
|
|
6
|
+
ledger: string;
|
|
7
|
+
session?: string;
|
|
8
|
+
since?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function runUsage(ctx: ToolContext, rawInput?: unknown): UsageResult;
|
|
11
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/tools/usage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAyB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAGtE,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,6DAA6D;IAC7D,KAAK,EAAE,UAAU,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,GAAE,OAAY,GAAG,WAAW,CAkB9E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DecisionsError } from "../errors.js";
|
|
2
|
+
import { checkInput, ledgerFor } from "./context.js";
|
|
3
|
+
export function runUsage(ctx, rawInput = {}) {
|
|
4
|
+
const input = checkInput("usage", rawInput);
|
|
5
|
+
const since = input.since ? new Date(input.since) : undefined;
|
|
6
|
+
if (since && Number.isNaN(since.getTime())) {
|
|
7
|
+
throw new DecisionsError("invalid-request", `--since "${input.since}" is not a date`);
|
|
8
|
+
}
|
|
9
|
+
const session = input.session === "current" ? currentSession(ctx) : input.session;
|
|
10
|
+
const ledger = ledgerFor(ctx);
|
|
11
|
+
return {
|
|
12
|
+
basis: "measured",
|
|
13
|
+
...ledger.summary({
|
|
14
|
+
...(session ? { session } : {}),
|
|
15
|
+
...(since ? { since } : {}),
|
|
16
|
+
}),
|
|
17
|
+
ledger: ledger.file,
|
|
18
|
+
...(session ? { session } : {}),
|
|
19
|
+
...(input.since ? { since: input.since } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function currentSession(ctx) {
|
|
23
|
+
if (ctx.config.session)
|
|
24
|
+
return ctx.config.session;
|
|
25
|
+
throw new DecisionsError("invalid-request", "no current session: not running under Claude Code, Codex or Pi, and SYSTEM1_SESSION is not set");
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/tools/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAoB,MAAM,cAAc,CAAA;AAWtE,MAAM,UAAU,QAAQ,CAAC,GAAgB,EAAE,QAAQ,GAAY,EAAE;IAC/D,MAAM,KAAK,GAAG,UAAU,CAAa,OAAO,EAAE,QAAQ,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7D,IAAI,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,cAAc,CAAC,iBAAiB,EAAE,YAAY,KAAK,CAAC,KAAK,iBAAiB,CAAC,CAAA;IACvF,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;IACjF,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAA;IAC7B,OAAO;QACL,KAAK,EAAE,UAAU;QACjB,GAAG,MAAM,CAAC,OAAO,CAAC;YAChB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5B,CAAC;QACF,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/C,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAgB;IACtC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAA;IACjD,MAAM,IAAI,cAAc,CACtB,iBAAiB,EACjB,gGAAgG,CACjG,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { DecisionRequest, DecisionResponse } from "../model/types.js";
|
|
2
|
+
export declare const DEFAULT_ENDPOINT = "https://openrouter.ai/api/alpha/decisions";
|
|
3
|
+
export declare const DEFAULT_TIMEOUT_MS = 5000;
|
|
4
|
+
/** Statuses worth another attempt: timeouts, rate limits and upstream hiccups. */
|
|
5
|
+
export declare const RETRY_STATUSES: ReadonlySet<number>;
|
|
6
|
+
export interface TransportOptions {
|
|
7
|
+
/** OpenRouter's decisions endpoint. An alpha path, so overridable. */
|
|
8
|
+
endpoint?: string;
|
|
9
|
+
apiKey: string;
|
|
10
|
+
/**
|
|
11
|
+
* Per attempt, not per call. Default 5 s: a normal decision call measured
|
|
12
|
+
* 225–650 ms, but upstream occasionally stalls a request with no response at
|
|
13
|
+
* all (seen live, 2026-09-22). The old 30 s default turned one stall into a
|
|
14
|
+
* 30 s fan-out; a timeout sized to the model makes a stall cost one retry.
|
|
15
|
+
*/
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
maxAttempts?: number;
|
|
18
|
+
/** First backoff; doubles on each retry. */
|
|
19
|
+
backoffMs?: number;
|
|
20
|
+
fetch?: typeof fetch;
|
|
21
|
+
sleep?: (ms: number) => Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
export interface TransportResult {
|
|
24
|
+
response: DecisionResponse;
|
|
25
|
+
/** Measured round trip across all attempts. */
|
|
26
|
+
latencyMs: number;
|
|
27
|
+
attempts: number;
|
|
28
|
+
}
|
|
29
|
+
export interface Transport {
|
|
30
|
+
decide(request: DecisionRequest, signal?: AbortSignal): Promise<TransportResult>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The `openrouter-decisions` transport: POSTs one decision request, with retry,
|
|
34
|
+
* exponential backoff, a timeout per attempt and caller abort, and validates
|
|
35
|
+
* the body strictly before anything downstream trusts it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createOpenRouterTransport(options: TransportOptions): Transport;
|
|
38
|
+
//# sourceMappingURL=openrouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.d.ts","sourceRoot":"","sources":["../../src/transport/openrouter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAG1E,eAAO,MAAM,gBAAgB,8CAA8C,CAAA;AAE3E,eAAO,MAAM,kBAAkB,OAAQ,CAAA;AAEvC,kFAAkF;AAClF,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAE7C,CAAA;AAEF,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;IACpB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CACjF;AAID;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA6E9E"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ProviderError } from "../errors.js";
|
|
2
|
+
import { parseDecisionResponse } from "../model/validate.js";
|
|
3
|
+
export const DEFAULT_ENDPOINT = "https://openrouter.ai/api/alpha/decisions";
|
|
4
|
+
export const DEFAULT_TIMEOUT_MS = 5_000;
|
|
5
|
+
/** Statuses worth another attempt: timeouts, rate limits and upstream hiccups. */
|
|
6
|
+
export const RETRY_STATUSES = new Set([
|
|
7
|
+
408, 429, 500, 502, 503, 504, 520, 521, 522, 524,
|
|
8
|
+
]);
|
|
9
|
+
const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
/**
|
|
11
|
+
* The `openrouter-decisions` transport: POSTs one decision request, with retry,
|
|
12
|
+
* exponential backoff, a timeout per attempt and caller abort, and validates
|
|
13
|
+
* the body strictly before anything downstream trusts it.
|
|
14
|
+
*/
|
|
15
|
+
export function createOpenRouterTransport(options) {
|
|
16
|
+
const endpoint = options.endpoint ?? DEFAULT_ENDPOINT;
|
|
17
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
18
|
+
const maxAttempts = Math.max(1, options.maxAttempts ?? 3);
|
|
19
|
+
const backoffMs = options.backoffMs ?? 400;
|
|
20
|
+
const doFetch = options.fetch ?? fetch;
|
|
21
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
22
|
+
return {
|
|
23
|
+
async decide(request, signal) {
|
|
24
|
+
const startedAt = performance.now();
|
|
25
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
26
|
+
// One timeout per attempt, linked to the caller's signal so an abort
|
|
27
|
+
// cancels the in-flight fetch rather than being ignored.
|
|
28
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
29
|
+
const composite = signal ? AbortSignal.any([signal, timeout]) : timeout;
|
|
30
|
+
const last = attempt === maxAttempts;
|
|
31
|
+
const wait = () => sleep(backoffMs * 2 ** (attempt - 1));
|
|
32
|
+
let response;
|
|
33
|
+
try {
|
|
34
|
+
response = await doFetch(endpoint, {
|
|
35
|
+
method: "POST",
|
|
36
|
+
headers: {
|
|
37
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
"HTTP-Referer": "https://github.com/garygentry/system1",
|
|
40
|
+
"X-Title": "system1",
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify(request),
|
|
43
|
+
signal: composite,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// A caller abort means the answer is no longer wanted: not retried.
|
|
48
|
+
if (signal?.aborted)
|
|
49
|
+
throw error;
|
|
50
|
+
if (last) {
|
|
51
|
+
throw new ProviderError("provider-unreachable", `Could not reach ${endpoint}: ${describe(error)}`);
|
|
52
|
+
}
|
|
53
|
+
await wait();
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
const detail = (await response.text()).slice(0, 500);
|
|
58
|
+
if (!RETRY_STATUSES.has(response.status) || last) {
|
|
59
|
+
throw new ProviderError("provider-http", `${endpoint} returned ${response.status}: ${detail}`, response.status);
|
|
60
|
+
}
|
|
61
|
+
await wait();
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
let raw;
|
|
65
|
+
try {
|
|
66
|
+
raw = await response.json();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
throw new ProviderError("malformed-response", `${endpoint} returned a body that is not JSON`);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
response: parseDecisionResponse(raw, request.questions, request.model),
|
|
73
|
+
latencyMs: Math.round(performance.now() - startedAt),
|
|
74
|
+
attempts: attempt,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Unreachable: the last attempt always returns or throws.
|
|
78
|
+
throw new ProviderError("provider-unreachable", `Could not reach ${endpoint}`);
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function describe(error) {
|
|
83
|
+
if (error instanceof Error) {
|
|
84
|
+
const cause = error.cause;
|
|
85
|
+
return cause instanceof Error ? `${error.message}: ${cause.message}` : error.message;
|
|
86
|
+
}
|
|
87
|
+
return String(error);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/transport/openrouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,OAAO,UAAU,CAAA;AAC9B,8CAA8C;AAC9C,eAAO,MAAM,WAAW,wBAAwB,CAAA"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA;AAC9B,8CAA8C;AAC9C,MAAM,CAAC,MAAM,WAAW,GAAG,qBAAqB,CAAA"}
|
package/dist/wiring.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience wiring for callers outside the tool layer (scripts, tests).
|
|
3
|
+
*
|
|
4
|
+
* The engine never reads a `.env` file: a project's `.env` belongs to that
|
|
5
|
+
* project, not to us.
|
|
6
|
+
*/
|
|
7
|
+
import type { DecideMode, Decider } from "./decide.js";
|
|
8
|
+
export { stateDir } from "./config/load.js";
|
|
9
|
+
export { DEFAULT_ENDPOINT } from "./transport/openrouter.js";
|
|
10
|
+
export declare const DEFAULT_MODEL = "typesafe/jev-1.13";
|
|
11
|
+
export interface ConnectionConfig {
|
|
12
|
+
endpoint: string;
|
|
13
|
+
model: string;
|
|
14
|
+
/** Never printed; only its presence is ever reported. */
|
|
15
|
+
apiKey: string | undefined;
|
|
16
|
+
/** `SYSTEM1_REPLAY` forces replay even when a key is present. */
|
|
17
|
+
replay: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** Env-only connection settings, for `ping` (which must work with no config at all). */
|
|
20
|
+
export declare function resolveConnection(env?: NodeJS.ProcessEnv): ConnectionConfig;
|
|
21
|
+
export interface EnvDeciderOptions {
|
|
22
|
+
cwd?: string;
|
|
23
|
+
env?: NodeJS.ProcessEnv;
|
|
24
|
+
home?: string;
|
|
25
|
+
mode?: DecideMode;
|
|
26
|
+
fetch?: typeof fetch;
|
|
27
|
+
}
|
|
28
|
+
/** A decider from layered config, as the tools build one. */
|
|
29
|
+
export declare function createDeciderFromEnv(options?: EnvDeciderOptions): Decider;
|
|
30
|
+
//# sourceMappingURL=wiring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiring.d.ts","sourceRoot":"","sources":["../src/wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAKtD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,eAAO,MAAM,aAAa,sBAAmB,CAAA;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,iEAAiE;IACjE,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAOxF;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAA;CACrB;AAED,6DAA6D;AAC7D,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAG7E"}
|
package/dist/wiring.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience wiring for callers outside the tool layer (scripts, tests).
|
|
3
|
+
*
|
|
4
|
+
* The engine never reads a `.env` file: a project's `.env` belongs to that
|
|
5
|
+
* project, not to us.
|
|
6
|
+
*/
|
|
7
|
+
import { allProfiles } from "./config/load.js";
|
|
8
|
+
import { DEFAULT_MODEL_ID, resolveProfile } from "./model/profiles.js";
|
|
9
|
+
import { createContext, deciderFor } from "./tools/context.js";
|
|
10
|
+
import { DEFAULT_ENDPOINT } from "./transport/openrouter.js";
|
|
11
|
+
export { stateDir } from "./config/load.js";
|
|
12
|
+
export { DEFAULT_ENDPOINT } from "./transport/openrouter.js";
|
|
13
|
+
export const DEFAULT_MODEL = DEFAULT_MODEL_ID;
|
|
14
|
+
/** Env-only connection settings, for `ping` (which must work with no config at all). */
|
|
15
|
+
export function resolveConnection(env = process.env) {
|
|
16
|
+
return {
|
|
17
|
+
endpoint: nonEmpty(env.SYSTEM1_ENDPOINT) ?? DEFAULT_ENDPOINT,
|
|
18
|
+
model: nonEmpty(env.SYSTEM1_MODEL) ?? DEFAULT_MODEL,
|
|
19
|
+
apiKey: nonEmpty(env.OPENROUTER_API_KEY),
|
|
20
|
+
replay: /^(1|true|yes)$/i.test(env.SYSTEM1_REPLAY ?? ""),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** A decider from layered config, as the tools build one. */
|
|
24
|
+
export function createDeciderFromEnv(options = {}) {
|
|
25
|
+
const ctx = createContext(options);
|
|
26
|
+
return deciderFor(ctx, resolveProfile(ctx.config.model, allProfiles(ctx.config)), options.mode);
|
|
27
|
+
}
|
|
28
|
+
function nonEmpty(value) {
|
|
29
|
+
return value === undefined || value.trim() === "" ? undefined : value.trim();
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=wiring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiring.js","sourceRoot":"","sources":["../src/wiring.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACtE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAA;AAW7C,wFAAwF;AACxF,MAAM,UAAU,iBAAiB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACpE,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,gBAAgB;QAC5D,KAAK,EAAE,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,aAAa;QACnD,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAC;QACxC,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;KACzD,CAAA;AACH,CAAC;AAUD,6DAA6D;AAC7D,MAAM,UAAU,oBAAoB,CAAC,OAAO,GAAsB,EAAE;IAClE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;IAClC,OAAO,UAAU,CAAC,GAAG,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;AACjG,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB;IACzC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;AAC9E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@garygentry/system1-core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Engine for decision-model calls: model profiles, transport, sources, fixtures, spend.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Gary Gentry",
|
|
10
|
+
"email": "gary@garygentry.net"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/garygentry/system1",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"decisions",
|
|
15
|
+
"decision-model",
|
|
16
|
+
"jev",
|
|
17
|
+
"classification",
|
|
18
|
+
"triage",
|
|
19
|
+
"agents",
|
|
20
|
+
"library"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/garygentry/system1",
|
|
25
|
+
"directory": "packages/core"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=22"
|
|
29
|
+
},
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"default": "./dist/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./errors": {
|
|
36
|
+
"types": "./dist/errors.d.ts",
|
|
37
|
+
"default": "./dist/errors.js"
|
|
38
|
+
},
|
|
39
|
+
"./version": {
|
|
40
|
+
"types": "./dist/version.d.ts",
|
|
41
|
+
"default": "./dist/version.js"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -b",
|
|
49
|
+
"prepublishOnly": "node ../../tools/prepublish-check.mjs"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"picomatch": "^4.0.7",
|
|
53
|
+
"tinyglobby": "^0.2.17",
|
|
54
|
+
"typebox": "^1.3.34",
|
|
55
|
+
"yaml": "^2.9.1"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/picomatch": "^4.0.3"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|