1 line
18 KiB
JSON
1 line
18 KiB
JSON
{"repo": "ai4nucleome/biomaster", "files": {"BioMaster/packages/opencode/src/session/retry.ts": {"6f98a63aa1823304403475b1929424ccf9d4ec46": {"t": 1785596376.866049, "n": 7152, "h": "0c7fcace557156bd", "c": "import type { NamedError } from \"@opencode-ai/core/util/error\"\nimport { SessionV1 } from \"@opencode-ai/core/v1/session\"\nimport { Cause, Clock, Duration, Effect, Schedule } from \"effect\"\nimport { MessageV2 } from \"./message-v2\"\nimport { iife } from \"@/util/iife\"\nimport { isRecord } from \"@/util/record\"\n\nexport type Err = ReturnType<NamedError[\"toObject\"]>\n\nexport const GO_UPSELL_MESSAGE = \"Free usage exceeded, subscribe to Go\"\nexport const GO_UPSELL_URL = \"https://opencode.ai/go\"\nexport type RetryReason = \"free_tier_limit\" | \"account_rate_limit\" | (string & {})\n\nexport type Retryable = {\n message: string\n action?: {\n reason: RetryReason\n provider: string\n title: string\n message: string\n label: string\n link?: string\n }\n}\n\nexport const RETRY_INITIAL_DELAY = 2000\nexport const RETRY_BACKOFF_FACTOR = 2\nexport const RETRY_MAX_DELAY_NO_HEADERS = 30_000 // 30 seconds\nexport const RETRY_MAX_DELAY = 2_147_483_647 // max 32-bit signed integer for setTimeout\n\nfunction cap(ms: number) {\n return Math.min(ms, RETRY_MAX_DELAY)\n}\n\nexport function delay(attempt: number, error?: SessionV1.APIError) {\n if (error) {\n const headers = error.data.responseHeaders\n if (headers) {\n const retryAfterMs = headers[\"retry-after-ms\"]\n if (retryAfterMs) {\n const parsedMs = Number.parseFloat(retryAfterMs)\n if (!Number.isNaN(parsedMs)) {\n return cap(parsedMs)\n }\n }\n\n const retryAfter = headers[\"retry-after\"]\n if (retryAfter) {\n const parsedSeconds = Number.parseFloat(retryAfter)\n if (!Number.isNaN(parsedSeconds)) {\n // convert seconds to milliseconds\n return cap(Math.ceil(parsedSeconds * 1000))\n }\n // Try parsing as HTTP date format\n const parsed = Date.parse(retryAfter) - Date.now()\n if (!Number.isNaN(parsed) && parsed > 0) {\n return cap(Math.ceil(parsed))\n }\n }\n\n return cap(RETRY_INITIAL_DELAY * Math.pow(RETRY_BACKOFF_FACTOR, attempt - 1))\n }\n }\n\n return cap(Math.min(RETRY_INITIAL_DELAY * Math.pow(RETRY_BACKOFF_FACTOR, attempt - 1), RETRY_MAX_DELAY_NO_HEADERS))\n}\n\nexport function retryable(error: Err, provider: string) {\n // context overflow errors should not be retried\n if (SessionV1.ContextOverflowError.isInstance(error)) return undefined\n if (SessionV1.APIError.isInstance(error)) {\n const status = error.data.statusCode\n // 5xx errors are transient server failures and should always be retried,\n // even when the provider SDK doesn't explicitly mark them as retryable.\n if (!error.data.isRetryable && !(status !== undefined && status >= 500)) return undefined\n if (error.data.responseBody?.includes(\"FreeUsageLimitError\")) {\n return {\n message: GO_UPSELL_MESSAGE,\n action: {\n reason: \"free_tier_limit\",\n provider,\n title: \"Free limit reached\",\n message: \"Subscribe to OpenCode Go for reliable access to the best open-source models, starting at $5/month.\",\n label: \"subscribe\",\n link: GO_UPSELL_URL,\n },\n }\n }\n if (error.data.responseBody?.includes(\"GoUsageLimitError\")) {\n const body = parseJSON(error.data.responseBody)\n const workspace = str(body?.metadata?.workspace)\n const limitName = str(body?.metadata?.limitName)\n const retryAfter = num(error.data.responseHeaders?.[\"retry-after\"])\n const resetIn = iife(() => {\n if (retryAfter === undefined) return \"\"\n const seconds = Math.max(0, Math.ceil(retryAfter))\n const days = Math.floor(seconds / 86_400)\n const hours = Math.floor((seconds % 86_400) / 3_600)\n const minutes = Math.ceil((seconds % 3_600) / 60)\n const unit = (value: number, name: string) => `${value} ${name}${value === 1 ? \"\" : \"s\"}`\n\n if (days > 0) return hours > 0 ? `${unit(days, \"day\")} ${unit(hours, \"hour\")}` : unit(days, \"day\")\n if (hours > 0) return minutes > 0 ? `${unit(hours, \"hour\")} ${unit(minutes, \"minute\")}` : unit(hours, \"hour\")\n return minutes > 0 ? unit(minutes, \"minute\") : \"less than a minute\"\n })\n\n const message = `${limitName ? `${limitName} usage limit` : \"Usage limit\"} reached. It will reset in ${resetIn}. To continue using this model now, enable usage from your available balance`\n\n const link = `https://opencode.ai/workspace/${workspace}/go`\n return {\n message: `${message} - ${link}`,\n action: {\n reason: \"account_rate_limit\",\n provider,\n title: \"Go limit reached\",\n message,\n label: \"open settings\",\n link,\n },\n }\n }\n return { message: error.data.message.includes(\"Overloaded\") ? \"Provider is overloaded\" : error.data.message }\n }\n\n // Check for rate limit patterns in plain text error messages\n const msg = isRecord(error.data) ? error.data.message : undefined\n if (typeof msg === \"string\") {\n const lower = msg.toLowerCase()\n if (\n lower.includes(\"rate increased too quickly\") ||\n lower.includes(\"rate limit\") ||\n lower.includes(\"too many requests\")\n ) {\n return { message: msg }\n }\n }\n\n const json = parseJSON(msg)\n if (!json || typeof json !== \"object\") return undefined\n const code = typeof json.code === \"string\" ? json.code : \"\"\n\n if (json.type === \"error\" && json.error?.type === \"too_many_requests\") {\n return { message: \"Too Many Requests\" }\n }\n if (code.includes(\"exhausted\") || code.includes(\"unavailable\")) {\n return { message: \"Provider is overloaded\" }\n }\n if (json.type === \"error\" && typeof json.error?.code === \"string\" && json.error.code.includes(\"rate_limit\")) {\n return { message: \"Rate Limited\" }\n }\n return undefined\n}\n\nfunction str(value: unknown) {\n if (value === undefined || value === null) return \"\"\n return String(value)\n}\n\nfunction num(value: unknown) {\n const parsed = Number.parseFloat(str(value))\n if (Number.isNaN(parsed)) return undefined\n return parsed\n}\n\nfunction parseJSON(value: unknown) {\n return iife(() => {\n try {\n if (typeof value !== \"string\") return undefined\n return JSON.parse(value)\n } catch {\n return undefined\n }\n })\n}\n\nexport function policy(opts: {\n provider: string\n parse: (error: unknown) => Err\n set: (input: { attempt: number; message: string; action?: Retryable[\"action\"]; next: number }) => Effect.Effect<void>\n}) {\n return Schedule.fromStepWithMetadata(\n Effect.succeed((meta: Schedule.InputMetadata<unknown>) => {\n const error = opts.parse(meta.input)\n const retry = retryable(error, opts.provider)\n if (!retry) return Cause.done(meta.attempt)\n return Effect.gen(function* () {\n const wait = delay(meta.attempt, SessionV1.APIError.isInstance(error) ? error : undefined)\n const now = yield* Clock.currentTimeMillis\n yield* opts.set({\n attempt: meta.attempt,\n message: retry.message,\n action: retry.action,\n next: now + wait,\n })\n return [meta.attempt, Duration.millis(wait)] as [number, Duration.Duration]\n })\n }),\n )\n}\n\nexport * as SessionRetry from \"./retry\"\n"}}, "BioMaster/packages/web/src/content/docs/de/go.mdx": {"6f98a63aa1823304403475b1929424ccf9d4ec46": {"t": 1785846940.8052664, "n": 10769, "h": "9739457ced6db659", "c": "---\ntitle: Go\ndescription: Kostengünstiges Abonnement für offene Coding-Modelle.\n---\n\nimport config from \"../../../../config.mjs\"\nexport const console = config.console\nexport const email = `mailto:${config.email}`\n\nOpenCode Go ist ein kostengünstiges Abonnement — **5 $ für deinen ersten Monat**, danach **10 $/Monat** —, das dir zuverlässigen Zugriff auf beliebte offene Coding-Modelle bietet.\n\nGo funktioniert wie jeder andere Provider in OpenCode. Du abonnierst OpenCode Go und\nerhältst deinen API-Key. Es ist **völlig optional** und du musst es nicht nutzen, um\nOpenCode zu verwenden.\n\nEs wurde primär für internationale Nutzer entwickelt, wobei die Modelle für einen stabilen weltweiten Zugriff in den USA, der EU und Singapur gehostet werden.\n\n---\n\n## Hintergrund\n\nOffene Modelle sind richtig gut geworden. Sie erreichen bei Coding-Aufgaben mittlerweile eine Leistung, die nahe an proprietäre Modelle herankommt. Und da viele Provider sie wettbewerbsfähig anbieten können, sind sie in der Regel viel günstiger.\n\nAllerdings kann es schwierig sein, zuverlässigen Zugriff mit geringer Latenz auf sie zu erhalten. Provider variieren in Qualität und Verfügbarkeit.\n\n:::tip\nWir haben eine ausgewählte Gruppe von Modellen und Providern getestet, die gut mit OpenCode funktionieren.\n:::\n\nUm dies zu beheben, haben wir einige Dinge getan:\n\n1. Wir haben eine ausgewählte Gruppe offener Modelle getestet und mit ihren Teams darüber gesprochen, wie man sie am besten ausführt.\n2. Anschließend haben wir mit einigen Providern zusammengearbeitet, um sicherzustellen, dass diese korrekt bereitgestellt werden.\n3. Zuletzt haben wir die Kombination aus Modell und Provider einem Benchmark unterzogen und eine Liste erstellt, die wir mit gutem Gewissen empfehlen können.\n\nOpenCode Go bietet dir Zugriff auf diese Modelle für **5 $ im ersten Monat**, danach **10 $/Monat**.\n\n---\n\n## Wie es funktioniert\n\nOpenCode Go funktioniert wie jeder andere Provider in OpenCode.\n\n1. Du meldest dich bei **<a href={console}>OpenCode Zen</a>** an, abonnierst Go und kopierst deinen API-Key.\n2. Du führst den Befehl `/connect` in der TUI aus, wählst `OpenCode Go` und fügst deinen API-Key ein.\n3. Führe `/models` in der TUI aus, um die Liste der über Go verfügbaren Modelle zu sehen.\n\n:::note\nNur ein Mitglied pro Workspace kann OpenCode Go abonnieren.\n:::\n\nDie aktuelle Liste der Modelle umfasst:\n\n- **GLM-5.2**\n- **GLM-5.1**\n- **Kimi K2.7 Code**\n- **Kimi K2.6**\n- **MiMo-V2.5**\n- **MiMo-V2.5-Pro**\n- **MiniMax M3**\n- **MiniMax M2.7**\n- **Qwen3.7 Max**\n- **Qwen3.7 Plus**\n- **Qwen3.6 Plus**\n- **DeepSeek V4 Pro**\n- **DeepSeek V4 Flash**\n\nDie Liste der Modelle kann sich ändern, während wir neue testen und hinzufügen.\n\n---\n\n## Nutzungslimits\n\nOpenCode Go beinhaltet die folgenden Limits:\n\n- **5-Stunden-Limit** — 12 $ Nutzung\n- **Wöchentliches Limit** — 30 $ Nutzung\n- **Monatliches Limit** — 60 $ Nutzung\n\nLimits sind in Dollarwerten definiert. Das bedeutet, dass die tatsächliche Anzahl deiner Anfragen von dem von dir genutzten Modell abhängt. Günstigere Modelle wie DeepSeek V4 Flash erlauben mehr Anfragen, während teurere Modelle wie GLM-5.2 weniger erlauben.\n\nDie folgende Tabelle zeigt eine geschätzte Anzahl von Anfragen basierend auf typischen Go-Nutzungsmustern:\n\n| Model | Anfragen pro 5 Stunden | Anfragen pro Woche | Anfragen pro Monat |\n| ----------------- | ---------------------- | ------------------ | ------------------ |\n| GLM-5.2 | 880 | 2,150 | 4,300 |\n| GLM-5.1 | 880 | 2,150 | 4,300 |\n| Kimi K2.6 | 1,150 | 2,880 | 5,750 |\n| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |\n| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |\n| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |\n| MiniMax M3 | 3,200 | 8,000 | 16,000 |\n| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |\n| Qwen3.7 Max | 950 | 2,390 | 4,770 |\n| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |\n| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |\n| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |\n| DeepSeek V4 Flash | 31,650 | 79,050 | 158,150 |\n\nDie Schätzungen basieren auf beobachteten durchschnittlichen Anfragemustern:\n\n- GLM-5.2/5.1 — 700 Input-, 52.000 Cached-, 150 Output-Tokens pro Anfrage\n- Kimi K2.7 Code/K2.6 — 870 Input-, 55.000 Cached-, 200 Output-Tokens pro Anfrage\n- DeepSeek V4 Pro — 750 Input-, 82.000 Cached-, 290 Output-Tokens pro Anfrage\n- DeepSeek V4 Flash — 790 Input-, 68.000 Cached-, 280 Output-Tokens pro Anfrage\n- MiniMax M3 — 510 Input-, 56.000 Cached-, 190 Output-Tokens pro Anfrage\n- MiniMax M2.7 — 300 Input-, 55.000 Cached-, 125 Output-Tokens pro Anfrage\n- Qwen3.7 Max — 420 Input-, 66.000 Cached-, 200 Output-Tokens pro Anfrage\n- Qwen3.7 Plus — 500 Input-, 57.000 Cached-, 190 Output-Tokens pro Anfrage\n- Qwen3.6 Plus — 500 Input-, 57.000 Cached-, 190 Output-Tokens pro Anfrage\n- MiMo-V2.5 — 830 Input-, 71.500 Cached-, 295 Output-Tokens pro Anfrage\n- MiMo-V2.5-Pro — 790 Input-, 86.000 Cached-, 305 Output-Tokens pro Anfrage\n\nDie Schätzungen basieren außerdem auf den folgenden Preisen pro 1M Tokens:\n\n| Model | Input | Output | Cached Read | Cached Write |\n| ---------------------------- | ----- | ------ | ----------- | ------------ |\n| GLM-5.2 | $1.40 | $4.40 | $0.26 | - |\n| GLM-5.1 | $1.40 | $4.40 | $0.26 | - |\n| Kimi K2.7 Code | $0.95 | $4.00 | $0.19 | - |\n| Kimi K2.6 | $0.95 | $4.00 | $0.16 | - |\n| MiMo V2.5 | $0.14 | $0.28 | $0.0028 | - |\n| MiMo V2.5 Pro | $1.74 | $3.48 | $0.0145 | - |\n| MiniMax M3 | $0.30 | $1.20 | $0.06 | - |\n| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 |\n| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 |\n| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 |\n| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 |\n| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 |\n| Qwen3.6 Plus (≤ 256K tokens) | $0.50 | $3.00 | $0.05 | $0.625 |\n| Qwen3.6 Plus (> 256K tokens) | $2.00 | $6.00 | $0.20 | $2.50 |\n| DeepSeek V4 Pro | $1.74 | $3.48 | $0.0145 | - |\n| DeepSeek V4 Flash | $0.14 | $0.28 | $0.0028 | - |\n\nDu kannst deine aktuelle Nutzung in der **<a href={console}>Console</a>** verfolgen.\n\n:::tip\nWenn du das Nutzungslimit erreichst, kannst du weiterhin die kostenlosen Modelle verwenden.\n:::\n\nDie Nutzungslimits können sich ändern, während wir aus der frühen Nutzung und dem Feedback lernen.\n\n---\n\n### Nutzung über die Limits hinaus\n\nWenn du auch Guthaben auf deinem Zen-Konto hast, kannst du in der Console die Option **Use balance** aktivieren. Wenn diese aktiviert ist, greift Go auf dein Zen-Guthaben zurück, nachdem du deine Nutzungslimits erreicht hast, anstatt Anfragen zu blockieren.\n\n---\n\n## Endpunkte\n\nDu kannst auf die Go-Modelle auch über die folgenden API-Endpunkte zugreifen.\n\n| Modell | Modell-ID | Endpunkt | AI SDK Package |\n| ----------------- | ----------------- | ------------------------------------------------ | --------------------------- |\n| GLM-5.2 | glm-5.2 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| Kimi K2.7 Code | kimi-k2.7-code | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| Kimi K2.6 | kimi-k2.6 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| DeepSeek V4 Pro | deepseek-v4-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| DeepSeek V4 Flash | deepseek-v4-flash | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| MiMo-V2.5 | mimo-v2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| MiMo-V2.5-Pro | mimo-v2.5-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` |\n| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |\n\nDie [Modell-ID](/docs/config/#models) in deiner OpenCode Config verwendet das Format `opencode-go/<model-id>`. Für Kimi K2.7 Code würdest du beispielsweise `opencode-go/kimi-k2.7-code` in deiner Config verwenden.\n\n---\n\n### Models\n\nDu kannst die vollständige Liste der verfügbaren Modelle und ihrer Metadaten hier abrufen:\n\n```\nhttps://opencode.ai/zen/go/v1/models\n```\n\n---\n\n## Datenschutz\n\nDer Plan ist in erster Linie für internationale Nutzer konzipiert, mit in US, EU und Singapore gehosteten Modellen für einen stabilen weltweiten Zugriff. Unsere Anbieter befolgen eine Zero-Retention-Richtlinie und verwenden Ihre Daten nicht für das Modelltraining.\n\n---\n\n## Ziele\n\nWir haben OpenCode Go entwickelt, um:\n\n1. AI Coding durch ein kostengünstiges Abonnement für mehr Menschen **zugänglich** zu machen.\n2. **Zuverlässigen** Zugriff auf die besten offenen Coding-Modelle zu bieten.\n3. Modelle zu kuratieren, die für den Einsatz als Coding Agent **getestet und einem Benchmark unterzogen** wurden.\n4. **Keinen Lock-in-Effekt** zu haben, indem wir dir ermöglichen, auch jeden anderen Provider mit OpenCode zu nutzen.\n"}}}} |