dsh-codex-connect 0.1.0-alpha.4.20 → 0.1.0-alpha.4.21

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.
@@ -1,4 +1,4 @@
1
- import { randomBytes, randomUUID } from "node:crypto";
1
+ import { createHash, randomBytes, randomUUID } from "node:crypto";
2
2
  import { basename, dirname, join, parse, resolve } from "node:path";
3
3
  import z from "@deepseek-ai/schemastery";
4
4
  import { deepEqualJson, installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
@@ -12,6 +12,7 @@ import { resolveDshHome } from "@deepseek-ai/dsh-home-paths";
12
12
  import { AsyncLocalStorage } from "node:async_hooks";
13
13
  import { Dispatcher, ProxyAgent, getGlobalDispatcher, setGlobalDispatcher } from "undici";
14
14
  import { fileURLToPath } from "node:url";
15
+ import { SessionId } from "@deepseek-ai/dsh-session";
15
16
  import { AttachmentId } from "@deepseek-ai/dsh-attachment";
16
17
  import { TOOL_ABORTED, defineTool } from "@deepseek-ai/dsh-tools";
17
18
  import { lookup } from "node:dns/promises";
@@ -19,8 +20,8 @@ import { request } from "node:http";
19
20
  import { request as request$1 } from "node:https";
20
21
  import { BlockList, isIP } from "node:net";
21
22
  import { Service } from "@deepseek-ai/cordis";
22
- import { WebError } from "@deepseek-ai/dsh-web";
23
23
  import { constants } from "node:fs";
24
+ import { WebError } from "@deepseek-ai/dsh-web";
24
25
  import { constants as constants$1, zstdCompressSync, zstdDecompressSync } from "node:zlib";
25
26
  //#region src/store.ts
26
27
  /**
@@ -53,7 +54,7 @@ async function assertOwnerOnly$1(filename) {
53
54
  /* v8 ignore stop */
54
55
  }
55
56
  /** Validate the strict JSON document without quoting token-bearing input. */
56
- function parseDocument$1(text, filename) {
57
+ function parseDocument$2(text, filename) {
57
58
  let value;
58
59
  try {
59
60
  value = JSON.parse(text);
@@ -118,7 +119,7 @@ var OpenAICodexCredentialStore = class {
118
119
  if (isENOENT$1(error)) return void 0;
119
120
  throw error;
120
121
  }
121
- return cloneCredential(parseDocument$1(text, this.filename).credential);
122
+ return cloneCredential(parseDocument$2(text, this.filename).credential);
122
123
  }
123
124
  /** @inheritdoc */
124
125
  async read(providerId) {
@@ -142,7 +143,7 @@ var OpenAICodexCredentialStore = class {
142
143
  const current = await this.readCurrent();
143
144
  const candidate = await fn(current);
144
145
  if (candidate === void 0) return current;
145
- const document = parseDocument$1(JSON.stringify({
146
+ const document = parseDocument$2(JSON.stringify({
146
147
  version: AUTH_FORMAT_VERSION,
147
148
  credential: candidate
148
149
  }), this.filename);
@@ -521,7 +522,7 @@ async function assertOwnerOnly(filename) {
521
522
  /* v8 ignore stop */
522
523
  }
523
524
  /** Reject malformed input without echoing its contents into an error. */
524
- function parseDocument(text, filename) {
525
+ function parseDocument$1(text, filename) {
525
526
  let value;
526
527
  try {
527
528
  value = JSON.parse(text);
@@ -601,7 +602,7 @@ var OpenAICodexTrustedOriginsStore = class {
601
602
  };
602
603
  throw error;
603
604
  }
604
- return parseDocument(text, this.filename);
605
+ return parseDocument$1(text, this.filename);
605
606
  }
606
607
  /** Read the current canonical list without acquiring the writer lock. */
607
608
  async list() {
@@ -963,7 +964,7 @@ async function trustedRequestDecision(req, trustedOrigins = new OpenAICodexTrust
963
964
  error: REMOTE_WEB_ORIGIN_NOT_TRUSTED
964
965
  };
965
966
  }
966
- function json$3(res, status, value) {
967
+ function json$4(res, status, value) {
967
968
  res.writeHead(status, {
968
969
  "content-type": "application/json; charset=utf-8",
969
970
  "cache-control": "no-store",
@@ -1056,7 +1057,7 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
1056
1057
  const authorize = async (req, res) => {
1057
1058
  const decision = await trustedRequestDecision(req, trustedOrigins);
1058
1059
  if (decision.trusted) return true;
1059
- json$3(res, 403, { error: decision.error });
1060
+ json$4(res, 403, { error: decision.error });
1060
1061
  return false;
1061
1062
  };
1062
1063
  const routes = [
@@ -1064,21 +1065,21 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
1064
1065
  kind: "exact",
1065
1066
  path: OPENAI_CODEX_AUTH_STATUS_PATH,
1066
1067
  handler: async (req, res) => {
1067
- if (req.method !== "GET") return json$3(res, 405, { error: "method not allowed" });
1068
+ if (req.method !== "GET") return json$4(res, 405, { error: "method not allowed" });
1068
1069
  if (!await authorize(req, res)) return;
1069
- json$3(res, 200, await auth.status());
1070
+ json$4(res, 200, await auth.status());
1070
1071
  }
1071
1072
  }),
1072
1073
  ctx.webServer.register({
1073
1074
  kind: "exact",
1074
1075
  path: OPENAI_CODEX_AUTH_LOGIN_PATH,
1075
1076
  handler: async (req, res) => {
1076
- if (req.method !== "POST") return json$3(res, 405, { error: "method not allowed" });
1077
+ if (req.method !== "POST") return json$4(res, 405, { error: "method not allowed" });
1077
1078
  if (!await authorize(req, res)) return;
1078
1079
  try {
1079
- json$3(res, 200, await auth.signIn());
1080
+ json$4(res, 200, await auth.signIn());
1080
1081
  } catch (error) {
1081
- json$3(res, 500, { error: safeMessage(error) });
1082
+ json$4(res, 500, { error: safeMessage(error) });
1082
1083
  }
1083
1084
  }
1084
1085
  }),
@@ -1086,13 +1087,13 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
1086
1087
  kind: "exact",
1087
1088
  path: OPENAI_CODEX_AUTH_LOGOUT_PATH,
1088
1089
  handler: async (req, res) => {
1089
- if (req.method !== "POST") return json$3(res, 405, { error: "method not allowed" });
1090
+ if (req.method !== "POST") return json$4(res, 405, { error: "method not allowed" });
1090
1091
  if (!await authorize(req, res)) return;
1091
1092
  try {
1092
1093
  await auth.signOut();
1093
- json$3(res, 200, { ok: true });
1094
+ json$4(res, 200, { ok: true });
1094
1095
  } catch (error) {
1095
- json$3(res, 500, { error: safeMessage(error) });
1096
+ json$4(res, 500, { error: safeMessage(error) });
1096
1097
  }
1097
1098
  }
1098
1099
  }),
@@ -1100,22 +1101,22 @@ function registerOpenAICodexAuthRoutes(ctx, store, trustedOriginsOverride, fastM
1100
1101
  kind: "exact",
1101
1102
  path: OPENAI_CODEX_FAST_MODE_PATH,
1102
1103
  handler: async (req, res) => {
1103
- if (req.method !== "GET" && req.method !== "POST") return json$3(res, 405, { error: "method not allowed" });
1104
+ if (req.method !== "GET" && req.method !== "POST") return json$4(res, 405, { error: "method not allowed" });
1104
1105
  if (!await authorize(req, res)) return;
1105
1106
  if (req.method === "GET") {
1106
1107
  const sessionId = fastModeSessionIdFromQuery(req);
1107
- if (sessionId === void 0) return json$3(res, 400, { error: "invalid input" });
1108
- return json$3(res, 200, { enabled: fastMode.isEnabled(sessionId) });
1108
+ if (sessionId === void 0) return json$4(res, 400, { error: "invalid input" });
1109
+ return json$4(res, 200, { enabled: fastMode.isEnabled(sessionId) });
1109
1110
  }
1110
1111
  const type = header(req, "content-type");
1111
- if (type === void 0 || !/^application\/json(?:\s*;|$)/iu.test(type.trim())) return json$3(res, 415, { error: "unsupported content type" });
1112
+ if (type === void 0 || !/^application\/json(?:\s*;|$)/iu.test(type.trim())) return json$4(res, 415, { error: "unsupported content type" });
1112
1113
  try {
1113
1114
  const body = fastModeBody(await readFastModeBody(req));
1114
- if (body === void 0) return json$3(res, 400, { error: "invalid input" });
1115
+ if (body === void 0) return json$4(res, 400, { error: "invalid input" });
1115
1116
  fastMode.set(body.sessionId, body.enabled);
1116
- return json$3(res, 200, { enabled: fastMode.isEnabled(body.sessionId) });
1117
+ return json$4(res, 200, { enabled: fastMode.isEnabled(body.sessionId) });
1117
1118
  } catch (error) {
1118
- return json$3(res, error instanceof RangeError ? 413 : 400, { error: error instanceof RangeError ? "request body too large" : "invalid input" });
1119
+ return json$4(res, error instanceof RangeError ? 413 : 400, { error: error instanceof RangeError ? "request body too large" : "invalid input" });
1119
1120
  }
1120
1121
  }
1121
1122
  })
@@ -1455,7 +1456,7 @@ const OPENAI_CODEX_PROXY_DETECT_PATH = "/plugins/dsh-openai-codex/proxy/detect";
1455
1456
  const OPENAI_CODEX_PROXY_TEST_PATH = "/plugins/dsh-openai-codex/proxy/test";
1456
1457
  //#endregion
1457
1458
  //#region src/proxy-routes.ts
1458
- function json$2(res, status, value) {
1459
+ function json$3(res, status, value) {
1459
1460
  res.writeHead(status, {
1460
1461
  "content-type": "application/json; charset=utf-8",
1461
1462
  "cache-control": "no-store",
@@ -1478,17 +1479,17 @@ function registerOpenAICodexProxyRoutes(ctx, trustedOrigins, manager) {
1478
1479
  const authorize = async (req, res) => {
1479
1480
  const decision = await trustedRequestDecision(req, trustedOrigins);
1480
1481
  if (decision.trusted) return true;
1481
- json$2(res, 403, { error: decision.error });
1482
+ json$3(res, 403, { error: decision.error });
1482
1483
  return false;
1483
1484
  };
1484
1485
  const routes = [ctx.webServer.register({
1485
1486
  kind: "exact",
1486
1487
  path: OPENAI_CODEX_PROXY_DETECT_PATH,
1487
1488
  handler: async (req, res) => {
1488
- if (req.method !== "POST") return json$2(res, 405, { error: "method not allowed" });
1489
+ if (req.method !== "POST") return json$3(res, 405, { error: "method not allowed" });
1489
1490
  if (!await authorize(req, res)) return;
1490
1491
  const results = await detectOpenAICodexProxies(manager);
1491
- return json$2(res, 200, {
1492
+ return json$3(res, 200, {
1492
1493
  candidates: results.filter((result) => result.reachable),
1493
1494
  results
1494
1495
  });
@@ -1497,11 +1498,11 @@ function registerOpenAICodexProxyRoutes(ctx, trustedOrigins, manager) {
1497
1498
  kind: "exact",
1498
1499
  path: OPENAI_CODEX_PROXY_TEST_PATH,
1499
1500
  handler: async (req, res) => {
1500
- if (req.method !== "POST") return json$2(res, 405, { error: "method not allowed" });
1501
+ if (req.method !== "POST") return json$3(res, 405, { error: "method not allowed" });
1501
1502
  if (!await authorize(req, res)) return;
1502
1503
  const proxyUrl = proxyUrlFromQuery(req);
1503
- if (proxyUrl === void 0) return json$2(res, 400, { error: "invalid proxy URL" });
1504
- return json$2(res, 200, await manager.probe(proxyUrl));
1504
+ if (proxyUrl === void 0) return json$3(res, 400, { error: "invalid proxy URL" });
1505
+ return json$3(res, 200, await manager.probe(proxyUrl));
1505
1506
  }
1506
1507
  })];
1507
1508
  return () => {
@@ -1616,7 +1617,12 @@ function evaluateCompatibility(input = {}) {
1616
1617
  }
1617
1618
  /** Alias for callers that prefer assessment terminology. */
1618
1619
  const assessCompatibility = evaluateCompatibility;
1619
- async function readPackageVersionFromEntry(name) {
1620
+ /**
1621
+ * Resolve installed package metadata without returning a filesystem path.
1622
+ * @param name - package to resolve from this plugin installation.
1623
+ * @returns its version, or undefined when metadata cannot be read.
1624
+ */
1625
+ async function readInstalledPackageVersion(name) {
1620
1626
  let entry;
1621
1627
  try {
1622
1628
  const resolved = import.meta.resolve(name);
@@ -1639,7 +1645,7 @@ async function readPackageVersionFromEntry(name) {
1639
1645
  }
1640
1646
  /** Read installed package metadata and return only versions and statuses. */
1641
1647
  async function detectCompatibility(options = {}) {
1642
- const readVersion = options.readPackageVersion ?? readPackageVersionFromEntry;
1648
+ const readVersion = options.readPackageVersion ?? readInstalledPackageVersion;
1643
1649
  const packageVersions = options.packageVersions ?? options.packages ?? options.installed?.packages;
1644
1650
  const resolvedPackages = packageVersions === void 0 ? Object.fromEntries(await Promise.all(COMPATIBILITY_PACKAGES.map(async (name) => [name, await readVersion(name)]))) : packageVersions;
1645
1651
  return evaluateCompatibility({
@@ -2094,7 +2100,7 @@ async function detectCurrentDshVersion() {
2094
2100
  const adapter = report.packages["@deepseek-ai/dsh-llm-pi-ai"].installed;
2095
2101
  return llm !== null && llm === adapter ? llm : void 0;
2096
2102
  }
2097
- function json$1(res, status, value) {
2103
+ function json$2(res, status, value) {
2098
2104
  res.writeHead(status, {
2099
2105
  "content-type": "application/json; charset=utf-8",
2100
2106
  "cache-control": "no-store",
@@ -2109,14 +2115,14 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
2109
2115
  kind: "exact",
2110
2116
  path: OPENAI_CODEX_RUNTIME_PATH,
2111
2117
  handler: async (req, res) => {
2112
- if (req.method !== "GET") return json$1(res, 405, { error: "method not allowed" });
2118
+ if (req.method !== "GET") return json$2(res, 405, { error: "method not allowed" });
2113
2119
  const decision = await trustedRequestDecision(req, trustedOrigins);
2114
- if (!decision.trusted) return json$1(res, 403, { error: decision.error });
2120
+ if (!decision.trusted) return json$2(res, 403, { error: decision.error });
2115
2121
  try {
2116
2122
  const currentDshVersion = await (options.resolveCurrentDshVersion ?? detectCurrentDshVersion)();
2117
- return json$1(res, 200, currentDshVersion === void 0 ? {} : { currentDshVersion });
2123
+ return json$2(res, 200, currentDshVersion === void 0 ? {} : { currentDshVersion });
2118
2124
  } catch {
2119
- return json$1(res, 200, {});
2125
+ return json$2(res, 200, {});
2120
2126
  }
2121
2127
  }
2122
2128
  });
@@ -2124,9 +2130,9 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
2124
2130
  kind: "exact",
2125
2131
  path: OPENAI_CODEX_UPDATE_PATH,
2126
2132
  handler: async (req, res) => {
2127
- if (req.method !== "GET") return json$1(res, 405, { error: "method not allowed" });
2133
+ if (req.method !== "GET") return json$2(res, 405, { error: "method not allowed" });
2128
2134
  const decision = await trustedRequestDecision(req, trustedOrigins);
2129
- if (!decision.trusted) return json$1(res, 403, { error: decision.error });
2135
+ if (!decision.trusted) return json$2(res, 403, { error: decision.error });
2130
2136
  let result;
2131
2137
  let currentDshVersion;
2132
2138
  try {
@@ -2149,7 +2155,7 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
2149
2155
  reason: "registry-unavailable"
2150
2156
  };
2151
2157
  }
2152
- return json$1(res, 200, result);
2158
+ return json$2(res, 200, result);
2153
2159
  }
2154
2160
  });
2155
2161
  return () => {
@@ -2165,7 +2171,7 @@ function registerOpenAICodexUpdateRoutes(ctx, options, trustedOrigins) {
2165
2171
  const OPENAI_CODEX_MODEL_CATALOG_PATH = "/plugins/dsh-codex-connect/models";
2166
2172
  //#endregion
2167
2173
  //#region src/model-routes.ts
2168
- function json(res, status, value) {
2174
+ function json$1(res, status, value) {
2169
2175
  res.writeHead(status, {
2170
2176
  "content-type": "application/json; charset=utf-8",
2171
2177
  "cache-control": "no-store",
@@ -2178,17 +2184,162 @@ function registerOpenAICodexModelCatalogRoute(ctx, resolveCatalog, trustedOrigin
2178
2184
  ctx.effect(() => ctx.webServer.register({
2179
2185
  kind: "exact",
2180
2186
  path: OPENAI_CODEX_MODEL_CATALOG_PATH,
2187
+ handler: async (req, res) => {
2188
+ if (req.method !== "GET") return json$1(res, 405, { error: "method not allowed" });
2189
+ const decision = await trustedRequestDecision(req, trustedOrigins);
2190
+ if (!decision.trusted) return json$1(res, 403, { error: decision.error });
2191
+ return json$1(res, 200, resolveCatalog());
2192
+ }
2193
+ }), "dsh-codex-connect: model catalog route");
2194
+ }
2195
+ //#endregion
2196
+ //#region src/image-assets-contract.ts
2197
+ /** Same-origin endpoint serving one session-owned original generated image. */
2198
+ const OPENAI_CODEX_ORIGINAL_IMAGE_PATH = "/plugins/dsh-codex-connect/images/original";
2199
+ /** Opaque identifier format for one plugin-owned original image. */
2200
+ const OPENAI_CODEX_IMAGE_ASSET_ID_PATTERN = /^img_[0-9a-f]{32}$/u;
2201
+ function positiveSafeInteger$3(value) {
2202
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
2203
+ }
2204
+ /** Decode session-log metadata without trusting an asset id, filename, or media type. */
2205
+ function decodeOpenAICodexOriginalImageRef(value) {
2206
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
2207
+ const candidate = value;
2208
+ if (typeof candidate.assetId !== "string" || !OPENAI_CODEX_IMAGE_ASSET_ID_PATTERN.test(candidate.assetId) || candidate.mediaType !== "image/png" && candidate.mediaType !== "image/jpeg" && candidate.mediaType !== "image/webp" || !positiveSafeInteger$3(candidate.width) || !positiveSafeInteger$3(candidate.height) || !positiveSafeInteger$3(candidate.bytes) || candidate.bytes > 50331648 || typeof candidate.name !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(candidate.name) || typeof candidate.sha256 !== "string" || !/^[0-9a-f]{64}$/u.test(candidate.sha256)) return void 0;
2209
+ return {
2210
+ assetId: candidate.assetId,
2211
+ mediaType: candidate.mediaType,
2212
+ width: candidate.width,
2213
+ height: candidate.height,
2214
+ bytes: candidate.bytes,
2215
+ name: candidate.name,
2216
+ sha256: candidate.sha256
2217
+ };
2218
+ }
2219
+ //#endregion
2220
+ //#region src/image-presentation.ts
2221
+ /** Stable metadata marker for generated image result views. */
2222
+ const IMAGE_PRESENTATION_KIND = "codex-connect-images";
2223
+ function positiveSafeInteger$2(value) {
2224
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
2225
+ }
2226
+ function mediaType$1(value) {
2227
+ return value === "image/png" || value === "image/jpeg" || value === "image/webp";
2228
+ }
2229
+ function imageRef(value) {
2230
+ if (typeof value !== "object" || value === null) return void 0;
2231
+ const candidate = value;
2232
+ if (typeof candidate.attachmentId !== "string" || candidate.attachmentId.length === 0 || !mediaType$1(candidate.mediaType) || !positiveSafeInteger$2(candidate.bytes) || !positiveSafeInteger$2(candidate.width) || !positiveSafeInteger$2(candidate.height) || candidate.name !== void 0 && (typeof candidate.name !== "string" || candidate.name.length === 0)) return void 0;
2233
+ return {
2234
+ attachmentId: candidate.attachmentId,
2235
+ mediaType: candidate.mediaType,
2236
+ bytes: candidate.bytes,
2237
+ width: candidate.width,
2238
+ height: candidate.height,
2239
+ ...candidate.name === void 0 ? {} : { name: candidate.name }
2240
+ };
2241
+ }
2242
+ /** Decode durable tool-result metadata without trusting arbitrary session JSON. */
2243
+ function decodeImagePresentationMeta(value) {
2244
+ if (typeof value !== "object" || value === null) return void 0;
2245
+ const candidate = value;
2246
+ if (candidate.kind !== "codex-connect-images" || typeof candidate.prompt !== "string" || candidate.prompt.length < 1 || candidate.prompt.length > 32e3 || !Array.isArray(candidate.images) || candidate.images.length < 1 || candidate.images.length > 4) return void 0;
2247
+ if (candidate.schemaVersion === void 0) {
2248
+ const previews = candidate.images.map(imageRef);
2249
+ if (previews.some((image) => image === void 0)) return void 0;
2250
+ return {
2251
+ kind: IMAGE_PRESENTATION_KIND,
2252
+ schemaVersion: 1,
2253
+ prompt: candidate.prompt,
2254
+ images: previews.map((preview) => ({ preview }))
2255
+ };
2256
+ }
2257
+ if (candidate.schemaVersion !== 1) return void 0;
2258
+ const images = [];
2259
+ for (const value of candidate.images) {
2260
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
2261
+ const entry = value;
2262
+ const preview = imageRef(entry.preview);
2263
+ const original = decodeOpenAICodexOriginalImageRef(entry.original);
2264
+ if (preview === void 0 || original === void 0) return void 0;
2265
+ images.push({
2266
+ preview,
2267
+ original
2268
+ });
2269
+ }
2270
+ return {
2271
+ kind: IMAGE_PRESENTATION_KIND,
2272
+ schemaVersion: 1,
2273
+ prompt: candidate.prompt,
2274
+ images
2275
+ };
2276
+ }
2277
+ //#endregion
2278
+ //#region src/image-asset-routes.ts
2279
+ /** Fork access follows copied result events, not every asset owned by an ancestor. */
2280
+ function inheritedOriginal(session, assetId) {
2281
+ if (session?.header.parentSession === void 0) return void 0;
2282
+ const seedLength = session.header.seedLength ?? 0;
2283
+ for (const event of session.events) {
2284
+ if (event.seq >= seedLength) break;
2285
+ if (event.type !== "tool/result") continue;
2286
+ const original = decodeImagePresentationMeta(event.data.meta)?.images.find((image) => image.original?.assetId === assetId)?.original;
2287
+ if (original !== void 0) return original;
2288
+ }
2289
+ }
2290
+ function json(res, status, value) {
2291
+ res.writeHead(status, {
2292
+ "content-type": "application/json; charset=utf-8",
2293
+ "cache-control": "no-store",
2294
+ "x-content-type-options": "nosniff"
2295
+ });
2296
+ res.end(JSON.stringify(value));
2297
+ }
2298
+ function query(req) {
2299
+ if (typeof req.url !== "string") return void 0;
2300
+ try {
2301
+ const parsed = new URL(req.url, "http://dsh.invalid");
2302
+ const sessionIds = parsed.searchParams.getAll("sessionId");
2303
+ const assetIds = parsed.searchParams.getAll("assetId");
2304
+ const sessionId = sessionIds[0];
2305
+ const assetId = assetIds[0];
2306
+ if (sessionIds.length !== 1 || assetIds.length !== 1 || sessionId === void 0 || sessionId.length < 1 || sessionId.length > 512 || assetId === void 0 || !OPENAI_CODEX_IMAGE_ASSET_ID_PATTERN.test(assetId)) return void 0;
2307
+ return {
2308
+ sessionId,
2309
+ assetId
2310
+ };
2311
+ } catch {
2312
+ return;
2313
+ }
2314
+ }
2315
+ /** Register a history-safe route even while new image generation is disabled. */
2316
+ function registerOpenAICodexOriginalImageRoute(ctx, trustedOrigins, assets) {
2317
+ ctx.effect(() => ctx.webServer.register({
2318
+ kind: "exact",
2319
+ path: OPENAI_CODEX_ORIGINAL_IMAGE_PATH,
2181
2320
  handler: async (req, res) => {
2182
2321
  if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
2183
2322
  const decision = await trustedRequestDecision(req, trustedOrigins);
2184
2323
  if (!decision.trusted) return json(res, 403, { error: decision.error });
2185
- return json(res, 200, resolveCatalog());
2324
+ const requested = query(req);
2325
+ if (requested === void 0) return json(res, 400, { error: "invalid input" });
2326
+ const session = ctx.get("sessions")?.get(SessionId(requested.sessionId));
2327
+ const stored = await assets.read(requested.sessionId, requested.assetId, inheritedOriginal(session, requested.assetId));
2328
+ if (stored === void 0) return json(res, 404, { error: "original image not found" });
2329
+ res.writeHead(200, {
2330
+ "content-type": stored.ref.mediaType,
2331
+ "content-length": String(stored.ref.bytes),
2332
+ "content-disposition": `attachment; filename="${stored.ref.name}"`,
2333
+ "cache-control": "private, no-store",
2334
+ "x-content-type-options": "nosniff"
2335
+ });
2336
+ res.end(Buffer.from(stored.data));
2186
2337
  }
2187
- }), "dsh-codex-connect: model catalog route");
2338
+ }), "dsh-codex-connect: original image download route");
2188
2339
  }
2189
2340
  //#endregion
2190
2341
  //#region src/version.ts
2191
- const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.20";
2342
+ const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.21";
2192
2343
  //#endregion
2193
2344
  //#region src/doctor.ts
2194
2345
  /** Secret-free diagnostics and duplicate-provider guidance. */
@@ -2370,10 +2521,6 @@ function detectEncodedImage(data) {
2370
2521
  }
2371
2522
  }
2372
2523
  //#endregion
2373
- //#region src/image-presentation.ts
2374
- /** Stable metadata marker for generated image result views. */
2375
- const IMAGE_PRESENTATION_KIND = "codex-connect-images";
2376
- //#endregion
2377
2524
  //#region src/image-tool.ts
2378
2525
  /** Stable model-callable tool name. */
2379
2526
  const IMAGE_GENERATE_TOOL_NAME = "codex_connect_image_generate";
@@ -2405,29 +2552,41 @@ function extension(mediaType) {
2405
2552
  return mediaType === "image/jpeg" ? "jpg" : mediaType.slice(6);
2406
2553
  }
2407
2554
  function outputContent(value) {
2408
- const lines = value.images.map((image, index) => `${String(index + 1)}. ${image.mediaType}, ${String(image.width)}x${String(image.height)} px, ${String(image.bytes)} bytes, attachment ${image.attachmentId}`);
2555
+ const lines = value.images.map(({ original, preview }, index) => `${String(index + 1)}. original ${original.mediaType}, ${String(original.width)}x${String(original.height)} px, ${String(original.bytes)} bytes; preview ${String(preview.width)}x${String(preview.height)} px, attachment ${preview.attachmentId}`);
2409
2556
  return [{
2410
2557
  type: "text",
2411
2558
  text: `Generated ${String(value.images.length)} image${value.images.length === 1 ? "" : "s"}:\n${lines.join("\n")}`
2412
- }, ...value.images.map((image) => ({
2559
+ }, ...value.images.map(({ preview }) => ({
2413
2560
  type: "image",
2414
2561
  attachment: {
2415
- attachmentId: AttachmentId(image.attachmentId),
2416
- mediaType: image.mediaType,
2417
- width: image.width,
2418
- height: image.height,
2419
- bytes: image.bytes,
2420
- name: image.name
2562
+ attachmentId: AttachmentId(preview.attachmentId),
2563
+ mediaType: preview.mediaType,
2564
+ width: preview.width,
2565
+ height: preview.height,
2566
+ bytes: preview.bytes,
2567
+ name: preview.name
2421
2568
  }
2422
2569
  }))];
2423
2570
  }
2424
- function validateRef(ref, parsed, input, name) {
2425
- if (typeof ref.attachmentId !== "string" || ref.attachmentId.length === 0 || ref.mediaType !== parsed.mediaType || ref.bytes !== input.data.byteLength || ref.width !== parsed.width || ref.height !== parsed.height || ref.name !== name) failure("The attachment store returned inconsistent image metadata.");
2571
+ function positiveSafeInteger$1(value) {
2572
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
2573
+ }
2574
+ function previewValue(ref, fallbackName) {
2575
+ if (typeof ref.attachmentId !== "string" || ref.attachmentId.length === 0 || ref.mediaType !== "image/png" && ref.mediaType !== "image/jpeg" && ref.mediaType !== "image/webp" || !positiveSafeInteger$1(ref.bytes) || !positiveSafeInteger$1(ref.width) || !positiveSafeInteger$1(ref.height)) failure("The attachment store returned invalid preview metadata.");
2576
+ const name = typeof ref.name === "string" && /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(ref.name) ? ref.name : fallbackName;
2577
+ return {
2578
+ attachmentId: ref.attachmentId,
2579
+ mediaType: ref.mediaType,
2580
+ width: ref.width,
2581
+ height: ref.height,
2582
+ bytes: ref.bytes,
2583
+ name
2584
+ };
2426
2585
  }
2427
2586
  function executionKey(exec) {
2428
2587
  return `${String(exec.agent?.id ?? "<no-agent>")}\u0000${String(exec.rootCallId)}\u0000${String(exec.callId)}`;
2429
2588
  }
2430
- async function generate(ctx, transport, prompt, exec) {
2589
+ async function generate(ctx, transport, assets, prompt, exec) {
2431
2590
  let response;
2432
2591
  try {
2433
2592
  response = await transport.generateImages({ prompt }, { signal: exec.signal });
@@ -2463,28 +2622,49 @@ async function generate(ctx, transport, prompt, exec) {
2463
2622
  name
2464
2623
  });
2465
2624
  }
2625
+ const sessionId = exec.agent?.id;
2626
+ if (sessionId === void 0) failure("Image generation requires a session-owned tool call.");
2627
+ let originals;
2628
+ try {
2629
+ originals = await assets.saveImages(String(sessionId), inputs.map((input, index) => {
2630
+ const parsed = parsedImages[index];
2631
+ if (parsed === void 0 || input.name === void 0) failure("The generated image batch is incomplete.");
2632
+ return {
2633
+ data: input.data,
2634
+ mediaType: parsed.mediaType,
2635
+ width: parsed.width,
2636
+ height: parsed.height,
2637
+ name: input.name
2638
+ };
2639
+ }));
2640
+ } catch {
2641
+ failure("The generated original images could not be saved.");
2642
+ }
2466
2643
  let refs;
2467
2644
  try {
2468
2645
  refs = await ctx.attachments.saveImages(inputs);
2469
2646
  } catch {
2647
+ await assets.removeImages(originals);
2470
2648
  failure("The generated images could not be saved; no attachment references were returned.");
2471
2649
  }
2472
- if (refs.length !== inputs.length) failure("The attachment store returned an incomplete image batch.");
2473
- return { images: refs.map((ref, index) => {
2474
- const parsed = parsedImages[index];
2475
- const input = inputs[index];
2476
- const name = input?.name;
2477
- if (parsed === void 0 || input === void 0 || name === void 0) failure("The attachment store returned an incomplete image batch.");
2478
- validateRef(ref, parsed, input, name);
2479
- return {
2480
- attachmentId: ref.attachmentId,
2481
- mediaType: parsed.mediaType,
2482
- width: parsed.width,
2483
- height: parsed.height,
2484
- bytes: input.data.byteLength,
2485
- name
2486
- };
2487
- }) };
2650
+ if (refs.length !== inputs.length || originals.length !== inputs.length) {
2651
+ await assets.removeImages(originals);
2652
+ failure("The image stores returned an incomplete image batch.");
2653
+ }
2654
+ try {
2655
+ return { images: refs.map((ref, index) => {
2656
+ const original = originals[index];
2657
+ const name = inputs[index]?.name;
2658
+ if (original === void 0 || name === void 0) failure("The image stores returned an incomplete image batch.");
2659
+ return {
2660
+ original,
2661
+ preview: previewValue(ref, name)
2662
+ };
2663
+ }) };
2664
+ } catch (error) {
2665
+ await assets.removeImages(originals);
2666
+ throw error;
2667
+ }
2488
2668
  }
2489
2669
  function appendAbortNote(result) {
2490
2670
  if (!result.isError || result.error.info?.code !== TOOL_ABORTED) return void 0;
@@ -2495,11 +2675,11 @@ function appendAbortNote(result) {
2495
2675
  }];
2496
2676
  }
2497
2677
  /** Build one fiber-owned image tool, including in-flight call deduplication. */
2498
- function imageGenerateTool(ctx) {
2678
+ function imageGenerateTool(ctx, assets) {
2499
2679
  const inFlight = /* @__PURE__ */ new Map();
2500
2680
  return defineTool({
2501
2681
  name: IMAGE_GENERATE_TOOL_NAME,
2502
- description: "Generate an image from a text prompt and save it as a durable DSH attachment. Supports one prompt only; output size and style are service defaults.",
2682
+ description: "Generate an image from a text prompt, preserve the exact original, and save a DSH conversation preview. Supports one prompt only; output size and style are service defaults.",
2503
2683
  parameters: { prompt: {
2504
2684
  type: "string",
2505
2685
  required: true,
@@ -2516,34 +2696,81 @@ function imageGenerateTool(ctx) {
2516
2696
  type: "object",
2517
2697
  additionalProperties: false,
2518
2698
  properties: {
2519
- attachmentId: {
2520
- type: "string",
2521
- required: true
2522
- },
2523
- mediaType: {
2524
- type: "string",
2699
+ original: {
2700
+ type: "object",
2525
2701
  required: true,
2526
- enum: [
2527
- "image/png",
2528
- "image/jpeg",
2529
- "image/webp"
2530
- ]
2702
+ additionalProperties: false,
2703
+ properties: {
2704
+ assetId: {
2705
+ type: "string",
2706
+ required: true
2707
+ },
2708
+ mediaType: {
2709
+ type: "string",
2710
+ required: true,
2711
+ enum: [
2712
+ "image/png",
2713
+ "image/jpeg",
2714
+ "image/webp"
2715
+ ]
2716
+ },
2717
+ width: {
2718
+ type: "integer",
2719
+ required: true
2720
+ },
2721
+ height: {
2722
+ type: "integer",
2723
+ required: true
2724
+ },
2725
+ bytes: {
2726
+ type: "integer",
2727
+ required: true
2728
+ },
2729
+ name: {
2730
+ type: "string",
2731
+ required: true
2732
+ },
2733
+ sha256: {
2734
+ type: "string",
2735
+ required: true
2736
+ }
2737
+ }
2531
2738
  },
2532
- width: {
2533
- type: "integer",
2534
- required: true
2535
- },
2536
- height: {
2537
- type: "integer",
2538
- required: true
2539
- },
2540
- bytes: {
2541
- type: "integer",
2542
- required: true
2543
- },
2544
- name: {
2545
- type: "string",
2546
- required: true
2739
+ preview: {
2740
+ type: "object",
2741
+ required: true,
2742
+ additionalProperties: false,
2743
+ properties: {
2744
+ attachmentId: {
2745
+ type: "string",
2746
+ required: true
2747
+ },
2748
+ mediaType: {
2749
+ type: "string",
2750
+ required: true,
2751
+ enum: [
2752
+ "image/png",
2753
+ "image/jpeg",
2754
+ "image/webp"
2755
+ ]
2756
+ },
2757
+ width: {
2758
+ type: "integer",
2759
+ required: true
2760
+ },
2761
+ height: {
2762
+ type: "integer",
2763
+ required: true
2764
+ },
2765
+ bytes: {
2766
+ type: "integer",
2767
+ required: true
2768
+ },
2769
+ name: {
2770
+ type: "string",
2771
+ required: true
2772
+ }
2773
+ }
2547
2774
  }
2548
2775
  }
2549
2776
  }
@@ -2552,6 +2779,7 @@ function imageGenerateTool(ctx) {
2552
2779
  render: (_args, value) => outputContent(value),
2553
2780
  presentationMeta: (args, value) => ({
2554
2781
  kind: IMAGE_PRESENTATION_KIND,
2782
+ schemaVersion: 1,
2555
2783
  prompt: args.prompt.trim(),
2556
2784
  images: value.images
2557
2785
  })
@@ -2567,7 +2795,7 @@ function imageGenerateTool(ctx) {
2567
2795
  const key = executionKey(exec);
2568
2796
  const current = inFlight.get(key);
2569
2797
  if (current !== void 0) return current;
2570
- const pending = generate(ctx, transport, prompt, exec).catch((error) => {
2798
+ const pending = generate(ctx, transport, assets, prompt, exec).catch((error) => {
2571
2799
  if (error instanceof SafeToolError) throw error;
2572
2800
  failure(fixedTransportMessage(error));
2573
2801
  }).finally(() => {
@@ -3185,6 +3413,169 @@ var OpenAICodexTransport = class extends Service {
3185
3413
  }
3186
3414
  };
3187
3415
  //#endregion
3416
+ //#region src/image-assets.ts
3417
+ /** Owner-only storage for exact GPT Image output bytes. */
3418
+ /** Versioned plugin-owned root below DSH_HOME; this is not the DSH attachment store. */
3419
+ const OPENAI_CODEX_IMAGE_ASSET_DIRECTORY = "dsh-codex-connect/images/v1";
3420
+ const METADATA_VERSION = 1;
3421
+ const ORIGINAL_FILENAME = "original";
3422
+ const METADATA_FILENAME = "metadata.json";
3423
+ const SAFE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u;
3424
+ function digest(data) {
3425
+ return createHash("sha256").update(data).digest("hex");
3426
+ }
3427
+ function positiveSafeInteger(value) {
3428
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
3429
+ }
3430
+ function mediaType(value) {
3431
+ return value === "image/png" || value === "image/jpeg" || value === "image/webp";
3432
+ }
3433
+ function validSessionId(value) {
3434
+ return typeof value === "string" && value.length > 0 && value.length <= 512;
3435
+ }
3436
+ function parseDocument(text) {
3437
+ let value;
3438
+ try {
3439
+ value = JSON.parse(text);
3440
+ } catch {
3441
+ return;
3442
+ }
3443
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
3444
+ const candidate = value;
3445
+ if (candidate.version !== METADATA_VERSION || !validSessionId(candidate.sessionId)) return void 0;
3446
+ const image = decodeOpenAICodexOriginalImageRef(candidate.image);
3447
+ return image === void 0 ? void 0 : {
3448
+ version: METADATA_VERSION,
3449
+ sessionId: candidate.sessionId,
3450
+ image
3451
+ };
3452
+ }
3453
+ async function assertOwnerFile(filename) {
3454
+ const metadata = await lstat(filename);
3455
+ if (!metadata.isFile()) throw new Error("original image object is not a regular file");
3456
+ /* v8 ignore next -- native Windows does not expose POSIX permission semantics. */
3457
+ if (process.platform !== "win32" && (metadata.mode & 63) !== 0) throw new Error("original image object is readable beyond its owner");
3458
+ }
3459
+ async function writeBinaryFile(filename, data) {
3460
+ await mkdir(dirname(filename), {
3461
+ recursive: true,
3462
+ mode: 448
3463
+ });
3464
+ const handle = await open(filename, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY, 384);
3465
+ try {
3466
+ await handle.writeFile(data);
3467
+ await handle.sync();
3468
+ } finally {
3469
+ await handle.close();
3470
+ }
3471
+ }
3472
+ /** Exact-byte image store kept separate from DSH's deliberately normalized attachments. */
3473
+ var OpenAICodexImageAssetStore = class {
3474
+ root;
3475
+ constructor(dshHome) {
3476
+ this.root = resolve(join(resolveDshHome(dshHome), OPENAI_CODEX_IMAGE_ASSET_DIRECTORY));
3477
+ }
3478
+ directory(assetId) {
3479
+ if (!OPENAI_CODEX_IMAGE_ASSET_ID_PATTERN.test(assetId)) throw new TypeError("invalid original image asset id");
3480
+ return join(this.root, assetId.slice(4, 6), assetId);
3481
+ }
3482
+ async saveOne(sessionId, input) {
3483
+ if (!validSessionId(sessionId)) throw new TypeError("invalid original image session id");
3484
+ if (!(input.data instanceof Uint8Array) || input.data.byteLength < 1 || input.data.byteLength > 50331648 || !mediaType(input.mediaType) || !positiveSafeInteger(input.width) || !positiveSafeInteger(input.height) || !SAFE_NAME_PATTERN.test(input.name)) throw new TypeError("invalid original image input");
3485
+ const detected = detectEncodedImage(input.data);
3486
+ if (detected === void 0 || detected.mediaType !== input.mediaType || detected.width !== input.width || detected.height !== input.height) throw new TypeError("original image bytes do not match their declared metadata");
3487
+ const assetId = `img_${randomUUID().replaceAll("-", "")}`;
3488
+ const directory = this.directory(assetId);
3489
+ const ref = {
3490
+ assetId,
3491
+ mediaType: input.mediaType,
3492
+ width: input.width,
3493
+ height: input.height,
3494
+ bytes: input.data.byteLength,
3495
+ name: input.name,
3496
+ sha256: digest(input.data)
3497
+ };
3498
+ try {
3499
+ await mkdir(dirname(directory), {
3500
+ recursive: true,
3501
+ mode: 448
3502
+ });
3503
+ await mkdir(directory, {
3504
+ recursive: false,
3505
+ mode: 448
3506
+ });
3507
+ await writeBinaryFile(join(directory, ORIGINAL_FILENAME), input.data);
3508
+ const document = {
3509
+ version: METADATA_VERSION,
3510
+ sessionId,
3511
+ image: ref
3512
+ };
3513
+ await writeFileAtomic(join(directory, METADATA_FILENAME), `${JSON.stringify(document, null, 2)}\n`, {
3514
+ mode: 384,
3515
+ dirMode: 448
3516
+ });
3517
+ return ref;
3518
+ } catch (error) {
3519
+ await rm(directory, {
3520
+ recursive: true,
3521
+ force: true
3522
+ }).catch(() => void 0);
3523
+ throw error;
3524
+ }
3525
+ }
3526
+ /** Save one complete response batch and remove already-written members if a later write fails. */
3527
+ async saveImages(sessionId, inputs) {
3528
+ if (inputs.length < 1 || inputs.length > 4) throw new TypeError("original image batch must contain 1 to 4 images");
3529
+ const refs = [];
3530
+ try {
3531
+ for (const input of inputs) refs.push(await this.saveOne(sessionId, input));
3532
+ return refs;
3533
+ } catch (error) {
3534
+ await this.removeImages(refs);
3535
+ throw error;
3536
+ }
3537
+ }
3538
+ /** Remove exact assets created by a failed cross-store operation. */
3539
+ async removeImages(refs) {
3540
+ await Promise.all(refs.map(async (ref) => {
3541
+ try {
3542
+ await rm(this.directory(ref.assetId), {
3543
+ recursive: true,
3544
+ force: true
3545
+ });
3546
+ } catch {}
3547
+ }));
3548
+ }
3549
+ /**
3550
+ * Read verified bytes for the owner or a server-authorized inherited reference.
3551
+ * @param sessionId - requesting session.
3552
+ * @param assetId - opaque original identifier.
3553
+ * @param inherited - reference resolved from the session's immutable fork prefix, never request data.
3554
+ * @returns the exact original, or undefined for denied access or invalid files.
3555
+ */
3556
+ async read(sessionId, assetId, inherited) {
3557
+ if (!validSessionId(sessionId) || !OPENAI_CODEX_IMAGE_ASSET_ID_PATTERN.test(assetId)) return void 0;
3558
+ const directory = this.directory(assetId);
3559
+ const metadataPath = join(directory, METADATA_FILENAME);
3560
+ const originalPath = join(directory, ORIGINAL_FILENAME);
3561
+ try {
3562
+ await Promise.all([assertOwnerFile(metadataPath), assertOwnerFile(originalPath)]);
3563
+ const document = parseDocument(await readFile(metadataPath, "utf8"));
3564
+ if (document === void 0 || document.image.assetId !== assetId) return void 0;
3565
+ if (document.sessionId !== sessionId && (inherited === void 0 || inherited.assetId !== document.image.assetId || inherited.sha256 !== document.image.sha256 || inherited.mediaType !== document.image.mediaType || inherited.width !== document.image.width || inherited.height !== document.image.height || inherited.bytes !== document.image.bytes || inherited.name !== document.image.name)) return void 0;
3566
+ const data = new Uint8Array(await readFile(originalPath));
3567
+ const detected = detectEncodedImage(data);
3568
+ if (data.byteLength !== document.image.bytes || digest(data) !== document.image.sha256 || detected === void 0 || detected.mediaType !== document.image.mediaType || detected.width !== document.image.width || detected.height !== document.image.height) return void 0;
3569
+ return {
3570
+ ref: document.image,
3571
+ data
3572
+ };
3573
+ } catch {
3574
+ return;
3575
+ }
3576
+ }
3577
+ };
3578
+ //#endregion
3188
3579
  //#region src/search.ts
3189
3580
  /**
3190
3581
  * OpenAI Codex standalone web search over the dsh web provider seam.
@@ -3706,6 +4097,7 @@ function apply(ctx, config) {
3706
4097
  const resolveProviderProxyUrl = () => resolveOpenAICodexProxyUrl(resolveOpenAICodexSettings(current()));
3707
4098
  let proxyWasActive = resolveProviderProxyUrl() !== void 0;
3708
4099
  const credentials = new OpenAICodexCredentialStore();
4100
+ const imageAssets = new OpenAICodexImageAssetStore();
3709
4101
  const trustedOrigins = new OpenAICodexTrustedOriginsStore(join(dirname(credentials.filename), OPENAI_CODEX_TRUSTED_ORIGINS_FILENAME));
3710
4102
  const fastMode = new FastModeRegistry();
3711
4103
  assertNoOpenAICodexProviderConflict(ctx.llm.listProviders().map((provider) => provider.id));
@@ -3716,6 +4108,7 @@ function apply(ctx, config) {
3716
4108
  registerOpenAICodexProxyRoutes(webCtx, trustedOrigins, proxyManager);
3717
4109
  registerOpenAICodexUpdateRoutes(webCtx, { currentVersion: CODEX_CONNECT_VERSION }, trustedOrigins);
3718
4110
  registerOpenAICodexModelCatalogRoute(webCtx, openAICodexModelCatalog, trustedOrigins);
4111
+ registerOpenAICodexOriginalImageRoute(webCtx, trustedOrigins, imageAssets);
3719
4112
  });
3720
4113
  let stopped = false;
3721
4114
  let searchFiber;
@@ -3789,7 +4182,7 @@ function apply(ctx, config) {
3789
4182
  imageGenerationFiber = void 0;
3790
4183
  if (previous !== void 0) await previous.dispose();
3791
4184
  if (stopped || !enabled) return;
3792
- const fiber = ctx.inject(["tools", "attachments"], (toolCtx) => toolCtx.tools.register(imageGenerateTool(toolCtx)));
4185
+ const fiber = ctx.inject(["tools", "attachments"], (toolCtx) => toolCtx.tools.register(imageGenerateTool(toolCtx, imageAssets)));
3793
4186
  imageGenerationFiber = fiber;
3794
4187
  Promise.resolve(fiber).catch((error) => {
3795
4188
  if (imageGenerationFiber === fiber) imageGenerationFiber = void 0;
@@ -3852,4 +4245,4 @@ function apply(ctx, config) {
3852
4245
  scheduleCapabilities();
3853
4246
  }
3854
4247
  //#endregion
3855
- export { OPENAI_CODEX_PROXY_PROBE_URL as $, openAICodexConflictMessage as A, openAICodexAuthPath as At, DSH_PLUGIN_API_PACKAGES as B, OpenAICodexTransport as C, readOpenAICodexRateLimits as Ct, IMAGE_GENERATE_TOOL_NAME as D, OPENAI_CODEX_AUTH_FILENAME as Dt, VIEW_IMAGE_TOOL_NAME as E, openAICodexAuthStatus as Et, parseOpenAICodexUpdateResult as F, assessCompatibility as G, SUPPORTED_DSH_PLUGIN_API_VERSION as H, parseOpenAICodexVersion as I, OPENAI_CODEX_PROXY_DETECT_PATH as J, detectCompatibility as K, COMPATIBILITY_CONTRACT as L, OPENAI_CODEX_UPDATE_PATH as M, checkForOpenAICodexUpdate as N, assertNoOpenAICodexProviderConflict as O, OPENAI_CODEX_PROVIDER as Ot, compareOpenAICodexVersions as P, OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS as Q, COMPATIBILITY_PACKAGES as R, OPENAI_CODEX_TRANSPORT_SERVICE as S, parseOpenAICodexUsage as St, isOpenAICodexTransportError as T, logoutOpenAICodex as Tt, SUPPORTED_NODE_RANGE as U, PI_AI_PACKAGE as V, SUPPORTED_PI_AI_VERSION as W, OPENAI_CODEX_LOCAL_PROXY_CANDIDATES as X, OPENAI_CODEX_PROXY_TEST_PATH as Y, OPENAI_CODEX_PROXY_CANDIDATE_LIMIT as Z, OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES as _, OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH as _t, name as a, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS as at, OPENAI_CODEX_TRANSPORT_API_VERSION as b, normalizeTrustedOrigin as bt, migrateOpenAICodexSearchHistory as c, DEFAULT_OPENAI_CODEX_SETTINGS as ct, OPENAI_CODEX_SEARCH_URL as d, isValidOpenAICodexProxyUrl as dt, OpenAICodexProxyManager as et, OpenAICodexSearchProvider as f, resolveOpenAICodexProxyUrl as ft, OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES as g, OPENAI_CODEX_FAST_MODE_MAX_SESSIONS as gt, OPENAI_CODEX_IMAGE_MAX_COUNT as h, FastModeRegistry as ht, inject as i, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE as it, CODEX_CONNECT_VERSION as j, diagnoseOpenAICodex as k, OpenAICodexCredentialStore as kt, OPENAI_CODEX_BASE_URL as l, OPENAI_CODEX_SETTINGS_NAMESPACE as lt, OPENAI_CODEX_IMAGE_GENERATION_URL as m, OPENAI_CODEX_FAST_MODE_PATH as mt, OPENAI_CODEX_SETTINGS_NS as n, listOpenAICodexProxyCandidates as nt, OPENAI_CODEX_HISTORY_BACKUP_SUFFIX as o, DEFAULT_OPENAI_CODEX_SEARCH_MODE as ot, mapOpenAICodexSearchResponse as p, resolveOpenAICodexSettings as pt, evaluateCompatibility as q, apply as r, DEFAULT_OPENAI_CODEX_PROXY_URL as rt, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT as s, DEFAULT_OPENAI_CODEX_SEARCH_MODEL as st, Config as t, detectOpenAICodexProxies as tt, OPENAI_CODEX_SEARCH_PROVIDER as u, decodeOpenAICodexSettings as ut, OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH as v, isFastModeSessionId as vt, OpenAICodexTransportError as w, loginOpenAICodex as wt, OPENAI_CODEX_TRANSPORT_ERROR_CODES as x, OPENAI_CODEX_USAGE_URL as xt, OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS as y, OpenAICodexTrustedOriginsStore as yt, COMPATIBILITY_SCHEMA_VERSION as z };
4248
+ export { OPENAI_CODEX_PROXY_PROBE_TIMEOUT_MS as $, openAICodexConflictMessage as A, OPENAI_CODEX_AUTH_FILENAME as At, DSH_PLUGIN_API_PACKAGES as B, OpenAICodexTransport as C, OPENAI_CODEX_USAGE_URL as Ct, IMAGE_GENERATE_TOOL_NAME as D, logoutOpenAICodex as Dt, VIEW_IMAGE_TOOL_NAME as E, loginOpenAICodex as Et, parseOpenAICodexUpdateResult as F, assessCompatibility as G, SUPPORTED_DSH_PLUGIN_API_VERSION as H, parseOpenAICodexVersion as I, readInstalledPackageVersion as J, detectCompatibility as K, COMPATIBILITY_CONTRACT as L, OPENAI_CODEX_UPDATE_PATH as M, OpenAICodexCredentialStore as Mt, checkForOpenAICodexUpdate as N, openAICodexAuthPath as Nt, assertNoOpenAICodexProviderConflict as O, openAICodexAuthStatus as Ot, compareOpenAICodexVersions as P, OPENAI_CODEX_PROXY_CANDIDATE_LIMIT as Q, COMPATIBILITY_PACKAGES as R, OPENAI_CODEX_TRANSPORT_SERVICE as S, normalizeTrustedOrigin as St, isOpenAICodexTransportError as T, readOpenAICodexRateLimits as Tt, SUPPORTED_NODE_RANGE as U, PI_AI_PACKAGE as V, SUPPORTED_PI_AI_VERSION as W, OPENAI_CODEX_PROXY_TEST_PATH as X, OPENAI_CODEX_PROXY_DETECT_PATH as Y, OPENAI_CODEX_LOCAL_PROXY_CANDIDATES as Z, OPENAI_CODEX_IMAGE_MAX_RESPONSE_BYTES as _, FastModeRegistry as _t, name as a, DEFAULT_OPENAI_CODEX_SEARCH_CONTEXT_SIZE as at, OPENAI_CODEX_TRANSPORT_API_VERSION as b, isFastModeSessionId as bt, migrateOpenAICodexSearchHistory as c, DEFAULT_OPENAI_CODEX_SEARCH_MODEL as ct, OPENAI_CODEX_SEARCH_URL as d, decodeOpenAICodexSettings as dt, OPENAI_CODEX_PROXY_PROBE_URL as et, OpenAICodexSearchProvider as f, isValidOpenAICodexProxyUrl as ft, OPENAI_CODEX_IMAGE_MAX_ERROR_BYTES as g, OPENAI_CODEX_FAST_MODE_PATH as gt, OPENAI_CODEX_IMAGE_MAX_COUNT as h, resolveOpenAICodexSettings as ht, inject as i, DEFAULT_OPENAI_CODEX_PROXY_URL as it, CODEX_CONNECT_VERSION as j, OPENAI_CODEX_PROVIDER as jt, diagnoseOpenAICodex as k, openAICodexModelCatalog as kt, OPENAI_CODEX_BASE_URL as l, DEFAULT_OPENAI_CODEX_SETTINGS as lt, OPENAI_CODEX_IMAGE_GENERATION_URL as m, resolveOpenAICodexProxyUrl as mt, OPENAI_CODEX_SETTINGS_NS as n, detectOpenAICodexProxies as nt, OPENAI_CODEX_HISTORY_BACKUP_SUFFIX as o, DEFAULT_OPENAI_CODEX_SEARCH_MAX_OUTPUT_TOKENS as ot, mapOpenAICodexSearchResponse as p, normalizeOpenAICodexProxyUrl as pt, evaluateCompatibility as q, apply as r, listOpenAICodexProxyCandidates as rt, OPENAI_CODEX_SEARCH_MODEL_REQUEST_EVENT as s, DEFAULT_OPENAI_CODEX_SEARCH_MODE as st, Config as t, OpenAICodexProxyManager as tt, OPENAI_CODEX_SEARCH_PROVIDER as u, OPENAI_CODEX_SETTINGS_NAMESPACE as ut, OPENAI_CODEX_IMAGE_PROMPT_MAX_LENGTH as v, OPENAI_CODEX_FAST_MODE_MAX_SESSIONS as vt, OpenAICodexTransportError as w, parseOpenAICodexUsage as wt, OPENAI_CODEX_TRANSPORT_ERROR_CODES as x, OpenAICodexTrustedOriginsStore as xt, OPENAI_CODEX_IMAGE_REQUEST_TIMEOUT_MS as y, OPENAI_CODEX_FAST_MODE_MAX_SESSION_ID_LENGTH as yt, COMPATIBILITY_SCHEMA_VERSION as z };