@oai404iao/pi-codex-runtime 0.1.0-alpha.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.
- package/LICENSE +28 -0
- package/LICENSES/Apache-2.0.txt +201 -0
- package/LICENSES/OpenAI-Codex-NOTICE.txt +6 -0
- package/README.md +26 -0
- package/THIRD_PARTY_NOTICES.md +19 -0
- package/config.schema.json +174 -0
- package/models.schema.json +217 -0
- package/package.json +68 -0
- package/provenance/openai-codex-eb9dceba-reserved-tools.json +140 -0
- package/src/activation.ts +56 -0
- package/src/broker.ts +133 -0
- package/src/capabilities.ts +146 -0
- package/src/codex-http.ts +133 -0
- package/src/codex-identity-extension.ts +341 -0
- package/src/codex-request-profile.ts +45 -0
- package/src/codex-reserved-tools.ts +33 -0
- package/src/codex-wire-identity.ts +596 -0
- package/src/extension/provider-presentation.ts +11 -0
- package/src/glyphs.ts +70 -0
- package/src/index.ts +4 -0
- package/src/model-catalog/catalog.ts +636 -0
- package/src/model-catalog/default-models.json +252 -0
- package/src/model-catalog/runtime.ts +113 -0
- package/src/model-catalog/types.ts +95 -0
- package/src/provider-headers.ts +54 -0
- package/src/providers/openai-codex/stream-effects.ts +21 -0
- package/src/providers/openai-codex/types.ts +155 -0
- package/src/providers/responses/citations.ts +105 -0
- package/src/providers/responses/history.ts +144 -0
- package/src/providers/responses/items.ts +87 -0
- package/src/providers/responses/markdown.ts +92 -0
- package/src/providers/responses/messages.ts +169 -0
- package/src/providers/responses/signatures.ts +102 -0
- package/src/providers/responses/stream-state.ts +99 -0
- package/src/providers/responses/stream.ts +386 -0
- package/src/providers/responses/text-renderer.ts +147 -0
- package/src/providers/responses/text.ts +32 -0
- package/src/providers/responses/tool-identity.ts +25 -0
- package/src/providers/responses/tools.ts +14 -0
- package/src/providers/responses/types.ts +113 -0
- package/src/providers/responses/usage.ts +53 -0
- package/src/reserved-tools/image-generation.ts +53 -0
- package/src/reserved-tools/types.ts +32 -0
- package/src/reserved-tools/web-search.ts +269 -0
- package/src/session-claims.ts +19 -0
- package/src/settings.ts +247 -0
- package/src/subagent-inline.ts +8 -0
- package/src/tool-activation.ts +89 -0
- package/src/utils/theme.ts +7 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://unpkg.com/@oai404iao/pi-codex-minimal-tools@1/models.schema.json",
|
|
4
|
+
"title": "@oai404iao/pi-codex-minimal-tools model catalog overrides",
|
|
5
|
+
"description": "Per-model Codex protocol and tool capability profiles. User entries override bundled entries by exact provider/model id.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["version", "models"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "JSON Schema URL used by editors for validation and completion.",
|
|
13
|
+
"default": "https://unpkg.com/@oai404iao/pi-codex-minimal-tools@1/models.schema.json"
|
|
14
|
+
},
|
|
15
|
+
"version": {
|
|
16
|
+
"const": 1,
|
|
17
|
+
"description": "Model catalog format version.",
|
|
18
|
+
"default": 1
|
|
19
|
+
},
|
|
20
|
+
"models": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"description": "Exact per-model profiles. Duplicate ids in one user file are rejected.",
|
|
23
|
+
"items": {
|
|
24
|
+
"$ref": "#/$defs/model"
|
|
25
|
+
},
|
|
26
|
+
"default": []
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"$defs": {
|
|
30
|
+
"modelId": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"pattern": "^[^\\s/]+/\\S+$"
|
|
33
|
+
},
|
|
34
|
+
"model": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"required": ["id"],
|
|
38
|
+
"properties": {
|
|
39
|
+
"id": {
|
|
40
|
+
"$ref": "#/$defs/modelId",
|
|
41
|
+
"description": "Exact provider/model id, for example openai/gpt-5.5."
|
|
42
|
+
},
|
|
43
|
+
"extends": {
|
|
44
|
+
"$ref": "#/$defs/modelId",
|
|
45
|
+
"description": "Optional parent profile. The parent is deep-merged first; arrays are replaced."
|
|
46
|
+
},
|
|
47
|
+
"enabled": {
|
|
48
|
+
"type": "boolean",
|
|
49
|
+
"description": "Whether this profile can activate extension behavior."
|
|
50
|
+
},
|
|
51
|
+
"responses": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"additionalProperties": false,
|
|
54
|
+
"properties": {
|
|
55
|
+
"providerShim": {
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"description": "Use this extension's Codex Responses serializer/parser. The Pi model must use api openai-responses or openai-codex-responses."
|
|
58
|
+
},
|
|
59
|
+
"endpoint": {
|
|
60
|
+
"enum": ["auto", "openai", "codex"],
|
|
61
|
+
"description": "Endpoint and authentication shape."
|
|
62
|
+
},
|
|
63
|
+
"mode": {
|
|
64
|
+
"enum": ["standard", "lite"],
|
|
65
|
+
"description": "Standard Responses or the internal Codex Responses Lite envelope."
|
|
66
|
+
},
|
|
67
|
+
"reasoningSummary": {
|
|
68
|
+
"enum": ["auto", "concise", "detailed", "none"],
|
|
69
|
+
"description": "Reasoning summary mode. none omits reasoning.summary; absent defaults to auto in Standard mode and none in Lite mode."
|
|
70
|
+
},
|
|
71
|
+
"systemPromptPlacement": {
|
|
72
|
+
"enum": ["instructions", "developer"],
|
|
73
|
+
"description": "Standard-mode prompt placement. Lite always uses a developer message."
|
|
74
|
+
},
|
|
75
|
+
"transport": {
|
|
76
|
+
"enum": ["sse", "websocket", "websocket-cached", "auto"],
|
|
77
|
+
"description": "Responses transport and continuation strategy."
|
|
78
|
+
},
|
|
79
|
+
"websocketPrewarm": {
|
|
80
|
+
"type": "boolean",
|
|
81
|
+
"description": "At session startup, schedule one best-effort generate:false prewarm request containing only the stable system/tool envelope."
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"tools": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"properties": {
|
|
89
|
+
"parallelCalls": {
|
|
90
|
+
"type": "boolean",
|
|
91
|
+
"description": "Whether the request permits parallel tool calls. Lite always forces false."
|
|
92
|
+
},
|
|
93
|
+
"applyPatch": {
|
|
94
|
+
"description": "Disable apply_patch, expose a JSON function tool, or use the Codex freeform custom tool.",
|
|
95
|
+
"enum": [false, "function", "custom"],
|
|
96
|
+
"enumDescriptions": [
|
|
97
|
+
"Do not expose an apply_patch tool.",
|
|
98
|
+
"Expose apply_patch as a regular JSON function tool.",
|
|
99
|
+
"Expose apply_patch as the Codex freeform custom tool."
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
"webSearch": {
|
|
103
|
+
"description": "Disable web search or choose hosted Responses search versus standalone Codex web.run.",
|
|
104
|
+
"if": {
|
|
105
|
+
"type": "boolean"
|
|
106
|
+
},
|
|
107
|
+
"then": {
|
|
108
|
+
"const": false
|
|
109
|
+
},
|
|
110
|
+
"else": {
|
|
111
|
+
"type": "object"
|
|
112
|
+
},
|
|
113
|
+
"defaultSnippets": [
|
|
114
|
+
{
|
|
115
|
+
"label": "Disable web search",
|
|
116
|
+
"description": "Do not expose web search for this model.",
|
|
117
|
+
"body": false
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"label": "Hosted web search",
|
|
121
|
+
"description": "Use the server-executed Responses web_search tool.",
|
|
122
|
+
"body": {
|
|
123
|
+
"implementation": "hosted"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"label": "Standalone web search",
|
|
128
|
+
"description": "Expose web.run and call the Codex alpha/search endpoint.",
|
|
129
|
+
"body": {
|
|
130
|
+
"implementation": "standalone"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
"additionalProperties": false,
|
|
135
|
+
"required": ["implementation"],
|
|
136
|
+
"properties": {
|
|
137
|
+
"implementation": {
|
|
138
|
+
"enum": ["hosted", "standalone"],
|
|
139
|
+
"enumDescriptions": [
|
|
140
|
+
"Use the server-executed Responses web_search tool.",
|
|
141
|
+
"Expose web.run and call the Codex alpha/search endpoint."
|
|
142
|
+
]
|
|
143
|
+
},
|
|
144
|
+
"contentTypes": {
|
|
145
|
+
"type": "array",
|
|
146
|
+
"description": "Search modalities advertised or accepted by this model.",
|
|
147
|
+
"minItems": 1,
|
|
148
|
+
"items": {
|
|
149
|
+
"enum": ["text", "image"]
|
|
150
|
+
},
|
|
151
|
+
"uniqueItems": true
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
"imageGeneration": {
|
|
156
|
+
"description": "Disable image generation, use hosted Responses image_generation, or use standalone Codex Images endpoints.",
|
|
157
|
+
"enum": [false, "hosted", "standalone"],
|
|
158
|
+
"enumDescriptions": [
|
|
159
|
+
"Do not expose an image-generation tool.",
|
|
160
|
+
"Use the hosted Responses image_generation tool.",
|
|
161
|
+
"Expose image_gen.imagegen and call the standalone Codex Images endpoints."
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
"viewImage": {
|
|
165
|
+
"type": "boolean",
|
|
166
|
+
"description": "Expose the local view_image tool when the Pi model accepts image input."
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
"compaction": {
|
|
171
|
+
"enum": ["pi", "responses", "responses-compact"],
|
|
172
|
+
"description": "Pi summary compaction, Codex remote compaction v2, or the legacy /responses/compact endpoint."
|
|
173
|
+
},
|
|
174
|
+
"fast": {
|
|
175
|
+
"description": "Disable Fast mode for this model or configure its service tier and optional usage-cost multiplier.",
|
|
176
|
+
"if": {
|
|
177
|
+
"type": "boolean"
|
|
178
|
+
},
|
|
179
|
+
"then": {
|
|
180
|
+
"const": false
|
|
181
|
+
},
|
|
182
|
+
"else": {
|
|
183
|
+
"type": "object"
|
|
184
|
+
},
|
|
185
|
+
"defaultSnippets": [
|
|
186
|
+
{
|
|
187
|
+
"label": "Disable Fast mode",
|
|
188
|
+
"description": "Do not enable a Fast service tier for this model.",
|
|
189
|
+
"body": false
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"label": "Configure Fast mode",
|
|
193
|
+
"description": "Configure the Responses service tier used by the global Fast toggle.",
|
|
194
|
+
"body": {
|
|
195
|
+
"serviceTier": "priority"
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
],
|
|
199
|
+
"additionalProperties": false,
|
|
200
|
+
"required": ["serviceTier"],
|
|
201
|
+
"properties": {
|
|
202
|
+
"serviceTier": {
|
|
203
|
+
"type": "string",
|
|
204
|
+
"minLength": 1,
|
|
205
|
+
"description": "Responses service_tier value sent when the global Fast toggle is enabled."
|
|
206
|
+
},
|
|
207
|
+
"costMultiplier": {
|
|
208
|
+
"type": "number",
|
|
209
|
+
"exclusiveMinimum": 0,
|
|
210
|
+
"description": "Optional multiplier applied to Pi's reported request cost for this tier."
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@oai404iao/pi-codex-runtime",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Unpublished pi-codex-runtime workspace for the staged Codex split",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/oai404iao/omp.git",
|
|
11
|
+
"directory": "pi-extensions/pi-codex-runtime"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/oai404iao/omp/tree/main/pi-extensions/pi-codex-runtime#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/oai404iao/omp/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"pi-codex-runtime"
|
|
19
|
+
],
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./src/index.ts",
|
|
22
|
+
"./internal/*": "./src/*.ts",
|
|
23
|
+
"./subagent-inline": "./src/subagent-inline.ts"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@earendil-works/pi-ai": ">=0.84.2",
|
|
27
|
+
"@earendil-works/pi-coding-agent": ">=0.84.2"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"@earendil-works/pi-ai": {
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"@earendil-works/pi-coding-agent": {
|
|
34
|
+
"optional": true
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@earendil-works/pi-ai": "0.85.1",
|
|
40
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
41
|
+
"@types/node": "^26.2.0",
|
|
42
|
+
"tsx": "^4.20.6",
|
|
43
|
+
"typescript": "^7.0.2"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
47
|
+
"test": "tsx --test tests/**/*.test.ts",
|
|
48
|
+
"check": "npm run typecheck && npm test"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public",
|
|
52
|
+
"registry": "https://registry.npmjs.org/"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"src/",
|
|
56
|
+
"LICENSE",
|
|
57
|
+
"LICENSES/",
|
|
58
|
+
"THIRD_PARTY_NOTICES.md",
|
|
59
|
+
"provenance/",
|
|
60
|
+
"README.md",
|
|
61
|
+
"config.schema.json",
|
|
62
|
+
"models.schema.json"
|
|
63
|
+
],
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=22.19.0"
|
|
66
|
+
},
|
|
67
|
+
"gitHead": "32ba01f3c08b7fd63d09e9b2373cf081c4525533"
|
|
68
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"upstream": {
|
|
4
|
+
"repository": "https://github.com/openai/codex",
|
|
5
|
+
"revision": "eb9dceba1a2e658142a456c5898836774835616b",
|
|
6
|
+
"commitUrl": "https://github.com/openai/codex/commit/eb9dceba1a2e658142a456c5898836774835616b",
|
|
7
|
+
"license": "Apache-2.0"
|
|
8
|
+
},
|
|
9
|
+
"files": {
|
|
10
|
+
"LICENSE": {
|
|
11
|
+
"role": "upstream Apache-2.0 license",
|
|
12
|
+
"gitBlobSha": "4606e72e042564097e8780d66c1d4dcb611869bd",
|
|
13
|
+
"sha256": "d17f227e4df5da1600391338865ce0f3055211760a36688f816941d58232d8dc",
|
|
14
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/LICENSE"
|
|
15
|
+
},
|
|
16
|
+
"NOTICE": {
|
|
17
|
+
"role": "upstream NOTICE",
|
|
18
|
+
"gitBlobSha": "2805899d56d0332d175cfc613c67d45d6f006db7",
|
|
19
|
+
"sha256": "9d71575ecfd9a843fc1677b0efb08053c6ba9fd686a0de1a6f5382fd3c220915",
|
|
20
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/NOTICE"
|
|
21
|
+
},
|
|
22
|
+
"codex-rs/ext/web-search/web_run_description.md": {
|
|
23
|
+
"role": "exact web.run function description",
|
|
24
|
+
"gitBlobSha": "77be9a0a03e6e2e2760651e903ead2dce9996a57",
|
|
25
|
+
"sha256": "1f3879b44690eb7aad9ba97351acda16c4d0c26847bcb4af2964d5989404407e",
|
|
26
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/web-search/web_run_description.md"
|
|
27
|
+
},
|
|
28
|
+
"codex-rs/ext/web-search/src/tool.rs": {
|
|
29
|
+
"role": "web namespace and tool construction",
|
|
30
|
+
"gitBlobSha": "9747b75eddd1052ee4d75e868a644de7fd4135c1",
|
|
31
|
+
"sha256": "6ce56d7705c4b29b91d9d39af5468788a04dd925b414c7b44de67014f3329cb3",
|
|
32
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/web-search/src/tool.rs"
|
|
33
|
+
},
|
|
34
|
+
"codex-rs/ext/web-search/src/schema.rs": {
|
|
35
|
+
"role": "web parameter-schema generation",
|
|
36
|
+
"gitBlobSha": "2f71f1595c3b75d21cf78f35877f75b9314a3737",
|
|
37
|
+
"sha256": "6371391751d2a5dddad546aa810a6c64f770498702cec8153df74d1d7dff6f9b",
|
|
38
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/web-search/src/schema.rs"
|
|
39
|
+
},
|
|
40
|
+
"codex-rs/codex-api/src/search.rs": {
|
|
41
|
+
"role": "web SearchCommands input types",
|
|
42
|
+
"gitBlobSha": "237e7a7ebff4a0eeaa6dbb7b94c457d23dfc09de",
|
|
43
|
+
"sha256": "a83fd7ddd41c86985cce2aa899a2907ca820c226d5e7337949cc7e47a35c5f4f",
|
|
44
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/codex-api/src/search.rs"
|
|
45
|
+
},
|
|
46
|
+
"codex-rs/ext/image-generation/imagegen_description.md": {
|
|
47
|
+
"role": "exact image_gen.imagegen function description",
|
|
48
|
+
"gitBlobSha": "368aa10ea8f1909f9171b7a7b701bba6321f6f89",
|
|
49
|
+
"sha256": "77a992a7c90e45fcd11623a1efa34bfd4c7870697e0aa54ce9b28f690877170e",
|
|
50
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/image-generation/imagegen_description.md"
|
|
51
|
+
},
|
|
52
|
+
"codex-rs/ext/image-generation/src/lib.rs": {
|
|
53
|
+
"role": "image namespace and function names",
|
|
54
|
+
"gitBlobSha": "fd9db419309e5b06acb944a553f5ef144c8a261d",
|
|
55
|
+
"sha256": "c710abe1967cd3f7faaf78c0a35de0f5e6cc5c461f130b79d2b25d27ba8df9de",
|
|
56
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/image-generation/src/lib.rs"
|
|
57
|
+
},
|
|
58
|
+
"codex-rs/ext/image-generation/src/tool.rs": {
|
|
59
|
+
"role": "image namespace-tool construction and ImagegenArgs schema",
|
|
60
|
+
"gitBlobSha": "ab973da74cec4de053cbe943171bb9ad5703bad6",
|
|
61
|
+
"sha256": "8b8abe637c63e1fa8f52340a4609d96f37a5089364c4d82f0e695fd6731b2206",
|
|
62
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/ext/image-generation/src/tool.rs"
|
|
63
|
+
},
|
|
64
|
+
"codex-rs/tools/src/responses_api.rs": {
|
|
65
|
+
"role": "namespace serialization and descriptions",
|
|
66
|
+
"gitBlobSha": "e450dcf35f93ab4af7bf3f34956755066114ccae",
|
|
67
|
+
"sha256": "7af0354e43c3fa7f052d86df5ae0c6ce276569243af6f6ea5fe00abcb15bd244",
|
|
68
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/tools/src/responses_api.rs"
|
|
69
|
+
},
|
|
70
|
+
"codex-rs/tools/src/tool_spec.rs": {
|
|
71
|
+
"role": "Responses Lite namespace-tool serialization",
|
|
72
|
+
"gitBlobSha": "530da1be164ce3c6aa4b128ccb878bda7025e217",
|
|
73
|
+
"sha256": "af8b5286fb6d2eb3574c484b25076f515bca2d4350ecb5059e436966ecdd519d",
|
|
74
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/tools/src/tool_spec.rs"
|
|
75
|
+
},
|
|
76
|
+
"codex-rs/core/src/client.rs": {
|
|
77
|
+
"role": "Responses Lite additional_tools placement",
|
|
78
|
+
"gitBlobSha": "da3b6dad382fd4520026ac447c270e5cc11fa887",
|
|
79
|
+
"sha256": "4b4d00234a7fb649525fdcc913ffe288e4ef3348a916acbd265c22607fd8652d",
|
|
80
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/core/src/client.rs"
|
|
81
|
+
},
|
|
82
|
+
"codex-rs/Cargo.toml": {
|
|
83
|
+
"role": "pinned workspace dependency manifest for schema generation",
|
|
84
|
+
"gitBlobSha": "f23232e3d0b8246330d2409fc7fe9690062075c2",
|
|
85
|
+
"sha256": "2e8122fdd528a4d648d9417865153827dc5f7b45ee3afd86bfb129a1e01dcdb8",
|
|
86
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/Cargo.toml"
|
|
87
|
+
},
|
|
88
|
+
"codex-rs/Cargo.lock": {
|
|
89
|
+
"role": "pinned schema-generator dependency lockfile",
|
|
90
|
+
"gitBlobSha": "a67d1f3d7b062424d881a612f4cfd8b14e0ac630",
|
|
91
|
+
"sha256": "3a4a5361f289227c1ce09dc072811a1e7d1c7b599c58dd91dce6758d187c993d",
|
|
92
|
+
"rawUrl": "https://raw.githubusercontent.com/openai/codex/eb9dceba1a2e658142a456c5898836774835616b/codex-rs/Cargo.lock"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"localCompatibilitySerialization": {
|
|
96
|
+
"path": "src/codex-reserved-tools.ts",
|
|
97
|
+
"classification": "modified TypeScript compatibility serialization",
|
|
98
|
+
"boundary": "This local compatibility path uses an internal Codex Responses Lite shape and does not claim a stable or OpenAI-supported public API contract.",
|
|
99
|
+
"canonicalization": "SHA-256 of recursively lexicographically sorted JSON object keys; arrays retain their order and no whitespace is emitted.",
|
|
100
|
+
"namespaces": {
|
|
101
|
+
"web_search": {
|
|
102
|
+
"namespace": "web",
|
|
103
|
+
"function": "run",
|
|
104
|
+
"description": {
|
|
105
|
+
"sourcePath": "codex-rs/ext/web-search/web_run_description.md",
|
|
106
|
+
"relationship": "byte-for-byte",
|
|
107
|
+
"sha256": "1f3879b44690eb7aad9ba97351acda16c4d0c26847bcb4af2964d5989404407e"
|
|
108
|
+
},
|
|
109
|
+
"parameters": {
|
|
110
|
+
"sourcePaths": [
|
|
111
|
+
"codex-rs/ext/web-search/src/tool.rs",
|
|
112
|
+
"codex-rs/ext/web-search/src/schema.rs",
|
|
113
|
+
"codex-rs/codex-api/src/search.rs"
|
|
114
|
+
],
|
|
115
|
+
"relationship": "compatibility serialization",
|
|
116
|
+
"canonicalJsonSha256": "de3be87e7abfe9b67ba757f27804d4206b51c2a8de9e9799fa7db9ef4abe3539"
|
|
117
|
+
},
|
|
118
|
+
"canonicalJsonSha256": "f67597d3df3f3a77cb517646508e7305804ea029c6f8b1c1c1f241f0de0b214f"
|
|
119
|
+
},
|
|
120
|
+
"image_generation": {
|
|
121
|
+
"namespace": "image_gen",
|
|
122
|
+
"function": "imagegen",
|
|
123
|
+
"description": {
|
|
124
|
+
"sourcePath": "codex-rs/ext/image-generation/imagegen_description.md",
|
|
125
|
+
"relationship": "byte-for-byte",
|
|
126
|
+
"sha256": "77a992a7c90e45fcd11623a1efa34bfd4c7870697e0aa54ce9b28f690877170e"
|
|
127
|
+
},
|
|
128
|
+
"parameters": {
|
|
129
|
+
"sourcePaths": [
|
|
130
|
+
"codex-rs/ext/image-generation/src/lib.rs",
|
|
131
|
+
"codex-rs/ext/image-generation/src/tool.rs"
|
|
132
|
+
],
|
|
133
|
+
"relationship": "compatibility serialization",
|
|
134
|
+
"canonicalJsonSha256": "b4fea7c38ae74635e0072643ac2030899db242657071271e13cdd192a7377a27"
|
|
135
|
+
},
|
|
136
|
+
"canonicalJsonSha256": "ccc508cff0a216bbdf368be8c98be94134a1aed0479cddd28c77d8e004f5b73e"
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ModelLike } from "./capabilities.js";
|
|
2
|
+
import { listResolvedModelProfiles, resolveModelProfile } from "./model-catalog/catalog.js";
|
|
3
|
+
import type { CodexMinimalToolsSettings } from "./settings.js";
|
|
4
|
+
|
|
5
|
+
export interface ModelRegistryLike {
|
|
6
|
+
getAll?: () => unknown;
|
|
7
|
+
getAvailable?: () => unknown;
|
|
8
|
+
find?: (provider: string, id: string) => unknown;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ActivationContextLike {
|
|
12
|
+
model?: ModelLike;
|
|
13
|
+
modelRegistry?: ModelRegistryLike;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function registryModels(registry: ModelRegistryLike | undefined): ModelLike[] {
|
|
17
|
+
if (!registry) return [];
|
|
18
|
+
for (const method of [registry.getAll, registry.getAvailable]) {
|
|
19
|
+
if (typeof method !== "function") continue;
|
|
20
|
+
try {
|
|
21
|
+
const value = method.call(registry);
|
|
22
|
+
if (Array.isArray(value)) return value.filter((model): model is ModelLike => Boolean(model) && typeof model === "object");
|
|
23
|
+
} catch {
|
|
24
|
+
// Try the next registry shape.
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function hasConfiguredModelsLoaded(
|
|
31
|
+
ctx: ActivationContextLike,
|
|
32
|
+
settings?: CodexMinimalToolsSettings,
|
|
33
|
+
): boolean {
|
|
34
|
+
const current = resolveModelProfile(ctx.model, { settings });
|
|
35
|
+
if (current?.effective.enabled) return true;
|
|
36
|
+
const configured = new Set(
|
|
37
|
+
listResolvedModelProfiles({ settings })
|
|
38
|
+
.filter((profile) => profile.effective.enabled)
|
|
39
|
+
.map((profile) => profile.id.toLowerCase()),
|
|
40
|
+
);
|
|
41
|
+
if (registryModels(ctx.modelRegistry).some((model) => {
|
|
42
|
+
const provider = model.provider?.trim().toLowerCase();
|
|
43
|
+
const id = model.id?.trim().toLowerCase();
|
|
44
|
+
return Boolean(provider && id && configured.has(`${provider}/${id}`));
|
|
45
|
+
})) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
return [...configured].some((fullId) => {
|
|
50
|
+
const slash = fullId.indexOf("/");
|
|
51
|
+
return Boolean(ctx.modelRegistry?.find?.(fullId.slice(0, slash), fullId.slice(slash + 1)));
|
|
52
|
+
});
|
|
53
|
+
} catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/broker.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import type { PackageToolName } from "./capabilities.js";
|
|
4
|
+
import type { ProviderPresentation } from "./extension/provider-presentation.js";
|
|
5
|
+
|
|
6
|
+
export const CODEX_BROKER_CHANNEL = "@oai404iao/pi-codex:broker";
|
|
7
|
+
export const CODEX_RUNTIME_VERSION: string = createRequire(import.meta.url)("../package.json").version;
|
|
8
|
+
const CACHE = Symbol.for("@oai404iao/pi-codex/broker/v1");
|
|
9
|
+
|
|
10
|
+
export interface InstalledTool {
|
|
11
|
+
register(): void;
|
|
12
|
+
registered: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CodexBroker {
|
|
16
|
+
readonly version: 1;
|
|
17
|
+
readonly runtimeVersion: string;
|
|
18
|
+
readonly closed: boolean;
|
|
19
|
+
readonly tools: Map<PackageToolName, InstalledTool>;
|
|
20
|
+
coreEnabled: boolean;
|
|
21
|
+
claim(name: string): boolean;
|
|
22
|
+
addPresentation(name: string, presentation: ProviderPresentation): void;
|
|
23
|
+
presentation: ProviderPresentation;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function createBroker(): CodexBroker & { close(): void } {
|
|
27
|
+
const claims = new Set<string>();
|
|
28
|
+
const tools = new Map<PackageToolName, InstalledTool>();
|
|
29
|
+
const presentations = new Map<string, ProviderPresentation>();
|
|
30
|
+
const rendered = new Set<string>();
|
|
31
|
+
let closed = false;
|
|
32
|
+
const ordered = () => [...presentations].sort(([a], [b]) => a.localeCompare(b));
|
|
33
|
+
return {
|
|
34
|
+
version: 1,
|
|
35
|
+
runtimeVersion: CODEX_RUNTIME_VERSION,
|
|
36
|
+
get closed() { return closed; },
|
|
37
|
+
coreEnabled: false,
|
|
38
|
+
tools,
|
|
39
|
+
claim(name) {
|
|
40
|
+
if (closed) throw new Error("Codex broker belongs to a closed session");
|
|
41
|
+
if (claims.has(name)) return false;
|
|
42
|
+
claims.add(name);
|
|
43
|
+
return true;
|
|
44
|
+
},
|
|
45
|
+
addPresentation(name, presentation) {
|
|
46
|
+
if (closed) throw new Error("Codex broker belongs to a closed session");
|
|
47
|
+
if (presentations.has(name)) throw new Error(`Duplicate Codex presentation: ${name}`);
|
|
48
|
+
presentations.set(name, presentation);
|
|
49
|
+
},
|
|
50
|
+
presentation: {
|
|
51
|
+
clear() { for (const [, p] of ordered()) p.clear(); },
|
|
52
|
+
flush() { for (const [, p] of ordered()) p.flush(); },
|
|
53
|
+
scheduleFlush() { for (const [, p] of ordered()) p.scheduleFlush(); },
|
|
54
|
+
registerRenderers() {
|
|
55
|
+
for (const [name, p] of ordered()) {
|
|
56
|
+
if (rendered.has(name)) continue;
|
|
57
|
+
p.registerRenderers();
|
|
58
|
+
rendered.add(name);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
streamEffects() {
|
|
62
|
+
// Capture contributions and their session-owned sinks before I/O.
|
|
63
|
+
const effects = ordered().map(([, p]) => p.streamEffects());
|
|
64
|
+
return {
|
|
65
|
+
createEventObserver(context) {
|
|
66
|
+
const observers = effects.map(p => p.createEventObserver?.(context)).filter(
|
|
67
|
+
(observer): observer is NonNullable<typeof observer> => !!observer,
|
|
68
|
+
);
|
|
69
|
+
return async event => { for (const observe of observers) await observe(event); };
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
close() { closed = true; },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function isCompatible(candidate: CodexBroker): boolean {
|
|
79
|
+
return candidate?.version === 1 && candidate.runtimeVersion === CODEX_RUNTIME_VERSION
|
|
80
|
+
&& typeof candidate.claim === "function"
|
|
81
|
+
&& typeof candidate.addPresentation === "function"
|
|
82
|
+
&& typeof candidate.tools?.get === "function"
|
|
83
|
+
&& typeof candidate.tools?.set === "function"
|
|
84
|
+
&& typeof candidate.closed === "boolean"
|
|
85
|
+
&& typeof candidate.coreEnabled === "boolean"
|
|
86
|
+
&& ["clear", "flush", "scheduleFlush", "registerRenderers", "streamEffects"].every(
|
|
87
|
+
name => typeof (candidate.presentation as unknown as Record<string, unknown>)?.[name] === "function",
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function incompatibleBroker(): Error {
|
|
92
|
+
return new Error(`Incompatible or duplicate Codex capability broker: requires ABI v1 and runtime ${CODEX_RUNTIME_VERSION}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Pi gives each extension a separate API/module root. Synchronous event-bus
|
|
97
|
+
* discovery shares the v1 service across those roots; no module-global registry
|
|
98
|
+
* or equality of pi.events wrapper objects is assumed. The cached property is
|
|
99
|
+
* only a fast path (and supports minimal ExtensionAPI test doubles).
|
|
100
|
+
*/
|
|
101
|
+
export function getCodexBroker(pi: ExtensionAPI): CodexBroker {
|
|
102
|
+
const api = pi as ExtensionAPI & { [CACHE]?: CodexBroker };
|
|
103
|
+
const cached = api[CACHE];
|
|
104
|
+
if (cached && cached.closed !== true) {
|
|
105
|
+
// Different runtime copies can receive the same API object.
|
|
106
|
+
if (!isCompatible(cached)) throw incompatibleBroker();
|
|
107
|
+
return cached;
|
|
108
|
+
}
|
|
109
|
+
let found: CodexBroker | undefined;
|
|
110
|
+
let incompatible = false;
|
|
111
|
+
pi.events?.emit(CODEX_BROKER_CHANNEL, {
|
|
112
|
+
version: 1,
|
|
113
|
+
accept(candidate: CodexBroker) {
|
|
114
|
+
if (!isCompatible(candidate)) incompatible = true;
|
|
115
|
+
else if (!candidate.closed) {
|
|
116
|
+
if (found && found !== candidate) incompatible = true;
|
|
117
|
+
found = candidate;
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
if (incompatible) throw incompatibleBroker();
|
|
122
|
+
if (found) return (api[CACHE] = found);
|
|
123
|
+
const broker = createBroker();
|
|
124
|
+
const unsubscribe = pi.events?.on(CODEX_BROKER_CHANNEL, value => {
|
|
125
|
+
const request = value as { accept?: (broker: CodexBroker) => void } | undefined;
|
|
126
|
+
if (!broker.closed && typeof request?.accept === "function") request.accept(broker);
|
|
127
|
+
});
|
|
128
|
+
pi.on("session_shutdown", () => {
|
|
129
|
+
broker.close();
|
|
130
|
+
unsubscribe?.();
|
|
131
|
+
});
|
|
132
|
+
return (api[CACHE] = broker);
|
|
133
|
+
}
|