From 4193ba9f017461a66190ef7148141256b69e2ca9 Mon Sep 17 00:00:00 2001 From: agent Date: Thu, 22 Oct 2026 14:08:19 +0300 Subject: [PATCH] Add English translation of the README after the Russian section --- README.md | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) diff --git a/README.md b/README.md index 3a1a48f..7700322 100644 --- a/README.md +++ b/README.md @@ -171,3 +171,180 @@ npm run mock # мок TeamoRouter на http://127.0.0.1:4123/v1 (кл ## Лицензия MIT + +--- +--- + +# English + +Custom n8n nodes for the **TeamoRouter** gateway (`https://api.teamorouter.com/v1`) — an OpenAI-compatible router in front of GPT, Claude, Gemini, DeepSeek, GLM, Grok, Kimi and other models. + +The package ships two nodes and one credential type: + +| Node | Type | Purpose | +| --- | --- | --- | +| **TeamoRouter Chat Model** (`lmChatTeamRouter`) | sub-node, `ai_languageModel` | Plugs into **AI Agent**, **Basic LLM Chain**, **Question and Answer Chain** and any other node that takes a Language Model | +| **TeamoRouter** (`teamorouter`) | regular node | Three operations: `Chat → Message a Model`, `Image → Generate an Image`, `Model → List Models` | +| **TeamoRouter API** (`teamorouterApi`) | credentials | API key + Base URL | + +--- + +## 1. Installation + +### Option A. Through the n8n UI (recommended) + +Community nodes in n8n are installed from npm, so the package has to be published: + +1. Push this folder to your git repository. +2. Publish to npm: + + ```bash + npm install + npm run build + npm publish --access public + ``` + +3. In n8n: **Settings → Community nodes → Install a community node**, enter `n8n-nodes-teamorouter` and confirm the warning. +4. No restart is needed — the nodes appear right away. + +The Owner/Admin role and enabled community nodes are required. Community nodes are installed instance-wide. + +### Option B. Copying the folder (if you have access to the n8n server) + +1. Run `npm install && npm run build` — you need the resulting `dist/` folder. +2. Put the **whole package folder** (it must contain `package.json`) into the custom extensions directory, for example: + + * in Docker: `/home/node/.n8n/custom/n8n-nodes-teamorouter/` + * via an environment variable: `N8N_CUSTOM_EXTENSIONS=/path/to/custom-nodes`, with the package folder inside it + +3. Inside the package folder run `npm install --omit=dev` once, so that `n8n-workflow` (a peer dependency) is reachable from your folder. +4. Restart n8n. + +### Option C. Local development + +```bash +npm install +npm run build:watch # tsc in watch mode +export N8N_CUSTOM_EXTENSIONS="$(pwd)" +npx n8n start +``` + +--- + +## 2. Credentials + +**Settings → Credentials → New → TeamoRouter API** + +| Field | Value | +| --- | --- | +| **API Key** | the key from the TeamoRouter dashboard, it starts with `sk-teamo-` | +| **Base URL** | `https://api.teamorouter.com/v1` (the default; change it only for the `.cn` mirror or your own router) | + +The test button issues `GET /v1/models` with the `Authorization: Bearer ` header. + +--- + +## 3. TeamoRouter Chat Model (for the AI Agent) + +1. Add an **AI Agent** (or a **Basic LLM Chain**). +2. Add **TeamoRouter Chat Model** into the **Chat Model** slot. +3. Pick a model from the list — it is read live from `GET /v1/models`. The label of each model shows the provider and the price per 1M tokens (when the router reports them). + +### Options + +| Option | What it does | +| --- | --- | +| **Sampling Temperature** | randomness of the answer, 0…2 | +| **Maximum Number of Tokens** | generation limit; `-1` = decided by the model | +| **Top P** | nucleus sampling; change either temperature or topP, not both | +| **Force JSON Response** | asks the model to answer with a JSON object (the prompt must mention JSON) | +| **Service Tier → Fast** | TeamoRouter Fast mode: up to 2.5x faster, billed at 2x | +| **Extra Body** | arbitrary JSON fields for the request body, e.g. `{"top_k": 40}`; overrides everything above | +| **Timeout** | 600000 ms by default (the router allows answers up to 600 s) | +| **Max Retries** | retries on failure, 2 by default | + +### A model that is missing from the list + +The **Model** field can be switched to expression mode (the `Expression` toggle in the top right corner of the field) and filled with the ID by hand: + +``` +{{ 'some-new-model-id' }} +``` + +Useful when the router already serves a new model but the list in the UI has not been reloaded yet. + +--- + +## 4. The TeamoRouter node (regular operations) + +### Chat → Message a Model + +Sends `POST /v1/chat/completions` and returns the JSON answer as is. + +| Field | Description | +| --- | --- | +| **Model** | the list is read from `GET /v1/models` (text models only; image models are hidden) | +| **Prompt** | the user message | +| **Options → System Prompt** | system instruction | +| **Options →** the rest | temperature, topP, max tokens, JSON answer, Service Tier Fast, Extra Body, Timeout | + +The answer text is available as `{{ $json.choices[0].message.content }}`, the token usage as `{{ $json.usage }}`. + +### Image → Generate an Image + +Sends `POST /v1/images/generations` and puts the result into a **binary field** (`data` by default, PNG). + +| Field | Description | +| --- | --- | +| **Model** | `gpt-image-2` by default; the list contains image models only; the ID can be entered as an expression | +| **Prompt** | description of the image | +| **Put Output File in Field** | name of the binary property | + +The file can then go to **Write Binary File**, Telegram, S3, and so on. Long generations are awaited for up to 5 minutes. + +### Model → List Models + +Returns the models of the router, one item per model (`id`, `object`, `owned_by`, `pricing` and more). Handy for building your own catalogue or for counting costs. + +--- + +## 5. Known details and limitations + +* **Requests go to `/v1/chat/completions`.** The exception is the `gpt-5.6*` model family and anything containing `codex`: LangChain inside n8n switches such IDs to `/v1/responses` on its own (this behaviour is hardcoded in `@langchain/openai` and cannot be turned off by settings). TeamoRouter supports `/v1/responses`, but **for GPT models only**, so the scheme works. Claude/Gemini requests use plain Chat Completions. +* **Claude through the OpenAI format gives up prompt caching.** That is a limitation of the router's format, not of the node: prompt caching is available only through the native Anthropic protocol (the TeamoRouter README says so explicitly). +* **`max_tokens`, not `max_completion_tokens`.** The node sends `max_tokens`, exactly as in the TeamoRouter documentation example. If a particular model requires `max_completion_tokens`, add it through **Extra Body**. +* **The JSON response format** is passed as `response_format`, which is a Chat Completions parameter. For models that go to `/v1/responses` it may be ignored. +* **The list of image models** is detected by name: `*-image`, `gpt-image*`, `nano-banana*`, `dall-e*`, `imagen*`. If the router names a model differently, it will land in the chat list (or the other way round); the field can always be filled in by hand as an expression. +* **Prices in the model list** are a hint. The router may report a price per token or already per 1M tokens; the node treats values below `0.005` as “per token”. This is display only and does not affect requests. +* The list of the **Model** fields is loaded when the field is opened and is not cached: if a model has just appeared, reload the list or use an expression. + +--- + +## 6. Development and checks + +```bash +npm install +npm run build # tsc + copying the icons into dist/ +npm test # package shape validation + node tests against a mock server +npm run typecheck +npm run mock # mock TeamoRouter on http://127.0.0.1:4123/v1 (key: test-key) +``` + +`npm test` runs two suites: + +1. `test/validate-nodes.mjs` — imitates n8n loading the package: checks the node descriptions, the presence of the icons, the implementation of every `loadOptionsMethod`, the credential references, and the `ai_languageModel` connection type of the sub-node. +2. `test/run-node-tests.mjs` — starts the mock router (`test/mock-server.mjs`, dependency-free) and drives the compiled nodes with real HTTP and real `@langchain/openai`: the model list and the filtering of image models, `supplyData` plus a real model call, the passing of options (`service_tier`, `extra_body`, limits), both operations of the regular node, image generation into a binary field, the handling of 401/402/404 errors, `Continue On Fail` and the timeout. + +The tests need no TeamoRouter key. The `fail-401`, `fail-402`, `fail-404` and `fail-500` models in the mock return an error on purpose, and `slow-model` answers after 2.5 s. + +--- + +## 7. First run and troubleshooting + +* The package is built and covered by the automated tests (see `npm test`), but it **has not been run inside a live n8n yet** — do the first run on a test workflow. +* When installing through `Settings → Community nodes`, the UI may show a warning about a community node — that is normal. +* If n8n reports that the node failed to load, check `Help → About` (the n8n version) and the container logs: the usual cause is the unreachable `n8n-workflow` peer dependency (Option B, step 3). + +## License + +MIT