@agentionai/agents 1.12.0 → 1.13.0

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.
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CODEX_CLIENT_VERSION = exports.CODEX_ORIGINATOR = exports.CODEX_TOKEN_URL = exports.CODEX_CLIENT_ID = exports.CODEX_BASE_URL = void 0;
37
+ exports.decodeJwtClaims = decodeJwtClaims;
38
+ exports.jwtExpiry = jwtExpiry;
39
+ exports.codexAuthFilePath = codexAuthFilePath;
40
+ exports.loadCodexCredentials = loadCodexCredentials;
41
+ exports.refreshCodexCredentials = refreshCodexCredentials;
42
+ exports.createCodexTokenProvider = createCodexTokenProvider;
43
+ const fs_1 = require("fs");
44
+ const os = __importStar(require("os"));
45
+ const path = __importStar(require("path"));
46
+ /**
47
+ * OAuth against a ChatGPT subscription, as used by OpenAI's Codex CLI.
48
+ *
49
+ * This is a different product surface from the platform API: the credentials are
50
+ * a ChatGPT login rather than a `sk-...` platform key, and requests are billed
51
+ * against the subscription instead of an API account. The endpoint differs too —
52
+ * see {@link CODEX_BASE_URL}.
53
+ *
54
+ * None of it is a documented public API. The values here were cross-checked
55
+ * against the Codex CLI's own behaviour and several independent
56
+ * reimplementations, but OpenAI can change them without notice.
57
+ */
58
+ /**
59
+ * Base URL for the ChatGPT-backed Codex Responses API.
60
+ *
61
+ * The SDK appends `/responses`, giving
62
+ * `https://chatgpt.com/backend-api/codex/responses`.
63
+ */
64
+ exports.CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex";
65
+ /** Public OAuth client id the Codex CLI uses. Not a secret. */
66
+ exports.CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
67
+ /** Token endpoint used to exchange a refresh token for a fresh access token. */
68
+ exports.CODEX_TOKEN_URL = "https://auth.openai.com/oauth/token";
69
+ /**
70
+ * Default `originator` header value.
71
+ *
72
+ * OpenAI gates parts of the model catalog on this, so an unrecognised value can
73
+ * quietly change which models an account may reach.
74
+ */
75
+ exports.CODEX_ORIGINATOR = "codex_cli_rs";
76
+ /**
77
+ * `client_version` for the Codex models endpoint, which 400s without one.
78
+ *
79
+ * Each model also carries a `minimal_client_version`; the backend hides models
80
+ * newer than the version claimed here, so an old value quietly shortens the
81
+ * list rather than erroring.
82
+ */
83
+ exports.CODEX_CLIENT_VERSION = "0.153.4";
84
+ /**
85
+ * Decode a JWT's payload without verifying its signature.
86
+ *
87
+ * Verification is the token endpoint's job — we are only reading claims out of a
88
+ * token we were just handed over TLS, never making a trust decision on it.
89
+ * Returns `undefined` for anything that does not parse, so a malformed or
90
+ * opaque token degrades to "no claims" rather than throwing.
91
+ */
92
+ function decodeJwtClaims(token) {
93
+ const payload = token.split(".")[1];
94
+ if (!payload)
95
+ return undefined;
96
+ try {
97
+ const json = Buffer.from(payload, "base64url").toString("utf8");
98
+ const claims = JSON.parse(json);
99
+ return typeof claims === "object" && claims !== null
100
+ ? claims
101
+ : undefined;
102
+ }
103
+ catch {
104
+ return undefined;
105
+ }
106
+ }
107
+ /**
108
+ * Seconds-since-epoch expiry of a JWT, or `undefined` if it has no `exp`.
109
+ */
110
+ function jwtExpiry(token) {
111
+ const exp = decodeJwtClaims(token)?.exp;
112
+ return typeof exp === "number" ? exp : undefined;
113
+ }
114
+ /** Default location of Codex's credential file. */
115
+ function codexAuthFilePath(codexHome) {
116
+ const home = codexHome ?? process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex");
117
+ return path.join(home, "auth.json");
118
+ }
119
+ /**
120
+ * Read the credentials the Codex CLI stored at `$CODEX_HOME/auth.json`
121
+ * (`~/.codex/auth.json` by default).
122
+ *
123
+ * Sign in with `codex login` first — this only reads what that wrote, it does
124
+ * not run the OAuth flow itself.
125
+ *
126
+ * @throws if the file is missing, unreadable, not JSON, or holds no access token.
127
+ */
128
+ async function loadCodexCredentials(codexHome) {
129
+ const file = codexAuthFilePath(codexHome);
130
+ let raw;
131
+ try {
132
+ raw = await fs_1.promises.readFile(file, "utf8");
133
+ }
134
+ catch (error) {
135
+ const reason = error?.code === "ENOENT"
136
+ ? "no such file — run `codex login` to sign in with your ChatGPT account"
137
+ : error instanceof Error
138
+ ? error.message
139
+ : "unknown error";
140
+ throw new Error(`Could not read Codex credentials from ${file}: ${reason}`);
141
+ }
142
+ let parsed;
143
+ try {
144
+ parsed = JSON.parse(raw);
145
+ }
146
+ catch {
147
+ throw new Error(`Codex credentials at ${file} are not valid JSON`);
148
+ }
149
+ const tokens = parsed.tokens;
150
+ if (!tokens?.access_token) {
151
+ throw new Error(`Codex credentials at ${file} contain no OAuth access token` +
152
+ (parsed.OPENAI_API_KEY
153
+ ? " — that file holds a platform API key instead, which belongs in `apiKey` with the default `authType: \"apiKey\"`"
154
+ : " — run `codex login` to sign in with your ChatGPT account"));
155
+ }
156
+ return credentialsFromTokens(tokens);
157
+ }
158
+ /** Build {@link CodexCredentials} from an `auth.json` `tokens` object. */
159
+ function credentialsFromTokens(tokens) {
160
+ const claims = tokens.id_token
161
+ ? decodeJwtClaims(tokens.id_token)
162
+ : undefined;
163
+ const auth = claims?.["https://api.openai.com/auth"];
164
+ return {
165
+ accessToken: tokens.access_token,
166
+ refreshToken: tokens.refresh_token,
167
+ // `auth.json` usually carries `account_id`, but not always; the same value
168
+ // is a claim on the id_token, so fall back to that before giving up.
169
+ accountId: tokens.account_id ?? auth?.chatgpt_account_id,
170
+ email: claims?.email ?? claims?.["https://api.openai.com/profile"]?.email,
171
+ planType: auth?.chatgpt_plan_type,
172
+ };
173
+ }
174
+ /**
175
+ * Exchange a refresh token for a fresh access token.
176
+ *
177
+ * The returned credentials carry the new `refresh_token` when the server
178
+ * rotated it, and the previous one otherwise.
179
+ */
180
+ async function refreshCodexCredentials(refreshToken, options = {}) {
181
+ const res = await fetch(options.tokenUrl ?? exports.CODEX_TOKEN_URL, {
182
+ method: "POST",
183
+ headers: { "Content-Type": "application/json" },
184
+ body: JSON.stringify({
185
+ grant_type: "refresh_token",
186
+ refresh_token: refreshToken,
187
+ client_id: options.clientId ?? exports.CODEX_CLIENT_ID,
188
+ }),
189
+ signal: options.signal,
190
+ });
191
+ if (!res.ok) {
192
+ const body = await res.text().catch(() => "");
193
+ throw new Error(`Codex token refresh failed (${res.status} ${res.statusText})${body ? `: ${body.slice(0, 500)}` : ""}`);
194
+ }
195
+ const data = (await res.json());
196
+ if (!data.access_token) {
197
+ throw new Error("Codex token refresh returned no access_token");
198
+ }
199
+ return credentialsFromTokens({
200
+ access_token: data.access_token,
201
+ // The endpoint only returns a refresh token when it rotates one; reuse the
202
+ // current one otherwise, or the next refresh has nothing to present.
203
+ refresh_token: data.refresh_token ?? refreshToken,
204
+ id_token: data.id_token,
205
+ });
206
+ }
207
+ /**
208
+ * Wrap credentials in a self-refreshing token provider.
209
+ *
210
+ * Refreshes lazily — only when a token is actually asked for and the current
211
+ * one is within `refreshSkewSeconds` of expiry. Concurrent callers share a
212
+ * single in-flight refresh rather than each starting their own.
213
+ */
214
+ function createCodexTokenProvider(credentials, options = {}) {
215
+ const skew = options.refreshSkewSeconds ?? 300;
216
+ let current = credentials;
217
+ let expiresAt = jwtExpiry(credentials.accessToken);
218
+ let inFlight;
219
+ const isFresh = () => {
220
+ // An opaque token with no readable `exp` is assumed good: refreshing on
221
+ // every call would be worse than letting a 401 surface.
222
+ if (expiresAt === undefined)
223
+ return true;
224
+ return Date.now() / 1000 < expiresAt - skew;
225
+ };
226
+ const refresh = async () => {
227
+ if (!current.refreshToken) {
228
+ throw new Error("Codex access token has expired and no refresh token is available — run `codex login` again");
229
+ }
230
+ const next = await refreshCodexCredentials(current.refreshToken, {
231
+ clientId: options.clientId,
232
+ tokenUrl: options.tokenUrl,
233
+ });
234
+ current = {
235
+ ...next,
236
+ // A refresh response carries no id_token in some cases, which would drop
237
+ // the account id the `chatgpt-account-id` header needs.
238
+ accountId: next.accountId ?? current.accountId,
239
+ email: next.email ?? current.email,
240
+ planType: next.planType ?? current.planType,
241
+ };
242
+ expiresAt = jwtExpiry(current.accessToken);
243
+ try {
244
+ await options.onRefresh?.(current);
245
+ }
246
+ catch {
247
+ // Persisting is best-effort; the token in hand is still valid.
248
+ }
249
+ return current.accessToken;
250
+ };
251
+ return {
252
+ getToken: async () => {
253
+ if (isFresh())
254
+ return current.accessToken;
255
+ // Collapse concurrent refreshes: the second caller awaits the first.
256
+ inFlight ?? (inFlight = refresh().finally(() => {
257
+ inFlight = undefined;
258
+ }));
259
+ return inFlight;
260
+ },
261
+ current: () => current,
262
+ };
263
+ }
264
+ //# sourceMappingURL=codex-auth.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  export * from "./agents/BaseAgent";
2
2
  export * from "./agents/anthropic/ClaudeAgent";
3
3
  export { OpenAiAgent } from "./agents/openai/OpenAiAgent";
4
+ export { CODEX_BASE_URL, CODEX_CLIENT_ID, CODEX_ORIGINATOR, CODEX_TOKEN_URL, codexAuthFilePath, createCodexTokenProvider, loadCodexCredentials, refreshCodexCredentials, } from "./agents/openai/codex-auth";
5
+ export type { CodexModelCard, CodexCredentials, CodexTokenProvider, CodexTokenProviderOptions, } from "./agents/openai/codex-auth";
6
+ export { CodexAgent } from "./agents/openai/CodexAgent";
7
+ export type { CodexAgentConfig, CodexModel, CodexReasoningEffort, } from "./agents/openai/CodexAgent";
4
8
  export { MistralAgent } from "./agents/mistral/MistralAgent";
5
9
  export type { MistralModelCard } from "./agents/mistral/MistralAgent";
6
10
  export { GeminiAgent, GEMINI_RETIRED_MODELS, } from "./agents/google/GeminiAgent";
package/dist/index.js CHANGED
@@ -22,12 +22,23 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
22
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
23
  };
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.openRouterTransformer = exports.chatCompletionsTransformer = exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.OpenRouterAgent = exports.OpenAICompatibleAgent = exports.LlamaCppAgent = exports.OllamaAgent = exports.GEMINI_RETIRED_MODELS = exports.GeminiAgent = exports.MistralAgent = exports.OpenAiAgent = void 0;
25
+ exports.openRouterTransformer = exports.chatCompletionsTransformer = exports.ollamaTransformer = exports.geminiTransformer = exports.mistralTransformer = exports.openAiTransformer = exports.anthropicTransformer = exports.OpenRouterAgent = exports.OpenAICompatibleAgent = exports.LlamaCppAgent = exports.OllamaAgent = exports.GEMINI_RETIRED_MODELS = exports.GeminiAgent = exports.MistralAgent = exports.CodexAgent = exports.refreshCodexCredentials = exports.loadCodexCredentials = exports.createCodexTokenProvider = exports.codexAuthFilePath = exports.CODEX_TOKEN_URL = exports.CODEX_ORIGINATOR = exports.CODEX_CLIENT_ID = exports.CODEX_BASE_URL = exports.OpenAiAgent = void 0;
26
26
  // Agents
27
27
  __exportStar(require("./agents/BaseAgent"), exports);
28
28
  __exportStar(require("./agents/anthropic/ClaudeAgent"), exports);
29
29
  var OpenAiAgent_1 = require("./agents/openai/OpenAiAgent");
30
30
  Object.defineProperty(exports, "OpenAiAgent", { enumerable: true, get: function () { return OpenAiAgent_1.OpenAiAgent; } });
31
+ var codex_auth_1 = require("./agents/openai/codex-auth");
32
+ Object.defineProperty(exports, "CODEX_BASE_URL", { enumerable: true, get: function () { return codex_auth_1.CODEX_BASE_URL; } });
33
+ Object.defineProperty(exports, "CODEX_CLIENT_ID", { enumerable: true, get: function () { return codex_auth_1.CODEX_CLIENT_ID; } });
34
+ Object.defineProperty(exports, "CODEX_ORIGINATOR", { enumerable: true, get: function () { return codex_auth_1.CODEX_ORIGINATOR; } });
35
+ Object.defineProperty(exports, "CODEX_TOKEN_URL", { enumerable: true, get: function () { return codex_auth_1.CODEX_TOKEN_URL; } });
36
+ Object.defineProperty(exports, "codexAuthFilePath", { enumerable: true, get: function () { return codex_auth_1.codexAuthFilePath; } });
37
+ Object.defineProperty(exports, "createCodexTokenProvider", { enumerable: true, get: function () { return codex_auth_1.createCodexTokenProvider; } });
38
+ Object.defineProperty(exports, "loadCodexCredentials", { enumerable: true, get: function () { return codex_auth_1.loadCodexCredentials; } });
39
+ Object.defineProperty(exports, "refreshCodexCredentials", { enumerable: true, get: function () { return codex_auth_1.refreshCodexCredentials; } });
40
+ var CodexAgent_1 = require("./agents/openai/CodexAgent");
41
+ Object.defineProperty(exports, "CodexAgent", { enumerable: true, get: function () { return CodexAgent_1.CodexAgent; } });
31
42
  var MistralAgent_1 = require("./agents/mistral/MistralAgent");
32
43
  Object.defineProperty(exports, "MistralAgent", { enumerable: true, get: function () { return MistralAgent_1.MistralAgent; } });
33
44
  var GeminiAgent_1 = require("./agents/google/GeminiAgent");
package/dist/openai.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from "./core";
2
- export { OpenAiAgent } from "./agents/openai/OpenAiAgent";
2
+ export { OpenAiAgent, describeOpenAIError, wrapErrorBodyFetch, } from "./agents/openai/OpenAiAgent";
3
+ export { CodexAgent } from "./agents/openai/CodexAgent";
4
+ export type { CodexAgentConfig, CodexModel, CodexReasoningEffort, } from "./agents/openai/CodexAgent";
3
5
  export { openAiTransformer } from "./history/transformers";
6
+ export { CODEX_BASE_URL, CODEX_CLIENT_ID, CODEX_ORIGINATOR, CODEX_TOKEN_URL, codexAuthFilePath, createCodexTokenProvider, decodeJwtClaims, jwtExpiry, loadCodexCredentials, refreshCodexCredentials, type CodexCredentials, type CodexTokenProvider, type CodexTokenProviderOptions, type CodexModelCard, } from "./agents/openai/codex-auth";
4
7
  //# sourceMappingURL=openai.d.ts.map
package/dist/openai.js CHANGED
@@ -14,11 +14,26 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.openAiTransformer = exports.OpenAiAgent = void 0;
17
+ exports.refreshCodexCredentials = exports.loadCodexCredentials = exports.jwtExpiry = exports.decodeJwtClaims = exports.createCodexTokenProvider = exports.codexAuthFilePath = exports.CODEX_TOKEN_URL = exports.CODEX_ORIGINATOR = exports.CODEX_CLIENT_ID = exports.CODEX_BASE_URL = exports.openAiTransformer = exports.CodexAgent = exports.wrapErrorBodyFetch = exports.describeOpenAIError = exports.OpenAiAgent = void 0;
18
18
  // OpenAI Agent Entry Point
19
19
  __exportStar(require("./core"), exports);
20
20
  var OpenAiAgent_1 = require("./agents/openai/OpenAiAgent");
21
21
  Object.defineProperty(exports, "OpenAiAgent", { enumerable: true, get: function () { return OpenAiAgent_1.OpenAiAgent; } });
22
+ Object.defineProperty(exports, "describeOpenAIError", { enumerable: true, get: function () { return OpenAiAgent_1.describeOpenAIError; } });
23
+ Object.defineProperty(exports, "wrapErrorBodyFetch", { enumerable: true, get: function () { return OpenAiAgent_1.wrapErrorBodyFetch; } });
24
+ var CodexAgent_1 = require("./agents/openai/CodexAgent");
25
+ Object.defineProperty(exports, "CodexAgent", { enumerable: true, get: function () { return CodexAgent_1.CodexAgent; } });
22
26
  var transformers_1 = require("./history/transformers");
23
27
  Object.defineProperty(exports, "openAiTransformer", { enumerable: true, get: function () { return transformers_1.openAiTransformer; } });
28
+ var codex_auth_1 = require("./agents/openai/codex-auth");
29
+ Object.defineProperty(exports, "CODEX_BASE_URL", { enumerable: true, get: function () { return codex_auth_1.CODEX_BASE_URL; } });
30
+ Object.defineProperty(exports, "CODEX_CLIENT_ID", { enumerable: true, get: function () { return codex_auth_1.CODEX_CLIENT_ID; } });
31
+ Object.defineProperty(exports, "CODEX_ORIGINATOR", { enumerable: true, get: function () { return codex_auth_1.CODEX_ORIGINATOR; } });
32
+ Object.defineProperty(exports, "CODEX_TOKEN_URL", { enumerable: true, get: function () { return codex_auth_1.CODEX_TOKEN_URL; } });
33
+ Object.defineProperty(exports, "codexAuthFilePath", { enumerable: true, get: function () { return codex_auth_1.codexAuthFilePath; } });
34
+ Object.defineProperty(exports, "createCodexTokenProvider", { enumerable: true, get: function () { return codex_auth_1.createCodexTokenProvider; } });
35
+ Object.defineProperty(exports, "decodeJwtClaims", { enumerable: true, get: function () { return codex_auth_1.decodeJwtClaims; } });
36
+ Object.defineProperty(exports, "jwtExpiry", { enumerable: true, get: function () { return codex_auth_1.jwtExpiry; } });
37
+ Object.defineProperty(exports, "loadCodexCredentials", { enumerable: true, get: function () { return codex_auth_1.loadCodexCredentials; } });
38
+ Object.defineProperty(exports, "refreshCodexCredentials", { enumerable: true, get: function () { return codex_auth_1.refreshCodexCredentials; } });
24
39
  //# sourceMappingURL=openai.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agentionai/agents",
3
3
  "author": "Laurent Zuijdwijk",
4
- "version": "1.12.0",
4
+ "version": "1.13.0",
5
5
  "description": "Agent Library",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",