typesafe-gates 0.1.0 → 0.2.1
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 +37 -14
- package/dist/gate.d.ts +3 -1
- package/dist/gate.d.ts.map +1 -1
- package/dist/gate.js.map +1 -1
- package/dist/gates/inbound-screen.d.ts +13 -4
- package/dist/gates/inbound-screen.d.ts.map +1 -1
- package/dist/gates/inbound-screen.js +22 -7
- package/dist/gates/inbound-screen.js.map +1 -1
- package/dist/gates/locality.d.ts +3 -1
- package/dist/gates/locality.d.ts.map +1 -1
- package/dist/gates/locality.js +6 -1
- package/dist/gates/locality.js.map +1 -1
- package/dist/judge.d.ts +3 -3
- package/dist/judge.d.ts.map +1 -1
- package/dist/judge.js +12 -4
- package/dist/judge.js.map +1 -1
- package/dist/usage.d.ts +2 -0
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js.map +1 -1
- package/package.json +9 -7
package/README.md
CHANGED
|
@@ -30,6 +30,9 @@ could fail (a whole batch silently dropped), the model could soft-refuse (a
|
|
|
30
30
|
polite decline parses as nothing), and there was no signal for *how* relevant
|
|
31
31
|
an item was, so a threshold was prompt wording instead of a number.
|
|
32
32
|
|
|
33
|
+
The long version of where these gates came from, with the audit numbers
|
|
34
|
+
behind each threshold, is in [docs/seven-production-gates.md](docs/seven-production-gates.md).
|
|
35
|
+
|
|
33
36
|
## Install
|
|
34
37
|
|
|
35
38
|
```sh
|
|
@@ -78,6 +81,17 @@ A gate declares four things:
|
|
|
78
81
|
the common shapes: `verdictsOrNull` (fail-open), `verdictOrNull` (one item),
|
|
79
82
|
`verdictsOr(result, reason => fallback)` (fail-closed).
|
|
80
83
|
|
|
84
|
+
The policy covers the judge being unavailable, not bugs in your gate. If
|
|
85
|
+
`state` or `interpret` throws (for example on a malformed webhook payload),
|
|
86
|
+
`run` rejects with that error. A fail-closed caller should catch it and take
|
|
87
|
+
the same conservative path:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const decision = await inboundScreenGate
|
|
91
|
+
.runOne(judge, email, inbox)
|
|
92
|
+
.then(inboundDecision, () => ({ action: "hold", reason: "screen_error", alert: true }) as const);
|
|
93
|
+
```
|
|
94
|
+
|
|
81
95
|
## The judge
|
|
82
96
|
|
|
83
97
|
`createJudge(config)` returns a function that asks the same questions of every
|
|
@@ -93,10 +107,10 @@ order.
|
|
|
93
107
|
- **Time budget.** `budgetMs` aborts everything in flight and returns
|
|
94
108
|
`over_budget`. Use it on request-path gates (a webhook with a 20 s limit).
|
|
95
109
|
- **Usage accounting.** `recordUsage` receives one record per invocation with
|
|
96
|
-
tokens, request count, estimated cost, task name, model, and
|
|
97
|
-
called even when the invocation failed, because tokens
|
|
98
|
-
failure were billed.
|
|
99
|
-
never fails a gate.
|
|
110
|
+
tokens, request count, estimated cost, duration, task name, model, and
|
|
111
|
+
`failed`. It is called even when the invocation failed, because tokens
|
|
112
|
+
spent before a failure were billed. It is not awaited, and a throwing
|
|
113
|
+
recorder is logged and swallowed: telemetry never fails or delays a gate.
|
|
100
114
|
- **No client, no judgment.** With `TYPESAFE_API_KEY` unset the judge returns
|
|
101
115
|
`no_client`. It never decides what that means for a gate.
|
|
102
116
|
|
|
@@ -125,7 +139,7 @@ context argument.
|
|
|
125
139
|
| `candidateGate(categories, fallback)` | relevance + newsworthiness (Score) + category (Choice) in one request; `rankCandidates` picks the top N | fail-open | as above; filler dropped at P ≥ 0.5 |
|
|
126
140
|
| `localityGate` | Score, 4 levels: not local / statewide / nearby / hyperlocal; `pickLocalFirst` builds a local-first pool | fail-open | `LOCALITY_MIN_PROBABILITY` (0.5), `LOCALITY_POOL_TARGET` (12, 8 to 30), `SOURCE_LOCALITY_MIN_LEVEL` (0.5) |
|
|
127
141
|
| `menuPageGate` | yes/no: is this page a restaurant's menu | fail-open | `MENU_MIN_PROBABILITY` (0.4) |
|
|
128
|
-
| `inboundScreenGate` | intent (Choice, 7 labels) + AI-directed-instruction injection (yes/no); `decideInboundAction` is the policy table | **fail-closed** | fixed: hold at P(injection) ≥ 0.3, auto-reply at P(sales) ≥ 0.7, silent spam at ≥ 0.8 |
|
|
142
|
+
| `inboundScreenGate` | intent (Choice, 7 labels) + AI-directed-instruction injection (yes/no); `decideInboundAction` is the policy table | **fail-closed** | fixed: hold at P(injection) ≥ 0.3, auto-reply at P(sales) ≥ 0.7, silent spam at ≥ 0.8; mail longer than the screen sees (subject 300, body 6,000 chars) is held |
|
|
129
143
|
| `factCheckGate` | unsupported + contradicts + personal (three yes/no) per section against the evidence the writer was given | fail-open | `FACT_CHECK_MIN_PROBABILITY` (0.7); contradicts at 0.5; personal note at 0.8 |
|
|
130
144
|
|
|
131
145
|
Provenance, briefly:
|
|
@@ -181,15 +195,24 @@ latency.
|
|
|
181
195
|
1. Bump `version` in `package.json` and add a `CHANGELOG.md` entry.
|
|
182
196
|
2. Commit, then publish a GitHub release whose tag is `vX.Y.Z` (a bare
|
|
183
197
|
`X.Y.Z` also works) targeting `main`. The release workflow checks the tag
|
|
184
|
-
against the version
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
198
|
+
against the version and re-runs lint, typecheck, tests and the build. A
|
|
199
|
+
release saved as a draft creates no tag and runs nothing.
|
|
200
|
+
3. Publish to npm by hand from a clean checkout of the tagged commit, in a
|
|
201
|
+
real terminal:
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
npm publish --access public
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
npm asks for an MFA step with a passkey; approve it in the browser while
|
|
208
|
+
the command waits. The registry can take a few minutes to show the new
|
|
209
|
+
version.
|
|
210
|
+
|
|
211
|
+
The workflow's own publish step (trusted publishing, owner `mpointer`,
|
|
212
|
+
repository `typesafe-gates`, workflow `release.yml`) fails with
|
|
213
|
+
`403 OIDC permission denied`, because the package requires that passkey
|
|
214
|
+
step and CI cannot complete it. Releases published by hand carry no
|
|
215
|
+
provenance attestation.
|
|
193
216
|
|
|
194
217
|
## License
|
|
195
218
|
|
package/dist/gate.d.ts
CHANGED
|
@@ -49,7 +49,9 @@ export interface Gate<Input, Context, Q extends Questions, Verdict> {
|
|
|
49
49
|
readonly questions: Q;
|
|
50
50
|
state(input: Input, context: Context): EntryType;
|
|
51
51
|
interpret(answers: SystemOneResult<Q>["answers"], input: Input, context: Context): Verdict;
|
|
52
|
-
/** Judge every input in one all-or-nothing invocation.
|
|
52
|
+
/** Judge every input in one all-or-nothing invocation. The policy covers
|
|
53
|
+
* the judge being unavailable; an error thrown by `state` or `interpret`
|
|
54
|
+
* rejects instead, so fail-closed callers should catch it and hold. */
|
|
53
55
|
run(judge: Judge, inputs: readonly Input[], context: Context, opts?: GateRunOptions): Promise<GateResult<Verdict>>;
|
|
54
56
|
/** Judge a single input. */
|
|
55
57
|
runOne(judge: Judge, input: Input, context: Context, opts?: GateRunOptions): Promise<GateResult<Verdict>>;
|
package/dist/gate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,aAAa,CAAC;AAErD,MAAM,WAAW,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,SAAS,SAAS,EAAE,OAAO;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,CAAC,CAAC;IACb;;yDAEqD;IACrD,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACrD,wEAAwE;IACxE,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;CAChG;AAED,MAAM,WAAW,UAAU,CAAC,OAAO;IACjC,MAAM,EAAE,QAAQ,CAAC;IACjB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC;AAExE,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,MAAM,WAAW,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,SAAS,SAAS,EAAE,OAAO;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;IACtB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IACjD,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IAC3F
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"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"}
|
package/dist/gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../src/gate.ts"],"names":[],"mappings":"AAgEA,MAAM,UAAU,UAAU,CACxB,IAA0C;IAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;IACpC,MAAM,IAAI,GAAqC;QAC7C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE;YACzC,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YACzF,IAAI,MAAM,CAAC,MAAM,KAAK,aAAa;gBAAE,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC/E,OAAO;gBACL,MAAM,EAAE,QAAQ;gBAChB,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAU,EAAE,OAAO,CAAC,CAAC;gBAClG,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI;YACtC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;8CAC8C;AAC9C,MAAM,UAAU,cAAc,CAAI,MAAqB;IACrD,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,aAAa,CAAI,MAAqB;IACpD,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AAED;;gDAEgD;AAChD,MAAM,UAAU,UAAU,CAAI,MAAqB,EAAE,QAA4C;IAC/F,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAChF,CAAC"}
|
|
@@ -53,9 +53,15 @@ export interface Inbox {
|
|
|
53
53
|
/** What the inbox is for and what the automatic reply does. */
|
|
54
54
|
purpose: string;
|
|
55
55
|
}
|
|
56
|
-
/** The
|
|
57
|
-
*
|
|
58
|
-
*
|
|
56
|
+
/** The screen judges at most this much of the subject and body, so a 50 KB
|
|
57
|
+
* forwarded thread is not billed in full. Mail longer than this is held (see
|
|
58
|
+
* `decideInboundAction`): the sender chooses where injected instructions
|
|
59
|
+
* go, and padding past the cut would otherwise hide them from the screen
|
|
60
|
+
* while the responder still reads them. */
|
|
61
|
+
export declare const INBOUND_SUBJECT_MAX_CHARS = 300;
|
|
62
|
+
export declare const INBOUND_BODY_MAX_CHARS = 6000;
|
|
63
|
+
/** True when the screen would not see the whole email. */
|
|
64
|
+
export declare function exceedsScreen(email: Pick<InboundEmail, "subject" | "body">): boolean;
|
|
59
65
|
export declare function inboundState(email: InboundEmail, inbox: Inbox): {
|
|
60
66
|
inbox: {
|
|
61
67
|
name: string;
|
|
@@ -71,6 +77,8 @@ export declare function inboundState(email: InboundEmail, inbox: Inbox): {
|
|
|
71
77
|
export interface InboundAnswers {
|
|
72
78
|
intent: Pick<ChoiceResponse<typeof INBOUND_INTENTS>, "choice" | "probabilities">;
|
|
73
79
|
injection: Pick<NoulResponse, "noul">;
|
|
80
|
+
/** The screen saw only part of the email. */
|
|
81
|
+
truncated?: boolean;
|
|
74
82
|
}
|
|
75
83
|
export type InboundDecision = {
|
|
76
84
|
action: "auto_reply";
|
|
@@ -89,7 +97,8 @@ export type InboundDecision = {
|
|
|
89
97
|
export declare const INJECTION_HOLD_AT = 0.3;
|
|
90
98
|
export declare const AUTO_REPLY_MIN = 0.7;
|
|
91
99
|
export declare const SPAM_SILENT_AT = 0.8;
|
|
92
|
-
/** Pure policy. `null` answers mean the screen was unavailable
|
|
100
|
+
/** Pure policy. `null` answers mean the screen was unavailable, and
|
|
101
|
+
* `truncated` means it saw only part of the email: hold either way. */
|
|
93
102
|
export declare function decideInboundAction(answers: InboundAnswers | null): InboundDecision;
|
|
94
103
|
export declare const inboundScreenGate: import("../gate.js").Gate<InboundEmail, Inbox, {
|
|
95
104
|
intent: import("@typesafe-ai/sdk").ChoiceQuestion<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound-screen.d.ts","sourceRoot":"","sources":["../../src/gates/inbound-screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,eAAO,MAAM,eAAe;;;;;;;;CAalB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,eAAe,CAAC;AAEzD,eAAO,MAAM,iBAAiB;;;;;;;;;;;CAoB7B,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED
|
|
1
|
+
{"version":3,"file":"inbound-screen.d.ts","sourceRoot":"","sources":["../../src/gates/inbound-screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAGzD,eAAO,MAAM,eAAe;;;;;;;;CAalB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,eAAe,CAAC;AAEzD,eAAO,MAAM,iBAAiB;;;;;;;;;;;CAoB7B,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;2CAI2C;AAC3C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAE5C,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC,GAAG,OAAO,CAEpF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;EAU7D;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC,OAAO,eAAe,CAAC,EAAE,QAAQ,GAAG,eAAe,CAAC,CAAC;IACjF,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACtC,6CAA6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F;;uBAEuB;AACvB,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;uEACuE;AACvE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,eAAe,CAgBnF;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;kBAU5B,CAAC;AAEH;wDACwD;AACxD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,eAAe,CAEnF"}
|
|
@@ -43,17 +43,25 @@ export const INBOUND_QUESTIONS = {
|
|
|
43
43
|
false: "The email is written to a human reader only.",
|
|
44
44
|
}),
|
|
45
45
|
};
|
|
46
|
-
/** The
|
|
47
|
-
*
|
|
48
|
-
*
|
|
46
|
+
/** The screen judges at most this much of the subject and body, so a 50 KB
|
|
47
|
+
* forwarded thread is not billed in full. Mail longer than this is held (see
|
|
48
|
+
* `decideInboundAction`): the sender chooses where injected instructions
|
|
49
|
+
* go, and padding past the cut would otherwise hide them from the screen
|
|
50
|
+
* while the responder still reads them. */
|
|
51
|
+
export const INBOUND_SUBJECT_MAX_CHARS = 300;
|
|
52
|
+
export const INBOUND_BODY_MAX_CHARS = 6_000;
|
|
53
|
+
/** True when the screen would not see the whole email. */
|
|
54
|
+
export function exceedsScreen(email) {
|
|
55
|
+
return email.subject.length > INBOUND_SUBJECT_MAX_CHARS || email.body.length > INBOUND_BODY_MAX_CHARS;
|
|
56
|
+
}
|
|
49
57
|
export function inboundState(email, inbox) {
|
|
50
58
|
return {
|
|
51
59
|
inbox: { name: inbox.name, purpose: inbox.purpose },
|
|
52
60
|
email: {
|
|
53
61
|
from: `${email.fromName} <${email.fromEmail}>`,
|
|
54
62
|
senderHistory: email.knownSender ? "has emailed this inbox before" : "first contact",
|
|
55
|
-
subject: email.subject.slice(0,
|
|
56
|
-
body: email.body.slice(0,
|
|
63
|
+
subject: email.subject.slice(0, INBOUND_SUBJECT_MAX_CHARS),
|
|
64
|
+
body: email.body.slice(0, INBOUND_BODY_MAX_CHARS),
|
|
57
65
|
},
|
|
58
66
|
};
|
|
59
67
|
}
|
|
@@ -63,10 +71,13 @@ export function inboundState(email, inbox) {
|
|
|
63
71
|
export const INJECTION_HOLD_AT = 0.3;
|
|
64
72
|
export const AUTO_REPLY_MIN = 0.7;
|
|
65
73
|
export const SPAM_SILENT_AT = 0.8;
|
|
66
|
-
/** Pure policy. `null` answers mean the screen was unavailable
|
|
74
|
+
/** Pure policy. `null` answers mean the screen was unavailable, and
|
|
75
|
+
* `truncated` means it saw only part of the email: hold either way. */
|
|
67
76
|
export function decideInboundAction(answers) {
|
|
68
77
|
if (!answers)
|
|
69
78
|
return { action: "hold", reason: "screen_unavailable", alert: true };
|
|
79
|
+
if (answers.truncated)
|
|
80
|
+
return { action: "hold", reason: "too_long_to_screen", alert: true };
|
|
70
81
|
const pSales = probabilityOf(answers.intent, "ad_inquiry", "negotiation");
|
|
71
82
|
const pSpam = probabilityOf(answers.intent, "spam_phishing");
|
|
72
83
|
const pInjection = answers.injection.noul;
|
|
@@ -86,7 +97,11 @@ export const inboundScreenGate = defineGate({
|
|
|
86
97
|
policy: "fail-closed",
|
|
87
98
|
questions: INBOUND_QUESTIONS,
|
|
88
99
|
state: (email, inbox) => inboundState(email, inbox),
|
|
89
|
-
interpret: (answers) => ({
|
|
100
|
+
interpret: (answers, email) => ({
|
|
101
|
+
intent: answers.intent,
|
|
102
|
+
injection: answers.injection,
|
|
103
|
+
truncated: exceedsScreen(email),
|
|
104
|
+
}),
|
|
90
105
|
});
|
|
91
106
|
/** The full fail-closed path: a result from `inboundScreenGate.runOne` to a
|
|
92
107
|
* decision, holding when the screen was unavailable. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbound-screen.js","sourceRoot":"","sources":["../../src/gates/inbound-screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAA0C,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EACR,2JAA2J;IAC7J,WAAW,EACT,gKAAgK;IAClK,SAAS,EACP,iHAAiH;IACnH,OAAO,EAAE,0EAA0E;IACnF,aAAa,EACX,yIAAyI;IAC3I,KAAK,EACH,0IAA0I;IAC5I,KAAK,EAAE,sGAAsG;CACrG,CAAC;AAIX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC,uFAAuF,EAAE,eAAe,CAAC;IACxH,SAAS,EAAE,IAAI,CACb;QACE,QAAQ,EACN,kHAAkH;QACpH,QAAQ,EAAE;YACR,4EAA4E;YAC5E,yEAAyE;YACzE,wHAAwH;YACxH,iFAAiF;SAClF;QACD,WAAW,EACT,kIAAkI;KACrI,EACD;QACE,IAAI,EAAE,wEAAwE;QAC9E,KAAK,EAAE,8CAA8C;KACtD,CACF;CACF,CAAC;AAkBF
|
|
1
|
+
{"version":3,"file":"inbound-screen.js","sourceRoot":"","sources":["../../src/gates/inbound-screen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,MAAM,EAAE,IAAI,EAA0C,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,UAAU,EACR,2JAA2J;IAC7J,WAAW,EACT,gKAAgK;IAClK,SAAS,EACP,iHAAiH;IACnH,OAAO,EAAE,0EAA0E;IACnF,aAAa,EACX,yIAAyI;IAC3I,KAAK,EACH,0IAA0I;IAC5I,KAAK,EAAE,sGAAsG;CACrG,CAAC;AAIX,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC,uFAAuF,EAAE,eAAe,CAAC;IACxH,SAAS,EAAE,IAAI,CACb;QACE,QAAQ,EACN,kHAAkH;QACpH,QAAQ,EAAE;YACR,4EAA4E;YAC5E,yEAAyE;YACzE,wHAAwH;YACxH,iFAAiF;SAClF;QACD,WAAW,EACT,kIAAkI;KACrI,EACD;QACE,IAAI,EAAE,wEAAwE;QAC9E,KAAK,EAAE,8CAA8C;KACtD,CACF;CACF,CAAC;AAkBF;;;;2CAI2C;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAC7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC;AAE5C,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAAC,KAA6C;IACzE,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,yBAAyB,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,sBAAsB,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAmB,EAAE,KAAY;IAC5D,OAAO;QACL,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;QACnD,KAAK,EAAE;YACL,IAAI,EAAE,GAAG,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,SAAS,GAAG;YAC9C,aAAa,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,eAAe;YACpF,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,yBAAyB,CAAC;YAC1D,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC;SAClD;KACF,CAAC;AACJ,CAAC;AAaD;;uBAEuB;AACvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC;uEACuE;AACvE,MAAM,UAAU,mBAAmB,CAAC,OAA8B;IAChE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACnF,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC5F,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC;IAE1C,6BAA6B;IAC7B,IAAI,CAAC,CAAC,UAAU,GAAG,iBAAiB,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC3F,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,eAAe,IAAI,KAAK,IAAI,cAAc,EAAE,CAAC;QACzE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC9E,CAAC;IACD,IAAI,MAAM,IAAI,cAAc;QAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAClF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACxG,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;IAC1C,IAAI,EAAE,gBAAgB;IACtB,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,iBAAiB;IAC5B,KAAK,EAAE,CAAC,KAAmB,EAAE,KAAY,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC;IACxE,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,EAAkB,EAAE,CAAC,CAAC;QAC9C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC;KAChC,CAAC;CACH,CAAC,CAAC;AAEH;wDACwD;AACxD,MAAM,UAAU,eAAe,CAAC,MAAkC;IAChE,OAAO,mBAAmB,CAAC,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/F,CAAC"}
|
package/dist/gates/locality.d.ts
CHANGED
|
@@ -63,7 +63,9 @@ export interface LocalFirstPick<T> {
|
|
|
63
63
|
}
|
|
64
64
|
/** The local-first pool: every item at P(nearby or closer) >= threshold,
|
|
65
65
|
* topped up to `target` with the next-most-local items that are at least
|
|
66
|
-
* statewide-ish. A slow news day yields a smaller pool, not an off-topic one.
|
|
66
|
+
* statewide-ish. A slow news day yields a smaller pool, not an off-topic one.
|
|
67
|
+
* `verdicts[i]` must be the verdict for `items[i]`; when the gate was
|
|
68
|
+
* unavailable, skip this and keep the previous path instead. */
|
|
67
69
|
export declare function pickLocalFirst<T>(items: readonly T[], verdicts: readonly LocalityVerdict[], opts?: {
|
|
68
70
|
target?: number;
|
|
69
71
|
minProbability?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locality.d.ts","sourceRoot":"","sources":["../../src/gates/locality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAK7D,eAAO,MAAM,eAAe,kqBAKlB,CAAC;AAEX,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,eAAO,MAAM,iBAAiB,4sBAS7B,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS;;;;;;;;;;;EAKrE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,GAAG,eAAe,CAE1F;AAED,eAAO,MAAM,YAAY;;mBAMvB,CAAC;AAEH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD;kDACkD;AAClD,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C;mDACmD;AACnD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAEpG;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAK7F;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,gCAAgC;IAChC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED
|
|
1
|
+
{"version":3,"file":"locality.d.ts","sourceRoot":"","sources":["../../src/gates/locality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAK7D,eAAO,MAAM,eAAe,kqBAKlB,CAAC;AAEX,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,eAAO,MAAM,iBAAiB,4sBAS7B,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS;;;;;;;;;;;EAKrE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,GAAG,eAAe,CAE1F;AAED,eAAO,MAAM,YAAY;;mBAMvB,CAAC;AAEH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD;kDACkD;AAClD,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C;mDACmD;AACnD,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAElC,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAEpG;AAED,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAK7F;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,gCAAgC;IAChC,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;gEAIgE;AAChE,wBAAgB,cAAc,CAAC,CAAC,EAC9B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAO,GACtD,cAAc,CAAC,CAAC,CAAC,CAiBnB;AAWD,eAAO,MAAM,iCAAiC,MAAM,CAAC;AACrD,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,MAAM,CAKpG;AAED;kEACkE;AAClE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,EAAE,UAAU,SAAI,GAAG,MAAM,GAAG,IAAI,CAGhG"}
|
package/dist/gates/locality.js
CHANGED
|
@@ -59,8 +59,13 @@ export function localPoolTarget(env = process.env) {
|
|
|
59
59
|
}
|
|
60
60
|
/** The local-first pool: every item at P(nearby or closer) >= threshold,
|
|
61
61
|
* topped up to `target` with the next-most-local items that are at least
|
|
62
|
-
* statewide-ish. A slow news day yields a smaller pool, not an off-topic one.
|
|
62
|
+
* statewide-ish. A slow news day yields a smaller pool, not an off-topic one.
|
|
63
|
+
* `verdicts[i]` must be the verdict for `items[i]`; when the gate was
|
|
64
|
+
* unavailable, skip this and keep the previous path instead. */
|
|
63
65
|
export function pickLocalFirst(items, verdicts, opts = {}) {
|
|
66
|
+
if (verdicts.length !== items.length) {
|
|
67
|
+
throw new RangeError(`pickLocalFirst: ${items.length} items but ${verdicts.length} verdicts`);
|
|
68
|
+
}
|
|
64
69
|
const target = opts.target ?? localPoolTarget();
|
|
65
70
|
const threshold = opts.minProbability ?? localityMinProbability();
|
|
66
71
|
const local = new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locality.js","sourceRoot":"","sources":["../../src/gates/locality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,EAAsB,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEzE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,iKAAiK;IACjK,mMAAmM;IACnM,kLAAkL;IAClL,yHAAyH;CACjH,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CACpC;IACE,QAAQ,EAAE,yFAAyF;IACnG,QAAQ,EAAE;QACR,oLAAoL;QACpL,gIAAgI;KACjI;CACF,EACD,eAAe,CAChB,CAAC;AAsBF,MAAM,aAAa,GAAG,GAAG,CAAC;AAE1B,MAAM,UAAU,aAAa,CAAC,IAAkB,EAAE,SAAoB;IACpE,OAAO;QACL,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,MAAM,EAAE;QACnG,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE;KAC9G,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAyC;IACvE,OAAO,EAAE,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;IACrC,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,WAAW;IACnB,SAAS,EAAE,EAAE,QAAQ,EAAE,iBAAiB,EAAE;IAC1C,KAAK,EAAE,CAAC,IAAkB,EAAE,SAAoB,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC;IACnF,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC;CAC1D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AACpD;kDACkD;AAClD,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAC5C;mDACmD;AACnD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAElC,MAAM,UAAU,sBAAsB,CAAC,MAA0C,OAAO,CAAC,GAAG;IAC1F,OAAO,oBAAoB,CAAC,0BAA0B,EAAE,gCAAgC,EAAE,GAAG,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAA0C,OAAO,CAAC,GAAG;IACnF,OAAO,gBAAgB,CACrB,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,yBAAyB,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EACpG,GAAG,CACJ,CAAC;AACJ,CAAC;AASD
|
|
1
|
+
{"version":3,"file":"locality.js","sourceRoot":"","sources":["../../src/gates/locality.ts"],"names":[],"mappings":"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"}
|
package/dist/judge.d.ts
CHANGED
|
@@ -23,12 +23,12 @@ export interface JudgeConfig {
|
|
|
23
23
|
* reason `no_client`. Omit to build one from `TYPESAFE_API_KEY` lazily. */
|
|
24
24
|
client?: SystemOneClient | null;
|
|
25
25
|
/** Receives one record per invocation, including failed ones (tokens spent
|
|
26
|
-
* before a failure were still billed).
|
|
27
|
-
* telemetry must never fail a gate. */
|
|
26
|
+
* before a failure were still billed). It is not awaited, and errors
|
|
27
|
+
* thrown here are swallowed: telemetry must never fail or delay a gate. */
|
|
28
28
|
recordUsage?: UsageRecorder;
|
|
29
29
|
/** Where "falling back" warnings go. `null` silences them. Default: console. */
|
|
30
30
|
logger?: Pick<Console, "warn"> | null;
|
|
31
|
-
/** Requests in flight per invocation. Default 8. */
|
|
31
|
+
/** Requests in flight per invocation, a positive integer. Default 8. */
|
|
32
32
|
concurrency?: number;
|
|
33
33
|
rates?: Rates;
|
|
34
34
|
/** Model override for every request. */
|
package/dist/judge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAA8B,KAAK,KAAK,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1G,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE3F;qEACqE;AACrE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,sDAAsD;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B;+EAC2E;IAC3E,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC
|
|
1
|
+
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAA8B,KAAK,KAAK,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1G,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,GAAG,aAAa,GAAG,SAAS,CAAC;AAE3F;qEACqE;AACrE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,MAAM,EAAE,QAAQ,CAAC;IACjB,sDAAsD;IACtD,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B;+EAC2E;IAC3E,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC;;+EAE2E;IAC3E,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,gFAAgF;IAChF,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B;6EACyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0EAA0E;AAC1E,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,EAC5C,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,SAAS,EAAE,CAAC,EACZ,IAAI,EAAE,YAAY,KACf,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAIzD;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,MAAM,GAAE,WAAgB,GAAG,KAAK,CAoH3D"}
|
package/dist/judge.js
CHANGED
|
@@ -28,6 +28,11 @@ export function createJudge(config = {}) {
|
|
|
28
28
|
const client = await getClient();
|
|
29
29
|
const usage = { inputTokens: 0, outputTokens: 0, requests: 0 };
|
|
30
30
|
const requestedModel = opts.model ?? config.model ?? "";
|
|
31
|
+
const concurrency = opts.concurrency ?? config.concurrency ?? DEFAULT_CONCURRENCY;
|
|
32
|
+
if (!Number.isInteger(concurrency) || concurrency < 1) {
|
|
33
|
+
throw new RangeError(`[typesafe-gates:${opts.task}] concurrency must be a positive integer, got ${concurrency}`);
|
|
34
|
+
}
|
|
35
|
+
const started = performance.now();
|
|
31
36
|
async function record(model, failed) {
|
|
32
37
|
if (!config.recordUsage)
|
|
33
38
|
return;
|
|
@@ -39,6 +44,7 @@ export function createJudge(config = {}) {
|
|
|
39
44
|
model: model || requestedModel || "jev-latest",
|
|
40
45
|
provider: "typesafe",
|
|
41
46
|
failed,
|
|
47
|
+
durationMs: performance.now() - started,
|
|
42
48
|
estimatedCostUsd: estimateCostUsd(usage, rates),
|
|
43
49
|
meta: opts.meta ?? {},
|
|
44
50
|
...usage,
|
|
@@ -78,8 +84,9 @@ export function createJudge(config = {}) {
|
|
|
78
84
|
: { state: states[i], questions };
|
|
79
85
|
const res = await client.systemOne(request, { signal: abort.signal });
|
|
80
86
|
answers[i] = res.answers;
|
|
81
|
-
|
|
82
|
-
usage.
|
|
87
|
+
// SDK >= 0.7 reports null when the API omits a count.
|
|
88
|
+
usage.inputTokens += res.usage.input_tokens ?? 0;
|
|
89
|
+
usage.outputTokens += res.usage.output_tokens ?? 0;
|
|
83
90
|
usage.requests += 1;
|
|
84
91
|
model ||= res.model;
|
|
85
92
|
}
|
|
@@ -92,7 +99,7 @@ export function createJudge(config = {}) {
|
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
|
-
const width = Math.min(
|
|
102
|
+
const width = Math.min(concurrency, states.length);
|
|
96
103
|
try {
|
|
97
104
|
await Promise.all(Array.from({ length: width }, () => worker()));
|
|
98
105
|
}
|
|
@@ -102,7 +109,8 @@ export function createJudge(config = {}) {
|
|
|
102
109
|
opts.signal?.removeEventListener("abort", onOuterAbort);
|
|
103
110
|
}
|
|
104
111
|
const incomplete = failed || abort.signal.aborted || usage.requests < states.length;
|
|
105
|
-
|
|
112
|
+
// Not awaited: a slow or hung recorder must never hold up the gate.
|
|
113
|
+
void record(model, incomplete);
|
|
106
114
|
if (incomplete) {
|
|
107
115
|
const reason = budgetHit
|
|
108
116
|
? "over_budget"
|
package/dist/judge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judge.js","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAoD,MAAM,YAAY,CAAC;AA4D1G,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,WAAW,CAAC,SAAsB,EAAE;IAClD,IAAI,cAAc,GAAuC,MAAM,CAAC,MAAM,CAAC;IACvE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC;IAExC,KAAK,UAAU,SAAS;QACtB,IAAI,cAAc,KAAK,SAAS;YAAE,OAAO,cAAc,CAAC;QACxD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACtD,cAAc,GAAG,aAAa,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,OAAO,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI;QACjD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,KAAK,GAAgB,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;QAC5E,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"judge.js","sourceRoot":"","sources":["../src/judge.ts"],"names":[],"mappings":"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"}
|
package/dist/usage.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface UsageRecord extends UsageTotals {
|
|
|
15
15
|
provider: "typesafe";
|
|
16
16
|
/** True when the invocation ended unavailable; the tokens were still billed. */
|
|
17
17
|
failed: boolean;
|
|
18
|
+
/** Wall-clock time of the invocation, from first request to result. */
|
|
19
|
+
durationMs: number;
|
|
18
20
|
estimatedCostUsd: number;
|
|
19
21
|
/** Whatever the caller attached: tenant id, run id, request id. */
|
|
20
22
|
meta: Record<string, unknown>;
|
package/dist/usage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;oDACgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,UAAU,CAAC;IACrB,gFAAgF;IAChF,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1E;wEACwE;AACxE,eAAO,MAAM,SAAS;;;CAAiE,CAAC;AAExF,MAAM,WAAW,KAAK;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,GAAE,KAAiB,GAAG,MAAM,CAKpF"}
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb;oDACgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,UAAU,CAAC;IACrB,gFAAgF;IAChF,MAAM,EAAE,OAAO,CAAC;IAChB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1E;wEACwE;AACxE,eAAO,MAAM,SAAS;;;CAAiE,CAAC;AAExF,MAAM,WAAW,KAAK;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,GAAE,KAAiB,GAAG,MAAM,CAKpF"}
|
package/dist/usage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AA2BA;wEACwE;AACxE,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAW,CAAC;AAOxF,MAAM,UAAU,eAAe,CAAC,KAAkB,EAAE,QAAe,SAAS;IAC1E,OAAO,CACL,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,kBAAkB,GAAG,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,mBAAmB,CAAC;QAC/F,SAAS,CACV,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "typesafe-gates",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Probabilistic decision gates for LLM pipelines on TypeSafe AI's System One (Jev): typed Score, Choice and yes/no judgments with explicit thresholds, a stated fail-open or fail-closed policy per gate, all-or-nothing batches, time budgets, and usage accounting. Ships six reference gates from production.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Mike Pointer <mpointer@gmail.com>",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
40
40
|
"test": "vitest run",
|
|
41
41
|
"lint": "eslint .",
|
|
42
|
-
"prepublishOnly": "npm run typecheck && npm run test && npm run build"
|
|
42
|
+
"prepublishOnly": "npm run typecheck && npm run test && npm run build",
|
|
43
|
+
"coverage": "vitest run --coverage"
|
|
43
44
|
},
|
|
44
45
|
"keywords": [
|
|
45
46
|
"typesafe-ai",
|
|
@@ -60,12 +61,13 @@
|
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@types/node": "^22.0.0",
|
|
62
63
|
"@typesafe-ai/sdk": "0.6.0",
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
64
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
65
|
+
"eslint": "^10.13.0",
|
|
66
|
+
"typescript": "~6.0.3",
|
|
67
|
+
"typescript-eslint": "^8.72.1",
|
|
68
|
+
"vitest": "^5.0.5"
|
|
67
69
|
},
|
|
68
70
|
"engines": {
|
|
69
|
-
"node": ">=
|
|
71
|
+
"node": ">=22.12"
|
|
70
72
|
}
|
|
71
73
|
}
|