diff --git a/English/ai-stack/ai-coding/README.md b/English/ai-stack/ai-coding/README.md index 46d4d963..74072e63 100644 --- a/English/ai-stack/ai-coding/README.md +++ b/English/ai-stack/ai-coding/README.md @@ -1,29 +1,38 @@ # AI Coding -AI Coding lets you connect popular AI coding tools — Claude Code, OpenAI SDK, IDE extensions — directly to GreenNode MaaS, using cloud models without managing API keys from external providers. +AI Coding lets you connect popular AI coding tools — Claude Code, OpenAI SDK, IDE extensions — directly to models operated by GreenNode, using cloud models without managing API keys from external providers. *** ## Architecture -Requests from your tool are redirected to the GreenNode MaaS endpoint. MaaS exposes two protocols in parallel to support all existing clients: +Requests from your tool are redirected to a GreenNode endpoint. The endpoint exposes two protocols in parallel to support all existing clients: -

Both API protocols connect to a single MaaS endpoint sharing the same Model Pool

+

Both API protocols connect to a single endpoint sharing the same Model Pool

-A single AI Platform API key works for both protocols. +A single key works for both protocols — but the **key must match the host of the service type that issued it**. -{% hint style="warning" %} -The LLM URL differs by protocol — see the table below. Using the wrong URL causes 404 errors or malformed request parsing. -{% endhint %} +*** + +## Two service types — settle this before configuring anything + +| Service type | Pricing model | Key used to call | Base URL host | +|---|---|---|---| +| **PAYG** | Pay per token actually used | API Key from **API Keys** | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| **Token Plan** | Prepaid 30-day package with a fixed token quota | subscription-key from Plan Detail → **Subscription keys** tab | `tokenplan.api.greennode.ai` | *** -## Protocol and LLM URL +## Base URL by service type and client standard + +| Service type | **Anthropic**-standard clients
(Claude Code, Anthropic SDK) | **OpenAI**-standard clients
(OpenAI SDK, LiteLLM, Cursor, Continue.dev, Codex, OpenCode) | +|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | `https://tokenplan.api.greennode.ai/v1` | -| Client | Protocol | LLM URL | -| ----------------------------------------- | ---------------------- | ---------------------------------------------------- | -| Claude Code, Anthropic SDK | Anthropic Messages API | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | -| OpenAI SDK, LiteLLM, Cursor, Continue.dev | OpenAI-compatible | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +{% hint style="warning" %} +Picking the wrong cell in this table is the most common failure: the wrong **`/v1` suffix** gives `404 Not Found`; the wrong **host for your key type** gives `401 Unauthorized` even while the key is still valid. Every tool guide has separate tabs per service type — pick your tab and copy it as-is. +{% endhint %} *** @@ -31,29 +40,32 @@ The LLM URL differs by protocol — see the table below. Using the wrong URL cau ### Claude Code -Claude Code CLI supports overriding `ANTHROPIC_BASE_URL` — pointing to GreenNode MaaS instead of Anthropic directly. All sessions, tool calls, and sub-agents route through the GreenNode endpoint, with usage visible in AI Platform Console. +Claude Code CLI supports overriding `ANTHROPIC_BASE_URL` — pointing to a GreenNode endpoint instead of Anthropic directly. All sessions, tool calls, and sub-agents route through the GreenNode endpoint, with usage visible in AI Platform Console. ### OpenAI-compatible clients -Any tool that allows setting a custom `base_url` in OpenAI SDK format works out of the box — OpenAI Python/Node.js SDK, LiteLLM, Cursor, Continue.dev, and other IDE extensions. Change the base URL and API key; no logic changes needed. +Any tool that allows setting a custom `base_url` in OpenAI SDK format works out of the box — OpenAI Python/Node.js SDK, LiteLLM, Cursor, Continue.dev, and other IDE extensions. Change the base URL and key; no logic changes needed. *** ## Billing -* **Credit-token:** 1 credit = 1 VND -* **Prepaid:** credits deducted every 5-minute collection cycle — model automatically disabled when credits run out -* **Postpaid:** usage recorded as debt with no quota limit -* View real-time usage at [AI Platform Console → Usage](https://aiplatform.console.vngcloud.vn/) +| | PAYG | Token Plan | +|---|---|---| +| Pricing | Credit-token, 1 credit = 1 VND | Fixed prepaid 30-day package | +| Quota | **Prepaid:** credits deducted every 5-minute collection cycle; model auto-disabled when credits run out. **Postpaid:** usage recorded as debt with no quota limit | Fixed token/request quota per model, shared across all subscription-keys in the plan | +| Where to track | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** and **Cost** | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** only | *** ## Getting Started -| I want to... | Go to | -| ------------------------------------------------ | -------------------------------------------------------------- | -| Prepare an API key, Base URL, and choose a model | [Getting Started with AI Coding](getting-started.md) | -| Use a GUI tool | Coming soon | -| Use a CLI tool | [CLI Tools group](cli-tools/) | -| Attach an MCP server to an agent | [Using MCP Servers with AI Coding](mcp-servers.md) | -| Get an API key | [AI Platform Console](https://aiplatform.console.vngcloud.vn/) | +| I want to... | Go to | +|---|---| +| Prepare a key and Base URL, and choose a model | [Getting Started with AI Coding](getting-started.md) | +| Use a GUI tool | [GUI Tools group](gui-tools/README.md) | +| Use a CLI tool | [CLI Tools group](cli-tools/README.md) | +| Configure an SDK / IDE extension on the OpenAI standard | [Connect OpenAI-compatible Tools to GreenNode MaaS](connect-openai-compatible-to-maas.md) | +| Attach an MCP server to an agent | [Using MCP Servers with AI Coding](mcp-servers.md) | +| Buy and use a Token Plan package | [Token Plan](../token-plan/README.md) | +| Get a PAYG API key | [AI Platform Console](https://aiplatform.console.greennode.ai/) | diff --git a/English/ai-stack/ai-coding/cli-tools/README.md b/English/ai-stack/ai-coding/cli-tools/README.md index 634660ca..c0e29d56 100644 --- a/English/ai-stack/ai-coding/cli-tools/README.md +++ b/English/ai-stack/ai-coding/cli-tools/README.md @@ -4,6 +4,10 @@ Before installing, see [Prerequisites](../getting-started.md). +{% hint style="warning" %} +Every page below has **separate tabs for PAYG and Token Plan** in its configuration section. Settle your service type first (go by where you got your key), then copy only from that tab — a key and Base URL from different service types return `401 Unauthorized`. +{% endhint %} + * [Claude Code](claude-code.md) * [Codex CLI](codex-cli.md) * [OpenCode](opencode.md) diff --git a/English/ai-stack/ai-coding/cli-tools/claude-code.md b/English/ai-stack/ai-coding/cli-tools/claude-code.md index 6fa43b41..c44870e5 100644 --- a/English/ai-stack/ai-coding/cli-tools/claude-code.md +++ b/English/ai-stack/ai-coding/cli-tools/claude-code.md @@ -3,18 +3,26 @@ > For terminal users (macOS / Linux / WSL / Windows). The Claude Code CLI will use GreenNode's **GLM 5.2** model via MaaS instead of calling Anthropic directly. {% hint style="info" %} -**First, complete the [Prerequisites](../getting-started.md):** an **ACTIVE** API key, the Base URL, and the GLM 5.2 model **ENABLED**. +**First, complete the [Prerequisites](../getting-started.md):** an **ACTIVE** key, the Base URL for your service type, and the model **ENABLED**. {% endhint %} -| Info | Value | -|-----------|---------| -| Base URL | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` (Anthropic standard, **no** `/v1`) | -| Base URL (Token Plan / package key) | `https://tokenplan.api.greennode.ai` (**no** `/v1`) — see [Token Plan](../../token-plan/README.md) | -| API key | your key | -| Model ID | `z-ai/glm-5.2` | +--- + +## Pick your configuration by service type + +Claude Code uses the **Anthropic standard** → the Base URL has **no** `/v1` on either service type. Only the host and the key type differ: + +| Service type | Base URL | Key | Model ID | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | API Key from the [API Keys page](https://aiplatform.console.greennode.ai/keys) | `z-ai/glm-5.2` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | subscription-key from Plan Detail → **Subscription keys** tab | Model code on the **Models** tab (e.g. `glm-5.2`) | + +{% hint style="warning" %} +**Your key and Base URL must belong to the same service type.** A PAYG API Key sent to the `tokenplan…` host (or the reverse) returns `401 Unauthorized` even while the key is still valid. You can't tell the key types apart by looking at them — go by where you got the key. See [section 2 of the Prerequisites page](../getting-started.md). +{% endhint %} {% hint style="info" %} -**GLM 5.2 is just an example model.** GreenNode offers many models — swap in whichever one you want. Each model's Model ID and Base URL are on the [model detail page](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 is just an example model.** GreenNode offers many models — swap in whichever one you want. On PAYG, find the Model ID on the [model detail page](https://aiplatform.console.greennode.ai/models); on Token Plan, check your plan's **Models** tab. {% endhint %} --- @@ -29,15 +37,15 @@ npm install -g @anthropic-ai/claude-code ## Step 2 — Declare the Base URL & API key -Pick the right section for your OS. +Pick the tab matching your **service type** and **OS**, then copy it as-is — only replace the key value. {% tabs %} -{% tab title="macOS / Linux / WSL (bash or zsh)" %} +{% tab title="PAYG — macOS / Linux / WSL" %} Set them temporarily for the current session: ```bash export ANTHROPIC_BASE_URL="https://maas-llm-aiplatform-hcm.api.vngcloud.vn" -export ANTHROPIC_AUTH_TOKEN="--" # replace with your API key +export ANTHROPIC_AUTH_TOKEN="" ``` To have this happen automatically every time you open a terminal, add the two lines above to the end of `~/.zshrc` (macOS) or `~/.bashrc` (Linux/WSL), then reload: @@ -47,19 +55,50 @@ source ~/.zshrc # or: source ~/.bashrc ``` {% endtab %} -{% tab title="Windows PowerShell" %} +{% tab title="PAYG — Windows PowerShell" %} Set them temporarily for the current PowerShell window: ```powershell $env:ANTHROPIC_BASE_URL = "https://maas-llm-aiplatform-hcm.api.vngcloud.vn" -$env:ANTHROPIC_AUTH_TOKEN = "--" # replace with your API key +$env:ANTHROPIC_AUTH_TOKEN = "" ``` To persist them for your account (run once, then **reopen PowerShell**): ```powershell [Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://maas-llm-aiplatform-hcm.api.vngcloud.vn", "User") -[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "--", "User") +[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User") +``` +{% endtab %} + +{% tab title="Token Plan — macOS / Linux / WSL" %} +Set them temporarily for the current session: + +```bash +export ANTHROPIC_BASE_URL="https://tokenplan.api.greennode.ai" +export ANTHROPIC_AUTH_TOKEN="" +``` + +To have this happen automatically every time you open a terminal, add the two lines above to the end of `~/.zshrc` (macOS) or `~/.bashrc` (Linux/WSL), then reload: + +```bash +source ~/.zshrc # or: source ~/.bashrc +``` +{% endtab %} + +{% tab title="Token Plan — Windows PowerShell" %} +Set them temporarily for the current PowerShell window: + +```powershell +$env:ANTHROPIC_BASE_URL = "https://tokenplan.api.greennode.ai" +$env:ANTHROPIC_AUTH_TOKEN = "" +``` + +To persist them for your account (run once, then **reopen PowerShell**): + +```powershell +[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://tokenplan.api.greennode.ai", "User") +[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User") ``` {% endtab %} {% endtabs %} @@ -68,26 +107,40 @@ To persist them for your account (run once, then **reopen PowerShell**): --- -## Step 3 — Run Claude Code with GLM 5.2 +## Step 3 — Run Claude Code -In your project directory, run: +In your project directory, run the command for your service type: +{% tabs %} +{% tab title="PAYG" %} ```bash claude --model z-ai/glm-5.2 ``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +claude --model glm-5.2 +``` + +Replace `glm-5.2` with the exact **Model code** shown on your plan's **Models** tab. +{% endtab %} +{% endtabs %} {% hint style="info" %} -The `--model z-ai/glm-5.2` flag sets the model for the current session. Inside Claude Code you can also switch models with the `/model` command. +The `--model` flag sets the model for the current session. Inside Claude Code you can also switch models with the `/model` command. {% endhint %} --- ## Step 4 — Verify -In Claude Code, type `/status` — it's correct when: +In Claude Code, type `/status` and compare: -* The Base URL points to `maas-llm-aiplatform-hcm.api.vngcloud.vn` -* The model is `z-ai/glm-5.2` +| Check | PAYG | Token Plan | +|---|---|---| +| Base URL points to | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | `tokenplan.api.greennode.ai` | +| Model | `z-ai/glm-5.2` | Your plan's Model code (e.g. `glm-5.2`) | Then check the **[AI Platform Console](https://aiplatform.console.greennode.ai/)** to see the call logged. @@ -99,12 +152,15 @@ Then check the **[AI Platform Console](https://aiplatform.console.greennode.ai/) | Symptom | Cause | Fix | |------------|-------------|------------| -| `401` / "Unauthorized" | Wrong or not-yet-ACTIVE API key | Check `ANTHROPIC_AUTH_TOKEN`; wait for the key to become **ACTIVE** | -| `404` / "Not Found" | Wrong Base URL (extra `/v1` or trailing `/`) | Should be exactly `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| `401` / "Unauthorized" | Wrong or not-yet-ACTIVE key | Check `ANTHROPIC_AUTH_TOKEN`; wait for the key to become **ACTIVE** | +| `401` while the key is still valid | **Key and Base URL belong to different service types** — e.g. a PAYG API Key sent to the `tokenplan…` host | Re-check the table at the top of this page: a key from the **API Keys** page → the `maas-llm-…` host; a key from the **Subscription keys** tab → the `tokenplan…` host | +| `403 Forbidden` (Token Plan) | Model isn't included in the plan | Only call models listed on the plan's **Models** tab | +| `402 Payment Required` (Token Plan) | Plan has expired or was deleted | Buy the plan again or enable **Auto-renew** | +| `404` / "Not Found" | Wrong Base URL (extra `/v1` or trailing `/`) | Claude Code is Anthropic-standard — the Base URL has **no** `/v1` | | Requests go straight to Anthropic | Old `ANTHROPIC_API_KEY` variable still set | Run `unset ANTHROPIC_API_KEY` (macOS/Linux) or remove that variable on Windows | -| Wrong model is used | Missing `--model` flag | Run `claude --model z-ai/glm-5.2` or use `/model` to switch | -| AI doesn't respond | Out of credit, model auto-disabled | Top up credit in the AI Platform Console | -| Connection timeout | Can't reach MaaS over the network | Check VPN / network access to `*.api.vngcloud.vn` | +| Wrong model is used | Missing `--model` flag, or a Model ID from the other service type | Run `claude --model ` or use `/model` to switch | +| AI doesn't respond | PAYG out of credit, or Token Plan out of token quota | PAYG: top up credit. Token Plan: wait for the next cycle, buy another plan, or temporarily switch to a PAYG API Key | +| Connection timeout | Can't reach the endpoint over the network | Check VPN / network access to `*.api.vngcloud.vn` (PAYG) or `tokenplan.api.greennode.ai` (Token Plan) | --- @@ -112,6 +168,7 @@ Then check the **[AI Platform Console](https://aiplatform.console.greennode.ai/) |------------------------|--------| | Use OpenCode | [OpenCode](opencode.md) | | See the prerequisites | [Getting Started with AI Coding](../getting-started.md) | +| Learn about Token Plan packages | [Token Plan](../../token-plan/README.md) | --- diff --git a/English/ai-stack/ai-coding/cli-tools/codex-cli.md b/English/ai-stack/ai-coding/cli-tools/codex-cli.md index 99506f66..e9f6af8d 100644 --- a/English/ai-stack/ai-coding/cli-tools/codex-cli.md +++ b/English/ai-stack/ai-coding/cli-tools/codex-cli.md @@ -6,13 +6,22 @@ ## Prerequisites -* Prepare your API key, Base URL, and model following [Getting Started with AI Coding](../getting-started.md) +* Prepare your key, Base URL, and model following [Getting Started with AI Coding](../getting-started.md) * Node.js ≥ 22 installed -> The Minimax M2.5 model via Codex uses the **OpenAI standard** — the Base URL includes `/v1`: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +*** -{% hint style="info" %} -**Using a Token Plan (subscription package) key instead of a pay-as-you-go API key?** Use `https://tokenplan.api.greennode.ai/v1` as the Base URL instead. See [Token Plan](../../token-plan/README.md) for details. +## Pick your configuration by service type + +Codex uses the **OpenAI standard** → the Base URL **includes** `/v1` on both service types. Only the host and the key type differ: + +| Service type | `base_url` | Key | `model` | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key from the [API Keys page](https://aiplatform.console.greennode.ai/keys) | `minimax/minimax-m2.5` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key from Plan Detail → **Subscription keys** tab | Model code on the plan's **Models** tab | + +{% hint style="warning" %} +**Your key and Base URL must belong to the same service type.** A PAYG API Key sent to the `tokenplan…` host (or the reverse) returns `401 Unauthorized` even while the key is still valid. Go by where you got the key — see [section 2 of the Prerequisites page](../getting-started.md). {% endhint %} *** @@ -31,83 +40,139 @@ codex --version *** -## Step 2 — Get an API key from AI Platform +## Step 2 — Get your key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Log in to the [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Go to **API Keys** → **Create API Key** 3. Name the key (5–50 characters, lowercase letters + numbers + hyphens) -4. Copy the API key (`vn-...`) you just created +4. Copy the API key you just created {% hint style="warning" %} A newly created API key starts in `pending` status. Wait until status = `ACTIVE` before using it. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Go to **API Key** → **Token Plan** → **My Token Plans** and open the plan you bought +2. **Subscription keys** tab → copy `default-key` or a key you created +3. **Models** tab → copy the **Model code** of the model you want + +No plan yet? See [Buy Token Plan](../../token-plan/buy-token-plan.md). +{% endtab %} +{% endtabs %} *** ## Step 3 — Configure `codex.toml` -Create or edit `~/.codex/config.toml` (system-wide config) or `codex.toml` at your project root (applies to that project only): +Create or edit `~/.codex/config.toml` (system-wide) or `codex.toml` in your project root (that project only). Copy the tab matching your service type: +{% tabs %} +{% tab title="PAYG" %} ```toml # API key — export before running Codex -# export MAAS_API_KEY="vn-...your-gateway-token..." +# export MAAS_API_KEY="" model_provider = "maas" model = "minimax/minimax-m2.5" -# Needed because MAAS doesn't return model metadata — avoids incorrect context truncation +# Required because MAAS doesn't return model metadata — prevents wrong context truncation model_context_window = 204800 model_max_output_tokens = 16400 -# The MAAS backend is stateless — Codex must resend the full conversation every turn +# The MAAS backend is stateless — Codex must resend the full conversation each turn disable_response_storage = true [model_providers.maas] name = "MAAS AI Gateway" -# base_url has NO trailing /responses — Codex appends it automatically (→ .../v1/responses) +# base_url must NOT have a trailing /responses — Codex appends it (→ .../v1/responses) base_url = "https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1" env_key = "MAAS_API_KEY" wire_api = "responses" request_max_retries = 3 ``` +{% endtab %} -**Key field explanations:** +{% tab title="Token Plan" %} +```toml +# subscription-key — export before running Codex +# export MAAS_API_KEY="" + +model_provider = "maas" +model = "glm-5.2" # replace with the Model code from your plan's Models tab + +# Required because MAAS doesn't return model metadata — prevents wrong context truncation +model_context_window = 204800 +model_max_output_tokens = 16400 -| Field | Purpose | -| -------------------------- | ---------------------------------------------------------------------------- | -| `model_provider` | The provider key under `[model_providers.*]` | -| `model` | Model ID sent to MaaS | -| `model_context_window` | Set manually since MaaS doesn't expose model metadata | -| `disable_response_storage` | Required for the stateless backend — resend the full conversation every turn | -| `base_url` | MaaS endpoint with `/v1` — Codex appends `/responses` after it | -| `env_key` | Name of the environment variable holding the API key | -| `wire_api` | Protocol used — `responses` corresponds to the OpenAI Responses API | +# The MAAS backend is stateless — Codex must resend the full conversation each turn +disable_response_storage = true + +[model_providers.maas] +name = "MAAS AI Gateway" + +# base_url must NOT have a trailing /responses — Codex appends it (→ .../v1/responses) +base_url = "https://tokenplan.api.greennode.ai/v1" +env_key = "MAAS_API_KEY" +wire_api = "responses" +request_max_retries = 3 +``` + +{% hint style="info" %} +`model` must match the **Model code** exactly as shown on the plan's **Models** tab, and that model must be included in the plan — calling a model outside the plan returns `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} + +**Key fields explained:** + +| Field | Purpose | +|---|---| +| `model_provider` | The provider key under `[model_providers.*]` | +| `model` | Model ID sent to MaaS — PAYG uses the Models portal ID, Token Plan uses the plan's Model code | +| `model_context_window` | Declared manually because MaaS doesn't expose model metadata | +| `disable_response_storage` | Required for a stateless backend — resends the full conversation each turn | +| `base_url` | The endpoint for your service type, including `/v1` — Codex appends `/responses` itself | +| `env_key` | Name of the environment variable holding the key | +| `wire_api` | Protocol used — `responses` maps to the OpenAI Responses API | *** -## Step 4 — Set the API key and run Codex +## Step 4 — Set the key and run Codex -Export the API key in your shell: +Export the key in your shell — use the key belonging to the same service type as the `base_url` you set in Step 3: + +{% tabs %} +{% tab title="PAYG" %} +```bash +export MAAS_API_KEY="" +``` +{% endtab %} +{% tab title="Token Plan" %} ```bash -export MAAS_API_KEY="vn-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +export MAAS_API_KEY="" ``` +{% endtab %} +{% endtabs %} -To do this automatically every time you open a terminal, add it to `~/.zshrc` or `~/.bashrc`: +To set it automatically every time you open a terminal, add it to `~/.zshrc` or `~/.bashrc`: ```bash -echo 'export MAAS_API_KEY="vn-xxxx..."' >> ~/.zshrc +echo 'export MAAS_API_KEY=""' >> ~/.zshrc source ~/.zshrc ``` -Run Codex inside your project directory: +Run Codex in your project directory: ```bash codex ``` -Codex will show the provider and model in use in the session header: +Codex shows the active provider and model in the session header: ``` model: minimax/minimax-m2.5 /model to change @@ -120,26 +185,30 @@ directory: ~/your-project ## Troubleshooting -| Symptom | Cause | Fix | -| ----------------------------- | ----------------------------------------- | --------------------------------------------------------------------------- | -| `401 Unauthorized` | Wrong, missing, or not-yet-ACTIVE API key | Re-export `MAAS_API_KEY`; check the key's status in the AI Platform Console | -| `404` when sending a request | `base_url` wrong or missing `/v1` | Make sure `base_url` ends with `/v1` (no `/responses`) | -| Context truncated incorrectly | Model metadata not declared | Check `model_context_window` and `model_max_output_tokens` in the config | -| Loses context every turn | `disable_response_storage` not set | Add `disable_response_storage = true` to the config | -| Connection timeout | Endpoint unreachable | Check VPN / connection to `*.api.vngcloud.vn` | +| Symptom | Cause | Fix | +|---|---|---| +| `401 Unauthorized` | Key wrong, missing, or not yet ACTIVE | Re-export `MAAS_API_KEY`; check the key status | +| `401` while the key is still valid | **Key and `base_url` belong to different service types** | Re-check the table at the top: a key from the **API Keys** page → the `maas-llm-…` host; a key from the **Subscription keys** tab → the `tokenplan…` host | +| `403 Forbidden` (Token Plan) | Model isn't included in the plan | Set `model` to a Model code listed on the plan's **Models** tab | +| `402 Payment Required` (Token Plan) | Plan expired or was deleted | Buy the plan again or enable **Auto-renew** | +| `404` on request | `base_url` wrong or missing `/v1` | Codex is OpenAI-standard — `base_url` must end with `/v1` (no `/responses`) | +| Context truncated incorrectly | Model metadata not declared | Check `model_context_window` and `model_max_output_tokens` in the config | +| Loses earlier context each turn | `disable_response_storage` not set | Add `disable_response_storage = true` to the config | +| Connection timeout | Endpoint unreachable | Check VPN / connectivity to `*.api.vngcloud.vn` (PAYG) or `tokenplan.api.greennode.ai` (Token Plan) | *** ## Result -Once done, the Codex CLI routes all requests through GreenNode MaaS using the Minimax model. Usage is logged on the [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). +Codex CLI now routes every request through the GreenNode endpoint for your chosen service type. Usage is recorded in the [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). -| I want to next... | Go to | -| --------------------------- | --------------------------------------------------------------- | -| Use the GUI version | [Codex Desktop](../gui-tools/codex-desktop.md) | -| Use OpenCode with MaaS | [Use OpenCode with GreenNode MaaS](opencode.md) | -| Connect Claude Code to MaaS | [Connect Claude Code to GreenNode MaaS](claude-code.md) | -| View usage and billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | +| I want to next... | Go to | +|---|---| +| Use the GUI version | [Codex Desktop](../gui-tools/codex-desktop.md) | +| Use OpenCode with MaaS | [OpenCode](opencode.md) | +| Connect Claude Code to MaaS | [Claude Code](claude-code.md) | +| Learn about Token Plan packages | [Token Plan](../../token-plan/README.md) | +| View usage and billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | *** diff --git a/English/ai-stack/ai-coding/cli-tools/opencode.md b/English/ai-stack/ai-coding/cli-tools/opencode.md index 06893a11..fc40b995 100644 --- a/English/ai-stack/ai-coding/cli-tools/opencode.md +++ b/English/ai-stack/ai-coding/cli-tools/opencode.md @@ -1,18 +1,27 @@ # OpenCode -> Guide to configuring [OpenCode](https://opencode.ai) — a TUI coding assistant — to call a model via GreenNode MaaS through the `@ai-sdk/openai-compatible` provider, billed via internal credit-tokens. +> Guide to configuring [OpenCode](https://opencode.ai) — a TUI coding assistant — to call a model via GreenNode MaaS through the `@ai-sdk/openai-compatible` provider. *** ## Prerequisites -* Prepare your API key, Base URL, and model following [Getting Started with AI Coding](../getting-started.md) +* Prepare your key, Base URL, and model following [Getting Started with AI Coding](../getting-started.md) * Node.js installed -> The GLM 5.2 model via OpenCode uses the **OpenAI standard** — the Base URL includes `/v1`: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +*** -{% hint style="info" %} -**Using a Token Plan (subscription package) key instead of a pay-as-you-go API key?** Use `https://tokenplan.api.greennode.ai/v1` as the Base URL instead. See [Token Plan](../../token-plan/README.md) for details. +## Pick your configuration by service type + +OpenCode uses the **OpenAI standard** → `baseURL` **includes** `/v1` on both service types. Only the host and the key type differ: + +| Service type | `baseURL` | Key | Model | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key from the [API Keys page](https://aiplatform.console.greennode.ai/keys) | `openai/gpt-oss-120b` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key from Plan Detail → **Subscription keys** tab | Model code on the plan's **Models** tab | + +{% hint style="warning" %} +**Your key and `baseURL` must belong to the same service type.** A PAYG API Key sent to the `tokenplan…` host (or the reverse) returns `401 Unauthorized` even while the key is still valid. Go by where you got the key — see [section 2 of the Prerequisites page](../getting-started.md). {% endhint %} *** @@ -31,23 +40,37 @@ brew install opencode *** -## Step 2 — Get an API key from AI Platform +## Step 2 — Get your key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Log in to the [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Go to **API Keys** → **Create API Key** 3. Name the key (5–50 characters, lowercase letters + numbers + hyphens) -4. Copy the API key (`vn-...`) you just created +4. Copy the API key you just created {% hint style="warning" %} A newly created API key starts in `pending` status. Wait until status = `ACTIVE` before using it. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Go to **API Key** → **Token Plan** → **My Token Plans** and open the plan you bought +2. **Subscription keys** tab → copy `default-key` or a key you created +3. **Models** tab → copy the **Model code** of the model you want + +No plan yet? See [Buy Token Plan](../../token-plan/buy-token-plan.md). +{% endtab %} +{% endtabs %} *** ## Step 3 — Create the `opencode.json` config file -Create an `opencode.json` file at your project root: +Create `opencode.json` in your project root. Copy the tab matching your service type: +{% tabs %} +{% tab title="PAYG" %} ```json { "$schema": "https://opencode.ai/config.json", @@ -69,122 +92,181 @@ Create an `opencode.json` file at your project root: } } ``` +{% endtab %} -**Field explanations:** +{% tab title="Token Plan" %} +```json +{ + "$schema": "https://opencode.ai/config.json", + "model": "MAAS-chat/glm-5.2", + "provider": { + "MAAS-chat": { + "npm": "@ai-sdk/openai-compatible", + "name": "MAAS chat", + "options": { + "baseURL": "https://tokenplan.api.greennode.ai/v1", + "apiKey": "{env:MAAS_API_KEY}" + }, + "models": { + "glm-5.2": { + "name": "glm-5.2" + } + } + } + } +} +``` -| Field | Purpose | -| -------------------- | --------------------------------------------------------------------------------- | -| `$schema` | Enables autocomplete/validation in your editor | -| `model` | Default model — format `/` | -| `provider.MAAS-chat` | Provider key — must exactly match the part before `/` in `model` | -| `npm` | Adapter package — `@ai-sdk/openai-compatible` works for any OpenAI-style endpoint | -| `options.baseURL` | MaaS endpoint, ending with `/v1` | -| `options.apiKey` | MaaS token — use `{env:MAAS_API_KEY}` instead of hardcoding | -| `models` | List of models exposed from this provider | +{% hint style="info" %} +Replace `glm-5.2` (in both `model` and `models`) with the exact **Model code** from your plan's **Models** tab. Calling a model outside the plan returns `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} + +**Field reference:** + +| Field | Purpose | +|---|---| +| `$schema` | Enables autocomplete/validation in your editor | +| `model` | Default model — format `/` | +| `provider.MAAS-chat` | Provider key — the part before `/` in `model` must match exactly | +| `npm` | Adapter package — `@ai-sdk/openai-compatible` works with any OpenAI-style endpoint | +| `options.baseURL` | The endpoint for your service type, ending in `/v1` | +| `options.apiKey` | Your MaaS key — use `{env:MAAS_API_KEY}` instead of hardcoding | +| `models` | The models exposed from this provider | {% hint style="warning" %} -Common mistake: setting `"model"` to a name that doesn't match a registered provider key. OpenCode splits on the first `/` to find the provider — if it doesn't match, the model won't load. Always use `MAAS-chat/openai/gpt-oss-120b`. +Common mistake: setting `"model"` to a name that doesn't match the registered provider key. OpenCode splits on the first `/` to find the provider — if it doesn't match, the model won't load. The `model` value must always start with `MAAS-chat/`. {% endhint %} *** -## Step 4 — Provide the API key +## Step 4 — Provide the key -Since the config uses `{env:MAAS_API_KEY}`, the key isn't in the file but is read from an environment variable at runtime. There are two ways: +Because the config uses `{env:MAAS_API_KEY}`, the key isn't stored in the file — it's read from the environment at runtime. Use the key belonging to the same service type as the `baseURL` you set in Step 3. **Option A — Export an environment variable (recommended)** -Export the key in your shell, then run OpenCode in the same session: +{% tabs %} +{% tab title="PAYG" %} +```bash +export MAAS_API_KEY="" +opencode +``` +{% endtab %} +{% tab title="Token Plan" %} ```bash -export MAAS_API_KEY="vn-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +export MAAS_API_KEY="" opencode ``` +{% endtab %} +{% endtabs %} -To do this automatically every time you open a terminal, add it to `~/.zshrc` or `~/.bashrc`: +To set it automatically every time you open a terminal, add it to `~/.zshrc` or `~/.bashrc`: ```bash -echo 'export MAAS_API_KEY="vn-xxxx..."' >> ~/.zshrc +echo 'export MAAS_API_KEY=""' >> ~/.zshrc source ~/.zshrc ``` Or set it inline for a single run: ```bash -MAAS_API_KEY="vn-xxxx..." opencode +MAAS_API_KEY="" opencode ``` -**Option B — Use a gitignored `.env` file in your project** +**Option B — Use a gitignored `.env` file in the project** Create a `.env` file (add it to `.gitignore`): ```bash -export MAAS_API_KEY="vn-xxxx..." +export MAAS_API_KEY="" ``` -Run OpenCode by loading the `.env` file first: +Run OpenCode after loading `.env`: ```bash source .env && opencode ``` {% hint style="warning" %} -Don't hardcode your API key directly in `opencode.json` if that file gets committed. If a key has already been committed, rotate it immediately in the MAAS Console since it must be treated as leaked. +Don't hardcode the key into `opencode.json` if that file gets committed. If a key has already been committed, rotate it right away — rotate a PAYG API Key on the [API Keys page](https://aiplatform.console.greennode.ai/keys); revoke and recreate a subscription-key on the plan's **Subscription keys** tab. {% endhint %} *** -## Step 5 — Run OpenCode and select a model +## Step 5 — Run OpenCode and pick a model + +1. Change into your project directory and run: -1. Navigate to your project directory and run: + ```bash + opencode + ``` - ```bash - opencode - ``` + OpenCode starts with the default model declared in `model` in Step 3. - OpenCode starts with `MAAS-chat/openai/gpt-oss-120b` as the default model. -2. Switch models within the session with the `/models` command, then choose **MAAS chat → openai/gpt-oss-120b** from the list. +2. Switch models during a session with `/models`, then choose **MAAS chat →** your model from the list.

OpenCode running with the openai/gpt-oss-120b model via GreenNode MaaS

*** -## Adding other MaaS models +## Add more models -To expose more models from the same MaaS endpoint, add entries to `models`: +To expose more models from the same endpoint, add entries to `models`: +{% tabs %} +{% tab title="PAYG" %} ```json "models": { "openai/gpt-oss-120b": { "name": "openai/gpt-oss-120b" }, "openai/gpt-oss-20b": { "name": "openai/gpt-oss-20b" } } ``` +{% endtab %} + +{% tab title="Token Plan" %} +```json +"models": { + "glm-5.2": { "name": "glm-5.2" }, + "minimax-m2.5": { "name": "minimax-m2.5" } +} +``` + +You can only add models **included in the plan** — check the plan's **Models** tab. +{% endtab %} +{% endtabs %} -Then select via `/models`, or change the top-level `model` to the new `MAAS-chat/`. +Then pick one via `/models`, or change the top-level `model` to the new `MAAS-chat/`. *** ## Troubleshooting -| Symptom | Cause | Fix | -| --------------------------------------- | --------------------------------------------- | -------------------------------------------------------------- | -| `provider not found` / model won't load | `model` value doesn't match the provider key | Use `MAAS-chat/openai/gpt-oss-120b` | -| `401 Unauthorized` | Wrong, expired, or not-yet-ACTIVE API key | Re-export `MAAS_API_KEY`; rotate the token in the MAAS Console | -| `404` when sending a request | Wrong Base URL or missing `/v1` | Check `baseURL` ends with `/v1` | -| Connection timeout | Endpoint unreachable from the current network | Check VPN / connection to `*.api.vngcloud.vn` | -| Model errors but auth is correct | Wrong model ID | Use the exact ID published by MaaS (`openai/gpt-oss-120b`) | +| Symptom | Cause | Fix | +|---|---|---| +| `provider not found` / model won't load | `model` value doesn't match the provider key | The `model` value must start with `MAAS-chat/` | +| `401 Unauthorized` | Key wrong, expired, or not yet ACTIVE | Re-export `MAAS_API_KEY`; check the key status | +| `401` while the key is still valid | **Key and `baseURL` belong to different service types** | Re-check the table at the top: a key from the **API Keys** page → the `maas-llm-…` host; a key from the **Subscription keys** tab → the `tokenplan…` host | +| `403 Forbidden` (Token Plan) | Model isn't included in the plan | Only declare models listed on the plan's **Models** tab | +| `402 Payment Required` (Token Plan) | Plan expired or was deleted | Buy the plan again or enable **Auto-renew** | +| `404` on request | Base URL wrong or missing `/v1` | OpenCode is OpenAI-standard — `baseURL` must end with `/v1` | +| Connection timeout | Endpoint unreachable from your network | Check VPN / connectivity to `*.api.vngcloud.vn` (PAYG) or `tokenplan.api.greennode.ai` (Token Plan) | +| Model errors while auth is fine | Wrong model ID | PAYG: use the ID the portal publishes. Token Plan: use the **Model code** from the **Models** tab | *** ## Result -Once done, OpenCode routes all requests through GreenNode MaaS. Usage is logged on the [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). +OpenCode now routes every request through the GreenNode endpoint for your chosen service type. Usage is recorded in the [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). -| I want to next... | Go to | -| ------------------------------- | --------------------------------------------------------------- | -| Use Codex with Minimax via MaaS | [Use Codex with Minimax via GreenNode MaaS](codex-cli.md) | -| Connect Claude Code to MaaS | [Connect Claude Code to GreenNode MaaS](claude-code.md) | -| View usage and billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | +| I want to next... | Go to | +|---|---| +| Use Codex with Minimax via MaaS | [Codex CLI](codex-cli.md) | +| Connect Claude Code to MaaS | [Claude Code](claude-code.md) | +| Learn about Token Plan packages | [Token Plan](../../token-plan/README.md) | +| View usage and billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | *** diff --git a/English/ai-stack/ai-coding/connect-openai-compatible-to-maas.md b/English/ai-stack/ai-coding/connect-openai-compatible-to-maas.md index e949a6bf..6c73f2ff 100644 --- a/English/ai-stack/ai-coding/connect-openai-compatible-to-maas.md +++ b/English/ai-stack/ai-coding/connect-openai-compatible-to-maas.md @@ -1,57 +1,92 @@ -# Connect OpenAI-compatible Clients to GreenNode MaaS +# Connect OpenAI-compatible Tools to GreenNode MaaS -> Configure tools, SDKs, and IDE extensions that use the OpenAI API format to call models through GreenNode MaaS, billed via internal credit-tokens. +> Guide to configuring tools, SDKs, and IDE extensions that speak the OpenAI API format to call models through a GreenNode endpoint — using either a **PAYG** API Key or a **Token Plan** subscription-key. ---- +*** ## Prerequisites -- An active [AI Platform](https://aiplatform.console.greennode.ai/) account -- An API key with status **ACTIVE** -- A tool or SDK that supports a custom base URL (OpenAI SDK, LiteLLM, Cursor, Continue.dev, etc.) +* An [AI Platform](https://aiplatform.console.greennode.ai/) account +* A key in **ACTIVE** status — either an API Key (PAYG) or a subscription-key (Token Plan) +* A tool/SDK that supports a custom base URL (OpenAI SDK, LiteLLM, Cursor, Continue.dev, etc.) -{% hint style="info" %} -The LLM URL for OpenAI-compatible clients is `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` (with `/v1`). This differs from Claude Code, which uses the Anthropic protocol (no `/v1`). +*** + +## Pick your configuration by service type + +Every tool on this page uses the **OpenAI standard** → the Base URL **includes** `/v1` on both service types. Only the host and the key type differ: + +| Service type | Base URL | Key | Model | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key from the [API Keys page](https://aiplatform.console.greennode.ai/keys) | Model ID from the [Models portal](https://aiplatform.console.greennode.ai/models) (e.g. `openai/gpt-4o`) | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key from Plan Detail → **Subscription keys** tab | Model code on the plan's **Models** tab (e.g. `glm-5.2`) | + +{% hint style="warning" %} +**Your key and Base URL must belong to the same service type.** A PAYG API Key sent to the `tokenplan…` host (or the reverse) returns `401 Unauthorized` even while the key is still valid. You can't tell the key types apart by looking at them — go by where you got the key. See [section 2 of the Prerequisites page](getting-started.md). {% endhint %} ---- +Every example below has 2 tabs — pick the tab for your service type and copy it as-is, replacing only the key and the model. + +*** -## Step 1 — Get an API key from AI Platform +## Step 1 — Get your key -1. Log in to [AI Platform Console](https://aiplatform.console.greennode.ai/) +{% tabs %} +{% tab title="PAYG — API Key" %} +1. Log in to the [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Go to **API Keys** → **Create API Key** -3. Name the key (5–50 chars, lowercase letters, numbers, and hyphens) -4. Copy the API key — it is shown only once +3. Name the key (5–50 characters, lowercase letters + numbers + hyphens) +4. Copy the API key you just created {% hint style="warning" %} -A newly created API key has status `pending`. Wait until the status is `ACTIVE` before using it. +A newly created API key starts in `pending` status. Wait until status = `ACTIVE` before using it. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Go to **API Key** → **Token Plan** → **My Token Plans** and open the plan you bought +2. **Subscription keys** tab → copy `default-key` or a key you created +3. **Models** tab → copy the **Model code** of the model you want ---- +No plan yet? See [Buy Token Plan](../token-plan/buy-token-plan.md). +{% endtab %} +{% endtabs %} -## Step 2 — List available models +*** -Fetch available models via the OpenAI-compatible endpoint: +## Step 2 — List the available models +{% tabs %} +{% tab title="PAYG" %} ```bash curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/models \ - -H "Authorization: Bearer " + -H "Authorization: Bearer " ``` -Use the `id` value from the response as the `model` parameter in your API calls. +Use the `id` value from the response as the `model` parameter when calling the API. +{% endtab %} ---- +{% tab title="Token Plan" %} +Your plan's model list is shown directly on **Plan Detail → Models tab** — the **Model code** column is exactly what goes into the `model` parameter. -## Step 3 — Configure the client +A plan can only call the models listed on that tab; anything else returns `403 Forbidden`. +{% endtab %} +{% endtabs %} -**OpenAI Python SDK** +*** +## Step 3 — Configure your client + +### OpenAI Python SDK + +{% tabs %} +{% tab title="PAYG" %} ```python from openai import OpenAI client = OpenAI( base_url="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - api_key="", + api_key="", ) response = client.chat.completions.create( @@ -60,15 +95,36 @@ response = client.chat.completions.create( ) print(response.choices[0].message.content) ``` +{% endtab %} + +{% tab title="Token Plan" %} +```python +from openai import OpenAI + +client = OpenAI( + base_url="https://tokenplan.api.greennode.ai/v1", + api_key="", +) + +response = client.chat.completions.create( + model="glm-5.2", # Model code from your plan's Models tab + messages=[{"role": "user", "content": "Hello"}], +) +print(response.choices[0].message.content) +``` +{% endtab %} +{% endtabs %} -**OpenAI Node.js SDK** +### OpenAI Node.js SDK +{% tabs %} +{% tab title="PAYG" %} ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - apiKey: "", + apiKey: "", }); const response = await client.chat.completions.create({ @@ -77,16 +133,48 @@ const response = await client.chat.completions.create({ }); console.log(response.choices[0].message.content); ``` +{% endtab %} -**Environment variables (for OpenAI-compatible tools and CLIs)** +{% tab title="Token Plan" %} +```javascript +import OpenAI from "openai"; +const client = new OpenAI({ + baseURL: "https://tokenplan.api.greennode.ai/v1", + apiKey: "", +}); + +const response = await client.chat.completions.create({ + model: "glm-5.2", // Model code from your plan's Models tab + messages: [{ role: "user", content: "Hello" }], +}); +console.log(response.choices[0].message.content); +``` +{% endtab %} +{% endtabs %} + +### Environment variables (for tools/CLIs that read OpenAI-compatible config) + +{% tabs %} +{% tab title="PAYG" %} ```bash export OPENAI_BASE_URL="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1" -export OPENAI_API_KEY="" +export OPENAI_API_KEY="" +``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +export OPENAI_BASE_URL="https://tokenplan.api.greennode.ai/v1" +export OPENAI_API_KEY="" ``` +{% endtab %} +{% endtabs %} -**LiteLLM** +### LiteLLM +{% tabs %} +{% tab title="PAYG" %} ```python import litellm @@ -94,71 +182,105 @@ response = litellm.completion( model="openai/gpt-4o", messages=[{"role": "user", "content": "Hello"}], base_url="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - api_key="", + api_key="", ) print(response.choices[0].message.content) ``` +{% endtab %} -**Cursor / Continue.dev** +{% tab title="Token Plan" %} +```python +import litellm -In the tool's settings, fill in: +response = litellm.completion( + model="glm-5.2", # Model code from your plan's Models tab + messages=[{"role": "user", "content": "Hello"}], + base_url="https://tokenplan.api.greennode.ai/v1", + api_key="", +) +print(response.choices[0].message.content) +``` +{% endtab %} +{% endtabs %} -| Field | Value | -|---|---| -| **Base URL** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | -| **API Key** | `` | -| **Model** | `openai/gpt-4o`, `gemini/gemini-2.5-flash`, `qwen/qwen3-27b` (or the model ID from Step 2) | +### Cursor / Continue.dev -{% hint style="info" %} -**Using a Token Plan (subscription package) key instead of a pay-as-you-go API key?** Use `https://tokenplan.api.greennode.ai/v1` as the Base URL instead. See [Token Plan](../token-plan/README.md) for details. -{% endhint %} +In the tool's settings, fill in the values for your key's service type: ---- +| Field | PAYG | Token Plan | +|---|---|---| +| **Base URL** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | `https://tokenplan.api.greennode.ai/v1` | +| **API Key** | your PAYG API Key | your subscription-key | +| **Model** | `openai/gpt-4o`, `gemini/gemini-2.5-flash`, `qwen/qwen3-27b` (or a model from Step 2) | Model code on the plan's **Models** tab | -## Step 4 — Verify the connection +*** + +## Step 4 — Test the connection Send a test request with curl: +{% tabs %} +{% tab title="PAYG" %} ```bash curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/chat/completions \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o", "messages": [{"role": "user", "content": "ping"}] }' ``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +curl https://tokenplan.api.greennode.ai/v1/chat/completions \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "model": "", + "messages": [{"role": "user", "content": "ping"}] + }' +``` +{% endtab %} +{% endtabs %} Expected result: a JSON response containing `choices[0].message.content`. ---- +*** ## Billing & Usage -- Requests through GreenNode MaaS are billed in credit-tokens (1 credit = 1 VND) -- View real-time usage on [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/) -- **Prepaid:** credits are deducted every 5-minute collection cycle — when credits run out, the model is automatically disabled -- **Postpaid:** usage is recorded as a debt with no quota limit +| | PAYG | Token Plan | +|---|---|---| +| Pricing model | Pay per token actually used, 1 credit = 1 VND | Fixed prepaid 30-day package, token/request quota per model | +| When it runs out | **Prepaid:** credit is deducted every 5-minute collection cycle — when credit hits zero, the model is auto-disabled. **Postpaid:** usage is billed on account, no quota cap | Once that model's token quota is exhausted, requests stop — wait for the next cycle, buy another plan, or temporarily switch to a PAYG API Key | +| Where to track | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** and **Cost** tabs | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** tab only (cost was fixed at purchase) | ---- +*** ## Troubleshooting | Symptom | Cause | Fix | |---|---|---| -| `401 Unauthorized` | Wrong or inactive API key | Verify the key | -| `404 Not Found` | Missing `/v1` in the URL | Ensure the base URL ends with `/v1` | -| Model not responding | Credits exhausted, model disabled | Add credits in AI Platform Console | -| `OPENAI_BASE_URL` not recognized | Tool uses its own config variable | Check the tool's docs for setting a custom base URL | -| Response parse error | Tool auto-appends `/v1` to base URL | Try removing `/v1` from the base URL if the tool handles it | +| `401 Unauthorized` | Wrong or not-yet-ACTIVE key | Re-check the key and its status | +| `401` while the key is still valid | **Key and Base URL belong to different service types** | Re-check the table at the top: a key from the **API Keys** page → the `maas-llm-…` host; a key from the **Subscription keys** tab → the `tokenplan…` host | +| `403 Forbidden` (Token Plan) | Model isn't included in the plan | Only call models listed on the plan's **Models** tab | +| `402 Payment Required` (Token Plan) | Plan expired or was deleted | Buy the plan again or enable **Auto-renew** | +| `404 Not Found` | Missing `/v1` in the URL | OpenAI standard — the base URL must end with `/v1` | +| Model doesn't respond | PAYG out of credit, or Token Plan out of token quota | PAYG: top up credit. Token Plan: wait for the next cycle or buy another plan | +| `OPENAI_BASE_URL` ignored | The tool overrides it with its own config variable | Check that tool's docs for how to set a custom base URL | +| Response parse errors | The tool appends `/v1` to the base URL itself | Try removing `/v1` from the base URL if the tool handles it | ---- +*** ## Result -After configuration, the tool or SDK calls models through GreenNode MaaS instead of OpenAI directly. Usage is recorded in AI Platform Console and billed via internal credit-tokens. +Your tool or SDK now calls models through the GreenNode endpoint for your chosen service type instead of OpenAI directly. Usage is recorded in the AI Platform Console. -| I want to... | Go to | +| I want to next... | Go to | |---|---| -| Use Claude Code with MaaS | [Connect Claude Code to GreenNode MaaS](cli-tools/claude-code.md) | +| Use Claude Code with MaaS | [Claude Code](cli-tools/claude-code.md) | +| Learn about Token Plan packages | [Token Plan](../token-plan/README.md) | +| Walk Token Plan end-to-end, from purchase to a running tool | [A-Z Guide](../token-plan/a-z-guide.md) | | View usage and billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | diff --git a/English/ai-stack/ai-coding/getting-started.md b/English/ai-stack/ai-coding/getting-started.md index 7d202222..d60a4aed 100644 --- a/English/ai-stack/ai-coding/getting-started.md +++ b/English/ai-stack/ai-coding/getting-started.md @@ -1,6 +1,6 @@ # Getting Started with AI Coding (Prerequisites) -> **Root page.** Read this page once to get everything ready, then pick a tool at the bottom of the page. Every tool guide assumes you've already completed the 3 steps here. +> **Root page.** Read this page once to get everything ready, then pick a tool at the bottom of the page. Every tool guide assumes you've already completed the steps here. --- @@ -19,26 +19,68 @@ An easy way to remember: **Base URL** = the address of the GLM "brain". **API ke --- -## 2. Prerequisites checklist +## 2. Identify which service type you're on + +GreenNode offers **two service types** for calling models, each with its **own host** and **own key type**. This is the step people most often get wrong when copying examples — settle it here before reading on. + +| Service type | Key used to call | Where to get the key | Base URL host | +|---|---|---|---| +| **PAYG** — pay per token actually used | API Key | AI Platform → **API Keys** | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| **Token Plan** — prepaid 30-day package with fixed quota | subscription-key | AI Platform → **Token Plan** → **My Token Plans** → open the plan → **Subscription keys** tab | `tokenplan.api.greennode.ai` | + +### 2.1 — Base URL lookup table + +Base URL = the **host for your service type** (table above) + **`/v1` suffix or not, depending on your tool's standard**: + +| Service type | **Anthropic**-standard tools
(Claude Code, Claude Desktop) | **OpenAI**-standard tools
(Codex, OpenCode, Cursor, LiteLLM, OpenAI SDK) | +|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | `https://tokenplan.api.greennode.ai/v1` | + +{% hint style="warning" %} +**Your key and Base URL must belong to the same service type.** Sending a PAYG API Key to the `tokenplan…` host — or a subscription-key to the `maas-llm-aiplatform-hcm…` host — returns `401 Unauthorized`, even though both the key and the URL are perfectly valid on their own. + +You **cannot tell the key types apart by looking at them** — go by **where you got the key**: the **API Keys** page means PAYG, a plan's **Subscription keys** tab means Token Plan. +{% endhint %} + +### 2.2 — Self-check before copying any example + +These three questions decide which tab you copy from on every tool page: + +| # | Question | How to answer | +|---|---|---| +| 1 | Which type is my key? | From the **API Keys** page → **PAYG**. From a plan's **Subscription keys** tab → **Token Plan** | +| 2 | Which standard is my tool? | Claude Code / Claude Desktop → **Anthropic**, Base URL has **no** `/v1`. Everything else → **OpenAI**, Base URL **has** `/v1` | +| 3 | Where does the Model ID come from? | **PAYG:** the model's detail page in the [Models portal](https://aiplatform.console.greennode.ai/models) (e.g. `z-ai/glm-5.2`). **Token Plan:** the **Model code** column on the plan's **Models** tab (e.g. `glm-5.2`) | + +{% hint style="info" %} +The Model ID for the same model **can differ** between the two service types. Always copy from the right source in question 3 — one wrong character gives you a `404` or a model that won't load. +{% endhint %} + +--- + +## 3. Prerequisites checklist | # | You need | What it is | Where to get it | |---|--------|-------|-----------| -| 1 | **API key** | Your personal key, format `--` / `vn-...` | [API Keys page](https://aiplatform.console.greennode.ai/keys) | -| 2 | **Base URL** | MaaS address: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | Fixed — copy it exactly as shown here | -| 3 | **GLM 5.2 model ENABLED** | Make sure GLM 5.2 is turned on for use | [Models page](https://aiplatform.console.greennode.ai/models) → search for **GLM 5.2** | +| 1 | **API key** | Your personal key | **PAYG:** [API Keys page](https://aiplatform.console.greennode.ai/keys) · **Token Plan:** the plan's **Subscription keys** tab | +| 2 | **Base URL** | The endpoint for your service type | Lookup table in **section 2.1** above | +| 3 | **Model ENABLED** | Make sure the model is turned on for use | **PAYG:** [Models page](https://aiplatform.console.greennode.ai/models) · **Token Plan:** the plan's **Models** tab | -Model ID used in configuration (example): **`z-ai/glm-5.2`** +Model ID used in configuration (PAYG example): **`z-ai/glm-5.2`** {% hint style="info" %} -**GLM 5.2 here is just an example model.** GreenNode self-hosts **many models** — swap in whichever model you want to use. The exact **Model ID** and **Base URL** for each model are on that model's **detail page** in the [Models portal](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 here is just an example model.** GreenNode self-hosts **many models** — swap in whichever model you want to use. On PAYG, the exact **Model ID** and **Base URL** for each model are on that model's **detail page** in the [Models portal](https://aiplatform.console.greennode.ai/models). On Token Plan, check your purchased plan's **Models** tab. {% endhint %} --- -## 3. How to get each prerequisite +## 4. How to get each prerequisite -### 3.1 — Get your API key +### 4.1 — Get your key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Open **[https://aiplatform.console.greennode.ai/keys](https://aiplatform.console.greennode.ai/keys)** and log in with your GreenNode account. 2. Click **Create API Key**. 3. Give it a memorable name, e.g. `ai-coding-` (lowercase letters, numbers, hyphens; 5–50 characters). @@ -47,33 +89,56 @@ Model ID used in configuration (example): **`z-ai/glm-5.2`** {% hint style="warning" %} A newly created key may be in **pending** status. Wait until the status becomes **ACTIVE** before using it — refresh the page to check. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Go to **API Key** → **Token Plan** → **My Token Plans** and click the **name of the plan** you bought. +2. Open the **Subscription keys** tab. +3. Copy `default-key` (created automatically when you buy the plan), or a key you created yourself. +4. Switch to the **Models** tab and copy the **Model code** of the model you want. -### 3.2 — Get the Base URL +No plan yet? See [Buy Token Plan](../token-plan/buy-token-plan.md), or walk the whole path end-to-end with the [A-Z Guide](../token-plan/a-z-guide.md). -The Base URL is also shown on each **model's detail page**. For models served through MaaS, the shared address is: +{% hint style="warning" %} +A subscription-key is a **secret** — anyone holding it can call models and burn your plan's quota. Don't paste it into group chats and don't commit it to Git. +{% endhint %} +{% endtab %} +{% endtabs %} +### 4.2 — Get the Base URL + +Pick the right cell from the lookup table in **section 2.1** above based on your key's **service type** and your tool's **standard**: + +{% tabs %} +{% tab title="PAYG" %} ``` +# Anthropic-standard tools (Claude Code, Claude Desktop) — NO /v1 https://maas-llm-aiplatform-hcm.api.vngcloud.vn + +# OpenAI-standard tools (Codex, OpenCode, Cursor, LiteLLM…) — WITH /v1 +https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1 ``` -{% hint style="warning" %} -**This address differs by tool type:** -* **Anthropic**-standard tools (Claude Desktop, Claude Code): use `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` — **no** `/v1`. -* **OpenAI**-standard tools (OpenCode, Codex, Cursor…): add `/v1` at the end → `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +This Base URL is also shown on each **model's detail page** in the Models portal. +{% endtab %} -Each tool's page will tell you which one you need. -{% endhint %} +{% tab title="Token Plan" %} +``` +# Anthropic-standard tools (Claude Code, Claude Desktop) — NO /v1 +https://tokenplan.api.greennode.ai -{% hint style="info" %} -**Using a Token Plan (subscription package) key instead of a pay-as-you-go API key?** The Token Plan Base URL follows the same Anthropic / OpenAI rule as above, just on a different domain: -* **Anthropic**-standard tools (Claude Desktop, Claude Code): `https://tokenplan.api.greennode.ai` — **no** `/v1`. -* **OpenAI**-standard tools (OpenCode, Codex, Cursor…): `https://tokenplan.api.greennode.ai/v1`. +# OpenAI-standard tools (Codex, OpenCode, Cursor, LiteLLM…) — WITH /v1 +https://tokenplan.api.greennode.ai/v1 +``` -See [Token Plan](../token-plan/README.md) for details. -{% endhint %} +This Base URL appears on the plan's **Models** tab, labelled **Gateway base URL**. See [Token Plan](../token-plan/README.md) for more. +{% endtab %} +{% endtabs %} -### 3.3 — Confirm the GLM 5.2 model is enabled +### 4.3 — Confirm the model is enabled +{% tabs %} +{% tab title="PAYG" %} 1. Open the **[Models page](https://aiplatform.console.greennode.ai/models)** and search for the model you want (e.g. **GLM 5.2**). 2. Open that model and confirm its status is **ENABLED**. 3. Right on the **model detail page**, copy the **Model ID** and **Base URL** to fill into your tool (e.g. GLM 5.2 → Model ID `z-ai/glm-5.2`). @@ -81,12 +146,58 @@ See [Token Plan](../token-plan/README.md) for details. {% hint style="info" %} If the model isn't ENABLED yet, contact GreenNode's AI Platform admin team to have it enabled — you can't do this step yourself. {% endhint %} +{% endtab %} + +{% tab title="Token Plan" %} +1. Open the plan's **Plan Detail** page → **Models** tab. +2. The model table lists exactly the models **included in the plan** — those are the only ones you can call. +3. Copy the **Model code** of the model you want (e.g. `glm-5.2`). + +{% hint style="warning" %} +Calling a model **not included in the plan** returns `403 Forbidden`. To use another model, buy a plan that includes it or temporarily switch to a PAYG API Key. +{% endhint %} +{% endtab %} +{% endtabs %} + +### 4.4 — Verify the Base URL + key pair before configuring any tool + +Test it straight from your terminal. Once this works, every tool afterwards is just filling in the same two values: + +{% tabs %} +{% tab title="PAYG" %} +```bash +curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/models \ + -H "Authorization: Bearer " +``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +curl https://tokenplan.api.greennode.ai/v1/chat/completions \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "model": "", + "messages": [{"role": "user", "content": "ping"}] + }' +``` +{% endtab %} +{% endtabs %} + +Reading the result: + +| Result | What it means | What to do | +|---|---|---| +| Valid JSON response | The URL + key pair is correct | Move on to section 5 and pick a tool | +| `401 Unauthorized` | Wrong key, key not **ACTIVE** yet, or **key and host belong to different service types** | Re-check section 2 — use the host that matches where you got the key | +| `403 Forbidden` | Model isn't included in the Token Plan | Only call models listed on the plan's **Models** tab | +| `404 Not Found` | Base URL has the wrong shape | Check the `/v1` rule for your tool's standard in section 2.1 | -✅ Once you have all 3 (an **ACTIVE** key, the Base URL, and an **ENABLED** model), you're ready to pick a tool. +✅ Once you have all 3 (an **ACTIVE** key, the Base URL for your service type, and an **ENABLED** model) and the check above passes, you're ready to pick a tool. --- -## 4. Choose the right tool +## 5. Choose the right tool | You prefer... | OS | Use | |--------------|--------------|----------| @@ -99,18 +210,17 @@ The **Claude Desktop app is only available for macOS and Windows.** If you use * --- -## 5. Quick reference values - -| Info | Value | -|-----------|---------| -| Base URL (Anthropic standard) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | -| Base URL (OpenAI standard) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | -| Base URL (Token Plan, Anthropic standard) | `https://tokenplan.api.greennode.ai` | -| Base URL (Token Plan, OpenAI standard) | `https://tokenplan.api.greennode.ai/v1` | -| Model ID | See the model's detail page (e.g. GLM 5.2 → `z-ai/glm-5.2`) | -| Create / get API key | https://aiplatform.console.greennode.ai/keys | -| Check GLM 5.2 model | https://aiplatform.console.greennode.ai/models (search for GLM 5.2) | -| View usage & billing | https://aiplatform.console.greennode.ai/ | +## 6. Quick reference values + +| Info | PAYG | Token Plan | +|---|---|---| +| Base URL (Anthropic standard) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://tokenplan.api.greennode.ai` | +| Base URL (OpenAI standard) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | `https://tokenplan.api.greennode.ai/v1` | +| Key type | API Key | subscription-key | +| Get the key | [API Keys page](https://aiplatform.console.greennode.ai/keys) | Plan Detail → **Subscription keys** tab | +| Model ID | Model detail page (e.g. `z-ai/glm-5.2`) | **Models** tab → **Model code** column (e.g. `glm-5.2`) | +| List of available models | [Models page](https://aiplatform.console.greennode.ai/models) | The plan's **Models** tab | +| View usage | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** & **Cost** tabs | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** tab only | --- diff --git a/English/ai-stack/ai-coding/gui-tools/README.md b/English/ai-stack/ai-coding/gui-tools/README.md index dcb82d4a..778b1181 100644 --- a/English/ai-stack/ai-coding/gui-tools/README.md +++ b/English/ai-stack/ai-coding/gui-tools/README.md @@ -4,6 +4,10 @@ Before installing, see [Prerequisites](../getting-started.md). +{% hint style="warning" %} +Each tool's configuration section has **separate tabs for PAYG and Token Plan**. Settle your service type first (go by where you got your key), then copy only from that tab — a key and Base URL from different service types return `401 Unauthorized`. +{% endhint %} + | Tool | Notes | |---|---| | [Codex Desktop](codex-desktop.md) | Configured via the `config.toml` file in Settings | diff --git a/English/ai-stack/ai-coding/gui-tools/codex-desktop.md b/English/ai-stack/ai-coding/gui-tools/codex-desktop.md index 6abb67cc..a9e79bcb 100644 --- a/English/ai-stack/ai-coding/gui-tools/codex-desktop.md +++ b/English/ai-stack/ai-coding/gui-tools/codex-desktop.md @@ -3,33 +3,39 @@ > For **beginners** on macOS or Windows. Configure it by editing a `config.toml` file from Settings — you can ask an AI to help draft it, no need to know TOML syntax. Codex Desktop will use GreenNode's self-hosted **GLM 5.2** model. {% hint style="info" %} -**First, complete the [Prerequisites](../getting-started.md):** an **ACTIVE** API key, the Base URL, and the GLM 5.2 model **ENABLED**. This page only covers install and configuration. +**First, complete the [Prerequisites](../getting-started.md):** an **ACTIVE** key, the Base URL for your service type, and the model **ENABLED**. This page only covers install and configuration. {% endhint %} -You'll need these 3 values (from the Prerequisites page): +--- + +## Pick your configuration by service type + +Codex Desktop uses the **OpenAI standard** → `base_url` **includes** `/v1` on both service types. Only the host and the key type differ: -| Info | Value | -| -------------------------- | ------------------------------------------------------------------------------- | -| Base URL (OpenAI standard) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` (**with** `/v1`) | -| Base URL (Token Plan / package key) | `https://tokenplan.api.greennode.ai/v1` — see [Token Plan](../../token-plan/README.md) | -| API key | your`vn-...` key | -| Model ID | `z-ai/glm-5.2` | +| Service type | `base_url` | Key | `model` | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key from the [API Keys page](https://aiplatform.console.greennode.ai/keys) | `z-ai/glm-5.2` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key from Plan Detail → **Subscription keys** tab | Model code on the **Models** tab (e.g. `glm-5.2`) | + +{% hint style="warning" %} +**Your key and `base_url` must belong to the same service type.** A PAYG API Key sent to the `tokenplan…` host (or the reverse) returns `401 Unauthorized` even while the key is still valid. You can't tell the key types apart by looking at them — go by where you got the key. See [section 2 of the Prerequisites page](../getting-started.md). +{% endhint %} {% hint style="info" %} -**GLM 5.2 is just an example model.** GreenNode offers many models — swap in whichever one you want. Each model's Model ID and Base URL are on its [model detail page](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 is just an example model.** GreenNode offers many models — swap in whichever one you want. On PAYG, find the Model ID on the [model detail page](https://aiplatform.console.greennode.ai/models); on Token Plan, check your plan's **Models** tab. {% endhint %} --- ## Step 1 — Download and install Codex Desktop -Go to **[openai.com/index/introducing-the-codex-app](https://openai.com/index/introducing-the-codex-app/)** and download the app for your machine, then install it like a normal app. +Go to **[openai.com/index/introducing-the-codex-app](https://openai.com/index/introducing-the-codex-app/)**, download the app for your machine, and install it like any normal application. --- -## Step 2 — Open the app and log in +## Step 2 — Open the app and sign in -Open Codex and log in with your ChatGPT/OpenAI account. +Open Codex and sign in with your ChatGPT/OpenAI account.

Codex home screen after logging in

@@ -38,7 +44,7 @@ Open Codex and log in with your ChatGPT/OpenAI account. ## Step 3 — Open the config.toml file 1. Click your avatar/account name in the bottom-left corner → **Settings**. -2. In the left search box, type **"config.toml"**. +2. In the search box on the left, type **"config.toml"**. 3. Click **Open config.toml** in the top-right of the **Custom config.toml settings** section — the file opens in your machine's default editor.

Find and open config.toml in Settings

@@ -47,13 +53,15 @@ Open Codex and log in with your ChatGPT/OpenAI account. ## Step 4 — Add the self-hosted model configuration -Add the following block to the **end** of `config.toml` (keep the existing content above it): +Append the block below to the **end** of `config.toml` (leave everything above it untouched). Copy the tab matching your service type: +{% tabs %} +{% tab title="PAYG" %} ```toml [model_providers.vngcloud-glm] name = "VNGCloud GLM" base_url = "https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1" -experimental_bearer_token = "vn-...your-key..." +experimental_bearer_token = "" wire_api = "responses" stream_idle_timeout_ms = 3000000 request_max_retries = 3 @@ -67,32 +75,59 @@ model_auto_compact_token_limit = 200000 model_reasoning_effort = "medium" model_reasoning_summary = "auto" ``` +{% endtab %} + +{% tab title="Token Plan" %} +```toml +[model_providers.greennode-tokenplan] +name = "GreenNode Token Plan" +base_url = "https://tokenplan.api.greennode.ai/v1" +experimental_bearer_token = "" +wire_api = "responses" +stream_idle_timeout_ms = 3000000 +request_max_retries = 3 +supports_websockets = false + +[profiles.glm] +model = "glm-5.2" # replace with the Model code from your plan's Models tab +model_provider = "greennode-tokenplan" +model_context_window = 200000 +model_auto_compact_token_limit = 200000 +model_reasoning_effort = "medium" +model_reasoning_summary = "auto" +``` + +{% hint style="info" %} +`model` must match the **Model code** exactly as shown on the plan's **Models** tab, and that model must be included in the plan — calling a model outside the plan returns `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} **Key fields explained:** -| Field | Purpose | -| -------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `model_providers.vngcloud-glm` | A provider name you choose — reused in`model_provider` below | -| `base_url` | The OpenAI-standard Base URL,**with** `/v1` | -| `experimental_bearer_token` | Your API key, pasted directly into the file — Codex Desktop doesn't need an exported env var like the CLI | -| `wire_api` | Keep as`"responses"` — the Responses API standard Codex Desktop uses | -| `stream_idle_timeout_ms` | Max idle time (ms) before the stream is treated as timed out | -| `request_max_retries` | Number of retries on a failed request | -| `supports_websockets` | Keep as `false` — MaaS doesn't support websockets yet | -| `profiles.glm` | A profile name you choose — appears in the app's model picker | -| `model` | The Model ID sent to MaaS | -| `model_provider` | Points back to the provider declared above | -| `model_context_window` | Set manually since MaaS doesn't expose model metadata | -| `model_auto_compact_token_limit` | Token threshold at which Codex auto-compacts the context | -| `model_reasoning_effort` | Default reasoning effort (`low` / `medium` / `high`) | -| `model_reasoning_summary` | Keep as `"auto"` — lets Codex decide whether to summarize its reasoning | +| Field | Purpose | +|---|---| +| `model_providers.` | A provider name you choose — reused in `model_provider` below | +| `base_url` | The endpoint for your service type, **with** `/v1` | +| `experimental_bearer_token` | Your key, pasted directly into the file — Codex Desktop doesn't need an exported environment variable like the CLI | +| `wire_api` | Leave as `"responses"` — matches the Responses API that Codex Desktop uses | +| `stream_idle_timeout_ms` | Max wait time (ms) before the stream is treated as timed out | +| `request_max_retries` | How many times a failed request is retried | +| `supports_websockets` | Leave as `false` — MaaS doesn't support websockets yet | +| `profiles.glm` | A profile name you choose — appears in the app's model picker | +| `model` | Model ID sent upstream — PAYG uses the Models portal ID, Token Plan uses the plan's Model code | +| `model_provider` | Points back to the provider declared above | +| `model_context_window` | Declared manually because MaaS doesn't expose model metadata | +| `model_auto_compact_token_limit` | Token threshold at which Codex auto-compacts the context | +| `model_reasoning_effort` | Default reasoning level (`low` / `medium` / `high`) | +| `model_reasoning_summary` | Leave as `"auto"` — Codex decides whether to summarize reasoning | {% hint style="warning" %} -**Don't copy the environment-variable style config used for Claude Code** (`export ANTHROPIC_BASE_URL=...`, `claude --model ...`) — that syntax is specific to Claude Code CLI and **doesn't** apply to Codex. Codex Desktop reads its config from `config.toml` using `model_providers` / `profiles` as shown above. +**Don't copy Claude Code's environment-variable style config** (`export ANTHROPIC_BASE_URL=...`, `claude --model ...`) — that syntax is specific to the Claude Code CLI and does **not** work for Codex. Codex Desktop reads its config from `config.toml` using `model_providers` / `profiles` as shown above. {% endhint %} {% hint style="info" %} -**Not comfortable with TOML syntax?** Copy the full content of your current `config.toml`, paste it into an AI chat (Codex, ChatGPT, Claude...) along with the 3 values above (Base URL / API key / Model ID), and ask it to write the `[model_providers.*]` and `[profiles.*]` blocks in the correct Codex format, then paste the result back into the file. +**Not familiar with TOML syntax?** Copy your current `config.toml` contents, paste them into an AI chat (Codex, ChatGPT, Claude...) along with the Base URL / key / Model ID for **your service type**, and ask it to write the `[model_providers.*]` and `[profiles.*]` blocks in valid Codex format, then paste the result back into the file. {% endhint %} --- @@ -100,43 +135,47 @@ model_reasoning_summary = "auto" ## Step 5 — Save the file and restart Codex 1. Save `config.toml`. -2. Fully quit and reopen Codex Desktop. +2. Quit Codex Desktop completely and reopen it. --- ## Step 6 — Verify -1. In the chat panel, click the model picker (bottom-right corner, e.g. **"5.6 Terra Medium"**). -2. Find the profile you just added (e.g. **glm**) in the list — select it. -3. Type a test message, e.g. *"Write a function to add two numbers in Python."* If it responds, you're set. +1. In the chat box, click the model selector (bottom-right, e.g. **"5.6 Terra Medium"**). +2. Find the profile you just added (e.g. **glm**) in the list and select it. +3. Try a prompt, e.g. *"Write a Python function that adds two numbers."* If it answers, you're done. 4. Check the **[AI Platform Console](https://aiplatform.console.greennode.ai/)** to see the call logged.

Configuration succeeded — chat responds and the model picker shows "Custom" instead of the default model

{% hint style="warning" %} -**Note on switching between the default model and your self-hosted model:** If you pick a default Codex model directly from the model picker (UI), the app **only overwrites the `model` field** in `config.toml` — it does **not** reset `model_provider` back to the default (`openai`) provider. If you later want to switch back to the self-hosted model, selecting it through the UI can leave `model` and `model_provider` out of sync (pointing at mismatched providers). To be safe, whenever you switch between the default model and your self-hosted model, **edit `model` / `model_provider` directly in `config.toml`** (or ask an AI to edit it for you) instead of just switching through the model picker. +**Note when switching between the default model and your self-hosted model:** If you pick one of Codex's default models from the model picker (UI), the app **only overwrites the `model` field** in `config.toml` — it does **not** reset `model_provider` back to the default provider (`openai`). If you then want to return to the self-hosted model, clicking through the UI can leave `model` and `model_provider` mismatched. To be safe, when switching between the default and self-hosted models, **edit `model` / `model_provider` directly in `config.toml`** (or ask an AI to do it) instead of only toggling the model picker. {% endhint %} --- ## Troubleshooting -| Symptom | Cause | Fix | -| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -| New profile doesn't show in the model picker | App wasn't restarted, or the`[profiles.*]` section name is wrong | Fully quit and reopen Codex; recheck the TOML syntax | -| `401` / "Unauthorized" | Wrong or not-yet-ACTIVE API key | Recheck your key; wait for**ACTIVE** status | -| `404` / "Not Found" | Wrong Base URL (missing`/v1`) | Should be exactly`https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | -| App errors out / can't read config | Invalid TOML syntax (missing quotes, wrong indentation) | Ask an AI to check the block you added, or compare it against the Step 4 sample | -| No response even with the right model selected | Out of credit, model auto-disabled | Top up credit in the AI Platform Console | -| Switched models via the model picker (UI) and the self-hosted model stopped working | `model` and `model_provider` in `config.toml` are out of sync — the picker only overwrites `model`, not `model_provider` | Reopen`config.toml`, fix `model` / `model_provider` back to a matching pair (see the Step 4 sample), save, and restart Codex | +| Symptom | Cause | Fix | +|------------|-------------|------------| +| New profile doesn't appear in the model picker | App not restarted, or a wrong `[profiles.*]` section name | Quit and reopen Codex; re-check the TOML syntax | +| `401` / "Unauthorized" | Wrong or not-yet-ACTIVE key | Re-check the key; wait for **ACTIVE** status | +| `401` while the key is still valid | **Key and `base_url` belong to different service types** | Re-check the table at the top: a key from the **API Keys** page → the `maas-llm-…` host; a key from the **Subscription keys** tab → the `tokenplan…` host | +| `403 Forbidden` (Token Plan) | Model isn't included in the plan | Set `model` to a Model code listed on the plan's **Models** tab | +| `402 Payment Required` (Token Plan) | Plan expired or was deleted | Buy the plan again or enable **Auto-renew** | +| `404` / "Not Found" | Wrong Base URL (missing `/v1`) | Codex Desktop is OpenAI-standard — `base_url` must end with `/v1` | +| App errors on launch / can't read the config | Invalid TOML syntax (missing `"`, wrong indentation) | Ask an AI to check the block you added, or compare it against the Step 4 sample | +| AI doesn't respond even with the right model selected | PAYG out of credit, or Token Plan out of token quota | PAYG: top up credit. Token Plan: wait for the next cycle, buy another plan, or temporarily switch to a PAYG API Key | +| Self-hosted model stops working after switching via the model picker (UI) | `model` and `model_provider` in `config.toml` are mismatched — the picker only overwrites `model`, it doesn't reset `model_provider` | Reopen `config.toml`, set `model` / `model_provider` to a matching pair (see the Step 4 sample), save, and restart Codex | --- -| I want to next... | Go to | -| --------------------- | -------------------------------------------------------------- | -| Use the CLI version | [Codex CLI](../cli-tools/codex-cli.md) | -| See the prerequisites | [Getting Started with AI Coding](../getting-started.md) | -| View usage & billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | +| I want to next... | Go to | +|------------------------|--------| +| Use it from the command line | [Codex CLI](../cli-tools/codex-cli.md) | +| See the prerequisites | [Getting Started with AI Coding](../getting-started.md) | +| Learn about Token Plan packages | [Token Plan](../../token-plan/README.md) | +| View usage & billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | --- diff --git a/Vietnamese/ai-stack/ai-coding/README.md b/Vietnamese/ai-stack/ai-coding/README.md index fcbc4b3c..e8a08ca8 100644 --- a/Vietnamese/ai-stack/ai-coding/README.md +++ b/Vietnamese/ai-stack/ai-coding/README.md @@ -1,29 +1,38 @@ # AI Coding -AI Coding cho phép kết nối các AI coding tool phổ biến — Claude Code, OpenAI SDK, IDE extension — trực tiếp với GreenNode MaaS, dùng model cloud mà không cần tự quản lý key từ các provider ngoài. +AI Coding cho phép kết nối các AI coding tool phổ biến — Claude Code, OpenAI SDK, IDE extension — trực tiếp với model do GreenNode vận hành, dùng model cloud mà không cần tự quản lý key từ các provider ngoài. --- ## Kiến trúc -Request từ tool của bạn được redirect sang GreenNode MaaS endpoint. MaaS expose hai protocol song song để tương thích với mọi client hiện có: +Request từ tool của bạn được redirect sang endpoint GreenNode. Endpoint expose hai protocol song song để tương thích với mọi client hiện có: -

Hai chuẩn API cùng kết nối tới một MaaS endpoint, dùng chung Model Pool

+

Hai chuẩn API cùng kết nối tới một endpoint, dùng chung Model Pool

-Một API key từ AI Platform dùng được cho cả hai protocol. +Một key dùng được cho cả hai protocol — nhưng **key phải khớp host của loại dịch vụ đã phát hành key đó**. -{% hint style="warning" %} -LLM URL khác nhau theo protocol — xem bảng bên dưới. Dùng sai URL sẽ gây lỗi 404 hoặc request không được parse đúng. -{% endhint %} +--- + +## Hai loại dịch vụ — chọn đúng trước khi cấu hình + +| Loại dịch vụ | Cách tính phí | Key dùng để gọi | Host của Base URL | +|---|---|---|---| +| **PAYG** | Trả theo token thực dùng | API Key từ **API Keys** | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| **Token Plan** | Gói prepaid 30 ngày, hạn mức token cố định | subscription-key từ Plan Detail → tab **Subscription keys** | `tokenplan.api.greennode.ai` | --- -## Protocol và LLM URL +## Base URL theo loại dịch vụ và chuẩn của client -| Client | Protocol | LLM URL | +| Loại dịch vụ | Client chuẩn **Anthropic**
(Claude Code, Anthropic SDK) | Client chuẩn **OpenAI**
(OpenAI SDK, LiteLLM, Cursor, Continue.dev, Codex, OpenCode) | |---|---|---| -| Claude Code, Anthropic SDK | Anthropic Messages API | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | -| OpenAI SDK, LiteLLM, Cursor, Continue.dev | OpenAI-compatible | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | `https://tokenplan.api.greennode.ai/v1` | + +{% hint style="warning" %} +Sai ô trong bảng này là nguyên nhân lỗi phổ biến nhất: sai **hậu tố `/v1`** → `404 Not Found`; sai **host so với loại key** → `401 Unauthorized` dù key vẫn còn hiệu lực. Mọi trang hướng dẫn công cụ đều có tab riêng cho từng loại dịch vụ — chọn đúng tab rồi copy nguyên văn. +{% endhint %} --- @@ -31,20 +40,21 @@ LLM URL khác nhau theo protocol — xem bảng bên dưới. Dùng sai URL sẽ ### Claude Code -Claude Code CLI hỗ trợ override `ANTHROPIC_BASE_URL` — trỏ về GreenNode MaaS thay vì Anthropic trực tiếp. Toàn bộ session, tool call và subagent đều đi qua endpoint GreenNode, billing hiển thị trên AI Platform Console. +Claude Code CLI hỗ trợ override `ANTHROPIC_BASE_URL` — trỏ về endpoint GreenNode thay vì Anthropic trực tiếp. Toàn bộ session, tool call và subagent đều đi qua endpoint GreenNode, usage hiển thị trên AI Platform Console. ### OpenAI-compatible client -Bất kỳ tool nào cho phép set custom `base_url` theo OpenAI SDK format đều hoạt động — OpenAI Python/Node.js SDK, LiteLLM, Cursor, Continue.dev, và các IDE extension khác. Chỉ cần đổi base URL và API key, không cần thay đổi code logic. +Bất kỳ tool nào cho phép set custom `base_url` theo OpenAI SDK format đều hoạt động — OpenAI Python/Node.js SDK, LiteLLM, Cursor, Continue.dev, và các IDE extension khác. Chỉ cần đổi base URL và key, không cần thay đổi code logic. --- ## Billing -- **Credit-token:** 1 credit = 1 VND -- **Prepaid:** credit bị trừ mỗi chu kỳ collect 5 phút. Khi hết credit → model bị tắt tự động -- **Postpaid:** usage được ghi nợ, không giới hạn quota -- Xem usage real-time tại [AI Platform Console → Usage](https://aiplatform.console.vngcloud.vn/) +| | PAYG | Token Plan | +|---|---|---| +| Cách tính | Credit-token, 1 credit = 1 VND | Prepaid trọn gói 30 ngày | +| Hạn mức | **Prepaid:** credit bị trừ mỗi chu kỳ collect 5 phút, hết credit → model bị tắt tự động. **Postpaid:** usage được ghi nợ, không giới hạn quota | Hạn mức token/request cố định theo từng model, dùng chung giữa các subscription-key trong gói | +| Theo dõi | [AI Platform Console](https://aiplatform.console.greennode.ai/) → **Usage** và **Cost** | [AI Platform Console](https://aiplatform.console.greennode.ai/) → chỉ **Usage** | --- @@ -52,8 +62,10 @@ Bất kỳ tool nào cho phép set custom `base_url` theo OpenAI SDK format đ | Tôi muốn... | Đi đến | |---|---| -| Chuẩn bị API key, Base URL, chọn model | [Bắt đầu với AI Coding](bat-dau.md) | -| Dùng công cụ có giao diện (GUI) | Đang cập nhật, sẽ có sau | +| Chuẩn bị key, Base URL, chọn model | [Bắt đầu với AI Coding](bat-dau.md) | +| Dùng công cụ có giao diện (GUI) | [Nhóm Có giao diện](co-giao-dien/README.md) | | Dùng công cụ dòng lệnh (CLI) | [Nhóm Dòng lệnh](dong-lenh/README.md) | +| Cấu hình SDK / IDE extension theo chuẩn OpenAI | [Kết nối OpenAI-compatible với GreenNode MaaS](ket-noi-openai-compatible-voi-maas.md) | | Gắn MCP server cho agent | [Dùng MCP Server với AI Coding](mcp-openrouter.md) | -| Lấy API key | [AI Platform Console](https://aiplatform.console.vngcloud.vn/) | +| Mua và dùng gói Token Plan | [Token Plan](../token-plan/README.md) | +| Lấy API key PAYG | [AI Platform Console](https://aiplatform.console.greennode.ai/) | diff --git a/Vietnamese/ai-stack/ai-coding/bat-dau.md b/Vietnamese/ai-stack/ai-coding/bat-dau.md index 6a6f1fc2..5df51297 100644 --- a/Vietnamese/ai-stack/ai-coding/bat-dau.md +++ b/Vietnamese/ai-stack/ai-coding/bat-dau.md @@ -1,6 +1,6 @@ # Bắt đầu với AI Coding (điều kiện cần) -> **Trang gốc.** Đọc trang này một lần để chuẩn bị đủ mọi thứ, sau đó chọn công cụ ở cuối trang. Mọi hướng dẫn công cụ đều giả định bạn đã làm xong 3 bước ở đây. +> **Trang gốc.** Đọc trang này một lần để chuẩn bị đủ mọi thứ, sau đó chọn công cụ ở cuối trang. Mọi hướng dẫn công cụ đều giả định bạn đã làm xong các bước ở đây. --- @@ -19,26 +19,68 @@ Ví von cho dễ nhớ: **Base URL** = địa chỉ nhà của "bộ não" GLM. --- -## 2. Điều kiện cần — checklist +## 2. Xác định loại dịch vụ bạn đang dùng + +GreenNode có **hai loại dịch vụ** để gọi model, mỗi loại dùng **host riêng** và **loại key riêng**. Đây là bước dễ sai nhất khi copy ví dụ — làm xong bước này rồi hãy đọc tiếp. + +| Loại dịch vụ | Key dùng để gọi | Lấy key ở đâu | Host của Base URL | +|---|---|---|---| +| **PAYG** — trả theo token thực dùng | API Key | AI Platform → **API Keys** | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| **Token Plan** — gói prepaid 30 ngày, hạn mức cố định | subscription-key | AI Platform → **Token Plan** → **My Token Plans** → mở gói → tab **Subscription keys** | `tokenplan.api.greennode.ai` | + +### 2.1 — Bảng tra Base URL + +Base URL = **host theo loại dịch vụ** (bảng trên) + **hậu tố `/v1` hay không, theo chuẩn của tool**: + +| Loại dịch vụ | Tool chuẩn **Anthropic**
(Claude Code, Claude Desktop) | Tool chuẩn **OpenAI**
(Codex, OpenCode, Cursor, LiteLLM, OpenAI SDK) | +|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | `https://tokenplan.api.greennode.ai/v1` | + +{% hint style="warning" %} +**Key và Base URL phải cùng một loại dịch vụ.** Dùng API Key PAYG với host `tokenplan…`, hoặc subscription-key với host `maas-llm-aiplatform-hcm…`, đều trả về `401 Unauthorized` — dù cả key và URL đều hợp lệ khi đứng riêng. + +Bạn **không nhận biết được loại key bằng mắt** — hãy nhớ theo **nơi bạn đã lấy key**: trang **API Keys** là PAYG, tab **Subscription keys** trong một gói là Token Plan. +{% endhint %} + +### 2.2 — Tự kiểm tra trước khi copy bất kỳ ví dụ nào + +Ba câu hỏi này quyết định bạn copy tab nào trong các trang hướng dẫn công cụ: + +| # | Câu hỏi | Cách trả lời | +|---|---|---| +| 1 | Key của tôi thuộc loại nào? | Lấy ở trang **API Keys** → **PAYG**. Lấy ở tab **Subscription keys** của một gói → **Token Plan** | +| 2 | Tool của tôi theo chuẩn nào? | Claude Code / Claude Desktop → **Anthropic**, Base URL **không** `/v1`. Các tool còn lại → **OpenAI**, Base URL **có** `/v1` | +| 3 | Model ID lấy từ đâu? | **PAYG:** trang chi tiết model trên [portal Models](https://aiplatform.console.greennode.ai/models) (ví dụ `z-ai/glm-5.2`). **Token Plan:** cột **Model code** ở tab **Models** của gói (ví dụ `glm-5.2`) | + +{% hint style="info" %} +Model ID của hai loại dịch vụ **có thể khác nhau** cho cùng một model. Luôn copy đúng nguồn ở câu 3 — sai một ký tự là lỗi `404` hoặc model không load. +{% endhint %} + +--- + +## 3. Điều kiện cần — checklist | # | Cần có | Là gì | Lấy ở đâu | |---|--------|-------|-----------| -| 1 | **API key** | Chìa khoá cá nhân, dạng `--` / `vn-...` | [Trang API Keys](https://aiplatform.console.greennode.ai/keys) | -| 2 | **Base URL** | Địa chỉ MaaS: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | Cố định — chép nguyên văn từ đây | -| 3 | **Model GLM 5.2 đã bật (ENABLED)** | Bảo đảm GLM 5.2 đang mở để dùng | [Trang Models](https://aiplatform.console.greennode.ai/models) → gõ tìm **GLM 5.2** | +| 1 | **API key** | Chìa khoá cá nhân | **PAYG:** [Trang API Keys](https://aiplatform.console.greennode.ai/keys) · **Token Plan:** tab **Subscription keys** của gói | +| 2 | **Base URL** | Địa chỉ endpoint theo loại dịch vụ | Bảng tra ở **Mục 2.1** phía trên | +| 3 | **Model đã bật (ENABLED)** | Bảo đảm model đang mở để dùng | **PAYG:** [Trang Models](https://aiplatform.console.greennode.ai/models) · **Token Plan:** tab **Models** của gói | -Model ID dùng khi cấu hình (ví dụ): **`z-ai/glm-5.2`** +Model ID dùng khi cấu hình (ví dụ PAYG): **`z-ai/glm-5.2`** {% hint style="info" %} -**GLM 5.2 ở đây chỉ là một model ví dụ.** GreenNode self-host **nhiều model** khác nhau — bạn thay bằng model mình muốn dùng. **Model ID** và **Base URL** chính xác của từng model đều nằm trong **trang chi tiết của model đó** trên [portal Models](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 ở đây chỉ là một model ví dụ.** GreenNode self-host **nhiều model** khác nhau — bạn thay bằng model mình muốn dùng. Với PAYG, **Model ID** và **Base URL** chính xác của từng model nằm trong **trang chi tiết của model đó** trên [portal Models](https://aiplatform.console.greennode.ai/models). Với Token Plan, xem tab **Models** của gói bạn đã mua. {% endhint %} --- -## 3. Cách lấy từng điều kiện cần +## 4. Cách lấy từng điều kiện cần -### 3.1 — Lấy API key (chìa khoá) +### 4.1 — Lấy API key (chìa khoá) +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Mở **[https://aiplatform.console.greennode.ai/keys](https://aiplatform.console.greennode.ai/keys)** và đăng nhập bằng tài khoản GreenNode. 2. Bấm **Create API Key** (Tạo API key). 3. Đặt tên gợi nhớ, ví dụ `ai-coding-` (chữ thường, số, gạch ngang; 5–50 ký tự). @@ -47,33 +89,56 @@ Model ID dùng khi cấu hình (ví dụ): **`z-ai/glm-5.2`** {% hint style="warning" %} Key mới tạo có thể ở trạng thái **pending** (đang chờ). Đợi tới khi trạng thái là **ACTIVE** mới dùng được — bấm refresh trang để xem. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Vào **API Key** → **Token Plan** → **My Token Plans**, bấm vào **tên gói** bạn đã mua. +2. Mở tab **Subscription keys**. +3. Copy `default-key` (key hệ thống tự tạo khi mua gói), hoặc key bạn tự tạo thêm. +4. Sang tab **Models** để copy luôn **Model code** của model muốn dùng. -### 3.2 — Lấy Base URL (địa chỉ) +Chưa có gói? Xem [Mua gói Token Plan](../token-plan/mua-goi-token-plan.md), hoặc đi hết một vòng theo [Hướng dẫn A-Z](../token-plan/huong-dan-a-z.md). -Base URL cũng hiển thị trong **trang chi tiết mỗi model**. Với các model qua MaaS, địa chỉ chung là: +{% hint style="warning" %} +Subscription-key là **bí mật** — ai cầm được key là gọi được model và tiêu hạn mức của gói. Không dán vào chat nhóm, không commit lên Git. +{% endhint %} +{% endtab %} +{% endtabs %} +### 4.2 — Lấy Base URL (địa chỉ) + +Chọn đúng ô trong bảng tra ở **Mục 2.1** phía trên theo **loại dịch vụ** của key và **chuẩn** của tool: + +{% tabs %} +{% tab title="PAYG" %} ``` +# Tool chuẩn Anthropic (Claude Code, Claude Desktop) — KHÔNG có /v1 https://maas-llm-aiplatform-hcm.api.vngcloud.vn + +# Tool chuẩn OpenAI (Codex, OpenCode, Cursor, LiteLLM…) — CÓ /v1 +https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1 ``` -{% hint style="warning" %} -**Địa chỉ này khác nhau theo loại công cụ:** -* Công cụ chuẩn **Anthropic** (Claude Desktop, Claude Code): dùng `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` — **không** có `/v1`. -* Công cụ chuẩn **OpenAI** (OpenCode, Codex, Cursor…): thêm `/v1` ở cuối → `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +Base URL này cũng hiển thị trong **trang chi tiết mỗi model** trên portal Models. +{% endtab %} -Trang công cụ sẽ nói rõ bạn cần bản nào. -{% endhint %} +{% tab title="Token Plan" %} +``` +# Tool chuẩn Anthropic (Claude Code, Claude Desktop) — KHÔNG có /v1 +https://tokenplan.api.greennode.ai -{% hint style="info" %} -**Nếu dùng key của gói Token Plan (subscription) thay vì API key trả theo mức dùng (pay-as-you-go)**, Base URL của Token Plan cũng theo đúng quy tắc Anthropic / OpenAI như trên, chỉ khác domain: -* Công cụ chuẩn **Anthropic** (Claude Desktop, Claude Code): `https://tokenplan.api.greennode.ai` — **không** có `/v1`. -* Công cụ chuẩn **OpenAI** (OpenCode, Codex, Cursor…): `https://tokenplan.api.greennode.ai/v1`. +# Tool chuẩn OpenAI (Codex, OpenCode, Cursor, LiteLLM…) — CÓ /v1 +https://tokenplan.api.greennode.ai/v1 +``` -Xem chi tiết tại [Token Plan](../token-plan/README.md). -{% endhint %} +Base URL này hiển thị ở tab **Models** của gói, dưới nhãn **Gateway base URL**. Xem thêm [Token Plan](../token-plan/README.md). +{% endtab %} +{% endtabs %} -### 3.3 — Kiểm tra model GLM 5.2 đã được bật +### 4.3 — Kiểm tra model đã được bật +{% tabs %} +{% tab title="PAYG" %} 1. Mở **[trang Models](https://aiplatform.console.greennode.ai/models)** và gõ tìm model bạn muốn dùng (ví dụ **GLM 5.2**). 2. Mở model đó ra, xác nhận trạng thái là **ENABLED** (đang bật). 3. Ngay trong **trang chi tiết model**, copy sẵn **Model ID** và **Base URL** để điền vào công cụ (ví dụ GLM 5.2 → Model ID `z-ai/glm-5.2`). @@ -81,12 +146,58 @@ Xem chi tiết tại [Token Plan](../token-plan/README.md). {% hint style="info" %} Nếu model chưa ENABLED, liên hệ đội quản trị AI Platform của GreenNode để được bật — bạn không tự làm bước này được. {% endhint %} +{% endtab %} + +{% tab title="Token Plan" %} +1. Mở **Plan Detail** của gói → tab **Models**. +2. Bảng model liệt kê đúng những model **nằm trong gói** — chỉ gọi được các model này. +3. Copy **Model code** của model muốn dùng (ví dụ `glm-5.2`). + +{% hint style="warning" %} +Gọi model **không nằm trong gói** trả về `403 Forbidden`. Muốn dùng model khác, mua gói có model đó hoặc tạm chuyển sang API Key PAYG. +{% endhint %} +{% endtab %} +{% endtabs %} + +### 4.4 — Kiểm tra cặp Base URL + key trước khi cấu hình tool + +Chạy thử ngay trong terminal. Nếu bước này chạy được, mọi tool phía sau chỉ là điền lại đúng 2 giá trị vừa dùng: + +{% tabs %} +{% tab title="PAYG" %} +```bash +curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/models \ + -H "Authorization: Bearer " +``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +curl https://tokenplan.api.greennode.ai/v1/chat/completions \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "model": "", + "messages": [{"role": "user", "content": "ping"}] + }' +``` +{% endtab %} +{% endtabs %} + +Đọc kết quả: + +| Kết quả | Nghĩa là | Làm gì | +|---|---|---| +| Response JSON hợp lệ | Cặp URL + key đúng | Sang Mục 5 chọn công cụ | +| `401 Unauthorized` | Key sai, chưa **ACTIVE**, hoặc **key và host lệch loại dịch vụ** | Đối chiếu lại Mục 2 — key lấy ở đâu thì dùng host của loại đó | +| `403 Forbidden` | Model không nằm trong gói Token Plan | Chỉ gọi model có trong tab **Models** của gói | +| `404 Not Found` | Base URL sai dạng | Kiểm tra `/v1` theo chuẩn tool ở Mục 2.1 | -✅ Có đủ 3 thứ (key **ACTIVE**, Base URL, model **ENABLED**) là bạn sẵn sàng chọn công cụ. +✅ Có đủ 3 thứ (key **ACTIVE**, Base URL đúng loại dịch vụ, model **ENABLED**) và bước kiểm tra trên chạy được là bạn sẵn sàng chọn công cụ. --- -## 4. Chọn công cụ phù hợp +## 5. Chọn công cụ phù hợp | Bạn thích... | Hệ điều hành | Nên dùng | |--------------|--------------|----------| @@ -99,18 +210,17 @@ App **Claude Desktop chỉ có bản macOS và Windows.** Nếu bạn dùng **Li --- -## 5. Bảng giá trị tham chiếu nhanh - -| Thông tin | Giá trị | -|-----------|---------| -| Base URL (chuẩn Anthropic) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | -| Base URL (chuẩn OpenAI) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | -| Base URL (Token Plan, chuẩn Anthropic) | `https://tokenplan.api.greennode.ai` | -| Base URL (Token Plan, chuẩn OpenAI) | `https://tokenplan.api.greennode.ai/v1` | -| Model ID | Xem trong chi tiết model (ví dụ GLM 5.2 → `z-ai/glm-5.2`) | -| Tạo / lấy API key | https://aiplatform.console.greennode.ai/keys | -| Kiểm tra model GLM 5.2 | https://aiplatform.console.greennode.ai/models (gõ tìm GLM 5.2) | -| Xem usage & billing | https://aiplatform.console.greennode.ai/ | +## 6. Bảng giá trị tham chiếu nhanh + +| Thông tin | PAYG | Token Plan | +|---|---|---| +| Base URL (chuẩn Anthropic) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | `https://tokenplan.api.greennode.ai` | +| Base URL (chuẩn OpenAI) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | `https://tokenplan.api.greennode.ai/v1` | +| Loại key | API Key | subscription-key | +| Lấy key | [Trang API Keys](https://aiplatform.console.greennode.ai/keys) | Plan Detail → tab **Subscription keys** | +| Model ID | Trang chi tiết model (ví dụ `z-ai/glm-5.2`) | Tab **Models** → cột **Model code** (ví dụ `glm-5.2`) | +| Danh sách model khả dụng | [Trang Models](https://aiplatform.console.greennode.ai/models) | Tab **Models** của gói | +| Xem usage | [AI Platform Console](https://aiplatform.console.greennode.ai/) → tab **Usage** & **Cost** | [AI Platform Console](https://aiplatform.console.greennode.ai/) → chỉ tab **Usage** | --- diff --git a/Vietnamese/ai-stack/ai-coding/co-giao-dien/README.md b/Vietnamese/ai-stack/ai-coding/co-giao-dien/README.md index 39a8379f..17f4c8e5 100644 --- a/Vietnamese/ai-stack/ai-coding/co-giao-dien/README.md +++ b/Vietnamese/ai-stack/ai-coding/co-giao-dien/README.md @@ -4,6 +4,10 @@ Trước khi cài, xem [Điều kiện cần](../bat-dau.md). +{% hint style="warning" %} +Phần cấu hình của mỗi công cụ có **tab riêng cho PAYG và Token Plan**. Xác định loại dịch vụ của bạn trước (theo nơi bạn lấy key), rồi chỉ copy từ tab đó — key và Base URL lệch loại dịch vụ sẽ trả về `401 Unauthorized`. +{% endhint %} + | Công cụ | Ghi chú | |---|---| | [Codex Desktop](codex-desktop.md) | Cấu hình qua file `config.toml` trong Settings | diff --git a/Vietnamese/ai-stack/ai-coding/co-giao-dien/codex-desktop.md b/Vietnamese/ai-stack/ai-coding/co-giao-dien/codex-desktop.md index e3147f1b..140c701a 100644 --- a/Vietnamese/ai-stack/ai-coding/co-giao-dien/codex-desktop.md +++ b/Vietnamese/ai-stack/ai-coding/co-giao-dien/codex-desktop.md @@ -3,20 +3,26 @@ > Dành cho **người mới bắt đầu** dùng macOS hoặc Windows. Cấu hình bằng cách sửa 1 file `config.toml` qua Settings — có thể nhờ AI hỗ trợ soạn, không cần thuộc cú pháp TOML. Codex Desktop sẽ dùng model **GLM 5.2** chạy nội bộ của GreenNode. {% hint style="info" %} -**Trước tiên hãy chuẩn bị [Điều kiện cần](../bat-dau.md):** API key (ACTIVE), Base URL, và model GLM 5.2 đã ENABLED. Trang này chỉ hướng dẫn cài và cấu hình. +**Trước tiên hãy chuẩn bị [Điều kiện cần](../bat-dau.md):** key (ACTIVE), Base URL đúng loại dịch vụ, và model đã ENABLED. Trang này chỉ hướng dẫn cài và cấu hình. {% endhint %} -Bạn sẽ cần 3 giá trị này (lấy ở trang Điều kiện cần): +--- + +## Chọn cấu hình theo loại dịch vụ + +Codex Desktop dùng **chuẩn OpenAI** → `base_url` **có** `/v1` ở cả hai loại dịch vụ. Chỉ khác host và loại key: -| Thông tin | Giá trị | -|-----------|---------| -| Base URL (chuẩn OpenAI) | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` (**có** `/v1`) | -| Base URL (key của gói Token Plan) | `https://tokenplan.api.greennode.ai/v1` — xem [Token Plan](../../token-plan/README.md) | -| API key | key `vn-...` của bạn | -| Model ID | `z-ai/glm-5.2` | +| Loại dịch vụ | `base_url` | Key | `model` | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key từ [trang API Keys](https://aiplatform.console.greennode.ai/keys) | `z-ai/glm-5.2` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key từ Plan Detail → tab **Subscription keys** | Model code ở tab **Models** (ví dụ `glm-5.2`) | + +{% hint style="warning" %} +**Key và `base_url` phải cùng một loại dịch vụ.** API Key PAYG gửi tới host `tokenplan…` (hoặc ngược lại) trả về `401 Unauthorized` dù key vẫn còn hiệu lực. Không nhận biết loại key bằng mắt được — nhớ theo nơi bạn đã lấy key. Xem [Mục 2 của trang Điều kiện cần](../bat-dau.md). +{% endhint %} {% hint style="info" %} -**GLM 5.2 chỉ là model ví dụ.** GreenNode có nhiều model — bạn thay bằng model mình muốn. Model ID và Base URL của từng model đều xem được trong [trang chi tiết model](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 chỉ là model ví dụ.** GreenNode có nhiều model — bạn thay bằng model mình muốn. Với PAYG, Model ID xem trong [trang chi tiết model](https://aiplatform.console.greennode.ai/models); với Token Plan, xem tab **Models** của gói. {% endhint %} --- @@ -47,13 +53,15 @@ Mở Codex, đăng nhập bằng tài khoản ChatGPT/OpenAI của bạn. ## Bước 4 — Thêm cấu hình model self-host -Thêm đoạn sau vào **cuối** file `config.toml` (giữ nguyên nội dung có sẵn phía trên): +Thêm đoạn dưới đây vào **cuối** file `config.toml` (giữ nguyên nội dung có sẵn phía trên). Copy đúng tab theo loại dịch vụ của bạn: +{% tabs %} +{% tab title="PAYG" %} ```toml [model_providers.vngcloud-glm] name = "VNGCloud GLM" base_url = "https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1" -experimental_bearer_token = "vn-...key-của-bạn..." +experimental_bearer_token = "" wire_api = "responses" stream_idle_timeout_ms = 3000000 request_max_retries = 3 @@ -67,20 +75,47 @@ model_auto_compact_token_limit = 200000 model_reasoning_effort = "medium" model_reasoning_summary = "auto" ``` +{% endtab %} + +{% tab title="Token Plan" %} +```toml +[model_providers.greennode-tokenplan] +name = "GreenNode Token Plan" +base_url = "https://tokenplan.api.greennode.ai/v1" +experimental_bearer_token = "" +wire_api = "responses" +stream_idle_timeout_ms = 3000000 +request_max_retries = 3 +supports_websockets = false + +[profiles.glm] +model = "glm-5.2" # thay bằng Model code ở tab Models của gói +model_provider = "greennode-tokenplan" +model_context_window = 200000 +model_auto_compact_token_limit = 200000 +model_reasoning_effort = "medium" +model_reasoning_summary = "auto" +``` + +{% hint style="info" %} +`model` phải là **Model code** đúng như tab **Models** của gói hiển thị, và model đó phải nằm trong gói — gọi model ngoài gói trả về `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} **Giải thích các field quan trọng:** | Field | Mục đích | |---|---| -| `model_providers.vngcloud-glm` | Tên provider tuỳ bạn đặt — dùng lại ở `model_provider` bên dưới | -| `base_url` | Base URL chuẩn OpenAI, **có** `/v1` | -| `experimental_bearer_token` | API key của bạn, dán trực tiếp vào file — Codex Desktop không cần export biến môi trường như CLI | +| `model_providers.` | Tên provider tuỳ bạn đặt — dùng lại ở `model_provider` bên dưới | +| `base_url` | Endpoint theo loại dịch vụ, **có** `/v1` | +| `experimental_bearer_token` | Key của bạn, dán trực tiếp vào file — Codex Desktop không cần export biến môi trường như CLI | | `wire_api` | Để `"responses"` — đúng chuẩn Responses API mà Codex Desktop dùng | | `stream_idle_timeout_ms` | Thời gian chờ tối đa (ms) trước khi coi stream là timeout | | `request_max_retries` | Số lần retry lại request khi gọi lỗi | | `supports_websockets` | Để `false` — MaaS chưa hỗ trợ websocket | | `profiles.glm` | Tên profile tuỳ bạn đặt — sẽ hiện trong model picker của app | -| `model` | Model ID gửi lên MaaS | +| `model` | Model ID gửi lên — PAYG dùng Model ID của portal Models, Token Plan dùng Model code của gói | | `model_provider` | Trỏ về provider đã khai báo ở trên | | `model_context_window` | Khai báo thủ công vì MaaS không expose metadata model | | `model_auto_compact_token_limit` | Ngưỡng token để Codex tự nén (compact) lại context | @@ -92,7 +127,7 @@ model_reasoning_summary = "auto" {% endhint %} {% hint style="info" %} -**Chưa quen cú pháp TOML?** Copy toàn bộ nội dung file `config.toml` hiện tại, dán vào một AI chat (Codex, ChatGPT, Claude...) kèm 3 giá trị Base URL / API key / Model ID ở trên, nhờ AI viết giúp đoạn `[model_providers.*]` và `[profiles.*]` đúng chuẩn Codex rồi dán lại vào file. +**Chưa quen cú pháp TOML?** Copy toàn bộ nội dung file `config.toml` hiện tại, dán vào một AI chat (Codex, ChatGPT, Claude...) kèm 3 giá trị Base URL / key / Model ID của **đúng loại dịch vụ** bạn dùng, nhờ AI viết giúp đoạn `[model_providers.*]` và `[profiles.*]` đúng chuẩn Codex rồi dán lại vào file. {% endhint %} --- @@ -124,10 +159,13 @@ model_reasoning_summary = "auto" | Hiện tượng | Nguyên nhân | Cách xử lý | |------------|-------------|------------| | Không thấy profile mới trong model picker | Chưa restart app, hoặc sai tên section `[profiles.*]` | Thoát hẳn và mở lại Codex; kiểm tra lại cú pháp TOML | -| `401` / "Unauthorized" | API key sai hoặc chưa ACTIVE | Kiểm tra lại key; đợi trạng thái **ACTIVE** | -| `404` / "Not Found" | Base URL sai (thiếu `/v1`) | Đúng phải là `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | +| `401` / "Unauthorized" | Key sai hoặc chưa ACTIVE | Kiểm tra lại key; đợi trạng thái **ACTIVE** | +| `401` dù key còn hiệu lực | **Key và `base_url` lệch loại dịch vụ** | Đối chiếu bảng đầu trang: key ở trang **API Keys** → host `maas-llm-…`; key ở tab **Subscription keys** → host `tokenplan…` | +| `403 Forbidden` (Token Plan) | Model không nằm trong gói | Đặt `model` là Model code có trong tab **Models** của gói | +| `402 Payment Required` (Token Plan) | Gói hết hạn hoặc bị xoá | Mua lại gói hoặc bật **Auto-renew** | +| `404` / "Not Found" | Base URL sai (thiếu `/v1`) | Codex Desktop là chuẩn OpenAI — `base_url` phải kết thúc bằng `/v1` | | App báo lỗi khi mở / không đọc được config | Sai cú pháp TOML (thiếu dấu `"`, sai indent) | Nhờ AI kiểm tra lại đoạn vừa thêm, hoặc so lại với mẫu ở Bước 4 | -| AI không phản hồi dù đã chọn đúng model | Hết credit nên model bị tắt | Nạp credit tại AI Platform Console | +| AI không phản hồi dù đã chọn đúng model | PAYG hết credit, hoặc Token Plan hết hạn mức token | PAYG: nạp credit. Token Plan: đợi chu kỳ mới, mua thêm gói, hoặc tạm chuyển sang API Key PAYG | | Đổi model qua model picker (UI) xong, model self-host không dùng được nữa | `model` và `model_provider` trong `config.toml` bị lệch nhau — picker chỉ ghi đè `model`, không reset `model_provider` | Mở lại `config.toml`, sửa `model` / `model_provider` cho khớp đúng cặp (xem mẫu ở Bước 4), lưu rồi restart Codex | --- @@ -136,6 +174,7 @@ model_reasoning_summary = "auto" |------------------------|--------| | Dùng bằng dòng lệnh | [Codex CLI](../dong-lenh/codex-cli.md) | | Xem điều kiện cần | [Bắt đầu với AI Coding](../bat-dau.md) | +| Tìm hiểu gói Token Plan | [Token Plan](../../token-plan/README.md) | | Xem usage & billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | --- diff --git a/Vietnamese/ai-stack/ai-coding/dong-lenh/README.md b/Vietnamese/ai-stack/ai-coding/dong-lenh/README.md index 4ad5d53b..5f53f0d4 100644 --- a/Vietnamese/ai-stack/ai-coding/dong-lenh/README.md +++ b/Vietnamese/ai-stack/ai-coding/dong-lenh/README.md @@ -4,6 +4,10 @@ Trước khi cài, xem [Điều kiện cần](../bat-dau.md). +{% hint style="warning" %} +Mỗi trang bên dưới có **tab riêng cho PAYG và Token Plan** ở phần cấu hình. Xác định loại dịch vụ của bạn trước (theo nơi bạn lấy key), rồi chỉ copy từ tab đó — key và Base URL lệch loại dịch vụ sẽ trả về `401 Unauthorized`. +{% endhint %} + * [Claude Code](claude-code.md) * [Codex CLI](codex-cli.md) * [OpenCode](opencode.md) diff --git a/Vietnamese/ai-stack/ai-coding/dong-lenh/claude-code.md b/Vietnamese/ai-stack/ai-coding/dong-lenh/claude-code.md index 85e40e95..4ba1def9 100644 --- a/Vietnamese/ai-stack/ai-coding/dong-lenh/claude-code.md +++ b/Vietnamese/ai-stack/ai-coding/dong-lenh/claude-code.md @@ -3,18 +3,26 @@ > Dành cho người dùng terminal (macOS / Linux / WSL / Windows). Claude Code CLI sẽ dùng model **GLM 5.2** của GreenNode qua MaaS thay vì gọi thẳng Anthropic. {% hint style="info" %} -**Trước tiên hãy chuẩn bị [Điều kiện cần](../bat-dau.md):** API key (ACTIVE), Base URL, và model GLM 5.2 đã ENABLED. +**Trước tiên hãy chuẩn bị [Điều kiện cần](../bat-dau.md):** key (ACTIVE), Base URL đúng loại dịch vụ, và model đã ENABLED. {% endhint %} -| Thông tin | Giá trị | -|-----------|---------| -| Base URL | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` (chuẩn Anthropic, **không** `/v1`) | -| Base URL (key của gói Token Plan) | `https://tokenplan.api.greennode.ai` (**không** `/v1`) — xem [Token Plan](../../token-plan/README.md) | -| API key | key của bạn | -| Model ID | `z-ai/glm-5.2` | +--- + +## Chọn cấu hình theo loại dịch vụ + +Claude Code dùng **chuẩn Anthropic** → Base URL **không** có `/v1` ở cả hai loại dịch vụ. Chỉ khác host và loại key: + +| Loại dịch vụ | Base URL | Key | Model ID | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | API Key từ [trang API Keys](https://aiplatform.console.greennode.ai/keys) | `z-ai/glm-5.2` | +| **Token Plan** | `https://tokenplan.api.greennode.ai` | subscription-key từ Plan Detail → tab **Subscription keys** | Model code ở tab **Models** (ví dụ `glm-5.2`) | + +{% hint style="warning" %} +**Key và Base URL phải cùng một loại dịch vụ.** API Key PAYG gửi tới host `tokenplan…` (hoặc ngược lại) trả về `401 Unauthorized` dù key vẫn còn hiệu lực. Không nhận biết loại key bằng mắt được — nhớ theo nơi bạn đã lấy key. Xem [Mục 2 của trang Điều kiện cần](../bat-dau.md). +{% endhint %} {% hint style="info" %} -**GLM 5.2 chỉ là model ví dụ.** GreenNode có nhiều model — bạn thay bằng model mình muốn. Model ID và Base URL của từng model đều xem được trong [trang chi tiết model](https://aiplatform.console.greennode.ai/models). +**GLM 5.2 chỉ là model ví dụ.** GreenNode có nhiều model — bạn thay bằng model mình muốn. Với PAYG, Model ID xem trong [trang chi tiết model](https://aiplatform.console.greennode.ai/models); với Token Plan, xem tab **Models** của gói. {% endhint %} --- @@ -29,15 +37,15 @@ npm install -g @anthropic-ai/claude-code ## Bước 2 — Khai báo Base URL & API key -Chọn đúng mục theo hệ điều hành của bạn. +Chọn đúng tab theo **loại dịch vụ** của bạn và **hệ điều hành**, rồi copy nguyên văn — chỉ thay giá trị key. {% tabs %} -{% tab title="macOS / Linux / WSL (bash hoặc zsh)" %} +{% tab title="PAYG — macOS / Linux / WSL" %} Chạy tạm cho phiên hiện tại: ```bash export ANTHROPIC_BASE_URL="https://maas-llm-aiplatform-hcm.api.vngcloud.vn" -export ANTHROPIC_AUTH_TOKEN="--" # thay bằng API key của bạn +export ANTHROPIC_AUTH_TOKEN="" ``` Để tự động mỗi lần mở terminal, thêm 2 dòng trên vào cuối `~/.zshrc` (macOS) hoặc `~/.bashrc` (Linux/WSL), rồi nạp lại: @@ -47,19 +55,50 @@ source ~/.zshrc # hoặc: source ~/.bashrc ``` {% endtab %} -{% tab title="Windows PowerShell" %} +{% tab title="PAYG — Windows PowerShell" %} Chạy tạm cho cửa sổ PowerShell hiện tại: ```powershell $env:ANTHROPIC_BASE_URL = "https://maas-llm-aiplatform-hcm.api.vngcloud.vn" -$env:ANTHROPIC_AUTH_TOKEN = "--" # thay bằng API key của bạn +$env:ANTHROPIC_AUTH_TOKEN = "" ``` Để lưu vĩnh viễn cho tài khoản (chỉ chạy một lần, rồi **mở lại PowerShell**): ```powershell [Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://maas-llm-aiplatform-hcm.api.vngcloud.vn", "User") -[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "--", "User") +[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User") +``` +{% endtab %} + +{% tab title="Token Plan — macOS / Linux / WSL" %} +Chạy tạm cho phiên hiện tại: + +```bash +export ANTHROPIC_BASE_URL="https://tokenplan.api.greennode.ai" +export ANTHROPIC_AUTH_TOKEN="" +``` + +Để tự động mỗi lần mở terminal, thêm 2 dòng trên vào cuối `~/.zshrc` (macOS) hoặc `~/.bashrc` (Linux/WSL), rồi nạp lại: + +```bash +source ~/.zshrc # hoặc: source ~/.bashrc +``` +{% endtab %} + +{% tab title="Token Plan — Windows PowerShell" %} +Chạy tạm cho cửa sổ PowerShell hiện tại: + +```powershell +$env:ANTHROPIC_BASE_URL = "https://tokenplan.api.greennode.ai" +$env:ANTHROPIC_AUTH_TOKEN = "" +``` + +Để lưu vĩnh viễn cho tài khoản (chỉ chạy một lần, rồi **mở lại PowerShell**): + +```powershell +[Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", "https://tokenplan.api.greennode.ai", "User") +[Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", "", "User") ``` {% endtab %} {% endtabs %} @@ -68,26 +107,40 @@ $env:ANTHROPIC_AUTH_TOKEN = "--" # thay bằng API key của bạn --- -## Bước 3 — Chạy Claude Code với GLM 5.2 +## Bước 3 — Chạy Claude Code -Trong thư mục project, chạy: +Trong thư mục project, chạy lệnh ứng với loại dịch vụ của bạn: +{% tabs %} +{% tab title="PAYG" %} ```bash claude --model z-ai/glm-5.2 ``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +claude --model glm-5.2 +``` + +Thay `glm-5.2` bằng đúng **Model code** ở tab **Models** của gói bạn đã mua. +{% endtab %} +{% endtabs %} {% hint style="info" %} -Cờ `--model z-ai/glm-5.2` chỉ định model cho phiên hiện tại. Trong Claude Code bạn cũng có thể đổi model bằng lệnh `/model`. +Cờ `--model` chỉ định model cho phiên hiện tại. Trong Claude Code bạn cũng có thể đổi model bằng lệnh `/model`. {% endhint %} --- ## Bước 4 — Kiểm tra -Trong Claude Code, gõ `/status` — đúng khi: +Trong Claude Code, gõ `/status` và đối chiếu: -* Base URL trỏ về `maas-llm-aiplatform-hcm.api.vngcloud.vn` -* Model là `z-ai/glm-5.2` +| Kiểm tra | PAYG | Token Plan | +|---|---|---| +| Base URL trỏ về | `maas-llm-aiplatform-hcm.api.vngcloud.vn` | `tokenplan.api.greennode.ai` | +| Model | `z-ai/glm-5.2` | Model code của gói (ví dụ `glm-5.2`) | Sau đó vào **[AI Platform Console](https://aiplatform.console.greennode.ai/)** để thấy lượt gọi được ghi nhận. @@ -99,12 +152,15 @@ Sau đó vào **[AI Platform Console](https://aiplatform.console.greennode.ai/)* | Hiện tượng | Nguyên nhân | Cách xử lý | |------------|-------------|------------| -| `401` / "Unauthorized" | API key sai hoặc chưa ACTIVE | Kiểm tra `ANTHROPIC_AUTH_TOKEN`; đợi key **ACTIVE** | -| `404` / "Not Found" | Base URL sai (thừa `/v1` hoặc `/` cuối) | Đúng phải là `https://maas-llm-aiplatform-hcm.api.vngcloud.vn` | +| `401` / "Unauthorized" | Key sai hoặc chưa ACTIVE | Kiểm tra `ANTHROPIC_AUTH_TOKEN`; đợi key **ACTIVE** | +| `401` dù key còn hiệu lực | **Key và Base URL lệch loại dịch vụ** — ví dụ API Key PAYG gửi tới host `tokenplan…` | Đối chiếu lại bảng ở đầu trang: key lấy ở trang **API Keys** → host `maas-llm-…`; key lấy ở tab **Subscription keys** → host `tokenplan…` | +| `403 Forbidden` (Token Plan) | Model không nằm trong gói | Chỉ gọi model có trong tab **Models** của gói | +| `402 Payment Required` (Token Plan) | Gói đã hết hạn hoặc bị xoá | Mua lại gói hoặc bật **Auto-renew** | +| `404` / "Not Found" | Base URL sai (thừa `/v1` hoặc `/` cuối) | Claude Code là chuẩn Anthropic — Base URL **không** có `/v1` | | Request đi thẳng Anthropic | Còn biến `ANTHROPIC_API_KEY` cũ | Chạy `unset ANTHROPIC_API_KEY` (macOS/Linux) hoặc xoá biến đó trong Windows | -| Sai model được dùng | Thiếu cờ `--model` | Chạy `claude --model z-ai/glm-5.2` hoặc dùng `/model` để đổi | -| AI không phản hồi | Hết credit nên model bị tắt | Nạp credit tại AI Platform Console | -| Connection timeout | Không ra được mạng tới MaaS | Kiểm tra VPN / mạng tới `*.api.vngcloud.vn` | +| Sai model được dùng | Thiếu cờ `--model`, hoặc dùng Model ID của loại dịch vụ khác | Chạy `claude --model ` hoặc dùng `/model` để đổi | +| AI không phản hồi | PAYG hết credit, hoặc Token Plan hết hạn mức token | PAYG: nạp credit. Token Plan: đợi chu kỳ mới, mua thêm gói, hoặc tạm chuyển sang API Key PAYG | +| Connection timeout | Không ra được mạng tới endpoint | Kiểm tra VPN / mạng tới `*.api.vngcloud.vn` (PAYG) hoặc `tokenplan.api.greennode.ai` (Token Plan) | --- @@ -112,6 +168,7 @@ Sau đó vào **[AI Platform Console](https://aiplatform.console.greennode.ai/)* |------------------------|--------| | Dùng OpenCode | [OpenCode](opencode.md) | | Xem điều kiện cần | [Bắt đầu với AI Coding](../bat-dau.md) | +| Tìm hiểu gói Token Plan | [Token Plan](../../token-plan/README.md) | --- diff --git a/Vietnamese/ai-stack/ai-coding/dong-lenh/codex-cli.md b/Vietnamese/ai-stack/ai-coding/dong-lenh/codex-cli.md index 5ebc6f52..f858a72e 100644 --- a/Vietnamese/ai-stack/ai-coding/dong-lenh/codex-cli.md +++ b/Vietnamese/ai-stack/ai-coding/dong-lenh/codex-cli.md @@ -6,13 +6,22 @@ ## Điều kiện cần (Prerequisites) -* Chuẩn bị API key, Base URL và model theo [Bắt đầu với AI Coding](../bat-dau.md) +* Chuẩn bị key, Base URL và model theo [Bắt đầu với AI Coding](../bat-dau.md) * Node.js ≥ 22 đã cài đặt -> Model Minimax M2.5 qua Codex dùng **chuẩn OpenAI** — Base URL có `/v1`: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +*** -{% hint style="info" %} -**Nếu dùng key của gói Token Plan (subscription) thay vì API key trả theo mức dùng (pay-as-you-go)**, dùng `https://tokenplan.api.greennode.ai/v1` làm Base URL thay thế. Xem chi tiết tại [Token Plan](../../token-plan/README.md). +## Chọn cấu hình theo loại dịch vụ + +Codex dùng **chuẩn OpenAI** → Base URL **có** `/v1` ở cả hai loại dịch vụ. Chỉ khác host và loại key: + +| Loại dịch vụ | `base_url` | Key | `model` | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key từ [trang API Keys](https://aiplatform.console.greennode.ai/keys) | `minimax/minimax-m2.5` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key từ Plan Detail → tab **Subscription keys** | Model code ở tab **Models** của gói | + +{% hint style="warning" %} +**Key và Base URL phải cùng một loại dịch vụ.** API Key PAYG gửi tới host `tokenplan…` (hoặc ngược lại) trả về `401 Unauthorized` dù key vẫn còn hiệu lực. Nhớ theo nơi bạn đã lấy key — xem [Mục 2 của trang Điều kiện cần](../bat-dau.md). {% endhint %} *** @@ -31,26 +40,40 @@ codex --version *** -## Bước 2 — Lấy API key từ AI Platform +## Bước 2 — Lấy key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Đăng nhập [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Vào **API Keys** → **Create API Key** 3. Đặt tên key (5–50 ký tự, chữ thường + số + gạch ngang) -4. Copy API key (`vn-...`) vừa tạo +4. Copy API key vừa tạo {% hint style="warning" %} API key mới tạo ở trạng thái `pending`. Đợi đến khi status = `ACTIVE` mới dùng được. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Vào **API Key** → **Token Plan** → **My Token Plans**, mở gói đã mua +2. Tab **Subscription keys** → copy `default-key` hoặc key bạn tự tạo +3. Tab **Models** → copy **Model code** của model muốn dùng + +Chưa có gói? Xem [Mua gói Token Plan](../../token-plan/mua-goi-token-plan.md). +{% endtab %} +{% endtabs %} *** ## Bước 3 — Cấu hình `codex.toml` -Tạo hoặc chỉnh sửa file `~/.codex/config.toml` (cấu hình toàn hệ thống) hoặc `codex.toml` tại thư mục gốc project (chỉ áp dụng cho project đó): +Tạo hoặc chỉnh sửa file `~/.codex/config.toml` (cấu hình toàn hệ thống) hoặc `codex.toml` tại thư mục gốc project (chỉ áp dụng cho project đó). Copy đúng tab theo loại dịch vụ của bạn: +{% tabs %} +{% tab title="PAYG" %} ```toml # API key — export trước khi chạy Codex -# export MAAS_API_KEY="vn-...your-gateway-token..." +# export MAAS_API_KEY="" model_provider = "maas" model = "minimax/minimax-m2.5" @@ -71,33 +94,75 @@ env_key = "MAAS_API_KEY" wire_api = "responses" request_max_retries = 3 ``` +{% endtab %} + +{% tab title="Token Plan" %} +```toml +# subscription-key — export trước khi chạy Codex +# export MAAS_API_KEY="" + +model_provider = "maas" +model = "glm-5.2" # thay bằng Model code ở tab Models của gói + +# Cần thiết vì MAAS không trả metadata model — tránh context bị cắt sai +model_context_window = 204800 +model_max_output_tokens = 16400 + +# MAAS backend là stateless — Codex phải gửi lại toàn bộ conversation mỗi turn +disable_response_storage = true + +[model_providers.maas] +name = "MAAS AI Gateway" + +# base_url KHÔNG có trailing /responses — Codex tự append (→ .../v1/responses) +base_url = "https://tokenplan.api.greennode.ai/v1" +env_key = "MAAS_API_KEY" +wire_api = "responses" +request_max_retries = 3 +``` + +{% hint style="info" %} +`model` phải là **Model code** đúng như tab **Models** của gói hiển thị, và model đó phải nằm trong gói — gọi model ngoài gói trả về `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} **Giải thích các field quan trọng:** | Field | Mục đích | |---|---| | `model_provider` | Key của provider trong `[model_providers.*]` | -| `model` | Model ID gửi lên MaaS | +| `model` | Model ID gửi lên MaaS — PAYG dùng Model ID của portal Models, Token Plan dùng Model code của gói | | `model_context_window` | Khai báo thủ công vì MaaS không expose metadata model | | `disable_response_storage` | Bắt buộc cho backend stateless — gửi lại full conversation mỗi turn | -| `base_url` | MaaS endpoint có `/v1` — Codex tự thêm `/responses` phía sau | -| `env_key` | Tên biến môi trường chứa API key | +| `base_url` | Endpoint theo loại dịch vụ, có `/v1` — Codex tự thêm `/responses` phía sau | +| `env_key` | Tên biến môi trường chứa key | | `wire_api` | Protocol sử dụng — `responses` tương ứng OpenAI Responses API | *** -## Bước 4 — Set API key và chạy Codex +## Bước 4 — Set key và chạy Codex + +Export key trong shell — dùng đúng key của loại dịch vụ đã khai trong `base_url` ở Bước 3: -Export API key trong shell: +{% tabs %} +{% tab title="PAYG" %} +```bash +export MAAS_API_KEY="" +``` +{% endtab %} +{% tab title="Token Plan" %} ```bash -export MAAS_API_KEY="vn-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +export MAAS_API_KEY="" ``` +{% endtab %} +{% endtabs %} Để tự động mỗi lần mở terminal, thêm vào `~/.zshrc` hoặc `~/.bashrc`: ```bash -echo 'export MAAS_API_KEY="vn-xxxx..."' >> ~/.zshrc +echo 'export MAAS_API_KEY=""' >> ~/.zshrc source ~/.zshrc ``` @@ -122,23 +187,27 @@ directory: ~/your-project | Triệu chứng | Nguyên nhân | Cách xử lý | |---|---|---| -| `401 Unauthorized` | API key sai, thiếu, hoặc chưa ACTIVE | Re-export `MAAS_API_KEY`; kiểm tra status key tại AI Platform Console | -| `404` khi gửi request | `base_url` sai hoặc thiếu `/v1` | Đảm bảo `base_url` kết thúc bằng `/v1` (không có `/responses`) | +| `401 Unauthorized` | Key sai, thiếu, hoặc chưa ACTIVE | Re-export `MAAS_API_KEY`; kiểm tra status key | +| `401` dù key còn hiệu lực | **Key và `base_url` lệch loại dịch vụ** | Đối chiếu bảng đầu trang: key ở trang **API Keys** → host `maas-llm-…`; key ở tab **Subscription keys** → host `tokenplan…` | +| `403 Forbidden` (Token Plan) | Model không nằm trong gói | Đặt `model` là Model code có trong tab **Models** của gói | +| `402 Payment Required` (Token Plan) | Gói hết hạn hoặc bị xoá | Mua lại gói hoặc bật **Auto-renew** | +| `404` khi gửi request | `base_url` sai hoặc thiếu `/v1` | Codex là chuẩn OpenAI — `base_url` phải kết thúc bằng `/v1` (không có `/responses`) | | Context bị cắt sai | Model metadata không được khai báo | Kiểm tra `model_context_window` và `model_max_output_tokens` trong config | | Mỗi turn mất context cũ | `disable_response_storage` chưa được set | Thêm `disable_response_storage = true` vào config | -| Connection timeout | Endpoint không truy cập được | Kiểm tra VPN / kết nối đến `*.api.vngcloud.vn` | +| Connection timeout | Endpoint không truy cập được | Kiểm tra VPN / kết nối đến `*.api.vngcloud.vn` (PAYG) hoặc `tokenplan.api.greennode.ai` (Token Plan) | *** ## Kết quả -Sau khi hoàn thành, Codex CLI route toàn bộ request qua GreenNode MaaS với model Minimax. Usage được ghi nhận trên [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). +Sau khi hoàn thành, Codex CLI route toàn bộ request qua endpoint GreenNode của loại dịch vụ bạn chọn. Usage được ghi nhận trên [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). | Tôi muốn tiếp theo... | Đi đến | |---|---| | Dùng bản có giao diện | [Codex Desktop](../co-giao-dien/codex-desktop.md) | | Dùng OpenCode với MaaS | [Dùng OpenCode với GreenNode MaaS](opencode.md) | | Kết nối Claude Code với MaaS | [Kết nối Claude Code với GreenNode MaaS](claude-code.md) | +| Tìm hiểu gói Token Plan | [Token Plan](../../token-plan/README.md) | | Xem usage và billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | *** diff --git a/Vietnamese/ai-stack/ai-coding/dong-lenh/opencode.md b/Vietnamese/ai-stack/ai-coding/dong-lenh/opencode.md index 17f76969..5989e619 100644 --- a/Vietnamese/ai-stack/ai-coding/dong-lenh/opencode.md +++ b/Vietnamese/ai-stack/ai-coding/dong-lenh/opencode.md @@ -1,18 +1,27 @@ # Dùng OpenCode với GreenNode MaaS -> Hướng dẫn cấu hình [OpenCode](https://opencode.ai) — TUI coding assistant — để gọi model qua GreenNode MaaS thông qua provider `@ai-sdk/openai-compatible`, thanh toán bằng credit-token nội bộ. +> Hướng dẫn cấu hình [OpenCode](https://opencode.ai) — TUI coding assistant — để gọi model qua GreenNode MaaS thông qua provider `@ai-sdk/openai-compatible`. *** ## Điều kiện cần (Prerequisites) -* Chuẩn bị API key, Base URL và model theo [Bắt đầu với AI Coding](../bat-dau.md) +* Chuẩn bị key, Base URL và model theo [Bắt đầu với AI Coding](../bat-dau.md) * Node.js đã cài đặt -> Model GLM 5.2 qua OpenCode dùng **chuẩn OpenAI** — Base URL có `/v1`: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1`. +*** -{% hint style="info" %} -**Nếu dùng key của gói Token Plan (subscription) thay vì API key trả theo mức dùng (pay-as-you-go)**, dùng `https://tokenplan.api.greennode.ai/v1` làm Base URL thay thế. Xem chi tiết tại [Token Plan](../../token-plan/README.md). +## Chọn cấu hình theo loại dịch vụ + +OpenCode dùng **chuẩn OpenAI** → `baseURL` **có** `/v1` ở cả hai loại dịch vụ. Chỉ khác host và loại key: + +| Loại dịch vụ | `baseURL` | Key | Model | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key từ [trang API Keys](https://aiplatform.console.greennode.ai/keys) | `openai/gpt-oss-120b` | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key từ Plan Detail → tab **Subscription keys** | Model code ở tab **Models** của gói | + +{% hint style="warning" %} +**Key và `baseURL` phải cùng một loại dịch vụ.** API Key PAYG gửi tới host `tokenplan…` (hoặc ngược lại) trả về `401 Unauthorized` dù key vẫn còn hiệu lực. Nhớ theo nơi bạn đã lấy key — xem [Mục 2 của trang Điều kiện cần](../bat-dau.md). {% endhint %} *** @@ -31,23 +40,37 @@ brew install opencode *** -## Bước 2 — Lấy API key từ AI Platform +## Bước 2 — Lấy key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Đăng nhập [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Vào **API Keys** → **Create API Key** 3. Đặt tên key (5–50 ký tự, chữ thường + số + gạch ngang) -4. Copy API key (`vn-...`) vừa tạo +4. Copy API key vừa tạo {% hint style="warning" %} API key mới tạo ở trạng thái `pending`. Đợi đến khi status = `ACTIVE` mới dùng được. {% endhint %} +{% endtab %} + +{% tab title="Token Plan — subscription-key" %} +1. Vào **API Key** → **Token Plan** → **My Token Plans**, mở gói đã mua +2. Tab **Subscription keys** → copy `default-key` hoặc key bạn tự tạo +3. Tab **Models** → copy **Model code** của model muốn dùng + +Chưa có gói? Xem [Mua gói Token Plan](../../token-plan/mua-goi-token-plan.md). +{% endtab %} +{% endtabs %} *** ## Bước 3 — Tạo file cấu hình `opencode.json` -Tạo file `opencode.json` tại thư mục gốc của project: +Tạo file `opencode.json` tại thư mục gốc của project. Copy đúng tab theo loại dịch vụ của bạn: +{% tabs %} +{% tab title="PAYG" %} ```json { "$schema": "https://opencode.ai/config.json", @@ -69,6 +92,36 @@ Tạo file `opencode.json` tại thư mục gốc của project: } } ``` +{% endtab %} + +{% tab title="Token Plan" %} +```json +{ + "$schema": "https://opencode.ai/config.json", + "model": "MAAS-chat/glm-5.2", + "provider": { + "MAAS-chat": { + "npm": "@ai-sdk/openai-compatible", + "name": "MAAS chat", + "options": { + "baseURL": "https://tokenplan.api.greennode.ai/v1", + "apiKey": "{env:MAAS_API_KEY}" + }, + "models": { + "glm-5.2": { + "name": "glm-5.2" + } + } + } + } +} +``` + +{% hint style="info" %} +Thay `glm-5.2` (ở cả `model` và trong `models`) bằng đúng **Model code** ở tab **Models** của gói. Gọi model ngoài gói trả về `403 Forbidden`. +{% endhint %} +{% endtab %} +{% endtabs %} **Giải thích các field:** @@ -78,40 +131,49 @@ Tạo file `opencode.json` tại thư mục gốc của project: | `model` | Model mặc định — format `/` | | `provider.MAAS-chat` | Provider key — phần trước `/` trong `model` phải khớp chính xác | | `npm` | Adapter package — `@ai-sdk/openai-compatible` dùng được cho mọi endpoint OpenAI-style | -| `options.baseURL` | MaaS endpoint, có `/v1` ở cuối | -| `options.apiKey` | Token MaaS — dùng `{env:MAAS_API_KEY}` thay vì hardcode | +| `options.baseURL` | Endpoint theo loại dịch vụ, có `/v1` ở cuối | +| `options.apiKey` | Key MaaS — dùng `{env:MAAS_API_KEY}` thay vì hardcode | | `models` | Danh sách model expose từ provider này | {% hint style="warning" %} -Lỗi phổ biến: đặt `"model"` thành tên không khớp với provider key đã đăng ký. OpenCode tách theo `/` đầu tiên để tìm provider — nếu không khớp, model không load được. Luôn dùng `MAAS-chat/openai/gpt-oss-120b`. +Lỗi phổ biến: đặt `"model"` thành tên không khớp với provider key đã đăng ký. OpenCode tách theo `/` đầu tiên để tìm provider — nếu không khớp, model không load được. Giá trị `model` luôn phải bắt đầu bằng `MAAS-chat/`. {% endhint %} *** -## Bước 4 — Cung cấp API key +## Bước 4 — Cung cấp key -Vì config dùng `{env:MAAS_API_KEY}`, key không nằm trong file mà được đọc từ biến môi trường lúc runtime. Có hai cách: +Vì config dùng `{env:MAAS_API_KEY}`, key không nằm trong file mà được đọc từ biến môi trường lúc runtime. Dùng đúng key của loại dịch vụ đã khai trong `baseURL` ở Bước 3. **Cách A — Export biến môi trường (khuyến nghị)** -Export key trong shell rồi chạy OpenCode trong cùng session: +{% tabs %} +{% tab title="PAYG" %} +```bash +export MAAS_API_KEY="" +opencode +``` +{% endtab %} +{% tab title="Token Plan" %} ```bash -export MAAS_API_KEY="vn-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +export MAAS_API_KEY="" opencode ``` +{% endtab %} +{% endtabs %} Để tự động mỗi lần mở terminal, thêm vào `~/.zshrc` hoặc `~/.bashrc`: ```bash -echo 'export MAAS_API_KEY="vn-xxxx..."' >> ~/.zshrc +echo 'export MAAS_API_KEY=""' >> ~/.zshrc source ~/.zshrc ``` Hoặc set inline cho một lần chạy duy nhất: ```bash -MAAS_API_KEY="vn-xxxx..." opencode +MAAS_API_KEY="" opencode ``` **Cách B — Dùng file `.env` gitignored trong project** @@ -119,7 +181,7 @@ MAAS_API_KEY="vn-xxxx..." opencode Tạo file `.env` (thêm vào `.gitignore`): ```bash -export MAAS_API_KEY="vn-xxxx..." +export MAAS_API_KEY="" ``` Chạy OpenCode bằng cách load `.env` trước: @@ -129,7 +191,7 @@ source .env && opencode ``` {% hint style="warning" %} -Không hardcode API key trực tiếp vào `opencode.json` nếu file đó được commit. Nếu key đã bị commit, rotate ngay tại MAAS Console vì key đó phải coi là đã bị lộ. +Không hardcode key trực tiếp vào `opencode.json` nếu file đó được commit. Nếu key đã bị commit, rotate ngay — API Key PAYG rotate tại [trang API Keys](https://aiplatform.console.greennode.ai/keys), subscription-key thu hồi và tạo lại tại tab **Subscription keys** của gói. {% endhint %} *** @@ -142,24 +204,39 @@ Không hardcode API key trực tiếp vào `opencode.json` nếu file đó đư opencode ``` - OpenCode khởi động với `MAAS-chat/openai/gpt-oss-120b` là model mặc định. + OpenCode khởi động với model mặc định khai trong `model` ở Bước 3. -2. Đổi model trong phiên bằng lệnh `/models`, sau đó chọn **MAAS chat → openai/gpt-oss-120b** từ danh sách. +2. Đổi model trong phiên bằng lệnh `/models`, sau đó chọn **MAAS chat →** model của bạn từ danh sách.

OpenCode chạy với model openai/gpt-oss-120b qua GreenNode MaaS

*** -## Thêm model MaaS khác +## Thêm model khác -Để expose thêm model từ cùng endpoint MaaS, thêm entry vào `models`: +Để expose thêm model từ cùng endpoint, thêm entry vào `models`: +{% tabs %} +{% tab title="PAYG" %} ```json "models": { "openai/gpt-oss-120b": { "name": "openai/gpt-oss-120b" }, "openai/gpt-oss-20b": { "name": "openai/gpt-oss-20b" } } ``` +{% endtab %} + +{% tab title="Token Plan" %} +```json +"models": { + "glm-5.2": { "name": "glm-5.2" }, + "minimax-m2.5": { "name": "minimax-m2.5" } +} +``` + +Chỉ thêm được model **nằm trong gói** — đối chiếu tab **Models** của gói. +{% endtab %} +{% endtabs %} Sau đó chọn qua `/models`, hoặc đổi `model` ở cấp top-level thành `MAAS-chat/` mới. @@ -169,22 +246,26 @@ Sau đó chọn qua `/models`, hoặc đổi `model` ở cấp top-level thành | Triệu chứng | Nguyên nhân | Cách xử lý | |---|---|---| -| `provider not found` / model không load | Giá trị `model` không khớp provider key | Dùng `MAAS-chat/openai/gpt-oss-120b` | -| `401 Unauthorized` | API key sai, hết hạn, hoặc chưa ACTIVE | Re-export `MAAS_API_KEY`; rotate token tại MAAS Console | -| `404` khi gửi request | Base URL sai hoặc thiếu `/v1` | Kiểm tra `baseURL` kết thúc bằng `/v1` | -| Connection timeout | Endpoint không truy cập được từ network hiện tại | Kiểm tra VPN / kết nối đến `*.api.vngcloud.vn` | -| Model trả lỗi nhưng auth đúng | Sai model ID | Dùng đúng ID mà MaaS publish (`openai/gpt-oss-120b`) | +| `provider not found` / model không load | Giá trị `model` không khớp provider key | Giá trị `model` phải bắt đầu bằng `MAAS-chat/` | +| `401 Unauthorized` | Key sai, hết hạn, hoặc chưa ACTIVE | Re-export `MAAS_API_KEY`; kiểm tra status key | +| `401` dù key còn hiệu lực | **Key và `baseURL` lệch loại dịch vụ** | Đối chiếu bảng đầu trang: key ở trang **API Keys** → host `maas-llm-…`; key ở tab **Subscription keys** → host `tokenplan…` | +| `403 Forbidden` (Token Plan) | Model không nằm trong gói | Chỉ khai model có trong tab **Models** của gói | +| `402 Payment Required` (Token Plan) | Gói hết hạn hoặc bị xoá | Mua lại gói hoặc bật **Auto-renew** | +| `404` khi gửi request | Base URL sai hoặc thiếu `/v1` | OpenCode là chuẩn OpenAI — `baseURL` phải kết thúc bằng `/v1` | +| Connection timeout | Endpoint không truy cập được từ network hiện tại | Kiểm tra VPN / kết nối đến `*.api.vngcloud.vn` (PAYG) hoặc `tokenplan.api.greennode.ai` (Token Plan) | +| Model trả lỗi nhưng auth đúng | Sai model ID | PAYG: dùng Model ID portal publish. Token Plan: dùng **Model code** ở tab **Models** | *** ## Kết quả -Sau khi hoàn thành, OpenCode route toàn bộ request qua GreenNode MaaS. Usage được ghi nhận trên [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). +Sau khi hoàn thành, OpenCode route toàn bộ request qua endpoint GreenNode của loại dịch vụ bạn chọn. Usage được ghi nhận trên [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/). | Tôi muốn tiếp theo... | Đi đến | |---|---| | Dùng Codex với Minimax qua MaaS | [Dùng Codex với Minimax qua GreenNode MaaS](codex-cli.md) | | Kết nối Claude Code với MaaS | [Kết nối Claude Code với GreenNode MaaS](claude-code.md) | +| Tìm hiểu gói Token Plan | [Token Plan](../../token-plan/README.md) | | Xem usage và billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | *** diff --git a/Vietnamese/ai-stack/ai-coding/ket-noi-openai-compatible-voi-maas.md b/Vietnamese/ai-stack/ai-coding/ket-noi-openai-compatible-voi-maas.md index d6711941..807610da 100644 --- a/Vietnamese/ai-stack/ai-coding/ket-noi-openai-compatible-voi-maas.md +++ b/Vietnamese/ai-stack/ai-coding/ket-noi-openai-compatible-voi-maas.md @@ -1,23 +1,38 @@ # Kết nối OpenAI-compatible với GreenNode MaaS -> Hướng dẫn cấu hình các tool, SDK và IDE extension dùng OpenAI API format để gọi model qua GreenNode MaaS endpoint, thanh toán bằng credit-token nội bộ. +> Hướng dẫn cấu hình các tool, SDK và IDE extension dùng OpenAI API format để gọi model qua endpoint GreenNode — dùng API Key **PAYG** hoặc subscription-key của gói **Token Plan**. *** ## Điều kiện cần (Prerequisites) * Đã có tài khoản [AI Platform](https://aiplatform.console.greennode.ai/) -* Đã tạo API key với status **ACTIVE** +* Đã có key ở trạng thái **ACTIVE** — API Key (PAYG) hoặc subscription-key (Token Plan) * Tool/SDK hỗ trợ tuỳ chỉnh base URL (OpenAI SDK, LiteLLM, Cursor, Continue.dev, v.v.) -{% hint style="info" %} -LLM URL cho OpenAI-compatible client: `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` (có `/v1`). Khác với Claude Code dùng Anthropic protocol (không có `/v1`). +*** + +## Chọn cấu hình theo loại dịch vụ + +Mọi tool trên trang này dùng **chuẩn OpenAI** → Base URL **có** `/v1` ở cả hai loại dịch vụ. Chỉ khác host và loại key: + +| Loại dịch vụ | Base URL | Key | Model | +|---|---|---|---| +| **PAYG** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | API Key từ [trang API Keys](https://aiplatform.console.greennode.ai/keys) | Model ID từ [portal Models](https://aiplatform.console.greennode.ai/models) (ví dụ `openai/gpt-4o`) | +| **Token Plan** | `https://tokenplan.api.greennode.ai/v1` | subscription-key từ Plan Detail → tab **Subscription keys** | Model code ở tab **Models** của gói (ví dụ `glm-5.2`) | + +{% hint style="warning" %} +**Key và Base URL phải cùng một loại dịch vụ.** API Key PAYG gửi tới host `tokenplan…` (hoặc ngược lại) trả về `401 Unauthorized` dù key vẫn còn hiệu lực. Không nhận biết loại key bằng mắt được — nhớ theo nơi bạn đã lấy key. Xem [Mục 2 của trang Điều kiện cần](bat-dau.md). {% endhint %} +Mọi ví dụ bên dưới đều có 2 tab — chọn đúng tab loại dịch vụ của bạn rồi copy nguyên văn, chỉ thay key và model. + *** -## Bước 1 — Lấy API key từ AI Platform +## Bước 1 — Lấy key +{% tabs %} +{% tab title="PAYG — API Key" %} 1. Đăng nhập [AI Platform Console](https://aiplatform.console.greennode.ai/) 2. Vào **API Keys** → **Create API Key** 3. Đặt tên key (5–50 ký tự, chữ thường + số + gạch ngang) @@ -26,32 +41,52 @@ LLM URL cho OpenAI-compatible client: `https://maas-llm-aiplatform-hcm.api.vngcl {% hint style="warning" %} API key mới tạo ở trạng thái `pending`. Đợi đến khi status = `ACTIVE` mới dùng được. {% endhint %} +{% endtab %} -*** +{% tab title="Token Plan — subscription-key" %} +1. Vào **API Key** → **Token Plan** → **My Token Plans**, mở gói đã mua +2. Tab **Subscription keys** → copy `default-key` hoặc key bạn tự tạo +3. Tab **Models** → copy **Model code** của model muốn dùng + +Chưa có gói? Xem [Mua gói Token Plan](../token-plan/mua-goi-token-plan.md). +{% endtab %} +{% endtabs %} -## Bước 2 — Xem danh sách model +*** -Lấy danh sách model khả dụng qua OpenAI-compatible endpoint: +## Bước 2 — Xem danh sách model khả dụng +{% tabs %} +{% tab title="PAYG" %} ```bash curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/models \ - -H "Authorization: Bearer " + -H "Authorization: Bearer " ``` Dùng giá trị `id` trong response để điền vào tham số `model` khi gọi API. +{% endtab %} + +{% tab title="Token Plan" %} +Danh sách model của gói xem trực tiếp trên **Plan Detail → tab Models** — cột **Model code** chính là giá trị điền vào tham số `model`. + +Gói chỉ gọi được các model có trong tab này; model ngoài gói trả về `403 Forbidden`. +{% endtab %} +{% endtabs %} *** ## Bước 3 — Cấu hình client -**OpenAI Python SDK** +### OpenAI Python SDK +{% tabs %} +{% tab title="PAYG" %} ```python from openai import OpenAI client = OpenAI( base_url="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - api_key="", + api_key="", ) response = client.chat.completions.create( @@ -60,15 +95,36 @@ response = client.chat.completions.create( ) print(response.choices[0].message.content) ``` +{% endtab %} + +{% tab title="Token Plan" %} +```python +from openai import OpenAI + +client = OpenAI( + base_url="https://tokenplan.api.greennode.ai/v1", + api_key="", +) + +response = client.chat.completions.create( + model="glm-5.2", # Model code ở tab Models của gói + messages=[{"role": "user", "content": "Hello"}], +) +print(response.choices[0].message.content) +``` +{% endtab %} +{% endtabs %} -**OpenAI Node.js SDK** +### OpenAI Node.js SDK +{% tabs %} +{% tab title="PAYG" %} ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - apiKey: "", + apiKey: "", }); const response = await client.chat.completions.create({ @@ -77,16 +133,48 @@ const response = await client.chat.completions.create({ }); console.log(response.choices[0].message.content); ``` +{% endtab %} -**Biến môi trường (cho tool/CLI nhận OpenAI-compatible config)** +{% tab title="Token Plan" %} +```javascript +import OpenAI from "openai"; +const client = new OpenAI({ + baseURL: "https://tokenplan.api.greennode.ai/v1", + apiKey: "", +}); + +const response = await client.chat.completions.create({ + model: "glm-5.2", // Model code ở tab Models của gói + messages: [{ role: "user", content: "Hello" }], +}); +console.log(response.choices[0].message.content); +``` +{% endtab %} +{% endtabs %} + +### Biến môi trường (cho tool/CLI nhận OpenAI-compatible config) + +{% tabs %} +{% tab title="PAYG" %} ```bash export OPENAI_BASE_URL="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1" -export OPENAI_API_KEY="" +export OPENAI_API_KEY="" +``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +export OPENAI_BASE_URL="https://tokenplan.api.greennode.ai/v1" +export OPENAI_API_KEY="" ``` +{% endtab %} +{% endtabs %} -**LiteLLM** +### LiteLLM +{% tabs %} +{% tab title="PAYG" %} ```python import litellm @@ -94,24 +182,36 @@ response = litellm.completion( model="openai/gpt-4o", messages=[{"role": "user", "content": "Hello"}], base_url="https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1", - api_key="", + api_key="", ) print(response.choices[0].message.content) ``` +{% endtab %} -**Cursor / Continue.dev** +{% tab title="Token Plan" %} +```python +import litellm -Trong phần cài đặt của tool, điền: +response = litellm.completion( + model="glm-5.2", # Model code ở tab Models của gói + messages=[{"role": "user", "content": "Hello"}], + base_url="https://tokenplan.api.greennode.ai/v1", + api_key="", +) +print(response.choices[0].message.content) +``` +{% endtab %} +{% endtabs %} -| Trường | Giá trị | -| ------------ | ---------------------------------------------------- | -| **Base URL** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | -| **API Key** | `` | -| **Model** | `openai/gpt-4o`, `gemini/gemini-2.5-flash`, `qwen/qwen3-27b` (hoặc model từ bước 2) | +### Cursor / Continue.dev -{% hint style="info" %} -**Nếu dùng key của gói Token Plan (subscription) thay vì API key trả theo mức dùng (pay-as-you-go)**, dùng `https://tokenplan.api.greennode.ai/v1` làm Base URL thay thế. Xem chi tiết tại [Token Plan](../token-plan/README.md). -{% endhint %} +Trong phần cài đặt của tool, điền theo đúng loại dịch vụ của key: + +| Trường | PAYG | Token Plan | +|---|---|---| +| **Base URL** | `https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1` | `https://tokenplan.api.greennode.ai/v1` | +| **API Key** | API Key PAYG của bạn | subscription-key của bạn | +| **Model** | `openai/gpt-4o`, `gemini/gemini-2.5-flash`, `qwen/qwen3-27b` (hoặc model từ Bước 2) | Model code ở tab **Models** của gói | *** @@ -119,15 +219,31 @@ Trong phần cài đặt của tool, điền: Gửi request thử bằng curl: +{% tabs %} +{% tab title="PAYG" %} ```bash curl https://maas-llm-aiplatform-hcm.api.vngcloud.vn/v1/chat/completions \ - -H "Authorization: Bearer " \ + -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "model": "openai/gpt-4o", "messages": [{"role": "user", "content": "ping"}] }' ``` +{% endtab %} + +{% tab title="Token Plan" %} +```bash +curl https://tokenplan.api.greennode.ai/v1/chat/completions \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "model": "", + "messages": [{"role": "user", "content": "ping"}] + }' +``` +{% endtab %} +{% endtabs %} Kết quả mong đợi: response JSON có trường `choices[0].message.content`. @@ -135,30 +251,36 @@ Kết quả mong đợi: response JSON có trường `choices[0].message.content ## Billing & Usage -* Request đi qua GreenNode MaaS được tính phí bằng credit-token (1 credit = 1 VND) -* Xem usage real-time trên [AI Platform Console → Usage](https://aiplatform.console.greennode.ai/) -* **Prepaid:** credit bị trừ mỗi chu kỳ collect 5 phút — khi hết credit, model bị tắt tự động -* **Postpaid:** usage được ghi nợ, không giới hạn quota +| | PAYG | Token Plan | +|---|---|---| +| Cách tính phí | Trả theo token thực dùng, 1 credit = 1 VND | Prepaid cố định 30 ngày, hạn mức token/request theo từng model | +| Khi cạn | **Prepaid:** credit bị trừ mỗi chu kỳ collect 5 phút — hết credit thì model bị tắt tự động. **Postpaid:** usage được ghi nợ, không giới hạn quota | Hết hạn mức token của model đó thì request dừng — đợi chu kỳ mới, mua thêm gói, hoặc tạm chuyển sang API Key PAYG | +| Theo dõi | [AI Platform Console](https://aiplatform.console.greennode.ai/) → tab **Usage** và **Cost** | [AI Platform Console](https://aiplatform.console.greennode.ai/) → chỉ tab **Usage** (chi phí đã cố định lúc mua gói) | *** ## Troubleshooting -| Triệu chứng | Nguyên nhân | Cách xử lý | -| ---------------------------- | ---------------------------------- | ----------------------------------------------- | -| `401 Unauthorized` | API key sai hoặc chưa ACTIVE | Kiểm tra lại key | -| `404 Not Found` | Thiếu `/v1` trong URL | Đảm bảo base URL kết thúc bằng `/v1` | -| Model không phản hồi | Credit hết, model bị tắt | Nạp thêm credit tại AI Platform Console | +| Triệu chứng | Nguyên nhân | Cách xử lý | +|---|---|---| +| `401 Unauthorized` | Key sai hoặc chưa ACTIVE | Kiểm tra lại key và status của key | +| `401` dù key còn hiệu lực | **Key và Base URL lệch loại dịch vụ** | Đối chiếu bảng đầu trang: key ở trang **API Keys** → host `maas-llm-…`; key ở tab **Subscription keys** → host `tokenplan…` | +| `403 Forbidden` (Token Plan) | Model không nằm trong gói | Chỉ gọi model có trong tab **Models** của gói | +| `402 Payment Required` (Token Plan) | Gói hết hạn hoặc bị xoá | Mua lại gói hoặc bật **Auto-renew** | +| `404 Not Found` | Thiếu `/v1` trong URL | Chuẩn OpenAI — base URL phải kết thúc bằng `/v1` | +| Model không phản hồi | PAYG hết credit, hoặc Token Plan hết hạn mức token | PAYG: nạp thêm credit. Token Plan: đợi chu kỳ mới hoặc mua thêm gói | | `OPENAI_BASE_URL` không nhận | Tool ghi đè bằng biến config riêng | Xem tài liệu của tool đó để set custom base URL | -| Response lỗi parse | Tool tự append `/v1` vào base URL | Thử bỏ `/v1` khỏi base URL nếu tool tự xử lý | +| Response lỗi parse | Tool tự append `/v1` vào base URL | Thử bỏ `/v1` khỏi base URL nếu tool tự xử lý | *** ## Kết quả -Sau khi cấu hình, tool hoặc SDK sẽ gọi model qua GreenNode MaaS thay vì OpenAI trực tiếp. Usage được ghi nhận trên AI Platform Console và tính phí theo credit-token nội bộ. +Sau khi cấu hình, tool hoặc SDK sẽ gọi model qua endpoint GreenNode của loại dịch vụ bạn chọn thay vì OpenAI trực tiếp. Usage được ghi nhận trên AI Platform Console. -| Tôi muốn tiếp theo... | Đi đến | -| ------------------------- | ------------------------------------------------------------------------- | +| Tôi muốn tiếp theo... | Đi đến | +|---|---| | Dùng Claude Code với MaaS | [Kết nối Claude Code với GreenNode MaaS](dong-lenh/claude-code.md) | -| Xem usage và billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) | +| Tìm hiểu gói Token Plan | [Token Plan](../token-plan/README.md) | +| Đi hết một vòng Token Plan từ mua gói đến chạy tool | [Hướng dẫn A-Z](../token-plan/huong-dan-a-z.md) | +| Xem usage và billing | [AI Platform Console](https://aiplatform.console.greennode.ai/) |