converse-mcp-server 4.1.1 → 4.2.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/.env.example +1 -1
- package/README.md +4 -4
- package/docs/API.md +6 -4
- package/docs/EXAMPLES.md +1 -1
- package/docs/PROVIDERS.md +3 -3
- package/package.json +1 -1
- package/src/decisionProviders/systemOne.js +50 -4
- package/src/providers/codex.js +1 -1
package/.env.example
CHANGED
|
@@ -91,7 +91,7 @@ TYPESAFE_API_KEY=your_typesafe_api_key_here
|
|
|
91
91
|
# The model a bare provider name ("codex", "openai", ...) and "auto" use.
|
|
92
92
|
# Each must be a model ID or alias from that provider's catalog; startup fails
|
|
93
93
|
# with "did you mean" suggestions otherwise. Per request, use "provider:model".
|
|
94
|
-
# CODEX_DEFAULT_MODEL=gpt-6-
|
|
94
|
+
# CODEX_DEFAULT_MODEL=gpt-6-astra # gpt-6-sol, gpt-6-luna, gpt-6-astra, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.3-codex-spark (CODEX_MODEL is the legacy name)
|
|
95
95
|
# CLAUDE_DEFAULT_MODEL=claude-opus-5-5
|
|
96
96
|
# AGY_DEFAULT_MODEL=gemini-3.8-flash # Antigravity CLI: gemini-3.8-flash, gemini-3.1-pro-preview
|
|
97
97
|
# COPILOT_DEFAULT_MODEL=gpt-6-sol # COPILOT_MODEL is the legacy name
|
package/README.md
CHANGED
|
@@ -304,7 +304,7 @@ Any other model works via its full `provider/model` slug or the `openrouter:` na
|
|
|
304
304
|
|
|
305
305
|
### Codex Models
|
|
306
306
|
|
|
307
|
-
OpenAI Codex agentic coding assistant. `codex` uses its default model (GPT-6
|
|
307
|
+
OpenAI Codex agentic coding assistant. `codex` uses its default model (GPT-6 Astra, or `CODEX_DEFAULT_MODEL`); `codex:<model>` picks one (e.g. `codex:luna`, `codex:astra`, `codex:gpt-5.6-terra`):
|
|
308
308
|
|
|
309
309
|
- **gpt-6-sol** (default; aliases: `sol`, `gpt-6`), **gpt-6-luna** (`luna`), **gpt-6-astra** (`astra`)
|
|
310
310
|
- **gpt-5.6-sol** (`gpt-5.6`), **gpt-5.6-terra** (`terra`), **gpt-5.6-luna**, **gpt-5.5**, **gpt-5.3-codex-spark** (`spark`)
|
|
@@ -388,7 +388,7 @@ CODEX_APPROVAL_POLICY=never # never (default), untrusted, on-fa
|
|
|
388
388
|
# Optional: per-provider default model, used for a bare provider name (`codex`,
|
|
389
389
|
# `openai`, ...) and for "auto". Must be a model or alias from that provider's
|
|
390
390
|
# list; startup fails with suggestions otherwise.
|
|
391
|
-
CODEX_DEFAULT_MODEL=gpt-6-
|
|
391
|
+
CODEX_DEFAULT_MODEL=gpt-6-astra # CODEX_MODEL still works as a fallback
|
|
392
392
|
CLAUDE_DEFAULT_MODEL=claude-opus-5-5
|
|
393
393
|
AGY_DEFAULT_MODEL=gemini-3.8-flash # Antigravity CLI (gemini)
|
|
394
394
|
COPILOT_DEFAULT_MODEL=gpt-6-sol # COPILOT_MODEL still works as a fallback
|
|
@@ -459,7 +459,7 @@ Every entry in `models` takes one of four forms:
|
|
|
459
459
|
"auto";
|
|
460
460
|
|
|
461
461
|
// A provider: its default model (hardcoded, or <PROVIDER>_DEFAULT_MODEL)
|
|
462
|
-
"codex"; // -> Codex (GPT-6
|
|
462
|
+
"codex"; // -> Codex (GPT-6 Astra)
|
|
463
463
|
"claude"; // -> Claude Agent SDK (Claude Opus 5.5)
|
|
464
464
|
"gemini"; // -> Antigravity CLI (Gemini 3.8 Flash); `agy` works too
|
|
465
465
|
"openai"; // -> OpenAI API (GPT-6 Sol)
|
|
@@ -492,7 +492,7 @@ Every entry in `models` takes one of four forms:
|
|
|
492
492
|
|
|
493
493
|
Provider priority order (subscription-based local providers first, then API-key providers), used by both `auto` and bare model names:
|
|
494
494
|
|
|
495
|
-
1. Codex (`codex` → GPT-6
|
|
495
|
+
1. Codex (`codex` → GPT-6 Astra)
|
|
496
496
|
2. Gemini via Antigravity CLI (`gemini` / `agy` → Gemini 3.8 Flash)
|
|
497
497
|
3. Claude Agent SDK (`claude` → Claude Opus 5.5)
|
|
498
498
|
4. Copilot (`copilot` → GPT-6 Sol; `auto` only, never bare names)
|
package/docs/API.md
CHANGED
|
@@ -422,6 +422,8 @@ Only jobs in a `queued` or `running` state can be cancelled; already-completed,
|
|
|
422
422
|
|
|
423
423
|
Each provider call retries timeouts, 408, 429 and 5xx with backoff, honoring `Retry-After`. Auth failures, exhausted retries and malformed responses fall back to the next provider. A 400/422 request fault stops immediately, because every host would reject it the same way.
|
|
424
424
|
|
|
425
|
+
TypeSafe's API sits behind a Cloudflare firewall that rejects some request bodies containing SQL-injection or shell-command patterns (for example `-- ; DROP TABLE`, or a quoted `'...; DROP TABLE ...;'`) with a 403 before the model sees them. This applies through OpenRouter too, since it forwards to the same edge. `decide` reports it as `Blocked by typesafe.ai's Cloudflare firewall before reaching the model (Ray ID …)` and stops without retrying or falling back. Treat a block as an unanswered question, not as a decision, and report the Ray ID to TypeSafe.
|
|
426
|
+
|
|
425
427
|
### Example Usage
|
|
426
428
|
|
|
427
429
|
```json
|
|
@@ -564,7 +566,7 @@ Any other model works via its full `provider/model` slug (e.g. `anthropic/claude
|
|
|
564
566
|
|
|
565
567
|
**Codex** is an agentic coding assistant with direct filesystem access:
|
|
566
568
|
|
|
567
|
-
- **Model**: `codex` (underlying model: GPT-6
|
|
569
|
+
- **Model**: `codex` (underlying model: GPT-6 Astra by default, or `CODEX_DEFAULT_MODEL`)
|
|
568
570
|
- **Backend selection**: `codex:<model>` per request (e.g. `codex:luna`, `codex:astra`, `codex:gpt-5.6-terra`) from the Codex catalog: `gpt-6-sol` (`sol`, `gpt-6`), `gpt-6-luna` (`luna`), `gpt-6-astra` (`astra`), `gpt-5.6-sol` (`gpt-5.6`), `gpt-5.6-terra` (`terra`), `gpt-5.6-luna`, `gpt-5.5`, `gpt-5.3-codex-spark` (`spark`). Other names are rejected with suggestions. Bare IDs from this list (e.g. `gpt-6-astra`) go to Codex first, then the OpenAI API.
|
|
569
571
|
- **Availability**: the Codex SDK is installed and `~/.codex/auth.json` exists (`$CODEX_HOME/auth.json` when set) or `CODEX_API_KEY` is set
|
|
570
572
|
- **Thread-based sessions**: persistent conversation history via `continuation_id` in `chat` mode
|
|
@@ -682,7 +684,7 @@ Control Codex behavior through environment variables:
|
|
|
682
684
|
- **`CODEX_SANDBOX_MODE`** — filesystem access: `read-only` (default), `workspace-write`, `danger-full-access` (containers only)
|
|
683
685
|
- **`CODEX_SKIP_GIT_CHECK`** — `true` (default) works in any directory; `false` requires a Git repository
|
|
684
686
|
- **`CODEX_APPROVAL_POLICY`** — `never` (default, recommended for servers), `untrusted`, `on-failure`, `on-request`
|
|
685
|
-
- **`CODEX_DEFAULT_MODEL`** — model used for `codex` and `auto` (default: `gpt-6-
|
|
687
|
+
- **`CODEX_DEFAULT_MODEL`** — model used for `codex` and `auto` (default: `gpt-6-astra`); the legacy name `CODEX_MODEL` is honored when it is unset
|
|
686
688
|
- **`CODEX_API_KEY`** — optional API key for headless deployments (alternative to ChatGPT login)
|
|
687
689
|
|
|
688
690
|
**Example (.env):**
|
|
@@ -691,7 +693,7 @@ CODEX_API_KEY=your_codex_api_key_here
|
|
|
691
693
|
CODEX_SANDBOX_MODE=read-only
|
|
692
694
|
CODEX_SKIP_GIT_CHECK=true
|
|
693
695
|
CODEX_APPROVAL_POLICY=never
|
|
694
|
-
CODEX_DEFAULT_MODEL=gpt-6-
|
|
696
|
+
CODEX_DEFAULT_MODEL=gpt-6-astra
|
|
695
697
|
```
|
|
696
698
|
|
|
697
699
|
### Default Models
|
|
@@ -699,7 +701,7 @@ CODEX_DEFAULT_MODEL=gpt-6-sol
|
|
|
699
701
|
Each provider's default model (used for its bare provider name and for `auto`) can be set with `<PROVIDER>_DEFAULT_MODEL`. The value must be a model ID or alias from that provider's list; startup fails with "Did you mean" suggestions otherwise (OpenRouter also accepts any `vendor/model` slug).
|
|
700
702
|
|
|
701
703
|
```bash
|
|
702
|
-
CODEX_DEFAULT_MODEL=gpt-6-
|
|
704
|
+
CODEX_DEFAULT_MODEL=gpt-6-astra # CODEX_MODEL is honored as a legacy fallback
|
|
703
705
|
CLAUDE_DEFAULT_MODEL=claude-opus-5-5
|
|
704
706
|
AGY_DEFAULT_MODEL=gemini-3.8-flash # Antigravity CLI (gemini)
|
|
705
707
|
COPILOT_DEFAULT_MODEL=gpt-6-sol # COPILOT_MODEL is honored as a legacy fallback
|
package/docs/EXAMPLES.md
CHANGED
|
@@ -446,7 +446,7 @@ Codex maintains conversation history through threads in `chat` mode:
|
|
|
446
446
|
|
|
447
447
|
### Choosing the Codex Model
|
|
448
448
|
|
|
449
|
-
`codex` uses GPT-6
|
|
449
|
+
`codex` uses GPT-6 Astra (or `CODEX_DEFAULT_MODEL`); `codex:<model>` picks another model from the Codex list:
|
|
450
450
|
|
|
451
451
|
```json
|
|
452
452
|
{
|
package/docs/PROVIDERS.md
CHANGED
|
@@ -106,9 +106,9 @@ This guide documents all supported AI providers in the Converse MCP Server and t
|
|
|
106
106
|
- `CODEX_SANDBOX_MODE` - Filesystem access control (default: read-only)
|
|
107
107
|
- `CODEX_SKIP_GIT_CHECK` - Skip Git repository validation (default: true)
|
|
108
108
|
- `CODEX_APPROVAL_POLICY` - Command approval behavior (default: never)
|
|
109
|
-
- `CODEX_DEFAULT_MODEL` - Model used for bare `codex` and `auto` (default: `gpt-6-
|
|
109
|
+
- `CODEX_DEFAULT_MODEL` - Model used for bare `codex` and `auto` (default: `gpt-6-astra`; any Codex model ID or alias below). The legacy name `CODEX_MODEL` is honored when `CODEX_DEFAULT_MODEL` is unset.
|
|
110
110
|
- **Supported Models**:
|
|
111
|
-
- `codex` - OpenAI Codex agentic coding assistant (GPT-6
|
|
111
|
+
- `codex` - OpenAI Codex agentic coding assistant (GPT-6 Astra by default)
|
|
112
112
|
- `codex:<model>` - Same, with an explicit backend from the Codex catalog:
|
|
113
113
|
- `gpt-6-sol` (aliases: `sol`, `gpt-6`), `gpt-6-luna` (`luna`), `gpt-6-astra` (`astra`)
|
|
114
114
|
- `gpt-5.6-sol` (`gpt-5.6`), `gpt-5.6-terra` (`terra`), `gpt-5.6-luna`, `gpt-5.5`, `gpt-5.3-codex-spark` (`spark`)
|
|
@@ -278,7 +278,7 @@ CODEX_APPROVAL_POLICY=never # never (default), untrusted, on-fa
|
|
|
278
278
|
Each provider has a `<PROVIDER>_DEFAULT_MODEL` variable that sets the model used for its bare provider name (`codex`, `openai`, ...) and for `auto`. The value must be a model ID or alias from that provider's list; startup fails with "Did you mean" suggestions otherwise. OpenRouter also accepts any `vendor/model` slug.
|
|
279
279
|
|
|
280
280
|
```bash
|
|
281
|
-
CODEX_DEFAULT_MODEL=gpt-6-
|
|
281
|
+
CODEX_DEFAULT_MODEL=gpt-6-astra # CODEX_MODEL is honored as a legacy fallback
|
|
282
282
|
CLAUDE_DEFAULT_MODEL=claude-opus-5-5
|
|
283
283
|
AGY_DEFAULT_MODEL=gemini-3.8-flash # Antigravity CLI (gemini)
|
|
284
284
|
COPILOT_DEFAULT_MODEL=gpt-6-sol # COPILOT_MODEL is honored as a legacy fallback
|
package/package.json
CHANGED
|
@@ -84,6 +84,43 @@ export function extractErrorMessage(body, rawText) {
|
|
|
84
84
|
return rawText?.trim() || 'No error details returned';
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
const MAX_ERROR_MESSAGE_LENGTH = 500;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Summarize an HTML error page, which arrives raw from TypeSafe's edge and
|
|
91
|
+
* embedded in OpenRouter's JSON error message when it forwards one.
|
|
92
|
+
* Cloudflare's block page means the firewall rejected the request content
|
|
93
|
+
* before any model saw it: typically SQL-injection or shell-command patterns
|
|
94
|
+
* inside state or questions.
|
|
95
|
+
* @returns {{ message: string, firewall: boolean, rayId: string|null }|null}
|
|
96
|
+
* null when the text is not an HTML page
|
|
97
|
+
*/
|
|
98
|
+
export function describeHtmlError(text) {
|
|
99
|
+
if (!/<!doctype html|<html[\s>]/i.test(text || '')) return null;
|
|
100
|
+
const rayId = text.match(/Cloudflare Ray ID:\s*<strong[^>]*>([0-9a-f]+)</i)?.[1] ?? null;
|
|
101
|
+
if (/cloudflare/i.test(text) && /you have been blocked|Attention Required/i.test(text)) {
|
|
102
|
+
const host = text.match(/unable to access<\/span>\s*([^<\s]+)/i)?.[1] ?? 'the upstream';
|
|
103
|
+
return {
|
|
104
|
+
firewall: true,
|
|
105
|
+
rayId,
|
|
106
|
+
message:
|
|
107
|
+
`Blocked by ${host}'s Cloudflare firewall before reaching the model${rayId ? ` (Ray ID ${rayId})` : ''}: ` +
|
|
108
|
+
'the request content matched an attack signature, typically SQL-injection or shell-command patterns in state or questions. ' +
|
|
109
|
+
'Retrying the same content will not help; report the Ray ID to the provider.',
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const title = text.match(/<title>([^<]*)<\/title>/i)?.[1]?.trim();
|
|
113
|
+
return {
|
|
114
|
+
firewall: false,
|
|
115
|
+
rayId,
|
|
116
|
+
message: `Upstream returned an HTML error page${title ? `: ${title}` : ''}${rayId ? ` (Ray ID ${rayId})` : ''}`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function truncate(text) {
|
|
121
|
+
return text.length > MAX_ERROR_MESSAGE_LENGTH ? `${text.slice(0, MAX_ERROR_MESSAGE_LENGTH)}…` : text;
|
|
122
|
+
}
|
|
123
|
+
|
|
87
124
|
function parseRetryAfter(headers) {
|
|
88
125
|
const ms = Number(headers.get('retry-after-ms'));
|
|
89
126
|
if (Number.isFinite(ms) && ms > 0) return ms;
|
|
@@ -145,11 +182,20 @@ async function sendOnce({ url, headers, body, signal, timeoutMs }) {
|
|
|
145
182
|
|
|
146
183
|
if (!response.ok) {
|
|
147
184
|
const status = response.status;
|
|
148
|
-
|
|
185
|
+
const detail = extractErrorMessage(parsed, rawText);
|
|
186
|
+
const html = describeHtmlError(detail);
|
|
187
|
+
// Every host forwards to TypeSafe's edge, so a firewall block repeats on
|
|
188
|
+
// retry and on failover alike.
|
|
189
|
+
const firewall = html?.firewall === true;
|
|
190
|
+
throw new DecisionError(`HTTP ${status}: ${html ? html.message : truncate(detail)}`, {
|
|
149
191
|
status,
|
|
150
|
-
retryable: status === 408 || status === 429 || status >= 500 || status === 401 || status === 403,
|
|
151
|
-
terminal: status === 400 || status === 422,
|
|
152
|
-
requestId:
|
|
192
|
+
retryable: !firewall && (status === 408 || status === 429 || status >= 500 || status === 401 || status === 403),
|
|
193
|
+
terminal: firewall || status === 400 || status === 422,
|
|
194
|
+
requestId:
|
|
195
|
+
response.headers.get('x-typesafe-request-id') ||
|
|
196
|
+
response.headers.get('x-generation-id') ||
|
|
197
|
+
html?.rayId ||
|
|
198
|
+
response.headers.get('cf-ray'),
|
|
153
199
|
retryAfterMs: parseRetryAfter(response.headers),
|
|
154
200
|
});
|
|
155
201
|
}
|