@darkjd/opencode-openai-codex-auth 4.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +37 -0
  2. package/README.md +137 -0
  3. package/assets/opencode-logo-ornate-dark.svg +18 -0
  4. package/assets/readme-hero.svg +31 -0
  5. package/dist/index.d.ts +42 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +226 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/auth/auth.d.ts +43 -0
  10. package/dist/lib/auth/auth.d.ts.map +1 -0
  11. package/dist/lib/auth/auth.js +163 -0
  12. package/dist/lib/auth/auth.js.map +1 -0
  13. package/dist/lib/auth/browser.d.ts +17 -0
  14. package/dist/lib/auth/browser.d.ts.map +1 -0
  15. package/dist/lib/auth/browser.js +76 -0
  16. package/dist/lib/auth/browser.js.map +1 -0
  17. package/dist/lib/auth/server.d.ts +10 -0
  18. package/dist/lib/auth/server.d.ts.map +1 -0
  19. package/dist/lib/auth/server.js +78 -0
  20. package/dist/lib/auth/server.js.map +1 -0
  21. package/dist/lib/auth/v2-storage.d.ts +35 -0
  22. package/dist/lib/auth/v2-storage.d.ts.map +1 -0
  23. package/dist/lib/auth/v2-storage.js +79 -0
  24. package/dist/lib/auth/v2-storage.js.map +1 -0
  25. package/dist/lib/config.d.ts +17 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/dist/lib/config.js +51 -0
  28. package/dist/lib/config.js.map +1 -0
  29. package/dist/lib/constants.d.ts +69 -0
  30. package/dist/lib/constants.d.ts.map +1 -0
  31. package/dist/lib/constants.js +69 -0
  32. package/dist/lib/constants.js.map +1 -0
  33. package/dist/lib/logger.d.ts +21 -0
  34. package/dist/lib/logger.d.ts.map +1 -0
  35. package/dist/lib/logger.js +77 -0
  36. package/dist/lib/logger.js.map +1 -0
  37. package/dist/lib/oauth-success.html +712 -0
  38. package/dist/lib/prompts/codex-opencode-bridge.d.ts +19 -0
  39. package/dist/lib/prompts/codex-opencode-bridge.d.ts.map +1 -0
  40. package/dist/lib/prompts/codex-opencode-bridge.js +157 -0
  41. package/dist/lib/prompts/codex-opencode-bridge.js.map +1 -0
  42. package/dist/lib/prompts/codex.d.ts +27 -0
  43. package/dist/lib/prompts/codex.d.ts.map +1 -0
  44. package/dist/lib/prompts/codex.js +256 -0
  45. package/dist/lib/prompts/codex.js.map +1 -0
  46. package/dist/lib/prompts/opencode-codex.d.ts +21 -0
  47. package/dist/lib/prompts/opencode-codex.d.ts.map +1 -0
  48. package/dist/lib/prompts/opencode-codex.js +91 -0
  49. package/dist/lib/prompts/opencode-codex.js.map +1 -0
  50. package/dist/lib/request/fetch-helpers.d.ts +73 -0
  51. package/dist/lib/request/fetch-helpers.d.ts.map +1 -0
  52. package/dist/lib/request/fetch-helpers.js +231 -0
  53. package/dist/lib/request/fetch-helpers.js.map +1 -0
  54. package/dist/lib/request/helpers/input-utils.d.ts +6 -0
  55. package/dist/lib/request/helpers/input-utils.d.ts.map +1 -0
  56. package/dist/lib/request/helpers/input-utils.js +174 -0
  57. package/dist/lib/request/helpers/input-utils.js.map +1 -0
  58. package/dist/lib/request/helpers/model-map.d.ts +28 -0
  59. package/dist/lib/request/helpers/model-map.d.ts.map +1 -0
  60. package/dist/lib/request/helpers/model-map.js +134 -0
  61. package/dist/lib/request/helpers/model-map.js.map +1 -0
  62. package/dist/lib/request/helpers/model-registry-data.d.ts +86 -0
  63. package/dist/lib/request/helpers/model-registry-data.d.ts.map +1 -0
  64. package/dist/lib/request/helpers/model-registry-data.js +293 -0
  65. package/dist/lib/request/helpers/model-registry-data.js.map +1 -0
  66. package/dist/lib/request/helpers/model-registry.d.ts +45 -0
  67. package/dist/lib/request/helpers/model-registry.d.ts.map +1 -0
  68. package/dist/lib/request/helpers/model-registry.js +208 -0
  69. package/dist/lib/request/helpers/model-registry.js.map +1 -0
  70. package/dist/lib/request/helpers/skill-catalog.d.ts +59 -0
  71. package/dist/lib/request/helpers/skill-catalog.d.ts.map +1 -0
  72. package/dist/lib/request/helpers/skill-catalog.js +81 -0
  73. package/dist/lib/request/helpers/skill-catalog.js.map +1 -0
  74. package/dist/lib/request/request-transformer.d.ts +81 -0
  75. package/dist/lib/request/request-transformer.d.ts.map +1 -0
  76. package/dist/lib/request/request-transformer.js +477 -0
  77. package/dist/lib/request/request-transformer.js.map +1 -0
  78. package/dist/lib/request/response-handler.d.ts +14 -0
  79. package/dist/lib/request/response-handler.d.ts.map +1 -0
  80. package/dist/lib/request/response-handler.js +88 -0
  81. package/dist/lib/request/response-handler.js.map +1 -0
  82. package/dist/lib/types.d.ts +178 -0
  83. package/dist/lib/types.d.ts.map +1 -0
  84. package/dist/lib/types.js +2 -0
  85. package/dist/lib/types.js.map +1 -0
  86. package/dist/v2.d.ts +34 -0
  87. package/dist/v2.d.ts.map +1 -0
  88. package/dist/v2.js +259 -0
  89. package/dist/v2.js.map +1 -0
  90. package/package.json +87 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Model Registry — lookup, merging, and optional remote overlay
3
+ *
4
+ * Consumers (normalizeModel, getReasoningConfig, getModelFamily) call
5
+ * `lookupModelRegistryEntry()` synchronously. The registry itself is always
6
+ * available synchronously (bundled defaults + last-persisted remote overlay,
7
+ * both loaded once at module init); a remote refresh — when configured — runs
8
+ * in the background and updates the in-memory copy for *future* lookups. This
9
+ * means a request is never delayed or blocked by a network call.
10
+ *
11
+ * The remote overlay is entirely OPT-IN: unless a maintainer or user
12
+ * explicitly configures `modelRegistryUrl` (plugin config) or the
13
+ * `OPENCODE_CODEX_MODEL_REGISTRY_URL` env var, no network request is ever
14
+ * made. This keeps the default (and every existing test) fully offline.
15
+ */
16
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
17
+ import { homedir } from "node:os";
18
+ import { join } from "node:path";
19
+ import { BUNDLED_MODEL_REGISTRY, } from "./model-registry-data.js";
20
+ const CACHE_DIR = join(homedir(), ".opencode", "cache");
21
+ const CACHE_FILE = join(CACHE_DIR, "model-registry-overlay.json");
22
+ const CACHE_META_FILE = join(CACHE_DIR, "model-registry-overlay-meta.json");
23
+ const CACHE_TTL_MS = 15 * 60 * 1000; // 15 minutes, matches lib/prompts/codex.ts
24
+ /** Set once (per process) by index.ts from the loaded plugin config. */
25
+ let configuredUrl;
26
+ /** In-memory registry: bundled defaults merged with the last-known overlay. */
27
+ let activeRegistry = BUNDLED_MODEL_REGISTRY;
28
+ let aliasIndex = buildAliasIndex(activeRegistry);
29
+ let refreshInFlight = false;
30
+ function buildAliasIndex(registry) {
31
+ const index = new Map();
32
+ for (const entry of registry) {
33
+ for (const alias of entry.aliases) {
34
+ index.set(alias.toLowerCase(), entry);
35
+ }
36
+ }
37
+ return index;
38
+ }
39
+ /**
40
+ * Merge a remote overlay into the bundled defaults.
41
+ * Overlay entries take precedence for any alias they also define, so a
42
+ * maintainer can both add brand-new models and patch an existing one.
43
+ */
44
+ function mergeRegistries(bundled, overlay) {
45
+ if (overlay.length === 0)
46
+ return bundled;
47
+ const overlayAliases = new Set(overlay.flatMap((entry) => entry.aliases.map((a) => a.toLowerCase())));
48
+ const remainingBundled = bundled.filter((entry) => !entry.aliases.some((a) => overlayAliases.has(a.toLowerCase())));
49
+ return [...overlay, ...remainingBundled];
50
+ }
51
+ function isValidRegistryEntry(value) {
52
+ if (!value || typeof value !== "object")
53
+ return false;
54
+ const entry = value;
55
+ return (typeof entry.id === "string" &&
56
+ Array.isArray(entry.aliases) &&
57
+ entry.aliases.every((a) => typeof a === "string") &&
58
+ typeof entry.family === "string" &&
59
+ typeof entry.defaultEffort === "string");
60
+ }
61
+ function loadCachedOverlaySync() {
62
+ try {
63
+ if (!existsSync(CACHE_FILE))
64
+ return [];
65
+ const parsed = JSON.parse(readFileSync(CACHE_FILE, "utf8"));
66
+ if (!Array.isArray(parsed))
67
+ return [];
68
+ return parsed.filter(isValidRegistryEntry);
69
+ }
70
+ catch {
71
+ return [];
72
+ }
73
+ }
74
+ function loadCachedMetaSync() {
75
+ try {
76
+ if (!existsSync(CACHE_META_FILE))
77
+ return null;
78
+ return JSON.parse(readFileSync(CACHE_META_FILE, "utf8"));
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ // Initialize from any previously-cached overlay so a restarted process picks
85
+ // up the last successful remote fetch immediately, without waiting on a
86
+ // network round-trip.
87
+ {
88
+ const cachedOverlay = loadCachedOverlaySync();
89
+ if (cachedOverlay.length > 0) {
90
+ activeRegistry = mergeRegistries(BUNDLED_MODEL_REGISTRY, cachedOverlay);
91
+ aliasIndex = buildAliasIndex(activeRegistry);
92
+ }
93
+ }
94
+ /**
95
+ * Configure the remote overlay source. Called once by index.ts from the
96
+ * loaded plugin config. Pass `undefined`/empty to disable.
97
+ */
98
+ export function configureModelRegistrySource(url) {
99
+ configuredUrl = url?.trim() || undefined;
100
+ }
101
+ function getConfiguredRegistryUrl() {
102
+ return process.env.OPENCODE_CODEX_MODEL_REGISTRY_URL?.trim() || configuredUrl;
103
+ }
104
+ /**
105
+ * Fetch the remote overlay JSON with ETag-based conditional requests,
106
+ * mirroring the caching strategy in lib/prompts/codex.ts. Never throws —
107
+ * all failures are swallowed since this only ever refines an already-usable
108
+ * in-memory registry.
109
+ */
110
+ async function fetchRemoteOverlay(url) {
111
+ const meta = loadCachedMetaSync();
112
+ const headers = {};
113
+ if (meta?.url === url && meta.etag) {
114
+ headers["If-None-Match"] = meta.etag;
115
+ }
116
+ const response = await fetch(url, { headers });
117
+ if (response.status === 304) {
118
+ return null; // Unchanged; nothing new to merge.
119
+ }
120
+ if (!response.ok) {
121
+ throw new Error(`HTTP ${response.status}`);
122
+ }
123
+ const data = (await response.json());
124
+ const entries = Array.isArray(data) ? data.filter(isValidRegistryEntry) : [];
125
+ if (!existsSync(CACHE_DIR)) {
126
+ mkdirSync(CACHE_DIR, { recursive: true });
127
+ }
128
+ writeFileSync(CACHE_FILE, JSON.stringify(entries), "utf8");
129
+ writeFileSync(CACHE_META_FILE, JSON.stringify({
130
+ etag: response.headers.get("etag"),
131
+ lastChecked: Date.now(),
132
+ url,
133
+ }), "utf8");
134
+ return entries;
135
+ }
136
+ async function performRefresh(url) {
137
+ refreshInFlight = true;
138
+ try {
139
+ const entries = await fetchRemoteOverlay(url);
140
+ if (entries && entries.length > 0) {
141
+ activeRegistry = mergeRegistries(BUNDLED_MODEL_REGISTRY, entries);
142
+ aliasIndex = buildAliasIndex(activeRegistry);
143
+ }
144
+ }
145
+ catch (error) {
146
+ console.error("[openai-codex-plugin] Failed to refresh remote model registry:", error.message);
147
+ }
148
+ finally {
149
+ refreshInFlight = false;
150
+ }
151
+ }
152
+ /**
153
+ * Kick off a background refresh if a remote source is configured and the
154
+ * cache is stale. Fire-and-forget: never awaited by request handling, so it
155
+ * can never slow down or fail a live request. Results apply to subsequent
156
+ * lookups only.
157
+ */
158
+ function maybeTriggerBackgroundRefresh() {
159
+ const url = getConfiguredRegistryUrl();
160
+ if (!url || refreshInFlight)
161
+ return;
162
+ const meta = loadCachedMetaSync();
163
+ if (meta?.url === url && Date.now() - meta.lastChecked < CACHE_TTL_MS) {
164
+ return; // Cache is fresh enough; don't spam the network.
165
+ }
166
+ void performRefresh(url);
167
+ }
168
+ /**
169
+ * Test-only: deterministically run (and await) a refresh attempt against the
170
+ * currently configured URL, bypassing the fire-and-forget wrapper. No-op
171
+ * (resolves immediately) if no URL is configured.
172
+ */
173
+ export async function __triggerModelRegistryRefreshForTests() {
174
+ const url = getConfiguredRegistryUrl();
175
+ if (!url)
176
+ return;
177
+ await performRefresh(url);
178
+ }
179
+ /**
180
+ * Get the current model registry (bundled defaults + any merged overlay).
181
+ * Synchronous — safe to call from hot request-handling paths.
182
+ */
183
+ export function getModelRegistry() {
184
+ maybeTriggerBackgroundRefresh();
185
+ return activeRegistry;
186
+ }
187
+ /**
188
+ * Look up a model id or preset name in the registry, case-insensitively.
189
+ * Returns undefined if nothing matches (callers should fall back to their
190
+ * own generic pattern matching for completely unrecognized names).
191
+ */
192
+ export function lookupModelRegistryEntry(modelId) {
193
+ if (!modelId)
194
+ return undefined;
195
+ maybeTriggerBackgroundRefresh();
196
+ return aliasIndex.get(modelId.toLowerCase());
197
+ }
198
+ /**
199
+ * Test-only: reset in-memory state and force a specific configured URL.
200
+ * Not exported from the package's public surface.
201
+ */
202
+ export function __resetModelRegistryForTests() {
203
+ configuredUrl = undefined;
204
+ refreshInFlight = false;
205
+ activeRegistry = BUNDLED_MODEL_REGISTRY;
206
+ aliasIndex = buildAliasIndex(activeRegistry);
207
+ }
208
+ //# sourceMappingURL=model-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-registry.js","sourceRoot":"","sources":["../../../../lib/request/helpers/model-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * OpenCode capability-block passthrough for OpenAI OAuth (Codex) sessions.
3
+ *
4
+ * Background: opencode's `isOpenaiOauth` branch (session/llm/request.ts) puts
5
+ * the entire joined system prompt - persona, env, AGENTS.md, `<mcp_instructions>`,
6
+ * and the `<available_skills>` catalog - into `options.instructions`, which the
7
+ * AI SDK forwards as the Responses API's top-level `instructions` field. This
8
+ * plugin's `transformRequestBody()` then unconditionally overwrites
9
+ * `body.instructions` with the official Codex CLI instructions, silently
10
+ * discarding both blocks before Codex ever sees them (confirmed empirically -
11
+ * see specs/skill-catalog-passthrough.md).
12
+ *
13
+ * These helpers extract the two capability blocks before that overwrite so
14
+ * they can be re-appended afterwards, giving Codex sessions the same
15
+ * skill/MCP awareness Anthropic sessions already get. Kept as small, pure,
16
+ * regex-based string functions - no assumptions about the rest of the
17
+ * instructions string, safe to no-op if opencode ever changes its wording.
18
+ */
19
+ /**
20
+ * Extract opencode's `<available_skills>...</available_skills>` block from an
21
+ * instructions string, if present.
22
+ * @param instructions - Raw instructions string (pre-overwrite)
23
+ * @returns The matched block verbatim, or null if absent/malformed
24
+ */
25
+ export declare function extractSkillCatalog(instructions: string | undefined): string | null;
26
+ /**
27
+ * Extract opencode's `<mcp_instructions>...</mcp_instructions>` block from an
28
+ * instructions string, if present.
29
+ * @param instructions - Raw instructions string (pre-overwrite)
30
+ * @returns The matched block verbatim, or null if absent/malformed
31
+ */
32
+ export declare function extractMcpInstructions(instructions: string | undefined): string | null;
33
+ /** Both capability blocks extracted from an instructions string, if present. */
34
+ export interface OpenCodeCapabilityBlocks {
35
+ skillCatalog: string | null;
36
+ mcpInstructions: string | null;
37
+ }
38
+ /**
39
+ * Extract both preservable opencode capability blocks from an instructions
40
+ * string in one pass, before the caller overwrites `body.instructions`.
41
+ * @param instructions - Raw instructions string (pre-overwrite)
42
+ */
43
+ export declare function extractOpenCodeCapabilityBlocks(instructions: string | undefined): OpenCodeCapabilityBlocks;
44
+ /**
45
+ * Short framing line opencode itself prints just before `<available_skills>`
46
+ * (see session/system.ts `sys.skills()`). That framing text lives in plain
47
+ * prose *outside* the tag, so the regex above doesn't capture it - this is
48
+ * our own equivalent framing to reattach when re-injecting the catalog into
49
+ * Codex's instructions, so the block isn't dropped in with no context.
50
+ */
51
+ export declare const SKILL_TOOL_BRIDGE_HEADER: string;
52
+ /**
53
+ * Recompose preserved capability blocks into a suffix to append to Codex's
54
+ * instructions, in the same relative order opencode itself uses
55
+ * (mcp before skills). Returns an empty string if nothing was preserved.
56
+ * @param blocks - Extracted capability blocks
57
+ */
58
+ export declare function formatPreservedCapabilityBlocks(blocks: OpenCodeCapabilityBlocks): string;
59
+ //# sourceMappingURL=skill-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-catalog.d.ts","sourceRoot":"","sources":["../../../../lib/request/helpers/skill-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAInF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAItF;AAED,gFAAgF;AAChF,MAAM,WAAW,wBAAwB;IACxC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC9C,YAAY,EAAE,MAAM,GAAG,SAAS,GAC9B,wBAAwB,CAK1B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,QAEqC,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CASxF"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * OpenCode capability-block passthrough for OpenAI OAuth (Codex) sessions.
3
+ *
4
+ * Background: opencode's `isOpenaiOauth` branch (session/llm/request.ts) puts
5
+ * the entire joined system prompt - persona, env, AGENTS.md, `<mcp_instructions>`,
6
+ * and the `<available_skills>` catalog - into `options.instructions`, which the
7
+ * AI SDK forwards as the Responses API's top-level `instructions` field. This
8
+ * plugin's `transformRequestBody()` then unconditionally overwrites
9
+ * `body.instructions` with the official Codex CLI instructions, silently
10
+ * discarding both blocks before Codex ever sees them (confirmed empirically -
11
+ * see specs/skill-catalog-passthrough.md).
12
+ *
13
+ * These helpers extract the two capability blocks before that overwrite so
14
+ * they can be re-appended afterwards, giving Codex sessions the same
15
+ * skill/MCP awareness Anthropic sessions already get. Kept as small, pure,
16
+ * regex-based string functions - no assumptions about the rest of the
17
+ * instructions string, safe to no-op if opencode ever changes its wording.
18
+ */
19
+ const AVAILABLE_SKILLS_RE = /<available_skills>[\s\S]*?<\/available_skills>/;
20
+ const MCP_INSTRUCTIONS_RE = /<mcp_instructions>[\s\S]*?<\/mcp_instructions>/;
21
+ /**
22
+ * Extract opencode's `<available_skills>...</available_skills>` block from an
23
+ * instructions string, if present.
24
+ * @param instructions - Raw instructions string (pre-overwrite)
25
+ * @returns The matched block verbatim, or null if absent/malformed
26
+ */
27
+ export function extractSkillCatalog(instructions) {
28
+ if (!instructions)
29
+ return null;
30
+ const match = instructions.match(AVAILABLE_SKILLS_RE);
31
+ return match ? match[0] : null;
32
+ }
33
+ /**
34
+ * Extract opencode's `<mcp_instructions>...</mcp_instructions>` block from an
35
+ * instructions string, if present.
36
+ * @param instructions - Raw instructions string (pre-overwrite)
37
+ * @returns The matched block verbatim, or null if absent/malformed
38
+ */
39
+ export function extractMcpInstructions(instructions) {
40
+ if (!instructions)
41
+ return null;
42
+ const match = instructions.match(MCP_INSTRUCTIONS_RE);
43
+ return match ? match[0] : null;
44
+ }
45
+ /**
46
+ * Extract both preservable opencode capability blocks from an instructions
47
+ * string in one pass, before the caller overwrites `body.instructions`.
48
+ * @param instructions - Raw instructions string (pre-overwrite)
49
+ */
50
+ export function extractOpenCodeCapabilityBlocks(instructions) {
51
+ return {
52
+ skillCatalog: extractSkillCatalog(instructions),
53
+ mcpInstructions: extractMcpInstructions(instructions),
54
+ };
55
+ }
56
+ /**
57
+ * Short framing line opencode itself prints just before `<available_skills>`
58
+ * (see session/system.ts `sys.skills()`). That framing text lives in plain
59
+ * prose *outside* the tag, so the regex above doesn't capture it - this is
60
+ * our own equivalent framing to reattach when re-injecting the catalog into
61
+ * Codex's instructions, so the block isn't dropped in with no context.
62
+ */
63
+ export const SKILL_TOOL_BRIDGE_HEADER = "Skills provide specialized instructions and workflows for specific tasks. " +
64
+ "Use the skill tool to load a skill when a task matches its description.";
65
+ /**
66
+ * Recompose preserved capability blocks into a suffix to append to Codex's
67
+ * instructions, in the same relative order opencode itself uses
68
+ * (mcp before skills). Returns an empty string if nothing was preserved.
69
+ * @param blocks - Extracted capability blocks
70
+ */
71
+ export function formatPreservedCapabilityBlocks(blocks) {
72
+ const parts = [];
73
+ if (blocks.mcpInstructions) {
74
+ parts.push(blocks.mcpInstructions);
75
+ }
76
+ if (blocks.skillCatalog) {
77
+ parts.push(`${SKILL_TOOL_BRIDGE_HEADER}\n${blocks.skillCatalog}`);
78
+ }
79
+ return parts.length > 0 ? `\n\n${parts.join("\n\n")}` : "";
80
+ }
81
+ //# sourceMappingURL=skill-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-catalog.js","sourceRoot":"","sources":["../../../../lib/request/helpers/skill-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,mBAAmB,GAAG,gDAAgD,CAAC;AAC7E,MAAM,mBAAmB,GAAG,gDAAgD,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,YAAgC;IACnE,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,YAAgC;IACtE,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,+BAA+B,CAC9C,YAAgC;IAEhC,OAAO;QACN,YAAY,EAAE,mBAAmB,CAAC,YAAY,CAAC;QAC/C,eAAe,EAAE,sBAAsB,CAAC,YAAY,CAAC;KACrD,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GACpC,4EAA4E;IAC5E,yEAAyE,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,+BAA+B,CAAC,MAAgC;IAC/E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,GAAG,wBAAwB,KAAK,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,81 @@
1
+ import type { ConfigOptions, InputItem, ReasoningConfig, RequestBody, UserConfig } from "../types.js";
2
+ export { isOpenCodeSystemPrompt, filterOpenCodeSystemPromptsWithCachedPrompt, } from "./helpers/input-utils.js";
3
+ /**
4
+ * Normalize model name to Codex-supported variants
5
+ *
6
+ * Uses explicit model map for known models, with fallback pattern matching
7
+ * for unknown/custom model names.
8
+ *
9
+ * @param model - Original model name (e.g., "gpt-5.1-codex-low", "openai/gpt-5-codex")
10
+ * @returns Normalized model name (e.g., "gpt-5.1-codex", "gpt-5-codex")
11
+ */
12
+ export declare function normalizeModel(model: string | undefined): string;
13
+ /**
14
+ * Extract configuration for a specific model
15
+ * Merges global options with model-specific options (model-specific takes precedence)
16
+ * @param modelName - Model name (e.g., "gpt-5-codex")
17
+ * @param userConfig - Full user configuration object
18
+ * @returns Merged configuration for this model
19
+ */
20
+ export declare function getModelConfig(modelName: string, userConfig?: UserConfig): ConfigOptions;
21
+ export declare function getReasoningConfig(modelName: string | undefined, userConfig?: ConfigOptions): ReasoningConfig;
22
+ /**
23
+ * Filter input array for stateless Codex API (store: false)
24
+ *
25
+ * Two transformations needed:
26
+ * 1. Remove AI SDK-specific items (not supported by Codex API)
27
+ * 2. Strip IDs from all remaining items (stateless mode)
28
+ *
29
+ * AI SDK constructs to REMOVE (not in OpenAI Responses API spec):
30
+ * - type: "item_reference" - AI SDK uses this for server-side state lookup
31
+ *
32
+ * Items to KEEP (strip IDs):
33
+ * - type: "message" - Conversation messages (provides context to LLM)
34
+ * - type: "function_call" - Tool calls from conversation
35
+ * - type: "function_call_output" - Tool results from conversation
36
+ *
37
+ * Context is maintained through:
38
+ * - Full message history (without IDs)
39
+ * - reasoning.encrypted_content (for reasoning continuity)
40
+ *
41
+ * @param input - Original input array from OpenCode/AI SDK
42
+ * @returns Filtered input array compatible with Codex API
43
+ */
44
+ export declare function filterInput(input: InputItem[] | undefined): InputItem[] | undefined;
45
+ /**
46
+ * Filter out OpenCode system prompts from input
47
+ * Used in CODEX_MODE to replace OpenCode prompts with Codex-OpenCode bridge
48
+ * @param input - Input array
49
+ * @returns Input array without OpenCode system prompts
50
+ */
51
+ export declare function filterOpenCodeSystemPrompts(input: InputItem[] | undefined): Promise<InputItem[] | undefined>;
52
+ /**
53
+ * Add Codex-OpenCode bridge message to input if tools are present
54
+ * @param input - Input array
55
+ * @param hasTools - Whether tools are present in request
56
+ * @returns Input array with bridge message prepended if needed
57
+ */
58
+ export declare function addCodexBridgeMessage(input: InputItem[] | undefined, hasTools: boolean): InputItem[] | undefined;
59
+ /**
60
+ * Add tool remapping message to input if tools are present
61
+ * @param input - Input array
62
+ * @param hasTools - Whether tools are present in request
63
+ * @returns Input array with tool remap message prepended if needed
64
+ */
65
+ export declare function addToolRemapMessage(input: InputItem[] | undefined, hasTools: boolean): InputItem[] | undefined;
66
+ /**
67
+ * Transform request body for Codex API
68
+ *
69
+ * NOTE: Configuration follows Codex CLI patterns instead of opencode defaults:
70
+ * - opencode sets textVerbosity="low" for gpt-5, but Codex CLI uses "medium"
71
+ * - opencode excludes gpt-5-codex from reasoning configuration
72
+ * - This plugin uses store=false (stateless), requiring encrypted reasoning content
73
+ *
74
+ * @param body - Original request body
75
+ * @param codexInstructions - Codex system instructions
76
+ * @param userConfig - User configuration from loader
77
+ * @param codexMode - Enable CODEX_MODE (bridge prompt instead of tool remap) - defaults to true
78
+ * @returns Transformed request body
79
+ */
80
+ export declare function transformRequestBody(body: RequestBody, codexInstructions: string, userConfig?: UserConfig, codexMode?: boolean): Promise<RequestBody>;
81
+ //# sourceMappingURL=request-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-transformer.d.ts","sourceRoot":"","sources":["../../../lib/request/request-transformer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,WAAW,EACX,UAAU,EACV,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,sBAAsB,EACtB,2CAA2C,GAC3C,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CA0IhE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,UAAuC,GACjD,aAAa,CAMf;AAiJD,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,GAAE,aAAkB,GAC5B,eAAe,CAyDjB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,WAAW,CAC1B,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,GAC5B,SAAS,EAAE,GAAG,SAAS,CAmBzB;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAChD,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,GAC5B,OAAO,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAalC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAC9B,QAAQ,EAAE,OAAO,GACf,SAAS,EAAE,GAAG,SAAS,CAezB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAC9B,QAAQ,EAAE,OAAO,GACf,SAAS,EAAE,GAAG,SAAS,CAezB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,WAAW,EACjB,iBAAiB,EAAE,MAAM,EACzB,UAAU,GAAE,UAAuC,EACnD,SAAS,UAAO,GACd,OAAO,CAAC,WAAW,CAAC,CAgHtB"}