@odla-ai/harness 0.4.0 → 0.5.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/dist/{chunk-C5VQI2IF.js → chunk-FVOMJKWK.js} +2 -2
- package/dist/{chunk-GKDKIU4P.js → chunk-K76I2TCQ.js} +3 -3
- package/dist/{chunk-ANNX7VGK.js → chunk-L2T3LPEF.js} +40 -18
- package/dist/chunk-L2T3LPEF.js.map +1 -0
- package/dist/{chunk-3QP4VDQS.js → chunk-LNQNFGQC.js} +1 -1
- package/dist/chunk-LNQNFGQC.js.map +1 -0
- package/dist/{chunk-KD7IN3NJ.js → chunk-XWXRNPGY.js} +4 -4
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4 -4
- package/dist/code-runtime-cli.cjs +37 -15
- package/dist/code-runtime-cli.cjs.map +1 -1
- package/dist/code-runtime-cli.js +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/node.cjs +37 -15
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +16 -1
- package/dist/node.d.ts +16 -1
- package/dist/node.js +5 -5
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/dist/{types-0_H9TKkO.d.cts → types-CK5EKmKm.d.cts} +17 -0
- package/dist/{types-0_H9TKkO.d.ts → types-CK5EKmKm.d.ts} +17 -0
- package/package.json +1 -1
- package/dist/chunk-3QP4VDQS.js.map +0 -1
- package/dist/chunk-ANNX7VGK.js.map +0 -1
- /package/dist/{chunk-C5VQI2IF.js.map → chunk-FVOMJKWK.js.map} +0 -0
- /package/dist/{chunk-GKDKIU4P.js.map → chunk-K76I2TCQ.js.map} +0 -0
- /package/dist/{chunk-KD7IN3NJ.js.map → chunk-XWXRNPGY.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HARNESS_PROTOCOL_VERSION
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LNQNFGQC.js";
|
|
4
4
|
|
|
5
5
|
// src/protocol.ts
|
|
6
6
|
var CONTROL = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/;
|
|
@@ -90,4 +90,4 @@ export {
|
|
|
90
90
|
encodeAgentInput,
|
|
91
91
|
makeHarnessEvent
|
|
92
92
|
};
|
|
93
|
-
//# sourceMappingURL=chunk-
|
|
93
|
+
//# sourceMappingURL=chunk-FVOMJKWK.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeAgentInput,
|
|
3
3
|
parseAgentOutput
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-FVOMJKWK.js";
|
|
5
5
|
import {
|
|
6
6
|
HARNESS_PROTOCOL_VERSION
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-LNQNFGQC.js";
|
|
8
8
|
|
|
9
9
|
// src/container.ts
|
|
10
10
|
import { execFile, spawn } from "child_process";
|
|
@@ -548,4 +548,4 @@ export {
|
|
|
548
548
|
stageWorkspacePair,
|
|
549
549
|
safeWorkspaceLabel
|
|
550
550
|
};
|
|
551
|
-
//# sourceMappingURL=chunk-
|
|
551
|
+
//# sourceMappingURL=chunk-K76I2TCQ.js.map
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
stageWorkspace,
|
|
5
5
|
stageWorkspacePair,
|
|
6
6
|
verifyContainerEngineBoundary
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-K76I2TCQ.js";
|
|
8
8
|
import {
|
|
9
9
|
HARNESS_PROTOCOL_VERSION
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-LNQNFGQC.js";
|
|
11
11
|
|
|
12
12
|
// src/workspace-digest.ts
|
|
13
13
|
import { createHash } from "crypto";
|
|
@@ -277,6 +277,7 @@ function parseSnapshot(value) {
|
|
|
277
277
|
return { host, bindings, commands };
|
|
278
278
|
}
|
|
279
279
|
async function parseSource(value) {
|
|
280
|
+
const repositoryLimits = { maximumFiles: 1e5, maximumBytes: 80 * 1024 * 1024 };
|
|
280
281
|
const snapshot = record(record(value)?.snapshot);
|
|
281
282
|
if (!snapshot || typeof snapshot.repository !== "string" || typeof snapshot.commitSha !== "string" || typeof snapshot.treeDigest !== "string" || !Array.isArray(snapshot.files)) throw invalid("source");
|
|
282
283
|
const files = snapshot.files.map((value2) => {
|
|
@@ -298,12 +299,12 @@ async function parseSource(value) {
|
|
|
298
299
|
return { path: file.path, content: file.content };
|
|
299
300
|
});
|
|
300
301
|
const source2 = { repository: reference.repository, commitSha: reference.commitSha, files: referenceFiles };
|
|
301
|
-
const referenceDigest = await digestCodeRepositorySnapshot(source2,
|
|
302
|
+
const referenceDigest = await digestCodeRepositorySnapshot(source2, repositoryLimits);
|
|
302
303
|
if (referenceDigest !== reference.treeDigest) throw invalid("reference source digest");
|
|
303
304
|
references.push({ alias: reference.alias, ...source2, treeDigest: referenceDigest });
|
|
304
305
|
}
|
|
305
306
|
const source = { repository: snapshot.repository, commitSha: snapshot.commitSha, files };
|
|
306
|
-
const digest = await digestCodeRepositorySnapshot(source,
|
|
307
|
+
const digest = await digestCodeRepositorySnapshot(source, repositoryLimits);
|
|
307
308
|
if (digest !== snapshot.treeDigest) throw invalid("source digest");
|
|
308
309
|
return { ...source, treeDigest: digest, ...references.length ? { references } : {} };
|
|
309
310
|
}
|
|
@@ -999,8 +1000,11 @@ import { tmpdir } from "os";
|
|
|
999
1000
|
import { dirname, join as join2, resolve as resolve3, sep as sep2 } from "path";
|
|
1000
1001
|
var RESERVED2 = /* @__PURE__ */ new Set([".git", ".odla", ".wrangler", "node_modules", "dist", "coverage"]);
|
|
1001
1002
|
var SECRET2 = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-token(?:\..+)?\.json)$/i;
|
|
1003
|
+
var SOURCE_MAX_FILES = 1e5;
|
|
1004
|
+
var SOURCE_MAX_BYTES = 80 * 1024 * 1024;
|
|
1005
|
+
var SOURCE_SET_MAX_BYTES = 480 * 1024 * 1024;
|
|
1002
1006
|
async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir()) {
|
|
1003
|
-
if (!snapshot.files.length || snapshot.files.length >
|
|
1007
|
+
if (!snapshot.files.length || snapshot.files.length > SOURCE_MAX_FILES) throw new TypeError("Code source file count is invalid");
|
|
1004
1008
|
const root = await mkdtemp(join2(tempRoot, "odla-code-source-"));
|
|
1005
1009
|
const sourceDir = join2(root, "source");
|
|
1006
1010
|
await mkdir(sourceDir);
|
|
@@ -1012,7 +1016,7 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir()) {
|
|
|
1012
1016
|
if (seen.has(file.path)) throw new TypeError("Code source repeats a path");
|
|
1013
1017
|
seen.add(file.path);
|
|
1014
1018
|
bytes += Buffer.byteLength(file.path) + Buffer.byteLength(file.content);
|
|
1015
|
-
if (bytes >
|
|
1019
|
+
if (bytes > SOURCE_MAX_BYTES) throw new TypeError("Code source exceeds its byte bound");
|
|
1016
1020
|
const target = resolve3(sourceDir, file.path);
|
|
1017
1021
|
if (!target.startsWith(`${resolve3(sourceDir)}${sep2}`)) throw new TypeError("Code source path escapes its root");
|
|
1018
1022
|
await mkdir(dirname(target), { recursive: true });
|
|
@@ -1020,14 +1024,14 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = tmpdir()) {
|
|
|
1020
1024
|
}
|
|
1021
1025
|
for (const reference of snapshot.references ?? []) {
|
|
1022
1026
|
validateAlias(reference.alias);
|
|
1023
|
-
if (!reference.files.length || reference.files.length >
|
|
1027
|
+
if (!reference.files.length || reference.files.length > SOURCE_MAX_FILES) throw new TypeError("Code reference file count is invalid");
|
|
1024
1028
|
for (const file of reference.files) {
|
|
1025
1029
|
validatePath(file.path);
|
|
1026
1030
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
1027
1031
|
if (seen.has(path)) throw new TypeError("Code reference repeats a path");
|
|
1028
1032
|
seen.add(path);
|
|
1029
1033
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
1030
|
-
if (bytes >
|
|
1034
|
+
if (bytes > SOURCE_SET_MAX_BYTES) throw new TypeError("Code source set exceeds its byte bound");
|
|
1031
1035
|
const target = resolve3(sourceDir, path);
|
|
1032
1036
|
if (!target.startsWith(`${resolve3(sourceDir)}${sep2}`)) throw new TypeError("Code reference path escapes its root");
|
|
1033
1037
|
await mkdir(dirname(target), { recursive: true });
|
|
@@ -1053,7 +1057,7 @@ async function attachCodeRuntimeReferences(workspace, references) {
|
|
|
1053
1057
|
validatePath(file.path);
|
|
1054
1058
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
1055
1059
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
1056
|
-
if (bytes >
|
|
1060
|
+
if (bytes > SOURCE_SET_MAX_BYTES - SOURCE_MAX_BYTES) throw new TypeError("Code reference set exceeds its byte bound");
|
|
1057
1061
|
for (const root of [workspace.baselineDir, workspace.workspaceDir]) {
|
|
1058
1062
|
const target = resolve3(root, path);
|
|
1059
1063
|
if (!target.startsWith(`${resolve3(root)}${sep2}`)) throw new TypeError("Code reference path escapes its root");
|
|
@@ -1103,7 +1107,10 @@ async function materializeCommandWorkspace(input) {
|
|
|
1103
1107
|
trustedBaseDir: materialized.sourceDir,
|
|
1104
1108
|
trustedBaseCommitSha: source.commitSha,
|
|
1105
1109
|
checkpoint: codeCheckpointPayload(command.payload)
|
|
1106
|
-
})).workspace : await stageWorkspace(materialized.sourceDir
|
|
1110
|
+
})).workspace : await stageWorkspace(materialized.sourceDir, {
|
|
1111
|
+
maxFiles: SOURCE_MAX_FILES,
|
|
1112
|
+
maxBytes: SOURCE_SET_MAX_BYTES
|
|
1113
|
+
});
|
|
1107
1114
|
return { workspace, sourceDigest: source.treeDigest, requestedLocal: null };
|
|
1108
1115
|
} finally {
|
|
1109
1116
|
await materialized.cleanup();
|
|
@@ -1372,6 +1379,9 @@ async function handleCodeRuntimeInference(input) {
|
|
|
1372
1379
|
call: request.call
|
|
1373
1380
|
});
|
|
1374
1381
|
state.tokens += response2.receipt.inputTokens + response2.receipt.outputTokens;
|
|
1382
|
+
const { costUsd } = response2.receipt;
|
|
1383
|
+
if (costUsd === void 0) state.costKnown = false;
|
|
1384
|
+
else state.costUsd += costUsd;
|
|
1375
1385
|
await input.event({
|
|
1376
1386
|
type: "usage",
|
|
1377
1387
|
provider: response2.receipt.provider,
|
|
@@ -1381,7 +1391,9 @@ async function handleCodeRuntimeInference(input) {
|
|
|
1381
1391
|
durationMs: Date.now() - startedAt,
|
|
1382
1392
|
interactionId: command.commandId,
|
|
1383
1393
|
interactionTokens: state.tokens,
|
|
1384
|
-
interactionMaxTokens: metadata.maxTokensPerInteraction
|
|
1394
|
+
interactionMaxTokens: metadata.maxTokensPerInteraction,
|
|
1395
|
+
...costUsd === void 0 ? {} : { costUsd },
|
|
1396
|
+
...state.costKnown ? { interactionCostUsd: state.costUsd } : {}
|
|
1385
1397
|
}).catch(() => void 0);
|
|
1386
1398
|
return {
|
|
1387
1399
|
protocolVersion: HARNESS_PROTOCOL_VERSION,
|
|
@@ -2297,10 +2309,16 @@ async function startGoalPursuit(input) {
|
|
|
2297
2309
|
attempt: async ({ prompt }) => {
|
|
2298
2310
|
const result = await input.attempt(prompt);
|
|
2299
2311
|
return {
|
|
2300
|
-
//
|
|
2301
|
-
//
|
|
2302
|
-
//
|
|
2303
|
-
|
|
2312
|
+
// What the attempt actually spent, so the runner's token_budget and
|
|
2313
|
+
// cost_budget checks can be reached. This used to be a hardcoded 0 with
|
|
2314
|
+
// no cost at all, which made maxTokens and maxUsd unreachable while
|
|
2315
|
+
// callers reasonably read them as hard ceilings.
|
|
2316
|
+
//
|
|
2317
|
+
// costUsd is omitted rather than zeroed when any call in the attempt
|
|
2318
|
+
// was unpriced: the runner only enforces a cost budget while the cost
|
|
2319
|
+
// is known, and a zero would make it enforce against a lie.
|
|
2320
|
+
tokens: result.tokens ?? 0,
|
|
2321
|
+
...result.costUsd === void 0 ? {} : { costUsd: result.costUsd },
|
|
2304
2322
|
...result.status === "failed" ? { error: result.error ?? "attempt failed" } : {}
|
|
2305
2323
|
};
|
|
2306
2324
|
},
|
|
@@ -2519,7 +2537,7 @@ var CodePiRuntimeEngine = class {
|
|
|
2519
2537
|
recipeAuthorization: this.options.recipeAuthorization
|
|
2520
2538
|
}, lease, metadata.role));
|
|
2521
2539
|
const startedAt = Date.now();
|
|
2522
|
-
const interaction = { tokens: 0, noticeEmitted: false };
|
|
2540
|
+
const interaction = { tokens: 0, noticeEmitted: false, costUsd: 0, costKnown: true };
|
|
2523
2541
|
const inference = createCodeRuntimeInference({
|
|
2524
2542
|
command,
|
|
2525
2543
|
metadata,
|
|
@@ -2557,7 +2575,11 @@ var CodePiRuntimeEngine = class {
|
|
|
2557
2575
|
await this.#diagnostic(command, active, detail);
|
|
2558
2576
|
await this.#failure(command, active, detail);
|
|
2559
2577
|
}
|
|
2560
|
-
return
|
|
2578
|
+
return {
|
|
2579
|
+
...result,
|
|
2580
|
+
tokens: interaction.tokens,
|
|
2581
|
+
...interaction.costKnown ? { costUsd: interaction.costUsd } : {}
|
|
2582
|
+
};
|
|
2561
2583
|
}
|
|
2562
2584
|
/** Report every brokered effect as it starts and finishes. */
|
|
2563
2585
|
#observed(command, active, broker) {
|
|
@@ -2651,4 +2673,4 @@ export {
|
|
|
2651
2673
|
runGoal,
|
|
2652
2674
|
CodePiRuntimeEngine
|
|
2653
2675
|
};
|
|
2654
|
-
//# sourceMappingURL=chunk-
|
|
2676
|
+
//# sourceMappingURL=chunk-L2T3LPEF.js.map
|