@yolk-sdk/openai 0.0.1-canary.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.
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/codex.d.mts +51 -0
- package/dist/codex.d.mts.map +1 -0
- package/dist/codex.mjs +52 -0
- package/dist/codex.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +2 -0
- package/package.json +56 -0
- package/src/codex.ts +74 -0
- package/src/index.ts +18 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yolk SDK contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @yolk-sdk/openai
|
|
2
|
+
|
|
3
|
+
OpenAI-family provider mechanics for Codex/ChatGPT OAuth and broker integration.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @yolk-sdk/openai@canary @yolk-sdk/oauth@canary effect
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Canary APIs are unstable. Keep all `@yolk-sdk/*` packages on the same version.
|
|
12
|
+
|
|
13
|
+
## Subpaths
|
|
14
|
+
|
|
15
|
+
| Subpath | Purpose |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `@yolk-sdk/openai` | OpenAI Codex OAuth constants, token schemas, broker helpers, and auth headers |
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {
|
|
23
|
+
makeOpenAiCodexBrokerRequest,
|
|
24
|
+
makeOpenAiCodexTokenBrokerClient,
|
|
25
|
+
openAiCodexAuthorizationHeaders,
|
|
26
|
+
openAiCodexProviderId,
|
|
27
|
+
toOAuthAccessToken
|
|
28
|
+
} from '@yolk-sdk/openai'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Broker request
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const request = makeOpenAiCodexBrokerRequest({
|
|
35
|
+
subject: 'opaque-host-subject',
|
|
36
|
+
minimumTtlMs: 60_000
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Hosts route this request to an authenticated token broker. The package never stores refresh tokens.
|
|
41
|
+
|
|
42
|
+
## Authorization headers
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const headers = openAiCodexAuthorizationHeaders(token)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Use these headers in host-owned Codex request adapters.
|
|
49
|
+
|
|
50
|
+
## Exposed constants
|
|
51
|
+
|
|
52
|
+
- Codex provider id and OAuth issuer.
|
|
53
|
+
- Device auth/user code/token URLs.
|
|
54
|
+
- Codex responses URL.
|
|
55
|
+
- Refresh buffer and token schemas.
|
|
56
|
+
|
|
57
|
+
## Host responsibilities
|
|
58
|
+
|
|
59
|
+
- Own device flow UI, session mapping, refresh-token storage, and policy.
|
|
60
|
+
- Provide token brokers through `@yolk-sdk/oauth` contracts.
|
|
61
|
+
- Own network execution, telemetry, error reporting, and product routing.
|
|
62
|
+
|
|
63
|
+
## Boundaries
|
|
64
|
+
|
|
65
|
+
- No app users, sessions, DB, Better Auth, routes, or Durable Objects.
|
|
66
|
+
- No OpenAI SDK dependency.
|
|
67
|
+
- API-key mode can be added later without changing OAuth contracts.
|
package/dist/codex.d.mts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { OAuthAccessToken, TokenBrokerClient, TokenBrokerRequest } from "@yolk-sdk/oauth";
|
|
3
|
+
|
|
4
|
+
//#region src/codex.d.ts
|
|
5
|
+
declare const openAiCodexProviderId = "openai-codex";
|
|
6
|
+
declare const openAiCodexResponsesUrl = "https://chatgpt.com/backend-api/codex/responses";
|
|
7
|
+
declare const openAiCodexAuthIssuer = "https://auth.openai.com";
|
|
8
|
+
declare const openAiCodexClientId = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
9
|
+
declare const openAiCodexDeviceAuthUserCodeUrl = "https://auth.openai.com/api/accounts/deviceauth/usercode";
|
|
10
|
+
declare const openAiCodexDeviceAuthTokenUrl = "https://auth.openai.com/api/accounts/deviceauth/token";
|
|
11
|
+
declare const openAiCodexDeviceAuthCallbackRedirect = "https://auth.openai.com/deviceauth/callback";
|
|
12
|
+
declare const openAiCodexDeviceVerificationUrl = "https://auth.openai.com/codex/device";
|
|
13
|
+
declare const openAiCodexTokenEndpoint = "https://auth.openai.com/oauth/token";
|
|
14
|
+
declare const openAiCodexRefreshBufferMs: number;
|
|
15
|
+
declare const OpenAiCodexOAuthToken_base: Schema.Class<OpenAiCodexOAuthToken, Schema.Struct<{
|
|
16
|
+
readonly accessToken: Schema.String;
|
|
17
|
+
readonly refreshToken: Schema.String;
|
|
18
|
+
readonly expiresAt: Schema.Number;
|
|
19
|
+
readonly accountId: Schema.optional<Schema.String>;
|
|
20
|
+
}>, {}>;
|
|
21
|
+
declare class OpenAiCodexOAuthToken extends OpenAiCodexOAuthToken_base {}
|
|
22
|
+
declare const OpenAiCodexTokenBrokerResponse_base: Schema.Class<OpenAiCodexTokenBrokerResponse, Schema.Struct<{
|
|
23
|
+
readonly accessToken: Schema.String;
|
|
24
|
+
readonly expiresAt: Schema.Number;
|
|
25
|
+
readonly accountId: Schema.optional<Schema.String>;
|
|
26
|
+
}>, {}>;
|
|
27
|
+
declare class OpenAiCodexTokenBrokerResponse extends OpenAiCodexTokenBrokerResponse_base {}
|
|
28
|
+
declare const toOAuthAccessToken: (token: OpenAiCodexTokenBrokerResponse) => OAuthAccessToken;
|
|
29
|
+
declare const makeOpenAiCodexBrokerRequest: (input: {
|
|
30
|
+
readonly subjectId: string;
|
|
31
|
+
readonly minTtlSeconds?: number;
|
|
32
|
+
readonly forceRefresh?: boolean;
|
|
33
|
+
}) => TokenBrokerRequest;
|
|
34
|
+
declare const openAiCodexAuthorizationHeaders: (token: OAuthAccessToken) => {
|
|
35
|
+
authorization: string;
|
|
36
|
+
originator: string;
|
|
37
|
+
} | {
|
|
38
|
+
'ChatGPT-Account-Id': string;
|
|
39
|
+
authorization: string;
|
|
40
|
+
originator: string;
|
|
41
|
+
};
|
|
42
|
+
declare const makeOpenAiCodexTokenBrokerClient: (broker: TokenBrokerClient) => {
|
|
43
|
+
getAccessToken: (input: {
|
|
44
|
+
readonly subjectId: string;
|
|
45
|
+
readonly minTtlSeconds?: number;
|
|
46
|
+
readonly forceRefresh?: boolean;
|
|
47
|
+
}) => import("effect/Effect").Effect<OAuthAccessToken, import("@yolk-sdk/oauth").OAuthError, never>;
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken };
|
|
51
|
+
//# sourceMappingURL=codex.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.d.mts","names":[],"sources":["../src/codex.ts"],"mappings":";;;;cAGa,qBAAA;AAAA,cACA,uBAAA;AAAA,cACA,qBAAA;AAAA,cACA,mBAAA;AAAA,cACA,gCAAA;AAAA,cACA,6BAAA;AAAA,cACA,qCAAA;AAAA,cACA,gCAAA;AAAA,cACA,wBAAA;AAAA,cACA,0BAAA;AAAA,cAA0C,0BAAA;;;;;;cAE1C,qBAAA,SAA8B,0BAOzC;AAAA,cAAG,mCAAA;;;;;cAEQ,8BAAA,SAAuC,mCAMlD;AAAA,cAEW,kBAAA,GAAsB,KAAA,EAAO,8BAAA,KAA8B,gBAMpE;AAAA,cAES,4BAAA,GAAgC,KAAA;EAAA,SAClC,SAAA;EAAA,SACA,aAAA;EAAA,SACA,YAAA;AAAA,MACV,kBAMG;AAAA,cAES,+BAAA,GAAmC,KAAA,EAAO,gBAAgB;;;;;;;;cAgB1D,gCAAA,GAAoC,MAAA,EAAQ,iBAAA;;aAE5C,SAAA;IAAA,SACA,aAAA;IAAA,SACA,YAAA;EAAA,8BACV,MAAA,CAAA,gBAAA,4BAAA,UAAA;AAAA"}
|
package/dist/codex.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { OAuthAccessToken, TokenBrokerRequest } from "@yolk-sdk/oauth";
|
|
3
|
+
//#region src/codex.ts
|
|
4
|
+
const openAiCodexProviderId = "openai-codex";
|
|
5
|
+
const openAiCodexResponsesUrl = "https://chatgpt.com/backend-api/codex/responses";
|
|
6
|
+
const openAiCodexAuthIssuer = "https://auth.openai.com";
|
|
7
|
+
const openAiCodexClientId = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
8
|
+
const openAiCodexDeviceAuthUserCodeUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/usercode`;
|
|
9
|
+
const openAiCodexDeviceAuthTokenUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/token`;
|
|
10
|
+
const openAiCodexDeviceAuthCallbackRedirect = `${openAiCodexAuthIssuer}/deviceauth/callback`;
|
|
11
|
+
const openAiCodexDeviceVerificationUrl = `${openAiCodexAuthIssuer}/codex/device`;
|
|
12
|
+
const openAiCodexTokenEndpoint = `${openAiCodexAuthIssuer}/oauth/token`;
|
|
13
|
+
const openAiCodexRefreshBufferMs = 300 * 1e3;
|
|
14
|
+
var OpenAiCodexOAuthToken = class extends Schema.Class("OpenAiCodexOAuthToken")({
|
|
15
|
+
accessToken: Schema.String,
|
|
16
|
+
refreshToken: Schema.String,
|
|
17
|
+
expiresAt: Schema.Number,
|
|
18
|
+
accountId: Schema.optional(Schema.String)
|
|
19
|
+
}) {};
|
|
20
|
+
var OpenAiCodexTokenBrokerResponse = class extends Schema.Class("OpenAiCodexTokenBrokerResponse")({
|
|
21
|
+
accessToken: Schema.String,
|
|
22
|
+
expiresAt: Schema.Number,
|
|
23
|
+
accountId: Schema.optional(Schema.String)
|
|
24
|
+
}) {};
|
|
25
|
+
const toOAuthAccessToken = (token) => new OAuthAccessToken({
|
|
26
|
+
provider: openAiCodexProviderId,
|
|
27
|
+
accessToken: token.accessToken,
|
|
28
|
+
expiresAt: token.expiresAt,
|
|
29
|
+
accountId: token.accountId
|
|
30
|
+
});
|
|
31
|
+
const makeOpenAiCodexBrokerRequest = (input) => new TokenBrokerRequest({
|
|
32
|
+
provider: openAiCodexProviderId,
|
|
33
|
+
subjectId: input.subjectId,
|
|
34
|
+
minTtlSeconds: input.minTtlSeconds,
|
|
35
|
+
forceRefresh: input.forceRefresh
|
|
36
|
+
});
|
|
37
|
+
const openAiCodexAuthorizationHeaders = (token) => {
|
|
38
|
+
const baseHeaders = {
|
|
39
|
+
authorization: `Bearer ${token.accessToken}`,
|
|
40
|
+
originator: "opencode"
|
|
41
|
+
};
|
|
42
|
+
if (token.accountId === void 0) return baseHeaders;
|
|
43
|
+
return {
|
|
44
|
+
...baseHeaders,
|
|
45
|
+
"ChatGPT-Account-Id": token.accountId
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const makeOpenAiCodexTokenBrokerClient = (broker) => ({ getAccessToken: (input) => broker.getAccessToken(makeOpenAiCodexBrokerRequest(input)) });
|
|
49
|
+
//#endregion
|
|
50
|
+
export { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=codex.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.mjs","names":[],"sources":["../src/codex.ts"],"sourcesContent":["import * as Schema from 'effect/Schema'\nimport { OAuthAccessToken, TokenBrokerRequest, type TokenBrokerClient } from '@yolk-sdk/oauth'\n\nexport const openAiCodexProviderId = 'openai-codex'\nexport const openAiCodexResponsesUrl = 'https://chatgpt.com/backend-api/codex/responses'\nexport const openAiCodexAuthIssuer = 'https://auth.openai.com'\nexport const openAiCodexClientId = 'app_EMoamEEZ73f0CkXaXp7hrann'\nexport const openAiCodexDeviceAuthUserCodeUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/usercode`\nexport const openAiCodexDeviceAuthTokenUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/token`\nexport const openAiCodexDeviceAuthCallbackRedirect = `${openAiCodexAuthIssuer}/deviceauth/callback`\nexport const openAiCodexDeviceVerificationUrl = `${openAiCodexAuthIssuer}/codex/device`\nexport const openAiCodexTokenEndpoint = `${openAiCodexAuthIssuer}/oauth/token`\nexport const openAiCodexRefreshBufferMs = 5 * 60 * 1000\n\nexport class OpenAiCodexOAuthToken extends Schema.Class<OpenAiCodexOAuthToken>(\n 'OpenAiCodexOAuthToken'\n)({\n accessToken: Schema.String,\n refreshToken: Schema.String,\n expiresAt: Schema.Number,\n accountId: Schema.optional(Schema.String)\n}) {}\n\nexport class OpenAiCodexTokenBrokerResponse extends Schema.Class<OpenAiCodexTokenBrokerResponse>(\n 'OpenAiCodexTokenBrokerResponse'\n)({\n accessToken: Schema.String,\n expiresAt: Schema.Number,\n accountId: Schema.optional(Schema.String)\n}) {}\n\nexport const toOAuthAccessToken = (token: OpenAiCodexTokenBrokerResponse) =>\n new OAuthAccessToken({\n provider: openAiCodexProviderId,\n accessToken: token.accessToken,\n expiresAt: token.expiresAt,\n accountId: token.accountId\n })\n\nexport const makeOpenAiCodexBrokerRequest = (input: {\n readonly subjectId: string\n readonly minTtlSeconds?: number\n readonly forceRefresh?: boolean\n}) =>\n new TokenBrokerRequest({\n provider: openAiCodexProviderId,\n subjectId: input.subjectId,\n minTtlSeconds: input.minTtlSeconds,\n forceRefresh: input.forceRefresh\n })\n\nexport const openAiCodexAuthorizationHeaders = (token: OAuthAccessToken) => {\n const baseHeaders = {\n authorization: `Bearer ${token.accessToken}`,\n originator: 'opencode'\n }\n\n if (token.accountId === undefined) {\n return baseHeaders\n }\n\n return {\n ...baseHeaders,\n 'ChatGPT-Account-Id': token.accountId\n }\n}\n\nexport const makeOpenAiCodexTokenBrokerClient = (broker: TokenBrokerClient) => ({\n getAccessToken: (input: {\n readonly subjectId: string\n readonly minTtlSeconds?: number\n readonly forceRefresh?: boolean\n }) => broker.getAccessToken(makeOpenAiCodexBrokerRequest(input))\n})\n"],"mappings":";;;AAGA,MAAa,wBAAwB;AACrC,MAAa,0BAA0B;AACvC,MAAa,wBAAwB;AACrC,MAAa,sBAAsB;AACnC,MAAa,mCAAmC,GAAG,sBAAsB;AACzE,MAAa,gCAAgC,GAAG,sBAAsB;AACtE,MAAa,wCAAwC,GAAG,sBAAsB;AAC9E,MAAa,mCAAmC,GAAG,sBAAsB;AACzE,MAAa,2BAA2B,GAAG,sBAAsB;AACjE,MAAa,6BAA6B,MAAS;AAEnD,IAAa,wBAAb,cAA2C,OAAO,MAChD,uBACF,EAAE;CACA,aAAa,OAAO;CACpB,cAAc,OAAO;CACrB,WAAW,OAAO;CAClB,WAAW,OAAO,SAAS,OAAO,MAAM;AAC1C,CAAC,EAAE,CAAC;AAEJ,IAAa,iCAAb,cAAoD,OAAO,MACzD,gCACF,EAAE;CACA,aAAa,OAAO;CACpB,WAAW,OAAO;CAClB,WAAW,OAAO,SAAS,OAAO,MAAM;AAC1C,CAAC,EAAE,CAAC;AAEJ,MAAa,sBAAsB,UACjC,IAAI,iBAAiB;CACnB,UAAU;CACV,aAAa,MAAM;CACnB,WAAW,MAAM;CACjB,WAAW,MAAM;AACnB,CAAC;AAEH,MAAa,gCAAgC,UAK3C,IAAI,mBAAmB;CACrB,UAAU;CACV,WAAW,MAAM;CACjB,eAAe,MAAM;CACrB,cAAc,MAAM;AACtB,CAAC;AAEH,MAAa,mCAAmC,UAA4B;CAC1E,MAAM,cAAc;EAClB,eAAe,UAAU,MAAM;EAC/B,YAAY;CACd;CAEA,IAAI,MAAM,cAAc,KAAA,GACtB,OAAO;CAGT,OAAO;EACL,GAAG;EACH,sBAAsB,MAAM;CAC9B;AACF;AAEA,MAAa,oCAAoC,YAA+B,EAC9E,iBAAiB,UAIX,OAAO,eAAe,6BAA6B,KAAK,CAAC,EACjE"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken } from "./codex.mjs";
|
|
2
|
+
export { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken } from "./codex.mjs";
|
|
2
|
+
export { OpenAiCodexOAuthToken, OpenAiCodexTokenBrokerResponse, makeOpenAiCodexBrokerRequest, makeOpenAiCodexTokenBrokerClient, openAiCodexAuthIssuer, openAiCodexAuthorizationHeaders, openAiCodexClientId, openAiCodexDeviceAuthCallbackRedirect, openAiCodexDeviceAuthTokenUrl, openAiCodexDeviceAuthUserCodeUrl, openAiCodexDeviceVerificationUrl, openAiCodexProviderId, openAiCodexRefreshBufferMs, openAiCodexResponsesUrl, openAiCodexTokenEndpoint, toOAuthAccessToken };
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yolk-sdk/openai",
|
|
3
|
+
"version": "0.0.1-canary.0",
|
|
4
|
+
"description": "OpenAI and Codex OAuth and provider mechanics for Yolk hosts.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/magoz/yolk-sdk.git",
|
|
11
|
+
"directory": "packages/openai"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/magoz/yolk-sdk/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/magoz/yolk-sdk#readme",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"openai",
|
|
19
|
+
"codex",
|
|
20
|
+
"oauth",
|
|
21
|
+
"agent",
|
|
22
|
+
"effect"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"default": "./dist/index.mjs"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"src/**/*.ts",
|
|
37
|
+
"!src/**/*.test.ts",
|
|
38
|
+
"!src/**/*.test.tsx",
|
|
39
|
+
"dist/**/*",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public",
|
|
44
|
+
"provenance": true
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"effect": "4.0.0-beta.65",
|
|
48
|
+
"@yolk-sdk/oauth": "^0.0.1-canary.0"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsdown",
|
|
52
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
53
|
+
"test": "vitest run --passWithNoTests",
|
|
54
|
+
"test:run": "vitest run --passWithNoTests"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/codex.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as Schema from 'effect/Schema'
|
|
2
|
+
import { OAuthAccessToken, TokenBrokerRequest, type TokenBrokerClient } from '@yolk-sdk/oauth'
|
|
3
|
+
|
|
4
|
+
export const openAiCodexProviderId = 'openai-codex'
|
|
5
|
+
export const openAiCodexResponsesUrl = 'https://chatgpt.com/backend-api/codex/responses'
|
|
6
|
+
export const openAiCodexAuthIssuer = 'https://auth.openai.com'
|
|
7
|
+
export const openAiCodexClientId = 'app_EMoamEEZ73f0CkXaXp7hrann'
|
|
8
|
+
export const openAiCodexDeviceAuthUserCodeUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/usercode`
|
|
9
|
+
export const openAiCodexDeviceAuthTokenUrl = `${openAiCodexAuthIssuer}/api/accounts/deviceauth/token`
|
|
10
|
+
export const openAiCodexDeviceAuthCallbackRedirect = `${openAiCodexAuthIssuer}/deviceauth/callback`
|
|
11
|
+
export const openAiCodexDeviceVerificationUrl = `${openAiCodexAuthIssuer}/codex/device`
|
|
12
|
+
export const openAiCodexTokenEndpoint = `${openAiCodexAuthIssuer}/oauth/token`
|
|
13
|
+
export const openAiCodexRefreshBufferMs = 5 * 60 * 1000
|
|
14
|
+
|
|
15
|
+
export class OpenAiCodexOAuthToken extends Schema.Class<OpenAiCodexOAuthToken>(
|
|
16
|
+
'OpenAiCodexOAuthToken'
|
|
17
|
+
)({
|
|
18
|
+
accessToken: Schema.String,
|
|
19
|
+
refreshToken: Schema.String,
|
|
20
|
+
expiresAt: Schema.Number,
|
|
21
|
+
accountId: Schema.optional(Schema.String)
|
|
22
|
+
}) {}
|
|
23
|
+
|
|
24
|
+
export class OpenAiCodexTokenBrokerResponse extends Schema.Class<OpenAiCodexTokenBrokerResponse>(
|
|
25
|
+
'OpenAiCodexTokenBrokerResponse'
|
|
26
|
+
)({
|
|
27
|
+
accessToken: Schema.String,
|
|
28
|
+
expiresAt: Schema.Number,
|
|
29
|
+
accountId: Schema.optional(Schema.String)
|
|
30
|
+
}) {}
|
|
31
|
+
|
|
32
|
+
export const toOAuthAccessToken = (token: OpenAiCodexTokenBrokerResponse) =>
|
|
33
|
+
new OAuthAccessToken({
|
|
34
|
+
provider: openAiCodexProviderId,
|
|
35
|
+
accessToken: token.accessToken,
|
|
36
|
+
expiresAt: token.expiresAt,
|
|
37
|
+
accountId: token.accountId
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const makeOpenAiCodexBrokerRequest = (input: {
|
|
41
|
+
readonly subjectId: string
|
|
42
|
+
readonly minTtlSeconds?: number
|
|
43
|
+
readonly forceRefresh?: boolean
|
|
44
|
+
}) =>
|
|
45
|
+
new TokenBrokerRequest({
|
|
46
|
+
provider: openAiCodexProviderId,
|
|
47
|
+
subjectId: input.subjectId,
|
|
48
|
+
minTtlSeconds: input.minTtlSeconds,
|
|
49
|
+
forceRefresh: input.forceRefresh
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
export const openAiCodexAuthorizationHeaders = (token: OAuthAccessToken) => {
|
|
53
|
+
const baseHeaders = {
|
|
54
|
+
authorization: `Bearer ${token.accessToken}`,
|
|
55
|
+
originator: 'opencode'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (token.accountId === undefined) {
|
|
59
|
+
return baseHeaders
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
...baseHeaders,
|
|
64
|
+
'ChatGPT-Account-Id': token.accountId
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export const makeOpenAiCodexTokenBrokerClient = (broker: TokenBrokerClient) => ({
|
|
69
|
+
getAccessToken: (input: {
|
|
70
|
+
readonly subjectId: string
|
|
71
|
+
readonly minTtlSeconds?: number
|
|
72
|
+
readonly forceRefresh?: boolean
|
|
73
|
+
}) => broker.getAccessToken(makeOpenAiCodexBrokerRequest(input))
|
|
74
|
+
})
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export {
|
|
2
|
+
OpenAiCodexOAuthToken,
|
|
3
|
+
OpenAiCodexTokenBrokerResponse,
|
|
4
|
+
makeOpenAiCodexBrokerRequest,
|
|
5
|
+
makeOpenAiCodexTokenBrokerClient,
|
|
6
|
+
openAiCodexAuthIssuer,
|
|
7
|
+
openAiCodexAuthorizationHeaders,
|
|
8
|
+
openAiCodexClientId,
|
|
9
|
+
openAiCodexDeviceAuthCallbackRedirect,
|
|
10
|
+
openAiCodexDeviceAuthTokenUrl,
|
|
11
|
+
openAiCodexDeviceAuthUserCodeUrl,
|
|
12
|
+
openAiCodexDeviceVerificationUrl,
|
|
13
|
+
openAiCodexProviderId,
|
|
14
|
+
openAiCodexRefreshBufferMs,
|
|
15
|
+
openAiCodexResponsesUrl,
|
|
16
|
+
openAiCodexTokenEndpoint,
|
|
17
|
+
toOAuthAccessToken
|
|
18
|
+
} from './codex.ts'
|