@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
package/dist/code-runtime-cli.js
CHANGED
|
@@ -6,13 +6,13 @@ import {
|
|
|
6
6
|
assertCodeBuildRecipe,
|
|
7
7
|
createCodeRuntimeControlClient,
|
|
8
8
|
runCodeRuntimeHeartbeatLoop
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-L2T3LPEF.js";
|
|
10
10
|
import {
|
|
11
11
|
assertPinnedImage,
|
|
12
12
|
selectContainerEngine
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-
|
|
15
|
-
import "./chunk-
|
|
13
|
+
} from "./chunk-K76I2TCQ.js";
|
|
14
|
+
import "./chunk-FVOMJKWK.js";
|
|
15
|
+
import "./chunk-LNQNFGQC.js";
|
|
16
16
|
|
|
17
17
|
// src/code-runtime-cli.ts
|
|
18
18
|
import { cpus, totalmem } from "os";
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/protocol.ts","../src/client.ts","../src/ai.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./protocol\";\nexport * from \"./client\";\nexport * from \"./ai\";\n","import type { ChatInput, OracleResponse } from \"@odla-ai/ai\";\n\n/** Current JSONL protocol version exchanged between a runner and an agent container. */\nexport const HARNESS_PROTOCOL_VERSION = 1 as const;\n\n/** Default control-plane route used for model inference requested by coding agents. */\nexport const DEFAULT_AI_ROUTE = \"coding\" as const;\n\n/** Lifecycle state reported for a harness task and its active attempt. */\nexport type HarnessTaskStatus =\n | \"queued\"\n | \"running\"\n | \"cancel_requested\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** Lifecycle state of one execution attempt for a task. */\nexport type HarnessAttemptStatus = HarnessTaskStatus;\n\n/** Trusted or untrusted participant that emitted a harness event. */\nexport type HarnessActor = \"operator\" | \"runner\" | \"agent\" | \"model\" | \"system\";\n\n/** Resource and isolation limits enforced while an untrusted task executes. */\nexport interface HarnessPolicy {\n network: \"none\";\n timeoutMs: number;\n maxOutputBytes: number;\n maxPatchBytes: number;\n}\n\n/** Immutable task instructions and execution policy delivered with a lease. */\nexport interface HarnessTaskSpec {\n taskId: string;\n attemptId: string;\n title: string;\n prompt: string;\n workspace: string;\n aiRoute: string;\n policy: HarnessPolicy;\n parentAttemptId?: string | null;\n checkpointSeq?: number | null;\n}\n\n/** Time-bound assignment authorizing a runner to execute one task attempt. */\nexport interface HarnessLease {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n leaseId: string;\n generation: number;\n expiresAt: number;\n task: HarnessTaskSpec;\n}\n\n/** Runner-supplied event before the control plane assigns sequence and task metadata. */\nexport interface HarnessEventInput {\n eventId: string;\n kind: string;\n actor: HarnessActor;\n payload: unknown;\n createdAt: number;\n}\n\n/** Persisted, ordered event associated with a specific task attempt. */\nexport interface HarnessEvent extends HarnessEventInput {\n seq: number;\n taskId: string;\n attemptId: string;\n}\n\n/** List-view metadata for a task and its current attempt. */\nexport interface HarnessTaskSummary {\n taskId: string;\n attemptId: string;\n appId: string;\n env: string;\n title: string;\n prompt: string;\n workspace: string;\n aiRoute: string;\n status: HarnessTaskStatus;\n parentAttemptId: string | null;\n checkpointSeq: number | null;\n runnerId: string | null;\n generation: number;\n createdAt: number;\n updatedAt: number;\n}\n\n/** List-view metadata for one attempt, including retry ancestry and runner ownership. */\nexport interface HarnessAttemptSummary {\n attemptId: string;\n taskId: string;\n parentAttemptId: string | null;\n checkpointSeq: number | null;\n status: HarnessAttemptStatus;\n runnerId: string | null;\n generation: number;\n createdAt: number;\n updatedAt: number;\n}\n\n/** Complete task view including attempts, events, result, and generated patch. */\nexport interface HarnessTaskDetail extends HarnessTaskSummary {\n attempts: HarnessAttemptSummary[];\n events: HarnessEvent[];\n patch: string | null;\n result: unknown;\n}\n\n/** Public control-plane view of a registered harness runner. */\nexport interface HarnessRunnerView {\n runnerId: string;\n appId: string;\n env: string;\n name: string;\n createdAt: number;\n lastSeenAt: number | null;\n revokedAt: number | null;\n}\n\n/** Credential-free normalized model request sent from an agent through the runner. */\nexport interface HarnessInferenceRequest {\n requestId: string;\n /** Exact initial, follow-up, or resume command whose budget this call consumes. */\n interactionId?: string;\n call: ChatInput;\n}\n\n/** Normalized model response plus auditable provider, policy, and token metadata. */\nexport interface HarnessInferenceResponse {\n requestId: string;\n response: OracleResponse;\n receipt: {\n provider: string;\n model: string;\n policyVersion: number;\n inputTokens: number;\n outputTokens: number;\n };\n}\n\n/** Bounded, content-free session activity emitted by a Code runtime. Message\n * bodies are projected separately into the app's owner-private odla-db chat. */\nexport type CodeSessionEventData =\n | { type: \"message\"; actor: \"agent\" | \"system\"; body: string }\n | { type: \"diagnostic\"; level: \"error\"; message: string }\n | { type: \"thinking\"; available: true; durationMs: number }\n | { type: \"tool\"; phase: \"started\"; tool: HarnessToolName }\n | { type: \"tool\"; phase: \"completed\"; tool: HarnessToolName; ok: boolean; durationMs: number }\n | {\n type: \"usage\"; provider: string; model: string;\n inputTokens: number; outputTokens: number; durationMs: number;\n interactionId?: string; interactionTokens?: number; interactionMaxTokens?: number;\n }\n | {\n type: \"status\"; status: \"running\" | \"idle\" | \"failed\" | \"checkpointed\";\n durationMs?: number;\n };\n\n/** Registry-assigned cursor and timestamp for an owner-visible Code event. */\nexport type CodeSessionEvent = CodeSessionEventData & {\n eventId: string; sequence: number; createdAt: number;\n};\n\n/** Closed set of effects an agent container may request from its trusted broker. */\nexport type HarnessToolName =\n | \"sandbox.read\"\n | \"sandbox.list\"\n | \"sandbox.search\"\n | \"sandbox.overview\"\n | \"sandbox.where_is\"\n | \"sandbox.who_imports\"\n | \"sandbox.who_touches\"\n | \"sandbox.apply_patch\"\n | \"sandbox.run_recipe\";\n/** Correlated, structured tool request emitted by an untrusted agent container. */\nexport interface HarnessToolRequest {\n requestId: string;\n tool: HarnessToolName;\n input: Record<string, unknown>;\n}\n/** Bounded tool result returned to an agent after trusted policy evaluation. */\nexport interface HarnessToolResponse {\n requestId: string;\n ok: boolean;\n content: string;\n details?: Record<string, unknown>;\n}\n\n/** Validated JSONL message emitted by an untrusted agent container. */\nexport type HarnessAgentOutput =\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"event\";\n kind: string;\n payload?: unknown;\n }\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"inference.request\";\n requestId: string;\n call: ChatInput;\n }\n | ({ protocolVersion: typeof HARNESS_PROTOCOL_VERSION; type: \"tool.request\" } & HarnessToolRequest)\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"attempt.complete\";\n status: \"completed\" | \"failed\" | \"cancelled\";\n result?: unknown;\n };\n\n/** JSONL command or inference result written by the trusted runner to an agent. */\nexport type HarnessAgentInput =\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"task.start\";\n task: HarnessTaskSpec;\n }\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"inference.response\";\n requestId: string;\n response: OracleResponse;\n }\n | ({ protocolVersion: typeof HARNESS_PROTOCOL_VERSION; type: \"tool.response\" } & HarnessToolResponse)\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"attempt.cancel\";\n reason: string;\n };\n\n/** Terminal attempt report submitted by a runner to the control plane. */\nexport interface HarnessCompletion {\n status: \"completed\" | \"failed\" | \"cancelled\";\n result?: unknown;\n patch?: string;\n error?: string;\n}\n\n/** Operations a credentialed runner may perform against the harness control plane. */\nexport interface HarnessControlPlane {\n lease(workspaces: string[]): Promise<HarnessLease | null>;\n heartbeat(attemptId: string, leaseId: string): Promise<{ cancelRequested: boolean; expiresAt: number }>;\n appendEvents(attemptId: string, leaseId: string, events: HarnessEventInput[]): Promise<void>;\n infer(attemptId: string, leaseId: string, request: HarnessInferenceRequest): Promise<HarnessInferenceResponse>;\n complete(attemptId: string, leaseId: string, completion: HarnessCompletion): Promise<void>;\n}\n\n/** Trusted inference bridge used to keep model credentials outside agent containers. */\nexport interface HarnessAiConnection {\n infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse>;\n}\n\n/** Trusted tool boundary. Implementations must evaluate CaMeL policy before effects. */\nexport interface HarnessToolBroker {\n execute(\n context: { lease: HarnessLease; workspaceDir: string; signal?: AbortSignal },\n request: HarnessToolRequest,\n ): Promise<HarnessToolResponse>;\n}\n","import type { ChatInput } from \"@odla-ai/ai\";\nimport {\n HARNESS_PROTOCOL_VERSION,\n type HarnessAgentInput,\n type HarnessAgentOutput,\n type HarnessEventInput,\n} from \"./types\";\n\nconst CONTROL = /[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/;\n\n/** Error raised when an agent emits malformed, oversized, or unsupported protocol data. */\nexport class HarnessProtocolError extends Error {\n override readonly name = \"HarnessProtocolError\";\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n}\n\nfunction boundedText(value: unknown, label: string, max: number): string {\n if (typeof value !== \"string\" || !value || value.length > max || CONTROL.test(value)) {\n throw new HarnessProtocolError(`${label} must be a non-empty string of at most ${max} characters`);\n }\n return value;\n}\n\n/** Parse and validate one newline-delimited message emitted by an agent container. */\nexport function parseAgentOutput(line: string): HarnessAgentOutput {\n if (Buffer.byteLength(line, \"utf8\") > 1_000_000) throw new HarnessProtocolError(\"agent message exceeds 1 MB\");\n let value: unknown;\n try { value = JSON.parse(line); } catch { throw new HarnessProtocolError(\"agent emitted invalid JSON\"); }\n const message = record(value);\n if (!message || message.protocolVersion !== HARNESS_PROTOCOL_VERSION) {\n throw new HarnessProtocolError(`agent protocolVersion must be ${HARNESS_PROTOCOL_VERSION}`);\n }\n if (message.type === \"event\") {\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"event\",\n kind: boundedText(message.kind, \"event.kind\", 120),\n ...(message.payload === undefined ? {} : { payload: message.payload }),\n };\n }\n if (message.type === \"inference.request\") {\n const call = record(message.call);\n if (!call || !Array.isArray(call.messages) || !Number.isSafeInteger(call.maxTokens)) {\n throw new HarnessProtocolError(\"inference.request.call requires messages and maxTokens\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"inference.request\",\n requestId: boundedText(message.requestId, \"requestId\", 180),\n call: call as unknown as ChatInput,\n };\n }\n if (message.type === \"tool.request\") {\n const input = record(message.input);\n const tool = String(message.tool);\n if (!input || ![\"sandbox.read\", \"sandbox.apply_patch\", \"sandbox.run_recipe\"].includes(tool)) {\n throw new HarnessProtocolError(\"tool.request requires a registered tool and object input\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"tool.request\",\n requestId: boundedText(message.requestId, \"requestId\", 180),\n tool: tool as \"sandbox.read\" | \"sandbox.apply_patch\" | \"sandbox.run_recipe\",\n input,\n };\n }\n if (message.type === \"attempt.complete\") {\n if (!new Set([\"completed\", \"failed\", \"cancelled\"]).has(String(message.status))) {\n throw new HarnessProtocolError(\"attempt.complete.status is invalid\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"attempt.complete\",\n status: message.status as \"completed\" | \"failed\" | \"cancelled\",\n ...(message.result === undefined ? {} : { result: message.result }),\n };\n }\n throw new HarnessProtocolError(\"agent message type is unsupported\");\n}\n\n/** Serialize one trusted runner message as a newline-terminated JSONL record. */\nexport function encodeAgentInput(message: HarnessAgentInput): string {\n return `${JSON.stringify(message)}\\n`;\n}\n\n/** Create a timestamped, uniquely identified event for control-plane submission. */\nexport function makeHarnessEvent(\n kind: string,\n actor: HarnessEventInput[\"actor\"],\n payload: unknown,\n now = Date.now(),\n id = crypto.randomUUID(),\n): HarnessEventInput {\n boundedText(kind, \"event.kind\", 120);\n return { eventId: id, kind, actor, payload, createdAt: now };\n}\n","import type {\n HarnessCompletion,\n HarnessControlPlane,\n HarnessEventInput,\n HarnessInferenceRequest,\n HarnessInferenceResponse,\n HarnessLease,\n} from \"./types\";\n\n/** HTTP error returned by the harness control plane, including its stable error code. */\nexport class HarnessControlError extends Error {\n override readonly name = \"HarnessControlError\";\n constructor(message: string, readonly status: number, readonly code = \"control_error\") { super(message); }\n}\n\n/** Connection, credential, cancellation, and timeout settings for a runner client. */\nexport interface HarnessControlClientOptions {\n endpoint: string;\n token: string;\n fetch?: typeof fetch;\n requestTimeoutMs?: number;\n signal?: AbortSignal;\n}\n\n/** Create a validated HTTPS client implementing the runner control-plane operations. */\nexport function createHarnessControlClient(options: HarnessControlClientOptions): HarnessControlPlane {\n const endpoint = options.endpoint.replace(/\\/+$/, \"\");\n let endpointUrl: URL;\n try { endpointUrl = new URL(endpoint); } catch { throw new TypeError(\"endpoint must be an HTTPS URL\"); }\n const loopback = endpointUrl.hostname === \"localhost\" || endpointUrl.hostname === \"127.0.0.1\" || endpointUrl.hostname === \"[::1]\";\n if (endpointUrl.username || endpointUrl.password || (endpointUrl.protocol !== \"https:\" && !(loopback && endpointUrl.protocol === \"http:\"))) {\n throw new TypeError(\"endpoint must use HTTPS (HTTP is allowed only for loopback testing)\");\n }\n if (!/^odla_hrn_[0-9a-f]{64}$/.test(options.token)) throw new TypeError(\"invalid harness runner credential\");\n const requestTimeoutMs = options.requestTimeoutMs ?? 30_000;\n if (!Number.isSafeInteger(requestTimeoutMs) || requestTimeoutMs < 1_000 || requestTimeoutMs > 120_000) {\n throw new TypeError(\"requestTimeoutMs must be an integer from 1000 to 120000\");\n }\n const request = options.fetch ?? fetch;\n const call = async <T>(path: string, body: unknown, allowEmpty = false): Promise<T | null> => {\n const timeout = AbortSignal.timeout(requestTimeoutMs);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n const response = await request(`${endpoint}${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${options.token}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n redirect: \"error\",\n signal,\n });\n if (allowEmpty && response.status === 204) return null;\n const value = await response.json().catch(() => null) as { error?: { code?: string; message?: string } } | null;\n if (!response.ok) throw new HarnessControlError(\n value?.error?.message ?? `harness control request failed (${response.status})`,\n response.status,\n value?.error?.code,\n );\n return value as T;\n };\n return {\n lease: async (workspaces) => {\n const body = await call<{ lease: HarnessLease }>(\"/registry/harness/lease\", { workspaces }, true);\n return body?.lease ?? null;\n },\n heartbeat: async (attemptId, leaseId) => {\n const body = await call<{ cancelRequested: boolean; expiresAt: number }>(\n `/registry/harness/attempts/${encodeURIComponent(attemptId)}/heartbeat`, { leaseId },\n );\n return body!;\n },\n appendEvents: async (attemptId, leaseId, events: HarnessEventInput[]) => {\n await call(`/registry/harness/attempts/${encodeURIComponent(attemptId)}/events`, { leaseId, events });\n },\n infer: async (attemptId, leaseId, inference: HarnessInferenceRequest) => {\n const body = await call<HarnessInferenceResponse>(\n `/registry/harness/attempts/${encodeURIComponent(attemptId)}/inference`, { leaseId, ...inference },\n );\n return body!;\n },\n complete: async (attemptId, leaseId, completion: HarnessCompletion) => {\n await call(`/registry/harness/attempts/${encodeURIComponent(attemptId)}/complete`, { leaseId, ...completion });\n },\n };\n}\n","import type { Ai } from \"@odla-ai/ai\";\nimport type { HarnessAiConnection, HarnessInferenceRequest, HarnessInferenceResponse } from \"./types\";\n\n/**\n * Adapt the normalized odla AI chat surface to a harness connection.\n * Provider credentials remain in the process that owns `ai`; only normalized\n * requests and responses cross the container protocol.\n */\nexport function createOdlaAiConnection(\n ai: Pick<Ai, \"chat\">,\n options: { model?: string; policyVersion?: number } = {},\n): HarnessAiConnection {\n return {\n async infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse> {\n const response = await ai.chat({ ...request.call, ...(options.model ? { model: options.model } : {}) });\n return {\n requestId: request.requestId,\n response,\n receipt: {\n provider: response.provider,\n model: response.model,\n policyVersion: options.policyVersion ?? 1,\n inputTokens: response.usage.inputTokens ?? 0,\n outputTokens: response.usage.outputTokens ?? 0,\n },\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/protocol.ts","../src/client.ts","../src/ai.ts"],"sourcesContent":["export * from \"./types\";\nexport * from \"./protocol\";\nexport * from \"./client\";\nexport * from \"./ai\";\n","import type { ChatInput, OracleResponse } from \"@odla-ai/ai\";\n\n/** Current JSONL protocol version exchanged between a runner and an agent container. */\nexport const HARNESS_PROTOCOL_VERSION = 1 as const;\n\n/** Default control-plane route used for model inference requested by coding agents. */\nexport const DEFAULT_AI_ROUTE = \"coding\" as const;\n\n/** Lifecycle state reported for a harness task and its active attempt. */\nexport type HarnessTaskStatus =\n | \"queued\"\n | \"running\"\n | \"cancel_requested\"\n | \"completed\"\n | \"failed\"\n | \"cancelled\";\n\n/** Lifecycle state of one execution attempt for a task. */\nexport type HarnessAttemptStatus = HarnessTaskStatus;\n\n/** Trusted or untrusted participant that emitted a harness event. */\nexport type HarnessActor = \"operator\" | \"runner\" | \"agent\" | \"model\" | \"system\";\n\n/** Resource and isolation limits enforced while an untrusted task executes. */\nexport interface HarnessPolicy {\n network: \"none\";\n timeoutMs: number;\n maxOutputBytes: number;\n maxPatchBytes: number;\n}\n\n/** Immutable task instructions and execution policy delivered with a lease. */\nexport interface HarnessTaskSpec {\n taskId: string;\n attemptId: string;\n title: string;\n prompt: string;\n workspace: string;\n aiRoute: string;\n policy: HarnessPolicy;\n parentAttemptId?: string | null;\n checkpointSeq?: number | null;\n}\n\n/** Time-bound assignment authorizing a runner to execute one task attempt. */\nexport interface HarnessLease {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n leaseId: string;\n generation: number;\n expiresAt: number;\n task: HarnessTaskSpec;\n}\n\n/** Runner-supplied event before the control plane assigns sequence and task metadata. */\nexport interface HarnessEventInput {\n eventId: string;\n kind: string;\n actor: HarnessActor;\n payload: unknown;\n createdAt: number;\n}\n\n/** Persisted, ordered event associated with a specific task attempt. */\nexport interface HarnessEvent extends HarnessEventInput {\n seq: number;\n taskId: string;\n attemptId: string;\n}\n\n/** List-view metadata for a task and its current attempt. */\nexport interface HarnessTaskSummary {\n taskId: string;\n attemptId: string;\n appId: string;\n env: string;\n title: string;\n prompt: string;\n workspace: string;\n aiRoute: string;\n status: HarnessTaskStatus;\n parentAttemptId: string | null;\n checkpointSeq: number | null;\n runnerId: string | null;\n generation: number;\n createdAt: number;\n updatedAt: number;\n}\n\n/** List-view metadata for one attempt, including retry ancestry and runner ownership. */\nexport interface HarnessAttemptSummary {\n attemptId: string;\n taskId: string;\n parentAttemptId: string | null;\n checkpointSeq: number | null;\n status: HarnessAttemptStatus;\n runnerId: string | null;\n generation: number;\n createdAt: number;\n updatedAt: number;\n}\n\n/** Complete task view including attempts, events, result, and generated patch. */\nexport interface HarnessTaskDetail extends HarnessTaskSummary {\n attempts: HarnessAttemptSummary[];\n events: HarnessEvent[];\n patch: string | null;\n result: unknown;\n}\n\n/** Public control-plane view of a registered harness runner. */\nexport interface HarnessRunnerView {\n runnerId: string;\n appId: string;\n env: string;\n name: string;\n createdAt: number;\n lastSeenAt: number | null;\n revokedAt: number | null;\n}\n\n/** Credential-free normalized model request sent from an agent through the runner. */\nexport interface HarnessInferenceRequest {\n requestId: string;\n /** Exact initial, follow-up, or resume command whose budget this call consumes. */\n interactionId?: string;\n call: ChatInput;\n}\n\n/** Normalized model response plus auditable provider, policy, and token metadata. */\nexport interface HarnessInferenceResponse {\n requestId: string;\n response: OracleResponse;\n receipt: {\n provider: string;\n model: string;\n policyVersion: number;\n inputTokens: number;\n outputTokens: number;\n /**\n * USD charged for this call, priced against the model the control plane\n * actually resolved.\n *\n * ABSENT when the live catalog has no price for that model — never zero.\n * An unpriced call is unknown spend, and reporting it as free is what let\n * a goal's `maxUsd` look enforced while nothing enforced it. The runtime\n * cannot compute this itself: it asks for `brokered` and only the control\n * plane knows which model answered.\n */\n costUsd?: number;\n };\n}\n\n/** Bounded, content-free session activity emitted by a Code runtime. Message\n * bodies are projected separately into the app's owner-private odla-db chat. */\nexport type CodeSessionEventData =\n | { type: \"message\"; actor: \"agent\" | \"system\"; body: string }\n | { type: \"diagnostic\"; level: \"error\"; message: string }\n | { type: \"thinking\"; available: true; durationMs: number }\n | { type: \"tool\"; phase: \"started\"; tool: HarnessToolName }\n | { type: \"tool\"; phase: \"completed\"; tool: HarnessToolName; ok: boolean; durationMs: number }\n | {\n type: \"usage\"; provider: string; model: string;\n inputTokens: number; outputTokens: number; durationMs: number;\n interactionId?: string; interactionTokens?: number; interactionMaxTokens?: number;\n /** USD for this call; absent when the model is unpriced, never zero. */\n costUsd?: number;\n /** Cumulative USD for this owner interaction, when every call in it was\n * priced. Absent the moment one was not, so a partial total can never be\n * mistaken for the whole. */\n interactionCostUsd?: number;\n }\n | {\n type: \"status\"; status: \"running\" | \"idle\" | \"failed\" | \"checkpointed\";\n durationMs?: number;\n };\n\n/** Registry-assigned cursor and timestamp for an owner-visible Code event. */\nexport type CodeSessionEvent = CodeSessionEventData & {\n eventId: string; sequence: number; createdAt: number;\n};\n\n/** Closed set of effects an agent container may request from its trusted broker. */\nexport type HarnessToolName =\n | \"sandbox.read\"\n | \"sandbox.list\"\n | \"sandbox.search\"\n | \"sandbox.overview\"\n | \"sandbox.where_is\"\n | \"sandbox.who_imports\"\n | \"sandbox.who_touches\"\n | \"sandbox.apply_patch\"\n | \"sandbox.run_recipe\";\n/** Correlated, structured tool request emitted by an untrusted agent container. */\nexport interface HarnessToolRequest {\n requestId: string;\n tool: HarnessToolName;\n input: Record<string, unknown>;\n}\n/** Bounded tool result returned to an agent after trusted policy evaluation. */\nexport interface HarnessToolResponse {\n requestId: string;\n ok: boolean;\n content: string;\n details?: Record<string, unknown>;\n}\n\n/** Validated JSONL message emitted by an untrusted agent container. */\nexport type HarnessAgentOutput =\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"event\";\n kind: string;\n payload?: unknown;\n }\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"inference.request\";\n requestId: string;\n call: ChatInput;\n }\n | ({ protocolVersion: typeof HARNESS_PROTOCOL_VERSION; type: \"tool.request\" } & HarnessToolRequest)\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"attempt.complete\";\n status: \"completed\" | \"failed\" | \"cancelled\";\n result?: unknown;\n };\n\n/** JSONL command or inference result written by the trusted runner to an agent. */\nexport type HarnessAgentInput =\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"task.start\";\n task: HarnessTaskSpec;\n }\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"inference.response\";\n requestId: string;\n response: OracleResponse;\n }\n | ({ protocolVersion: typeof HARNESS_PROTOCOL_VERSION; type: \"tool.response\" } & HarnessToolResponse)\n | {\n protocolVersion: typeof HARNESS_PROTOCOL_VERSION;\n type: \"attempt.cancel\";\n reason: string;\n };\n\n/** Terminal attempt report submitted by a runner to the control plane. */\nexport interface HarnessCompletion {\n status: \"completed\" | \"failed\" | \"cancelled\";\n result?: unknown;\n patch?: string;\n error?: string;\n}\n\n/** Operations a credentialed runner may perform against the harness control plane. */\nexport interface HarnessControlPlane {\n lease(workspaces: string[]): Promise<HarnessLease | null>;\n heartbeat(attemptId: string, leaseId: string): Promise<{ cancelRequested: boolean; expiresAt: number }>;\n appendEvents(attemptId: string, leaseId: string, events: HarnessEventInput[]): Promise<void>;\n infer(attemptId: string, leaseId: string, request: HarnessInferenceRequest): Promise<HarnessInferenceResponse>;\n complete(attemptId: string, leaseId: string, completion: HarnessCompletion): Promise<void>;\n}\n\n/** Trusted inference bridge used to keep model credentials outside agent containers. */\nexport interface HarnessAiConnection {\n infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse>;\n}\n\n/** Trusted tool boundary. Implementations must evaluate CaMeL policy before effects. */\nexport interface HarnessToolBroker {\n execute(\n context: { lease: HarnessLease; workspaceDir: string; signal?: AbortSignal },\n request: HarnessToolRequest,\n ): Promise<HarnessToolResponse>;\n}\n","import type { ChatInput } from \"@odla-ai/ai\";\nimport {\n HARNESS_PROTOCOL_VERSION,\n type HarnessAgentInput,\n type HarnessAgentOutput,\n type HarnessEventInput,\n} from \"./types\";\n\nconst CONTROL = /[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/;\n\n/** Error raised when an agent emits malformed, oversized, or unsupported protocol data. */\nexport class HarnessProtocolError extends Error {\n override readonly name = \"HarnessProtocolError\";\n}\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null;\n}\n\nfunction boundedText(value: unknown, label: string, max: number): string {\n if (typeof value !== \"string\" || !value || value.length > max || CONTROL.test(value)) {\n throw new HarnessProtocolError(`${label} must be a non-empty string of at most ${max} characters`);\n }\n return value;\n}\n\n/** Parse and validate one newline-delimited message emitted by an agent container. */\nexport function parseAgentOutput(line: string): HarnessAgentOutput {\n if (Buffer.byteLength(line, \"utf8\") > 1_000_000) throw new HarnessProtocolError(\"agent message exceeds 1 MB\");\n let value: unknown;\n try { value = JSON.parse(line); } catch { throw new HarnessProtocolError(\"agent emitted invalid JSON\"); }\n const message = record(value);\n if (!message || message.protocolVersion !== HARNESS_PROTOCOL_VERSION) {\n throw new HarnessProtocolError(`agent protocolVersion must be ${HARNESS_PROTOCOL_VERSION}`);\n }\n if (message.type === \"event\") {\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"event\",\n kind: boundedText(message.kind, \"event.kind\", 120),\n ...(message.payload === undefined ? {} : { payload: message.payload }),\n };\n }\n if (message.type === \"inference.request\") {\n const call = record(message.call);\n if (!call || !Array.isArray(call.messages) || !Number.isSafeInteger(call.maxTokens)) {\n throw new HarnessProtocolError(\"inference.request.call requires messages and maxTokens\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"inference.request\",\n requestId: boundedText(message.requestId, \"requestId\", 180),\n call: call as unknown as ChatInput,\n };\n }\n if (message.type === \"tool.request\") {\n const input = record(message.input);\n const tool = String(message.tool);\n if (!input || ![\"sandbox.read\", \"sandbox.apply_patch\", \"sandbox.run_recipe\"].includes(tool)) {\n throw new HarnessProtocolError(\"tool.request requires a registered tool and object input\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"tool.request\",\n requestId: boundedText(message.requestId, \"requestId\", 180),\n tool: tool as \"sandbox.read\" | \"sandbox.apply_patch\" | \"sandbox.run_recipe\",\n input,\n };\n }\n if (message.type === \"attempt.complete\") {\n if (!new Set([\"completed\", \"failed\", \"cancelled\"]).has(String(message.status))) {\n throw new HarnessProtocolError(\"attempt.complete.status is invalid\");\n }\n return {\n protocolVersion: HARNESS_PROTOCOL_VERSION,\n type: \"attempt.complete\",\n status: message.status as \"completed\" | \"failed\" | \"cancelled\",\n ...(message.result === undefined ? {} : { result: message.result }),\n };\n }\n throw new HarnessProtocolError(\"agent message type is unsupported\");\n}\n\n/** Serialize one trusted runner message as a newline-terminated JSONL record. */\nexport function encodeAgentInput(message: HarnessAgentInput): string {\n return `${JSON.stringify(message)}\\n`;\n}\n\n/** Create a timestamped, uniquely identified event for control-plane submission. */\nexport function makeHarnessEvent(\n kind: string,\n actor: HarnessEventInput[\"actor\"],\n payload: unknown,\n now = Date.now(),\n id = crypto.randomUUID(),\n): HarnessEventInput {\n boundedText(kind, \"event.kind\", 120);\n return { eventId: id, kind, actor, payload, createdAt: now };\n}\n","import type {\n HarnessCompletion,\n HarnessControlPlane,\n HarnessEventInput,\n HarnessInferenceRequest,\n HarnessInferenceResponse,\n HarnessLease,\n} from \"./types\";\n\n/** HTTP error returned by the harness control plane, including its stable error code. */\nexport class HarnessControlError extends Error {\n override readonly name = \"HarnessControlError\";\n constructor(message: string, readonly status: number, readonly code = \"control_error\") { super(message); }\n}\n\n/** Connection, credential, cancellation, and timeout settings for a runner client. */\nexport interface HarnessControlClientOptions {\n endpoint: string;\n token: string;\n fetch?: typeof fetch;\n requestTimeoutMs?: number;\n signal?: AbortSignal;\n}\n\n/** Create a validated HTTPS client implementing the runner control-plane operations. */\nexport function createHarnessControlClient(options: HarnessControlClientOptions): HarnessControlPlane {\n const endpoint = options.endpoint.replace(/\\/+$/, \"\");\n let endpointUrl: URL;\n try { endpointUrl = new URL(endpoint); } catch { throw new TypeError(\"endpoint must be an HTTPS URL\"); }\n const loopback = endpointUrl.hostname === \"localhost\" || endpointUrl.hostname === \"127.0.0.1\" || endpointUrl.hostname === \"[::1]\";\n if (endpointUrl.username || endpointUrl.password || (endpointUrl.protocol !== \"https:\" && !(loopback && endpointUrl.protocol === \"http:\"))) {\n throw new TypeError(\"endpoint must use HTTPS (HTTP is allowed only for loopback testing)\");\n }\n if (!/^odla_hrn_[0-9a-f]{64}$/.test(options.token)) throw new TypeError(\"invalid harness runner credential\");\n const requestTimeoutMs = options.requestTimeoutMs ?? 30_000;\n if (!Number.isSafeInteger(requestTimeoutMs) || requestTimeoutMs < 1_000 || requestTimeoutMs > 120_000) {\n throw new TypeError(\"requestTimeoutMs must be an integer from 1000 to 120000\");\n }\n const request = options.fetch ?? fetch;\n const call = async <T>(path: string, body: unknown, allowEmpty = false): Promise<T | null> => {\n const timeout = AbortSignal.timeout(requestTimeoutMs);\n const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;\n const response = await request(`${endpoint}${path}`, {\n method: \"POST\",\n headers: { authorization: `Bearer ${options.token}`, \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n redirect: \"error\",\n signal,\n });\n if (allowEmpty && response.status === 204) return null;\n const value = await response.json().catch(() => null) as { error?: { code?: string; message?: string } } | null;\n if (!response.ok) throw new HarnessControlError(\n value?.error?.message ?? `harness control request failed (${response.status})`,\n response.status,\n value?.error?.code,\n );\n return value as T;\n };\n return {\n lease: async (workspaces) => {\n const body = await call<{ lease: HarnessLease }>(\"/registry/harness/lease\", { workspaces }, true);\n return body?.lease ?? null;\n },\n heartbeat: async (attemptId, leaseId) => {\n const body = await call<{ cancelRequested: boolean; expiresAt: number }>(\n `/registry/harness/attempts/${encodeURIComponent(attemptId)}/heartbeat`, { leaseId },\n );\n return body!;\n },\n appendEvents: async (attemptId, leaseId, events: HarnessEventInput[]) => {\n await call(`/registry/harness/attempts/${encodeURIComponent(attemptId)}/events`, { leaseId, events });\n },\n infer: async (attemptId, leaseId, inference: HarnessInferenceRequest) => {\n const body = await call<HarnessInferenceResponse>(\n `/registry/harness/attempts/${encodeURIComponent(attemptId)}/inference`, { leaseId, ...inference },\n );\n return body!;\n },\n complete: async (attemptId, leaseId, completion: HarnessCompletion) => {\n await call(`/registry/harness/attempts/${encodeURIComponent(attemptId)}/complete`, { leaseId, ...completion });\n },\n };\n}\n","import type { Ai } from \"@odla-ai/ai\";\nimport type { HarnessAiConnection, HarnessInferenceRequest, HarnessInferenceResponse } from \"./types\";\n\n/**\n * Adapt the normalized odla AI chat surface to a harness connection.\n * Provider credentials remain in the process that owns `ai`; only normalized\n * requests and responses cross the container protocol.\n */\nexport function createOdlaAiConnection(\n ai: Pick<Ai, \"chat\">,\n options: { model?: string; policyVersion?: number } = {},\n): HarnessAiConnection {\n return {\n async infer(request: HarnessInferenceRequest): Promise<HarnessInferenceResponse> {\n const response = await ai.chat({ ...request.call, ...(options.model ? { model: options.model } : {}) });\n return {\n requestId: request.requestId,\n response,\n receipt: {\n provider: response.provider,\n model: response.model,\n policyVersion: options.policyVersion ?? 1,\n inputTokens: response.usage.inputTokens ?? 0,\n outputTokens: response.usage.outputTokens ?? 0,\n },\n };\n },\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as HarnessAgentInput, b as HarnessEventInput, g as HarnessAgentOutput, H as HarnessControlPlane, h as HarnessAiConnection } from './types-
|
|
2
|
-
export { C as CodeSessionEvent, i as CodeSessionEventData, D as DEFAULT_AI_ROUTE, j as HARNESS_PROTOCOL_VERSION, k as HarnessActor, l as HarnessAttemptStatus, m as HarnessAttemptSummary, c as HarnessCompletion, n as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, o as HarnessPolicy, p as HarnessRunnerView, q as HarnessTaskDetail, r as HarnessTaskSpec, s as HarnessTaskStatus, t as HarnessTaskSummary, u as HarnessToolBroker, v as HarnessToolName, w as HarnessToolRequest, x as HarnessToolResponse } from './types-
|
|
1
|
+
import { f as HarnessAgentInput, b as HarnessEventInput, g as HarnessAgentOutput, H as HarnessControlPlane, h as HarnessAiConnection } from './types-CK5EKmKm.cjs';
|
|
2
|
+
export { C as CodeSessionEvent, i as CodeSessionEventData, D as DEFAULT_AI_ROUTE, j as HARNESS_PROTOCOL_VERSION, k as HarnessActor, l as HarnessAttemptStatus, m as HarnessAttemptSummary, c as HarnessCompletion, n as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, o as HarnessPolicy, p as HarnessRunnerView, q as HarnessTaskDetail, r as HarnessTaskSpec, s as HarnessTaskStatus, t as HarnessTaskSummary, u as HarnessToolBroker, v as HarnessToolName, w as HarnessToolRequest, x as HarnessToolResponse } from './types-CK5EKmKm.cjs';
|
|
3
3
|
import { Ai } from '@odla-ai/ai';
|
|
4
4
|
|
|
5
5
|
/** Error raised when an agent emits malformed, oversized, or unsupported protocol data. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as HarnessAgentInput, b as HarnessEventInput, g as HarnessAgentOutput, H as HarnessControlPlane, h as HarnessAiConnection } from './types-
|
|
2
|
-
export { C as CodeSessionEvent, i as CodeSessionEventData, D as DEFAULT_AI_ROUTE, j as HARNESS_PROTOCOL_VERSION, k as HarnessActor, l as HarnessAttemptStatus, m as HarnessAttemptSummary, c as HarnessCompletion, n as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, o as HarnessPolicy, p as HarnessRunnerView, q as HarnessTaskDetail, r as HarnessTaskSpec, s as HarnessTaskStatus, t as HarnessTaskSummary, u as HarnessToolBroker, v as HarnessToolName, w as HarnessToolRequest, x as HarnessToolResponse } from './types-
|
|
1
|
+
import { f as HarnessAgentInput, b as HarnessEventInput, g as HarnessAgentOutput, H as HarnessControlPlane, h as HarnessAiConnection } from './types-CK5EKmKm.js';
|
|
2
|
+
export { C as CodeSessionEvent, i as CodeSessionEventData, D as DEFAULT_AI_ROUTE, j as HARNESS_PROTOCOL_VERSION, k as HarnessActor, l as HarnessAttemptStatus, m as HarnessAttemptSummary, c as HarnessCompletion, n as HarnessEvent, d as HarnessInferenceRequest, e as HarnessInferenceResponse, a as HarnessLease, o as HarnessPolicy, p as HarnessRunnerView, q as HarnessTaskDetail, r as HarnessTaskSpec, s as HarnessTaskStatus, t as HarnessTaskSummary, u as HarnessToolBroker, v as HarnessToolName, w as HarnessToolRequest, x as HarnessToolResponse } from './types-CK5EKmKm.js';
|
|
3
3
|
import { Ai } from '@odla-ai/ai';
|
|
4
4
|
|
|
5
5
|
/** Error raised when an agent emits malformed, oversized, or unsupported protocol data. */
|
package/dist/index.js
CHANGED
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
encodeAgentInput,
|
|
8
8
|
makeHarnessEvent,
|
|
9
9
|
parseAgentOutput
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FVOMJKWK.js";
|
|
11
11
|
import {
|
|
12
12
|
DEFAULT_AI_ROUTE,
|
|
13
13
|
HARNESS_PROTOCOL_VERSION
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-LNQNFGQC.js";
|
|
15
15
|
|
|
16
16
|
// src/ai.ts
|
|
17
17
|
function createOdlaAiConnection(ai, options = {}) {
|
package/dist/node.cjs
CHANGED
|
@@ -1055,6 +1055,7 @@ function parseSnapshot(value) {
|
|
|
1055
1055
|
return { host, bindings, commands };
|
|
1056
1056
|
}
|
|
1057
1057
|
async function parseSource(value) {
|
|
1058
|
+
const repositoryLimits = { maximumFiles: 1e5, maximumBytes: 80 * 1024 * 1024 };
|
|
1058
1059
|
const snapshot = record2(record2(value)?.snapshot);
|
|
1059
1060
|
if (!snapshot || typeof snapshot.repository !== "string" || typeof snapshot.commitSha !== "string" || typeof snapshot.treeDigest !== "string" || !Array.isArray(snapshot.files)) throw invalid("source");
|
|
1060
1061
|
const files = snapshot.files.map((value2) => {
|
|
@@ -1076,12 +1077,12 @@ async function parseSource(value) {
|
|
|
1076
1077
|
return { path: file.path, content: file.content };
|
|
1077
1078
|
});
|
|
1078
1079
|
const source2 = { repository: reference.repository, commitSha: reference.commitSha, files: referenceFiles };
|
|
1079
|
-
const referenceDigest = await (0, import_code.digestCodeRepositorySnapshot)(source2,
|
|
1080
|
+
const referenceDigest = await (0, import_code.digestCodeRepositorySnapshot)(source2, repositoryLimits);
|
|
1080
1081
|
if (referenceDigest !== reference.treeDigest) throw invalid("reference source digest");
|
|
1081
1082
|
references.push({ alias: reference.alias, ...source2, treeDigest: referenceDigest });
|
|
1082
1083
|
}
|
|
1083
1084
|
const source = { repository: snapshot.repository, commitSha: snapshot.commitSha, files };
|
|
1084
|
-
const digest = await (0, import_code.digestCodeRepositorySnapshot)(source,
|
|
1085
|
+
const digest = await (0, import_code.digestCodeRepositorySnapshot)(source, repositoryLimits);
|
|
1085
1086
|
if (digest !== snapshot.treeDigest) throw invalid("source digest");
|
|
1086
1087
|
return { ...source, treeDigest: digest, ...references.length ? { references } : {} };
|
|
1087
1088
|
}
|
|
@@ -1848,8 +1849,11 @@ var import_node_os3 = require("os");
|
|
|
1848
1849
|
var import_node_path8 = require("path");
|
|
1849
1850
|
var RESERVED2 = /* @__PURE__ */ new Set([".git", ".odla", ".wrangler", "node_modules", "dist", "coverage"]);
|
|
1850
1851
|
var SECRET2 = /^(?:\.env(?:\..+)?|\.dev\.vars|credentials(?:\..+)?\.json|dev-token(?:\..+)?\.json)$/i;
|
|
1852
|
+
var SOURCE_MAX_FILES = 1e5;
|
|
1853
|
+
var SOURCE_MAX_BYTES = 80 * 1024 * 1024;
|
|
1854
|
+
var SOURCE_SET_MAX_BYTES = 480 * 1024 * 1024;
|
|
1851
1855
|
async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_node_os3.tmpdir)()) {
|
|
1852
|
-
if (!snapshot.files.length || snapshot.files.length >
|
|
1856
|
+
if (!snapshot.files.length || snapshot.files.length > SOURCE_MAX_FILES) throw new TypeError("Code source file count is invalid");
|
|
1853
1857
|
const root = await (0, import_promises8.mkdtemp)((0, import_node_path8.join)(tempRoot, "odla-code-source-"));
|
|
1854
1858
|
const sourceDir = (0, import_node_path8.join)(root, "source");
|
|
1855
1859
|
await (0, import_promises8.mkdir)(sourceDir);
|
|
@@ -1861,7 +1865,7 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_node
|
|
|
1861
1865
|
if (seen.has(file.path)) throw new TypeError("Code source repeats a path");
|
|
1862
1866
|
seen.add(file.path);
|
|
1863
1867
|
bytes += Buffer.byteLength(file.path) + Buffer.byteLength(file.content);
|
|
1864
|
-
if (bytes >
|
|
1868
|
+
if (bytes > SOURCE_MAX_BYTES) throw new TypeError("Code source exceeds its byte bound");
|
|
1865
1869
|
const target = (0, import_node_path8.resolve)(sourceDir, file.path);
|
|
1866
1870
|
if (!target.startsWith(`${(0, import_node_path8.resolve)(sourceDir)}${import_node_path8.sep}`)) throw new TypeError("Code source path escapes its root");
|
|
1867
1871
|
await (0, import_promises8.mkdir)((0, import_node_path8.dirname)(target), { recursive: true });
|
|
@@ -1869,14 +1873,14 @@ async function materializeCodeRuntimeSource(snapshot, tempRoot = (0, import_node
|
|
|
1869
1873
|
}
|
|
1870
1874
|
for (const reference of snapshot.references ?? []) {
|
|
1871
1875
|
validateAlias(reference.alias);
|
|
1872
|
-
if (!reference.files.length || reference.files.length >
|
|
1876
|
+
if (!reference.files.length || reference.files.length > SOURCE_MAX_FILES) throw new TypeError("Code reference file count is invalid");
|
|
1873
1877
|
for (const file of reference.files) {
|
|
1874
1878
|
validatePath(file.path);
|
|
1875
1879
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
1876
1880
|
if (seen.has(path)) throw new TypeError("Code reference repeats a path");
|
|
1877
1881
|
seen.add(path);
|
|
1878
1882
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
1879
|
-
if (bytes >
|
|
1883
|
+
if (bytes > SOURCE_SET_MAX_BYTES) throw new TypeError("Code source set exceeds its byte bound");
|
|
1880
1884
|
const target = (0, import_node_path8.resolve)(sourceDir, path);
|
|
1881
1885
|
if (!target.startsWith(`${(0, import_node_path8.resolve)(sourceDir)}${import_node_path8.sep}`)) throw new TypeError("Code reference path escapes its root");
|
|
1882
1886
|
await (0, import_promises8.mkdir)((0, import_node_path8.dirname)(target), { recursive: true });
|
|
@@ -1902,7 +1906,7 @@ async function attachCodeRuntimeReferences(workspace, references) {
|
|
|
1902
1906
|
validatePath(file.path);
|
|
1903
1907
|
const path = `.odla-references/${reference.alias}/${file.path}`;
|
|
1904
1908
|
bytes += Buffer.byteLength(path) + Buffer.byteLength(file.content);
|
|
1905
|
-
if (bytes >
|
|
1909
|
+
if (bytes > SOURCE_SET_MAX_BYTES - SOURCE_MAX_BYTES) throw new TypeError("Code reference set exceeds its byte bound");
|
|
1906
1910
|
for (const root of [workspace.baselineDir, workspace.workspaceDir]) {
|
|
1907
1911
|
const target = (0, import_node_path8.resolve)(root, path);
|
|
1908
1912
|
if (!target.startsWith(`${(0, import_node_path8.resolve)(root)}${import_node_path8.sep}`)) throw new TypeError("Code reference path escapes its root");
|
|
@@ -1952,7 +1956,10 @@ async function materializeCommandWorkspace(input) {
|
|
|
1952
1956
|
trustedBaseDir: materialized.sourceDir,
|
|
1953
1957
|
trustedBaseCommitSha: source.commitSha,
|
|
1954
1958
|
checkpoint: codeCheckpointPayload(command.payload)
|
|
1955
|
-
})).workspace : await stageWorkspace(materialized.sourceDir
|
|
1959
|
+
})).workspace : await stageWorkspace(materialized.sourceDir, {
|
|
1960
|
+
maxFiles: SOURCE_MAX_FILES,
|
|
1961
|
+
maxBytes: SOURCE_SET_MAX_BYTES
|
|
1962
|
+
});
|
|
1956
1963
|
return { workspace, sourceDigest: source.treeDigest, requestedLocal: null };
|
|
1957
1964
|
} finally {
|
|
1958
1965
|
await materialized.cleanup();
|
|
@@ -2220,6 +2227,9 @@ async function handleCodeRuntimeInference(input) {
|
|
|
2220
2227
|
call: request.call
|
|
2221
2228
|
});
|
|
2222
2229
|
state.tokens += response2.receipt.inputTokens + response2.receipt.outputTokens;
|
|
2230
|
+
const { costUsd } = response2.receipt;
|
|
2231
|
+
if (costUsd === void 0) state.costKnown = false;
|
|
2232
|
+
else state.costUsd += costUsd;
|
|
2223
2233
|
await input.event({
|
|
2224
2234
|
type: "usage",
|
|
2225
2235
|
provider: response2.receipt.provider,
|
|
@@ -2229,7 +2239,9 @@ async function handleCodeRuntimeInference(input) {
|
|
|
2229
2239
|
durationMs: Date.now() - startedAt,
|
|
2230
2240
|
interactionId: command.commandId,
|
|
2231
2241
|
interactionTokens: state.tokens,
|
|
2232
|
-
interactionMaxTokens: metadata.maxTokensPerInteraction
|
|
2242
|
+
interactionMaxTokens: metadata.maxTokensPerInteraction,
|
|
2243
|
+
...costUsd === void 0 ? {} : { costUsd },
|
|
2244
|
+
...state.costKnown ? { interactionCostUsd: state.costUsd } : {}
|
|
2233
2245
|
}).catch(() => void 0);
|
|
2234
2246
|
return {
|
|
2235
2247
|
protocolVersion: HARNESS_PROTOCOL_VERSION,
|
|
@@ -3130,10 +3142,16 @@ async function startGoalPursuit(input) {
|
|
|
3130
3142
|
attempt: async ({ prompt }) => {
|
|
3131
3143
|
const result = await input.attempt(prompt);
|
|
3132
3144
|
return {
|
|
3133
|
-
//
|
|
3134
|
-
//
|
|
3135
|
-
//
|
|
3136
|
-
|
|
3145
|
+
// What the attempt actually spent, so the runner's token_budget and
|
|
3146
|
+
// cost_budget checks can be reached. This used to be a hardcoded 0 with
|
|
3147
|
+
// no cost at all, which made maxTokens and maxUsd unreachable while
|
|
3148
|
+
// callers reasonably read them as hard ceilings.
|
|
3149
|
+
//
|
|
3150
|
+
// costUsd is omitted rather than zeroed when any call in the attempt
|
|
3151
|
+
// was unpriced: the runner only enforces a cost budget while the cost
|
|
3152
|
+
// is known, and a zero would make it enforce against a lie.
|
|
3153
|
+
tokens: result.tokens ?? 0,
|
|
3154
|
+
...result.costUsd === void 0 ? {} : { costUsd: result.costUsd },
|
|
3137
3155
|
...result.status === "failed" ? { error: result.error ?? "attempt failed" } : {}
|
|
3138
3156
|
};
|
|
3139
3157
|
},
|
|
@@ -3352,7 +3370,7 @@ var CodePiRuntimeEngine = class {
|
|
|
3352
3370
|
recipeAuthorization: this.options.recipeAuthorization
|
|
3353
3371
|
}, lease, metadata.role));
|
|
3354
3372
|
const startedAt = Date.now();
|
|
3355
|
-
const interaction = { tokens: 0, noticeEmitted: false };
|
|
3373
|
+
const interaction = { tokens: 0, noticeEmitted: false, costUsd: 0, costKnown: true };
|
|
3356
3374
|
const inference = createCodeRuntimeInference({
|
|
3357
3375
|
command,
|
|
3358
3376
|
metadata,
|
|
@@ -3390,7 +3408,11 @@ var CodePiRuntimeEngine = class {
|
|
|
3390
3408
|
await this.#diagnostic(command, active, detail);
|
|
3391
3409
|
await this.#failure(command, active, detail);
|
|
3392
3410
|
}
|
|
3393
|
-
return
|
|
3411
|
+
return {
|
|
3412
|
+
...result,
|
|
3413
|
+
tokens: interaction.tokens,
|
|
3414
|
+
...interaction.costKnown ? { costUsd: interaction.costUsd } : {}
|
|
3415
|
+
};
|
|
3394
3416
|
}
|
|
3395
3417
|
/** Report every brokered effect as it starts and finishes. */
|
|
3396
3418
|
#observed(command, active, broker) {
|