n8n-nodes-codex-pro 1.0.2
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 +247 -0
- package/dist/credentials/CodexProApi.credentials.d.ts +8 -0
- package/dist/credentials/CodexProApi.credentials.js +37 -0
- package/dist/credentials/CodexProApi.credentials.js.map +1 -0
- package/dist/credentials/codex-cli-auth.svg +7 -0
- package/dist/nodes/CodexPro/CodexPro.node.d.ts +67 -0
- package/dist/nodes/CodexPro/CodexPro.node.js +618 -0
- package/dist/nodes/CodexPro/CodexPro.node.js.map +1 -0
- package/dist/nodes/CodexPro/codex-pro.svg +5 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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,247 @@
|
|
|
1
|
+
# n8n-nodes-codex-pro
|
|
2
|
+
|
|
3
|
+
An n8n community node that exposes the local Codex CLI as a Language Model node for n8n AI Agent.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
This package is meant to be easy to install if you already use Codex CLI.
|
|
8
|
+
|
|
9
|
+
1. Install Codex CLI on the machine that runs n8n:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @openai/codex
|
|
13
|
+
codex login
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. Install this node in n8n:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install n8n-nodes-codex-pro
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. Restart n8n.
|
|
23
|
+
|
|
24
|
+
4. In n8n, create the credential **Codex CLI Auth**:
|
|
25
|
+
|
|
26
|
+
- **Codex Binary Path**: leave empty first
|
|
27
|
+
- **CODEX_HOME**: leave empty on a normal host install, or set `/home/node/.codex` in Docker
|
|
28
|
+
- **Config Profile**: optional
|
|
29
|
+
|
|
30
|
+
5. Add **Codex Pro LM** to your AI Agent.
|
|
31
|
+
|
|
32
|
+
For most users, that is enough.
|
|
33
|
+
|
|
34
|
+
This package is designed for the setup where you already use Codex locally with:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
codex login
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
and the CLI stores credentials in:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
~/.codex/auth.json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The node does not send `auth.json` to the OpenAI API directly. It shells out to the local `codex` CLI, and the CLI handles authentication itself.
|
|
47
|
+
|
|
48
|
+
## Requirements
|
|
49
|
+
|
|
50
|
+
The machine running n8n must have:
|
|
51
|
+
|
|
52
|
+
- `@openai/codex` installed
|
|
53
|
+
- a completed `codex login`
|
|
54
|
+
- access to the same `CODEX_HOME` that contains `auth.json`
|
|
55
|
+
|
|
56
|
+
Install Codex CLI:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install -g @openai/codex
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then log in:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
codex login
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Install from npm
|
|
69
|
+
|
|
70
|
+
### Host n8n install
|
|
71
|
+
|
|
72
|
+
If n8n runs directly on your machine, install the package into n8n's custom extensions folder:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mkdir -p ~/.n8n/custom
|
|
76
|
+
cd ~/.n8n/custom
|
|
77
|
+
npm install n8n-nodes-codex-pro
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Then restart n8n.
|
|
81
|
+
|
|
82
|
+
### Docker n8n install
|
|
83
|
+
|
|
84
|
+
If n8n runs in Docker, the container needs:
|
|
85
|
+
|
|
86
|
+
- Codex CLI installed in the image
|
|
87
|
+
- your host `~/.codex` mounted into the container
|
|
88
|
+
- the community node installed in n8n's custom extensions directory
|
|
89
|
+
|
|
90
|
+
Recommended `Dockerfile`:
|
|
91
|
+
|
|
92
|
+
```dockerfile
|
|
93
|
+
FROM docker.n8n.io/n8nio/n8n:latest
|
|
94
|
+
|
|
95
|
+
USER root
|
|
96
|
+
RUN npm install -g @openai/codex
|
|
97
|
+
|
|
98
|
+
RUN mkdir -p /home/node/agents /home/node/.codex \
|
|
99
|
+
&& chown -R node:node /home/node
|
|
100
|
+
|
|
101
|
+
USER node
|
|
102
|
+
WORKDIR /home/node
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Recommended `docker-compose.yml` additions:
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
services:
|
|
109
|
+
n8n:
|
|
110
|
+
volumes:
|
|
111
|
+
- ./n8n_data:/home/node/.n8n
|
|
112
|
+
- /home/your-user/.codex:/home/node/.codex:ro
|
|
113
|
+
- /path/to/custom-packages:/home/node/.n8n/custom
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Then install the package into that mounted custom folder on the host:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
mkdir -p /path/to/custom-packages
|
|
120
|
+
cd /path/to/custom-packages
|
|
121
|
+
npm init -y
|
|
122
|
+
npm install n8n-nodes-codex-pro
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then restart n8n:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
docker compose restart n8n
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Credential type
|
|
132
|
+
|
|
133
|
+
Create the n8n credential:
|
|
134
|
+
|
|
135
|
+
- **Codex CLI Auth**
|
|
136
|
+
|
|
137
|
+
Fields:
|
|
138
|
+
|
|
139
|
+
- **Codex Binary Path**: optional. Leave empty to auto-detect standard Codex install locations. This covers the recommended Docker and npm-global setups, but custom installs may still need an explicit path.
|
|
140
|
+
- **CODEX_HOME**: optional override if n8n runs under a different home directory
|
|
141
|
+
- **Config Profile**: optional Codex profile name passed to `codex exec -p`
|
|
142
|
+
|
|
143
|
+
Node options:
|
|
144
|
+
|
|
145
|
+
- Open **Options** -> **Add Option** in the node editor to reveal these controls.
|
|
146
|
+
- **Reasoning Effort**: passed as `-c model_reasoning_effort="low|medium|high"`
|
|
147
|
+
- **Sandbox Mode**: passed as `codex exec -s ...`
|
|
148
|
+
- **Allow Codex MCP**: allows Codex to use MCP servers defined in `CODEX_HOME/config.toml`
|
|
149
|
+
- **Codex Config Overrides**: one `key=value` per line, each passed as `-c key=value`
|
|
150
|
+
- **Timeout / Max Retries**
|
|
151
|
+
|
|
152
|
+
Default values:
|
|
153
|
+
|
|
154
|
+
- **Reasoning Effort**: `high`
|
|
155
|
+
- **Sandbox Mode**: `read-only`
|
|
156
|
+
- **Allow Codex MCP**: `off`
|
|
157
|
+
- **Timeout**: `300000`
|
|
158
|
+
- **Max Retries**: `1`
|
|
159
|
+
- **Codex Binary Path**: empty, which enables auto-detection
|
|
160
|
+
|
|
161
|
+
## How it works
|
|
162
|
+
|
|
163
|
+
The node runs:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
codex exec
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
non-interactively in a temporary directory, with a read-only sandbox, and converts the result back into an n8n AI language model response.
|
|
170
|
+
|
|
171
|
+
For AI Agent tool use, the node asks Codex to return structured JSON that either:
|
|
172
|
+
|
|
173
|
+
- contains a final assistant response
|
|
174
|
+
- or contains one or more tool calls for n8n to execute
|
|
175
|
+
|
|
176
|
+
## Install from source
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
cd /path/to/n8n-nodes-codex-pro
|
|
180
|
+
npm install
|
|
181
|
+
npm run build
|
|
182
|
+
mkdir -p ~/.n8n/custom/node_modules
|
|
183
|
+
ln -sfn "$(pwd)" ~/.n8n/custom/node_modules/n8n-nodes-codex-pro
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Then restart n8n.
|
|
187
|
+
|
|
188
|
+
## First test
|
|
189
|
+
|
|
190
|
+
1. Make sure `codex --version` works on the n8n host.
|
|
191
|
+
2. Make sure `codex login` has already been completed for that same host or `CODEX_HOME`.
|
|
192
|
+
3. Create credential: **Codex CLI Auth**
|
|
193
|
+
4. Leave **Codex Binary Path** empty first. The node will auto-detect common Codex install paths.
|
|
194
|
+
5. Set **CODEX_HOME** if n8n runs under Docker or a different user.
|
|
195
|
+
6. Add **Codex Pro LM** to your AI Agent.
|
|
196
|
+
7. Pick model `gpt-5-codex`.
|
|
197
|
+
|
|
198
|
+
If auto-detection fails in Docker, you can still set the explicit wrapper path manually. For example:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
/opt/nodejs/node-v24.13.1/lib/node_modules/@openai/codex/bin/codex.js
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Prefer the wrapper script path over the deeply nested vendored binary path. It is more stable across Codex updates because the wrapper resolves the current platform binary for you.
|
|
205
|
+
|
|
206
|
+
## MCP support
|
|
207
|
+
|
|
208
|
+
If your Codex `config.toml` defines MCP servers, the node can optionally allow Codex to use them by enabling:
|
|
209
|
+
|
|
210
|
+
- **Allow Codex MCP**
|
|
211
|
+
|
|
212
|
+
This keeps the feature extendable later without hard-coding MCP server definitions into the node itself. The node simply inherits the MCP configuration already managed by Codex.
|
|
213
|
+
|
|
214
|
+
## Handling Codex updates
|
|
215
|
+
|
|
216
|
+
The recommended path for users is:
|
|
217
|
+
|
|
218
|
+
- leave `Codex Binary Path` empty and rely on auto-detection
|
|
219
|
+
- or point to the Codex wrapper script (`.../@openai/codex/bin/codex.js`), not the vendored platform binary
|
|
220
|
+
|
|
221
|
+
That makes upgrades easier because the wrapper script remains the stable entrypoint while the internal platform binary path may change between Codex releases.
|
|
222
|
+
|
|
223
|
+
## Caveats
|
|
224
|
+
|
|
225
|
+
- This wraps the Codex CLI. It is not the same as calling the OpenAI Responses API directly.
|
|
226
|
+
- Behavior depends on the installed Codex CLI version.
|
|
227
|
+
- If n8n runs in Docker, the container needs both the `codex` binary and access to the correct `auth.json`.
|
|
228
|
+
- After updating this package, rebuild it and restart n8n. If you do not, newly added options such as **Allow Codex MCP** may not appear in the UI.
|
|
229
|
+
|
|
230
|
+
## Publishing
|
|
231
|
+
|
|
232
|
+
Before publishing:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm login
|
|
236
|
+
npm whoami
|
|
237
|
+
npm run build
|
|
238
|
+
npm run pack:check
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Then publish:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
npm publish --access public
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
If `npm whoami` does not return the expected npm user, stop and fix that first.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodexProApi = void 0;
|
|
4
|
+
class CodexProApi {
|
|
5
|
+
name = 'codexProApi';
|
|
6
|
+
displayName = 'Codex CLI Auth';
|
|
7
|
+
documentationUrl = 'https://developers.openai.com/codex/cli';
|
|
8
|
+
icon = 'file:codex-cli-auth.svg';
|
|
9
|
+
properties = [
|
|
10
|
+
{
|
|
11
|
+
displayName: 'Codex Binary Path',
|
|
12
|
+
name: 'codexPath',
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: '',
|
|
15
|
+
required: false,
|
|
16
|
+
description: 'Optional path to the local Codex executable. Default: empty, which enables auto-detection of common system, npm, and Docker install locations. This works for the recommended setup, but custom installs may still need an explicit path.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
displayName: 'CODEX_HOME',
|
|
20
|
+
name: 'codexHome',
|
|
21
|
+
type: 'string',
|
|
22
|
+
default: '',
|
|
23
|
+
required: false,
|
|
24
|
+
description: 'Optional path to the Codex home directory that contains `auth.json` and `config.toml`. In Docker, set this to `/home/node/.codex`. If empty, the default Codex home for the n8n process user is used.',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
displayName: 'Config Profile',
|
|
28
|
+
name: 'configProfile',
|
|
29
|
+
type: 'string',
|
|
30
|
+
default: '',
|
|
31
|
+
required: false,
|
|
32
|
+
description: 'Optional Codex config profile passed through as `codex exec -p <profile>`. Default: empty.',
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
exports.CodexProApi = CodexProApi;
|
|
37
|
+
//# sourceMappingURL=CodexProApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodexProApi.credentials.js","sourceRoot":"","sources":["../../credentials/CodexProApi.credentials.ts"],"names":[],"mappings":";;;AAEA,MAAa,WAAW;IACvB,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAAG,gBAAgB,CAAC;IAC/B,gBAAgB,GAAG,yCAAyC,CAAC;IAC7D,IAAI,GAAS,yBAAyB,CAAC;IAEvC,UAAU,GAAsB;QAC/B;YACC,WAAW,EAAE,mBAAmB;YAChC,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,KAAK;YACf,WAAW,EACV,2OAA2O;SAC5O;QACD;YACC,WAAW,EAAE,YAAY;YACzB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,KAAK;YACf,WAAW,EACV,uMAAuM;SACxM;QACD;YACC,WAAW,EAAE,gBAAgB;YAC7B,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,KAAK;YACf,WAAW,EAAE,4FAA4F;SACzG;KACD,CAAC;CACF;AAlCD,kCAkCC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="none">
|
|
2
|
+
<rect width="256" height="256" rx="48" fill="#0F172A"/>
|
|
3
|
+
<path d="M128 48c-44.183 0-80 35.817-80 80s35.817 80 80 80c22.903 0 43.56-9.625 58.153-25.056l-22.667-18.223C154.087 173.711 141.7 180 128 180c-28.719 0-52-23.281-52-52s23.281-52 52-52c13.7 0 26.087 6.289 35.486 16.279l22.667-18.223C171.56 57.625 150.903 48 128 48Z" fill="#10A37F"/>
|
|
4
|
+
<path d="M156 96h28v64h-28z" fill="#10A37F"/>
|
|
5
|
+
<rect x="136" y="154" width="78" height="46" rx="16" fill="#111827"/>
|
|
6
|
+
<text x="175" y="184" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="24" font-weight="700" fill="#F8FAFC">BS</text>
|
|
7
|
+
</svg>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type INodeType, type INodeTypeDescription, type ISupplyDataFunctions, type NodeConnectionType } from 'n8n-workflow';
|
|
2
|
+
import { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
3
|
+
import { AIMessageChunk } from '@langchain/core/messages';
|
|
4
|
+
import { ChatGenerationChunk } from '@langchain/core/outputs';
|
|
5
|
+
type N8nContext = {
|
|
6
|
+
addInputData: (...args: any[]) => any;
|
|
7
|
+
addOutputData: (...args: any[]) => any;
|
|
8
|
+
connectionType: NodeConnectionType;
|
|
9
|
+
};
|
|
10
|
+
type CodexCliCredentials = {
|
|
11
|
+
codexPath: string;
|
|
12
|
+
codexHome?: string;
|
|
13
|
+
configProfile?: string;
|
|
14
|
+
};
|
|
15
|
+
type OpenAITool = {
|
|
16
|
+
type: 'function';
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
parameters: Record<string, any>;
|
|
20
|
+
};
|
|
21
|
+
declare class CodexProChatModel extends BaseChatModel {
|
|
22
|
+
lc_serializable: boolean;
|
|
23
|
+
credentials: CodexCliCredentials;
|
|
24
|
+
modelId: string;
|
|
25
|
+
timeout: number;
|
|
26
|
+
maxRetries: number;
|
|
27
|
+
sandboxMode: 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
28
|
+
configOverrides: string[];
|
|
29
|
+
allowCodexMcp: boolean;
|
|
30
|
+
boundTools?: OpenAITool[];
|
|
31
|
+
n8nContext?: N8nContext;
|
|
32
|
+
constructor(fields: {
|
|
33
|
+
credentials: CodexCliCredentials;
|
|
34
|
+
modelId: string;
|
|
35
|
+
timeout: number;
|
|
36
|
+
maxRetries: number;
|
|
37
|
+
sandboxMode: 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
38
|
+
configOverrides: string[];
|
|
39
|
+
allowCodexMcp: boolean;
|
|
40
|
+
tools?: OpenAITool[];
|
|
41
|
+
n8nContext?: N8nContext;
|
|
42
|
+
});
|
|
43
|
+
_llmType(): string;
|
|
44
|
+
bindTools(tools: any[], _kwargs: any): CodexProChatModel;
|
|
45
|
+
_isRetryableError(error: unknown): boolean;
|
|
46
|
+
_withRetry<T>(fn: () => Promise<T>): Promise<T>;
|
|
47
|
+
_invokeCodex(messages: any[], options: any): Promise<{
|
|
48
|
+
generations: {
|
|
49
|
+
text: string;
|
|
50
|
+
message: AIMessageChunk<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>>;
|
|
51
|
+
}[];
|
|
52
|
+
}>;
|
|
53
|
+
_generate(messages: any[], options: any, _runManager?: any): Promise<{
|
|
54
|
+
generations: {
|
|
55
|
+
text: string;
|
|
56
|
+
message: AIMessageChunk<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>>;
|
|
57
|
+
}[];
|
|
58
|
+
}>;
|
|
59
|
+
_streamResponseChunks(messages: any[], options: any, runManager?: any): AsyncGenerator<ChatGenerationChunk, void, unknown>;
|
|
60
|
+
}
|
|
61
|
+
export declare class CodexPro implements INodeType {
|
|
62
|
+
description: INodeTypeDescription;
|
|
63
|
+
supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<{
|
|
64
|
+
response: CodexProChatModel;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodexPro = void 0;
|
|
4
|
+
const node_child_process_1 = require("node:child_process");
|
|
5
|
+
const node_fs_1 = require("node:fs");
|
|
6
|
+
const promises_1 = require("node:fs/promises");
|
|
7
|
+
const node_os_1 = require("node:os");
|
|
8
|
+
const node_path_1 = require("node:path");
|
|
9
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
10
|
+
const chat_models_1 = require("@langchain/core/language_models/chat_models");
|
|
11
|
+
const messages_1 = require("@langchain/core/messages");
|
|
12
|
+
const outputs_1 = require("@langchain/core/outputs");
|
|
13
|
+
const function_calling_1 = require("@langchain/core/utils/function_calling");
|
|
14
|
+
const DEFAULT_TIMEOUT_MS = 300000;
|
|
15
|
+
const DEFAULT_MAX_RETRIES = 1;
|
|
16
|
+
const DEFAULT_MODELS = [
|
|
17
|
+
{ name: 'GPT-5-Codex', value: 'gpt-5-codex' },
|
|
18
|
+
{ name: 'GPT-5.4', value: 'gpt-5.4' },
|
|
19
|
+
{ name: 'GPT-5.4-mini', value: 'gpt-5.4-mini' },
|
|
20
|
+
{ name: 'GPT-5.3-Codex', value: 'gpt-5.3-codex' },
|
|
21
|
+
{ name: 'GPT-5.3-Codex-Spark', value: 'gpt-5.3-codex-spark' },
|
|
22
|
+
{ name: 'GPT-5.2-Codex', value: 'gpt-5.2-codex' },
|
|
23
|
+
{ name: 'GPT-5.1-Codex-Max', value: 'gpt-5.1-codex-max' },
|
|
24
|
+
{ name: 'GPT-5.1-Codex', value: 'gpt-5.1-codex' },
|
|
25
|
+
{ name: 'GPT-5.2', value: 'gpt-5.2' },
|
|
26
|
+
{ name: 'GPT-5.1', value: 'gpt-5.1' },
|
|
27
|
+
];
|
|
28
|
+
function getCliCredentials(raw) {
|
|
29
|
+
const codexPath = typeof raw.codexPath === 'string' ? raw.codexPath.trim() : '';
|
|
30
|
+
const codexHome = typeof raw.codexHome === 'string' ? raw.codexHome.trim() : '';
|
|
31
|
+
const configProfile = typeof raw.configProfile === 'string' ? raw.configProfile.trim() : '';
|
|
32
|
+
return {
|
|
33
|
+
codexPath,
|
|
34
|
+
codexHome: codexHome || undefined,
|
|
35
|
+
configProfile: configProfile || undefined,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async function pathExists(path) {
|
|
39
|
+
try {
|
|
40
|
+
await (0, promises_1.access)(path, node_fs_1.constants.X_OK);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function findCodexWrapperUnder(root) {
|
|
48
|
+
try {
|
|
49
|
+
const entries = await (0, promises_1.readdir)(root, { withFileTypes: true });
|
|
50
|
+
for (const entry of entries) {
|
|
51
|
+
if (!entry.isDirectory())
|
|
52
|
+
continue;
|
|
53
|
+
const candidate = (0, node_path_1.join)(root, entry.name, 'lib', 'node_modules', '@openai', 'codex', 'bin', 'codex.js');
|
|
54
|
+
if (await pathExists(candidate))
|
|
55
|
+
return candidate;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch { }
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
async function resolveCodexExecutable(preferredPath) {
|
|
62
|
+
if (preferredPath) {
|
|
63
|
+
if (!preferredPath.includes('/')) {
|
|
64
|
+
return preferredPath;
|
|
65
|
+
}
|
|
66
|
+
if (await pathExists(preferredPath)) {
|
|
67
|
+
return preferredPath;
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Configured Codex binary path does not exist or is not executable: ${preferredPath}`);
|
|
70
|
+
}
|
|
71
|
+
const directCandidates = [
|
|
72
|
+
'/usr/local/bin/codex',
|
|
73
|
+
'/usr/bin/codex',
|
|
74
|
+
'/usr/local/lib/node_modules/@openai/codex/bin/codex.js',
|
|
75
|
+
'/home/node/.npm-global/lib/node_modules/@openai/codex/bin/codex.js',
|
|
76
|
+
];
|
|
77
|
+
for (const candidate of directCandidates) {
|
|
78
|
+
if (await pathExists(candidate)) {
|
|
79
|
+
return candidate;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const optNodeJsWrapper = await findCodexWrapperUnder('/opt/nodejs');
|
|
83
|
+
if (optNodeJsWrapper) {
|
|
84
|
+
return optNodeJsWrapper;
|
|
85
|
+
}
|
|
86
|
+
return 'codex';
|
|
87
|
+
}
|
|
88
|
+
function serializeContent(content) {
|
|
89
|
+
if (typeof content === 'string')
|
|
90
|
+
return content;
|
|
91
|
+
if (content === undefined || content === null)
|
|
92
|
+
return '';
|
|
93
|
+
try {
|
|
94
|
+
return JSON.stringify(content, null, 2);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return String(content);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function serializeMessages(messages) {
|
|
101
|
+
return messages
|
|
102
|
+
.map((msg, index) => {
|
|
103
|
+
const role = String(msg._getType?.() ?? 'unknown').toUpperCase();
|
|
104
|
+
const sections = [`[${index + 1}] ${role}`];
|
|
105
|
+
const text = serializeContent(msg.content);
|
|
106
|
+
if (text)
|
|
107
|
+
sections.push(text);
|
|
108
|
+
const toolCalls = msg.tool_calls;
|
|
109
|
+
if (Array.isArray(toolCalls) && toolCalls.length) {
|
|
110
|
+
sections.push(`Tool calls:\n${JSON.stringify(toolCalls, null, 2)}`);
|
|
111
|
+
}
|
|
112
|
+
const toolCallId = msg.tool_call_id || msg.additional_kwargs?.tool_call_id;
|
|
113
|
+
if (toolCallId) {
|
|
114
|
+
sections.push(`Tool call id: ${toolCallId}`);
|
|
115
|
+
}
|
|
116
|
+
return sections.join('\n');
|
|
117
|
+
})
|
|
118
|
+
.join('\n\n');
|
|
119
|
+
}
|
|
120
|
+
function convertTools(tools) {
|
|
121
|
+
return tools.map((tool) => {
|
|
122
|
+
const openAiTool = (0, function_calling_1.convertToOpenAITool)(tool);
|
|
123
|
+
const parameters = { ...(openAiTool.function.parameters || { type: 'object', properties: {} }) };
|
|
124
|
+
delete parameters.$schema;
|
|
125
|
+
return {
|
|
126
|
+
type: 'function',
|
|
127
|
+
name: openAiTool.function.name,
|
|
128
|
+
description: openAiTool.function.description || '',
|
|
129
|
+
parameters,
|
|
130
|
+
};
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function buildStructuredSchema(toolNames) {
|
|
134
|
+
return {
|
|
135
|
+
type: 'object',
|
|
136
|
+
additionalProperties: false,
|
|
137
|
+
required: ['mode', 'response', 'tool_calls'],
|
|
138
|
+
properties: {
|
|
139
|
+
mode: {
|
|
140
|
+
type: 'string',
|
|
141
|
+
enum: ['respond', 'tool_calls'],
|
|
142
|
+
},
|
|
143
|
+
response: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
},
|
|
146
|
+
tool_calls: {
|
|
147
|
+
type: 'array',
|
|
148
|
+
items: {
|
|
149
|
+
type: 'object',
|
|
150
|
+
additionalProperties: false,
|
|
151
|
+
required: ['name', 'arguments_json'],
|
|
152
|
+
properties: {
|
|
153
|
+
name: toolNames.length
|
|
154
|
+
? { type: 'string', enum: toolNames }
|
|
155
|
+
: { type: 'string' },
|
|
156
|
+
arguments_json: {
|
|
157
|
+
type: 'string',
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function buildCodexPrompt(messages, tools, allowCodexMcp) {
|
|
166
|
+
const toolSection = tools.length
|
|
167
|
+
? `Available n8n tools:\n${JSON.stringify(tools.map((tool) => ({
|
|
168
|
+
name: tool.name,
|
|
169
|
+
description: tool.description,
|
|
170
|
+
parameters: tool.parameters,
|
|
171
|
+
})), null, 2)}`
|
|
172
|
+
: 'Available n8n tools:\n[]';
|
|
173
|
+
return [
|
|
174
|
+
'You are acting as the language model inside n8n AI Agent.',
|
|
175
|
+
'Your job is to read the conversation and either return a final assistant response or request one or more n8n tool calls.',
|
|
176
|
+
allowCodexMcp
|
|
177
|
+
? 'Do not execute shell commands or inspect local files. You may use configured Codex MCP servers if they help answer the request.'
|
|
178
|
+
: 'Do not execute shell commands, inspect files, or use Codex CLI local tools or MCP servers. Ignore your terminal environment.',
|
|
179
|
+
'Respond only based on the conversation and the tool definitions below.',
|
|
180
|
+
'If a tool is needed, set mode to "tool_calls", leave response as an empty string, and provide valid JSON arguments for each tool call encoded as a JSON string in `arguments_json`.',
|
|
181
|
+
'If no tool is needed, set mode to "respond", put the full assistant reply in response, and return an empty tool_calls array.',
|
|
182
|
+
toolSection,
|
|
183
|
+
`Conversation:\n${serializeMessages(messages)}`,
|
|
184
|
+
].join('\n\n');
|
|
185
|
+
}
|
|
186
|
+
function parseStructuredResult(raw, tools) {
|
|
187
|
+
const trimmed = raw.trim();
|
|
188
|
+
const normalized = trimmed.startsWith('```')
|
|
189
|
+
? trimmed.replace(/^```(?:json)?\s*/i, '').replace(/\s*```$/, '')
|
|
190
|
+
: trimmed;
|
|
191
|
+
let parsed;
|
|
192
|
+
try {
|
|
193
|
+
parsed = JSON.parse(normalized);
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
return {
|
|
197
|
+
mode: 'respond',
|
|
198
|
+
response: trimmed,
|
|
199
|
+
tool_calls: [],
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const mode = parsed?.mode === 'tool_calls' ? 'tool_calls' : 'respond';
|
|
203
|
+
const response = typeof parsed?.response === 'string' ? parsed.response : '';
|
|
204
|
+
const toolNames = new Set(tools.map((tool) => tool.name));
|
|
205
|
+
const toolCalls = Array.isArray(parsed?.tool_calls)
|
|
206
|
+
? parsed.tool_calls
|
|
207
|
+
.filter((call) => typeof call?.name === 'string' && (!toolNames.size || toolNames.has(call.name)))
|
|
208
|
+
.map((call) => {
|
|
209
|
+
let parsedArguments = {};
|
|
210
|
+
if (typeof call.arguments_json === 'string' && call.arguments_json.trim()) {
|
|
211
|
+
try {
|
|
212
|
+
const rawArguments = JSON.parse(call.arguments_json);
|
|
213
|
+
if (rawArguments && typeof rawArguments === 'object' && !Array.isArray(rawArguments)) {
|
|
214
|
+
parsedArguments = rawArguments;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch { }
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
name: call.name,
|
|
221
|
+
arguments_json: JSON.stringify(parsedArguments),
|
|
222
|
+
};
|
|
223
|
+
})
|
|
224
|
+
: [];
|
|
225
|
+
if (mode === 'tool_calls' && toolCalls.length) {
|
|
226
|
+
return {
|
|
227
|
+
mode,
|
|
228
|
+
response: '',
|
|
229
|
+
tool_calls: toolCalls,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
mode: 'respond',
|
|
234
|
+
response: response || trimmed,
|
|
235
|
+
tool_calls: [],
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
async function runCodexExec(options) {
|
|
239
|
+
const codexExecutable = await resolveCodexExecutable(options.credentials.codexPath);
|
|
240
|
+
const tempRoot = await (0, promises_1.mkdtemp)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'n8n-codex-pro-'));
|
|
241
|
+
const outputPath = (0, node_path_1.join)(tempRoot, 'last-message.txt');
|
|
242
|
+
const schemaPath = (0, node_path_1.join)(tempRoot, 'schema.json');
|
|
243
|
+
try {
|
|
244
|
+
const schema = buildStructuredSchema(options.toolNames);
|
|
245
|
+
await (0, promises_1.writeFile)(schemaPath, JSON.stringify(schema, null, 2), 'utf8');
|
|
246
|
+
const args = [
|
|
247
|
+
'exec',
|
|
248
|
+
'-',
|
|
249
|
+
'--skip-git-repo-check',
|
|
250
|
+
'--ephemeral',
|
|
251
|
+
'--color',
|
|
252
|
+
'never',
|
|
253
|
+
'-C',
|
|
254
|
+
tempRoot,
|
|
255
|
+
'-s',
|
|
256
|
+
options.sandboxMode,
|
|
257
|
+
'-o',
|
|
258
|
+
outputPath,
|
|
259
|
+
'--output-schema',
|
|
260
|
+
schemaPath,
|
|
261
|
+
'-m',
|
|
262
|
+
options.modelId,
|
|
263
|
+
];
|
|
264
|
+
if (options.credentials.configProfile) {
|
|
265
|
+
args.push('-p', options.credentials.configProfile);
|
|
266
|
+
}
|
|
267
|
+
for (const override of options.configOverrides) {
|
|
268
|
+
args.push('-c', override);
|
|
269
|
+
}
|
|
270
|
+
const env = {
|
|
271
|
+
...process.env,
|
|
272
|
+
CODEX_QUIET_MODE: '1',
|
|
273
|
+
};
|
|
274
|
+
if (options.credentials.codexHome) {
|
|
275
|
+
env.CODEX_HOME = options.credentials.codexHome;
|
|
276
|
+
}
|
|
277
|
+
const child = (0, node_child_process_1.spawn)(codexExecutable, args, {
|
|
278
|
+
cwd: tempRoot,
|
|
279
|
+
env,
|
|
280
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
281
|
+
});
|
|
282
|
+
let stdout = '';
|
|
283
|
+
let stderr = '';
|
|
284
|
+
let timedOut = false;
|
|
285
|
+
const timeoutId = setTimeout(() => {
|
|
286
|
+
timedOut = true;
|
|
287
|
+
child.kill('SIGTERM');
|
|
288
|
+
setTimeout(() => child.kill('SIGKILL'), 5000);
|
|
289
|
+
}, options.timeout);
|
|
290
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
291
|
+
child.stdout.on('data', (chunk) => {
|
|
292
|
+
stdout += chunk.toString();
|
|
293
|
+
});
|
|
294
|
+
child.stderr.on('data', (chunk) => {
|
|
295
|
+
stderr += chunk.toString();
|
|
296
|
+
});
|
|
297
|
+
child.on('error', reject);
|
|
298
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
299
|
+
child.stdin.end(options.prompt);
|
|
300
|
+
}).finally(() => clearTimeout(timeoutId));
|
|
301
|
+
if (timedOut) {
|
|
302
|
+
throw new Error(`Codex CLI request timed out after ${options.timeout}ms`);
|
|
303
|
+
}
|
|
304
|
+
if (exitCode !== 0) {
|
|
305
|
+
throw new Error(`Codex CLI failed with exit code ${exitCode}: ${(stderr || stdout).trim() || 'Unknown error'}`);
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
return (await (0, promises_1.readFile)(outputPath, 'utf8')).trim();
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
const fallback = stdout.trim();
|
|
312
|
+
if (!fallback) {
|
|
313
|
+
throw new Error(`Codex CLI returned no assistant message.${stderr ? ` ${stderr.trim()}` : ''}`);
|
|
314
|
+
}
|
|
315
|
+
return fallback;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
finally {
|
|
319
|
+
await (0, promises_1.rm)(tempRoot, { recursive: true, force: true });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
class CodexProChatModel extends chat_models_1.BaseChatModel {
|
|
323
|
+
lc_serializable = false;
|
|
324
|
+
credentials;
|
|
325
|
+
modelId;
|
|
326
|
+
timeout;
|
|
327
|
+
maxRetries;
|
|
328
|
+
sandboxMode;
|
|
329
|
+
configOverrides;
|
|
330
|
+
allowCodexMcp;
|
|
331
|
+
boundTools;
|
|
332
|
+
n8nContext;
|
|
333
|
+
constructor(fields) {
|
|
334
|
+
super({});
|
|
335
|
+
this.credentials = fields.credentials;
|
|
336
|
+
this.modelId = fields.modelId;
|
|
337
|
+
this.timeout = fields.timeout;
|
|
338
|
+
this.maxRetries = fields.maxRetries;
|
|
339
|
+
this.sandboxMode = fields.sandboxMode;
|
|
340
|
+
this.configOverrides = fields.configOverrides;
|
|
341
|
+
this.allowCodexMcp = fields.allowCodexMcp;
|
|
342
|
+
this.boundTools = fields.tools;
|
|
343
|
+
this.n8nContext = fields.n8nContext;
|
|
344
|
+
}
|
|
345
|
+
_llmType() {
|
|
346
|
+
return 'codex-pro-cli';
|
|
347
|
+
}
|
|
348
|
+
bindTools(tools, _kwargs) {
|
|
349
|
+
return new CodexProChatModel({
|
|
350
|
+
credentials: this.credentials,
|
|
351
|
+
modelId: this.modelId,
|
|
352
|
+
timeout: this.timeout,
|
|
353
|
+
maxRetries: this.maxRetries,
|
|
354
|
+
sandboxMode: this.sandboxMode,
|
|
355
|
+
configOverrides: this.configOverrides,
|
|
356
|
+
allowCodexMcp: this.allowCodexMcp,
|
|
357
|
+
tools: convertTools(tools),
|
|
358
|
+
n8nContext: this.n8nContext,
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
_isRetryableError(error) {
|
|
362
|
+
if (!(error instanceof Error))
|
|
363
|
+
return false;
|
|
364
|
+
const msg = error.message;
|
|
365
|
+
return (msg.includes('timed out') ||
|
|
366
|
+
msg.includes('ECONNRESET') ||
|
|
367
|
+
msg.includes('ETIMEDOUT') ||
|
|
368
|
+
msg.includes('spawn') ||
|
|
369
|
+
msg.includes('exit code'));
|
|
370
|
+
}
|
|
371
|
+
async _withRetry(fn) {
|
|
372
|
+
let lastError;
|
|
373
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
374
|
+
try {
|
|
375
|
+
return await fn();
|
|
376
|
+
}
|
|
377
|
+
catch (error) {
|
|
378
|
+
lastError = error;
|
|
379
|
+
if (attempt < this.maxRetries && this._isRetryableError(error)) {
|
|
380
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * (attempt + 1)));
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
throw error;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
throw lastError;
|
|
387
|
+
}
|
|
388
|
+
async _invokeCodex(messages, options) {
|
|
389
|
+
const tools = options.tools?.length ? options.tools : this.boundTools ?? [];
|
|
390
|
+
const prompt = buildCodexPrompt(messages, tools, this.allowCodexMcp);
|
|
391
|
+
const raw = await runCodexExec({
|
|
392
|
+
credentials: this.credentials,
|
|
393
|
+
modelId: this.modelId,
|
|
394
|
+
prompt,
|
|
395
|
+
timeout: this.timeout,
|
|
396
|
+
toolNames: tools.map((tool) => tool.name),
|
|
397
|
+
sandboxMode: this.sandboxMode,
|
|
398
|
+
configOverrides: this.configOverrides,
|
|
399
|
+
});
|
|
400
|
+
const parsed = parseStructuredResult(raw, tools);
|
|
401
|
+
const toolCalls = parsed.mode === 'tool_calls'
|
|
402
|
+
? parsed.tool_calls.map((call, index) => {
|
|
403
|
+
let args = {};
|
|
404
|
+
try {
|
|
405
|
+
const parsedArgs = JSON.parse(call.arguments_json);
|
|
406
|
+
if (parsedArgs && typeof parsedArgs === 'object' && !Array.isArray(parsedArgs)) {
|
|
407
|
+
args = parsedArgs;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch { }
|
|
411
|
+
return {
|
|
412
|
+
type: 'tool_call',
|
|
413
|
+
name: call.name,
|
|
414
|
+
args,
|
|
415
|
+
id: `codex_tool_${index + 1}`,
|
|
416
|
+
};
|
|
417
|
+
})
|
|
418
|
+
: [];
|
|
419
|
+
const message = new messages_1.AIMessageChunk({
|
|
420
|
+
content: parsed.response,
|
|
421
|
+
tool_calls: toolCalls.length ? toolCalls : undefined,
|
|
422
|
+
});
|
|
423
|
+
return {
|
|
424
|
+
generations: [
|
|
425
|
+
{
|
|
426
|
+
text: parsed.response,
|
|
427
|
+
message,
|
|
428
|
+
},
|
|
429
|
+
],
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
async _generate(messages, options, _runManager) {
|
|
433
|
+
let runIndex;
|
|
434
|
+
if (this.n8nContext) {
|
|
435
|
+
const inputPayload = messages.map((msg) => ({
|
|
436
|
+
json: {
|
|
437
|
+
role: msg._getType(),
|
|
438
|
+
content: msg.content,
|
|
439
|
+
},
|
|
440
|
+
}));
|
|
441
|
+
const result = this.n8nContext.addInputData(this.n8nContext.connectionType, [inputPayload]);
|
|
442
|
+
runIndex = result.index;
|
|
443
|
+
}
|
|
444
|
+
try {
|
|
445
|
+
const chatResult = await this._withRetry(() => this._invokeCodex(messages, options));
|
|
446
|
+
if (this.n8nContext && runIndex !== undefined) {
|
|
447
|
+
const outputPayload = chatResult.generations.map((generation) => ({
|
|
448
|
+
json: {
|
|
449
|
+
text: generation.text,
|
|
450
|
+
toolCalls: generation.message.tool_calls || [],
|
|
451
|
+
},
|
|
452
|
+
}));
|
|
453
|
+
this.n8nContext.addOutputData(this.n8nContext.connectionType, runIndex, [outputPayload]);
|
|
454
|
+
}
|
|
455
|
+
return chatResult;
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
if (this.n8nContext && runIndex !== undefined) {
|
|
459
|
+
this.n8nContext.addOutputData(this.n8nContext.connectionType, runIndex, error);
|
|
460
|
+
}
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
async *_streamResponseChunks(messages, options, runManager) {
|
|
465
|
+
const result = await this._generate(messages, options, runManager);
|
|
466
|
+
const generation = result.generations[0];
|
|
467
|
+
const text = generation?.text || '';
|
|
468
|
+
if (text) {
|
|
469
|
+
await runManager?.handleLLMNewToken(text);
|
|
470
|
+
}
|
|
471
|
+
yield new outputs_1.ChatGenerationChunk({
|
|
472
|
+
text,
|
|
473
|
+
message: generation.message,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
class CodexPro {
|
|
478
|
+
description = {
|
|
479
|
+
displayName: 'Codex Pro LM',
|
|
480
|
+
name: 'codexPro',
|
|
481
|
+
icon: 'file:codex-pro.svg',
|
|
482
|
+
group: ['transform'],
|
|
483
|
+
version: 1,
|
|
484
|
+
subtitle: '={{$parameter["model"]}}',
|
|
485
|
+
description: 'Language Model node backed by the local Codex CLI login and ~/.codex/auth.json.',
|
|
486
|
+
defaults: {
|
|
487
|
+
name: 'Codex Pro LM',
|
|
488
|
+
},
|
|
489
|
+
codex: {
|
|
490
|
+
categories: ['AI'],
|
|
491
|
+
subcategories: {
|
|
492
|
+
AI: ['Language Models', 'Root Nodes'],
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
inputs: [],
|
|
496
|
+
outputs: [n8n_workflow_1.NodeConnectionTypes.AiLanguageModel],
|
|
497
|
+
outputNames: ['Model'],
|
|
498
|
+
credentials: [
|
|
499
|
+
{
|
|
500
|
+
name: 'codexProApi',
|
|
501
|
+
required: true,
|
|
502
|
+
},
|
|
503
|
+
],
|
|
504
|
+
properties: [
|
|
505
|
+
{
|
|
506
|
+
displayName: 'Model',
|
|
507
|
+
name: 'model',
|
|
508
|
+
type: 'options',
|
|
509
|
+
options: DEFAULT_MODELS,
|
|
510
|
+
default: 'gpt-5-codex',
|
|
511
|
+
description: 'The Codex / GPT-5 model to use through the local Codex CLI.',
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
displayName: 'Options',
|
|
515
|
+
name: 'options',
|
|
516
|
+
type: 'collection',
|
|
517
|
+
placeholder: 'Add Option',
|
|
518
|
+
default: {},
|
|
519
|
+
description: 'Open `Add Option` to configure Codex-specific controls. Defaults: Reasoning Effort = High, Sandbox Mode = Read Only, Allow Codex MCP = Off, Timeout = 300000 ms, Max Retries = 1.',
|
|
520
|
+
options: [
|
|
521
|
+
{
|
|
522
|
+
displayName: 'Reasoning Effort',
|
|
523
|
+
name: 'reasoningEffort',
|
|
524
|
+
type: 'options',
|
|
525
|
+
options: [
|
|
526
|
+
{ name: 'Low', value: 'low' },
|
|
527
|
+
{ name: 'Medium', value: 'medium' },
|
|
528
|
+
{ name: 'High', value: 'high' },
|
|
529
|
+
],
|
|
530
|
+
default: 'high',
|
|
531
|
+
description: 'Default: High. Passed to Codex as `-c model_reasoning_effort="<value>"`.',
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
displayName: 'Sandbox Mode',
|
|
535
|
+
name: 'sandboxMode',
|
|
536
|
+
type: 'options',
|
|
537
|
+
options: [
|
|
538
|
+
{ name: 'Read Only', value: 'read-only' },
|
|
539
|
+
{ name: 'Workspace Write', value: 'workspace-write' },
|
|
540
|
+
{ name: 'Danger Full Access', value: 'danger-full-access' },
|
|
541
|
+
],
|
|
542
|
+
default: 'read-only',
|
|
543
|
+
description: 'Default: Read Only. Sandbox policy passed to `codex exec -s`.',
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
displayName: 'Allow Codex MCP',
|
|
547
|
+
name: 'allowCodexMcp',
|
|
548
|
+
type: 'boolean',
|
|
549
|
+
default: false,
|
|
550
|
+
description: 'Default: Off. Allow Codex to use MCP servers configured in `CODEX_HOME/config.toml`. Leave off if you want the node limited to plain model behavior plus n8n tools only.',
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
displayName: 'Timeout (ms)',
|
|
554
|
+
name: 'timeout',
|
|
555
|
+
type: 'number',
|
|
556
|
+
typeOptions: { minValue: 1000 },
|
|
557
|
+
default: DEFAULT_TIMEOUT_MS,
|
|
558
|
+
description: 'Default: 300000 ms. Maximum time in milliseconds to wait for the local Codex CLI.',
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
displayName: 'Max Retries',
|
|
562
|
+
name: 'maxRetries',
|
|
563
|
+
type: 'number',
|
|
564
|
+
typeOptions: { minValue: 0, maxValue: 5 },
|
|
565
|
+
default: DEFAULT_MAX_RETRIES,
|
|
566
|
+
description: 'Default: 1. Number of retries after transient Codex CLI failures.',
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
displayName: 'Codex Config Overrides',
|
|
570
|
+
name: 'configOverrides',
|
|
571
|
+
type: 'string',
|
|
572
|
+
typeOptions: {
|
|
573
|
+
rows: 4,
|
|
574
|
+
},
|
|
575
|
+
default: '',
|
|
576
|
+
description: 'One `key=value` override per line. Each line is passed to Codex as `-c key=value`, matching `codex exec --config` behavior.',
|
|
577
|
+
},
|
|
578
|
+
],
|
|
579
|
+
},
|
|
580
|
+
],
|
|
581
|
+
};
|
|
582
|
+
async supplyData(itemIndex) {
|
|
583
|
+
const credentials = await this.getCredentials('codexProApi');
|
|
584
|
+
const cliCredentials = getCliCredentials(credentials);
|
|
585
|
+
const modelId = this.getNodeParameter('model', itemIndex);
|
|
586
|
+
const options = this.getNodeParameter('options', itemIndex, {});
|
|
587
|
+
const timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
588
|
+
const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
589
|
+
const sandboxMode = (options.sandboxMode ?? 'read-only');
|
|
590
|
+
const allowCodexMcp = Boolean(options.allowCodexMcp);
|
|
591
|
+
const reasoningEffort = typeof options.reasoningEffort === 'string' ? options.reasoningEffort.trim() : 'high';
|
|
592
|
+
const rawConfigOverrides = typeof options.configOverrides === 'string' ? options.configOverrides : '';
|
|
593
|
+
const configOverrides = rawConfigOverrides
|
|
594
|
+
.split('\n')
|
|
595
|
+
.map((line) => line.trim())
|
|
596
|
+
.filter(Boolean);
|
|
597
|
+
if (reasoningEffort) {
|
|
598
|
+
configOverrides.unshift(`model_reasoning_effort="${reasoningEffort}"`);
|
|
599
|
+
}
|
|
600
|
+
const model = new CodexProChatModel({
|
|
601
|
+
credentials: cliCredentials,
|
|
602
|
+
modelId,
|
|
603
|
+
timeout,
|
|
604
|
+
maxRetries,
|
|
605
|
+
sandboxMode,
|
|
606
|
+
configOverrides,
|
|
607
|
+
allowCodexMcp,
|
|
608
|
+
n8nContext: {
|
|
609
|
+
addInputData: this.addInputData.bind(this),
|
|
610
|
+
addOutputData: this.addOutputData.bind(this),
|
|
611
|
+
connectionType: n8n_workflow_1.NodeConnectionTypes.AiLanguageModel,
|
|
612
|
+
},
|
|
613
|
+
});
|
|
614
|
+
return { response: model };
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
exports.CodexPro = CodexPro;
|
|
618
|
+
//# sourceMappingURL=CodexPro.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CodexPro.node.js","sourceRoot":"","sources":["../../../nodes/CodexPro/CodexPro.node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="none">
|
|
2
|
+
<rect width="256" height="256" rx="48" fill="#111827"/>
|
|
3
|
+
<path d="M128 48c-44.183 0-80 35.817-80 80s35.817 80 80 80c22.903 0 43.56-9.625 58.153-25.056l-22.667-18.223C154.087 173.711 141.7 180 128 180c-28.719 0-52-23.281-52-52s23.281-52 52-52c13.7 0 26.087 6.289 35.486 16.279l22.667-18.223C171.56 57.625 150.903 48 128 48Z" fill="#10A37F"/>
|
|
4
|
+
<path d="M156 96h28v64h-28z" fill="#10A37F"/>
|
|
5
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n8n-nodes-codex-pro",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "n8n node for local Codex CLI authentication via `codex login`, suitable for Codex-backed AI Agent workflows.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"n8n-community-node-package",
|
|
7
|
+
"n8n",
|
|
8
|
+
"openai",
|
|
9
|
+
"codex",
|
|
10
|
+
"gpt-5",
|
|
11
|
+
"ai",
|
|
12
|
+
"llm"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "bloodshop"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"main": "dist/nodes/CodexPro/CodexPro.node.js",
|
|
25
|
+
"n8n": {
|
|
26
|
+
"n8nNodesApiVersion": 1,
|
|
27
|
+
"nodes": [
|
|
28
|
+
"dist/nodes/CodexPro/CodexPro.node.js"
|
|
29
|
+
],
|
|
30
|
+
"credentials": [
|
|
31
|
+
"dist/credentials/CodexProApi.credentials.js"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc && cp nodes/CodexPro/codex-pro.svg dist/nodes/CodexPro/codex-pro.svg && cp credentials/codex-cli-auth.svg dist/credentials/codex-cli-auth.svg",
|
|
36
|
+
"dev": "tsc --watch",
|
|
37
|
+
"prepublishOnly": "npm run build",
|
|
38
|
+
"pack:check": "npm pack --dry-run"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE"
|
|
44
|
+
],
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@langchain/core": ">=0.3.0",
|
|
47
|
+
"n8n-workflow": "*"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@langchain/core": ">=0.3.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.15.30",
|
|
54
|
+
"n8n-workflow": "^2.13.1",
|
|
55
|
+
"typescript": "^5.7.0"
|
|
56
|
+
}
|
|
57
|
+
}
|