pi-openai-codex-compat 0.0.3 → 0.0.4
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/CHANGELOG.md +36 -0
- package/README.md +71 -37
- package/extensions/openai-codex-compat/apply-patch-diff-render.ts +6 -2
- package/extensions/openai-codex-compat/apply-patch-engine.ts +89 -5
- package/extensions/openai-codex-compat/codex-cache-diagnostics.ts +97 -0
- package/extensions/openai-codex-compat/codex-installation.ts +51 -0
- package/extensions/openai-codex-compat/codex-metadata.ts +139 -0
- package/extensions/openai-codex-compat/codex-protocol.ts +1 -0
- package/extensions/openai-codex-compat/codex-provider.ts +524 -58
- package/extensions/openai-codex-compat/codex-stream.ts +52 -26
- package/extensions/openai-codex-compat/codex-thread-lineage.ts +156 -0
- package/extensions/openai-codex-compat/codex-transport.ts +1129 -86
- package/extensions/openai-codex-compat/compaction-checkpoint.ts +2 -2
- package/extensions/openai-codex-compat/config.ts +13 -0
- package/extensions/openai-codex-compat/index.ts +6 -0
- package/extensions/openai-codex-compat/namespaced-tools.ts +2 -0
- package/extensions/openai-codex-compat/output-limit-continuation.ts +151 -0
- package/extensions/openai-codex-compat/remote-compaction.ts +13 -0
- package/extensions/openai-codex-compat/request-options.ts +2 -2
- package/extensions/openai-codex-compat/responses-lite.ts +147 -0
- package/extensions/openai-codex-compat/settings-pane.ts +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { uuidv7 } from "@earendil-works/pi-ai";
|
|
2
|
+
import { isObject, type JsonRecord } from "./codex-protocol.ts";
|
|
3
|
+
|
|
4
|
+
export const CODEX_TURN_METADATA_HEADER = "x-codex-turn-metadata";
|
|
5
|
+
export const CODEX_INSTALLATION_ID_METADATA_KEY = "x-codex-installation-id";
|
|
6
|
+
export const CODEX_WINDOW_ID_HEADER = "x-codex-window-id";
|
|
7
|
+
|
|
8
|
+
export type CodexRequestKind = "turn" | "prewarm" | "compaction";
|
|
9
|
+
|
|
10
|
+
export type CodexCompactionMetadata = {
|
|
11
|
+
trigger: "manual" | "auto";
|
|
12
|
+
reason: "user_requested" | "context_limit" | "model_downshift" | "comp_hash_changed";
|
|
13
|
+
implementation: "responses" | "responses_compaction_v2" | "responses_compact";
|
|
14
|
+
phase: "standalone_turn" | "pre_turn" | "mid_turn";
|
|
15
|
+
strategy: "memento" | "prefix_compaction";
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type CodexMetadataRequest =
|
|
19
|
+
| { kind: "turn" | "prewarm" }
|
|
20
|
+
| { kind: "compaction"; compaction: CodexCompactionMetadata };
|
|
21
|
+
|
|
22
|
+
export type CodexMetadataIdentity = {
|
|
23
|
+
installationId: string;
|
|
24
|
+
threadId?: string;
|
|
25
|
+
forkedFromThreadId?: string;
|
|
26
|
+
windowNumber?: number;
|
|
27
|
+
turnStartedAtUnixMs?: number;
|
|
28
|
+
threadSource?: string;
|
|
29
|
+
sandbox?: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const EPHEMERAL_METADATA_IDENTITY: CodexMetadataIdentity = { installationId: uuidv7() };
|
|
33
|
+
|
|
34
|
+
type CodexClientMetadata = {
|
|
35
|
+
[CODEX_INSTALLATION_ID_METADATA_KEY]: string;
|
|
36
|
+
session_id: string;
|
|
37
|
+
thread_id: string;
|
|
38
|
+
turn_id: string;
|
|
39
|
+
[CODEX_WINDOW_ID_HEADER]: string;
|
|
40
|
+
[CODEX_TURN_METADATA_HEADER]: string;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export function responsesCompactionV2Metadata(
|
|
44
|
+
trigger: CodexCompactionMetadata["trigger"],
|
|
45
|
+
reason: CodexCompactionMetadata["reason"],
|
|
46
|
+
phase: CodexCompactionMetadata["phase"],
|
|
47
|
+
): CodexCompactionMetadata {
|
|
48
|
+
return {
|
|
49
|
+
trigger,
|
|
50
|
+
reason,
|
|
51
|
+
implementation: "responses_compaction_v2",
|
|
52
|
+
phase,
|
|
53
|
+
strategy: "memento",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function windowId(sessionId: string, identity: CodexMetadataIdentity): string {
|
|
58
|
+
return `${identity.threadId ?? sessionId}:${identity.windowNumber ?? 0}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function turnMetadata(
|
|
62
|
+
sessionId: string,
|
|
63
|
+
turnId: string,
|
|
64
|
+
request: CodexMetadataRequest,
|
|
65
|
+
identity: CodexMetadataIdentity,
|
|
66
|
+
): string {
|
|
67
|
+
const threadId = identity.threadId ?? sessionId;
|
|
68
|
+
return JSON.stringify({
|
|
69
|
+
installation_id: identity.installationId,
|
|
70
|
+
session_id: sessionId,
|
|
71
|
+
thread_id: threadId,
|
|
72
|
+
turn_id: turnId,
|
|
73
|
+
window_id: windowId(sessionId, identity),
|
|
74
|
+
request_kind: request.kind,
|
|
75
|
+
...(identity.forkedFromThreadId ? { forked_from_thread_id: identity.forkedFromThreadId } : {}),
|
|
76
|
+
...(identity.threadSource ? { thread_source: identity.threadSource } : {}),
|
|
77
|
+
...(identity.sandbox ? { sandbox: identity.sandbox } : {}),
|
|
78
|
+
...(identity.turnStartedAtUnixMs === undefined
|
|
79
|
+
? {}
|
|
80
|
+
: { turn_started_at_unix_ms: identity.turnStartedAtUnixMs }),
|
|
81
|
+
...(request.kind === "compaction" ? { compaction: request.compaction } : {}),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function codexClientMetadata(
|
|
86
|
+
sessionId: string | undefined,
|
|
87
|
+
request: CodexMetadataRequest,
|
|
88
|
+
turnId = uuidv7(),
|
|
89
|
+
identity: CodexMetadataIdentity = EPHEMERAL_METADATA_IDENTITY,
|
|
90
|
+
): CodexClientMetadata | undefined {
|
|
91
|
+
if (!sessionId) return undefined;
|
|
92
|
+
const threadId = identity.threadId ?? sessionId;
|
|
93
|
+
return {
|
|
94
|
+
[CODEX_INSTALLATION_ID_METADATA_KEY]: identity.installationId,
|
|
95
|
+
session_id: sessionId,
|
|
96
|
+
thread_id: threadId,
|
|
97
|
+
turn_id: turnId,
|
|
98
|
+
[CODEX_WINDOW_ID_HEADER]: windowId(sessionId, identity),
|
|
99
|
+
[CODEX_TURN_METADATA_HEADER]: turnMetadata(sessionId, turnId, request, identity),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function withCodexRequestMetadata(
|
|
104
|
+
payload: JsonRecord,
|
|
105
|
+
sessionId: string | undefined,
|
|
106
|
+
request: CodexMetadataRequest,
|
|
107
|
+
turnId?: string,
|
|
108
|
+
identity: CodexMetadataIdentity = EPHEMERAL_METADATA_IDENTITY,
|
|
109
|
+
): JsonRecord {
|
|
110
|
+
const metadata = codexClientMetadata(sessionId, request, turnId, identity);
|
|
111
|
+
if (!metadata) {
|
|
112
|
+
const result = structuredClone(payload);
|
|
113
|
+
delete result["client_metadata"];
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
const existing = isObject(payload["client_metadata"]) ? payload["client_metadata"] : {};
|
|
117
|
+
return {
|
|
118
|
+
...payload,
|
|
119
|
+
client_metadata: {
|
|
120
|
+
...existing,
|
|
121
|
+
...metadata,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function applyCodexMetadataHeaders(headers: Headers, payload: JsonRecord): void {
|
|
127
|
+
const metadata = payload["client_metadata"];
|
|
128
|
+
if (!isObject(metadata)) return;
|
|
129
|
+
|
|
130
|
+
if (typeof metadata["thread_id"] === "string") {
|
|
131
|
+
headers.set("thread-id", metadata["thread_id"]);
|
|
132
|
+
}
|
|
133
|
+
if (typeof metadata[CODEX_WINDOW_ID_HEADER] === "string") {
|
|
134
|
+
headers.set(CODEX_WINDOW_ID_HEADER, metadata[CODEX_WINDOW_ID_HEADER]);
|
|
135
|
+
}
|
|
136
|
+
if (typeof metadata[CODEX_TURN_METADATA_HEADER] === "string") {
|
|
137
|
+
headers.set(CODEX_TURN_METADATA_HEADER, metadata[CODEX_TURN_METADATA_HEADER]);
|
|
138
|
+
}
|
|
139
|
+
}
|