@moxxy/plugin-provider-codex-agent 0.0.0-stage → 0.45.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/dist/account-limit.d.ts +11 -0
- package/dist/account-limit.d.ts.map +1 -0
- package/dist/account-limit.js +24 -0
- package/dist/account-limit.js.map +1 -0
- package/dist/agent-provider.d.ts +62 -0
- package/dist/agent-provider.d.ts.map +1 -0
- package/dist/agent-provider.js +209 -0
- package/dist/agent-provider.js.map +1 -0
- package/dist/codex-session.d.ts +220 -0
- package/dist/codex-session.d.ts.map +1 -0
- package/dist/codex-session.js +1113 -0
- package/dist/codex-session.js.map +1 -0
- package/dist/constants.d.ts +15 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +15 -0
- package/dist/constants.js.map +1 -0
- package/dist/executable.d.ts +16 -0
- package/dist/executable.d.ts.map +1 -0
- package/dist/executable.js +43 -0
- package/dist/executable.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/login.d.ts +37 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +127 -0
- package/dist/login.js.map +1 -0
- package/dist/offered-models.d.ts +12 -0
- package/dist/offered-models.d.ts.map +1 -0
- package/dist/offered-models.js +53 -0
- package/dist/offered-models.js.map +1 -0
- package/dist/own-settings.d.ts +9 -0
- package/dist/own-settings.d.ts.map +1 -0
- package/dist/own-settings.js +34 -0
- package/dist/own-settings.js.map +1 -0
- package/dist/protocol.d.ts +279 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +30 -0
- package/dist/protocol.js.map +1 -0
- package/dist/subagents.d.ts +20 -0
- package/dist/subagents.d.ts.map +1 -0
- package/dist/subagents.js +90 -0
- package/dist/subagents.js.map +1 -0
- package/dist/translate.d.ts +87 -0
- package/dist/translate.d.ts.map +1 -0
- package/dist/translate.js +334 -0
- package/dist/translate.js.map +1 -0
- package/dist/view-image.d.ts +4 -0
- package/dist/view-image.d.ts.map +1 -0
- package/dist/view-image.js +47 -0
- package/dist/view-image.js.map +1 -0
- package/package.json +82 -3
- package/src/account-limit.ts +25 -0
- package/src/agent-cli.test.ts +76 -0
- package/src/agent-provider.test.ts +1556 -0
- package/src/agent-provider.ts +234 -0
- package/src/codex-session.ts +1258 -0
- package/src/constants.ts +18 -0
- package/src/event-coverage.test.ts +200 -0
- package/src/executable.test.ts +53 -0
- package/src/executable.ts +49 -0
- package/src/fake-codex.testkit.ts +576 -0
- package/src/fixtures/codex-app-server-0.155.1.json +122 -0
- package/src/fixtures/codex-app-server-0.163.0.json +125 -0
- package/src/fixtures/codex-model-list-0.163.0.json +436 -0
- package/src/index.test.ts +45 -0
- package/src/index.ts +99 -0
- package/src/login.test.ts +93 -0
- package/src/login.ts +167 -0
- package/src/offered-models.test.ts +87 -0
- package/src/offered-models.ts +65 -0
- package/src/own-settings.test.ts +45 -0
- package/src/own-settings.ts +39 -0
- package/src/protocol.ts +256 -0
- package/src/subagents.test.ts +47 -0
- package/src/subagents.ts +98 -0
- package/src/translate.test.ts +160 -0
- package/src/translate.ts +362 -0
- package/src/view-image.test.ts +29 -0
- package/src/view-image.ts +47 -0
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Moxxy (moxxy.ai)
|
|
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.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type AgentAccountLimit } from '@moxxy/sdk';
|
|
2
|
+
import type { CodexRateLimitSnapshot } from './protocol.js';
|
|
3
|
+
/**
|
|
4
|
+
* Codex's rate limits as Moxxy's account limit, from the most used of its windows; undefined when
|
|
5
|
+
* the update leaves the windows out (they stay as they were). Codex does not say when a window is
|
|
6
|
+
* near, so it is near from the share Claude warns at.
|
|
7
|
+
*/
|
|
8
|
+
export declare function accountLimitFrom(snapshot: CodexRateLimitSnapshot): AgentAccountLimit | undefined;
|
|
9
|
+
/** Whether Codex failed a turn because the account's usage limit is used up. */
|
|
10
|
+
export declare function failedOnUsageLimit(errorInfo: unknown): boolean;
|
|
11
|
+
//# sourceMappingURL=account-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-limit.d.ts","sourceRoot":"","sources":["../src/account-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAwB,MAAM,eAAe,CAAC;AAElF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,GAAG,iBAAiB,GAAG,SAAS,CAWhG;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAE9D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ACCOUNT_LIMIT_NEAR_PERCENT } from '@moxxy/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Codex's rate limits as Moxxy's account limit, from the most used of its windows; undefined when
|
|
4
|
+
* the update leaves the windows out (they stay as they were). Codex does not say when a window is
|
|
5
|
+
* near, so it is near from the share Claude warns at.
|
|
6
|
+
*/
|
|
7
|
+
export function accountLimitFrom(snapshot) {
|
|
8
|
+
const windows = [snapshot.primary, snapshot.secondary].filter((w) => w !== null && w !== undefined);
|
|
9
|
+
const top = windows.reduce((most, w) => (!most || w.usedPercent > most.usedPercent ? w : most), undefined);
|
|
10
|
+
if (!top)
|
|
11
|
+
return undefined;
|
|
12
|
+
const reached = (snapshot.rateLimitReachedType !== null && snapshot.rateLimitReachedType !== undefined) || top.usedPercent >= 100;
|
|
13
|
+
return {
|
|
14
|
+
state: reached ? 'reached' : top.usedPercent >= ACCOUNT_LIMIT_NEAR_PERCENT ? 'near' : 'ok',
|
|
15
|
+
usedPercent: top.usedPercent,
|
|
16
|
+
...(top.windowDurationMins !== null ? { windowMinutes: top.windowDurationMins } : {}),
|
|
17
|
+
...(top.resetsAt !== null ? { resetsAt: top.resetsAt * 1000 } : {}),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Whether Codex failed a turn because the account's usage limit is used up. */
|
|
21
|
+
export function failedOnUsageLimit(errorInfo) {
|
|
22
|
+
return errorInfo === 'usageLimitExceeded';
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=account-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-limit.js","sourceRoot":"","sources":["../src/account-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAA0B,MAAM,YAAY,CAAC;AAGhF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgC;IAC/D,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAA6B,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/H,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAmC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7I,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,oBAAoB,KAAK,IAAI,IAAI,QAAQ,CAAC,oBAAoB,KAAK,SAAS,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC;IAClI,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,IAAI,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;QAC1F,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,GAAG,CAAC,GAAG,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACpE,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,SAAkB;IACnD,OAAO,SAAS,KAAK,oBAAoB,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type AgentActivity, type AgentStepEvent, type AgentStepRequest, type AgentTurnStart, type LLMProvider, type ModelDescriptor, type ProviderEvent, type ProviderRequest } from '@moxxy/sdk';
|
|
2
|
+
import { AgentSessionPool } from '@moxxy/agent-connection-kit';
|
|
3
|
+
import { CodexAgentSession, type StartCodexAppServer } from './codex-session.js';
|
|
4
|
+
export declare const CODEX_AGENT_DEFAULT_MODEL = "gpt-6-astra";
|
|
5
|
+
/** What a new conversation starts on while the person chose no default: light, so it spares their plan. */
|
|
6
|
+
export declare const CODEX_AGENT_STARTER_MODEL = "gpt-6-luna";
|
|
7
|
+
/** Models Codex offers on a ChatGPT sign-in, used until Codex's own `model/list` answered; Codex decides what the account may use. */
|
|
8
|
+
export declare const codexAgentModels: ReadonlyArray<ModelDescriptor>;
|
|
9
|
+
export interface CodexAgentProviderConfig {
|
|
10
|
+
/** The person's Codex CLI; resolved from PATH when left out. */
|
|
11
|
+
readonly executable?: string;
|
|
12
|
+
/** Persisted provider-item model (`plugins.provider.items.codex-agent.model`). */
|
|
13
|
+
readonly model?: string;
|
|
14
|
+
readonly defaultModel?: string;
|
|
15
|
+
/** Runner workspace, supplied on activation. */
|
|
16
|
+
readonly cwd?: string;
|
|
17
|
+
/** How `codex app-server` is started; spawns the person's Codex by default. */
|
|
18
|
+
readonly startAppServer?: StartCodexAppServer;
|
|
19
|
+
/** The live Codex sessions; shared across the process by default. */
|
|
20
|
+
readonly sessions?: AgentSessionPool<CodexAgentSession>;
|
|
21
|
+
}
|
|
22
|
+
/** The live Codex sessions of this process, one per Moxxy conversation. */
|
|
23
|
+
export declare function codexSessions(): AgentSessionPool<CodexAgentSession>;
|
|
24
|
+
/**
|
|
25
|
+
* The Codex agent connection: Codex does each turn itself through
|
|
26
|
+
* `codex app-server`, unmodified (its instructions, config, tools, skills and
|
|
27
|
+
* MCP servers), on the person's ChatGPT sign-in. Moxxy adds only its own MCP
|
|
28
|
+
* server to the thread, and nothing to the prompt.
|
|
29
|
+
*/
|
|
30
|
+
export declare class CodexAgentProvider implements LLMProvider {
|
|
31
|
+
private readonly config;
|
|
32
|
+
readonly name = "codex-agent";
|
|
33
|
+
readonly agentName = "Codex";
|
|
34
|
+
/** Its own plan mode and goal: Moxxy shows the plan and ends the goal when the agent says so. */
|
|
35
|
+
readonly agentOwns: {
|
|
36
|
+
readonly plan: true;
|
|
37
|
+
readonly goal: true;
|
|
38
|
+
};
|
|
39
|
+
readonly models: readonly ModelDescriptor[];
|
|
40
|
+
readonly starterModel = "gpt-6-luna";
|
|
41
|
+
private readonly defaultModel;
|
|
42
|
+
private readonly start;
|
|
43
|
+
constructor(config?: CodexAgentProviderConfig);
|
|
44
|
+
agentStep(req: AgentStepRequest): AsyncIterable<AgentStepEvent>;
|
|
45
|
+
/**
|
|
46
|
+
* Work Codex left running (a subagent, a command in the background) ended
|
|
47
|
+
* between turns. Codex starts no turn then, so Moxxy opens one to show it.
|
|
48
|
+
*/
|
|
49
|
+
onAgentTurn(listener: (start: AgentTurnStart) => void): () => void;
|
|
50
|
+
/** What Codex's background work does between turns, recorded at once. */
|
|
51
|
+
onAgentActivity(listener: (activity: AgentActivity) => void): () => void;
|
|
52
|
+
/** Stop one work Codex runs in the background in the conversation. */
|
|
53
|
+
stopBackgroundWork(sessionId: string, workId: string): Promise<boolean>;
|
|
54
|
+
private sessions;
|
|
55
|
+
/** One-off text (summaries, skill drafts): an ephemeral read-only Codex thread, kept nowhere. */
|
|
56
|
+
stream(req: ProviderRequest): AsyncIterable<ProviderEvent>;
|
|
57
|
+
countTokens(req: Pick<ProviderRequest, 'model' | 'messages' | 'system' | 'tools'>): Promise<number>;
|
|
58
|
+
/** The conversation's running Codex, or a new one (resuming its thread) when there is none that fits. */
|
|
59
|
+
private lease;
|
|
60
|
+
}
|
|
61
|
+
export declare function createCodexAgentClient(config?: CodexAgentProviderConfig): LLMProvider;
|
|
62
|
+
//# sourceMappingURL=agent-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-provider.d.ts","sourceRoot":"","sources":["../src/agent-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EAErB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAkE,MAAM,6BAA6B,CAAC;AAE/H,OAAO,EAAE,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKjF,eAAO,MAAM,yBAAyB,gBAAgB,CAAC;AACvD,2GAA2G;AAC3G,eAAO,MAAM,yBAAyB,eAAe,CAAC;AAetD,sIAAsI;AACtI,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,eAAe,CAS3D,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IAC9C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,CAAC;CACzD;AAID,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,gBAAgB,CAAC,iBAAiB,CAAC,CAGnE;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IAUxC,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,QAAQ,CAAC,IAAI,iBAA2B;IACxC,QAAQ,CAAC,SAAS,WAAoB;IACtC,iGAAiG;IACjG,QAAQ,CAAC,SAAS;;;MAAuC;IACzD,QAAQ,CAAC,MAAM,6BAAoB;IACnC,QAAQ,CAAC,YAAY,gBAA6B;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;gBAEf,MAAM,GAAE,wBAA6B;IAK3D,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,aAAa,CAAC,cAAc,CAAC;IAgBtE;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAIlE,yEAAyE;IACzE,eAAe,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,IAAI,GAAG,MAAM,IAAI;IAIxE,sEAAsE;IAChE,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK7E,OAAO,CAAC,QAAQ;IAIhB,iGAAiG;IAC1F,MAAM,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAAC,aAAa,CAAC;IA8D3D,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAazG,yGAAyG;YAC3F,KAAK;CAkBpB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,wBAA6B,GAAG,WAAW,CAEzF"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { estimateTextTokens, } from '@moxxy/sdk';
|
|
2
|
+
import { AgentSessionPool, Inbox, JsonRpcLineClient, oneOffPrompt } from '@moxxy/agent-connection-kit';
|
|
3
|
+
import { CODEX_AGENT_NAME, CODEX_AGENT_PROVIDER_ID } from './constants.js';
|
|
4
|
+
import { CodexAgentSession } from './codex-session.js';
|
|
5
|
+
import { spawnCodexAppServer } from './executable.js';
|
|
6
|
+
import { toTokenUsage } from './translate.js';
|
|
7
|
+
export const CODEX_AGENT_DEFAULT_MODEL = 'gpt-6-astra';
|
|
8
|
+
/** What a new conversation starts on while the person chose no default: light, so it spares their plan. */
|
|
9
|
+
export const CODEX_AGENT_STARTER_MODEL = 'gpt-6-luna';
|
|
10
|
+
const NON_TEXT_BLOCK_TOKENS = 256;
|
|
11
|
+
const MAX_LIVE_CODEX_SESSIONS = 8;
|
|
12
|
+
const agentCapabilities = {
|
|
13
|
+
supportsTools: true,
|
|
14
|
+
supportsStreaming: true,
|
|
15
|
+
supportsImages: true,
|
|
16
|
+
supportsDocuments: false,
|
|
17
|
+
supportsAudio: false,
|
|
18
|
+
supportsReasoning: true,
|
|
19
|
+
supportsFast: true,
|
|
20
|
+
hostedTools: ['web_search'],
|
|
21
|
+
};
|
|
22
|
+
/** Models Codex offers on a ChatGPT sign-in, used until Codex's own `model/list` answered; Codex decides what the account may use. */
|
|
23
|
+
export const codexAgentModels = [
|
|
24
|
+
{ id: CODEX_AGENT_DEFAULT_MODEL, contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
25
|
+
// Codex 0.163's own catalog: 500k for 6.1 Sol, 272k for the rest (the API models have 1.05M).
|
|
26
|
+
{ id: 'gpt-6.1-sol', contextWindow: 500_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
27
|
+
{ id: 'gpt-6-sol', contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
28
|
+
{ id: 'gpt-6-luna', contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
29
|
+
{ id: 'gpt-5.6-sol', contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
30
|
+
{ id: 'gpt-5.6-terra', contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
31
|
+
{ id: 'gpt-5.6-luna', contextWindow: 272_000, maxOutputTokens: 128_000, ...agentCapabilities },
|
|
32
|
+
];
|
|
33
|
+
let sharedSessions;
|
|
34
|
+
/** The live Codex sessions of this process, one per Moxxy conversation. */
|
|
35
|
+
export function codexSessions() {
|
|
36
|
+
sharedSessions ??= new AgentSessionPool({ limit: MAX_LIVE_CODEX_SESSIONS });
|
|
37
|
+
return sharedSessions;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The Codex agent connection: Codex does each turn itself through
|
|
41
|
+
* `codex app-server`, unmodified (its instructions, config, tools, skills and
|
|
42
|
+
* MCP servers), on the person's ChatGPT sign-in. Moxxy adds only its own MCP
|
|
43
|
+
* server to the thread, and nothing to the prompt.
|
|
44
|
+
*/
|
|
45
|
+
export class CodexAgentProvider {
|
|
46
|
+
config;
|
|
47
|
+
name = CODEX_AGENT_PROVIDER_ID;
|
|
48
|
+
agentName = CODEX_AGENT_NAME;
|
|
49
|
+
/** Its own plan mode and goal: Moxxy shows the plan and ends the goal when the agent says so. */
|
|
50
|
+
agentOwns = { plan: true, goal: true };
|
|
51
|
+
models = codexAgentModels;
|
|
52
|
+
starterModel = CODEX_AGENT_STARTER_MODEL;
|
|
53
|
+
defaultModel;
|
|
54
|
+
start;
|
|
55
|
+
constructor(config = {}) {
|
|
56
|
+
this.config = config;
|
|
57
|
+
this.defaultModel = config.model ?? config.defaultModel ?? CODEX_AGENT_DEFAULT_MODEL;
|
|
58
|
+
this.start = config.startAppServer ?? spawnCodexAppServer(config.executable ?? 'codex');
|
|
59
|
+
}
|
|
60
|
+
async *agentStep(req) {
|
|
61
|
+
let lease;
|
|
62
|
+
try {
|
|
63
|
+
lease = await this.lease(req);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
if (!req.signal.aborted)
|
|
67
|
+
yield { type: 'error', message: messageOf(err), retryable: false };
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
yield* lease.session.turn(req);
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
if (lease.session.isAlive)
|
|
75
|
+
lease.release();
|
|
76
|
+
else
|
|
77
|
+
await lease.discard();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Work Codex left running (a subagent, a command in the background) ended
|
|
82
|
+
* between turns. Codex starts no turn then, so Moxxy opens one to show it.
|
|
83
|
+
*/
|
|
84
|
+
onAgentTurn(listener) {
|
|
85
|
+
return this.sessions().onAgentTurn(listener);
|
|
86
|
+
}
|
|
87
|
+
/** What Codex's background work does between turns, recorded at once. */
|
|
88
|
+
onAgentActivity(listener) {
|
|
89
|
+
return this.sessions().onActivity(listener);
|
|
90
|
+
}
|
|
91
|
+
/** Stop one work Codex runs in the background in the conversation. */
|
|
92
|
+
async stopBackgroundWork(sessionId, workId) {
|
|
93
|
+
const live = this.sessions().running(sessionId);
|
|
94
|
+
return live ? live.stopWork(workId) : false;
|
|
95
|
+
}
|
|
96
|
+
sessions() {
|
|
97
|
+
return this.config.sessions ?? codexSessions();
|
|
98
|
+
}
|
|
99
|
+
/** One-off text (summaries, skill drafts): an ephemeral read-only Codex thread, kept nowhere. */
|
|
100
|
+
async *stream(req) {
|
|
101
|
+
const model = req.model || this.defaultModel;
|
|
102
|
+
yield { type: 'message_start', model };
|
|
103
|
+
const cwd = this.config.cwd ?? process.cwd();
|
|
104
|
+
let usage;
|
|
105
|
+
let connection;
|
|
106
|
+
try {
|
|
107
|
+
connection = await this.start({ cwd });
|
|
108
|
+
const client = new JsonRpcLineClient({ readable: connection.readable, writable: connection.writable });
|
|
109
|
+
const notes = new Inbox();
|
|
110
|
+
client.onNotification((method, params) => notes.push({ method, params: (params ?? {}) }));
|
|
111
|
+
connection.readable.once('close', () => notes.push(null));
|
|
112
|
+
await client.request('initialize', { clientInfo: { name: 'moxxy', title: 'Moxxy', version: '1' }, capabilities: { experimentalApi: true } });
|
|
113
|
+
client.notify('initialized');
|
|
114
|
+
const { system, prompt } = oneOffPrompt(req);
|
|
115
|
+
const thread = await client.request('thread/start', {
|
|
116
|
+
cwd,
|
|
117
|
+
ephemeral: true,
|
|
118
|
+
approvalPolicy: 'never',
|
|
119
|
+
sandbox: 'read-only',
|
|
120
|
+
model,
|
|
121
|
+
...(system ? { developerInstructions: system } : {}),
|
|
122
|
+
});
|
|
123
|
+
const started = await client.request('turn/start', { threadId: thread.thread.id, input: [{ type: 'text', text: prompt, text_elements: [] }] }, req.signal);
|
|
124
|
+
const stop = () => void client.request('turn/interrupt', { threadId: thread.thread.id, turnId: started.turn.id }).catch(() => undefined);
|
|
125
|
+
req.signal?.addEventListener('abort', stop, { once: true });
|
|
126
|
+
try {
|
|
127
|
+
for (;;) {
|
|
128
|
+
const note = await notes.next();
|
|
129
|
+
if (note === null)
|
|
130
|
+
throw new Error('Codex stopped.');
|
|
131
|
+
const { method, params } = note;
|
|
132
|
+
if (params.turnId !== undefined && params.turnId !== started.turn.id)
|
|
133
|
+
continue;
|
|
134
|
+
if (method === 'item/agentMessage/delta' && typeof params.delta === 'string')
|
|
135
|
+
yield { type: 'text_delta', delta: params.delta };
|
|
136
|
+
else if (method === 'thread/tokenUsage/updated') {
|
|
137
|
+
const last = params.tokenUsage?.last;
|
|
138
|
+
if (last)
|
|
139
|
+
usage = toTokenUsage(last);
|
|
140
|
+
}
|
|
141
|
+
else if (method === 'turn/completed') {
|
|
142
|
+
const turn = params.turn;
|
|
143
|
+
if (!turn || turn.id !== started.turn.id)
|
|
144
|
+
continue;
|
|
145
|
+
if (turn.status === 'failed') {
|
|
146
|
+
yield { type: 'error', message: `Codex: ${turn.error?.message ?? 'the turn failed'}`, retryable: false };
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
req.signal?.removeEventListener('abort', stop);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
if (!req.signal?.aborted)
|
|
159
|
+
yield { type: 'error', message: messageOf(err), retryable: false };
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
connection?.close();
|
|
164
|
+
}
|
|
165
|
+
yield { type: 'message_end', stopReason: 'end_turn', ...(usage ? { usage } : {}) };
|
|
166
|
+
}
|
|
167
|
+
async countTokens(req) {
|
|
168
|
+
let text = req.system ?? '';
|
|
169
|
+
let nonTextBlocks = 0;
|
|
170
|
+
for (const message of req.messages) {
|
|
171
|
+
for (const block of message.content) {
|
|
172
|
+
if (block.type === 'text')
|
|
173
|
+
text += block.text;
|
|
174
|
+
else
|
|
175
|
+
nonTextBlocks += 1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const tool of req.tools ?? [])
|
|
179
|
+
text += tool.name + tool.description;
|
|
180
|
+
return estimateTextTokens(text) + nonTextBlocks * NON_TEXT_BLOCK_TOKENS;
|
|
181
|
+
}
|
|
182
|
+
/** The conversation's running Codex, or a new one (resuming its thread) when there is none that fits. */
|
|
183
|
+
async lease(req) {
|
|
184
|
+
const settings = {
|
|
185
|
+
start: this.start,
|
|
186
|
+
cwd: req.cwd,
|
|
187
|
+
...(req.model ? { model: req.model } : {}),
|
|
188
|
+
tools: req.allTools ?? req.tools,
|
|
189
|
+
...(req.skills ? { skills: req.skills } : {}),
|
|
190
|
+
...(req.resumeSessionId ? { resume: req.resumeSessionId } : {}),
|
|
191
|
+
onAgentTurn: (name, workId) => this.sessions().agentTurn({ sessionId: req.sessionId, name, ...(workId ? { workId } : {}) }),
|
|
192
|
+
onActivity: (events) => this.sessions().activity({ sessionId: req.sessionId, events }),
|
|
193
|
+
};
|
|
194
|
+
const sessions = this.sessions();
|
|
195
|
+
const create = () => CodexAgentSession.start(settings);
|
|
196
|
+
const lease = await sessions.acquire(req.sessionId, { signal: req.signal, create });
|
|
197
|
+
if (lease.session.isAlive && lease.session.fits(settings))
|
|
198
|
+
return lease;
|
|
199
|
+
await lease.discard();
|
|
200
|
+
return sessions.acquire(req.sessionId, { signal: req.signal, create });
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
export function createCodexAgentClient(config = {}) {
|
|
204
|
+
return new CodexAgentProvider(config);
|
|
205
|
+
}
|
|
206
|
+
function messageOf(err) {
|
|
207
|
+
return err instanceof Error ? err.message : String(err);
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=agent-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-provider.js","sourceRoot":"","sources":["../src/agent-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import type { Readable, Writable } from 'node:stream';
|
|
2
|
+
import type { AgentStepEvent, AgentStepRequest, Skill, ToolDef } from '@moxxy/sdk';
|
|
3
|
+
import { type LiveSession } from '@moxxy/agent-connection-kit';
|
|
4
|
+
import type { CodexApprovalPolicy, CodexSandboxPolicy } from './protocol.js';
|
|
5
|
+
/** A running `codex app-server`: its stdout, stdin and stderr. */
|
|
6
|
+
export interface CodexConnection {
|
|
7
|
+
readonly readable: Readable;
|
|
8
|
+
readonly writable: Writable;
|
|
9
|
+
readonly stderr?: Readable;
|
|
10
|
+
close(): void;
|
|
11
|
+
}
|
|
12
|
+
export type StartCodexAppServer = (opts: {
|
|
13
|
+
readonly cwd: string;
|
|
14
|
+
}) => Promise<CodexConnection>;
|
|
15
|
+
export interface CodexSessionSettings {
|
|
16
|
+
readonly start: StartCodexAppServer;
|
|
17
|
+
readonly cwd: string;
|
|
18
|
+
/** The conversation's Codex thread from an earlier process, to resume. */
|
|
19
|
+
readonly resume?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The model the turn runs. The thread opens on it: one opened on the config's
|
|
22
|
+
* model and switched before the turn carries Codex's model-switch
|
|
23
|
+
* instructions in every request after.
|
|
24
|
+
*/
|
|
25
|
+
readonly model?: string;
|
|
26
|
+
/** Every Moxxy tool of the conversation: Codex reads the list once, as the thread opens or resumes. */
|
|
27
|
+
readonly tools?: ReadonlyArray<ToolDef>;
|
|
28
|
+
/** The conversation's Moxxy skills: Codex reads those meant for it through one more Moxxy tool, listed with the tools. */
|
|
29
|
+
readonly skills?: ReadonlyArray<Skill>;
|
|
30
|
+
/** Work Codex left running ended while no Moxxy turn runs; `name` says what, `workId` which work. Codex itself starts no turn then. */
|
|
31
|
+
readonly onAgentTurn?: (name: string, workId?: string) => void;
|
|
32
|
+
/** What Codex's background work did, for the conversation to record at once: its list, a command's end, a subagent's steps after its turn. */
|
|
33
|
+
readonly onActivity?: (events: ReadonlyArray<AgentStepEvent>) => void;
|
|
34
|
+
}
|
|
35
|
+
interface Policy {
|
|
36
|
+
readonly approvalPolicy: CodexApprovalPolicy;
|
|
37
|
+
readonly sandbox: CodexSandboxPolicy;
|
|
38
|
+
}
|
|
39
|
+
export declare function isAuto(policy: Policy): boolean;
|
|
40
|
+
export declare function toolsLentToCodex(tools: ReadonlyArray<ToolDef>): ToolDef[];
|
|
41
|
+
/**
|
|
42
|
+
* One running `codex app-server` with one thread for one Moxxy conversation.
|
|
43
|
+
* Every message the person sends is the next turn of the same thread, so
|
|
44
|
+
* Codex keeps its context, tools and goal between turns. Codex's
|
|
45
|
+
* notifications and its requests to Moxxy (approvals, questions) and Moxxy
|
|
46
|
+
* tool calls over MCP are queued together and handled in order, so the log
|
|
47
|
+
* shows a call before the decision about it.
|
|
48
|
+
*/
|
|
49
|
+
export declare class CodexAgentSession implements LiveSession {
|
|
50
|
+
readonly settings: CodexSessionSettings;
|
|
51
|
+
private readonly mcp;
|
|
52
|
+
private readonly connection;
|
|
53
|
+
private readonly inbox;
|
|
54
|
+
private readonly client;
|
|
55
|
+
private alive;
|
|
56
|
+
private closed;
|
|
57
|
+
private inTurn;
|
|
58
|
+
/**
|
|
59
|
+
* The conversation has not been told how Codex runs yet. Only a thread
|
|
60
|
+
* started for it does that: a conversation going on keeps the auto-approve
|
|
61
|
+
* the person chose, which a new process resuming the thread knows nothing of.
|
|
62
|
+
*/
|
|
63
|
+
private fresh;
|
|
64
|
+
private threadId;
|
|
65
|
+
/** How the person's Codex config runs the thread; restored when Moxxy no longer overrides it. */
|
|
66
|
+
private original;
|
|
67
|
+
private originalTier;
|
|
68
|
+
private originalReviewer;
|
|
69
|
+
/** `model_reasoning_summary` from the person's config: `null` unset, `undefined` unread. */
|
|
70
|
+
private ownSummary;
|
|
71
|
+
private current;
|
|
72
|
+
/** Why the person declined, for Codex's next message when its turn could not take it. */
|
|
73
|
+
private pendingNotes;
|
|
74
|
+
/** The question Codex asked while it works, open until answered, closed, or its turn ends. */
|
|
75
|
+
private asked;
|
|
76
|
+
/** The thread is new while the conversation may already have run: its first message carries the conversation so far. */
|
|
77
|
+
private newThread;
|
|
78
|
+
private goal;
|
|
79
|
+
/**
|
|
80
|
+
* How Codex asks while auto-approve is off: ASKING on a Codex set up to run
|
|
81
|
+
* without asking, else the person's own setup, or tighter if something
|
|
82
|
+
* outside Moxxy tightened it since (Moxxy never loosens that back by itself).
|
|
83
|
+
*/
|
|
84
|
+
private asking;
|
|
85
|
+
/** Something outside Moxxy made Codex ask while auto-approve was on; the switch shows it on the next turn. */
|
|
86
|
+
private turnedOffElsewhere;
|
|
87
|
+
/** Moxxy set back a change made outside it between turns; the next turn says so. */
|
|
88
|
+
private restoredElsewhere;
|
|
89
|
+
/** Codex turns that belong to the Moxxy turn running now. */
|
|
90
|
+
private readonly myTurns;
|
|
91
|
+
/** The Codex turn each command still running started in, by item id: what Stop ends. */
|
|
92
|
+
private readonly commandTurns;
|
|
93
|
+
/** Subagents Codex started; they work in threads of their own and may outlive a turn. */
|
|
94
|
+
private readonly subagents;
|
|
95
|
+
/** Calls Codex left running when its turn ended, by item id; their end is shown when it comes. */
|
|
96
|
+
private readonly leftRunning;
|
|
97
|
+
/** What that work did after its turn, for the turn opened to show it (or the person's next turn). */
|
|
98
|
+
private late;
|
|
99
|
+
/** A turn was asked of the conversation to show what finished after Codex's turn. */
|
|
100
|
+
private agentTurnPending;
|
|
101
|
+
/** The background work last reported, to report it again only when it changes. */
|
|
102
|
+
private shownWork;
|
|
103
|
+
/** Background work the person stopped: its end is recorded, but asks no turn of the conversation. */
|
|
104
|
+
private readonly stopping;
|
|
105
|
+
/** The Moxxy tools Codex listed as the thread opened, the same for every turn. */
|
|
106
|
+
private listed;
|
|
107
|
+
/** Names of Codex's own skills, read as the thread opens. */
|
|
108
|
+
private ownSkills;
|
|
109
|
+
/** Codex's own MCP servers that are on: Moxxy's server of the same name is left to Codex's. */
|
|
110
|
+
private ownMcpServers;
|
|
111
|
+
/** The Moxxy skills Codex listed with the tools; their instructions are read fresh at each call. */
|
|
112
|
+
private offered;
|
|
113
|
+
private activeTurn;
|
|
114
|
+
private lastError;
|
|
115
|
+
private lastErrorInfo;
|
|
116
|
+
/** The account limit Codex last reported; its updates leave out what has not changed. */
|
|
117
|
+
private limit;
|
|
118
|
+
private stderr;
|
|
119
|
+
static start(settings: CodexSessionSettings): Promise<CodexAgentSession>;
|
|
120
|
+
private constructor();
|
|
121
|
+
get isAlive(): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Whether this Codex was started where the turn runs (a running thread
|
|
124
|
+
* cannot move) and listed the tools the conversation has now: Codex reads
|
|
125
|
+
* them only as a thread opens, so other tools mean resuming it in a new Codex.
|
|
126
|
+
*/
|
|
127
|
+
fits(settings: Pick<CodexSessionSettings, 'cwd' | 'tools' | 'skills'>): boolean;
|
|
128
|
+
private lent;
|
|
129
|
+
private skillsFor;
|
|
130
|
+
turn(req: AgentStepRequest): AsyncGenerator<AgentStepEvent>;
|
|
131
|
+
/** Stop one work Codex runs in the background (`AgentBackgroundWork.id`); `false` when Codex runs no such work. */
|
|
132
|
+
stopWork(workId: string): Promise<boolean>;
|
|
133
|
+
close(): Promise<void>;
|
|
134
|
+
/** Codex's own skills that are switched on: a Moxxy skill of the same name is left to Codex's. */
|
|
135
|
+
private ownSkillNames;
|
|
136
|
+
private open;
|
|
137
|
+
/** What the thread should run with for this turn's mode, model and auto-approve. */
|
|
138
|
+
private wanted;
|
|
139
|
+
/** Change on the thread only what differs; nothing is written to the person's Codex config. */
|
|
140
|
+
private apply;
|
|
141
|
+
/** Start the turn: a goal Codex works on by itself, or the person's message. */
|
|
142
|
+
private begin;
|
|
143
|
+
private startTurn;
|
|
144
|
+
private clearGoal;
|
|
145
|
+
/** Read Codex until the Moxxy turn is over: its turn ended, or its goal stopped running. */
|
|
146
|
+
private read;
|
|
147
|
+
/**
|
|
148
|
+
* Show Codex's question at once and let Codex work on: Codex asks in a
|
|
149
|
+
* message and does not wait, so the answer goes into its running turn, or
|
|
150
|
+
* waits for its turn to end when it ended on the question.
|
|
151
|
+
*/
|
|
152
|
+
private askWhileWorking;
|
|
153
|
+
/**
|
|
154
|
+
* The person's answer goes into Codex's running turn once Codex has gone on
|
|
155
|
+
* from the question; until then Codex may still end its turn on it, and the
|
|
156
|
+
* answer is its next message. A question closed unanswered is let go.
|
|
157
|
+
*/
|
|
158
|
+
private steerAnswer;
|
|
159
|
+
/** What Codex asked of Moxxy, answered with the turn's host. */
|
|
160
|
+
private answer;
|
|
161
|
+
private decide;
|
|
162
|
+
/**
|
|
163
|
+
* Codex's answer to an approval is a bare `decline`, so the person's reason
|
|
164
|
+
* goes into its running turn (`turn/steer`), or its next message when the
|
|
165
|
+
* turn can no longer take input.
|
|
166
|
+
*/
|
|
167
|
+
private explainDecline;
|
|
168
|
+
private steerPending;
|
|
169
|
+
private interrupt;
|
|
170
|
+
/**
|
|
171
|
+
* Codex leaves an interrupted turn's commands running, so Stop ends the ones
|
|
172
|
+
* these turns started. What an earlier turn left running (a dev server) is
|
|
173
|
+
* not this turn's to stop.
|
|
174
|
+
*/
|
|
175
|
+
private endCommandsOf;
|
|
176
|
+
/** End the command a call left running, found by the item that started it; `false` when no such command runs. */
|
|
177
|
+
private terminateCommand;
|
|
178
|
+
/** End every background command of the thread whose item `pick` chooses; how many it ended. */
|
|
179
|
+
private terminateWhere;
|
|
180
|
+
/** Which Codex turn started each command, noted as Codex reports it, ahead of the turn reading it. */
|
|
181
|
+
private noteCommand;
|
|
182
|
+
private belongsHere;
|
|
183
|
+
private onNotification;
|
|
184
|
+
/**
|
|
185
|
+
* A change of the thread's approvals made without Moxxy (another client, a
|
|
186
|
+
* hook): only the person loosens them. A change that holds Codex back at
|
|
187
|
+
* least as much is `kept` (`turned-off` when auto-approve was on), a looser
|
|
188
|
+
* one is `loosened` and set back. Codex reports Moxxy's own changes too; those
|
|
189
|
+
* match what Moxxy set and are passed over.
|
|
190
|
+
*/
|
|
191
|
+
private noteSettings;
|
|
192
|
+
/** Put the thread's approvals back as Moxxy last set them. */
|
|
193
|
+
private restore;
|
|
194
|
+
/**
|
|
195
|
+
* Between turns: what Codex's background work does. Codex starts no turn
|
|
196
|
+
* when it ends (0.155.1), so the conversation is asked for one to show it:
|
|
197
|
+
* a subagent's tools and answer, a command's output.
|
|
198
|
+
*/
|
|
199
|
+
private noteLate;
|
|
200
|
+
/**
|
|
201
|
+
* The end of a call Codex left running, as a call of its own beside the one
|
|
202
|
+
* shown running; `undefined` for anything else. Its end is recorded for the
|
|
203
|
+
* agents panel at once, with what the command printed last.
|
|
204
|
+
*/
|
|
205
|
+
private endOfLeftRunning;
|
|
206
|
+
private askForTurn;
|
|
207
|
+
/** What Codex runs in the background now: the commands its turns left running and the subagents still working. Reported when it changes. */
|
|
208
|
+
private reportWork;
|
|
209
|
+
private workNow;
|
|
210
|
+
private report;
|
|
211
|
+
private takeLate;
|
|
212
|
+
/** Keep the goal's state, whether or not a turn is reading. */
|
|
213
|
+
private noteGoal;
|
|
214
|
+
private ended;
|
|
215
|
+
private endedMessage;
|
|
216
|
+
/** Answer whatever is still queued once no turn can: Codex must never wait on Moxxy forever. */
|
|
217
|
+
private dismissQueued;
|
|
218
|
+
}
|
|
219
|
+
export {};
|
|
220
|
+
//# sourceMappingURL=codex-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-session.d.ts","sourceRoot":"","sources":["../src/codex-session.ts"],"names":[],"mappings":"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"}
|