@once-agent/sdk 0.1.4 → 0.1.6
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 +20 -20
- package/README.md +62 -3
- package/dist/benchmark.d.ts +40 -0
- package/dist/benchmark.d.ts.map +1 -0
- package/dist/benchmark.js +169 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/cli.js +52 -12
- package/dist/cli.js.map +1 -1
- package/dist/connect/binding.d.ts +17 -0
- package/dist/connect/binding.d.ts.map +1 -0
- package/dist/connect/binding.js +91 -0
- package/dist/connect/binding.js.map +1 -0
- package/dist/connect/classifier.d.ts +18 -0
- package/dist/connect/classifier.d.ts.map +1 -0
- package/dist/connect/classifier.js +49 -0
- package/dist/connect/classifier.js.map +1 -0
- package/dist/connect/execute.d.ts +30 -0
- package/dist/connect/execute.d.ts.map +1 -0
- package/dist/connect/execute.js +47 -0
- package/dist/connect/execute.js.map +1 -0
- package/dist/connect/kernel.d.ts +33 -0
- package/dist/connect/kernel.d.ts.map +1 -0
- package/dist/connect/kernel.js +46 -0
- package/dist/connect/kernel.js.map +1 -0
- package/dist/connect/openai-agents.d.ts +31 -0
- package/dist/connect/openai-agents.d.ts.map +1 -0
- package/dist/connect/openai-agents.js +42 -0
- package/dist/connect/openai-agents.js.map +1 -0
- package/dist/dataset-cli.d.ts +3 -0
- package/dist/dataset-cli.d.ts.map +1 -0
- package/dist/dataset-cli.js +49 -0
- package/dist/dataset-cli.js.map +1 -0
- package/dist/dataset-progress.d.ts +16 -0
- package/dist/dataset-progress.d.ts.map +1 -0
- package/dist/dataset-progress.js +130 -0
- package/dist/dataset-progress.js.map +1 -0
- package/dist/dataset.d.ts +35 -0
- package/dist/dataset.d.ts.map +1 -0
- package/dist/dataset.js +133 -0
- package/dist/dataset.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +259 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime/decision.d.ts +39 -0
- package/dist/runtime/decision.d.ts.map +1 -0
- package/dist/runtime/decision.js +102 -0
- package/dist/runtime/decision.js.map +1 -0
- package/dist/runtime/fetch-interceptor.d.ts +74 -0
- package/dist/runtime/fetch-interceptor.d.ts.map +1 -0
- package/dist/runtime/fetch-interceptor.js +156 -0
- package/dist/runtime/fetch-interceptor.js.map +1 -0
- package/dist/runtime/identity.d.ts +23 -0
- package/dist/runtime/identity.d.ts.map +1 -0
- package/dist/runtime/identity.js +191 -0
- package/dist/runtime/identity.js.map +1 -0
- package/dist/runtime/pipeline.d.ts +25 -0
- package/dist/runtime/pipeline.d.ts.map +1 -0
- package/dist/runtime/pipeline.js +121 -0
- package/dist/runtime/pipeline.js.map +1 -0
- package/dist/setup.d.ts +2 -0
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +126 -33
- package/dist/setup.js.map +1 -1
- package/dist/trace.d.ts +13 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +60 -0
- package/dist/trace.js.map +1 -0
- package/dist-cjs/connect/binding.js +99 -0
- package/dist-cjs/connect/binding.js.map +1 -0
- package/dist-cjs/connect/classifier.js +53 -0
- package/dist-cjs/connect/classifier.js.map +1 -0
- package/dist-cjs/connect/execute.js +52 -0
- package/dist-cjs/connect/execute.js.map +1 -0
- package/dist-cjs/connect/kernel.js +51 -0
- package/dist-cjs/connect/kernel.js.map +1 -0
- package/dist-cjs/connect/openai-agents.js +47 -0
- package/dist-cjs/connect/openai-agents.js.map +1 -0
- package/dist-cjs/index.js +282 -3
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/runtime/decision.js +105 -0
- package/dist-cjs/runtime/decision.js.map +1 -0
- package/dist-cjs/runtime/fetch-interceptor.js +162 -0
- package/dist-cjs/runtime/fetch-interceptor.js.map +1 -0
- package/dist-cjs/runtime/identity.js +194 -0
- package/dist-cjs/runtime/identity.js.map +1 -0
- package/dist-cjs/runtime/pipeline.js +124 -0
- package/dist-cjs/runtime/pipeline.js.map +1 -0
- package/package.json +91 -69
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Jamie Oswald
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jamie Oswald
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# @once-agent/sdk
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
<!-- ONCE_STRIPE_SANDBOX_NOTICE -->
|
|
@@ -62,6 +62,49 @@ Do not commit API keys to source control.
|
|
|
62
62
|
|
|
63
63
|
## 60-second quick start
|
|
64
64
|
|
|
65
|
+
### Runtime HTTP protection
|
|
66
|
+
|
|
67
|
+
For supported POST + JSON HTTP writes, configure the exact protected HTTPS target:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx once setup . --runtime-http=https://api.example.com/v1/action
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This setup pins that exact target in the provider allowlist and opts the immutable provider version into durable HTTP response replay.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { createOnceRuntimeFetch } from "@once-agent/sdk";
|
|
77
|
+
|
|
78
|
+
const onceFetch = createOnceRuntimeFetch({
|
|
79
|
+
provider: "my-provider"
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
async function main() {
|
|
83
|
+
const response = await onceFetch(
|
|
84
|
+
"https://api.example.com/v1/action",
|
|
85
|
+
{
|
|
86
|
+
method: "POST",
|
|
87
|
+
headers: {
|
|
88
|
+
"content-type": "application/json",
|
|
89
|
+
"idempotency-key": "order_123"
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({ example: true })
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
console.log(response.status);
|
|
96
|
+
console.log(await response.text());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
main().catch(console.error);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Retry the same logical real-world action with the same stable identity. In this Runtime HTTP example, that identity is carried by the `idempotency-key`.
|
|
103
|
+
|
|
104
|
+
The Runtime fails closed rather than silently falling back to a direct target write when an operation cannot be safely protected.
|
|
105
|
+
|
|
106
|
+
### Direct SDK execution
|
|
107
|
+
|
|
65
108
|
First configure a provider with `once setup .`, or use a provider alias already registered with your Once account.
|
|
66
109
|
|
|
67
110
|
```ts
|
|
@@ -235,6 +278,18 @@ npx once setup .
|
|
|
235
278
|
|
|
236
279
|
Setup can install/configure the SDK, verify your API key, register a supported provider, and prepare local Once configuration.
|
|
237
280
|
|
|
281
|
+
For Runtime HTTP protection, provide the exact target URL:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
npx once setup . --runtime-http=https://api.example.com/v1/action
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Runtime HTTP setup registers that exact URL in `allowed_urls` and requests `response_replay="required"` for that immutable provider version.
|
|
288
|
+
|
|
289
|
+
Only non-secret provider metadata is written to `.once/config.json`; the provider bearer token is not stored there.
|
|
290
|
+
|
|
291
|
+
Plain `npx once setup .` preserves the existing provider-registration behavior and does not opt that provider version into HTTP response replay.
|
|
292
|
+
|
|
238
293
|
Preview setup without making changes:
|
|
239
294
|
|
|
240
295
|
```bash
|
|
@@ -335,12 +390,16 @@ Its safety properties depend on:
|
|
|
335
390
|
- sufficiently authoritative provider truth
|
|
336
391
|
- the failure mode being within that provider integration's supported model
|
|
337
392
|
|
|
338
|
-
For supported provider integrations, Once is designed to
|
|
393
|
+
For supported provider integrations, Once is designed to suppress duplicate execution across retries and ambiguous transport failures by reconciling provider truth before permitting re-execution.
|
|
394
|
+
|
|
395
|
+
For Runtime HTTP providers registered with `response_replay="required"`, Once also requires a durable, sanitized application-visible HTTP response replay before the local operation can become `CONFIRMED`. Confirmed retries can return that stored response without executing the provider again.
|
|
339
396
|
|
|
340
|
-
When Once cannot determine whether an external side effect occurred,
|
|
397
|
+
When Once cannot determine whether an external side effect occurred, or when required replay evidence is missing after an effect may have happened, it preserves the operation as uncertain rather than assume another execution is safe.
|
|
341
398
|
|
|
342
399
|
This means Once may sacrifice availability temporarily in order to avoid an unsafe duplicate side effect.
|
|
343
400
|
|
|
401
|
+
The external effect itself is not atomically committed with Once's local ledger. The supported claim is duplicate suppression on confirmed/replay paths plus fail-closed handling of ambiguous outcomes, not generic exactly-once execution.
|
|
402
|
+
|
|
344
403
|
## Provider truth
|
|
345
404
|
|
|
346
405
|
Once is strongest when the external system can answer a question equivalent to:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type OnceBenchmarkDecision = "BASELINE_CREATED" | "UNCHANGED" | "CHANGED" | "UNKNOWN";
|
|
2
|
+
export interface BenchmarkObservation {
|
|
3
|
+
timestamp: string;
|
|
4
|
+
resource: string;
|
|
5
|
+
fingerprint: string;
|
|
6
|
+
latency_ms?: number;
|
|
7
|
+
response_bytes?: number;
|
|
8
|
+
upstream_cost?: number;
|
|
9
|
+
once_cost?: number;
|
|
10
|
+
once_decision?: OnceBenchmarkDecision;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface BenchmarkMetrics {
|
|
14
|
+
observations: number;
|
|
15
|
+
unique_resources: number;
|
|
16
|
+
baseline_observations: number;
|
|
17
|
+
eligible_repeated_observations: number;
|
|
18
|
+
unchanged_repeats: number;
|
|
19
|
+
changed_repeats: number;
|
|
20
|
+
hindsight_repeat_opportunities: number;
|
|
21
|
+
hindsight_avoidance_upper_bound: number;
|
|
22
|
+
evaluated_once_decisions: number;
|
|
23
|
+
safely_avoidable_observations: number;
|
|
24
|
+
avoidance_rate: number | null;
|
|
25
|
+
real_changes_with_once_decision: number;
|
|
26
|
+
real_changes_correctly_detected: number;
|
|
27
|
+
change_recall: number | null;
|
|
28
|
+
stale_state_errors: number;
|
|
29
|
+
stale_state_error_rate: number | null;
|
|
30
|
+
latency_avoidable_ms: number;
|
|
31
|
+
response_bytes_avoidable: number;
|
|
32
|
+
upstream_cost_avoidable: number;
|
|
33
|
+
once_check_cost: number;
|
|
34
|
+
economic_avoidance_ratio: number | null;
|
|
35
|
+
}
|
|
36
|
+
export declare function appendBenchmarkObservation(tracePath: string, observation: BenchmarkObservation): Promise<void>;
|
|
37
|
+
export declare function readBenchmarkTrace(tracePath: string): Promise<BenchmarkObservation[]>;
|
|
38
|
+
export declare function calculateBenchmarkMetrics(observations: BenchmarkObservation[]): BenchmarkMetrics;
|
|
39
|
+
export declare function runBenchmark(tracePath: string): Promise<BenchmarkMetrics>;
|
|
40
|
+
//# sourceMappingURL=benchmark.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.d.ts","sourceRoot":"","sources":["../src/benchmark.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,WAAW,GACX,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,8BAA8B,EAAE,MAAM,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,8BAA8B,EAAE,MAAM,CAAC;IACvC,+BAA+B,EAAE,MAAM,CAAC;IACxC,wBAAwB,EAAE,MAAM,CAAC;IACjC,6BAA6B,EAAE,MAAM,CAAC;IACtC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,+BAA+B,EAAE,MAAM,CAAC;IACxC,+BAA+B,EAAE,MAAM,CAAC;IACxC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wBAAwB,EAAE,MAAM,CAAC;IACjC,uBAAuB,EAAE,MAAM,CAAC;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;CACzC;AA8BD,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,oBAAoB,GAChC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAgBjC;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,oBAAoB,EAAE,GACnC,gBAAgB,CA2GlB;AAMD,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+B/E"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { appendFile, readFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { mkdir } from "node:fs/promises";
|
|
4
|
+
function finiteNumber(value) {
|
|
5
|
+
return typeof value === "number" && Number.isFinite(value)
|
|
6
|
+
? value
|
|
7
|
+
: 0;
|
|
8
|
+
}
|
|
9
|
+
function validateObservation(value, lineNumber) {
|
|
10
|
+
if (!value || typeof value !== "object") {
|
|
11
|
+
throw new Error(`Invalid benchmark observation on line ${lineNumber}.`);
|
|
12
|
+
}
|
|
13
|
+
const candidate = value;
|
|
14
|
+
if (typeof candidate.timestamp !== "string" || candidate.timestamp.length === 0) {
|
|
15
|
+
throw new Error(`Missing timestamp on line ${lineNumber}.`);
|
|
16
|
+
}
|
|
17
|
+
if (typeof candidate.resource !== "string" || candidate.resource.length === 0) {
|
|
18
|
+
throw new Error(`Missing resource on line ${lineNumber}.`);
|
|
19
|
+
}
|
|
20
|
+
if (typeof candidate.fingerprint !== "string" || candidate.fingerprint.length === 0) {
|
|
21
|
+
throw new Error(`Missing fingerprint on line ${lineNumber}.`);
|
|
22
|
+
}
|
|
23
|
+
return candidate;
|
|
24
|
+
}
|
|
25
|
+
export async function appendBenchmarkObservation(tracePath, observation) {
|
|
26
|
+
const absolutePath = resolve(tracePath);
|
|
27
|
+
await mkdir(dirname(absolutePath), { recursive: true });
|
|
28
|
+
await appendFile(absolutePath, `${JSON.stringify(observation)}\n`, "utf8");
|
|
29
|
+
}
|
|
30
|
+
export async function readBenchmarkTrace(tracePath) {
|
|
31
|
+
const text = await readFile(resolve(tracePath), "utf8");
|
|
32
|
+
const lines = text
|
|
33
|
+
.split(/\r?\n/u)
|
|
34
|
+
.map(line => line.trim())
|
|
35
|
+
.filter(Boolean);
|
|
36
|
+
return lines.map((line, index) => {
|
|
37
|
+
let parsed;
|
|
38
|
+
try {
|
|
39
|
+
parsed = JSON.parse(line);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error(`Invalid JSON on benchmark trace line ${index + 1}.`);
|
|
43
|
+
}
|
|
44
|
+
return validateObservation(parsed, index + 1);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export function calculateBenchmarkMetrics(observations) {
|
|
48
|
+
const previousByResource = new Map();
|
|
49
|
+
const resources = new Set();
|
|
50
|
+
let baselineObservations = 0;
|
|
51
|
+
let eligibleRepeatedObservations = 0;
|
|
52
|
+
let unchangedRepeats = 0;
|
|
53
|
+
let changedRepeats = 0;
|
|
54
|
+
let evaluatedOnceDecisions = 0;
|
|
55
|
+
let safelyAvoidableObservations = 0;
|
|
56
|
+
let realChangesWithOnceDecision = 0;
|
|
57
|
+
let realChangesCorrectlyDetected = 0;
|
|
58
|
+
let staleStateErrors = 0;
|
|
59
|
+
let latencyAvoidableMs = 0;
|
|
60
|
+
let responseBytesAvoidable = 0;
|
|
61
|
+
let upstreamCostAvoidable = 0;
|
|
62
|
+
let onceCheckCost = 0;
|
|
63
|
+
for (const observation of observations) {
|
|
64
|
+
resources.add(observation.resource);
|
|
65
|
+
const previous = previousByResource.get(observation.resource);
|
|
66
|
+
if (!previous) {
|
|
67
|
+
baselineObservations += 1;
|
|
68
|
+
previousByResource.set(observation.resource, observation);
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
eligibleRepeatedObservations += 1;
|
|
72
|
+
const actuallyChanged = previous.fingerprint !== observation.fingerprint;
|
|
73
|
+
if (actuallyChanged) {
|
|
74
|
+
changedRepeats += 1;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
unchangedRepeats += 1;
|
|
78
|
+
}
|
|
79
|
+
if (observation.once_decision) {
|
|
80
|
+
evaluatedOnceDecisions += 1;
|
|
81
|
+
onceCheckCost += finiteNumber(observation.once_cost);
|
|
82
|
+
if (actuallyChanged) {
|
|
83
|
+
realChangesWithOnceDecision += 1;
|
|
84
|
+
if (observation.once_decision === "CHANGED") {
|
|
85
|
+
realChangesCorrectlyDetected += 1;
|
|
86
|
+
}
|
|
87
|
+
if (observation.once_decision === "UNCHANGED") {
|
|
88
|
+
staleStateErrors += 1;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (observation.once_decision === "UNCHANGED") {
|
|
92
|
+
safelyAvoidableObservations += 1;
|
|
93
|
+
latencyAvoidableMs += finiteNumber(observation.latency_ms);
|
|
94
|
+
responseBytesAvoidable += finiteNumber(observation.response_bytes);
|
|
95
|
+
upstreamCostAvoidable += finiteNumber(observation.upstream_cost);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
previousByResource.set(observation.resource, observation);
|
|
99
|
+
}
|
|
100
|
+
const hindsightRepeatOpportunities = unchangedRepeats;
|
|
101
|
+
const hindsightAvoidanceUpperBound = eligibleRepeatedObservations === 0
|
|
102
|
+
? 0
|
|
103
|
+
: hindsightRepeatOpportunities / eligibleRepeatedObservations;
|
|
104
|
+
const avoidanceRate = evaluatedOnceDecisions === 0
|
|
105
|
+
? null
|
|
106
|
+
: safelyAvoidableObservations / evaluatedOnceDecisions;
|
|
107
|
+
const changeRecall = realChangesWithOnceDecision === 0
|
|
108
|
+
? null
|
|
109
|
+
: realChangesCorrectlyDetected / realChangesWithOnceDecision;
|
|
110
|
+
const staleStateErrorRate = evaluatedOnceDecisions === 0
|
|
111
|
+
? null
|
|
112
|
+
: staleStateErrors / evaluatedOnceDecisions;
|
|
113
|
+
const economicAvoidanceRatio = onceCheckCost > 0
|
|
114
|
+
? upstreamCostAvoidable / onceCheckCost
|
|
115
|
+
: null;
|
|
116
|
+
return {
|
|
117
|
+
observations: observations.length,
|
|
118
|
+
unique_resources: resources.size,
|
|
119
|
+
baseline_observations: baselineObservations,
|
|
120
|
+
eligible_repeated_observations: eligibleRepeatedObservations,
|
|
121
|
+
unchanged_repeats: unchangedRepeats,
|
|
122
|
+
changed_repeats: changedRepeats,
|
|
123
|
+
hindsight_repeat_opportunities: hindsightRepeatOpportunities,
|
|
124
|
+
hindsight_avoidance_upper_bound: hindsightAvoidanceUpperBound,
|
|
125
|
+
evaluated_once_decisions: evaluatedOnceDecisions,
|
|
126
|
+
safely_avoidable_observations: safelyAvoidableObservations,
|
|
127
|
+
avoidance_rate: avoidanceRate,
|
|
128
|
+
real_changes_with_once_decision: realChangesWithOnceDecision,
|
|
129
|
+
real_changes_correctly_detected: realChangesCorrectlyDetected,
|
|
130
|
+
change_recall: changeRecall,
|
|
131
|
+
stale_state_errors: staleStateErrors,
|
|
132
|
+
stale_state_error_rate: staleStateErrorRate,
|
|
133
|
+
latency_avoidable_ms: latencyAvoidableMs,
|
|
134
|
+
response_bytes_avoidable: responseBytesAvoidable,
|
|
135
|
+
upstream_cost_avoidable: upstreamCostAvoidable,
|
|
136
|
+
once_check_cost: onceCheckCost,
|
|
137
|
+
economic_avoidance_ratio: economicAvoidanceRatio
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function percent(value) {
|
|
141
|
+
return value === null ? "n/a" : `${(value * 100).toFixed(2)}%`;
|
|
142
|
+
}
|
|
143
|
+
export async function runBenchmark(tracePath) {
|
|
144
|
+
const observations = await readBenchmarkTrace(tracePath);
|
|
145
|
+
const metrics = calculateBenchmarkMetrics(observations);
|
|
146
|
+
console.log("");
|
|
147
|
+
console.log("Once Benchmark");
|
|
148
|
+
console.log("--------------");
|
|
149
|
+
console.log(`Trace: ${resolve(tracePath)}`);
|
|
150
|
+
console.log(`Observations: ${metrics.observations}`);
|
|
151
|
+
console.log(`Unique resources: ${metrics.unique_resources}`);
|
|
152
|
+
console.log(`Eligible repeated observations: ${metrics.eligible_repeated_observations}`);
|
|
153
|
+
console.log(`Hindsight repeat opportunities: ${metrics.hindsight_repeat_opportunities}`);
|
|
154
|
+
console.log(`Hindsight avoidance upper bound: ${percent(metrics.hindsight_avoidance_upper_bound)}`);
|
|
155
|
+
console.log(`Shadow Once decisions evaluated: ${metrics.evaluated_once_decisions}`);
|
|
156
|
+
console.log(`Safely avoided by Once: ${metrics.safely_avoidable_observations}`);
|
|
157
|
+
console.log(`Measured avoidance rate: ${percent(metrics.avoidance_rate)}`);
|
|
158
|
+
console.log(`Change recall: ${percent(metrics.change_recall)}`);
|
|
159
|
+
console.log(`Stale-state errors: ${metrics.stale_state_errors}`);
|
|
160
|
+
console.log(`Avoidable upstream latency: ${metrics.latency_avoidable_ms.toFixed(0)} ms`);
|
|
161
|
+
console.log(`Avoidable response bytes: ${metrics.response_bytes_avoidable.toFixed(0)}`);
|
|
162
|
+
console.log(`Avoidable upstream cost: ${metrics.upstream_cost_avoidable.toFixed(6)}`);
|
|
163
|
+
console.log(`Once check cost: ${metrics.once_check_cost.toFixed(6)}`);
|
|
164
|
+
console.log(`Economic Avoidance Ratio: ${metrics.economic_avoidance_ratio === null
|
|
165
|
+
? "n/a"
|
|
166
|
+
: `${metrics.economic_avoidance_ratio.toFixed(2)}x`}`);
|
|
167
|
+
return metrics;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benchmark.js","sourceRoot":"","sources":["../src/benchmark.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,8 @@ import { runScan } from "./scan.js";
|
|
|
5
5
|
import { runSetup } from "./setup.js";
|
|
6
6
|
import { runProtect } from "./protect.js";
|
|
7
7
|
import { applyProtectionPlan } from "./apply.js";
|
|
8
|
+
import { runBenchmark } from "./benchmark.js";
|
|
9
|
+
import { runTraceFetch } from "./trace.js";
|
|
8
10
|
async function runDoctor() {
|
|
9
11
|
console.log("");
|
|
10
12
|
console.log("Once Doctor");
|
|
@@ -66,13 +68,19 @@ function printHelp() {
|
|
|
66
68
|
console.log(" Use --snippets to generate per-callsite integration guidance.");
|
|
67
69
|
console.log(" Use --apply to transactionally apply exactly one PATCHABLE candidate.");
|
|
68
70
|
console.log("");
|
|
69
|
-
console.log(" once setup [directory]");
|
|
71
|
+
console.log(" once setup [directory] [--runtime-http=<target-url>]");
|
|
70
72
|
console.log(" Detect, configure and install Once.");
|
|
71
|
-
console.log(" Use --plan to preview
|
|
73
|
+
console.log(" Use --plan to preview; --runtime-http=<https-url> enables Runtime HTTP replay protection.");
|
|
72
74
|
console.log("");
|
|
73
75
|
console.log(" once scan [directory]");
|
|
74
76
|
console.log(" Find likely consequential operations locally.");
|
|
75
77
|
console.log("");
|
|
78
|
+
console.log(" once trace fetch <url> [--resource=<id>] [--trace=<path>]");
|
|
79
|
+
console.log(" Record a raw HTTP observation for Dataset #1 without inventing an Once decision.");
|
|
80
|
+
console.log("");
|
|
81
|
+
console.log(" once benchmark <trace.jsonl>");
|
|
82
|
+
console.log(" Measure hindsight opportunity separately from measured Once avoidance.");
|
|
83
|
+
console.log("");
|
|
76
84
|
console.log(" once doctor");
|
|
77
85
|
console.log(" Verify your Once connection.");
|
|
78
86
|
console.log("");
|
|
@@ -83,6 +91,8 @@ function printHelp() {
|
|
|
83
91
|
console.log(" once protect . --apply");
|
|
84
92
|
console.log(" once setup .");
|
|
85
93
|
console.log(" once scan .");
|
|
94
|
+
console.log(" once trace fetch https://api.github.com/repos/stringsofthemind-oss/once");
|
|
95
|
+
console.log(" once benchmark .once/agent-trace.jsonl");
|
|
86
96
|
console.log(" once doctor");
|
|
87
97
|
}
|
|
88
98
|
async function main() {
|
|
@@ -93,6 +103,35 @@ async function main() {
|
|
|
93
103
|
case "doctor":
|
|
94
104
|
await runDoctor();
|
|
95
105
|
return;
|
|
106
|
+
case "trace": {
|
|
107
|
+
const subcommand = (args.shift() ?? "").toLowerCase();
|
|
108
|
+
if (subcommand !== "fetch") {
|
|
109
|
+
throw new Error("trace currently supports only read-only HTTP collection: once trace fetch <url>");
|
|
110
|
+
}
|
|
111
|
+
const urlValue = args.find(value => !value.startsWith("--"));
|
|
112
|
+
if (!urlValue) {
|
|
113
|
+
throw new Error("trace fetch requires a URL. Example: once trace fetch https://api.github.com/repos/stringsofthemind-oss/once");
|
|
114
|
+
}
|
|
115
|
+
const resourceArgument = args.find(value => value.startsWith("--resource="));
|
|
116
|
+
const traceArgument = args.find(value => value.startsWith("--trace="));
|
|
117
|
+
await runTraceFetch(urlValue, {
|
|
118
|
+
resource: resourceArgument
|
|
119
|
+
? resourceArgument.substring("--resource=".length)
|
|
120
|
+
: undefined,
|
|
121
|
+
tracePath: traceArgument
|
|
122
|
+
? traceArgument.substring("--trace=".length)
|
|
123
|
+
: undefined
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
case "benchmark": {
|
|
128
|
+
const tracePath = args.find(value => !value.startsWith("--"));
|
|
129
|
+
if (!tracePath) {
|
|
130
|
+
throw new Error("benchmark requires a JSONL trace path. Example: once benchmark .once/agent-trace.jsonl");
|
|
131
|
+
}
|
|
132
|
+
await runBenchmark(tracePath);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
96
135
|
case "scan": {
|
|
97
136
|
const noEstimate = args.includes("--no-estimate");
|
|
98
137
|
const requestedPath = args.find(value => !value.startsWith("--")) ?? ".";
|
|
@@ -129,15 +168,6 @@ async function main() {
|
|
|
129
168
|
const message = String(error instanceof Error
|
|
130
169
|
? error.message
|
|
131
170
|
: error);
|
|
132
|
-
/*
|
|
133
|
-
* runProtect currently does not persist a plan
|
|
134
|
-
* when zero candidates are selected.
|
|
135
|
-
*
|
|
136
|
-
* Because this apply path has just run Protect
|
|
137
|
-
* successfully with writePlan=true, a missing
|
|
138
|
-
* protect-plan here means there were zero
|
|
139
|
-
* selected candidates.
|
|
140
|
-
*/
|
|
141
171
|
if (message.includes("protect-plan.json") &&
|
|
142
172
|
message.includes("ENOENT")) {
|
|
143
173
|
throw new Error("--apply requires exactly one PATCHABLE candidate; found 0.");
|
|
@@ -155,11 +185,21 @@ async function main() {
|
|
|
155
185
|
const autoConfirm = args.includes("--yes");
|
|
156
186
|
const planOnly = args.includes("--plan");
|
|
157
187
|
const skipInstall = args.includes("--skip-install");
|
|
188
|
+
const runtimeHttpArgument = args.find(value => value.startsWith("--runtime-http="));
|
|
189
|
+
const runtimeHttp = args.includes("--runtime-http") ||
|
|
190
|
+
Boolean(runtimeHttpArgument);
|
|
191
|
+
const runtimeHttpTargetUrl = runtimeHttpArgument
|
|
192
|
+
? runtimeHttpArgument
|
|
193
|
+
.substring("--runtime-http=".length)
|
|
194
|
+
.trim()
|
|
195
|
+
: undefined;
|
|
158
196
|
const requestedPath = args.find(value => !value.startsWith("--")) ?? ".";
|
|
159
197
|
await runSetup(requestedPath, {
|
|
160
198
|
autoConfirm,
|
|
161
199
|
planOnly,
|
|
162
|
-
skipInstall
|
|
200
|
+
skipInstall,
|
|
201
|
+
runtimeHttp,
|
|
202
|
+
runtimeHttpTargetUrl
|
|
163
203
|
});
|
|
164
204
|
return;
|
|
165
205
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ConnectPayload = Record<string, unknown>;
|
|
2
|
+
export interface ConnectBinding {
|
|
3
|
+
operationId: string;
|
|
4
|
+
payloadFingerprint: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class ConnectBindingError extends Error {
|
|
7
|
+
readonly code: string;
|
|
8
|
+
constructor(message: string, code: string);
|
|
9
|
+
}
|
|
10
|
+
export declare function canonicalizeConnectPayload(payload: ConnectPayload): string;
|
|
11
|
+
export declare function fingerprintConnectPayload(payload: ConnectPayload): string;
|
|
12
|
+
export declare function bindConnectOperation({ operationId, payload, }: {
|
|
13
|
+
operationId: string;
|
|
14
|
+
payload: ConnectPayload;
|
|
15
|
+
}): Readonly<ConnectBinding>;
|
|
16
|
+
export declare function assertConnectBindingMatch(previousBinding: ConnectBinding, nextBinding: ConnectBinding): true;
|
|
17
|
+
//# sourceMappingURL=binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.d.ts","sourceRoot":"","sources":["../../src/connect/binding.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1B,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAGpB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM;CAMf;AA0FD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,cAAc,GACtB,MAAM,CAaR;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,cAAc,GACtB,MAAM,CAcR;AAED,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,OAAO,GACR,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;CACzB,GAAG,QAAQ,CAAC,cAAc,CAAC,CAgB3B;AAED,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,cAAc,EAC/B,WAAW,EAAE,cAAc,GAC1B,IAAI,CAsBN"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export class ConnectBindingError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, code) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "ConnectBindingError";
|
|
7
|
+
this.code = code;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function canonicalize(value, path = "$") {
|
|
11
|
+
if (value === null) {
|
|
12
|
+
return "null";
|
|
13
|
+
}
|
|
14
|
+
const type = typeof value;
|
|
15
|
+
if (type === "string") {
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
}
|
|
18
|
+
if (type === "boolean") {
|
|
19
|
+
return value ? "true" : "false";
|
|
20
|
+
}
|
|
21
|
+
if (type === "number") {
|
|
22
|
+
const numberValue = value;
|
|
23
|
+
if (!Number.isFinite(numberValue)) {
|
|
24
|
+
throw new ConnectBindingError(`Unsupported non-finite number at ${path}.`, "UNSUPPORTED_PAYLOAD_VALUE");
|
|
25
|
+
}
|
|
26
|
+
if (Object.is(numberValue, -0)) {
|
|
27
|
+
return "0";
|
|
28
|
+
}
|
|
29
|
+
return JSON.stringify(numberValue);
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
return "[" +
|
|
33
|
+
value
|
|
34
|
+
.map((item, index) => canonicalize(item, `${path}[${index}]`))
|
|
35
|
+
.join(",") +
|
|
36
|
+
"]";
|
|
37
|
+
}
|
|
38
|
+
if (type === "object") {
|
|
39
|
+
const objectValue = value;
|
|
40
|
+
const prototype = Object.getPrototypeOf(objectValue);
|
|
41
|
+
if (prototype !== Object.prototype &&
|
|
42
|
+
prototype !== null) {
|
|
43
|
+
throw new ConnectBindingError(`Unsupported object type at ${path}.`, "UNSUPPORTED_PAYLOAD_VALUE");
|
|
44
|
+
}
|
|
45
|
+
const keys = Object.keys(objectValue).sort();
|
|
46
|
+
return "{" +
|
|
47
|
+
keys
|
|
48
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalize(objectValue[key], `${path}.${key}`)}`)
|
|
49
|
+
.join(",") +
|
|
50
|
+
"}";
|
|
51
|
+
}
|
|
52
|
+
throw new ConnectBindingError(`Unsupported payload value at ${path}.`, "UNSUPPORTED_PAYLOAD_VALUE");
|
|
53
|
+
}
|
|
54
|
+
export function canonicalizeConnectPayload(payload) {
|
|
55
|
+
if (payload === null ||
|
|
56
|
+
typeof payload !== "object" ||
|
|
57
|
+
Array.isArray(payload)) {
|
|
58
|
+
throw new ConnectBindingError("Once Connect payload must be a plain object.", "INVALID_PAYLOAD");
|
|
59
|
+
}
|
|
60
|
+
return canonicalize(payload);
|
|
61
|
+
}
|
|
62
|
+
export function fingerprintConnectPayload(payload) {
|
|
63
|
+
const canonical = canonicalizeConnectPayload(payload);
|
|
64
|
+
const digest = createHash("sha256")
|
|
65
|
+
.update("once-connect-payload-v1\0", "utf8")
|
|
66
|
+
.update(canonical, "utf8")
|
|
67
|
+
.digest("hex");
|
|
68
|
+
return `once-connect-payload-v1:${digest}`;
|
|
69
|
+
}
|
|
70
|
+
export function bindConnectOperation({ operationId, payload, }) {
|
|
71
|
+
if (typeof operationId !== "string" ||
|
|
72
|
+
operationId.trim() === "") {
|
|
73
|
+
throw new ConnectBindingError("Once Connect requires a stable operationId.", "INVALID_OPERATION_ID");
|
|
74
|
+
}
|
|
75
|
+
return Object.freeze({
|
|
76
|
+
operationId,
|
|
77
|
+
payloadFingerprint: fingerprintConnectPayload(payload),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
export function assertConnectBindingMatch(previousBinding, nextBinding) {
|
|
81
|
+
if (previousBinding.operationId !==
|
|
82
|
+
nextBinding.operationId) {
|
|
83
|
+
throw new ConnectBindingError("Operation identities do not match.", "OPERATION_ID_MISMATCH");
|
|
84
|
+
}
|
|
85
|
+
if (previousBinding.payloadFingerprint !==
|
|
86
|
+
nextBinding.payloadFingerprint) {
|
|
87
|
+
throw new ConnectBindingError("The same operationId was reused with a different consequential payload.", "PAYLOAD_DRIFT");
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"binding.js","sourceRoot":"","sources":["../../src/connect/binding.ts"],"names":[],"mappings":"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"}
|