From 22938b01ca660fb418f9e6d3e8a491006004ef89 Mon Sep 17 00:00:00 2001 From: Dmitry Shilov Date: Thu, 27 Aug 2026 17:56:04 +0300 Subject: [PATCH] refactor: move OpenCode artifacts under opencode/ arka/public is the dump for all Arka downloads. Keep a root stub so the old installer URL still works. Document in-OpenCode bash install. --- README.md | 204 ++---------- install-arka-provider.sh | 308 +----------------- opencode/README.md | 237 ++++++++++++++ catalog.json => opencode/catalog.json | 0 opencode/install-arka-provider.sh | 304 +++++++++++++++++ {plugins => opencode/plugins}/arka-ai.ts | 2 +- {scripts => opencode/scripts}/cron-sync.sh | 14 +- {scripts => opencode/scripts}/sync-catalog.py | 2 +- .../skills}/arka-provider/SKILL.md | 4 +- 9 files changed, 585 insertions(+), 490 deletions(-) create mode 100644 opencode/README.md rename catalog.json => opencode/catalog.json (100%) create mode 100755 opencode/install-arka-provider.sh rename {plugins => opencode/plugins}/arka-ai.ts (98%) rename {scripts => opencode/scripts}/cron-sync.sh (61%) rename {scripts => opencode/scripts}/sync-catalog.py (97%) rename {skills => opencode/skills}/arka-provider/SKILL.md (92%) diff --git a/README.md b/README.md index 1afb207..354bbe1 100644 --- a/README.md +++ b/README.md @@ -1,187 +1,35 @@ -# OpenCode и модели Arka AI +# arka/public -Arka AI — OpenAI-совместимый API (`https://api.arka-ai.ru/v1`). В каталоге models.dev его нет, поэтому в свежем OpenCode провайдера **Arka-AI** и списка моделей нет, пока не поставить плагин. +Публичные файлы Arka AI: загрузки, инструкции, скрипты. Анонимный raw, без токена. -Одна команда ставит плагин, skill и (по желанию) ключ. Каталог чат-моделей подтягивается сам (~116 из ~216; без TTS/картинок/видео/эмбеддингов). Снимок каталога обновляется каждый день в **05:00 по Москве**. +`https://git.arka-ai.ru/arka/public/raw/branch/main/` -Нужен [API-ключ Arka AI](https://arka-ai.ru/docs/account/api-keys). Секрет ключа показывается **один раз** при создании. +Каждый продукт — своя папка на `main`. Приватный код сюда не кладём. + +| Папка | Что | +|-------|-----| +| [`opencode/`](opencode/) | Провайдер OpenCode **Arka-AI**: установщик, плагин, skill, каталог чат-моделей | + +Однострочник OpenCode: + +```bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash +``` --- -## Быстрый старт +Public Arka AI downloads, docs, and scripts. Anonymous raw URLs, no token. + +`https://git.arka-ai.ru/arka/public/raw/branch/main/` + +One top-level folder per product. No private source. + +| Folder | What | +|--------|------| +| [`opencode/`](opencode/) | OpenCode **Arka-AI** provider: installer, plugin, skill, chat catalog | + +OpenCode one-liner: ```bash -curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/install-arka-provider.sh | bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash ``` - -Скрипт спросит `ARKA_API_KEY` (можно оставить пустым и задать позже). - -Ключ и модель по умолчанию сразу: - -```bash -curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/install-arka-provider.sh \ - | bash -s -- --key "$ARKA_API_KEY" --set-default DeepSeek-V4-Pro -``` - -Дальше: - -1. Откройте **новый терминал** (чтобы подхватился `export ARKA_API_KEY`). -2. Перезапустите OpenCode. -3. Команда `/models` — в списке должен быть провайдер **Arka-AI** и чат-модели. - -Если OpenCode запущен из GUI / иконки / сокета, а не из login-shell, переменная из `~/.bashrc` до него может не дойти. Задайте `ARKA_API_KEY` в том окружении, откуда стартует OpenCode, или введите ключ в интерактивном приглашении установщика. - -### Что ставится - -| Куда | Что | -|------|-----| -| `~/.config/opencode/plugins/arka-ai.ts` | Плагин провайдера **Arka-AI** | -| `~/.config/opencode/skills/arka-provider/SKILL.md` | Skill: как обновить каталог и сменить модель | -| `~/.bashrc` (или первый из `.zshrc` / `.profile`) | `export ARKA_API_KEY=…`, если ключ передали | -| `~/.config/opencode/opencode.json` | Только при `--set-default`: `"model": "Arka-AI/"`. Существующий конфиг **не затирается**. | - -Установщик **офлайн** и идемпотентный: сеть не трогает, повторный запуск перезаписывает плагин и skill каноническими копиями. - -`python3` нужен только с `--set-default`. Отдельный `bun` на машине не нужен — у OpenCode свой runtime. - -### Модель по умолчанию - -Идентификаторы — как в каталоге, с префиксом провайдера: - -```json -{ - "model": "Arka-AI/DeepSeek-V4-Pro" -} -``` - -Примеры: `Arka-AI/DeepSeek-V4-Pro`, `Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`, `Arka-AI/MiniMax-M3`, `Arka-AI/GLM-5.3`, `Arka-AI/deepseek-v4-flash-0731`. - -Их всегда оставляем в списке, даже если фильтр чат-моделей их бы отсёк. - -### Обновить каталог - -```bash -rm -f ~/.cache/opencode/arka-ai-models.json -``` - -Перезапустите OpenCode. Плагин сначала берёт публичный снимок -`https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json` -(без ключа), при ошибке — живой `https://api.arka-ai.ru/v1/models`. Локальный кэш живёт 24 часа. Конфиг OpenCode на лету не перечитывается. - -Список моделей (ключ не нужен): - -```bash -curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json | python3 -m json.tool -``` - -Вызовы моделей идут на `https://api.arka-ai.ru/v1` с `ARKA_API_KEY`. - -### Если что-то не так - -| Симптом | Что проверить | -|---------|----------------| -| После `/models` нет Arka-AI | Есть ли `~/.config/opencode/plugins/arka-ai.ts`; экспортирован ли `ARKA_API_KEY` **в процессе OpenCode**; открыт ли новый шелл | -| Каталог не меняется | `rm -f ~/.cache/opencode/arka-ai-models.json` и рестарт | -| Ошибка импорта плагина | Снова запустить установщик — он вернёт канонический файл | -| `curl` отдаёт HTML, не скрипт | Нужен путь `/raw/branch/main/…`, не страница репозитория | - ---- - -# OpenCode and Arka AI models - -Arka AI is an OpenAI-compatible API at `https://api.arka-ai.ru/v1`. It is not in models.dev, so a fresh OpenCode install has no **Arka-AI** provider until you add the plugin. - -One command installs the plugin, a companion skill, and (optionally) your API key. The chat catalog loads on OpenCode start (~116 of ~216 models; TTS, image, video, and embeddings are filtered out). The published catalog snapshot refreshes daily at **05:00 Europe/Moscow**. - -You need an [Arka AI API key](https://arka-ai.ru/docs/account/api-keys). The secret is shown **once** at creation. - -## Quick start - -```bash -curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/install-arka-provider.sh | bash -``` - -The script prompts for `ARKA_API_KEY` (blank is allowed; set it later). - -Key and default model in one go: - -```bash -curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/install-arka-provider.sh \ - | bash -s -- --key "$ARKA_API_KEY" --set-default DeepSeek-V4-Pro -``` - -Then: - -1. Open a **new shell** so `export ARKA_API_KEY` is picked up. -2. Restart OpenCode. -3. Run `/models` — you should see provider **Arka-AI** and the chat models. - -If OpenCode is started from a GUI, dock icon, or socket rather than a login shell, `~/.bashrc` may not reach it. Set `ARKA_API_KEY` in that process environment, or type it at the installer prompt. - -### What the installer writes - -| Path | Role | -|------|------| -| `~/.config/opencode/plugins/arka-ai.ts` | **Arka-AI** provider plugin | -| `~/.config/opencode/skills/arka-provider/SKILL.md` | How to refresh the catalog and change the default model | -| `~/.bashrc` (else first existing `.zshrc` / `.profile`) | `export ARKA_API_KEY=…` when a key is given | -| `~/.config/opencode/opencode.json` | Only with `--set-default`: `"model": "Arka-AI/"`. An existing config is **not** replaced. | - -The installer is **offline** and idempotent: no network calls; re-running overwrites plugin and skill with the canonical copies. - -`python3` is required **only** with `--set-default`. You do not need `bun` on the host — OpenCode ships its own runtime. - -### Default model - -Use catalog ids with the provider prefix: - -```json -{ - "model": "Arka-AI/DeepSeek-V4-Pro" -} -``` - -Examples: `Arka-AI/DeepSeek-V4-Pro`, `Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`, `Arka-AI/MiniMax-M3`, `Arka-AI/GLM-5.3`, `Arka-AI/deepseek-v4-flash-0731`. - -Those ids stay visible even if the chat filter would drop them. - -### Refresh the catalog - -```bash -rm -f ~/.cache/opencode/arka-ai-models.json -``` - -Restart OpenCode. The plugin fetches the public snapshot -`https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json` -(no key), then falls back to live `https://api.arka-ai.ru/v1/models`. Local cache TTL is 24 hours. OpenCode does not hot-reload config. - -Inspect the published list (no key): - -```bash -curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json | python3 -m json.tool -``` - -Inference still uses `ARKA_API_KEY` against `https://api.arka-ai.ru/v1`. - -### Troubleshooting - -| Symptom | Check | -|---------|--------| -| No Arka-AI after `/models` | `~/.config/opencode/plugins/arka-ai.ts` exists; `ARKA_API_KEY` is set **in the OpenCode process**; you opened a new shell | -| Models look stale | `rm -f ~/.cache/opencode/arka-ai-models.json` and restart | -| Plugin import error | Re-run the installer to restore the canonical file | -| `curl` returns HTML | Use `/raw/branch/main/…`, not the repo page | - ---- - -## This repository - -Public, anonymous files. Private product code lives in other Gitea repos. - -| File | Role | -|------|------| -| `install-arka-provider.sh` | Self-contained installer (the one-liner) | -| `plugins/arka-ai.ts` | Plugin source (embedded in the installer) | -| `skills/arka-provider/SKILL.md` | Skill source (embedded in the installer) | -| `catalog.json` | Filtered chat catalog, refreshed daily at 05:00 Europe/Moscow | -| `README.md` | This page — copy the Russian or English section into arka-ai.ru «агентные помощники» / agentic helpers | diff --git a/install-arka-provider.sh b/install-arka-provider.sh index d528b67..508e5a5 100755 --- a/install-arka-provider.sh +++ b/install-arka-provider.sh @@ -1,304 +1,8 @@ #!/usr/bin/env bash -# -# install-arka-provider.sh — one-shot installer for the arka-ai.ru LLM provider -# in a fresh opencode install. -# -# It is fully self-contained: it embeds the provider plugin and the companion -# skill, writes them into ~/.config/opencode, and persists ARKA_API_KEY. -# -# Usage: -# bash install-arka-provider.sh # prompt for API key -# ARKA_API_KEY=xxx bash install-arka-provider.sh # key from env (no prompt) -# bash install-arka-provider.sh --key xxx --set-default DeepSeek-V4-Pro -# -# Options: -# --key KEY ARKA_API_KEY to persist (default: $ARKA_API_KEY, else prompt) -# --set-default MODEL also set "model": "Arka-AI/" in opencode.json -# -h, --help show this help -# -# Idempotent: safe to run multiple times. Overwrites plugin/skill with the -# embedded versions; never clobbers an existing opencode.json (only upserts the -# requested default model). Makes no network calls. - +# Compatibility stub. Canonical installer: +# https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh set -euo pipefail - -usage() { - sed -n '2,21p' "$0" -} - -KEY="" -MODEL="" - -while [ $# -gt 0 ]; do - case "$1" in - --key) KEY="$2"; shift 2 ;; - --key=*) KEY="${1#*=}"; shift ;; - --set-default) MODEL="$2"; shift 2 ;; - --set-default=*) MODEL="${1#*=}"; shift ;; - -h|--help) usage; exit 0 ;; - *) printf 'unknown option: %s\n' "$1" >&2; usage; exit 1 ;; - esac -done - -CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/opencode" -PLUGIN_DIR="$CONF_DIR/plugins" -SKILL_DIR="$CONF_DIR/skills/arka-provider" - -mkdir -p "$PLUGIN_DIR" "$SKILL_DIR" "$HOME" - -echo "==> writing provider plugin to $PLUGIN_DIR/arka-ai.ts" -cat > "$PLUGIN_DIR/arka-ai.ts" <<'PLUGIN' -import { homedir } from "node:os" -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs" -import { join } from "node:path" - -const PROVIDER_ID = "Arka-AI" -const API_URL = "https://api.arka-ai.ru/v1" -const CATALOG_URL = - "https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json" -const CACHE_FILE = join(homedir(), ".cache", "opencode", "arka-ai-models.json") -const TTL_MS = 24 * 60 * 60 * 1000 - -// Ids that must always be exposed, even if the filter would drop them. -const FORCED_MODELS = [ - "DeepSeek-V4-Pro", - "deepseek-v4-flash-0731", - "qwen3.8-max", - "kimi-k3", - "MiniMax-M3", - "GLM-5.3", -] - -// Heuristic: drop non-chat models (TTS/ASR/image/video/OCR/embeddings/rerankers…) -// from the catalog so they don't clutter the /models picker. -// Keep in sync with scripts/sync-catalog.py -const NON_CHAT = new RegExp( - [ - "tts", "asr", "audio", "speech", "voice", "whisper", "sensevoice", - "image", "(^|[.-])img", "wan", "vidu", "video", "sora", "flux", - "diffus", "kolors", "cogview", "ocr", "embedding", "(^|[.-])embed", - "rerank", "clip", "moderation", "(^|[.-])filter", "detect", "classif", - "(^|[.-])location", "(^|[.-])search", "comfyui", "meme", "hello", - "(^|[.-])sam", "florence", "esrgan", "rmbg", "background", "poster", - "(^|[.-])face", "(^|[.-])lip", "translate", "(^|[.-])mt([2-]|$)", - "(^|[.-])bge", "(^|[.-])e5", "(^|[.-])jina", "(^|[.-])mpnet", - "spark-tts", "cosyvoice", "chattts", "indextts", "step-audio", - "fish-speech", "cosy", "mate-gguf", "tokenizer", - ].join("|"), - "i", -) - -type ModelMap = Record -type Cache = { ts: number; models: ModelMap } - -function loadCache(): Cache | null { - try { - if (existsSync(CACHE_FILE)) return JSON.parse(readFileSync(CACHE_FILE, "utf8")) - } catch {} - return null -} - -function saveCache(models: ModelMap): void { - try { - mkdirSync(join(homedir(), ".cache", "opencode"), { recursive: true }) - writeFileSync(CACHE_FILE, JSON.stringify({ ts: Date.now(), models })) - } catch {} -} - -async function fetchJson( - url: string, - headers: Record, - timeoutMs: number, -): Promise { - const ctrl = new AbortController() - const timer = setTimeout(() => ctrl.abort(), timeoutMs) - try { - const res = await fetch(url, { headers, signal: ctrl.signal }) - if (!res.ok) throw new Error(`HTTP ${res.status}`) - return await res.json() - } finally { - clearTimeout(timer) - } -} - -function idsFromPayload(json: unknown): string[] { - const data = (json as { data?: Array<{ id: string }> }).data - return (data ?? []).map((m) => m.id).filter(Boolean) -} - -function toModelMap(ids: string[], filter: boolean): ModelMap { - const models: ModelMap = {} - for (const id of ids) { - if (!filter || FORCED_MODELS.includes(id) || !NON_CHAT.test(id)) { - models[id] = { name: id } - } - } - return models -} - -async function resolveModels(): Promise { - const cache = loadCache() - if (cache && Date.now() - cache.ts < TTL_MS) return cache.models - - try { - const models = toModelMap(idsFromPayload(await fetchJson(CATALOG_URL, {}, 5000)), false) - if (Object.keys(models).length) { - saveCache(models) - return models - } - } catch {} - - try { - const key = process.env.ARKA_API_KEY - const json = await fetchJson( - `${API_URL}/models`, - key ? { Authorization: `Bearer ${key}` } : {}, - 5000, - ) - const models = toModelMap(idsFromPayload(json), true) - saveCache(models) - return models - } catch { - return cache?.models ?? null - } -} - -export default async function ArkaAIProviderPlugin() { - const models = await resolveModels() - - return { - config: (cfg: any) => { - cfg.provider ??= {} - const prev = cfg.provider[PROVIDER_ID] ?? {} - - // Static models from opencode.json act as a fallback; the fetched - // catalog is layered on top so the configured default model never - // disappears even if the catalog drops it. - cfg.provider[PROVIDER_ID] = { - name: "Arka-AI", - api: API_URL, - env: ["ARKA_API_KEY"], - ...prev, - models: { ...(prev.models ?? {}), ...(models ?? {}) }, - } - }, - } -} -PLUGIN - -echo "==> writing companion skill to $SKILL_DIR/SKILL.md" -cat > "$SKILL_DIR/SKILL.md" <<'SKILL' ---- -name: arka-provider -description: Manage the custom Arka-AI (arka-ai.ru) LLM provider in opencode config. Use when the user needs to add, refresh, or fix the arka-ai.ru provider, sync its model catalog, change the Arka-AI default model, or when arka models are missing from /models. ---- - -# Arka-AI provider - -arka-ai.ru is **not** in models.dev, so opencode ships no built-in config for it. -It is wired up locally with a plugin + a static `provider` block in -`~/.config/opencode/opencode.json`. - -## How it works - -- Plugin: `~/.config/opencode/plugins/arka-ai.ts` - - On startup it loads the published chat catalog - `https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json` - (no API key; refreshed daily at 05:00 Europe/Moscow). - - If that fetch fails, it falls back to `https://api.arka-ai.ru/v1/models` - and filters out non-chat models (TTS/ASR/image/video/OCR/embedding/reranker/…) - via a heuristic regex so the `/models` picker stays clean. - - Caches the result at `~/.cache/opencode/arka-ai-models.json` (TTL 24h). - - Injects the provider into config via the `config` hook, layered over the - static block in `opencode.json`. -- Static block (`opencode.json` → `provider["Arka-AI"]`) holds - `name`, `api`, `env`, and a small fallback `models` map that is used when the - catalog is unreachable. -- Inference still uses `ARKA_API_KEY` against `https://api.arka-ai.ru/v1`. - -## Refresh the model list - -Catalog ~216 raw models / ~116 chat; the public snapshot updates at 05:00 -Europe/Moscow. Changes land in opencode only after cache expiry + restart -(config is not hot-reloaded). - -1. `rm -f ~/.cache/opencode/arka-ai-models.json` -2. Restart opencode (or run `opencode` again) — the plugin re-fetches on the - next cold start. - -Optionally inspect the live API (no key required for listing): - -```bash -curl -sS https://api.arka-ai.ru/v1/models | python3 -m json.tool -curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json | python3 -m json.tool -``` - -## Change default model - -Edit `opencode.json` → `"model": "Arka-AI/"`. Use the IDs exactly as -returned by the catalog (e.g. `Arka-AI/DeepSeek-V4-Pro`, -`Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`). - -## Adjust filtering - -Edit `NON_CHAT` (regex) or `FORCED_MODELS` in the plugin file **and** the same -lists in `scripts/sync-catalog.py` in `arka/public`, then re-run the installer -and restart. `FORCED_MODELS` keeps must-have chat models even if the heuristic -would drop them. -SKILL - -# --- API key ----------------------------------------------------------- - -if [ -z "$KEY" ]; then - read -rsp "ARKA_API_KEY (leave blank to skip): " KEY || true - echo -fi - -if [ -n "$KEY" ]; then - RC="" - for f in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.profile"; do - if [ -f "$f" ]; then RC="$f"; break; fi - done - RC="${RC:-$HOME/.bashrc}" - touch "$RC" - if grep -q 'ARKA_API_KEY' "$RC"; then - echo "==> ARKA_API_KEY already present in $RC (skipped)" - else - printf '\n# opencode Arka-AI provider\nexport ARKA_API_KEY="%s"\n' "$KEY" >> "$RC" - echo "==> wrote ARKA_API_KEY to $RC" - fi - export ARKA_API_KEY="$KEY" -else - echo "==> warning: no ARKA_API_KEY set; export it in your shell before starting opencode" >&2 -fi - -# --- default model (optional) ------------------------------------------ - -if [ -n "$MODEL" ]; then - CONF="$CONF_DIR/opencode.json" - echo "==> setting default model Arka-AI/$MODEL in $CONF" - python3 - "$CONF" "Arka-AI/$MODEL" <<'PY' -import json, os, sys - -path, model = sys.argv[1], sys.argv[2] -data = {} -if os.path.exists(path): - with open(path) as f: - data = json.load(f) -data.setdefault("$schema", "https://opencode.ai/config.json") -data["model"] = model -with open(path, "w") as f: - json.dump(data, f, indent=2) - f.write("\n") -PY -fi - -echo -echo "Done." -echo " - provider plugin: $PLUGIN_DIR/arka-ai.ts" -echo " - skill: $SKILL_DIR/SKILL.md" -echo -echo "Next steps:" -echo " 1. Restart opencode (open a new shell so ARKA_API_KEY is exported)." -echo " 2. Run /models — the Arka-AI catalog (~116 chat models) loads on first start." -echo " 3. Optional: refresh catalog later with: rm -f ~/.cache/opencode/arka-ai-models.json" +echo "==> installer lives at opencode/install-arka-provider.sh" >&2 +curl -fsSL \ + 'https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh' \ + | bash -s -- "$@" diff --git a/opencode/README.md b/opencode/README.md new file mode 100644 index 0000000..3cc7deb --- /dev/null +++ b/opencode/README.md @@ -0,0 +1,237 @@ +# OpenCode и модели Arka AI + +Arka AI — OpenAI-совместимый API (`https://api.arka-ai.ru/v1`). В каталоге models.dev его нет, поэтому в свежем OpenCode провайдера **Arka-AI** и списка моделей нет, пока не поставить плагин. + +Одна команда ставит плагин, skill и (по желанию) ключ. Каталог чат-моделей подтягивается сам (~116 из ~216; без TTS/картинок/видео/эмбеддингов). Снимок каталога обновляется каждый день в **05:00 по Москве**. + +Нужен [API-ключ Arka AI](https://arka-ai.ru/docs/account/api-keys). Секрет ключа показывается **один раз** при создании. + +--- + +## Быстрый старт + +```bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash +``` + +Скрипт спросит `ARKA_API_KEY` (можно оставить пустым и задать позже). + +Ключ и модель по умолчанию сразу: + +```bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh \ + | bash -s -- --key "$ARKA_API_KEY" --set-default DeepSeek-V4-Pro +``` + +Дальше: + +1. Откройте **новый терминал** (чтобы подхватился `export ARKA_API_KEY`). +2. Перезапустите OpenCode. +3. Команда `/models` — в списке должен быть провайдер **Arka-AI** и чат-модели. + +Если OpenCode запущен из GUI / иконки / сокета, а не из login-shell, переменная из `~/.bashrc` до него может не дойти. Задайте `ARKA_API_KEY` в том окружении, откуда стартует OpenCode, или введите ключ в интерактивном приглашении установщика. + +### Из уже открытого OpenCode + +Отдельного магазина плагинов у OpenCode нет. Можно не выходить из CLI: попросите **текущую** модель (любую, не Arka) выполнить установщик через bash. + +Вставьте в чат (подставьте свой ключ): + +``` +Поставь провайдер Arka AI для OpenCode. Не спрашивай ключ интерактивно. +Выполни одну команду и покажи вывод: + +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash -s -- --key 'ARKA_API_KEY_HERE' --set-default DeepSeek-V4-Pro + +После успеха напиши, что нужно полностью перезапустить OpenCode (конфиг не подхватывается на лету). +``` + +Что происходит: + +1. Агент вызывает встроенный bash/shell. +2. OpenCode спросит разрешение на команду — нажмите Allow. +3. Скрипт пишет плагин, skill и ключ в `~/.config/opencode` (установщик сам по себе офлайн; `curl` только качает скрипт). +4. `--key` обязателен: приглашение «введите ключ» в неинтерактивном пайпе зависнет. +5. **Перезапустите OpenCode целиком** — плагин грузится только на старте. Затем `/models` → **Arka-AI**. + +Пока сессия не перезапущена, разговор идёт на старой модели. Это нормально: установщик не требует Arka. + +### Что ставится + +| Куда | Что | +|------|-----| +| `~/.config/opencode/plugins/arka-ai.ts` | Плагин провайдера **Arka-AI** | +| `~/.config/opencode/skills/arka-provider/SKILL.md` | Skill: как обновить каталог и сменить модель | +| `~/.bashrc` (или первый из `.zshrc` / `.profile`) | `export ARKA_API_KEY=…`, если ключ передали | +| `~/.config/opencode/opencode.json` | Только при `--set-default`: `"model": "Arka-AI/"`. Существующий конфиг **не затирается**. | + +Установщик **офлайн** и идемпотентный: сеть не трогает, повторный запуск перезаписывает плагин и skill каноническими копиями. + +`python3` нужен только с `--set-default`. Отдельный `bun` на машине не нужен — у OpenCode свой runtime. + +### Модель по умолчанию + +Идентификаторы — как в каталоге, с префиксом провайдера: + +```json +{ + "model": "Arka-AI/DeepSeek-V4-Pro" +} +``` + +Примеры: `Arka-AI/DeepSeek-V4-Pro`, `Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`, `Arka-AI/MiniMax-M3`, `Arka-AI/GLM-5.3`, `Arka-AI/deepseek-v4-flash-0731`. + +Их всегда оставляем в списке, даже если фильтр чат-моделей их бы отсёк. + +### Обновить каталог + +```bash +rm -f ~/.cache/opencode/arka-ai-models.json +``` + +Перезапустите OpenCode. Плагин сначала берёт публичный снимок +`https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json` +(без ключа), при ошибке — живой `https://api.arka-ai.ru/v1/models`. Локальный кэш живёт 24 часа. Конфиг OpenCode на лету не перечитывается. + +Список моделей (ключ не нужен): + +```bash +curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json | python3 -m json.tool +``` + +Вызовы моделей идут на `https://api.arka-ai.ru/v1` с `ARKA_API_KEY`. + +### Если что-то не так + +| Симптом | Что проверить | +|---------|----------------| +| После `/models` нет Arka-AI | Есть ли `~/.config/opencode/plugins/arka-ai.ts`; экспортирован ли `ARKA_API_KEY` **в процессе OpenCode**; открыт ли новый шелл | +| Каталог не меняется | `rm -f ~/.cache/opencode/arka-ai-models.json` и рестарт | +| Ошибка импорта плагина | Снова запустить установщик — он вернёт канонический файл | +| `curl` отдаёт HTML, не скрипт | Нужен путь `/raw/branch/main/…`, не страница репозитория | + +--- + +# OpenCode and Arka AI models + +Arka AI is an OpenAI-compatible API at `https://api.arka-ai.ru/v1`. It is not in models.dev, so a fresh OpenCode install has no **Arka-AI** provider until you add the plugin. + +One command installs the plugin, a companion skill, and (optionally) your API key. The chat catalog loads on OpenCode start (~116 of ~216 models; TTS, image, video, and embeddings are filtered out). The published catalog snapshot refreshes daily at **05:00 Europe/Moscow**. + +You need an [Arka AI API key](https://arka-ai.ru/docs/account/api-keys). The secret is shown **once** at creation. + +## Quick start + +```bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash +``` + +The script prompts for `ARKA_API_KEY` (blank is allowed; set it later). + +Key and default model in one go: + +```bash +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh \ + | bash -s -- --key "$ARKA_API_KEY" --set-default DeepSeek-V4-Pro +``` + +Then: + +1. Open a **new shell** so `export ARKA_API_KEY` is picked up. +2. Restart OpenCode. +3. Run `/models` — you should see provider **Arka-AI** and the chat models. + +If OpenCode is started from a GUI, dock icon, or socket rather than a login shell, `~/.bashrc` may not reach it. Set `ARKA_API_KEY` in that process environment, or type it at the installer prompt. + +### From inside OpenCode + +OpenCode has no plugin store. You do not have to leave the CLI: ask the **current** model (any provider, not Arka) to run the installer via bash. + +Paste this (put your real key in): + +``` +Install the Arka AI OpenCode provider. Do not prompt for the key. +Run this exact command and show the output: + +curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/install-arka-provider.sh | bash -s -- --key 'ARKA_API_KEY_HERE' --set-default DeepSeek-V4-Pro + +When it succeeds, tell me I must fully restart OpenCode (config is not hot-reloaded). +``` + +What happens: + +1. The agent uses the built-in bash/shell tool. +2. OpenCode asks permission — Allow the command. +3. The script writes the plugin, skill, and key under `~/.config/opencode` (the installer itself is offline; `curl` only fetches the script). +4. `--key` is required: the interactive key prompt hangs in a non-interactive pipe. +5. **Fully restart OpenCode** — plugins load only at startup. Then `/models` → **Arka-AI**. + +Until you restart, this session keeps the old model. That is expected: the installer does not need Arka. + +### What the installer writes + +| Path | Role | +|------|------| +| `~/.config/opencode/plugins/arka-ai.ts` | **Arka-AI** provider plugin | +| `~/.config/opencode/skills/arka-provider/SKILL.md` | How to refresh the catalog and change the default model | +| `~/.bashrc` (else first existing `.zshrc` / `.profile`) | `export ARKA_API_KEY=…` when a key is given | +| `~/.config/opencode/opencode.json` | Only with `--set-default`: `"model": "Arka-AI/"`. An existing config is **not** replaced. | + +The installer is **offline** and idempotent: no network calls; re-running overwrites plugin and skill with the canonical copies. + +`python3` is required **only** with `--set-default`. You do not need `bun` on the host — OpenCode ships its own runtime. + +### Default model + +Use catalog ids with the provider prefix: + +```json +{ + "model": "Arka-AI/DeepSeek-V4-Pro" +} +``` + +Examples: `Arka-AI/DeepSeek-V4-Pro`, `Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`, `Arka-AI/MiniMax-M3`, `Arka-AI/GLM-5.3`, `Arka-AI/deepseek-v4-flash-0731`. + +Those ids stay visible even if the chat filter would drop them. + +### Refresh the catalog + +```bash +rm -f ~/.cache/opencode/arka-ai-models.json +``` + +Restart OpenCode. The plugin fetches the public snapshot +`https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json` +(no key), then falls back to live `https://api.arka-ai.ru/v1/models`. Local cache TTL is 24 hours. OpenCode does not hot-reload config. + +Inspect the published list (no key): + +```bash +curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json | python3 -m json.tool +``` + +Inference still uses `ARKA_API_KEY` against `https://api.arka-ai.ru/v1`. + +### Troubleshooting + +| Symptom | Check | +|---------|--------| +| No Arka-AI after `/models` | `~/.config/opencode/plugins/arka-ai.ts` exists; `ARKA_API_KEY` is set **in the OpenCode process**; you opened a new shell | +| Models look stale | `rm -f ~/.cache/opencode/arka-ai-models.json` and restart | +| Plugin import error | Re-run the installer to restore the canonical file | +| `curl` returns HTML | Use `/raw/branch/main/…`, not the repo page | + +--- + +## Files in this folder + +| File | Role | +|------|------| +| `install-arka-provider.sh` | Self-contained installer (the one-liner) | +| `plugins/arka-ai.ts` | Plugin source (embedded in the installer) | +| `skills/arka-provider/SKILL.md` | Skill source (embedded in the installer) | +| `catalog.json` | Filtered chat catalog, refreshed daily at 05:00 Europe/Moscow | +| `README.md` | This page — copy into arka-ai.ru «агентные помощники» / agentic helpers | + +This directory is `opencode/` inside the public dump [arka/public](https://git.arka-ai.ru/arka/public). diff --git a/catalog.json b/opencode/catalog.json similarity index 100% rename from catalog.json rename to opencode/catalog.json diff --git a/opencode/install-arka-provider.sh b/opencode/install-arka-provider.sh new file mode 100755 index 0000000..49153d6 --- /dev/null +++ b/opencode/install-arka-provider.sh @@ -0,0 +1,304 @@ +#!/usr/bin/env bash +# +# install-arka-provider.sh — one-shot installer for the arka-ai.ru LLM provider +# in a fresh opencode install. +# +# It is fully self-contained: it embeds the provider plugin and the companion +# skill, writes them into ~/.config/opencode, and persists ARKA_API_KEY. +# +# Usage: +# bash install-arka-provider.sh # prompt for API key +# ARKA_API_KEY=xxx bash install-arka-provider.sh # key from env (no prompt) +# bash install-arka-provider.sh --key xxx --set-default DeepSeek-V4-Pro +# +# Options: +# --key KEY ARKA_API_KEY to persist (default: $ARKA_API_KEY, else prompt) +# --set-default MODEL also set "model": "Arka-AI/" in opencode.json +# -h, --help show this help +# +# Idempotent: safe to run multiple times. Overwrites plugin/skill with the +# embedded versions; never clobbers an existing opencode.json (only upserts the +# requested default model). Makes no network calls. + +set -euo pipefail + +usage() { + sed -n '2,21p' "$0" +} + +KEY="" +MODEL="" + +while [ $# -gt 0 ]; do + case "$1" in + --key) KEY="$2"; shift 2 ;; + --key=*) KEY="${1#*=}"; shift ;; + --set-default) MODEL="$2"; shift 2 ;; + --set-default=*) MODEL="${1#*=}"; shift ;; + -h|--help) usage; exit 0 ;; + *) printf 'unknown option: %s\n' "$1" >&2; usage; exit 1 ;; + esac +done + +CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/opencode" +PLUGIN_DIR="$CONF_DIR/plugins" +SKILL_DIR="$CONF_DIR/skills/arka-provider" + +mkdir -p "$PLUGIN_DIR" "$SKILL_DIR" "$HOME" + +echo "==> writing provider plugin to $PLUGIN_DIR/arka-ai.ts" +cat > "$PLUGIN_DIR/arka-ai.ts" <<'PLUGIN' +import { homedir } from "node:os" +import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs" +import { join } from "node:path" + +const PROVIDER_ID = "Arka-AI" +const API_URL = "https://api.arka-ai.ru/v1" +const CATALOG_URL = + "https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json" +const CACHE_FILE = join(homedir(), ".cache", "opencode", "arka-ai-models.json") +const TTL_MS = 24 * 60 * 60 * 1000 + +// Ids that must always be exposed, even if the filter would drop them. +const FORCED_MODELS = [ + "DeepSeek-V4-Pro", + "deepseek-v4-flash-0731", + "qwen3.8-max", + "kimi-k3", + "MiniMax-M3", + "GLM-5.3", +] + +// Heuristic: drop non-chat models (TTS/ASR/image/video/OCR/embeddings/rerankers…) +// from the catalog so they don't clutter the /models picker. +// Keep in sync with scripts/sync-catalog.py +const NON_CHAT = new RegExp( + [ + "tts", "asr", "audio", "speech", "voice", "whisper", "sensevoice", + "image", "(^|[.-])img", "wan", "vidu", "video", "sora", "flux", + "diffus", "kolors", "cogview", "ocr", "embedding", "(^|[.-])embed", + "rerank", "clip", "moderation", "(^|[.-])filter", "detect", "classif", + "(^|[.-])location", "(^|[.-])search", "comfyui", "meme", "hello", + "(^|[.-])sam", "florence", "esrgan", "rmbg", "background", "poster", + "(^|[.-])face", "(^|[.-])lip", "translate", "(^|[.-])mt([2-]|$)", + "(^|[.-])bge", "(^|[.-])e5", "(^|[.-])jina", "(^|[.-])mpnet", + "spark-tts", "cosyvoice", "chattts", "indextts", "step-audio", + "fish-speech", "cosy", "mate-gguf", "tokenizer", + ].join("|"), + "i", +) + +type ModelMap = Record +type Cache = { ts: number; models: ModelMap } + +function loadCache(): Cache | null { + try { + if (existsSync(CACHE_FILE)) return JSON.parse(readFileSync(CACHE_FILE, "utf8")) + } catch {} + return null +} + +function saveCache(models: ModelMap): void { + try { + mkdirSync(join(homedir(), ".cache", "opencode"), { recursive: true }) + writeFileSync(CACHE_FILE, JSON.stringify({ ts: Date.now(), models })) + } catch {} +} + +async function fetchJson( + url: string, + headers: Record, + timeoutMs: number, +): Promise { + const ctrl = new AbortController() + const timer = setTimeout(() => ctrl.abort(), timeoutMs) + try { + const res = await fetch(url, { headers, signal: ctrl.signal }) + if (!res.ok) throw new Error(`HTTP ${res.status}`) + return await res.json() + } finally { + clearTimeout(timer) + } +} + +function idsFromPayload(json: unknown): string[] { + const data = (json as { data?: Array<{ id: string }> }).data + return (data ?? []).map((m) => m.id).filter(Boolean) +} + +function toModelMap(ids: string[], filter: boolean): ModelMap { + const models: ModelMap = {} + for (const id of ids) { + if (!filter || FORCED_MODELS.includes(id) || !NON_CHAT.test(id)) { + models[id] = { name: id } + } + } + return models +} + +async function resolveModels(): Promise { + const cache = loadCache() + if (cache && Date.now() - cache.ts < TTL_MS) return cache.models + + try { + const models = toModelMap(idsFromPayload(await fetchJson(CATALOG_URL, {}, 5000)), false) + if (Object.keys(models).length) { + saveCache(models) + return models + } + } catch {} + + try { + const key = process.env.ARKA_API_KEY + const json = await fetchJson( + `${API_URL}/models`, + key ? { Authorization: `Bearer ${key}` } : {}, + 5000, + ) + const models = toModelMap(idsFromPayload(json), true) + saveCache(models) + return models + } catch { + return cache?.models ?? null + } +} + +export default async function ArkaAIProviderPlugin() { + const models = await resolveModels() + + return { + config: (cfg: any) => { + cfg.provider ??= {} + const prev = cfg.provider[PROVIDER_ID] ?? {} + + // Static models from opencode.json act as a fallback; the fetched + // catalog is layered on top so the configured default model never + // disappears even if the catalog drops it. + cfg.provider[PROVIDER_ID] = { + name: "Arka-AI", + api: API_URL, + env: ["ARKA_API_KEY"], + ...prev, + models: { ...(prev.models ?? {}), ...(models ?? {}) }, + } + }, + } +} +PLUGIN + +echo "==> writing companion skill to $SKILL_DIR/SKILL.md" +cat > "$SKILL_DIR/SKILL.md" <<'SKILL' +--- +name: arka-provider +description: Manage the custom Arka-AI (arka-ai.ru) LLM provider in opencode config. Use when the user needs to add, refresh, or fix the arka-ai.ru provider, sync its model catalog, change the Arka-AI default model, or when arka models are missing from /models. +--- + +# Arka-AI provider + +arka-ai.ru is **not** in models.dev, so opencode ships no built-in config for it. +It is wired up locally with a plugin + a static `provider` block in +`~/.config/opencode/opencode.json`. + +## How it works + +- Plugin: `~/.config/opencode/plugins/arka-ai.ts` + - On startup it loads the published chat catalog + `https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json` + (no API key; refreshed daily at 05:00 Europe/Moscow). + - If that fetch fails, it falls back to `https://api.arka-ai.ru/v1/models` + and filters out non-chat models (TTS/ASR/image/video/OCR/embedding/reranker/…) + via a heuristic regex so the `/models` picker stays clean. + - Caches the result at `~/.cache/opencode/arka-ai-models.json` (TTL 24h). + - Injects the provider into config via the `config` hook, layered over the + static block in `opencode.json`. +- Static block (`opencode.json` → `provider["Arka-AI"]`) holds + `name`, `api`, `env`, and a small fallback `models` map that is used when the + catalog is unreachable. +- Inference still uses `ARKA_API_KEY` against `https://api.arka-ai.ru/v1`. + +## Refresh the model list + +Catalog ~216 raw models / ~116 chat; the public snapshot updates at 05:00 +Europe/Moscow. Changes land in opencode only after cache expiry + restart +(config is not hot-reloaded). + +1. `rm -f ~/.cache/opencode/arka-ai-models.json` +2. Restart opencode (or run `opencode` again) — the plugin re-fetches on the + next cold start. + +Optionally inspect the live API (no key required for listing): + +```bash +curl -sS https://api.arka-ai.ru/v1/models | python3 -m json.tool +curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json | python3 -m json.tool +``` + +## Change default model + +Edit `opencode.json` → `"model": "Arka-AI/"`. Use the IDs exactly as +returned by the catalog (e.g. `Arka-AI/DeepSeek-V4-Pro`, +`Arka-AI/qwen3.8-max`, `Arka-AI/kimi-k3`). + +## Adjust filtering + +Edit `NON_CHAT` (regex) or `FORCED_MODELS` in the plugin file **and** the same +lists in `scripts/sync-catalog.py` in `arka/public`, then re-run the installer +and restart. `FORCED_MODELS` keeps must-have chat models even if the heuristic +would drop them. +SKILL + +# --- API key ----------------------------------------------------------- + +if [ -z "$KEY" ]; then + read -rsp "ARKA_API_KEY (leave blank to skip): " KEY || true + echo +fi + +if [ -n "$KEY" ]; then + RC="" + for f in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.profile"; do + if [ -f "$f" ]; then RC="$f"; break; fi + done + RC="${RC:-$HOME/.bashrc}" + touch "$RC" + if grep -q 'ARKA_API_KEY' "$RC"; then + echo "==> ARKA_API_KEY already present in $RC (skipped)" + else + printf '\n# opencode Arka-AI provider\nexport ARKA_API_KEY="%s"\n' "$KEY" >> "$RC" + echo "==> wrote ARKA_API_KEY to $RC" + fi + export ARKA_API_KEY="$KEY" +else + echo "==> warning: no ARKA_API_KEY set; export it in your shell before starting opencode" >&2 +fi + +# --- default model (optional) ------------------------------------------ + +if [ -n "$MODEL" ]; then + CONF="$CONF_DIR/opencode.json" + echo "==> setting default model Arka-AI/$MODEL in $CONF" + python3 - "$CONF" "Arka-AI/$MODEL" <<'PY' +import json, os, sys + +path, model = sys.argv[1], sys.argv[2] +data = {} +if os.path.exists(path): + with open(path) as f: + data = json.load(f) +data.setdefault("$schema", "https://opencode.ai/config.json") +data["model"] = model +with open(path, "w") as f: + json.dump(data, f, indent=2) + f.write("\n") +PY +fi + +echo +echo "Done." +echo " - provider plugin: $PLUGIN_DIR/arka-ai.ts" +echo " - skill: $SKILL_DIR/SKILL.md" +echo +echo "Next steps:" +echo " 1. Restart opencode (open a new shell so ARKA_API_KEY is exported)." +echo " 2. Run /models — the Arka-AI catalog (~116 chat models) loads on first start." +echo " 3. Optional: refresh catalog later with: rm -f ~/.cache/opencode/arka-ai-models.json" diff --git a/plugins/arka-ai.ts b/opencode/plugins/arka-ai.ts similarity index 98% rename from plugins/arka-ai.ts rename to opencode/plugins/arka-ai.ts index a51d424..676b776 100644 --- a/plugins/arka-ai.ts +++ b/opencode/plugins/arka-ai.ts @@ -5,7 +5,7 @@ import { join } from "node:path" const PROVIDER_ID = "Arka-AI" const API_URL = "https://api.arka-ai.ru/v1" const CATALOG_URL = - "https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json" + "https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json" const CACHE_FILE = join(homedir(), ".cache", "opencode", "arka-ai-models.json") const TTL_MS = 24 * 60 * 60 * 1000 diff --git a/scripts/cron-sync.sh b/opencode/scripts/cron-sync.sh similarity index 61% rename from scripts/cron-sync.sh rename to opencode/scripts/cron-sync.sh index 5738512..2f6c4bb 100755 --- a/scripts/cron-sync.sh +++ b/opencode/scripts/cron-sync.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash -# Daily catalog refresh for arka/public. Runs on core at 05:00 Europe/Moscow. +# Daily catalog refresh for arka/public/opencode. +# Runs on core at 05:00 Europe/Moscow. set -euo pipefail -ROOT="$(cd "$(dirname "$0")/.." && pwd)" -cd "$ROOT" +# this file lives at opencode/scripts/cron-sync.sh → repo root is ../.. +REPO="$(cd "$(dirname "$0")/../.." && pwd)" +cd "$REPO" export GIT_SSH_COMMAND="${GIT_SSH_COMMAND:-ssh -i /root/.ssh/arka_public_catalog -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new}" @@ -11,14 +13,14 @@ git fetch origin main git checkout -q main git reset --hard origin/main -python3 scripts/sync-catalog.py +python3 opencode/scripts/sync-catalog.py -if git diff --quiet -- catalog.json; then +if git diff --quiet -- opencode/catalog.json; then printf '%s no catalog change\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" exit 0 fi -git add catalog.json +git add opencode/catalog.json git -c user.name='arka-catalog-bot' -c user.email='noreply@arka-ai.ru' \ commit -m "chore(catalog): refresh $(date -u +%Y-%m-%d)" git push origin main diff --git a/scripts/sync-catalog.py b/opencode/scripts/sync-catalog.py similarity index 97% rename from scripts/sync-catalog.py rename to opencode/scripts/sync-catalog.py index 14eb301..89ce817 100755 --- a/scripts/sync-catalog.py +++ b/opencode/scripts/sync-catalog.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Rebuild catalog.json from the public arka-ai.ru OpenAI-compatible models list. -Keep FORCED_MODELS / NON_CHAT in lockstep with plugins/arka-ai.ts. +Keep FORCED_MODELS / NON_CHAT in lockstep with opencode/plugins/arka-ai.ts. """ from __future__ import annotations diff --git a/skills/arka-provider/SKILL.md b/opencode/skills/arka-provider/SKILL.md similarity index 92% rename from skills/arka-provider/SKILL.md rename to opencode/skills/arka-provider/SKILL.md index 09410a1..e4637f2 100644 --- a/skills/arka-provider/SKILL.md +++ b/opencode/skills/arka-provider/SKILL.md @@ -13,7 +13,7 @@ It is wired up locally with a plugin + a static `provider` block in - Plugin: `~/.config/opencode/plugins/arka-ai.ts` - On startup it loads the published chat catalog - `https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json` + `https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json` (no API key; refreshed daily at 05:00 Europe/Moscow). - If that fetch fails, it falls back to `https://api.arka-ai.ru/v1/models` and filters out non-chat models (TTS/ASR/image/video/OCR/embedding/reranker/…) @@ -40,7 +40,7 @@ Optionally inspect the live API (no key required for listing): ```bash curl -sS https://api.arka-ai.ru/v1/models | python3 -m json.tool -curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/catalog.json | python3 -m json.tool +curl -sS https://git.arka-ai.ru/arka/public/raw/branch/main/opencode/catalog.json | python3 -m json.tool ``` ## Change default model