Claude/review merge conflicts yv ug x#175
Closed
PetrAnto wants to merge 85 commits intocloudflare:mainfrom
Closed
Conversation
Resolved conflicts while preserving fork customizations: Upstream changes integrated: - arm64 architecture support in Dockerfile - TELEGRAM_DM_ALLOW_FROM env var for explicit allowlists - Fixed Discord dm object initialization (prevents potential crash) - E2E tests, log redaction, LICENSE, CONTRIBUTING.md Fork modifications preserved: - Git & GitHub CLI installation for Storia orchestrator - Storia Bot git configuration - OpenRouter cleanup code (fixed duplicate) - OpenRouter default models (DeepSeek + model aliases) - skills/storia-orchestrator skill https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
Claude/resolve merge conflicts aj7 jz
Added comprehensive model selection with aliases and metadata: - auto (default): OpenRouter Auto-routing - deep: DeepSeek V3.2 - General purpose - qwen/qwenfree: Qwen Coder 32B - Best coding (81% SWE) - devstral: Devstral 2 - Agentic code (FREE) - mimo: Xiaomi MiMo - Budget coding (FREE) - grokcode/grok: Grok models - Code & Agentic - kimi: Kimi K2.5 - Visual+Agents - flash: Gemini 2.0 Flash - Speed - haiku/sonnet: Claude models - mini/gpt: GPT-4o variants - think: DeepSeek Reasoner - qwq: QwQ 32B - Budget reasoning Each model includes description with specialty, benchmark scores, and cost info. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
feat: expand OpenRouter model catalog with 16 models + descriptions
Moved storia-orchestrator skill to R2 storage to keep it private. Skills in R2 will be restored at container startup. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
chore: remove private skill from public repo
Adds a parallel Telegram webhook path that bypasses clawdbot and calls OpenRouter API directly. This enables: - Dynamic model selection via aliases (22 models) - Per-user model preferences stored in R2 - Vision support (image analysis) - Image generation with FLUX models - Conversation history New endpoints: - POST /telegram/webhook/:token - Telegram webhook - GET /telegram/setup - Set webhook URL - GET /telegram/info - Health check Commands: - /models - List all models with specialty/score/cost - /use <alias> - Set your default model - /model - Show current model - /clear - Clear conversation history - /img <prompt> - Generate image with FLUX - /credits - Check OpenRouter balance - /<alias> - Quick switch (e.g., /deep, /gpt, /sonnet) Model catalog includes: - FREE: auto, trinity, deepchimera, glmfree, stepfree, llama405free, mimo - IMAGE: fluxpro, fluxmax - PAID: deep, gpt, sonnet, opus, haiku, flash, grok, kimi, etc. Set OPENROUTER_API_KEY via: wrangler secret put OPENROUTER_API_KEY https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
feat: add direct OpenRouter API integration for Telegram bot
Auto-deploys on push to main and sets secrets from GitHub Actions secrets. Required GitHub secrets: - CLOUDFLARE_API_TOKEN - CLOUDFLARE_ACCOUNT_ID - OPENROUTER_API_KEY - TELEGRAM_BOT_TOKEN https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
ci: add deploy workflow for Cloudflare Workers
fix: correct secrets check syntax in deploy workflow
fix: add build step before deploy
The clawdbot schema only supports 'alias' field, not 'description'. This was causing the gateway to crash on startup. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
fix: remove unsupported description field from clawdbot config
The CF Access middleware was redirecting telegram webhook requests (302 Found). Added checks to skip both validation and auth middlewares for /telegram/* paths. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
fix: skip auth middleware for telegram webhook routes
- Add SkillStorage class to read skills from R2 bucket - Telegram handler now loads storia-orchestrator skill as system prompt - Add /skill command to check status, reload, and preview skill content - Skills are cached for performance https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ feat: add skill loading from R2 for Telegram bot
- Add TELEGRAM_ALLOWED_USERS env var (comma-separated user IDs) - Unauthorized users get "Access denied" message - If not set, bot remains open (backwards compatible) https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ feat: add user allowlist for Telegram bot security
OpenRouter doesn't have /images/generations endpoint. FLUX models return images via chat completions with markdown URL format. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
Now supports: /img fluxmax <prompt> to choose image model Default remains fluxpro if no model specified https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ fix: use chat completions endpoint for FLUX image generation OpenRouter doesn't have /images/generations endpoint. FLUX models return images via chat completions with markdown URL format. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
- Fixed model IDs: flux.2-pro, flux.2-max (not flux-2-*) - Added modalities: ['image', 'text'] to request (required by OpenRouter) - Added base64 image upload support for Telegram - Handle both data URL and regular URL responses https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
- Fixed qwencoder: qwen/qwen3-coder (was wrong ID) - Added qwennext: qwen/qwen3-coder-next (70.6% SWE-Bench) https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ fix: correct Qwen model IDs and add qwen3-coder-next - Fixed qwencoder: qwen/qwen3-coder (was wrong ID) - Added qwennext: qwen/qwen3-coder-next (70.6% SWE-Bench) https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ feat: add alarm-based watchdog to detect DO crashes
Standard usage model gives Durable Objects 30 seconds of CPU time instead of the default bundled limits. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
- Remove redundant checkpoint before API call (already saved after tools) - Save checkpoints every 3 tools instead of every tool - Remove token estimation from progress updates (O(n) operation) These changes reduce JSON.stringify calls and message iterations, which should help stay within the 30-second CPU limit. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ Claude/resolve merge conflicts aj7 jz
Adds three new model aliases that bypass OpenRouter: - /q25 - Qwen 2.5 Plus via DashScope (Alibaba) - /k21 - Kimi 128K via Moonshot API - /dcode - DeepSeek Coder via DeepSeek API These direct APIs are cheaper, faster, and avoid OpenRouter validation issues for long-running tasks. New Cloudflare secrets required: - DASHSCOPE_API_KEY (for /q25) - MOONSHOT_API_KEY (for /k21) - DEEPSEEK_API_KEY (for /dcode) https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ feat: add direct API support for Qwen, Kimi, DeepSeek
The function had a hardcoded list that didn't include the new direct API models (q25, k21, dcode). Now it checks the model's supportsTools flag first, falling back to the hardcoded list. This ensures direct API models are routed through the TaskProcessor DO which handles the provider-specific API calls. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
OpenRouter changed their API - FLUX models now use the dedicated /images/generations endpoint instead of chat/completions with modalities parameter. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
OpenRouter returns images in message.images[].image_url.url format when using modalities: ["image", "text"]. Updated to parse this correctly instead of using /images/generations endpoint. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ Claude/resolve merge conflicts aj7 jz
- Reduce MAX_TOOL_RESULT_LENGTH: 15000 → 8000 chars - Compress context more frequently: every 6 tools instead of 10 - Reduce MAX_CONTEXT_TOKENS: 80000 → 60000 - Save checkpoints every 5 tools instead of 3 These changes should help tasks stay within the 30-second CPU limit. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
Adds detailed timing logs to track: - Iteration start/end times - API call duration - Individual tool execution times and result sizes View with: wrangler tail --format=pretty This will help identify if CPU limit, memory, or something else is causing the DO to stop unexpectedly. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ debug: add timing logs to diagnose CPU vs other issues Adds detailed timing logs to track: - Iteration start/end times - API call duration - Individual tool execution times and result sizes View with: wrangler tail --format=pretty This will help identify if CPU limit, memory, or something else is causing the DO to stop unexpectedly. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
The CPU metrics showed low usage (26ms max, not 30s), so the issue is NOT CPU limits. The DO is stopping during I/O waits. Added: - Heartbeat every 10s during API calls to keep DO active - Updates lastUpdate to prevent watchdog from false-triggering - More logging to pinpoint exactly where process stops This will help identify if DO hibernation or fetch timeouts are the issue. https://claude.ai/code/session_01KUEtYSvgqjt5fPenHTCT2b
…J7JZ debug: add heartbeat during API calls to diagnose DO stopping
The DO was dying after receiving API response but before parsing. Added logging to pinpoint exactly where it fails: - Reading response body - Response size in chars - JSON parsing start/complete This will help identify if large responses cause memory issues. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
The DO was dying during response.text() - after receiving headers (200) but while streaming the response body from DeepSeek. Added 5-second heartbeat interval during body reading to: - Keep DO active during slow response streaming - Update lastUpdate to prevent watchdog false triggers - Log progress to diagnose slow responses https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
The DO keeps dying during response.text() before any heartbeat fires. This suggests Cloudflare is hard-killing the DO, not just timing out. Changes: - Heartbeat every 2s instead of 5s during body reading - Add 30s timeout wrapper around response.text() - Checkpoint every 3 tools instead of 5 (less lost progress) If the timeout fires, we'll see an error. If DO still dies silently, the issue is Cloudflare terminating the process entirely. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
Root cause found: DeepSeek API sends HTTP 200 headers but then hangs during response body streaming. The 30s timeout catches this. Added: - Retry loop with up to 3 attempts for API calls - Automatic retry on response.text() timeout - 2 second delay between retries - Logging to track retry attempts This should make the bot much more resilient to DeepSeek's occasional response streaming hangs. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
- DeepSeek V3.2 is latest version with GPT-5 class reasoning - Routes through OpenRouter instead of direct API (more reliable) - Same cheap pricing: $0.25/$0.38 per 1M tokens - Avoids streaming hang issues seen with direct DeepSeek API https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
Fixes response.text() hang issue with DeepInfra-routed models (Qwen3 Coder, etc.) Changes: - Add chatCompletionStreamingWithTools() method to OpenRouterClient - Uses SSE streaming (stream: true) to read response incrementally - 30s idle timeout with AbortController for clean cancellation - Accumulates tool_call deltas by index - Returns same ChatCompletionResponse structure as non-streaming - stream_options.include_usage for token tracking - Update TaskProcessor to use streaming for OpenRouter provider - Non-OpenRouter providers keep existing fetch-based approach - Progress callback updates watchdog every 50 chunks - Retry logic preserved (3 attempts) Why streaming fixes the hang: - Non-streaming: response.text() waits for entire body, can hang indefinitely - Streaming: reads small chunks incrementally, detects stalls via idle timeout https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
Without this, if fetch() hangs before returning a response, the idle timeout never starts and we wait for the 90s watchdog. Now: - 60s timeout on initial fetch (before streaming starts) - 30s idle timeout during streaming (resets on each chunk) - Better error messages: "connection timeout" vs "idle timeout" https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
Root cause (from Grok research): - Cloudflare Workers aggressively pool outbound connections - After many requests to same host, pooled connections become stale - Reusing stale connection causes fetch() to hang indefinitely - AbortController doesn't reliably interrupt stuck pooled connections Fix: - Add unique `_nc` query param to each request URL - This forces potentially new connections, bypassing stale pool - Tradeoff: ~100-300ms extra latency per call (new TLS handshake) - Benefit: Eliminates hangs entirely in most cases https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
- Increased idle timeout from 30s to 45s per Grok's analysis - Added diagnostic info (model ID, content length) to timeout errors - Note: iteration 10 hang was likely caused by version rollout during test https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
AbortController only affects fetch(), not subsequent reader.read() calls. When the stream hangs mid-read, the abort signal doesn't interrupt it. Now each reader.read() is wrapped in Promise.race with a 45s timeout, ensuring mid-stream hangs are properly detected and trigger retries. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
The "task stopped unexpectedly" message was misleading users by suggesting CPU issues. Updated to correctly indicate API timeouts or network issues, and prompt them to tap Resume. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
- Add autoResume flag to TaskState and TaskRequest - Implement auto-resume in alarm handler (up to 10 attempts) - Add /automode (or /auto) command to toggle the setting - Show auto-resume status in /status command - Update error message to mention API timeouts instead of CPU When enabled, tasks automatically resume on timeout instead of requiring manual "Resume" button tap. Useful for long-running tasks with intermittent API timeouts. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
When resuming from checkpoint, the model would re-read rules and re-acknowledge the task instead of continuing implementation. This adds a [SYSTEM RESUME NOTICE] message to the conversation when loading a checkpoint, instructing the model to skip the acknowledgment phase and continue directly with implementation. Root cause: The skill prompt says "read rules and acknowledge", and the model follows that instruction on every resume. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
Auto-resume was failing for direct provider models (DeepSeek, DashScope, Moonshot) because the API keys weren't stored in TaskState and weren't passed to the reconstructed TaskRequest. Now stores dashscopeKey, moonshotKey, deepseekKey in TaskState and passes them through during auto-resume. https://claude.ai/code/session_01CoLZ1rPPP3Th81EGm55GAi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.