@jigging/jig 0.1.0-alpha.5 → 0.1.0-alpha.7
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 +10 -6
- package/THIRD_PARTY_NOTICES +40 -1
- package/libexec/agent/claude-agent-acp.LICENSE +191 -0
- package/libexec/agent/claude-agent-acp.js +71361 -0
- package/libexec/agent/claude-agent-launcher.js +53 -0
- package/libexec/agent/claude-agent-sdk.LICENSE +1 -0
- package/libexec/agent/codex-acp.LICENSE +190 -0
- package/libexec/agent/codex-acp.js +34238 -0
- package/libexec/agent/codex-agent-launcher.js +54 -0
- package/libexec/agent/codex-requirements.toml +5 -0
- package/libexec/agent/{openrouter-responses-worker.js → openai-responses-worker.js} +196 -75
- package/libexec/agent/pi-acp.LICENSE +21 -0
- package/libexec/agent/pi-acp.js +16468 -0
- package/libexec/agent/pi-agent-launcher.js +196 -0
- package/libexec/installed-cli.js +20604 -1420
- package/libexec/linux-rootless-supervisor.js +4 -5
- package/package.json +20 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/internal/codex-agent-launcher.ts
|
|
3
|
+
import { closeSync, mkdirSync, openSync, readSync, writeSync } from "fs";
|
|
4
|
+
var STARTUP_INPUT_BYTES = 64 * 1024;
|
|
5
|
+
var CODEX_HOME = "/tmp/codex-home";
|
|
6
|
+
var CREDENTIAL_PATH = `${CODEX_HOME}/auth.json`;
|
|
7
|
+
var ADAPTER_SPECIFIER = "./codex-acp.js";
|
|
8
|
+
if (import.meta.main)
|
|
9
|
+
await main();
|
|
10
|
+
async function main() {
|
|
11
|
+
mkdirSync(CODEX_HOME, { mode: 448 });
|
|
12
|
+
const startup = process.env.JIG_CODEX_STARTUP_INPUT;
|
|
13
|
+
if (startup !== undefined && startup !== "subscription") {
|
|
14
|
+
throw new Error("Codex startup input mode is invalid");
|
|
15
|
+
}
|
|
16
|
+
if (startup === "subscription")
|
|
17
|
+
materializeCredential();
|
|
18
|
+
delete process.env.JIG_CODEX_STARTUP_INPUT;
|
|
19
|
+
await import(ADAPTER_SPECIFIER);
|
|
20
|
+
}
|
|
21
|
+
function materializeCredential() {
|
|
22
|
+
const header = readExactly(4);
|
|
23
|
+
const size = new DataView(header.buffer, header.byteOffset, header.byteLength).getUint32(0, false);
|
|
24
|
+
if (size === 0 || size > STARTUP_INPUT_BYTES - 4) {
|
|
25
|
+
throw new Error("Codex startup input is invalid");
|
|
26
|
+
}
|
|
27
|
+
const credential = readExactly(size);
|
|
28
|
+
let descriptor;
|
|
29
|
+
try {
|
|
30
|
+
descriptor = openSync(CREDENTIAL_PATH, "wx", 384);
|
|
31
|
+
writeExactly(descriptor, credential);
|
|
32
|
+
} finally {
|
|
33
|
+
credential.fill(0);
|
|
34
|
+
if (descriptor !== undefined)
|
|
35
|
+
closeSync(descriptor);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function readExactly(size) {
|
|
39
|
+
const result = new Uint8Array(size);
|
|
40
|
+
let offset = 0;
|
|
41
|
+
while (offset < result.byteLength) {
|
|
42
|
+
const count = readSync(0, result, offset, result.byteLength - offset, null);
|
|
43
|
+
if (count === 0)
|
|
44
|
+
throw new Error("Codex startup input ended early");
|
|
45
|
+
offset += count;
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function writeExactly(descriptor, value) {
|
|
50
|
+
let offset = 0;
|
|
51
|
+
while (offset < value.byteLength) {
|
|
52
|
+
offset += writeSync(descriptor, value, offset, value.byteLength - offset, null);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -13915,69 +13915,67 @@ function compareUtf16(left, right) {
|
|
|
13915
13915
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
13916
13916
|
}
|
|
13917
13917
|
|
|
13918
|
-
// src/internal/
|
|
13919
|
-
var
|
|
13920
|
-
var
|
|
13921
|
-
var
|
|
13922
|
-
var PRIVATE_OPENROUTER_RESPONSES_REQUEST_BYTES = JSON_1_LIMITS.bytes;
|
|
13923
|
-
var PRIVATE_OPENROUTER_RESPONSES_RESPONSE_BYTES = JSON_1_LIMITS.bytes;
|
|
13918
|
+
// src/internal/openai-responses-protocol.ts
|
|
13919
|
+
var PRIVATE_OPENAI_RESPONSES_PROTOCOL = "jig-private-openai-responses/1";
|
|
13920
|
+
var PRIVATE_OPENAI_RESPONSES_REQUEST_BYTES = JSON_1_LIMITS.bytes;
|
|
13921
|
+
var PRIVATE_OPENAI_RESPONSES_RESPONSE_BYTES = JSON_1_LIMITS.bytes;
|
|
13924
13922
|
var MAX_INSTRUCTION_CHARACTERS = 1048576;
|
|
13925
13923
|
var MAX_RESPONSE_SCHEMA_BYTES = 256 * 1024;
|
|
13926
13924
|
var MAX_FAILURE_MESSAGE_BYTES = 4096;
|
|
13927
|
-
var
|
|
13925
|
+
var PRIVATE_OPENAI_RESPONSES_ERROR_CODES = Object.freeze([
|
|
13928
13926
|
"AGENT_PROVIDER_CONFIGURATION",
|
|
13929
13927
|
"AGENT_PROVIDER_OUTPUT_LIMIT",
|
|
13930
13928
|
"AGENT_PROVIDER_PROTOCOL",
|
|
13931
13929
|
"AGENT_PROVIDER_RESPONSE_INVALID",
|
|
13932
13930
|
"AGENT_PROVIDER_UNAVAILABLE"
|
|
13933
13931
|
]);
|
|
13934
|
-
var ERROR_CODES = new Set(
|
|
13932
|
+
var ERROR_CODES = new Set(PRIVATE_OPENAI_RESPONSES_ERROR_CODES);
|
|
13935
13933
|
|
|
13936
|
-
class
|
|
13934
|
+
class PrivateOpenAIResponsesError extends Error {
|
|
13937
13935
|
code;
|
|
13938
13936
|
constructor(code, message) {
|
|
13939
13937
|
super(message);
|
|
13940
13938
|
this.code = code;
|
|
13941
|
-
this.name = "
|
|
13939
|
+
this.name = "PrivateOpenAIResponsesError";
|
|
13942
13940
|
}
|
|
13943
13941
|
}
|
|
13944
|
-
function
|
|
13945
|
-
if (bytes.byteLength === 0 || bytes.byteLength >
|
|
13946
|
-
throw new
|
|
13942
|
+
function decodePrivateOpenAIResponsesRequest(bytes) {
|
|
13943
|
+
if (bytes.byteLength === 0 || bytes.byteLength > PRIVATE_OPENAI_RESPONSES_REQUEST_BYTES) {
|
|
13944
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_PROTOCOL", "OpenAI Responses worker request exceeds its byte bound");
|
|
13947
13945
|
}
|
|
13948
13946
|
let value;
|
|
13949
13947
|
try {
|
|
13950
13948
|
value = decodeJson1(bytes);
|
|
13951
13949
|
} catch {
|
|
13952
|
-
throw new
|
|
13950
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_PROTOCOL", "OpenAI Responses worker request is not valid JSON/1");
|
|
13953
13951
|
}
|
|
13954
|
-
return
|
|
13952
|
+
return requirePrivateOpenAIResponsesRequest(value);
|
|
13955
13953
|
}
|
|
13956
|
-
function
|
|
13957
|
-
const result =
|
|
13954
|
+
function encodePrivateOpenAIResponsesSuccess(value) {
|
|
13955
|
+
const result = requirePrivateOpenAIResponsesResult(value);
|
|
13958
13956
|
return encodeBounded({
|
|
13959
|
-
protocol:
|
|
13957
|
+
protocol: PRIVATE_OPENAI_RESPONSES_PROTOCOL,
|
|
13960
13958
|
status: "ok",
|
|
13961
13959
|
value: result
|
|
13962
|
-
},
|
|
13960
|
+
}, PRIVATE_OPENAI_RESPONSES_RESPONSE_BYTES, "AGENT_PROVIDER_OUTPUT_LIMIT", "OpenAI Responses worker result exceeds its byte bound");
|
|
13963
13961
|
}
|
|
13964
|
-
function
|
|
13962
|
+
function encodePrivateOpenAIResponsesFailure(code, message) {
|
|
13965
13963
|
if (!ERROR_CODES.has(code)) {
|
|
13966
|
-
throw new TypeError("unknown
|
|
13964
|
+
throw new TypeError("unknown OpenAI Responses worker error code");
|
|
13967
13965
|
}
|
|
13968
13966
|
const bounded = boundUtf8(message, MAX_FAILURE_MESSAGE_BYTES);
|
|
13969
13967
|
return encodeBounded({
|
|
13970
|
-
protocol:
|
|
13968
|
+
protocol: PRIVATE_OPENAI_RESPONSES_PROTOCOL,
|
|
13971
13969
|
status: "error",
|
|
13972
13970
|
code,
|
|
13973
13971
|
message: bounded
|
|
13974
|
-
},
|
|
13972
|
+
}, PRIVATE_OPENAI_RESPONSES_RESPONSE_BYTES, "AGENT_PROVIDER_OUTPUT_LIMIT", "OpenAI Responses worker failure exceeds its byte bound");
|
|
13975
13973
|
}
|
|
13976
|
-
function
|
|
13974
|
+
function requirePrivateOpenAIResponsesRequest(value) {
|
|
13977
13975
|
const record = ordinaryRecord(value);
|
|
13978
13976
|
const hasSchema = record !== undefined && Object.hasOwn(record, "responseSchema");
|
|
13979
|
-
if (record === undefined || !exactKeys(record, hasSchema ? ["apiKey", "baseURL", "instructions", "model", "protocol", "responseSchema"] : ["apiKey", "baseURL", "instructions", "model", "protocol"]) || record.protocol !==
|
|
13980
|
-
throw protocolFailure("
|
|
13977
|
+
if (record === undefined || !exactKeys(record, hasSchema ? ["apiKey", "baseURL", "instructions", "model", "protocol", "responseSchema"] : ["apiKey", "baseURL", "instructions", "model", "protocol"]) || record.protocol !== PRIVATE_OPENAI_RESPONSES_PROTOCOL || typeof record.apiKey !== "string" || record.apiKey.trim().length === 0 || record.apiKey.includes("\x00") || new TextEncoder().encode(record.apiKey).byteLength > 16384 || !validBaseURL(record.baseURL) || !validModel(record.model) || typeof record.instructions !== "string" || !boundedCharacters(record.instructions, MAX_INSTRUCTION_CHARACTERS) || hasSchema && ordinaryRecord(record.responseSchema) === undefined) {
|
|
13978
|
+
throw protocolFailure("OpenAI Responses worker request has an invalid shape");
|
|
13981
13979
|
}
|
|
13982
13980
|
if (hasSchema) {
|
|
13983
13981
|
const responseSchema = record.responseSchema;
|
|
@@ -13985,39 +13983,39 @@ function requirePrivateOpenRouterResponsesRequest(value) {
|
|
|
13985
13983
|
try {
|
|
13986
13984
|
schemaBytes = canonicalJson(responseSchema);
|
|
13987
13985
|
} catch {
|
|
13988
|
-
throw protocolFailure("
|
|
13986
|
+
throw protocolFailure("OpenAI Responses response schema is not valid JSON/1");
|
|
13989
13987
|
}
|
|
13990
13988
|
if (schemaBytes.byteLength > MAX_RESPONSE_SCHEMA_BYTES) {
|
|
13991
|
-
throw protocolFailure("
|
|
13989
|
+
throw protocolFailure("OpenAI Responses response schema exceeds its byte bound");
|
|
13992
13990
|
}
|
|
13993
13991
|
return Object.freeze({
|
|
13994
|
-
protocol:
|
|
13992
|
+
protocol: PRIVATE_OPENAI_RESPONSES_PROTOCOL,
|
|
13995
13993
|
apiKey: record.apiKey,
|
|
13996
|
-
baseURL:
|
|
13997
|
-
model:
|
|
13994
|
+
baseURL: record.baseURL,
|
|
13995
|
+
model: record.model,
|
|
13998
13996
|
instructions: record.instructions,
|
|
13999
13997
|
responseSchema
|
|
14000
13998
|
});
|
|
14001
13999
|
}
|
|
14002
14000
|
return Object.freeze({
|
|
14003
|
-
protocol:
|
|
14001
|
+
protocol: PRIVATE_OPENAI_RESPONSES_PROTOCOL,
|
|
14004
14002
|
apiKey: record.apiKey,
|
|
14005
|
-
baseURL:
|
|
14006
|
-
model:
|
|
14003
|
+
baseURL: record.baseURL,
|
|
14004
|
+
model: record.model,
|
|
14007
14005
|
instructions: record.instructions
|
|
14008
14006
|
});
|
|
14009
14007
|
}
|
|
14010
|
-
function
|
|
14008
|
+
function requirePrivateOpenAIResponsesResult(value) {
|
|
14011
14009
|
const record = ordinaryRecord(value);
|
|
14012
14010
|
const hasStructured = record !== undefined && Object.hasOwn(record, "structured");
|
|
14013
14011
|
if (record === undefined || !exactKeys(record, hasStructured ? ["outcome", "structured", "text"] : ["outcome", "text"]) || record.outcome !== "completed" && record.outcome !== "blocked" && record.outcome !== "limit" || typeof record.text !== "string" || new TextEncoder().encode(record.text).byteLength > JSON_1_LIMITS.stringBytes) {
|
|
14014
|
-
throw protocolFailure("
|
|
14012
|
+
throw protocolFailure("OpenAI Responses worker result has an invalid shape");
|
|
14015
14013
|
}
|
|
14016
14014
|
if (hasStructured) {
|
|
14017
14015
|
try {
|
|
14018
14016
|
validateJson1(record.structured);
|
|
14019
14017
|
} catch {
|
|
14020
|
-
throw protocolFailure("
|
|
14018
|
+
throw protocolFailure("OpenAI Responses worker structured result is not JSON/1");
|
|
14021
14019
|
}
|
|
14022
14020
|
return Object.freeze({
|
|
14023
14021
|
outcome: record.outcome,
|
|
@@ -14032,10 +14030,10 @@ function encodeBounded(value, maximum, code, message) {
|
|
|
14032
14030
|
try {
|
|
14033
14031
|
bytes = canonicalJson(value);
|
|
14034
14032
|
} catch {
|
|
14035
|
-
throw new
|
|
14033
|
+
throw new PrivateOpenAIResponsesError(code, message);
|
|
14036
14034
|
}
|
|
14037
14035
|
if (bytes.byteLength > maximum) {
|
|
14038
|
-
throw new
|
|
14036
|
+
throw new PrivateOpenAIResponsesError(code, message);
|
|
14039
14037
|
}
|
|
14040
14038
|
return bytes;
|
|
14041
14039
|
}
|
|
@@ -14062,6 +14060,19 @@ function boundedCharacters(value, maximum) {
|
|
|
14062
14060
|
}
|
|
14063
14061
|
return true;
|
|
14064
14062
|
}
|
|
14063
|
+
function validBaseURL(value) {
|
|
14064
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 4096)
|
|
14065
|
+
return false;
|
|
14066
|
+
try {
|
|
14067
|
+
const parsed = new URL(value);
|
|
14068
|
+
return parsed.protocol === "https:" && parsed.username === "" && parsed.password === "" && parsed.search === "" && parsed.hash === "";
|
|
14069
|
+
} catch {
|
|
14070
|
+
return false;
|
|
14071
|
+
}
|
|
14072
|
+
}
|
|
14073
|
+
function validModel(value) {
|
|
14074
|
+
return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/.test(value);
|
|
14075
|
+
}
|
|
14065
14076
|
function boundUtf8(value, maximum) {
|
|
14066
14077
|
if (new TextEncoder().encode(value).byteLength <= maximum)
|
|
14067
14078
|
return value;
|
|
@@ -14077,19 +14088,122 @@ function boundUtf8(value, maximum) {
|
|
|
14077
14088
|
return result;
|
|
14078
14089
|
}
|
|
14079
14090
|
function protocolFailure(message) {
|
|
14080
|
-
return new
|
|
14091
|
+
return new PrivateOpenAIResponsesError("AGENT_PROVIDER_PROTOCOL", message);
|
|
14081
14092
|
}
|
|
14082
14093
|
|
|
14083
|
-
// src/internal/
|
|
14094
|
+
// src/internal/openai-responses-client.ts
|
|
14084
14095
|
var MAX_INSTRUCTION_CHARACTERS2 = 1048576;
|
|
14085
14096
|
var MAX_RESPONSE_SCHEMA_BYTES2 = 256 * 1024;
|
|
14086
14097
|
var RESPONSE_FORMAT_NAME = "jig_agent_run_result";
|
|
14087
14098
|
var MAX_OUTPUT_TOKENS = 4096;
|
|
14088
|
-
|
|
14089
|
-
|
|
14099
|
+
var MAX_RESPONSE_SCHEMA_DEPTH = 8;
|
|
14100
|
+
var MAX_PROPERTIES_PER_OBJECT = 32;
|
|
14101
|
+
var MAX_RESPONSE_SCHEMA_PROPERTIES = 128;
|
|
14102
|
+
var MAX_ARRAY_ITEMS = 256;
|
|
14103
|
+
var MAX_RESPONSE_SCHEMA_ENUM_VALUES = 256;
|
|
14104
|
+
var MAX_RESPONSE_SCHEMA_SYMBOL_CHARACTERS = 120000;
|
|
14105
|
+
var MAX_LARGE_ENUM_CHARACTERS = 15000;
|
|
14106
|
+
function assertPrivateAgentResponseSchema(schema) {
|
|
14107
|
+
if (schema.$schema !== "https://flow.jig.md/schemas/schema-1.json")
|
|
14108
|
+
invalidSchemaProfile();
|
|
14109
|
+
const state2 = {
|
|
14110
|
+
properties: 0,
|
|
14111
|
+
enumValues: 0,
|
|
14112
|
+
symbolCharacters: 0
|
|
14113
|
+
};
|
|
14114
|
+
assertResponseSchemaNode(schema, 1, true, state2);
|
|
14115
|
+
}
|
|
14116
|
+
function assertResponseSchemaNode(value, depth, root, state2) {
|
|
14117
|
+
const schema = ordinaryRecord2(value);
|
|
14118
|
+
if (schema === undefined || depth > MAX_RESPONSE_SCHEMA_DEPTH)
|
|
14119
|
+
invalidSchemaProfile();
|
|
14120
|
+
if (schema.type === "object") {
|
|
14121
|
+
assertClosedResponseObject(schema, depth, root, state2);
|
|
14122
|
+
return;
|
|
14123
|
+
}
|
|
14124
|
+
if (root || Object.hasOwn(schema, "$schema"))
|
|
14125
|
+
invalidSchemaProfile();
|
|
14126
|
+
if (schema.type === "array") {
|
|
14127
|
+
const baseExpected = Object.hasOwn(schema, "minItems") ? ["items", "maxItems", "minItems", "type"] : ["items", "maxItems", "type"];
|
|
14128
|
+
if (!exactProfileKeys(schema, baseExpected) || !boundedNonnegativeInteger(schema.maxItems, MAX_ARRAY_ITEMS) || Object.hasOwn(schema, "minItems") && (!boundedNonnegativeInteger(schema.minItems, MAX_ARRAY_ITEMS) || schema.minItems > schema.maxItems)) {
|
|
14129
|
+
invalidSchemaProfile();
|
|
14130
|
+
}
|
|
14131
|
+
assertResponseSchemaNode(schema.items, depth + 1, false, state2);
|
|
14132
|
+
return;
|
|
14133
|
+
}
|
|
14134
|
+
if (schema.type === "integer" || isNullableType(schema.type, "integer")) {
|
|
14135
|
+
if (!exactProfileKeys(schema, ["type"]))
|
|
14136
|
+
invalidSchemaProfile();
|
|
14137
|
+
return;
|
|
14138
|
+
}
|
|
14139
|
+
if (schema.type === "string" || isNullableType(schema.type, "string")) {
|
|
14140
|
+
assertResponseString(schema, isNullableType(schema.type, "string"), state2);
|
|
14141
|
+
return;
|
|
14142
|
+
}
|
|
14143
|
+
invalidSchemaProfile();
|
|
14144
|
+
}
|
|
14145
|
+
function assertClosedResponseObject(schema, depth, root, state2) {
|
|
14146
|
+
const expected = root ? ["$schema", "additionalProperties", "properties", "required", "type"] : ["additionalProperties", "properties", "required", "type"];
|
|
14147
|
+
const properties = ordinaryRecord2(schema.properties);
|
|
14148
|
+
if (!exactProfileKeys(schema, expected) || schema.additionalProperties !== false || properties === undefined || !Array.isArray(schema.required)) {
|
|
14149
|
+
invalidSchemaProfile();
|
|
14150
|
+
}
|
|
14151
|
+
const names = Object.keys(properties);
|
|
14152
|
+
if (names.length === 0 || names.length > MAX_PROPERTIES_PER_OBJECT || schema.required.length !== names.length || new Set(schema.required).size !== names.length || schema.required.some((name) => typeof name !== "string" || !Object.hasOwn(properties, name))) {
|
|
14153
|
+
invalidSchemaProfile();
|
|
14154
|
+
}
|
|
14155
|
+
state2.properties += names.length;
|
|
14156
|
+
if (state2.properties > MAX_RESPONSE_SCHEMA_PROPERTIES)
|
|
14157
|
+
invalidSchemaProfile();
|
|
14158
|
+
for (const name of names) {
|
|
14159
|
+
state2.symbolCharacters += unicodeScalarLength(name);
|
|
14160
|
+
if (state2.symbolCharacters > MAX_RESPONSE_SCHEMA_SYMBOL_CHARACTERS)
|
|
14161
|
+
invalidSchemaProfile();
|
|
14162
|
+
assertResponseSchemaNode(properties[name], depth + 1, false, state2);
|
|
14163
|
+
}
|
|
14164
|
+
}
|
|
14165
|
+
function assertResponseString(schema, nullable, state2) {
|
|
14166
|
+
if (!Object.hasOwn(schema, "enum")) {
|
|
14167
|
+
if (!exactProfileKeys(schema, ["type"]))
|
|
14168
|
+
invalidSchemaProfile();
|
|
14169
|
+
return;
|
|
14170
|
+
}
|
|
14171
|
+
if (!exactProfileKeys(schema, ["enum", "type"]) || !Array.isArray(schema.enum) || schema.enum.length === 0 || schema.enum.length > MAX_RESPONSE_SCHEMA_ENUM_VALUES || schema.enum.some((item) => typeof item !== "string" && (!nullable || item !== null)) || new Set(schema.enum).size !== schema.enum.length || nullable && (!schema.enum.includes(null) || !schema.enum.some((item) => typeof item === "string"))) {
|
|
14172
|
+
invalidSchemaProfile();
|
|
14173
|
+
}
|
|
14174
|
+
state2.enumValues += schema.enum.length;
|
|
14175
|
+
const enumCharacters = schema.enum.reduce((total, item) => total + (typeof item === "string" ? unicodeScalarLength(item) : 0), 0);
|
|
14176
|
+
if (schema.enum.length > 250 && enumCharacters > MAX_LARGE_ENUM_CHARACTERS) {
|
|
14177
|
+
invalidSchemaProfile();
|
|
14178
|
+
}
|
|
14179
|
+
state2.symbolCharacters += enumCharacters;
|
|
14180
|
+
if (state2.enumValues > MAX_RESPONSE_SCHEMA_ENUM_VALUES)
|
|
14181
|
+
invalidSchemaProfile();
|
|
14182
|
+
if (state2.symbolCharacters > MAX_RESPONSE_SCHEMA_SYMBOL_CHARACTERS)
|
|
14183
|
+
invalidSchemaProfile();
|
|
14184
|
+
}
|
|
14185
|
+
function isNullableType(value, base) {
|
|
14186
|
+
return Array.isArray(value) && value.length === 2 && new Set(value).size === 2 && value.includes(base) && value.includes("null");
|
|
14187
|
+
}
|
|
14188
|
+
function exactProfileKeys(value, expected) {
|
|
14189
|
+
if (Object.hasOwn(value, "description") && typeof value.description !== "string")
|
|
14190
|
+
return false;
|
|
14191
|
+
return exactKeys2(value, Object.hasOwn(value, "description") ? [...expected, "description"] : expected);
|
|
14192
|
+
}
|
|
14193
|
+
function boundedNonnegativeInteger(value, maximum) {
|
|
14194
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && value <= maximum;
|
|
14195
|
+
}
|
|
14196
|
+
function unicodeScalarLength(value) {
|
|
14197
|
+
return [...value].length;
|
|
14198
|
+
}
|
|
14199
|
+
function invalidSchemaProfile() {
|
|
14200
|
+
throw new TypeError("Agent responseSchema must use the bounded structured-output profile");
|
|
14201
|
+
}
|
|
14202
|
+
async function requestPrivateOpenAIResponse(request, dependencies) {
|
|
14203
|
+
requireClientRequest(request);
|
|
14090
14204
|
requireApiKey(dependencies.apiKey);
|
|
14091
14205
|
if (dependencies.client !== undefined && dependencies.fetch !== undefined) {
|
|
14092
|
-
throw new
|
|
14206
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses test transport is ambiguous");
|
|
14093
14207
|
}
|
|
14094
14208
|
const body = createBody(request);
|
|
14095
14209
|
const client = dependencies.client ?? sdkClient(request.baseURL, dependencies.apiKey, dependencies.fetch);
|
|
@@ -14097,17 +14211,17 @@ async function requestPrivateOpenRouterResponse(request, dependencies) {
|
|
|
14097
14211
|
try {
|
|
14098
14212
|
response = await client.create(body);
|
|
14099
14213
|
} catch {
|
|
14100
|
-
throw new
|
|
14214
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_UNAVAILABLE", "OpenAI Responses request failed");
|
|
14101
14215
|
}
|
|
14102
|
-
return
|
|
14216
|
+
return normalizePrivateOpenAIResponse(response, request.responseSchema !== undefined);
|
|
14103
14217
|
}
|
|
14104
|
-
function
|
|
14218
|
+
function normalizePrivateOpenAIResponse(response, structuredRequested) {
|
|
14105
14219
|
const record = ordinaryRecord2(response);
|
|
14106
14220
|
if (record === undefined || record.status !== "completed" && record.status !== "incomplete" && record.status !== "failed" && record.status !== "cancelled" && record.status !== "queued" && record.status !== "in_progress" || !Array.isArray(record.output)) {
|
|
14107
14221
|
throw invalidResponse();
|
|
14108
14222
|
}
|
|
14109
14223
|
if (Object.hasOwn(record, "error") && record.error !== null || record.status === "failed" || record.status === "cancelled") {
|
|
14110
|
-
throw new
|
|
14224
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_UNAVAILABLE", "OpenAI Responses request did not complete");
|
|
14111
14225
|
}
|
|
14112
14226
|
if (record.status === "queued" || record.status === "in_progress") {
|
|
14113
14227
|
throw invalidResponse();
|
|
@@ -14132,7 +14246,7 @@ function normalizePrivateOpenRouterResponse(response, structuredRequested) {
|
|
|
14132
14246
|
} catch {
|
|
14133
14247
|
if (outcome !== "completed")
|
|
14134
14248
|
return Object.freeze({ outcome, text });
|
|
14135
|
-
throw new
|
|
14249
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_RESPONSE_INVALID", "OpenAI structured response is not valid JSON/1");
|
|
14136
14250
|
}
|
|
14137
14251
|
}
|
|
14138
14252
|
function sdkClient(baseURL, apiKey, injectedFetch) {
|
|
@@ -14176,44 +14290,46 @@ function createBody(request) {
|
|
|
14176
14290
|
format: {
|
|
14177
14291
|
type: "json_schema",
|
|
14178
14292
|
name: RESPONSE_FORMAT_NAME,
|
|
14179
|
-
schema:
|
|
14293
|
+
schema: projectPrivateAgentResponseSchema(request.responseSchema),
|
|
14180
14294
|
strict: true
|
|
14181
14295
|
}
|
|
14182
14296
|
}
|
|
14183
14297
|
};
|
|
14184
14298
|
}
|
|
14185
|
-
function
|
|
14299
|
+
function projectPrivateAgentResponseSchema(responseSchema) {
|
|
14186
14300
|
return Object.fromEntries(Object.entries(responseSchema).filter(([name]) => name !== "$schema"));
|
|
14187
14301
|
}
|
|
14188
|
-
function requireClientRequest(request
|
|
14302
|
+
function requireClientRequest(request) {
|
|
14189
14303
|
if (request === null || typeof request !== "object" || typeof request.baseURL !== "string" || typeof request.model !== "string" || typeof request.instructions !== "string" || !boundedCharacters2(request.instructions, MAX_INSTRUCTION_CHARACTERS2)) {
|
|
14190
|
-
throw new
|
|
14304
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses client request is invalid");
|
|
14191
14305
|
}
|
|
14192
14306
|
try {
|
|
14193
14307
|
validateJson1(request.instructions);
|
|
14194
14308
|
} catch {
|
|
14195
|
-
throw new
|
|
14309
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses instructions are not valid JSON/1 text");
|
|
14196
14310
|
}
|
|
14197
14311
|
requireEndpoint(request.baseURL);
|
|
14198
14312
|
if (!/^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/.test(request.model)) {
|
|
14199
|
-
throw new
|
|
14200
|
-
}
|
|
14201
|
-
if (!injectedTransport && (request.baseURL !== PRIVATE_OPENROUTER_RESPONSES_BASE_URL || request.model !== PRIVATE_OPENROUTER_RESPONSES_MODEL)) {
|
|
14202
|
-
throw new PrivateOpenRouterResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenRouter Responses production configuration is not pinned");
|
|
14313
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses model is invalid");
|
|
14203
14314
|
}
|
|
14204
14315
|
if (request.responseSchema !== undefined) {
|
|
14205
14316
|
if (ordinaryRecord2(request.responseSchema) === undefined) {
|
|
14206
|
-
throw new
|
|
14317
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI response schema is invalid");
|
|
14207
14318
|
}
|
|
14208
14319
|
let bytes;
|
|
14209
14320
|
try {
|
|
14210
14321
|
validateJson1(request.responseSchema);
|
|
14211
14322
|
bytes = canonicalJson(request.responseSchema);
|
|
14212
14323
|
} catch {
|
|
14213
|
-
throw new
|
|
14324
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI response schema is not valid JSON/1");
|
|
14214
14325
|
}
|
|
14215
14326
|
if (bytes.byteLength > MAX_RESPONSE_SCHEMA_BYTES2) {
|
|
14216
|
-
throw new
|
|
14327
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI response schema exceeds its byte bound");
|
|
14328
|
+
}
|
|
14329
|
+
try {
|
|
14330
|
+
assertPrivateAgentResponseSchema(request.responseSchema);
|
|
14331
|
+
} catch {
|
|
14332
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI response schema is outside the supported profile");
|
|
14217
14333
|
}
|
|
14218
14334
|
}
|
|
14219
14335
|
}
|
|
@@ -14227,16 +14343,16 @@ function requireEndpoint(baseURL) {
|
|
|
14227
14343
|
} catch {
|
|
14228
14344
|
throw invalidEndpoint();
|
|
14229
14345
|
}
|
|
14230
|
-
if (parsed.protocol !== "https:"
|
|
14346
|
+
if (parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "" || parsed.search !== "" || parsed.hash !== "") {
|
|
14231
14347
|
throw invalidEndpoint();
|
|
14232
14348
|
}
|
|
14233
14349
|
}
|
|
14234
14350
|
function invalidEndpoint() {
|
|
14235
|
-
return new
|
|
14351
|
+
return new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses base URL is invalid");
|
|
14236
14352
|
}
|
|
14237
14353
|
function requireApiKey(apiKey) {
|
|
14238
14354
|
if (typeof apiKey !== "string" || apiKey.trim().length === 0 || apiKey.includes("\x00") || new TextEncoder().encode(apiKey).byteLength > 16384) {
|
|
14239
|
-
throw new
|
|
14355
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_CONFIGURATION", "OpenAI Responses API key is unavailable");
|
|
14240
14356
|
}
|
|
14241
14357
|
}
|
|
14242
14358
|
function responseContent(record, allowEmpty) {
|
|
@@ -14285,7 +14401,7 @@ function joinBounded(parts, separator) {
|
|
|
14285
14401
|
if (index !== 0)
|
|
14286
14402
|
bytes += separatorBytes;
|
|
14287
14403
|
if (bytes > JSON_1_LIMITS.stringBytes) {
|
|
14288
|
-
throw new
|
|
14404
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_OUTPUT_LIMIT", "OpenAI Responses text exceeds its byte bound");
|
|
14289
14405
|
}
|
|
14290
14406
|
}
|
|
14291
14407
|
return parts.join(separator);
|
|
@@ -14298,6 +14414,11 @@ function ordinaryRecord2(value) {
|
|
|
14298
14414
|
return;
|
|
14299
14415
|
return value;
|
|
14300
14416
|
}
|
|
14417
|
+
function exactKeys2(value, expected) {
|
|
14418
|
+
const actual = Object.keys(value).sort();
|
|
14419
|
+
const sorted = [...expected].sort();
|
|
14420
|
+
return actual.length === sorted.length && actual.every((name, index) => name === sorted[index]);
|
|
14421
|
+
}
|
|
14301
14422
|
function boundedCharacters2(value, maximum) {
|
|
14302
14423
|
if (value.length === 0)
|
|
14303
14424
|
return false;
|
|
@@ -14310,23 +14431,23 @@ function boundedCharacters2(value, maximum) {
|
|
|
14310
14431
|
return true;
|
|
14311
14432
|
}
|
|
14312
14433
|
function invalidResponse() {
|
|
14313
|
-
return new
|
|
14434
|
+
return new PrivateOpenAIResponsesError("AGENT_PROVIDER_RESPONSE_INVALID", "OpenAI Responses returned an invalid final response");
|
|
14314
14435
|
}
|
|
14315
14436
|
|
|
14316
|
-
// src/internal/
|
|
14437
|
+
// src/internal/openai-responses-worker.ts
|
|
14317
14438
|
await main();
|
|
14318
14439
|
async function main() {
|
|
14319
14440
|
let output;
|
|
14320
14441
|
try {
|
|
14321
|
-
const input = await readBoundedInput(
|
|
14322
|
-
const request =
|
|
14323
|
-
const value = await
|
|
14442
|
+
const input = await readBoundedInput(PRIVATE_OPENAI_RESPONSES_REQUEST_BYTES);
|
|
14443
|
+
const request = decodePrivateOpenAIResponsesRequest(input);
|
|
14444
|
+
const value = await requestPrivateOpenAIResponse(request, {
|
|
14324
14445
|
apiKey: request.apiKey
|
|
14325
14446
|
});
|
|
14326
|
-
output =
|
|
14447
|
+
output = encodePrivateOpenAIResponsesSuccess(value);
|
|
14327
14448
|
} catch (error2) {
|
|
14328
14449
|
const failure = safeFailure(error2);
|
|
14329
|
-
output =
|
|
14450
|
+
output = encodePrivateOpenAIResponsesFailure(failure.code, failure.message);
|
|
14330
14451
|
}
|
|
14331
14452
|
try {
|
|
14332
14453
|
await writeOutput(output);
|
|
@@ -14341,7 +14462,7 @@ async function readBoundedInput(maximum) {
|
|
|
14341
14462
|
const chunk = typeof raw === "string" ? new TextEncoder().encode(raw) : new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength);
|
|
14342
14463
|
total += chunk.byteLength;
|
|
14343
14464
|
if (total > maximum) {
|
|
14344
|
-
throw new
|
|
14465
|
+
throw new PrivateOpenAIResponsesError("AGENT_PROVIDER_PROTOCOL", "OpenAI Responses worker request exceeds its byte bound");
|
|
14345
14466
|
}
|
|
14346
14467
|
chunks.push(chunk.slice());
|
|
14347
14468
|
}
|
|
@@ -14354,12 +14475,12 @@ async function readBoundedInput(maximum) {
|
|
|
14354
14475
|
return result;
|
|
14355
14476
|
}
|
|
14356
14477
|
function safeFailure(error2) {
|
|
14357
|
-
if (error2 instanceof
|
|
14478
|
+
if (error2 instanceof PrivateOpenAIResponsesError) {
|
|
14358
14479
|
return Object.freeze({ code: error2.code, message: error2.message });
|
|
14359
14480
|
}
|
|
14360
14481
|
return Object.freeze({
|
|
14361
14482
|
code: "AGENT_PROVIDER_UNAVAILABLE",
|
|
14362
|
-
message: "
|
|
14483
|
+
message: "OpenAI Responses worker failed"
|
|
14363
14484
|
});
|
|
14364
14485
|
}
|
|
14365
14486
|
function writeOutput(bytes) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sergii Kozak
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|