Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/senpi-qa/references/env-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The first present key wins; `devenv-setup.mjs` seeds `.env.local` from it.
`MISTRAL_API_KEY`, `MINIMAX_API_KEY`, `MOONSHOT_API_KEY`, `KIMI_API_KEY`,
`OPENCODE_API_KEY`, `CLOUDFLARE_API_KEY` (+ `CLOUDFLARE_ACCOUNT_ID` /
`CLOUDFLARE_GATEWAY_ID`), `XIAOMI_API_KEY` (+ regional token-plan keys),
`ALIBABA_TOKEN_PLAN_API_KEY`,
`ALIBABA_TOKEN_PLAN_API_KEY`, `NEURALWATT_API_KEY`,
`HF_TOKEN`, and the AWS Bedrock / Google Vertex variable sets.

OAuth-only subscription providers have no env key: `openai-codex` and
Expand Down
1 change: 1 addition & 0 deletions .agents/skills/senpi-qa/scripts/lib/mock-loop-support.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const PROVIDER_ENV_KEYS = [
"FIREWORKS_API_KEY", "TOGETHER_API_KEY", "OPENROUTER_API_KEY", "AI_GATEWAY_API_KEY", "ZAI_API_KEY",
"ZAI_CODING_CN_API_KEY", "MISTRAL_API_KEY", "MINIMAX_API_KEY", "MINIMAX_CN_API_KEY", "MOONSHOT_API_KEY",
"MOONSHOTAI_API_KEY", "KIMI_API_KEY", "OPENCODE_API_KEY", "CLOUDFLARE_API_KEY", "HF_TOKEN",
"NEURALWATT_API_KEY",
];

export function hermeticEnv(boxEnv) {
Expand Down
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
},
"ALIBABA_TOKEN_PLAN_API_KEY": {
"description": "(Optional) Alibaba Cloud Model Studio Token Plan API key (ap-southeast-1)."
},
"NEURALWATT_API_KEY": {
"description": "(Optional) Neuralwatt API key (Neuralwatt's OpenAI-compatible inference endpoint)."
}
},
"customizations": {
Expand Down
2 changes: 2 additions & 0 deletions packages/ai/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and

- **OpenAI**
- **Ant Ling**
- **Neuralwatt**
- **Azure OpenAI (Responses)**
- **OpenAI Codex** (ChatGPT Plus/Pro subscription, requires OAuth, see below)
- **DeepSeek**
Expand Down Expand Up @@ -419,6 +420,7 @@ Built-in providers resolve these env vars (Node.js; in browsers pass `apiKey` ex
| OpenAI | `OPENAI_API_KEY` |
| Ollama Cloud | `OLLAMA_API_KEY` |
| Ant Ling | `ANT_LING_API_KEY` |
| Neuralwatt | `NEURALWATT_API_KEY` |
| Azure OpenAI | `AZURE_OPENAI_API_KEY` + `AZURE_OPENAI_BASE_URL` (e.g. `https://{resource}.ai.azure.com`) or `AZURE_OPENAI_RESOURCE_NAME`. Supports `*.openai.azure.com`, `*.cognitiveservices.azure.com` and `*.ai.azure.com`; root endpoints auto-normalize to `/openai/v1`. Optional: `AZURE_OPENAI_API_VERSION` (default `v1`), `AZURE_OPENAI_DEPLOYMENT_NAME_MAP`. |
| Anthropic | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
| DeepSeek | `DEEPSEEK_API_KEY` |
Expand Down
296 changes: 296 additions & 0 deletions packages/ai/scripts/generate-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3038,6 +3038,302 @@ async function generateModels() {
}
}

const neuralwattCompat: OpenAICompletionsCompat = {
supportsStore: false,
supportsDeveloperRole: false,
supportsReasoningEffort: false,
maxTokensField: "max_tokens",
};
const neuralwattModels: Model<"openai-completions">[] = [
{
id: "qwen3.6-35b-fast",
name: "Qwen3.6 35B Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.29, output: 1.15, cacheRead: 0.0725, cacheWrite: 0 },
contextWindow: 131056,
maxTokens: 131056,
compat: neuralwattCompat,
},
{
id: "kimi-k3",
name: "Kimi K3",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 1048560,
compat: neuralwattCompat,
},
{
id: "deepseek-v4-flash",
name: "DeepSeek V4 Flash",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 0.104, output: 0.207, cacheRead: 0.026, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 65536,
compat: neuralwattCompat,
},
{
id: "kimi-k3-fast",
name: "Kimi K3 Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 1048560,
compat: neuralwattCompat,
},
{
id: "glm-5.2-fast",
name: "GLM 5.2 Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text"],
cost: { input: 1.45, output: 4.5, cacheRead: 0.3625, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 1048560,
compat: neuralwattCompat,
},
{
id: "glm-5.2-flex",
name: "GLM 5.2 Flex",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 0.725, output: 2.25, cacheRead: 0.18125, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 1048560,
compat: neuralwattCompat,
},
{
id: "glm-5.2-short",
name: "GLM 5.2 Short",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 1.45, output: 4.5, cacheRead: 0.3625, cacheWrite: 0 },
contextWindow: 199984,
maxTokens: 199984,
compat: neuralwattCompat,
},
{
id: "gemma-4-31b",
name: "Gemma 4 31B",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.144, output: 0.42, cacheRead: 0.036, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 16384,
compat: neuralwattCompat,
},
{
id: "kimi-k2.5-fast",
name: "Kimi K2.5 Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.52, output: 2.59, cacheRead: 0.13, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "kimi-k2.6-flex",
name: "Kimi K2.6 Flex",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.345, output: 1.61, cacheRead: 0.08625, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "qwen3.5-397b-fast",
name: "Qwen3.5 397B Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text"],
cost: { input: 0.69, output: 4.14, cacheRead: 0.1725, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "glm-5.2-short-fast-flex",
name: "GLM 5.2 Short Fast Flex",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text"],
cost: { input: 0.725, output: 2.25, cacheRead: 0.18125, cacheWrite: 0 },
contextWindow: 199984,
maxTokens: 199984,
compat: neuralwattCompat,
},
{
id: "glm-5.2",
name: "GLM 5.2",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 1.45, output: 4.5, cacheRead: 0.3625, cacheWrite: 0 },
contextWindow: 1048560,
maxTokens: 1048560,
compat: neuralwattCompat,
},
{
id: "kimi-k2.6-fast",
name: "Kimi K2.6 Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text", "image"],
cost: { input: 0.69, output: 3.22, cacheRead: 0.1725, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "glm-5.2-short-fast",
name: "GLM 5.2 Short Fast",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: false,
input: ["text"],
cost: { input: 1.45, output: 4.5, cacheRead: 0.3625, cacheWrite: 0 },
contextWindow: 199984,
maxTokens: 199984,
compat: neuralwattCompat,
},
{
id: "kimi-k2.7-code-flex",
name: "Kimi K2.7 Code Flex",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.475, output: 2, cacheRead: 0.11875, cacheWrite: 0 },
contextWindow: 262144,
maxTokens: 262144,
compat: neuralwattCompat,
},
{
id: "glm-5.2-short-flex",
name: "GLM 5.2 Short Flex",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 0.725, output: 2.25, cacheRead: 0.18125, cacheWrite: 0 },
contextWindow: 199984,
maxTokens: 199984,
compat: neuralwattCompat,
},
{
id: "moonshotai/Kimi-K2.5",
name: "Kimi K2.5",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.52, output: 2.59, cacheRead: 0.13, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "moonshotai/Kimi-K2.7-Code",
name: "Kimi K2.7 Code",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.95, output: 4, cacheRead: 0.2375, cacheWrite: 0 },
contextWindow: 262144,
maxTokens: 262144,
compat: neuralwattCompat,
},
{
id: "moonshotai/Kimi-K2.6",
name: "Kimi K2.6",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.69, output: 3.22, cacheRead: 0.1725, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "Qwen/Qwen3.5-397B-A17B-FP8",
name: "Qwen3.5 397B A17B FP8",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text"],
cost: { input: 0.69, output: 4.14, cacheRead: 0.1725, cacheWrite: 0 },
contextWindow: 262128,
maxTokens: 262128,
compat: neuralwattCompat,
},
{
id: "Qwen/Qwen3.6-35B-A3B",
name: "Qwen3.6 35B A3B",
api: "openai-completions",
baseUrl: "https://api.neuralwatt.com/v1",
provider: "neuralwatt",
reasoning: true,
input: ["text", "image"],
cost: { input: 0.29, output: 1.15, cacheRead: 0.0725, cacheWrite: 0 },
contextWindow: 131056,
maxTokens: 131056,
compat: neuralwattCompat,
},
];
allModels.push(...neuralwattModels);

const minimaxDirectSupportedIds = new Set(["MiniMax-M2.7", "MiniMax-M2.7-highspeed", "MiniMax-M3"]);

for (let i = allModels.length - 1; i >= 0; i--) {
Expand Down
43 changes: 43 additions & 0 deletions packages/ai/src/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,49 @@ The divergence lives in core wiring, package identity, or build plumbing that ex
### Expected merge conflict zones

- LOW: Cursor `resource_exhausted` handling in `packages/ai/src/utils/overflow.ts`.
## 2026-08-21 - Add Neuralwatt provider

### What changed

- `packages/ai/scripts/generate-models.ts`: 22-model `neuralwatt` catalog block (`openai-completions`
API, ant-ling entry pattern).
- `packages/ai/src/env-api-keys.ts`: maps `NEURALWATT_API_KEY`.
- `packages/ai/src/types.ts`: `neuralwatt` joins the `KnownProvider` union.
- `packages/ai/src/providers/all.ts`: registers the Neuralwatt factory in the `builtinProviders()` list.
- `packages/ai/src/providers/neuralwatt.ts` and `packages/ai/src/providers/neuralwatt.models.ts` (new):
provider factory and catalog module.
- `packages/ai/README.md`: Neuralwatt bullet in the provider list and a `NEURALWATT_API_KEY` row in the
env-var matrix.
- Test files: provider unit/request tests and env-key coverage under `packages/ai/test/`,
model-resolver coverage under `packages/coding-agent/test/`.
- Coding-agent mirror files: the `Record<KnownProvider, ...>` maps and display-name entries in
`packages/coding-agent/src/cli/args.ts`, `src/core/model-config.ts`, `src/core/model-config-schema.ts`,
`src/core/model-resolver.ts`, `src/core/provider-display-names.ts`, plus
`packages/coding-agent/docs/providers.md`.
- Infra mirror files: `.devcontainer/devcontainer.json`, the `test.sh` / `pi-test.sh` env-unset lists,
and the senpi-qa skill env-vars reference / mock-loop support.
- Generated artifacts: `packages/ai/src/models.generated.ts` and `packages/ai/src/providers/data/`
(including `neuralwatt.json`) — resolve by regenerating.

### Why

- Neuralwatt is a public OpenAI-compatible Korean inference API (docs:
https://portal.neuralwatt.com/docs, free tier) that omo-native/senpi users currently cannot reach
without per-user `models.json` overlays; adding it as a built-in provider lets users configure only
an API key.

### Why an extension could not handle it

- Built-in provider catalogs and env-key detection live in `packages/ai` core; extensions cannot
register a builtin catalog provider or contribute to the `KnownProvider` union /
`builtinProviders()` map / env-api-keys map.

### Expected merge conflict zones

- `packages/ai/src/env-api-keys.ts` env-key map.
- `packages/ai/src/providers/all.ts` `builtinProviders` list.
- `packages/ai/src/types.ts` `KnownProvider` union.
- `packages/ai/scripts/generate-models.ts` ant-ling-adjacent block.

## Unreleased

Expand Down
Loading