orizu 0.5.27 → 0.5.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/dataset-transfer-download.d.ts +2 -0
- package/dist/dataset-transfer-download.d.ts.map +1 -0
- package/dist/dataset-transfer-download.js +66 -0
- package/dist/dataset-transfer-policy.d.ts +2 -0
- package/dist/dataset-transfer-policy.d.ts.map +1 -0
- package/dist/dataset-transfer-policy.js +8 -0
- package/dist/dataset-transfer-upload.d.ts +42 -0
- package/dist/dataset-transfer-upload.d.ts.map +1 -0
- package/dist/dataset-transfer-upload.js +110 -0
- package/dist/hosted-harness-opencode.d.ts +8 -9
- package/dist/hosted-harness-opencode.d.ts.map +1 -1
- package/dist/hosted-harness-opencode.js +12 -9
- package/dist/hosted-loop.d.ts.map +1 -1
- package/dist/hosted-loop.js +15 -9
- package/dist/http.d.ts +1 -1
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +10 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -87
- package/package.json +2 -1
- package/src/dataset-transfer-download.ts +61 -0
- package/src/dataset-transfer-policy.ts +8 -0
- package/src/dataset-transfer-upload.ts +145 -0
- package/src/hosted-harness-opencode.ts +12 -9
- package/src/hosted-loop.ts +15 -8
- package/src/http.ts +10 -4
- package/src/index.ts +21 -129
- package/vendor/skills/orizu/references/prompt-control-plane.md +4 -3
package/README.md
CHANGED
|
@@ -427,6 +427,25 @@ Task and dataset export support:
|
|
|
427
427
|
- `json`
|
|
428
428
|
- `jsonl`
|
|
429
429
|
|
|
430
|
+
Dataset `upload` and `push` create an immutable version after the rows are
|
|
431
|
+
acknowledged. With `--json`, upload prints one result document. A failed snapshot
|
|
432
|
+
reports the uploaded dataset identity so recovery can target the snapshot step.
|
|
433
|
+
If a write's response is lost or times out, inspect the dataset before retrying:
|
|
434
|
+
the last chunk may already have committed.
|
|
435
|
+
|
|
436
|
+
Dataset downloads retry transient read failures up to three attempts. Each
|
|
437
|
+
transfer request, including its response body, has a two-minute deadline;
|
|
438
|
+
`ORIZU_DATASET_TRANSFER_TIMEOUT_MS` accepts 1–300000 milliseconds. Downloads
|
|
439
|
+
receive the complete response before writing to the destination. Existing files
|
|
440
|
+
keep their inode, ownership, permissions and ACLs; writes follow existing
|
|
441
|
+
symlinks and update hardlinked readers. New files request mode `0600`, subject
|
|
442
|
+
to the filesystem's access rules. A failed network transfer leaves an existing output
|
|
443
|
+
untouched. The final write retains ordinary filesystem behavior: it is not
|
|
444
|
+
atomic, and a disk failure during that write can leave partial output.
|
|
445
|
+
SIGINT/SIGTERM cancels a download. Upload writes
|
|
446
|
+
have no additional transient retries; the existing session refresh behavior is
|
|
447
|
+
unchanged.
|
|
448
|
+
|
|
430
449
|
## Interactive And Automated Usage
|
|
431
450
|
|
|
432
451
|
Many commands can prompt for missing team, project, app, dataset, or task selections in an interactive terminal. In scripts and CI, pass explicit flags instead:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset-transfer-download.d.ts","sourceRoot":"","sources":["../src/dataset-transfer-download.ts"],"names":[],"mappings":"AAmBA,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyChH"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Effect, Either, Schedule } from 'effect';
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { datasetTransferTimeoutMs } from './dataset-transfer-policy.js';
|
|
4
|
+
import { authedFetch } from './http.js';
|
|
5
|
+
class DownloadHttpError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
_tag = 'DownloadHttpError';
|
|
8
|
+
constructor(status, detail) {
|
|
9
|
+
super(`Download failed (HTTP ${status}): ${detail}`);
|
|
10
|
+
this.status = status;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
class DownloadTransportError extends Error {
|
|
14
|
+
_tag = 'DownloadTransportError';
|
|
15
|
+
constructor(cause) {
|
|
16
|
+
super('Dataset download transport failed', { cause });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function transferDatasetDownload(datasetId, format, filename) {
|
|
20
|
+
const timeoutMs = datasetTransferTimeoutMs();
|
|
21
|
+
const download = Effect.tryPromise({
|
|
22
|
+
try: async (signal) => {
|
|
23
|
+
const response = await authedFetch(`/api/cli/datasets/${encodeURIComponent(datasetId)}/download?format=${encodeURIComponent(format)}`, { signal });
|
|
24
|
+
if (!response.ok)
|
|
25
|
+
throw new DownloadHttpError(response.status, await response.text());
|
|
26
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
27
|
+
},
|
|
28
|
+
catch: cause => {
|
|
29
|
+
if (cause instanceof TypeError)
|
|
30
|
+
return new DownloadTransportError(cause);
|
|
31
|
+
return cause instanceof Error ? cause : new Error('Dataset download request failed', { cause });
|
|
32
|
+
},
|
|
33
|
+
}).pipe(Effect.timeoutFail({
|
|
34
|
+
duration: timeoutMs,
|
|
35
|
+
onTimeout: () => new Error('DATASET_TRANSFER_TIMEOUT: Dataset download exceeded its deadline'),
|
|
36
|
+
}), Effect.retry({
|
|
37
|
+
times: 2,
|
|
38
|
+
schedule: Schedule.spaced(100),
|
|
39
|
+
while: error => error instanceof DownloadTransportError || (error instanceof DownloadHttpError && [429, 502, 503, 504].includes(error.status)),
|
|
40
|
+
}));
|
|
41
|
+
const fileError = (cause) => new Error(`DATASET_DOWNLOAD_FILE: Could not save dataset to ${filename}: ${cause instanceof Error ? cause.message : String(cause)}`, { cause });
|
|
42
|
+
const write = (bytes) => Effect.try({
|
|
43
|
+
// Wait for the complete response, then retain the CLI's existing in-place
|
|
44
|
+
// write semantics, including inode metadata, hardlinks and symlink targets.
|
|
45
|
+
try: () => writeFileSync(filename, bytes, { mode: 0o600 }),
|
|
46
|
+
catch: fileError,
|
|
47
|
+
});
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
const handleInterrupt = () => controller.abort();
|
|
50
|
+
process.once('SIGINT', handleInterrupt);
|
|
51
|
+
process.once('SIGTERM', handleInterrupt);
|
|
52
|
+
try {
|
|
53
|
+
const result = await Effect.runPromise(Effect.either(Effect.flatMap(download, write)), { signal: controller.signal });
|
|
54
|
+
if (Either.isLeft(result))
|
|
55
|
+
throw result.left;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
if (controller.signal.aborted)
|
|
59
|
+
throw new Error('DATASET_TRANSFER_INTERRUPTED: Dataset download cancelled');
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
process.removeListener('SIGINT', handleInterrupt);
|
|
64
|
+
process.removeListener('SIGTERM', handleInterrupt);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset-transfer-policy.d.ts","sourceRoot":"","sources":["../src/dataset-transfer-policy.ts"],"names":[],"mappings":"AAAA,wBAAgB,wBAAwB,IAAI,MAAM,CAOjD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function datasetTransferTimeoutMs() {
|
|
2
|
+
const configured = process.env.ORIZU_DATASET_TRANSFER_TIMEOUT_MS;
|
|
3
|
+
const timeoutMs = configured === undefined ? 120_000 : Number(configured);
|
|
4
|
+
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 300_000) {
|
|
5
|
+
throw new Error('DATASET_TRANSFER_CONFIG: ORIZU_DATASET_TRANSFER_TIMEOUT_MS must be an integer from 1 to 300000');
|
|
6
|
+
}
|
|
7
|
+
return timeoutMs;
|
|
8
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface DatasetUploadResponse {
|
|
2
|
+
dataset: {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
rowCount: number;
|
|
6
|
+
sourceType: string;
|
|
7
|
+
url?: string;
|
|
8
|
+
};
|
|
9
|
+
readmeVersion?: {
|
|
10
|
+
id: string;
|
|
11
|
+
version_num: number;
|
|
12
|
+
created_at: string;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
interface DatasetSnapshot {
|
|
16
|
+
datasetVersion: {
|
|
17
|
+
id: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
type UploadRows = Array<Record<string, unknown>>;
|
|
21
|
+
type UploadSource = {
|
|
22
|
+
kind: 'jsonl';
|
|
23
|
+
file: string;
|
|
24
|
+
} | {
|
|
25
|
+
kind: 'rows';
|
|
26
|
+
rows: UploadRows;
|
|
27
|
+
sourceType: 'csv' | 'json' | 'jsonl';
|
|
28
|
+
};
|
|
29
|
+
export interface DatasetUploadOptions {
|
|
30
|
+
project: string;
|
|
31
|
+
name: string;
|
|
32
|
+
source: UploadSource;
|
|
33
|
+
readmeMarkdown: string | null;
|
|
34
|
+
json: boolean;
|
|
35
|
+
onChunk: (index: number, rowCount: number) => void;
|
|
36
|
+
}
|
|
37
|
+
export declare function transferDatasetUpload(options: DatasetUploadOptions): Promise<{
|
|
38
|
+
data: DatasetUploadResponse;
|
|
39
|
+
version: DatasetSnapshot;
|
|
40
|
+
}>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=dataset-transfer-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset-transfer-upload.d.ts","sourceRoot":"","sources":["../src/dataset-transfer-upload.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzF,aAAa,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC/E;AAED,UAAU,eAAe;IAAG,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE;AAE5D,KAAK,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;AAChD,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAE9H,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,YAAY,CAAA;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;CACnD;AAoHD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC,CAEvI"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Context, Effect, Either, Layer } from 'effect';
|
|
2
|
+
import { ensureDatasetUploadSnapshot } from './dataset-upload-snapshot.js';
|
|
3
|
+
import { datasetTransferTimeoutMs } from './dataset-transfer-policy.js';
|
|
4
|
+
import { extractErrorMessage } from './error-response.js';
|
|
5
|
+
import { authedFetch } from './http.js';
|
|
6
|
+
import { parseJsonResponse, sanitizeTerminalText } from './json-response.js';
|
|
7
|
+
import { streamJsonlRowChunks } from './jsonl-stream.js';
|
|
8
|
+
class DatasetWriteFailure extends Error {
|
|
9
|
+
outcome;
|
|
10
|
+
_tag = 'DatasetWriteFailure';
|
|
11
|
+
constructor(message, outcome, options) {
|
|
12
|
+
super(message, options);
|
|
13
|
+
this.outcome = outcome;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class DatasetInputFailure extends Error {
|
|
17
|
+
_tag = 'DatasetInputFailure';
|
|
18
|
+
constructor(cause) { super(cause instanceof Error ? cause.message : String(cause), { cause }); }
|
|
19
|
+
}
|
|
20
|
+
const DatasetUploadApi = Context.GenericTag('orizu/DatasetUploadApi');
|
|
21
|
+
// Only the existing authentication client's rejected-token refresh may replay a
|
|
22
|
+
// request. No transient/transport retries belong around these non-idempotent writes.
|
|
23
|
+
function post(path, body, context, prefix, timeoutMs) {
|
|
24
|
+
return Effect.suspend(() => {
|
|
25
|
+
let requestStarted = false;
|
|
26
|
+
return Effect.tryPromise({
|
|
27
|
+
try: async (signal) => {
|
|
28
|
+
const response = await authedFetch(path, {
|
|
29
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
30
|
+
body: JSON.stringify(body), signal,
|
|
31
|
+
}, () => { requestStarted = true; });
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new DatasetWriteFailure(`${prefix}: ${await extractErrorMessage(response)}`, response.status >= 500 ? 'unknown' : 'rejected');
|
|
34
|
+
}
|
|
35
|
+
return await parseJsonResponse(response, context);
|
|
36
|
+
},
|
|
37
|
+
catch: cause => cause instanceof DatasetWriteFailure ? cause : new DatasetWriteFailure(cause instanceof Error ? cause.message : String(cause), requestStarted ? 'unknown' : 'rejected', { cause }),
|
|
38
|
+
}).pipe(Effect.timeoutFail({
|
|
39
|
+
duration: timeoutMs,
|
|
40
|
+
onTimeout: () => new DatasetWriteFailure(`DATASET_TRANSFER_TIMEOUT: ${context} exceeded its deadline`, requestStarted ? 'unknown' : 'rejected'),
|
|
41
|
+
}));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function liveUploadApi(options) {
|
|
45
|
+
const timeoutMs = datasetTransferTimeoutMs();
|
|
46
|
+
return Layer.succeed(DatasetUploadApi, {
|
|
47
|
+
create: (rows, sourceType) => post('/api/cli/datasets/upload', {
|
|
48
|
+
projectSlug: options.project, name: options.name, rows, sourceType,
|
|
49
|
+
...(options.readmeMarkdown !== null ? { readmeMarkdown: options.readmeMarkdown } : {}),
|
|
50
|
+
}, 'Dataset upload', 'Upload failed', timeoutMs),
|
|
51
|
+
append: (id, rows) => post(`/api/cli/datasets/${encodeURIComponent(id)}/rows`, { rows }, 'Dataset append', 'Append failed', timeoutMs),
|
|
52
|
+
snapshot: id => post(`/api/cli/datasets/${encodeURIComponent(id)}/versions`, {}, 'Dataset version create', 'Failed to create dataset version', timeoutMs),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function expectedPromise(program) {
|
|
56
|
+
const result = await Effect.runPromise(Effect.either(program));
|
|
57
|
+
if (Either.isLeft(result))
|
|
58
|
+
throw result.left;
|
|
59
|
+
return result.right;
|
|
60
|
+
}
|
|
61
|
+
function uploadProgram(options) {
|
|
62
|
+
return Effect.gen(function* () {
|
|
63
|
+
const api = yield* DatasetUploadApi;
|
|
64
|
+
const chunks = yield* Effect.acquireRelease(Effect.sync(() => options.source.kind === 'jsonl'
|
|
65
|
+
? streamJsonlRowChunks(options.source.file)
|
|
66
|
+
: (async function* () { if (options.source.kind === 'rows')
|
|
67
|
+
yield options.source.rows; })()), iterator => Effect.promise(async () => { await iterator.return(undefined); }));
|
|
68
|
+
let data;
|
|
69
|
+
let confirmedRows = 0;
|
|
70
|
+
let chunkIndex = 0;
|
|
71
|
+
while (true) {
|
|
72
|
+
const next = yield* Effect.tryPromise({ try: () => chunks.next(), catch: cause => new DatasetInputFailure(cause) }).pipe(Effect.mapError(error => new Error(data
|
|
73
|
+
? `Upload stopped while reading the next JSONL chunk: ${error.message}\nDataset ${sanitizeTerminalText(data.dataset.name)} (${sanitizeTerminalText(data.dataset.id)}) was created and ${confirmedRows} rows were uploaded. Fix the file, remove the first ${confirmedRows} rows, and run orizu datasets append --dataset ${data.dataset.id} --file <remaining-file>.`
|
|
74
|
+
: error.message)));
|
|
75
|
+
if (next.done)
|
|
76
|
+
break;
|
|
77
|
+
chunkIndex++;
|
|
78
|
+
if (options.source.kind === 'jsonl')
|
|
79
|
+
yield* Effect.sync(() => options.onChunk(chunkIndex, next.value.length));
|
|
80
|
+
const write = data
|
|
81
|
+
? api.append(data.dataset.id, next.value).pipe(Effect.map(result => ({
|
|
82
|
+
data: { ...data, dataset: { ...data.dataset, rowCount: result.dataset.rowCount } },
|
|
83
|
+
added: result.appendedCount,
|
|
84
|
+
})))
|
|
85
|
+
: api.create(next.value, options.source.kind === 'jsonl' ? 'jsonl' : options.source.sourceType).pipe(Effect.map(result => ({ data: result, added: result.dataset.rowCount })));
|
|
86
|
+
const result = yield* write.pipe(Effect.mapError(error => {
|
|
87
|
+
if (error.outcome === 'unknown') {
|
|
88
|
+
return new Error(`DATASET_UPLOAD_UNCERTAIN: Chunk ${chunkIndex} may have committed, but its outcome could not be confirmed: ${error.message}\n` +
|
|
89
|
+
(data ? `Dataset ${sanitizeTerminalText(data.dataset.id)} has ${confirmedRows} confirmed uploaded rows. ` : 'Dataset creation could not be confirmed. ') +
|
|
90
|
+
'Inspect the dataset and reconcile row IDs before retrying; do not replay this chunk blindly.');
|
|
91
|
+
}
|
|
92
|
+
return new Error(data
|
|
93
|
+
? `Chunk ${chunkIndex} failed: ${error.message}\nDataset ${sanitizeTerminalText(data.dataset.name)} (${sanitizeTerminalText(data.dataset.id)}) was created and ${confirmedRows} rows were uploaded. To retry, remove the first ${confirmedRows} rows from your file and run orizu datasets append --dataset ${data.dataset.id} --file <remaining-file>.`
|
|
94
|
+
: error.message);
|
|
95
|
+
}));
|
|
96
|
+
data = result.data;
|
|
97
|
+
confirmedRows += result.added;
|
|
98
|
+
}
|
|
99
|
+
if (!data)
|
|
100
|
+
return yield* Effect.fail(new Error('Dataset file contains no rows'));
|
|
101
|
+
const version = yield* Effect.tryPromise({
|
|
102
|
+
try: () => ensureDatasetUploadSnapshot(data.dataset, options.json, id => expectedPromise(api.snapshot(id))),
|
|
103
|
+
catch: cause => cause instanceof Error ? cause : new Error(String(cause)),
|
|
104
|
+
});
|
|
105
|
+
return { data, version };
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export function transferDatasetUpload(options) {
|
|
109
|
+
return expectedPromise(uploadProgram(options).pipe(Effect.scoped, Effect.provide(liveUploadApi(options))));
|
|
110
|
+
}
|
|
@@ -156,20 +156,19 @@ export interface OpenCodeConfigOptions {
|
|
|
156
156
|
permission?: Record<string, unknown>;
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
|
-
* Tools
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* to it as a tool error) so it proceeds autonomously per the standing preamble
|
|
166
|
-
* (HOSTED_TASK_PREAMBLE), instead of blocking the run forever. This is the
|
|
167
|
-
* documented fallback path in ALI-1037 (answer-externally is not cleanly possible).
|
|
159
|
+
* Tools denied for CLI-origin headless runs (ALI-1037). OpenCode 1.14.41 removes
|
|
160
|
+
* a tool from the model toolset when its permission rule is `deny` on `*`; it does
|
|
161
|
+
* not expose the tool and report a denial result. Hosted-web therefore overrides
|
|
162
|
+
* `question` to `allow`, intercepts its measured running part, and quiesces the
|
|
163
|
+
* turn while waiting for the human. CLI-origin runs retain this deny list because
|
|
164
|
+
* no human reply flow exists there.
|
|
168
165
|
*/
|
|
169
166
|
export declare const HEADLESS_DENIED_TOOLS: readonly ["question"];
|
|
170
167
|
/** The default headless permission map: allow everything, deny the interactive
|
|
171
168
|
* question tool (see HEADLESS_DENIED_TOOLS). */
|
|
172
169
|
export declare function defaultHeadlessPermission(): Record<string, unknown>;
|
|
170
|
+
/** Select the OpenCode permission map for the session's human-input surface. */
|
|
171
|
+
export declare function permissionForOrigin(origin?: 'hosted-web' | 'cli'): Record<string, unknown>;
|
|
173
172
|
/**
|
|
174
173
|
* Build the `OPENCODE_CONFIG_CONTENT` payload OpenCode reads at boot (mirrors
|
|
175
174
|
* OpenInspect's `start_opencode`). Kept pure so the launch command and the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-harness-opencode.d.ts","sourceRoot":"","sources":["../src/hosted-harness-opencode.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hosted-harness-opencode.d.ts","sourceRoot":"","sources":["../src/hosted-harness-opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -931,15 +931,12 @@ export async function awaitOpenCodeModelResolvable(opts) {
|
|
|
931
931
|
};
|
|
932
932
|
}
|
|
933
933
|
/**
|
|
934
|
-
* Tools
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
*
|
|
940
|
-
* to it as a tool error) so it proceeds autonomously per the standing preamble
|
|
941
|
-
* (HOSTED_TASK_PREAMBLE), instead of blocking the run forever. This is the
|
|
942
|
-
* documented fallback path in ALI-1037 (answer-externally is not cleanly possible).
|
|
934
|
+
* Tools denied for CLI-origin headless runs (ALI-1037). OpenCode 1.14.41 removes
|
|
935
|
+
* a tool from the model toolset when its permission rule is `deny` on `*`; it does
|
|
936
|
+
* not expose the tool and report a denial result. Hosted-web therefore overrides
|
|
937
|
+
* `question` to `allow`, intercepts its measured running part, and quiesces the
|
|
938
|
+
* turn while waiting for the human. CLI-origin runs retain this deny list because
|
|
939
|
+
* no human reply flow exists there.
|
|
943
940
|
*/
|
|
944
941
|
export const HEADLESS_DENIED_TOOLS = ['question'];
|
|
945
942
|
/** The default headless permission map: allow everything, deny the interactive
|
|
@@ -950,6 +947,12 @@ export function defaultHeadlessPermission() {
|
|
|
950
947
|
permission[tool] = 'deny';
|
|
951
948
|
return permission;
|
|
952
949
|
}
|
|
950
|
+
/** Select the OpenCode permission map for the session's human-input surface. */
|
|
951
|
+
export function permissionForOrigin(origin) {
|
|
952
|
+
if (origin === 'hosted-web')
|
|
953
|
+
return { ...defaultHeadlessPermission(), question: 'allow' };
|
|
954
|
+
return defaultHeadlessPermission();
|
|
955
|
+
}
|
|
953
956
|
/**
|
|
954
957
|
* Build the `OPENCODE_CONFIG_CONTENT` payload OpenCode reads at boot (mirrors
|
|
955
958
|
* OpenInspect's `start_opencode`). Kept pure so the launch command and the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-loop.d.ts","sourceRoot":"","sources":["../src/hosted-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAOH,OAAO,EAAyB,KAAK,YAAY,EAAyC,MAAM,qBAAqB,CAAA;AAQrH,OAAO,EAAoB,KAAK,WAAW,EAAuB,MAAM,qBAAqB,CAAA;AAE7F,OAAO,
|
|
1
|
+
{"version":3,"file":"hosted-loop.d.ts","sourceRoot":"","sources":["../src/hosted-loop.ts"],"names":[],"mappings":"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"}
|
package/dist/hosted-loop.js
CHANGED
|
@@ -42,7 +42,7 @@ import { isHarnessTerminalKind } from './hosted-harness.js';
|
|
|
42
42
|
import { SETUP_HOOK_RELATIVE_PATH, composeHostedTaskPrompt, parsePrebakedMarker, resolveHostedTaskPreamble, resolvePrebakedMarkerPath, } from './hosted-runtime-assets.js';
|
|
43
43
|
import { harvestWorkspace } from './hosted-harvest.js';
|
|
44
44
|
import { annotateHeadlessQuestions, withIdleWatchdog } from './hosted-headless.js';
|
|
45
|
-
import { DEFAULT_PROMPT_MAX_DURATION_MS, OPENCODE_PINNED_VERSION, awaitOpenCodeModelResolvable, createOpenCodeHarness, spawnOpenCode, } from './hosted-harness-opencode.js';
|
|
45
|
+
import { DEFAULT_PROMPT_MAX_DURATION_MS, OPENCODE_PINNED_VERSION, awaitOpenCodeModelResolvable, createOpenCodeHarness, permissionForOrigin, spawnOpenCode, } from './hosted-harness-opencode.js';
|
|
46
46
|
import { createClaudeAgentHarness } from './hosted-harness-claude.js';
|
|
47
47
|
import { INJECTED_ENV_VARS_ENV } from './hosted-environment.js';
|
|
48
48
|
import { interceptHostedQuestions } from './hosted-question.js';
|
|
@@ -444,6 +444,7 @@ export async function runHostedLoop(opts) {
|
|
|
444
444
|
// connection-refused "fetch failed" (ALI-1034).
|
|
445
445
|
spawned = await spawnImpl({
|
|
446
446
|
model: context.model,
|
|
447
|
+
permission: permissionForOrigin(context.sessionOrigin),
|
|
447
448
|
cwd: context.workspaceDir,
|
|
448
449
|
port: context.opencodePort,
|
|
449
450
|
env: buildOpenCodeSpawnEnv(context),
|
|
@@ -522,8 +523,9 @@ export async function runHostedLoop(opts) {
|
|
|
522
523
|
content: composeHostedTaskPrompt(taskPrompt, opts.taskPreamble ?? resolveHostedTaskPreamble(context.sessionOrigin)),
|
|
523
524
|
author: context.author,
|
|
524
525
|
};
|
|
525
|
-
// Drive the prompt through
|
|
526
|
-
//
|
|
526
|
+
// Drive the prompt through question-deny annotation unless hosted-web
|
|
527
|
+
// OpenCode interception owns the outcome, then through the idle watchdog
|
|
528
|
+
// (ALI-1037): no harness event for `idleTimeoutMs` aborts the
|
|
527
529
|
// prompt and throws `AgentStalledError` → the catch below harvests, then
|
|
528
530
|
// finishes the run `failed`. The prompt runs under a CHILD AbortController
|
|
529
531
|
// linked to the loop signal so the watchdog can abort the in-flight prompt
|
|
@@ -570,9 +572,10 @@ export async function runHostedLoop(opts) {
|
|
|
570
572
|
interruptSignal?.addEventListener('abort', handleInterrupt, { once: true });
|
|
571
573
|
const terminalSummary = { agentSessionId };
|
|
572
574
|
let hasQuestionOutcome = false;
|
|
573
|
-
const
|
|
574
|
-
const
|
|
575
|
-
|
|
575
|
+
const promptEvents = harness.runPrompt(prompt, promptController.signal);
|
|
576
|
+
const hasHostedQuestionInterception = harnessKind === 'opencode' && context.sessionOrigin === 'hosted-web';
|
|
577
|
+
const intercepted = hasHostedQuestionInterception
|
|
578
|
+
? interceptHostedQuestions(promptEvents, {
|
|
576
579
|
onDetected: question => {
|
|
577
580
|
hasQuestionOutcome = true;
|
|
578
581
|
terminalSummary.outcome = 'question_pending';
|
|
@@ -588,7 +591,10 @@ export async function runHostedLoop(opts) {
|
|
|
588
591
|
onPersisted: beginQuiescence,
|
|
589
592
|
onInvalidPersisted: beginQuiescence,
|
|
590
593
|
})
|
|
591
|
-
:
|
|
594
|
+
: promptEvents;
|
|
595
|
+
const questionAware = hasHostedQuestionInterception
|
|
596
|
+
? intercepted
|
|
597
|
+
: annotateHeadlessQuestions(intercepted);
|
|
592
598
|
const interruptAware = (async function* () {
|
|
593
599
|
for await (const event of questionAware) {
|
|
594
600
|
if (isHarnessTerminalKind(event.kind)) {
|
|
@@ -639,8 +645,8 @@ export async function runHostedLoop(opts) {
|
|
|
639
645
|
promptController.abort();
|
|
640
646
|
await harness.stop();
|
|
641
647
|
},
|
|
642
|
-
//
|
|
643
|
-
//
|
|
648
|
+
// Without hosted-web OpenCode interception, a model stuck retrying a
|
|
649
|
+
// denied question emits synthetic `question_auto_answered` events. Those are
|
|
644
650
|
// NOT progress — excluding them lets a deny/retry loop trip agent_stalled
|
|
645
651
|
// instead of resetting the idle timer forever (ALI-1069).
|
|
646
652
|
isProgress: event => event.kind !== 'question_auto_answered',
|
package/dist/http.d.ts
CHANGED
|
@@ -25,5 +25,5 @@ export interface LogoutResult {
|
|
|
25
25
|
export declare function captureAuthenticatedRequestContext(options?: {
|
|
26
26
|
allowRefresh?: boolean;
|
|
27
27
|
}): AuthenticatedRequestContext;
|
|
28
|
-
export declare function authedFetch(path: string, init?: RequestInit): Promise<Response>;
|
|
28
|
+
export declare function authedFetch(path: string, init?: RequestInit, onRequestStart?: () => void): Promise<Response>;
|
|
29
29
|
//# sourceMappingURL=http.d.ts.map
|
package/dist/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,WAAW,EAAoB,MAAM,mBAAmB,CAAA;AASjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,QAEhD;AAED,wBAAgB,cAAc,CAAC,KAAK,GAAE,WAA0B,GAAG,MAAM,CAiBxE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,WAA0B,GAAG,MAAM,CAY7E;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAWD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,QAmBzD;AAqFD,wBAAgB,+BAA+B,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAE/E;AAkGD,MAAM,MAAM,0BAA0B,GAAG,aAAa,GAAG,kBAAkB,GAAG,QAAQ,CAAA;AAEtF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAA;IAC3C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC1D,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CAC3D;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,sBAAsB,EAAE,OAAO,CAAA;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,2BAA2B,CAgI7B;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,WAAW,EAAoB,MAAM,mBAAmB,CAAA;AASjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,QAEhD;AAED,wBAAgB,cAAc,CAAC,KAAK,GAAE,WAA0B,GAAG,MAAM,CAiBxE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,GAAE,WAA0B,GAAG,MAAM,CAY7E;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAWD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,QAmBzD;AAqFD,wBAAgB,+BAA+B,IAAI,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAE/E;AAkGD,MAAM,MAAM,0BAA0B,GAAG,aAAa,GAAG,kBAAkB,GAAG,QAAQ,CAAA;AAEtF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAA;IAC3C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC1D,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CAC3D;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,sBAAsB,EAAE,OAAO,CAAA;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,2BAA2B,CAgI7B;AAID,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,EAAE,cAAc,CAAC,EAAE,MAAM,IAAI,qBAqElG"}
|
package/dist/http.js
CHANGED
|
@@ -311,7 +311,13 @@ export function captureAuthenticatedRequestContext(options = {}) {
|
|
|
311
311
|
},
|
|
312
312
|
};
|
|
313
313
|
}
|
|
314
|
-
|
|
314
|
+
// The optional observer runs immediately before a resource fetch, after auth
|
|
315
|
+
// preflight. Authentication refresh requests do not mark the resource as sent.
|
|
316
|
+
export async function authedFetch(path, init = {}, onRequestStart) {
|
|
317
|
+
const fetchResource = (url, requestInit) => {
|
|
318
|
+
onRequestStart?.();
|
|
319
|
+
return fetch(url, requestInit);
|
|
320
|
+
};
|
|
315
321
|
const baseUrl = resolveBaseUrl();
|
|
316
322
|
assertSecureTokenTransport(baseUrl);
|
|
317
323
|
// In-sandbox pre-auth (ALI-1044): a bearer supplied via ORIZU_TOKEN /
|
|
@@ -321,7 +327,7 @@ export async function authedFetch(path, init = {}) {
|
|
|
321
327
|
// the file and the next request naturally picks up the new bearer.
|
|
322
328
|
const envBearer = resolveEnvBearerToken();
|
|
323
329
|
if (envBearer) {
|
|
324
|
-
return await
|
|
330
|
+
return await fetchResource(`${baseUrl}${path}`, {
|
|
325
331
|
...init,
|
|
326
332
|
headers: {
|
|
327
333
|
...(init.headers || {}),
|
|
@@ -336,7 +342,7 @@ export async function authedFetch(path, init = {}) {
|
|
|
336
342
|
}
|
|
337
343
|
const resolved = await refreshExpiredStoredCredentials(baseUrl, credentials, init.signal);
|
|
338
344
|
let activeCredentials = resolved.credentials;
|
|
339
|
-
let response = await
|
|
345
|
+
let response = await fetchResource(`${baseUrl}${path}`, {
|
|
340
346
|
...init,
|
|
341
347
|
headers: {
|
|
342
348
|
...(init.headers || {}),
|
|
@@ -352,7 +358,7 @@ export async function authedFetch(path, init = {}) {
|
|
|
352
358
|
throw new Error('ORIZU_AUTH_CONTEXT_CHANGED: stored credentials changed after this request began; the request was not replayed.');
|
|
353
359
|
}
|
|
354
360
|
activeCredentials = requireCurrentCredentials(baseUrl, refreshResult.credentials);
|
|
355
|
-
response = await
|
|
361
|
+
response = await fetchResource(`${baseUrl}${path}`, {
|
|
356
362
|
...init,
|
|
357
363
|
headers: {
|
|
358
364
|
...(init.headers || {}),
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAwHgF,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAqChJ,eAAO,MAAM,wBAAwB,GAAI,iBAAiB,MAAM;;;EACJ,CAAA;AAE5D,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAuU5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAUD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOnD;AAyBD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAsBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,GAAG,CAqB5E;AA6BD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBtD;AA28JD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA0B1G;AAED,eAAO,MAAM,iBAAiB,SAAU,CAAA;AACxC,eAAO,MAAM,uBAAuB,QAAkB,CAAA;AACtD,eAAO,MAAM,oBAAoB,aAgB/B,CAAA;AAEF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAaxH;AAmMD,wBAAsB,IAAI,CAAC,OAAO,WAAwB,iBA6gBzD"}
|