hermes - 💡(How to fix) Fix [i18n] Thai Translation: Guides Part a - automate-with-cron, automation-templates, aws-bedrock, build-a-hermes-plugin [1 participants]
ON THIS PAGE
Recommended Tools
×6Utilities matched from this issue’s tags and category — try them while you read without losing context.
GitHub issue graph ai analysis
Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.
The report is written in English Markdown for sharing and archival.
Helpful · Quick feedback
Error Message
gateway จะอ่าน config.yaml และใช้การตั้งค่า provider Bedrock เดียวกัน
Troubleshooting
"No API key found" / "No AWS credentials"
Hermes จะตรวจสอบ credentials ตามลำดับนี้:
AWS_BEARER_TOKEN_BEDROCKAWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEYAWS_PROFILE- EC2 instance metadata (IMDS)
- ECS container credentials
- Lambda execution role
หากไม่พบ credentials ใดๆ ให้รัน aws configure หรือแนบ IAM role เข้ากับ compute instance ของคุณ
"Invocation of model ID ... with on-demand throughput isn't supported"
ให้ใช้ inference profile ID (ที่ขึ้นต้นด้วย us. หรือ global.) แทนการใช้ foundation model ID แบบเปลือย ตัวอย่างเช่น:
- ❌
anthropic.claude-sonnet-4-6 - ✅
us.anthropic.claude-sonnet-4-6
"ThrottlingException"
คุณถึงขีดจำกัด rate limit ของ Bedrock ต่อ model แล้ว Hermes จะพยายาม retry โดยอัตโนมัติพร้อม backoff หากต้องการเพิ่มขีดจำกัด ให้ขอเพิ่ม quota ใน AWS Service Quotas console
📄 guides/build-a-hermes-plugin.md
sidebar_position: 9 sidebar_label: "Build a Plugin" title: "Build a Hermes Plugin" description: "Step-by-step guide to building a complete Hermes plugin with tools, hooks, data files, and skills"
Build a Hermes Plugin
คู่มือนี้จะพาคุณไปดูขั้นตอนการสร้าง Hermes plugin แบบสมบูรณ์ตั้งแต่เริ่มต้น คุณจะได้ plugin ที่ใช้งานได้จริงซึ่งมีเครื่องมือ (tools) หลายตัว, lifecycle hooks, data files ที่ถูกบรรจุมาพร้อมกัน, และ skill ที่รวมไว้แล้ว - ครอบคลุมทุกสิ่งที่ plugin system รองรับ
What you're building
plugin calculator ที่มีเครื่องมือสองตัว:
calculate- สำหรับประเมินนิพจน์ทางคณิตศาสตร์ (เช่น2**16,sqrt(144),pi * 5**2)unit_convert- สำหรับแปลงหน่วยระหว่างหน่วยต่างๆ (เช่น100 F → 37.78 C,5 km → 3.11 mi)
นอกจากนี้ยังมี hook ที่บันทึกการเรียกใช้ tool ทุกครั้ง และไฟล์ skill ที่ถูกรวมไว้
Step 1: Create the plugin directory
Root Cause
Investigate:
- Search the web for known issues with this error pattern
- Check if this correlates with any recent deployments or config changes
- Draft a triage summary with:
- Likely root cause
- Suggested first response steps
- Escalation recommendation (P1-P4)
Fix Action
Fix / Workaround
/cron add "every 6h" "Check the GitHub repository NousResearch/hermes-agent for:
- New issues opened in the last 6 hours
- New PRs opened or merged in the last 6 hours
- Any new releases
1. Run: gh pr list --repo NousResearch/hermes-agent --state merged --json number,title,files,mergedAt --limit 30
2. Filter to PRs merged in the last 7 days
3. For each merged PR, check if it modified:
- Tool schemas (tools/*.py) - may need docs/reference/tools-reference.md update
- CLI commands (hermes_cli/commands.py, hermes_cli/main.py) - may need docs/reference/cli-commands.md update
- Config options (hermes_cli/config.py) - may need docs/user-guide/configuration.md update
- Environment variables - may need docs/reference/environment-variables.md update
4. Cross-reference: for each code change, check if the corresponding docs page was also updated in the same PR
```bash
hermes webhook subscribe auto-port \
--events "pull_request" \
--prompt "PR merged in the source repository:
Repository: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Author: {pull_request.user.login}
Action: {action}
Merge commit: {pull_request.merge_commit_sha}Code Example
mkdir -p ~/.hermes/scripts
---
ตั้งค่า cron job:
---
:::tip ทริค [SILENT]
เมื่อการตอบกลับสุดท้ายของ agent มี `[SILENT]` การส่งมอบจะถูกระงับ นั่นหมายความว่าคุณจะได้รับการแจ้งเตือนก็ต่อเมื่อมีบางอย่างเกิดขึ้นจริงเท่านั้น - ไม่มีสแปมในช่วงเวลาที่เงียบสงบ
:::
---
## Pattern 2: Weekly Report
รวบรวมข้อมูลจากหลายแหล่งเข้าสู่สรุปที่จัดรูปแบบไว้ รูปแบบนี้จะทำงานสัปดาห์ละครั้งและส่งไปยังช่องหลักของคุณ
---
จาก CLI:
---
`0 9 * * 1` คือ cron expression มาตรฐาน: เวลา 9:00 น. ทุกวันจันทร์
---
## Pattern 3: GitHub Repository Watcher
เฝ้าดู repository สำหรับ issues, PRs, หรือ releases ใหม่
---
:::warning Prompt ที่มีเนื้อหาครบถ้วนด้วยตัวเอง
สังเกตว่า prompt ได้รวมคำสั่ง `gh` ที่แน่นอนไว้ Agent cron ไม่มีหน่วยความจำของการรันครั้งก่อนหน้าหรือความชอบของคุณ - ต้องระบุทุกอย่างให้ชัดเจน
:::
---
## Pattern 4: Data Collection Pipeline
สแกนข้อมูลในช่วงเวลาปกติ บันทึกเป็นไฟล์ และตรวจจับแนวโน้มเมื่อเวลาผ่านไป รูปแบบนี้รวมสคริปต์ (สำหรับการรวบรวม) เข้ากับ agent (สำหรับการวิเคราะห์)
---
---
สคริปต์ทำหน้าที่รวบรวมข้อมูลเชิงกลไก; ส่วน agent เพิ่มชั้นของการให้เหตุผล
---
## Pattern 5: Multi-Skill Workflow
เชื่อมโยงทักษะเข้าด้วยกันสำหรับงานที่กำหนดเวลาที่ซับซ้อน Skills จะถูกโหลดตามลำดับก่อนที่ prompt จะทำงาน
---
จากเครื่องมือโดยตรง:
---
Skills จะถูกโหลดตามลำดับ - `arxiv` ก่อน (สอน agent วิธีค้นหาบทความ) จากนั้น `obsidian` (สอนวิธีเขียนโน้ต) Prompt จะเชื่อมโยงทั้งหมดเข้าด้วยกัน
---
## การจัดการ Jobs ของคุณ
---
---
## เป้าหมายการส่งมอบ (Delivery Targets)
แฟล็ก `--deliver` ควบคุมว่าผลลัพธ์จะไปที่ใด:
| Target | Example | Use case |
|--------|---------|----------|
| `origin` | `--deliver origin` | แชทเดิมที่สร้าง job (ค่าเริ่มต้น) |
| `local` | `--deliver local` | บันทึกในไฟล์ท้องถิ่นเท่านั้น |
| `telegram` | `--deliver telegram` | ช่องหลัก Telegram ของคุณ |
| `discord` | `--deliver discord` | ช่องหลัก Discord ของคุณ |
| `slack` | `--deliver slack` | ช่องหลัก Slack ของคุณ |
| Specific chat | `--deliver telegram:-1001234567890` | กลุ่ม Telegram เฉพาะ |
| Threaded | `--deliver telegram:-1001234567890:17585` | หัวข้อ (topic) ของ Telegram เฉพาะ |
---
## เคล็ดลับ
**ทำให้ prompt มีเนื้อหาครบถ้วนด้วยตัวเอง (self-contained).** agent ใน cron job ไม่มีหน่วยความจำของการสนทนาของคุณ ต้องรวม URLs, ชื่อ repo, ความชอบในการจัดรูปแบบ, และคำแนะนำในการส่งมอบไว้ใน prompt โดยตรง
**ใช้ `[SILENT]` อย่างแพร่หลาย.** สำหรับงานเฝ้าติดตาม ควรใส่คำแนะนำเสมอว่า "หากไม่มีอะไรเปลี่ยนแปลง ให้ตอบกลับด้วย `[SILENT]`" สิ่งนี้จะป้องกันการแจ้งเตือนที่มากเกินไป
**ใช้สคริปต์สำหรับการรวบรวมข้อมูล.** พารามิเตอร์ `script` ช่วยให้สคริปต์ Python จัดการส่วนที่น่าเบื่อ (เช่น HTTP requests, file I/O, state tracking) agent จะเห็นเพียง stdout ของสคริปต์และนำไปใช้ในการให้เหตุผล ซึ่งมีค่าใช้จ่ายน้อยกว่าและเชื่อถือได้มากกว่าการให้ agent ดึงข้อมูลด้วยตัวเอง
**ทดสอบด้วย `/cron run`.** ก่อนรอให้กำหนดเวลาทำงาน ให้ใช้ `/cron run <job_id>` เพื่อดำเนินการทันทีและตรวจสอบว่าผลลัพธ์ถูกต้องหรือไม่
**นิพจน์กำหนดเวลา (Schedule expressions).** รูปแบบที่รองรับ: ความล่าช้าแบบสัมพัทธ์ (`30m`), ช่วงเวลา (`every 2h`), cron expression มาตรฐาน (`0 9 * * *`), และ ISO timestamps (`2025-06-15T09:00:00`) ภาษาธรรมชาติ เช่น `daily at 9am` ไม่รองรับ - ให้ใช้ `0 9 * * *` แทน
---
*สำหรับข้อมูลอ้างอิง cron ที่สมบูรณ์ - พารามิเตอร์ทั้งหมด, กรณีขอบ, และส่วนภายใน - โปรดดูที่ [Scheduled Tasks (Cron)](/docs/user-guide/features/cron).*
---
## 📄 guides/automation-templates.md
---
sidebar_position: 15
title: "Automation Templates"
description: "Ready-to-use automation recipes - scheduled tasks, GitHub event triggers, API webhooks, and multi-skill workflows"
---
# Automation Templates
ชุดคำสั่งสำเร็จรูปสำหรับรูปแบบการทำงานอัตโนมัติที่พบบ่อย แต่ละ Template ใช้ [cron scheduler](/docs/user-guide/features/cron) ที่มาพร้อมกับ Hermes สำหรับการทริกเกอร์ตามเวลา และ [webhook platform](/docs/user-guide/messaging/webhooks) สำหรับการทริกเกอร์ที่ขับเคลื่อนด้วยเหตุการณ์ (event-driven triggers)
ทุก Template สามารถทำงานกับ **โมเดลใดก็ได้** - ไม่ได้จำกัดอยู่แค่ Provider เดียว
:::tip Three Trigger Types
| Trigger | How | Tool |
|---------|-----|------|
| **Schedule** | Runs on a cadence (hourly, nightly, weekly) | `cronjob` tool or `/cron` slash command |
| **GitHub Event** | Fires on PR opens, pushes, issues, CI results | Webhook platform (`hermes webhook subscribe`) |
| **API Call** | External service POSTs JSON to your endpoint | Webhook platform (config.yaml routes or `hermes webhook subscribe`) |
ทั้งสามประเภทรองรับการส่งข้อมูลไปยัง Telegram, Discord, Slack, SMS, email, GitHub comments, หรือ local files
:::
---
## Development Workflow
### Nightly Backlog Triage
การติดป้ายกำกับ จัดลำดับความสำคัญ และสรุปปัญหาใหม่ทุกคืน ส่งสรุปไปยังช่องทางของทีมคุณ
**Trigger:** Schedule (nightly)
---
### Automatic PR Code Review
ตรวจสอบ Pull Request ทุกครั้งที่เปิดโดยอัตโนมัติ โพสต์ความคิดเห็นการตรวจสอบโดยตรงบน PR
**Trigger:** GitHub webhook
**Option A - Dynamic subscription (CLI):**
---
**Option B - Static route (config.yaml):**
---
จากนั้นใน GitHub: **Settings → Webhooks → Add webhook** → Payload URL: `http://your-server:8644/webhooks/github-pr-review`, Content type: `application/json`, Secret: `github-webhook-secret`, Events: **Pull requests**.
### Docs Drift Detection
การสแกนรายสัปดาห์ของ PR ที่ถูก merge เพื่อค้นหาการเปลี่ยนแปลง API ที่จำเป็นต้องอัปเดตเอกสาร
**Trigger:** Schedule (weekly)
---
### Dependency Security Audit
การสแกนรายวันเพื่อค้นหาช่องโหว่ที่ทราบใน Dependency ของโปรเจกต์
**Trigger:** Schedule (daily)
---
---
## DevOps & Monitoring
### Deploy Verification
ทริกเกอร์ smoke tests หลังจากการ Deploy ทุกครั้ง Pipeline CI/CD ของคุณจะ POST ไปยัง webhook เมื่อการ Deploy เสร็จสมบูรณ์
**Trigger:** API call (webhook)
---
Pipeline CI/CD ของคุณจะทริกเกอร์มัน:
---
### Alert Triage
การเชื่อมโยง Alert จากระบบ Monitoring กับการเปลี่ยนแปลงล่าสุดเพื่อร่างคำตอบ ทำงานร่วมกับ Datadog, PagerDuty, Grafana, หรือระบบ Alerting ใดๆ ที่สามารถ POST JSON ได้
**Trigger:** API call (webhook)
---
### Uptime Monitor
ตรวจสอบ Endpoints ทุก 30 นาที แจ้งเตือนเฉพาะเมื่อมีบางอย่างล่มเท่านั้น
**Trigger:** Schedule (every 30 min)
---
---
---
## Research & Intelligence
### Competitive Repository Scout
ตรวจสอบ Repository ของคู่แข่งเพื่อหา PR, ฟีเจอร์, และการตัดสินใจด้านสถาปัตยกรรมที่น่าสนใจ
**Trigger:** Schedule (daily)
---
### AI News Digest
สรุปข่าว AI/ML ประจำสัปดาห์
**Trigger:** Schedule (weekly)
---
### Paper Digest with Notes
การสแกน arXiv รายวันที่บันทึกสรุปไปยังระบบจดบันทึกของคุณ
**Trigger:** Schedule (daily)
---
---
## GitHub Event Automations
### Issue Auto-Labeling
ติดป้ายกำกับและตอบกลับ Issue ใหม่โดยอัตโนมัติ
**Trigger:** GitHub webhook
---
### CI Failure Analysis
วิเคราะห์ความล้มเหลวของ CI และโพสต์การวินิจฉัยบน PR
**Trigger:** GitHub webhook
---
### Auto-Port Changes Across Repos
เมื่อ PR ถูก merge ใน Repo หนึ่ง ให้ทำการ Port การเปลี่ยนแปลงที่เทียบเท่าไปยัง Repo อื่นโดยอัตโนมัติ
**Trigger:** GitHub webhook
---
---
## Business Operations
### Stripe Payment Monitoring
ติดตามเหตุการณ์การชำระเงินและรับสรุปความล้มเหลว
**Trigger:** API call (webhook)
---
### Daily Revenue Summary
รวบรวมตัวชี้วัดทางธุรกิจที่สำคัญทุกเช้า
**Trigger:** Schedule (daily)
---
---
## Multi-Skill Workflows
### Security Audit Pipeline
รวมหลาย Skills เข้าด้วยกันเพื่อการตรวจสอบความปลอดภัยประจำสัปดาห์ที่ครอบคลุม
**Trigger:** Schedule (weekly)
---
### Content Pipeline
การวิจัย ร่าง และเตรียมเนื้อหาตามกำหนดเวลา
**Trigger:** Schedule (weekly)
---
---
## Quick Reference
### Cron Schedule Syntax
| Expression | Meaning |
|-----------|---------|
| `every 30m` | ทุก 30 นาที |
| `every 2h` | ทุก 2 ชั่วโมง |
| `0 2 * * *` | ทุกวัน เวลา 02:00 น. |
| `0 9 * * 1` | ทุกวันจันทร์ เวลา 09:00 น. |
| `0 9 * * 1-5` | วันธรรมดา เวลา 09:00 น. |
| `0 3 * * 0` | ทุกวันอาทิตย์ เวลา 03:00 น. |
| `0 */6 * * *` | ทุก 6 ชั่วโมง |
### Delivery Targets
| Target | Flag | Notes |
|--------|------|-------|
| Same chat | `--deliver origin` | ค่าเริ่มต้น - ส่งไปยังที่ที่สร้าง Job |
| Local file | `--deliver local` | บันทึก Output โดยไม่มีการแจ้งเตือน |
| Telegram | `--deliver telegram` | ช่องหลัก หรือ `telegram:CHAT_ID` สำหรับเฉพาะเจาะจง |
| Discord | `--deliver discord` | ช่องหลัก หรือ `discord:CHANNEL_ID` |
| Slack | `--deliver slack` | ช่องหลัก |
| SMS | `--deliver sms:+15551234567` | ส่งตรงไปยังหมายเลขโทรศัพท์ |
| Specific thread | `--deliver telegram:-100123:456` | หัวข้อ (topic) ใน Telegram |
### Webhook Template Variables
| Variable | Description |
|----------|-------------|
| `{pull_request.title}` | ชื่อ PR |
| `{issue.number}` | หมายเลข Issue |
| `{repository.full_name}` | `owner/repo` |
| `{action}` | การกระทำของ Event (opened, closed, etc.) |
| `{__raw__}` | Payload JSON เต็ม (ถูกตัดทอนที่ 4000 ตัวอักษร) |
| `{sender.login}` | ผู้ใช้ GitHub ที่ทริกเกอร์ Event |
### The [SILENT] Pattern
เมื่อ Response ของ cron job มีข้อความ `[SILENT]` การส่งข้อมูลจะถูกระงับ ใช้สิ่งนี้เพื่อหลีกเลี่ยงการแจ้งเตือนสแปมในการรันที่เงียบ:
---
นั่นหมายความว่าคุณจะได้รับการแจ้งเตือนก็ต่อเมื่อ Agent มีข้อมูลที่ต้องรายงานเท่านั้น.
---
## 📄 guides/aws-bedrock.md
---
sidebar_position: 14
title: "AWS Bedrock"
description: "Use Hermes Agent with Amazon Bedrock - native Converse API, IAM authentication, Guardrails, and cross-region inference"
---
# AWS Bedrock
Hermes Agent รองรับ Amazon Bedrock ในฐานะ native provider โดยใช้ **Converse API** - ไม่ใช่ endpoint ที่เข้ากันได้กับ OpenAI สิ่งนี้ช่วยให้คุณเข้าถึงระบบนิเวศของ Bedrock ได้อย่างเต็มที่: IAM authentication, Guardrails, cross-region inference profiles, และ foundation models ทั้งหมด
## Prerequisites
- **AWS credentials** - แหล่งที่มาใดๆ ที่รองรับโดย [boto3 credential chain](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html):
- IAM instance role (EC2, ECS, Lambda - zero config)
- `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` environment variables
- `AWS_PROFILE` สำหรับ SSO หรือ named profiles
- `aws configure` สำหรับการพัฒนาในเครื่อง (local development)
- **boto3** - ติดตั้งด้วย `pip install hermes-agent[bedrock]`
- **IAM permissions** - อย่างน้อยที่สุด:
- `bedrock:InvokeModel` และ `bedrock:InvokeModelWithResponseStream` (สำหรับการทำ inference)
- `bedrock:ListFoundationModels` และ `bedrock:ListInferenceProfiles` (สำหรับการค้นหา model)
:::tip EC2 / ECS / Lambda
บน AWS compute ให้แนบ IAM role ที่มี `AmazonBedrockFullAccess` ก็เสร็จเรียบร้อยแล้ว ไม่ต้องใช้ API keys ไม่ต้องตั้งค่า `.env` - Hermes จะตรวจจับ instance role โดยอัตโนมัติ
:::
## Quick Start
---
## Configuration
หลังจากรัน `hermes model` ไฟล์ `~/.hermes/config.yaml` ของคุณจะมีเนื้อหาดังนี้:
---
### Region
ตั้งค่า AWS region ด้วยวิธีใดวิธีหนึ่งต่อไปนี้ (เรียงตามลำดับความสำคัญสูงสุด):
1. `bedrock.region` ใน `config.yaml`
2. `AWS_REGION` environment variable
3. `AWS_DEFAULT_REGION` environment variable
4. ค่าเริ่มต้น: `us-east-1`
### Guardrails
ในการใช้ [Amazon Bedrock Guardrails](https://docs.aws.amazon.com/bedrock/latest/userguide/guardrails.html) กับการเรียกใช้ model ทั้งหมด:
---
### Model Discovery
Hermes จะค้นหา model ที่พร้อมใช้งานโดยอัตโนมัติผ่าน Bedrock control plane คุณสามารถปรับแต่งการค้นหาได้:
---
## Available Models
Bedrock models ใช้ **inference profile IDs** สำหรับการเรียกใช้งานแบบ on-demand ตัวเลือก `hermes model` จะแสดงสิ่งเหล่านี้โดยอัตโนมัติ โดยมีโมเดลแนะนำอยู่ด้านบน:
| Model | ID | Notes |
|-------|-----|-------|
| Claude Sonnet 4.6 | `us.anthropic.claude-sonnet-4-6` | แนะนำ - ความสมดุลที่ดีที่สุดระหว่างความเร็วและความสามารถ |
| Claude Opus 4.6 | `us.anthropic.claude-opus-4-6-v1` | มีความสามารถสูงสุด |
| Claude Haiku 4.5 | `us.anthropic.claude-haiku-4-5-20251001-v1:0` | Claude ที่เร็วที่สุด |
| Amazon Nova Pro | `us.amazon.nova-pro-v1:0` | โมเดลเรือธงของ Amazon |
| Amazon Nova Micro | `us.amazon.nova-micro-v1:0` | เร็วที่สุดและราคาถูกที่สุด |
| DeepSeek V3.2 | `deepseek.v3.2` | โมเดล open source ที่แข็งแกร่ง |
| Llama 4 Scout 17B | `us.meta.llama4-scout-17b-instruct-v1:0` | ล่าสุดจาก Meta |
:::info Cross-Region Inference
โมเดลที่ขึ้นต้นด้วย `us.` ใช้ cross-region inference profiles ซึ่งให้ capacity ที่ดีกว่าและมีการ failover อัตโนมัติข้าม AWS regions ส่วนโมเดลที่ขึ้นต้นด้วย `global.` จะถูกกำหนดเส้นทางข้ามทุก regions ที่พร้อมใช้งานทั่วโลก
:::
## Switching Models Mid-Session
ใช้คำสั่ง `/model` ระหว่างการสนทนา:
---
## Diagnostics
---
doctor จะตรวจสอบ:
- ว่ามี AWS credentials หรือไม่ (env vars, IAM role, SSO)
- ว่าติดตั้ง `boto3` แล้วหรือไม่
- ว่าสามารถเข้าถึง Bedrock API ได้หรือไม่ (ListFoundationModels)
- จำนวน model ที่พร้อมใช้งานใน region ของคุณ
## Gateway (Messaging Platforms)
Bedrock ทำงานร่วมกับทุกแพลตฟอร์ม gateway ของ Hermes (Telegram, Discord, Slack, Feishu, ฯลฯ) ให้ตั้งค่า Bedrock เป็น provider ของคุณ จากนั้นจึงเริ่ม gateway ตามปกติ:
---
gateway จะอ่าน `config.yaml` และใช้การตั้งค่า provider Bedrock เดียวกัน
## Troubleshooting
### "No API key found" / "No AWS credentials"
Hermes จะตรวจสอบ credentials ตามลำดับนี้:
1. `AWS_BEARER_TOKEN_BEDROCK`
2. `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`
3. `AWS_PROFILE`
4. EC2 instance metadata (IMDS)
5. ECS container credentials
6. Lambda execution role
หากไม่พบ credentials ใดๆ ให้รัน `aws configure` หรือแนบ IAM role เข้ากับ compute instance ของคุณ
### "Invocation of model ID ... with on-demand throughput isn't supported"
ให้ใช้ **inference profile ID** (ที่ขึ้นต้นด้วย `us.` หรือ `global.`) แทนการใช้ foundation model ID แบบเปลือย ตัวอย่างเช่น:
- ❌ `anthropic.claude-sonnet-4-6`
- ✅ `us.anthropic.claude-sonnet-4-6`
### "ThrottlingException"
คุณถึงขีดจำกัด rate limit ของ Bedrock ต่อ model แล้ว Hermes จะพยายาม retry โดยอัตโนมัติพร้อม backoff หากต้องการเพิ่มขีดจำกัด ให้ขอเพิ่ม quota ใน [AWS Service Quotas console](https://console.aws.amazon.com/servicequotas/)
---
## 📄 guides/build-a-hermes-plugin.md
---
sidebar_position: 9
sidebar_label: "Build a Plugin"
title: "Build a Hermes Plugin"
description: "Step-by-step guide to building a complete Hermes plugin with tools, hooks, data files, and skills"
---
# Build a Hermes Plugin
คู่มือนี้จะพาคุณไปดูขั้นตอนการสร้าง Hermes plugin แบบสมบูรณ์ตั้งแต่เริ่มต้น คุณจะได้ plugin ที่ใช้งานได้จริงซึ่งมีเครื่องมือ (tools) หลายตัว, lifecycle hooks, data files ที่ถูกบรรจุมาพร้อมกัน, และ skill ที่รวมไว้แล้ว - ครอบคลุมทุกสิ่งที่ plugin system รองรับ
## What you're building
plugin **calculator** ที่มีเครื่องมือสองตัว:
- `calculate` - สำหรับประเมินนิพจน์ทางคณิตศาสตร์ (เช่น `2**16`, `sqrt(144)`, `pi * 5**2`)
- `unit_convert` - สำหรับแปลงหน่วยระหว่างหน่วยต่างๆ (เช่น `100 F → 37.78 C`, `5 km → 3.11 mi`)
นอกจากนี้ยังมี hook ที่บันทึกการเรียกใช้ tool ทุกครั้ง และไฟล์ skill ที่ถูกรวมไว้
## Step 1: Create the plugin directory
---
## Step 2: Write the manifest
สร้างไฟล์ `plugin.yaml`:
---
สิ่งนี้บอก Hermes ว่า: "ฉันคือ plugin ชื่อ calculator, ฉันมี tools และ hooks ให้บริการ" ฟิลด์ `provides_tools` และ `provides_hooks` คือรายการสิ่งที่ plugin ลงทะเบียน
ฟิลด์ทางเลือกที่คุณสามารถเพิ่มได้:
---
## Step 3: Write the tool schemas
สร้างไฟล์ `schemas.py` - นี่คือสิ่งที่ LLM ใช้ในการตัดสินใจว่าจะเรียกใช้ tool ของคุณเมื่อใด:
---
**ทำไม schemas ถึงสำคัญ:** ฟิลด์ `description` คือวิธีที่ LLM ตัดสินใจว่าจะใช้ tool ของคุณเมื่อใด คุณต้องระบุให้ชัดเจนว่ามันทำอะไรและเมื่อไหร่ ส่วน `parameters` จะกำหนดว่า LLM จะส่ง arguments อะไรมา
## Step 4: Write the tool handlers
สร้างไฟล์ `tools.py` - นี่คือโค้ดที่ทำงานจริงเมื่อ LLM เรียกใช้ tool ของคุณ:
---
**กฎสำคัญสำหรับ handlers:**
1. **Signature:** `def my_handler(args: dict, **kwargs) -> str`
2. **Return:** ต้องเป็น JSON string เสมอ ทั้งกรณีสำเร็จและกรณีเกิดข้อผิดพลาด
3. **Never raise:** ต้องดักจับทุก Exception และส่งคืน error JSON แทน
4. **Accept `**kwargs`:** Hermes อาจส่ง context เพิ่มเติมในอนาคต
## Step 5: Write the registration
สร้างไฟล์ `__init__.py` - นี่คือส่วนที่เชื่อม schemas เข้ากับ handlers:
---
**สิ่งที่ `register()` ทำ:**
- ถูกเรียกใช้เพียงครั้งเดียวเมื่อเริ่มต้นระบบ
- `ctx.register_tool()` นำ tool ของคุณเข้าสู่ registry — model จะเห็นมันทันที
- `ctx.register_hook()` สมัครรับการแจ้งเตือนเหตุการณ์ (lifecycle events)
- `ctx.register_cli_command()` ลงทะเบียน subcommand สำหรับ CLI (เช่น `hermes my-plugin <subcommand>`)
- หากฟังก์ชันนี้ล้มเหลว plugin จะถูกปิดการใช้งาน แต่ Hermes จะยังคงทำงานได้ตามปกติ
## Step 6: Test it
เริ่ม Hermes:
---
คุณควรเห็น `calculator: calculate, unit_convert` ในรายการ tool ของ banner
ลองใช้ prompt เหล่านี้:
---
ตรวจสอบสถานะ plugin:
---
Output:
---
## Your plugin's final structure
---
สี่ไฟล์ที่แยกส่วนอย่างชัดเจน:
- **Manifest** ประกาศว่า plugin คืออะไร
- **Schemas** อธิบาย tools สำหรับ LLM
- **Handlers** ใช้งาน logic จริง
- **Registration** เชื่อมทุกอย่างเข้าด้วยกัน
## What else can plugins do?
### Ship data files
ใส่ไฟล์ใดๆ ใน directory ของ plugin และอ่านมันเมื่อ import:
---
### Bundle skills
Plugins สามารถส่งไฟล์ skill ที่ agent โหลดผ่าน `skill_view("plugin:skill")` ลงทะเบียนพวกมันใน `__init__.py` ของคุณ:
---
---
ตอนนี้ agent สามารถโหลด skill ของคุณด้วยชื่อที่ระบุ namespace:
---
**คุณสมบัติสำคัญ:**
- Plugin skills เป็นแบบ **read-only** — พวกมันจะไม่ถูกใส่ใน `~/.hermes/skills/` และไม่สามารถแก้ไขผ่าน `skill_manage` ได้
- Plugin skills จะ **ไม่** ถูกแสดงใน index `<available_skills>` ของ system prompt — พวกมันต้องโหลดแบบ explicit opt-in
- ชื่อ skill แบบเปลือย (Bare skill names) จะไม่ได้รับผลกระทบ — namespace ป้องกันการชนกับ built-in skills
- เมื่อ agent โหลด plugin skill จะมีการเพิ่ม banner context ที่ระบุ sibling skills จาก plugin เดียวกัน
:::tip Legacy pattern
รูปแบบเก่าที่ใช้ `shutil.copy2` (การคัดลอก skill เข้าไปใน `~/.hermes/skills/`) ยังคงใช้งานได้ แต่มีความเสี่ยงที่จะเกิด name collision กับ built-in skills ควรใช้ `ctx.register_skill()` สำหรับ plugin ใหม่
:::
### Gate on environment variables
หาก plugin ของคุณต้องการ API key:
---
หาก `WEATHER_API_KEY` ไม่ได้ถูกตั้งค่า plugin จะถูกปิดการใช้งานพร้อมข้อความที่ชัดเจน ไม่เกิด crash และไม่มี error ใน agent — เพียงแค่ "Plugin weather disabled (missing: WEATHER_API_KEY)"
เมื่อผู้ใช้รัน `hermes plugins install` พวกเขาจะถูก **prompt แบบโต้ตอบ** สำหรับ `requires_env` ที่ขาดหายไป ค่าต่างๆ จะถูกบันทึกใน `.env` โดยอัตโนมัติ
เพื่อให้ประสบการณ์การติดตั้งดีขึ้น ให้ใช้ rich format พร้อม description และ URL สำหรับการลงทะเบียน:
---
| Field | Required | Description |
|-------|----------|-------------|
| `name` | Yes | ชื่อ environment variable |
| `description` | No | แสดงให้ผู้ใช้เห็นระหว่าง prompt การติดตั้ง |
| `url` | No | ที่ที่สามารถรับ credential ได้ |
| `secret` | No | ถ้าเป็น `true` input จะถูกซ่อน (เหมือนช่องรหัสผ่าน) |
ทั้งสองรูปแบบสามารถผสมกันในรายการเดียวกันได้ ตัวแปรที่ตั้งค่าไว้แล้วจะถูกข้ามไปอย่างเงียบๆ
### Conditional tool availability
สำหรับ tools ที่ขึ้นอยู่กับ libraries ทางเลือก:
---
### Register multiple hooks
---
### Hook reference
แต่ละ hook มีการบันทึกรายละเอียดทั้งหมดใน **[Event Hooks reference](/docs/user-guide/features/hooks#plugin-hooks)** — signature ของ callback, ตารางพารามิเตอร์, เวลาที่เรียกใช้ที่แน่นอน, และตัวอย่าง นี่คือสรุป:
| Hook | Fires when | Callback signature | Returns |
|------|-----------|-------------------|---------|
| [`pre_tool_call`](/docs/user-guide/features/hooks#pre_tool_call) | ก่อนที่ tool ใดๆ จะทำงาน | `tool_name: str, args: dict, task_id: str` | ignored |
| [`post_tool_call`](/docs/user-guide/features/hooks#post_tool_call) | หลังที่ tool ใดๆ ส่งคืนผลลัพธ์ | `tool_name: str, args: dict, result: str, task_id: str` | ignored |
| [`pre_llm_call`](/docs/user-guide/features/hooks#pre_llm_call) | ครั้งเดียวต่อ turn, ก่อน loop การเรียก tool | `session_id: str, user_message: str, conversation_history: list, is_first_turn: bool, model: str, platform: str` | [context injection](#pre_llm_call-context-injection) |
| [`post_llm_call`](/docs/user-guide/features/hooks#post_llm_call) | ครั้งเดียวต่อ turn, หลัง loop การเรียก tool (เฉพาะ turn ที่สำเร็จ) | `session_id: str, user_message: str, assistant_response: str, conversation_history: list, model: str, platform: str` | ignored |
| [`on_session_start`](/docs/user-guide/features/hooks#on_session_start) | สร้าง session ใหม่ (เฉพาะ turn แรก) | `session_id: str, model: str, platform: str` | ignored |
| [`on_session_end`](/docs/user-guide/features/hooks#on_session_end) | สิ้นสุดการเรียก `run_conversation` ทุกครั้ง + CLI exit | `session_id: str, completed: bool, interrupted: bool, model: str, platform: str` | ignored |
| [`on_session_finalize`](/docs/user-guide/features/hooks#on_session_finalize) | CLI/gateway ปิด session ที่ใช้งานอยู่ | `session_id: str \| None, platform: str` | ignored |
| [`on_session_reset`](/docs/user-guide/features/hooks#on_session_reset) | Gateway สลับ key session ใหม่ (`/new`, `/reset`) | `session_id: str, platform: str` | ignored |
Hook ส่วนใหญ่เป็นแบบ observer ที่ทำงานแล้วจบไป — ค่าที่ส่งคืนจะถูกละเลย ยกเว้น `pre_llm_call` ซึ่งสามารถ inject context เข้าไปใน conversation ได้
Callback ทั้งหมดควรรับ `**kwargs` เพื่อรองรับการเปลี่ยนแปลงในอนาคต หาก hook callback ล้มเหลว จะถูกบันทึกและข้ามไป ส่วน hook อื่นๆ และ agent จะยังคงทำงานตามปกติ
### `pre_llm_call` context injection
นี่คือ hook เดียวที่ค่าที่ส่งคืนมีความสำคัญ เมื่อ callback `pre_llm_call` ส่งคืน dict ที่มี key `"context"` (หรือ plain string) Hermes จะ inject ข้อความนั้นเข้าไปใน **user message ของ turn ปัจจุบัน** นี่คือกลไกสำหรับ memory plugins, RAG integrations, guardrails, และ plugin ใดๆ ที่ต้องการให้ context เพิ่มเติมแก่ model
#### Return format
---
ค่าที่ส่งคืนที่ไม่ใช่ None และไม่ว่างเปล่า พร้อม key `"context"` (หรือ plain string ที่ไม่ว่างเปล่า) จะถูกรวบรวมและต่อท้าย user message สำหรับ turn ปัจจุบัน
#### How injection works
Context ที่ถูก inject จะถูกต่อท้าย **user message** ไม่ใช่ system prompt นี่คือการออกแบบที่จงใจ:
- **Prompt cache preservation** — system prompt จะคงที่ตลอดทุก turn Anthropic และ OpenRouter จะ cache system prompt prefix ดังนั้นการรักษาความเสถียรจึงช่วยประหยัด input tokens ได้กว่า 75%+ ในการสนทนาหลาย turn หาก plugins แก้ไข system prompt ทุก turn จะกลายเป็น cache miss
- **Ephemeral** — การ inject เกิดขึ้นเฉพาะเวลาเรียก API เท่านั้น user message เดิมใน conversation history จะไม่ถูกแก้ไข และไม่มีอะไรถูกบันทึกใน session database
- **The system prompt is Hermes's territory** — มันมีคำแนะนำเฉพาะ model, rules การบังคับใช้ tool, คำแนะนำด้านบุคลิกภาพ, และเนื้อหา skill ที่ถูก cache Plugins จะให้ context ควบคู่ไปกับ input ของผู้ใช้ ไม่ใช่การเปลี่ยนแปลงคำแนะนำหลักของ agent
#### Example: Memory recall plugin
---
#### Example: Guardrails plugin
---
#### Example: Observer-only hook (no injection)
---
#### Multiple plugins returning context
เมื่อหลาย plugin ส่ง context จาก `pre_llm_call` ผลลัพธ์ของพวกมันจะถูกรวมด้วย double newlines และต่อท้าย user message ด้วยกัน ลำดับจะเป็นไปตามลำดับการค้นพบ plugin (ตามตัวอักษรของชื่อ directory plugin)
### Register CLI commands
Plugins สามารถเพิ่ม subcommand tree ของตัวเองได้:
---
หลังจากลงทะเบียนแล้ว ผู้ใช้สามารถรัน `hermes my-plugin status`, `hermes my-plugin config` ฯลฯ
**Memory provider plugins** ใช้แนวทางแบบ convention-based แทน: เพิ่มฟังก์ชัน `register_cli(subparser)` ไปยังไฟล์ `cli.py` ของ plugin ของคุณ ระบบการค้นหา memory plugin จะหาเจอโดยอัตโนมัติ — ไม่จำเป็นต้องเรียก `ctx.register_cli_command()` ดูรายละเอียดได้ที่ [Memory Provider Plugin guide](/docs/developer-guide/memory-provider-plugin#adding-cli-commands)
**Active-provider gating:** คำสั่ง CLI ของ Memory plugin จะปรากฏก็ต่อเมื่อ provider นั้นเป็น `memory.provider` ที่ใช้งานอยู่ใน config เท่านั้น หากผู้ใช้ยังไม่ได้ตั้งค่า provider ของคุณ คำสั่ง CLI ของคุณจะไม่ทำให้ output help ดูรก
### Register slash commands
Plugins สามารถลงทะเบียน slash commands ใน session ได้ — คำสั่งที่ผู้ใช้พิมพ์ระหว่างการสนทนา (เช่น `/lcm status` หรือ `/ping`) สิ่งเหล่านี้ใช้ได้ทั้งใน CLI และ gateway (Telegram, Discord, ฯลฯ)
---
หลังจากลงทะเบียนแล้ว ผู้ใช้สามารถพิมพ์ `/mystatus` ใน session ใดก็ได้ คำสั่งจะปรากฏใน autocomplete, `/help` output, และเมนู bot ของ Telegram
**Signature:** `ctx.register_command(name: str, handler: Callable, description: str = "")`
| Parameter | Type | Description |
|-----------|------|-------------|
| `name` | `str` | ชื่อคำสั่งโดยไม่มีเครื่องหมาย slash นำหน้า (เช่น `"lcm"`, `"mystatus"`) |
| `handler` | `Callable[[str], str \| None]` | ถูกเรียกด้วย raw argument string อาจเป็น `async` ได้ |
| `description` | `str` | แสดงใน `/help`, autocomplete, และเมนู bot ของ Telegram |
**ความแตกต่างที่สำคัญจาก `register_cli_command()`:**
| | `register_command()` | `register_cli_command()` |
|---|---|---|
| Invoked as | `/name` ใน session | `hermes name` ใน terminal |
| Where it works | CLI sessions, Telegram, Discord, etc. | Terminal only |
| Handler receives | Raw args string | argparse `Namespace` |
| Use case | Diagnostics, status, quick actions | Complex subcommand trees, setup wizards |
**Conflict protection:** หาก plugin พยายามลงทะเบียนชื่อที่ขัดแย้งกับคำสั่ง built-in (`help`, `model`, `new`, ฯลฯ) การลงทะเบียนจะถูกปฏิเสธอย่างเงียบๆ พร้อมคำเตือน log คำสั่ง built-in จะมีลำดับความสำคัญเสมอ
**Async handlers:** Gateway dispatch จะตรวจจับและรอ async handlers โดยอัตโนมัติ ดังนั้นคุณสามารถใช้ได้ทั้ง sync หรือ async functions:
---
:::tip
คู่มือนี้ครอบคลุม **general plugins** (tools, hooks, slash commands, CLI commands) สำหรับ plugin ประเภทเฉพาะทาง โปรดดูที่:
- [Memory Provider Plugins](/docs/developer-guide/memory-provider-plugin) — cross-session knowledge backends
- [Context Engine Plugins](/docs/developer-guide/context-engine-plugin) — alternative context management strategies
:::
### Distribute via pip
สำหรับการแชร์ plugin สาธารณะ ให้เพิ่ม entry point ใน Python package ของคุณ:
---
---
## Common mistakes
**Handler doesn't return JSON string:**
---
**Missing `**kwargs` in handler signature:**
---
**Handler raises exceptions:**
---
**Schema description too vague:**RAW_BUFFERClick to expand / collapse
📄 guides/automate-with-cron.md
sidebar_position: 11 title: "ทำให้ทุกอย่างเป็นอัตโนมัติด้วย Cron" description: "รูปแบบการทำงานอัตโนมัติในโลกจริงโดยใช้ Hermes cron - การเฝ้าติดตาม, รายงาน, pipeline, และเวิร์กโฟลว์หลายทักษะ"
ทำให้ทุกอย่างเป็นอัตโนมัติด้วย Cron
บทช่วยสอน daily briefing bot tutorial ครอบคลุมพื้นฐาน คู่มือนี้จะเจาะลึกยิ่งขึ้น - รูปแบบการทำงานอัตโนมัติในโลกจริง 5 รูปแบบที่คุณสามารถปรับใช้กับเวิร์กโฟลว์ของคุณเองได้
สำหรับข้อมูลอ้างอิงคุณสมบัติทั้งหมด โปรดดูที่ Scheduled Tasks (Cron)
:::info แนวคิดหลัก Cron jobs ทำงานในเซสชัน agent ใหม่โดยไม่มีความจำของการแชทปัจจุบันของคุณ Prompt ต้อง มีเนื้อหาครบถ้วนด้วยตัวเอง - ต้องรวมทุกสิ่งที่ agent จำเป็นต้องรู้ :::
Pattern 1: Website Change Monitor
เฝ้าดู URL เพื่อหาการเปลี่ยนแปลง และได้รับการแจ้งเตือนเมื่อมีบางอย่างแตกต่างออกไปเท่านั้น
พารามิเตอร์ script คืออาวุธลับในส่วนนี้ สคริปต์ Python จะทำงานก่อนการรันแต่ละครั้ง และ stdout ของมันจะกลายเป็นบริบทสำหรับ agent สคริปต์จะจัดการงานเชิงกลไก (เช่น การดึงข้อมูล, การเปรียบเทียบความแตกต่าง); ส่วน agent จะจัดการการให้เหตุผล (การเปลี่ยนแปลงนี้น่าสนใจหรือไม่?)
สร้างสคริปต์เฝ้าติดตาม:
mkdir -p ~/.hermes/scriptsimport hashlib, json, os, urllib.request
URL = "https://example.com/pricing"
STATE_FILE = os.path.expanduser("~/.hermes/scripts/.watch-site-state.json")
# Fetch current content
req = urllib.request.Request(URL, headers={"User-Agent": "Hermes-Monitor/1.0"})
content = urllib.request.urlopen(req, timeout=30).read().decode()
current_hash = hashlib.sha256(content.encode()).hexdigest()
# Load previous state
prev_hash = None
if os.path.exists(STATE_FILE):
with open(STATE_FILE) as f:
prev_hash = json.load(f).get("hash")
# Save current state
with open(STATE_FILE, "w") as f:
json.dump({"hash": current_hash, "url": URL}, f)
# Output for the agent
if prev_hash and prev_hash != current_hash:
print(f"CHANGE DETECTED on {URL}")
print(f"Previous hash: {prev_hash}")
print(f"Current hash: {current_hash}")
print(f"\nCurrent content (first 2000 chars):\n{content[:2000]}")
else:
print("NO_CHANGE")ตั้งค่า cron job:
/cron add "every 1h" "If the script output says CHANGE DETECTED, summarize what changed on the page and why it might matter. If it says NO_CHANGE, respond with just [SILENT]." --script ~/.hermes/scripts/watch-site.py --name "Pricing monitor" --deliver telegram:::tip ทริค [SILENT]
เมื่อการตอบกลับสุดท้ายของ agent มี [SILENT] การส่งมอบจะถูกระงับ นั่นหมายความว่าคุณจะได้รับการแจ้งเตือนก็ต่อเมื่อมีบางอย่างเกิดขึ้นจริงเท่านั้น - ไม่มีสแปมในช่วงเวลาที่เงียบสงบ
:::
Pattern 2: Weekly Report
รวบรวมข้อมูลจากหลายแหล่งเข้าสู่สรุปที่จัดรูปแบบไว้ รูปแบบนี้จะทำงานสัปดาห์ละครั้งและส่งไปยังช่องหลักของคุณ
/cron add "0 9 * * 1" "Generate a weekly report covering:
1. Search the web for the top 5 AI news stories from the past week
2. Search GitHub for trending repositories in the 'machine-learning' topic
3. Check Hacker News for the most discussed AI/ML posts
Format as a clean summary with sections for each source. Include links.
Keep it under 500 words - highlight only what matters." --name "Weekly AI digest" --deliver telegramจาก CLI:
hermes cron create "0 9 * * 1" \
"Generate a weekly report covering the top AI news, trending ML GitHub repos, and most-discussed HN posts. Format with sections, include links, keep under 500 words." \
--name "Weekly AI digest" \
--deliver telegram0 9 * * 1 คือ cron expression มาตรฐาน: เวลา 9:00 น. ทุกวันจันทร์
Pattern 3: GitHub Repository Watcher
เฝ้าดู repository สำหรับ issues, PRs, หรือ releases ใหม่
/cron add "every 6h" "Check the GitHub repository NousResearch/hermes-agent for:
- New issues opened in the last 6 hours
- New PRs opened or merged in the last 6 hours
- Any new releases
Use the terminal to run gh commands:
gh issue list --repo NousResearch/hermes-agent --state open --json number,title,author,createdAt --limit 10
gh pr list --repo NousResearch/hermes-agent --state all --json number,title,author,createdAt,mergedAt --limit 10
Filter to only items from the last 6 hours. If nothing new, respond with [SILENT].
Otherwise, provide a concise summary of the activity." --name "Repo watcher" --deliver discord:::warning Prompt ที่มีเนื้อหาครบถ้วนด้วยตัวเอง
สังเกตว่า prompt ได้รวมคำสั่ง gh ที่แน่นอนไว้ Agent cron ไม่มีหน่วยความจำของการรันครั้งก่อนหน้าหรือความชอบของคุณ - ต้องระบุทุกอย่างให้ชัดเจน
:::
Pattern 4: Data Collection Pipeline
สแกนข้อมูลในช่วงเวลาปกติ บันทึกเป็นไฟล์ และตรวจจับแนวโน้มเมื่อเวลาผ่านไป รูปแบบนี้รวมสคริปต์ (สำหรับการรวบรวม) เข้ากับ agent (สำหรับการวิเคราะห์)
import json, os, urllib.request
from datetime import datetime
DATA_DIR = os.path.expanduser("~/.hermes/data/prices")
os.makedirs(DATA_DIR, exist_ok=True)
# Fetch current data (example: crypto prices)
url = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum&vs_currencies=usd"
data = json.loads(urllib.request.urlopen(url, timeout=30).read())
# Append to history file
entry = {"timestamp": datetime.now().isoformat(), "prices": data}
history_file = os.path.join(DATA_DIR, "history.jsonl")
with open(history_file, "a") as f:
f.write(json.dumps(entry) + "\n")
# Load recent history for analysis
lines = open(history_file).readlines()
recent = [json.loads(l) for l in lines[-24:]] # Last 24 data points
# Output for the agent
print(f"Current: BTC=${data['bitcoin']['usd']}, ETH=${data['ethereum']['usd']}")
print(f"Data points collected: {len(lines)} total, showing last {len(recent)}")
print(f"\nRecent history:")
for r in recent[-6:]:
print(f" {r['timestamp']}: BTC=${r['prices']['bitcoin']['usd']}, ETH=${r['prices']['ethereum']['usd']}")/cron add "every 1h" "Analyze the price data from the script output. Report:
1. Current prices
2. Trend direction over the last 6 data points (up/down/flat)
3. Any notable movements (>5% change)
If prices are flat and nothing notable, respond with [SILENT].
If there's a significant move, explain what happened." \
--script ~/.hermes/scripts/collect-prices.py \
--name "Price tracker" \
--deliver telegramสคริปต์ทำหน้าที่รวบรวมข้อมูลเชิงกลไก; ส่วน agent เพิ่มชั้นของการให้เหตุผล
Pattern 5: Multi-Skill Workflow
เชื่อมโยงทักษะเข้าด้วยกันสำหรับงานที่กำหนดเวลาที่ซับซ้อน Skills จะถูกโหลดตามลำดับก่อนที่ prompt จะทำงาน
# Use the arxiv skill to find papers, then the obsidian skill to save notes
/cron add "0 8 * * *" "Search arXiv for the 3 most interesting papers on 'language model reasoning' from the past day. For each paper, create an Obsidian note with the title, authors, abstract summary, and key contribution." \
--skill arxiv \
--skill obsidian \
--name "Paper digest"จากเครื่องมือโดยตรง:
cronjob(
action="create",
skills=["arxiv", "obsidian"],
prompt="Search arXiv for papers on 'language model reasoning' from the past day. Save the top 3 as Obsidian notes.",
schedule="0 8 * * *",
name="Paper digest",
deliver="local"
)Skills จะถูกโหลดตามลำดับ - arxiv ก่อน (สอน agent วิธีค้นหาบทความ) จากนั้น obsidian (สอนวิธีเขียนโน้ต) Prompt จะเชื่อมโยงทั้งหมดเข้าด้วยกัน
การจัดการ Jobs ของคุณ
# List all active jobs
/cron list
# Trigger a job immediately (for testing)
/cron run <job_id>
# Pause a job without deleting it
/cron pause <job_id>
# Edit a running job's schedule or prompt
/cron edit <job_id> --schedule "every 4h"
/cron edit <job_id> --prompt "Updated task description"
# Add or remove skills from an existing job
/cron edit <job_id> --skill arxiv --skill obsidian
/cron edit <job_id> --clear-skills
# Remove a job permanently
/cron remove <job_id>เป้าหมายการส่งมอบ (Delivery Targets)
แฟล็ก --deliver ควบคุมว่าผลลัพธ์จะไปที่ใด:
| Target | Example | Use case |
|---|---|---|
origin | --deliver origin | แชทเดิมที่สร้าง job (ค่าเริ่มต้น) |
local | --deliver local | บันทึกในไฟล์ท้องถิ่นเท่านั้น |
telegram | --deliver telegram | ช่องหลัก Telegram ของคุณ |
discord | --deliver discord | ช่องหลัก Discord ของคุณ |
slack | --deliver slack | ช่องหลัก Slack ของคุณ |
| Specific chat | --deliver telegram:-1001234567890 | กลุ่ม Telegram เฉพาะ |
| Threaded | --deliver telegram:-1001234567890:17585 | หัวข้อ (topic) ของ Telegram เฉพาะ |
เคล็ดลับ
ทำให้ prompt มีเนื้อหาครบถ้วนด้วยตัวเอง (self-contained). agent ใน cron job ไม่มีหน่วยความจำของการสนทนาของคุณ ต้องรวม URLs, ชื่อ repo, ความชอบในการจัดรูปแบบ, และคำแนะนำในการส่งมอบไว้ใน prompt โดยตรง
ใช้ [SILENT] อย่างแพร่หลาย. สำหรับงานเฝ้าติดตาม ควรใส่คำแนะนำเสมอว่า "หากไม่มีอะไรเปลี่ยนแปลง ให้ตอบกลับด้วย [SILENT]" สิ่งนี้จะป้องกันการแจ้งเตือนที่มากเกินไป
ใช้สคริปต์สำหรับการรวบรวมข้อมูล. พารามิเตอร์ script ช่วยให้สคริปต์ Python จัดการส่วนที่น่าเบื่อ (เช่น HTTP requests, file I/O, state tracking) agent จะเห็นเพียง stdout ของสคริปต์และนำไปใช้ในการให้เหตุผล ซึ่งมีค่าใช้จ่ายน้อยกว่าและเชื่อถือได้มากกว่าการให้ agent ดึงข้อมูลด้วยตัวเอง
ทดสอบด้วย /cron run. ก่อนรอให้กำหนดเวลาทำงาน ให้ใช้ /cron run <job_id> เพื่อดำเนินการทันทีและตรวจสอบว่าผลลัพธ์ถูกต้องหรือไม่
นิพจน์กำหนดเวลา (Schedule expressions). รูปแบบที่รองรับ: ความล่าช้าแบบสัมพัทธ์ (30m), ช่วงเวลา (every 2h), cron expression มาตรฐาน (0 9 * * *), และ ISO timestamps (2025-06-15T09:00:00) ภาษาธรรมชาติ เช่น daily at 9am ไม่รองรับ - ให้ใช้ 0 9 * * * แทน
สำหรับข้อมูลอ้างอิง cron ที่สมบูรณ์ - พารามิเตอร์ทั้งหมด, กรณีขอบ, และส่วนภายใน - โปรดดูที่ Scheduled Tasks (Cron).
📄 guides/automation-templates.md
sidebar_position: 15 title: "Automation Templates" description: "Ready-to-use automation recipes - scheduled tasks, GitHub event triggers, API webhooks, and multi-skill workflows"
Automation Templates
ชุดคำสั่งสำเร็จรูปสำหรับรูปแบบการทำงานอัตโนมัติที่พบบ่อย แต่ละ Template ใช้ cron scheduler ที่มาพร้อมกับ Hermes สำหรับการทริกเกอร์ตามเวลา และ webhook platform สำหรับการทริกเกอร์ที่ขับเคลื่อนด้วยเหตุการณ์ (event-driven triggers)
ทุก Template สามารถทำงานกับ โมเดลใดก็ได้ - ไม่ได้จำกัดอยู่แค่ Provider เดียว
:::tip Three Trigger Types
| Trigger | How | Tool |
|---|---|---|
| Schedule | Runs on a cadence (hourly, nightly, weekly) | cronjob tool or /cron slash command |
| GitHub Event | Fires on PR opens, pushes, issues, CI results | Webhook platform (hermes webhook subscribe) |
| API Call | External service POSTs JSON to your endpoint | Webhook platform (config.yaml routes or hermes webhook subscribe) |
ทั้งสามประเภทรองรับการส่งข้อมูลไปยัง Telegram, Discord, Slack, SMS, email, GitHub comments, หรือ local files :::
Development Workflow
Nightly Backlog Triage
การติดป้ายกำกับ จัดลำดับความสำคัญ และสรุปปัญหาใหม่ทุกคืน ส่งสรุปไปยังช่องทางของทีมคุณ
Trigger: Schedule (nightly)
hermes cron create "0 2 * * *" \
"You are a project manager triaging the NousResearch/hermes-agent GitHub repo.
1. Run: gh issue list --repo NousResearch/hermes-agent --state open --json number,title,labels,author,createdAt --limit 30
2. Identify issues opened in the last 24 hours
3. For each new issue:
- Suggest a priority label (P0-critical, P1-high, P2-medium, P3-low)
- Suggest a category label (bug, feature, docs, security)
- Write a one-line triage note
4. Summarize: total open issues, new today, breakdown by priority
Format as a clean digest. If no new issues, respond with [SILENT]." \
--name "Nightly backlog triage" \
--deliver telegramAutomatic PR Code Review
ตรวจสอบ Pull Request ทุกครั้งที่เปิดโดยอัตโนมัติ โพสต์ความคิดเห็นการตรวจสอบโดยตรงบน PR
Trigger: GitHub webhook
Option A - Dynamic subscription (CLI):
hermes webhook subscribe github-pr-review \
--events "pull_request" \
--prompt "Review this pull request:
Repository: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Author: {pull_request.user.login}
Action: {action}
Diff URL: {pull_request.diff_url}
Fetch the diff with: curl -sL {pull_request.diff_url}
Review for:
- Security issues (injection, auth bypass, secrets in code)
- Performance concerns (N+1 queries, unbounded loops, memory leaks)
- Code quality (naming, duplication, error handling)
- Missing tests for new behavior
Post a concise review. If the PR is a trivial docs/typo change, say so briefly." \
--skills "github-code-review" \
--deliver github_commentOption B - Static route (config.yaml):
platforms:
webhook:
enabled: true
extra:
port: 8644
secret: "your-global-secret"
routes:
github-pr-review:
events: ["pull_request"]
secret: "github-webhook-secret"
prompt: |
Review PR #{pull_request.number}: {pull_request.title}
Repository: {repository.full_name}
Author: {pull_request.user.login}
Diff URL: {pull_request.diff_url}
Review for security, performance, and code quality.
skills: ["github-code-review"]
deliver: "github_comment"
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{pull_request.number}"จากนั้นใน GitHub: Settings → Webhooks → Add webhook → Payload URL: http://your-server:8644/webhooks/github-pr-review, Content type: application/json, Secret: github-webhook-secret, Events: Pull requests.
Docs Drift Detection
การสแกนรายสัปดาห์ของ PR ที่ถูก merge เพื่อค้นหาการเปลี่ยนแปลง API ที่จำเป็นต้องอัปเดตเอกสาร
Trigger: Schedule (weekly)
hermes cron create "0 9 * * 1" \
"Scan the NousResearch/hermes-agent repo for documentation drift.
1. Run: gh pr list --repo NousResearch/hermes-agent --state merged --json number,title,files,mergedAt --limit 30
2. Filter to PRs merged in the last 7 days
3. For each merged PR, check if it modified:
- Tool schemas (tools/*.py) - may need docs/reference/tools-reference.md update
- CLI commands (hermes_cli/commands.py, hermes_cli/main.py) - may need docs/reference/cli-commands.md update
- Config options (hermes_cli/config.py) - may need docs/user-guide/configuration.md update
- Environment variables - may need docs/reference/environment-variables.md update
4. Cross-reference: for each code change, check if the corresponding docs page was also updated in the same PR
Report any gaps where code changed but docs didn't. If everything is in sync, respond with [SILENT]." \
--name "Docs drift detection" \
--deliver telegramDependency Security Audit
การสแกนรายวันเพื่อค้นหาช่องโหว่ที่ทราบใน Dependency ของโปรเจกต์
Trigger: Schedule (daily)
hermes cron create "0 6 * * *" \
"Run a dependency security audit on the hermes-agent project.
1. cd ~/.hermes/hermes-agent && source .venv/bin/activate
2. Run: pip audit --format json 2>/dev/null || pip audit 2>&1
3. Run: npm audit --json 2>/dev/null (in website/ directory if it exists)
4. Check for any CVEs with CVSS score >= 7.0
If vulnerabilities found:
- List each one with package name, version, CVE ID, severity
- Check if an upgrade is available
- Note if it's a direct dependency or transitive
If no vulnerabilities, respond with [SILENT]." \
--name "Dependency audit" \
--deliver telegramDevOps & Monitoring
Deploy Verification
ทริกเกอร์ smoke tests หลังจากการ Deploy ทุกครั้ง Pipeline CI/CD ของคุณจะ POST ไปยัง webhook เมื่อการ Deploy เสร็จสมบูรณ์
Trigger: API call (webhook)
hermes webhook subscribe deploy-verify \
--events "deployment" \
--prompt "A deployment just completed:
Service: {service}
Environment: {environment}
Version: {version}
Deployed by: {deployer}
Run these verification steps:
1. Check if the service is responding: curl -s -o /dev/null -w '%{http_code}' {health_url}
2. Search recent logs for errors: check the deployment payload for any error indicators
3. Verify the version matches: curl -s {health_url}/version
Report: deployment status (healthy/degraded/failed), response time, any errors found.
If healthy, keep it brief. If degraded or failed, provide detailed diagnostics." \
--deliver telegramPipeline CI/CD ของคุณจะทริกเกอร์มัน:
curl -X POST http://your-server:8644/webhooks/deploy-verify \
-H "Content-Type: application/json" \
-H "X-Hub-Signature-256: sha256=$(echo -n '{"service":"api","environment":"prod","version":"2.1.0","deployer":"ci","health_url":"https://api.example.com/health"}' | openssl dgst -sha256 -hmac 'your-secret' | cut -d' ' -f2)" \
-d '{"service":"api","environment":"prod","version":"2.1.0","deployer":"ci","health_url":"https://api.example.com/health"}'Alert Triage
การเชื่อมโยง Alert จากระบบ Monitoring กับการเปลี่ยนแปลงล่าสุดเพื่อร่างคำตอบ ทำงานร่วมกับ Datadog, PagerDuty, Grafana, หรือระบบ Alerting ใดๆ ที่สามารถ POST JSON ได้
Trigger: API call (webhook)
hermes webhook subscribe alert-triage \
--prompt "Monitoring alert received:
Alert: {alert.name}
Severity: {alert.severity}
Service: {alert.service}
Message: {alert.message}
Timestamp: {alert.timestamp}
Investigate:
1. Search the web for known issues with this error pattern
2. Check if this correlates with any recent deployments or config changes
3. Draft a triage summary with:
- Likely root cause
- Suggested first response steps
- Escalation recommendation (P1-P4)
Be concise. This goes to the on-call channel." \
--deliver slackUptime Monitor
ตรวจสอบ Endpoints ทุก 30 นาที แจ้งเตือนเฉพาะเมื่อมีบางอย่างล่มเท่านั้น
Trigger: Schedule (every 30 min)
import urllib.request, json, time
ENDPOINTS = [
{"name": "API", "url": "https://api.example.com/health"},
{"name": "Web", "url": "https://www.example.com"},
{"name": "Docs", "url": "https://docs.example.com"},
]
results = []
for ep in ENDPOINTS:
try:
start = time.time()
req = urllib.request.Request(ep["url"], headers={"User-Agent": "Hermes-Monitor/1.0"})
resp = urllib.request.urlopen(req, timeout=10)
elapsed = round((time.time() - start) * 1000)
results.append({"name": ep["name"], "status": resp.getcode(), "ms": elapsed})
except Exception as e:
results.append({"name": ep["name"], "status": "DOWN", "error": str(e)})
down = [r for r in results if r.get("status") == "DOWN" or (isinstance(r.get("status"), int) and r["status"] >= 500)]
if down:
print("OUTAGE DETECTED")
for r in down:
print(f" {r['name']}: {r.get('error', f'HTTP {r[\"status\"]}')} ")
print(f"\nAll results: {json.dumps(results, indent=2)}")
else:
print("NO_ISSUES")hermes cron create "every 30m" \
"If the script reports OUTAGE DETECTED, summarize which services are down and suggest likely causes. If NO_ISSUES, respond with [SILENT]." \
--script ~/.hermes/scripts/check-uptime.py \
--name "Uptime monitor" \
--deliver telegramResearch & Intelligence
Competitive Repository Scout
ตรวจสอบ Repository ของคู่แข่งเพื่อหา PR, ฟีเจอร์, และการตัดสินใจด้านสถาปัตยกรรมที่น่าสนใจ
Trigger: Schedule (daily)
hermes cron create "0 8 * * *" \
"Scout these AI agent repositories for notable activity in the last 24 hours:
Repos to check:
- anthropics/claude-code
- openai/codex
- All-Hands-AI/OpenHands
- Aider-AI/aider
For each repo:
1. gh pr list --repo <repo> --state all --json number,title,author,createdAt,mergedAt --limit 15
2. gh issue list --repo <repo> --state open --json number,title,labels,createdAt --limit 10
Focus on:
- New features being developed
- Architectural changes
- Integration patterns we could learn from
- Security fixes that might affect us too
Skip routine dependency bumps and CI fixes. If nothing notable, respond with [SILENT].
If there are findings, organize by repo with brief analysis of each item." \
--skills "competitive-pr-scout" \
--name "Competitor scout" \
--deliver telegramAI News Digest
สรุปข่าว AI/ML ประจำสัปดาห์
Trigger: Schedule (weekly)
hermes cron create "0 9 * * 1" \
"Generate a weekly AI news digest covering the past 7 days:
1. Search the web for major AI announcements, model releases, and research breakthroughs
2. Search for trending ML repositories on GitHub
3. Check arXiv for highly-cited papers on language models and agents
Structure:
## Headlines (3-5 major stories)
## Notable Papers (2-3 papers with one-sentence summaries)
## Open Source (interesting new repos or major releases)
## Industry Moves (funding, acquisitions, launches)
Keep each item to 1-2 sentences. Include links. Total under 600 words." \
--name "Weekly AI digest" \
--deliver telegramPaper Digest with Notes
การสแกน arXiv รายวันที่บันทึกสรุปไปยังระบบจดบันทึกของคุณ
Trigger: Schedule (daily)
hermes cron create "0 8 * * *" \
"Search arXiv for the 3 most interesting papers on 'language model reasoning' OR 'tool-use agents' from the past day. For each paper, create an Obsidian note with the title, authors, abstract summary, key contribution, and potential relevance to Hermes Agent development." \
--skills "arxiv,obsidian" \
--name "Paper digest" \
--deliver localGitHub Event Automations
Issue Auto-Labeling
ติดป้ายกำกับและตอบกลับ Issue ใหม่โดยอัตโนมัติ
Trigger: GitHub webhook
hermes webhook subscribe github-issues \
--events "issues" \
--prompt "New GitHub issue received:
Repository: {repository.full_name}
Issue #{issue.number}: {issue.title}
Author: {issue.user.login}
Action: {action}
Body: {issue.body}
Labels: {issue.labels}
If this is a new issue (action=opened):
1. Read the issue title and body carefully
2. Suggest appropriate labels (bug, feature, docs, security, question)
3. If it's a bug report, check if you can identify the affected component from the description
4. Post a helpful initial response acknowledging the issue
If this is a label or assignment change, respond with [SILENT]." \
--deliver github_commentCI Failure Analysis
วิเคราะห์ความล้มเหลวของ CI และโพสต์การวินิจฉัยบน PR
Trigger: GitHub webhook
# config.yaml route
platforms:
webhook:
enabled: true
extra:
routes:
ci-failure:
events: ["check_run"]
secret: "ci-secret"
prompt: |
CI check failed:
Repository: {repository.full_name}
Check: {check_run.name}
Status: {check_run.conclusion}
PR: #{check_run.pull_requests.0.number}
Details URL: {check_run.details_url}
If conclusion is "failure":
1. Fetch the log from the details URL if accessible
2. Identify the likely cause of failure
3. Suggest a fix
If conclusion is "success", respond with [SILENT].
deliver: "github_comment"
deliver_extra:
repo: "{repository.full_name}"
pr_number: "{check_run.pull_requests.0.number}"Auto-Port Changes Across Repos
เมื่อ PR ถูก merge ใน Repo หนึ่ง ให้ทำการ Port การเปลี่ยนแปลงที่เทียบเท่าไปยัง Repo อื่นโดยอัตโนมัติ
Trigger: GitHub webhook
hermes webhook subscribe auto-port \
--events "pull_request" \
--prompt "PR merged in the source repository:
Repository: {repository.full_name}
PR #{pull_request.number}: {pull_request.title}
Author: {pull_request.user.login}
Action: {action}
Merge commit: {pull_request.merge_commit_sha}
If action is 'closed' and pull_request.merged is true:
1. Fetch the diff: curl -sL {pull_request.diff_url}
2. Analyze what changed
3. Determine if this change needs to be ported to the Go SDK equivalent
4. If yes, create a branch, apply the equivalent changes, and open a PR on the target repo
5. Reference the original PR in the new PR description
If action is not 'closed' or not merged, respond with [SILENT]." \
--skills "github-pr-workflow" \
--deliver logBusiness Operations
Stripe Payment Monitoring
ติดตามเหตุการณ์การชำระเงินและรับสรุปความล้มเหลว
Trigger: API call (webhook)
hermes webhook subscribe stripe-payments \
--events "payment_intent.succeeded,payment_intent.payment_failed,charge.dispute.created" \
--prompt "Stripe event received:
Event type: {type}
Amount: {data.object.amount} cents ({data.object.currency})
Customer: {data.object.customer}
Status: {data.object.status}
For payment_intent.payment_failed:
- Identify the failure reason from {data.object.last_payment_error}
- Suggest whether this is a transient issue (retry) or permanent (contact customer)
For charge.dispute.created:
- Flag as urgent
- Summarize the dispute details
For payment_intent.succeeded:
- Brief confirmation only
Keep responses concise for the ops channel." \
--deliver slackDaily Revenue Summary
รวบรวมตัวชี้วัดทางธุรกิจที่สำคัญทุกเช้า
Trigger: Schedule (daily)
hermes cron create "0 8 * * *" \
"Generate a morning business metrics summary.
Search the web for:
1. Current Bitcoin and Ethereum prices
2. S&P 500 status (pre-market or previous close)
3. Any major tech/AI industry news from the last 12 hours
Format as a brief morning briefing, 3-4 bullet points max.
Deliver as a clean, scannable message." \
--name "Morning briefing" \
--deliver telegramMulti-Skill Workflows
Security Audit Pipeline
รวมหลาย Skills เข้าด้วยกันเพื่อการตรวจสอบความปลอดภัยประจำสัปดาห์ที่ครอบคลุม
Trigger: Schedule (weekly)
hermes cron create "0 3 * * 0" \
"Run a comprehensive security audit of the hermes-agent codebase.
1. Check for dependency vulnerabilities (pip audit, npm audit)
2. Search the codebase for common security anti-patterns:
- Hardcoded secrets or API keys
- SQL injection vectors (string formatting in queries)
- Path traversal risks (user input in file paths without validation)
- Unsafe deserialization (pickle.loads, yaml.load without SafeLoader)
3. Review recent commits (last 7 days) for security-relevant changes
4. Check if any new environment variables were added without being documented
Write a security report with findings categorized by severity (Critical, High, Medium, Low).
If nothing found, report a clean bill of health." \
--skills "codebase-security-audit" \
--name "Weekly security audit" \
--deliver telegramContent Pipeline
การวิจัย ร่าง และเตรียมเนื้อหาตามกำหนดเวลา
Trigger: Schedule (weekly)
hermes cron create "0 10 * * 3" \
"Research and draft a technical blog post outline about a trending topic in AI agents.
1. Search the web for the most discussed AI agent topics this week
2. Pick the most interesting one that's relevant to open-source AI agents
3. Create an outline with:
- Hook/intro angle
- 3-4 key sections
- Technical depth appropriate for developers
- Conclusion with actionable takeaway
4. Save the outline to ~/drafts/blog-$(date +%Y%m%d).md
Keep the outline to ~300 words. This is a starting point, not a finished post." \
--name "Blog outline" \
--deliver localQuick Reference
Cron Schedule Syntax
| Expression | Meaning |
|---|---|
every 30m | ทุก 30 นาที |
every 2h | ทุก 2 ชั่วโมง |
0 2 * * * | ทุกวัน เวลา 02:00 น. |
0 9 * * 1 | ทุกวันจันทร์ เวลา 09:00 น. |
0 9 * * 1-5 | วันธรรมดา เวลา 09:00 น. |
0 3 * * 0 | ทุกวันอาทิตย์ เวลา 03:00 น. |
0 */6 * * * | ทุก 6 ชั่วโมง |
Delivery Targets
| Target | Flag | Notes |
|---|---|---|
| Same chat | --deliver origin | ค่าเริ่มต้น - ส่งไปยังที่ที่สร้าง Job |
| Local file | --deliver local | บันทึก Output โดยไม่มีการแจ้งเตือน |
| Telegram | --deliver telegram | ช่องหลัก หรือ telegram:CHAT_ID สำหรับเฉพาะเจาะจง |
| Discord | --deliver discord | ช่องหลัก หรือ discord:CHANNEL_ID |
| Slack | --deliver slack | ช่องหลัก |
| SMS | --deliver sms:+15551234567 | ส่งตรงไปยังหมายเลขโทรศัพท์ |
| Specific thread | --deliver telegram:-100123:456 | หัวข้อ (topic) ใน Telegram |
Webhook Template Variables
| Variable | Description |
|---|---|
{pull_request.title} | ชื่อ PR |
{issue.number} | หมายเลข Issue |
{repository.full_name} | owner/repo |
{action} | การกระทำของ Event (opened, closed, etc.) |
{__raw__} | Payload JSON เต็ม (ถูกตัดทอนที่ 4000 ตัวอักษร) |
{sender.login} | ผู้ใช้ GitHub ที่ทริกเกอร์ Event |
The [SILENT] Pattern
เมื่อ Response ของ cron job มีข้อความ [SILENT] การส่งข้อมูลจะถูกระงับ ใช้สิ่งนี้เพื่อหลีกเลี่ยงการแจ้งเตือนสแปมในการรันที่เงียบ:
If nothing noteworthy happened, respond with [SILENT].นั่นหมายความว่าคุณจะได้รับการแจ้งเตือนก็ต่อเมื่อ Agent มีข้อมูลที่ต้องรายงานเท่านั้น.
📄 guides/aws-bedrock.md
sidebar_position: 14 title: "AWS Bedrock" description: "Use Hermes Agent with Amazon Bedrock - native Converse API, IAM authentication, Guardrails, and cross-region inference"
AWS Bedrock
Hermes Agent รองรับ Amazon Bedrock ในฐานะ native provider โดยใช้ Converse API - ไม่ใช่ endpoint ที่เข้ากันได้กับ OpenAI สิ่งนี้ช่วยให้คุณเข้าถึงระบบนิเวศของ Bedrock ได้อย่างเต็มที่: IAM authentication, Guardrails, cross-region inference profiles, และ foundation models ทั้งหมด
Prerequisites
- AWS credentials - แหล่งที่มาใดๆ ที่รองรับโดย boto3 credential chain:
- IAM instance role (EC2, ECS, Lambda - zero config)
AWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEYenvironment variablesAWS_PROFILEสำหรับ SSO หรือ named profilesaws configureสำหรับการพัฒนาในเครื่อง (local development)
- boto3 - ติดตั้งด้วย
pip install hermes-agent[bedrock] - IAM permissions - อย่างน้อยที่สุด:
bedrock:InvokeModelและbedrock:InvokeModelWithResponseStream(สำหรับการทำ inference)bedrock:ListFoundationModelsและbedrock:ListInferenceProfiles(สำหรับการค้นหา model)
:::tip EC2 / ECS / Lambda
บน AWS compute ให้แนบ IAM role ที่มี AmazonBedrockFullAccess ก็เสร็จเรียบร้อยแล้ว ไม่ต้องใช้ API keys ไม่ต้องตั้งค่า .env - Hermes จะตรวจจับ instance role โดยอัตโนมัติ
:::
Quick Start
# Install with Bedrock support
pip install hermes-agent[bedrock]
# Select Bedrock as your provider
hermes model
# → Choose "More providers..." → "AWS Bedrock"
# → Select your region and model
# Start chatting
hermes chatConfiguration
หลังจากรัน hermes model ไฟล์ ~/.hermes/config.yaml ของคุณจะมีเนื้อหาดังนี้:
model:
default: us.anthropic.claude-sonnet-4-6
provider: bedrock
base_url: https://bedrock-runtime.us-east-2.amazonaws.com
bedrock:
region: us-east-2Region
ตั้งค่า AWS region ด้วยวิธีใดวิธีหนึ่งต่อไปนี้ (เรียงตามลำดับความสำคัญสูงสุด):
bedrock.regionในconfig.yamlAWS_REGIONenvironment variableAWS_DEFAULT_REGIONenvironment variable- ค่าเริ่มต้น:
us-east-1
Guardrails
ในการใช้ Amazon Bedrock Guardrails กับการเรียกใช้ model ทั้งหมด:
bedrock:
region: us-east-2
guardrail:
guardrail_identifier: "abc123def456" # จาก Bedrock console
guardrail_version: "1" # หมายเลขเวอร์ชัน หรือ "DRAFT"
stream_processing_mode: "async" # "sync" หรือ "async"
trace: "disabled" # "enabled", "disabled", หรือ "enabled_full"Model Discovery
Hermes จะค้นหา model ที่พร้อมใช้งานโดยอัตโนมัติผ่าน Bedrock control plane คุณสามารถปรับแต่งการค้นหาได้:
bedrock:
discovery:
enabled: true
provider_filter: ["anthropic", "amazon"] # แสดงเฉพาะ provider เหล่านี้
refresh_interval: 3600 # แคชเป็นเวลา 1 ชั่วโมงAvailable Models
Bedrock models ใช้ inference profile IDs สำหรับการเรียกใช้งานแบบ on-demand ตัวเลือก hermes model จะแสดงสิ่งเหล่านี้โดยอัตโนมัติ โดยมีโมเดลแนะนำอยู่ด้านบน:
| Model | ID | Notes |
|---|---|---|
| Claude Sonnet 4.6 | us.anthropic.claude-sonnet-4-6 | แนะนำ - ความสมดุลที่ดีที่สุดระหว่างความเร็วและความสามารถ |
| Claude Opus 4.6 | us.anthropic.claude-opus-4-6-v1 | มีความสามารถสูงสุด |
| Claude Haiku 4.5 | us.anthropic.claude-haiku-4-5-20251001-v1:0 | Claude ที่เร็วที่สุด |
| Amazon Nova Pro | us.amazon.nova-pro-v1:0 | โมเดลเรือธงของ Amazon |
| Amazon Nova Micro | us.amazon.nova-micro-v1:0 | เร็วที่สุดและราคาถูกที่สุด |
| DeepSeek V3.2 | deepseek.v3.2 | โมเดล open source ที่แข็งแกร่ง |
| Llama 4 Scout 17B | us.meta.llama4-scout-17b-instruct-v1:0 | ล่าสุดจาก Meta |
:::info Cross-Region Inference
โมเดลที่ขึ้นต้นด้วย us. ใช้ cross-region inference profiles ซึ่งให้ capacity ที่ดีกว่าและมีการ failover อัตโนมัติข้าม AWS regions ส่วนโมเดลที่ขึ้นต้นด้วย global. จะถูกกำหนดเส้นทางข้ามทุก regions ที่พร้อมใช้งานทั่วโลก
:::
Switching Models Mid-Session
ใช้คำสั่ง /model ระหว่างการสนทนา:
/model us.amazon.nova-pro-v1:0
/model deepseek.v3.2
/model us.anthropic.claude-opus-4-6-v1Diagnostics
hermes doctordoctor จะตรวจสอบ:
- ว่ามี AWS credentials หรือไม่ (env vars, IAM role, SSO)
- ว่าติดตั้ง
boto3แล้วหรือไม่ - ว่าสามารถเข้าถึง Bedrock API ได้หรือไม่ (ListFoundationModels)
- จำนวน model ที่พร้อมใช้งานใน region ของคุณ
Gateway (Messaging Platforms)
Bedrock ทำงานร่วมกับทุกแพลตฟอร์ม gateway ของ Hermes (Telegram, Discord, Slack, Feishu, ฯลฯ) ให้ตั้งค่า Bedrock เป็น provider ของคุณ จากนั้นจึงเริ่ม gateway ตามปกติ:
hermes gateway setup
hermes gateway startgateway จะอ่าน config.yaml และใช้การตั้งค่า provider Bedrock เดียวกัน
Troubleshooting
"No API key found" / "No AWS credentials"
Hermes จะตรวจสอบ credentials ตามลำดับนี้:
AWS_BEARER_TOKEN_BEDROCKAWS_ACCESS_KEY_ID+AWS_SECRET_ACCESS_KEYAWS_PROFILE- EC2 instance metadata (IMDS)
- ECS container credentials
- Lambda execution role
หากไม่พบ credentials ใดๆ ให้รัน aws configure หรือแนบ IAM role เข้ากับ compute instance ของคุณ
"Invocation of model ID ... with on-demand throughput isn't supported"
ให้ใช้ inference profile ID (ที่ขึ้นต้นด้วย us. หรือ global.) แทนการใช้ foundation model ID แบบเปลือย ตัวอย่างเช่น:
- ❌
anthropic.claude-sonnet-4-6 - ✅
us.anthropic.claude-sonnet-4-6
"ThrottlingException"
คุณถึงขีดจำกัด rate limit ของ Bedrock ต่อ model แล้ว Hermes จะพยายาม retry โดยอัตโนมัติพร้อม backoff หากต้องการเพิ่มขีดจำกัด ให้ขอเพิ่ม quota ใน AWS Service Quotas console
📄 guides/build-a-hermes-plugin.md
sidebar_position: 9 sidebar_label: "Build a Plugin" title: "Build a Hermes Plugin" description: "Step-by-step guide to building a complete Hermes plugin with tools, hooks, data files, and skills"
Build a Hermes Plugin
คู่มือนี้จะพาคุณไปดูขั้นตอนการสร้าง Hermes plugin แบบสมบูรณ์ตั้งแต่เริ่มต้น คุณจะได้ plugin ที่ใช้งานได้จริงซึ่งมีเครื่องมือ (tools) หลายตัว, lifecycle hooks, data files ที่ถูกบรรจุมาพร้อมกัน, และ skill ที่รวมไว้แล้ว - ครอบคลุมทุกสิ่งที่ plugin system รองรับ
What you're building
plugin calculator ที่มีเครื่องมือสองตัว:
calculate- สำหรับประเมินนิพจน์ทางคณิตศาสตร์ (เช่น2**16,sqrt(144),pi * 5**2)unit_convert- สำหรับแปลงหน่วยระหว่างหน่วยต่างๆ (เช่น100 F → 37.78 C,5 km → 3.11 mi)
นอกจากนี้ยังมี hook ที่บันทึกการเรียกใช้ tool ทุกครั้ง และไฟล์ skill ที่ถูกรวมไว้
Step 1: Create the plugin directory
mkdir -p ~/.hermes/plugins/calculator
cd ~/.hermes/plugins/calculatorStep 2: Write the manifest
สร้างไฟล์ plugin.yaml:
name: calculator
version: 1.0.0
description: Math calculator — evaluate expressions and convert units
provides_tools:
- calculate
- unit_convert
provides_hooks:
- post_tool_callสิ่งนี้บอก Hermes ว่า: "ฉันคือ plugin ชื่อ calculator, ฉันมี tools และ hooks ให้บริการ" ฟิลด์ provides_tools และ provides_hooks คือรายการสิ่งที่ plugin ลงทะเบียน
ฟิลด์ทางเลือกที่คุณสามารถเพิ่มได้:
author: Your Name
requires_env: # gate loading on env vars; prompted during install
- SOME_API_KEY # simple format — plugin disabled if missing
- name: OTHER_KEY # rich format — shows description/url during install
description: "Key for the Other service"
url: "https://other.com/keys"
secret: trueStep 3: Write the tool schemas
สร้างไฟล์ schemas.py - นี่คือสิ่งที่ LLM ใช้ในการตัดสินใจว่าจะเรียกใช้ tool ของคุณเมื่อใด:
"""Tool schemas — what the LLM sees."""
CALCULATE = {
"name": "calculate",
"description": (
"Evaluate a mathematical expression and return the result. "
"Supports arithmetic (+, -, *, /, **), functions (sqrt, sin, cos, "
"log, abs, round, floor, ceil), and constants (pi, e). "
"Use this for any math the user asks about."
),
"parameters": {
"type": "object",
"properties": {
"expression": {
"type": "string",
"description": "Math expression to evaluate (e.g., '2**10', 'sqrt(144)')",
},
},
"required": ["expression"],
},
}
UNIT_CONVERT = {
"name": "unit_convert",
"description": (
"Convert a value between units. Supports length (m, km, mi, ft, in), "
"weight (kg, lb, oz, g), temperature (C, F, K), data (B, KB, MB, GB, TB), "
"and time (s, min, hr, day)."
),
"parameters": {
"type": "object",
"properties": {
"value": {
"type": "number",
"description": "The numeric value to convert",
},
"from_unit": {
"type": "string",
"description": "Source unit (e.g., 'km', 'lb', 'F', 'GB')",
},
"to_unit": {
"type": "string",
"description": "Target unit (e.g., 'mi', 'kg', 'C', 'MB')",
},
},
"required": ["value", "from_unit", "to_unit"],
},
}ทำไม schemas ถึงสำคัญ: ฟิลด์ description คือวิธีที่ LLM ตัดสินใจว่าจะใช้ tool ของคุณเมื่อใด คุณต้องระบุให้ชัดเจนว่ามันทำอะไรและเมื่อไหร่ ส่วน parameters จะกำหนดว่า LLM จะส่ง arguments อะไรมา
Step 4: Write the tool handlers
สร้างไฟล์ tools.py - นี่คือโค้ดที่ทำงานจริงเมื่อ LLM เรียกใช้ tool ของคุณ:
"""Tool handlers — the code that runs when the LLM calls each tool."""
import json
import math
# Safe globals for expression evaluation — no file/network access
_SAFE_MATH = {
"abs": abs, "round": round, "min": min, "max": max,
"pow": pow, "sqrt": math.sqrt, "sin": math.sin, "cos": math.cos,
"tan": math.tan, "log": math.log, "log2": math.log2, "log10": math.log10,
"floor": math.floor, "ceil": math.ceil,
"pi": math.pi, "e": math.e,
"factorial": math.factorial,
}
def calculate(args: dict, **kwargs) -> str:
"""Evaluate a math expression safely.
Rules for handlers:
1. Receive args (dict) — the parameters the LLM passed
2. Do the work
3. Return a JSON string — ALWAYS, even on error
4. Accept **kwargs for forward compatibility
"""
expression = args.get("expression", "").strip()
if not expression:
return json.dumps({"error": "No expression provided"})
try:
result = eval(expression, {"__builtins__": {}}, _SAFE_MATH)
return json.dumps({"expression": expression, "result": result})
except ZeroDivisionError:
return json.dumps({"expression": expression, "error": "Division by zero"})
except Exception as e:
return json.dumps({"expression": expression, "error": f"Invalid: {e}"})
# Conversion tables — values are in base units
_LENGTH = {"m": 1, "km": 1000, "mi": 1609.34, "ft": 0.3048, "in": 0.0254, "cm": 0.01}
_WEIGHT = {"kg": 1, "g": 0.001, "lb": 0.453592, "oz": 0.0283495}
_DATA = {"B": 1, "KB": 1024, "MB": 1024**2, "GB": 1024**3, "TB": 1024**4}
_TIME = {"s": 1, "ms": 0.001, "min": 60, "hr": 3600, "day": 86400}
def _convert_temp(value, from_u, to_u):
# Normalize to Celsius
c = {"F": (value - 32) * 5/9, "K": value - 273.15}.get(from_u, value)
# Convert to target
return {"F": c * 9/5 + 32, "K": c + 273.15}.get(to_u, c)
def unit_convert(args: dict, **kwargs) -> str:
"""Convert between units."""
value = args.get("value")
from_unit = args.get("from_unit", "").strip()
to_unit = args.get("to_unit", "").strip()
if value is None or not from_unit or not to_unit:
return json.dumps({"error": "Need value, from_unit, and to_unit"})
try:
# Temperature
if from_unit.upper() in {"C","F","K"} and to_unit.upper() in {"C","F","K"}:
result = _convert_temp(float(value), from_unit.upper(), to_unit.upper())
return json.dumps({"input": f"{value} {from_unit}", "result": round(result, 4),
"output": f"{round(result, 4)} {to_unit}"})
# Ratio-based conversions
for table in (_LENGTH, _WEIGHT, _DATA, _TIME):
lc = {k.lower(): v for k, v in table.items()}
if from_unit.lower() in lc and to_unit.lower() in lc:
result = float(value) * lc[from_unit.lower()] / lc[to_unit.lower()]
return json.dumps({"input": f"{value} {from_unit}",
"result": round(result, 6),
"output": f"{round(result, 6)} {to_unit}"})
return json.dumps({"error": f"Cannot convert {from_unit} → {to_unit}"})
except Exception as e:
return json.dumps({"error": f"Conversion failed: {e}"})กฎสำคัญสำหรับ handlers:
- Signature:
def my_handler(args: dict, **kwargs) -> str - Return: ต้องเป็น JSON string เสมอ ทั้งกรณีสำเร็จและกรณีเกิดข้อผิดพลาด
- Never raise: ต้องดักจับทุก Exception และส่งคืน error JSON แทน
- Accept
**kwargs: Hermes อาจส่ง context เพิ่มเติมในอนาคต
Step 5: Write the registration
สร้างไฟล์ __init__.py - นี่คือส่วนที่เชื่อม schemas เข้ากับ handlers:
"""Calculator plugin — registration."""
import logging
from . import schemas, tools
logger = logging.getLogger(__name__)
# Track tool usage via hooks
_call_log = []
def _on_post_tool_call(tool_name, args, result, task_id, **kwargs):
"""Hook: runs after every tool call (not just ours)."""
_call_log.append({"tool": tool_name, "session": task_id})
if len(_call_log) > 100:
_call_log.pop(0)
logger.debug("Tool called: %s (session %s)", tool_name, task_id)
def register(ctx):
"""Wire schemas to handlers and register hooks."""
ctx.register_tool(name="calculate", toolset="calculator",
schema=schemas.CALCULATE, handler=tools.calculate)
ctx.register_tool(name="unit_convert", toolset="calculator",
schema=schemas.UNIT_CONVERT, handler=tools.unit_convert)
# This hook fires for ALL tool calls, not just ours
ctx.register_hook("post_tool_call", _on_post_tool_call)สิ่งที่ register() ทำ:
- ถูกเรียกใช้เพียงครั้งเดียวเมื่อเริ่มต้นระบบ
ctx.register_tool()นำ tool ของคุณเข้าสู่ registry — model จะเห็นมันทันทีctx.register_hook()สมัครรับการแจ้งเตือนเหตุการณ์ (lifecycle events)ctx.register_cli_command()ลงทะเบียน subcommand สำหรับ CLI (เช่นhermes my-plugin <subcommand>)- หากฟังก์ชันนี้ล้มเหลว plugin จะถูกปิดการใช้งาน แต่ Hermes จะยังคงทำงานได้ตามปกติ
Step 6: Test it
เริ่ม Hermes:
hermesคุณควรเห็น calculator: calculate, unit_convert ในรายการ tool ของ banner
ลองใช้ prompt เหล่านี้:
What's 2 to the power of 16?
Convert 100 fahrenheit to celsius
What's the square root of 2 times pi?
How many gigabytes is 1.5 terabytes?ตรวจสอบสถานะ plugin:
/pluginsOutput:
Plugins (1):
✓ calculator v1.0.0 (2 tools, 1 hooks)Your plugin's final structure
~/.hermes/plugins/calculator/
├── plugin.yaml # "I'm calculator, I provide tools and hooks"
├── __init__.py # Wiring: schemas → handlers, register hooks
├── schemas.py # What the LLM reads (descriptions + parameter specs)
└── tools.py # What runs (calculate, unit_convert functions)สี่ไฟล์ที่แยกส่วนอย่างชัดเจน:
- Manifest ประกาศว่า plugin คืออะไร
- Schemas อธิบาย tools สำหรับ LLM
- Handlers ใช้งาน logic จริง
- Registration เชื่อมทุกอย่างเข้าด้วยกัน
What else can plugins do?
Ship data files
ใส่ไฟล์ใดๆ ใน directory ของ plugin และอ่านมันเมื่อ import:
# In tools.py or __init__.py
from pathlib import Path
_PLUGIN_DIR = Path(__file__).parent
_DATA_FILE = _PLUGIN_DIR / "data" / "languages.yaml"
with open(_DATA_FILE) as f:
_DATA = yaml.safe_load(f)Bundle skills
Plugins สามารถส่งไฟล์ skill ที่ agent โหลดผ่าน skill_view("plugin:skill") ลงทะเบียนพวกมันใน __init__.py ของคุณ:
~/.hermes/plugins/my-plugin/
├── __init__.py
├── plugin.yaml
└── skills/
├── my-workflow/
│ └── SKILL.md
└── my-checklist/
└── SKILL.mdfrom pathlib import Path
def register(ctx):
skills_dir = Path(__file__).parent / "skills"
for child in sorted(skills_dir.iterdir()):
skill_md = child / "SKILL.md"
if child.is_dir() and skill_md.exists():
ctx.register_skill(child.name, skill_md)ตอนนี้ agent สามารถโหลด skill ของคุณด้วยชื่อที่ระบุ namespace:
skill_view("my-plugin:my-workflow") # → plugin's version
skill_view("my-workflow") # → built-in version (unchanged)คุณสมบัติสำคัญ:
- Plugin skills เป็นแบบ read-only — พวกมันจะไม่ถูกใส่ใน
~/.hermes/skills/และไม่สามารถแก้ไขผ่านskill_manageได้ - Plugin skills จะ ไม่ ถูกแสดงใน index
<available_skills>ของ system prompt — พวกมันต้องโหลดแบบ explicit opt-in - ชื่อ skill แบบเปลือย (Bare skill names) จะไม่ได้รับผลกระทบ — namespace ป้องกันการชนกับ built-in skills
- เมื่อ agent โหลด plugin skill จะมีการเพิ่ม banner context ที่ระบุ sibling skills จาก plugin เดียวกัน
:::tip Legacy pattern
รูปแบบเก่าที่ใช้ shutil.copy2 (การคัดลอก skill เข้าไปใน ~/.hermes/skills/) ยังคงใช้งานได้ แต่มีความเสี่ยงที่จะเกิด name collision กับ built-in skills ควรใช้ ctx.register_skill() สำหรับ plugin ใหม่
:::
Gate on environment variables
หาก plugin ของคุณต้องการ API key:
# plugin.yaml — simple format (backwards-compatible)
requires_env:
- WEATHER_API_KEYหาก WEATHER_API_KEY ไม่ได้ถูกตั้งค่า plugin จะถูกปิดการใช้งานพร้อมข้อความที่ชัดเจน ไม่เกิด crash และไม่มี error ใน agent — เพียงแค่ "Plugin weather disabled (missing: WEATHER_API_KEY)"
เมื่อผู้ใช้รัน hermes plugins install พวกเขาจะถูก prompt แบบโต้ตอบ สำหรับ requires_env ที่ขาดหายไป ค่าต่างๆ จะถูกบันทึกใน .env โดยอัตโนมัติ
เพื่อให้ประสบการณ์การติดตั้งดีขึ้น ให้ใช้ rich format พร้อม description และ URL สำหรับการลงทะเบียน:
# plugin.yaml — rich format
requires_env:
- name: WEATHER_API_KEY
description: "API key for OpenWeather"
url: "https://openweathermap.org/api"
secret: true| Field | Required | Description |
|---|---|---|
name | Yes | ชื่อ environment variable |
description | No | แสดงให้ผู้ใช้เห็นระหว่าง prompt การติดตั้ง |
url | No | ที่ที่สามารถรับ credential ได้ |
secret | No | ถ้าเป็น true input จะถูกซ่อน (เหมือนช่องรหัสผ่าน) |
ทั้งสองรูปแบบสามารถผสมกันในรายการเดียวกันได้ ตัวแปรที่ตั้งค่าไว้แล้วจะถูกข้ามไปอย่างเงียบๆ
Conditional tool availability
สำหรับ tools ที่ขึ้นอยู่กับ libraries ทางเลือก:
ctx.register_tool(
name="my_tool",
schema={...},
handler=my_handler,
check_fn=lambda: _has_optional_lib(), # False = tool hidden from model
)Register multiple hooks
def register(ctx):
ctx.register_hook("pre_tool_call", before_any_tool)
ctx.register_hook("post_tool_call", after_any_tool)
ctx.register_hook("pre_llm_call", inject_memory)
ctx.register_hook("on_session_start", on_new_session)
ctx.register_hook("on_session_end", on_session_end)Hook reference
แต่ละ hook มีการบันทึกรายละเอียดทั้งหมดใน Event Hooks reference — signature ของ callback, ตารางพารามิเตอร์, เวลาที่เรียกใช้ที่แน่นอน, และตัวอย่าง นี่คือสรุป:
| Hook | Fires when | Callback signature | Returns |
|---|---|---|---|
pre_tool_call | ก่อนที่ tool ใดๆ จะทำงาน | tool_name: str, args: dict, task_id: str | ignored |
post_tool_call | หลังที่ tool ใดๆ ส่งคืนผลลัพธ์ | tool_name: str, args: dict, result: str, task_id: str | ignored |
pre_llm_call | ครั้งเดียวต่อ turn, ก่อน loop การเรียก tool | session_id: str, user_message: str, conversation_history: list, is_first_turn: bool, model: str, platform: str | context injection |
post_llm_call | ครั้งเดียวต่อ turn, หลัง loop การเรียก tool (เฉพาะ turn ที่สำเร็จ) | session_id: str, user_message: str, assistant_response: str, conversation_history: list, model: str, platform: str | ignored |
on_session_start | สร้าง session ใหม่ (เฉพาะ turn แรก) | session_id: str, model: str, platform: str | ignored |
on_session_end | สิ้นสุดการเรียก run_conversation ทุกครั้ง + CLI exit | session_id: str, completed: bool, interrupted: bool, model: str, platform: str | ignored |
on_session_finalize | CLI/gateway ปิด session ที่ใช้งานอยู่ | session_id: str | None, platform: str | ignored |
on_session_reset | Gateway สลับ key session ใหม่ (/new, /reset) | session_id: str, platform: str | ignored |
Hook ส่วนใหญ่เป็นแบบ observer ที่ทำงานแล้วจบไป — ค่าที่ส่งคืนจะถูกละเลย ยกเว้น pre_llm_call ซึ่งสามารถ inject context เข้าไปใน conversation ได้
Callback ทั้งหมดควรรับ **kwargs เพื่อรองรับการเปลี่ยนแปลงในอนาคต หาก hook callback ล้มเหลว จะถูกบันทึกและข้ามไป ส่วน hook อื่นๆ และ agent จะยังคงทำงานตามปกติ
pre_llm_call context injection
นี่คือ hook เดียวที่ค่าที่ส่งคืนมีความสำคัญ เมื่อ callback pre_llm_call ส่งคืน dict ที่มี key "context" (หรือ plain string) Hermes จะ inject ข้อความนั้นเข้าไปใน user message ของ turn ปัจจุบัน นี่คือกลไกสำหรับ memory plugins, RAG integrations, guardrails, และ plugin ใดๆ ที่ต้องการให้ context เพิ่มเติมแก่ model
Return format
# Dict with context key
return {"context": "Recalled memories:\n- User prefers dark mode\n- Last project: hermes-agent"}
# Plain string (equivalent to the dict form above)
return "Recalled memories:\n- User prefers dark mode"
# Return None or don't return → no injection (observer-only)
return Noneค่าที่ส่งคืนที่ไม่ใช่ None และไม่ว่างเปล่า พร้อม key "context" (หรือ plain string ที่ไม่ว่างเปล่า) จะถูกรวบรวมและต่อท้าย user message สำหรับ turn ปัจจุบัน
How injection works
Context ที่ถูก inject จะถูกต่อท้าย user message ไม่ใช่ system prompt นี่คือการออกแบบที่จงใจ:
- Prompt cache preservation — system prompt จะคงที่ตลอดทุก turn Anthropic และ OpenRouter จะ cache system prompt prefix ดังนั้นการรักษาความเสถียรจึงช่วยประหยัด input tokens ได้กว่า 75%+ ในการสนทนาหลาย turn หาก plugins แก้ไข system prompt ทุก turn จะกลายเป็น cache miss
- Ephemeral — การ inject เกิดขึ้นเฉพาะเวลาเรียก API เท่านั้น user message เดิมใน conversation history จะไม่ถูกแก้ไข และไม่มีอะไรถูกบันทึกใน session database
- The system prompt is Hermes's territory — มันมีคำแนะนำเฉพาะ model, rules การบังคับใช้ tool, คำแนะนำด้านบุคลิกภาพ, และเนื้อหา skill ที่ถูก cache Plugins จะให้ context ควบคู่ไปกับ input ของผู้ใช้ ไม่ใช่การเปลี่ยนแปลงคำแนะนำหลักของ agent
Example: Memory recall plugin
"""Memory plugin — recalls relevant context from a vector store."""
import httpx
MEMORY_API = "https://your-memory-api.example.com"
def recall_context(session_id, user_message, is_first_turn, **kwargs):
"""Called before each LLM turn. Returns recalled memories."""
try:
resp = httpx.post(f"{MEMORY_API}/recall", json={
"session_id": session_id,
"query": user_message,
}, timeout=3)
memories = resp.json().get("results", [])
if not memories:
return None # nothing to inject
text = "Recalled context from previous sessions:\n"
text += "\n".join(f"- {m['text']}" for m in memories)
return {"context": text}
except Exception:
return None # fail silently, don't break the agent
def register(ctx):
ctx.register_hook("pre_llm_call", recall_context)Example: Guardrails plugin
"""Guardrails plugin — enforces content policies."""
POLICY = """You MUST follow these content policies for this session:
- Never generate code that accesses the filesystem outside the working directory
- Always warn before executing destructive operations
- Refuse requests involving personal data extraction"""
def inject_guardrails(**kwargs):
"""Injects policy text into every turn."""
return {"context": POLICY}
def register(ctx):
ctx.register_hook("pre_llm_call", inject_guardrails)Example: Observer-only hook (no injection)
"""Analytics plugin — tracks turn metadata without injecting context."""
import logging
logger = logging.getLogger(__name__)
def log_turn(session_id, user_message, model, is_first_turn, **kwargs):
"""Fires before each LLM call. Returns None — no context injected."""
logger.info("Turn: session=%s model=%s first=%s msg_len=%d",
session_id, model, is_first_turn, len(user_message or ""))
# No return → no injection
def register(ctx):
ctx.register_hook("pre_llm_call", log_turn)Multiple plugins returning context
เมื่อหลาย plugin ส่ง context จาก pre_llm_call ผลลัพธ์ของพวกมันจะถูกรวมด้วย double newlines และต่อท้าย user message ด้วยกัน ลำดับจะเป็นไปตามลำดับการค้นพบ plugin (ตามตัวอักษรของชื่อ directory plugin)
Register CLI commands
Plugins สามารถเพิ่ม subcommand tree ของตัวเองได้:
def _my_command(args):
"""Handler for hermes my-plugin <subcommand>."""
sub = getattr(args, "my_command", None)
if sub == "status":
print("All good!")
elif sub == "config":
print("Current config: ...")
else:
print("Usage: hermes my-plugin <status|config>")
def _setup_argparse(subparser):
"""Build the argparse tree for hermes my-plugin."""
subs = subparser.add_subparsers(dest="my_command")
subs.add_parser("status", help="Show plugin status")
subs.add_parser("config", help="Show plugin config")
subparser.set_defaults(func=_my_command)
def register(ctx):
ctx.register_tool(...)
ctx.register_cli_command(
name="my-plugin",
help="Manage my plugin",
setup_fn=_setup_argparse,
handler_fn=_my_command,
)หลังจากลงทะเบียนแล้ว ผู้ใช้สามารถรัน hermes my-plugin status, hermes my-plugin config ฯลฯ
Memory provider plugins ใช้แนวทางแบบ convention-based แทน: เพิ่มฟังก์ชัน register_cli(subparser) ไปยังไฟล์ cli.py ของ plugin ของคุณ ระบบการค้นหา memory plugin จะหาเจอโดยอัตโนมัติ — ไม่จำเป็นต้องเรียก ctx.register_cli_command() ดูรายละเอียดได้ที่ Memory Provider Plugin guide
Active-provider gating: คำสั่ง CLI ของ Memory plugin จะปรากฏก็ต่อเมื่อ provider นั้นเป็น memory.provider ที่ใช้งานอยู่ใน config เท่านั้น หากผู้ใช้ยังไม่ได้ตั้งค่า provider ของคุณ คำสั่ง CLI ของคุณจะไม่ทำให้ output help ดูรก
Register slash commands
Plugins สามารถลงทะเบียน slash commands ใน session ได้ — คำสั่งที่ผู้ใช้พิมพ์ระหว่างการสนทนา (เช่น /lcm status หรือ /ping) สิ่งเหล่านี้ใช้ได้ทั้งใน CLI และ gateway (Telegram, Discord, ฯลฯ)
def _handle_status(raw_args: str) -> str:
"""Handler for /mystatus — called with everything after the command name."""
if raw_args.strip() == "help":
return "Usage: /mystatus [help|check]"
return "Plugin status: all systems nominal"
def register(ctx):
ctx.register_command(
"mystatus",
handler=_handle_status,
description="Show plugin status",
)หลังจากลงทะเบียนแล้ว ผู้ใช้สามารถพิมพ์ /mystatus ใน session ใดก็ได้ คำสั่งจะปรากฏใน autocomplete, /help output, และเมนู bot ของ Telegram
Signature: ctx.register_command(name: str, handler: Callable, description: str = "")
| Parameter | Type | Description |
|---|---|---|
name | str | ชื่อคำสั่งโดยไม่มีเครื่องหมาย slash นำหน้า (เช่น "lcm", "mystatus") |
handler | Callable[[str], str | None] | ถูกเรียกด้วย raw argument string อาจเป็น async ได้ |
description | str | แสดงใน /help, autocomplete, และเมนู bot ของ Telegram |
ความแตกต่างที่สำคัญจาก register_cli_command():
register_command() | register_cli_command() | |
|---|---|---|
| Invoked as | /name ใน session | hermes name ใน terminal |
| Where it works | CLI sessions, Telegram, Discord, etc. | Terminal only |
| Handler receives | Raw args string | argparse Namespace |
| Use case | Diagnostics, status, quick actions | Complex subcommand trees, setup wizards |
Conflict protection: หาก plugin พยายามลงทะเบียนชื่อที่ขัดแย้งกับคำสั่ง built-in (help, model, new, ฯลฯ) การลงทะเบียนจะถูกปฏิเสธอย่างเงียบๆ พร้อมคำเตือน log คำสั่ง built-in จะมีลำดับความสำคัญเสมอ
Async handlers: Gateway dispatch จะตรวจจับและรอ async handlers โดยอัตโนมัติ ดังนั้นคุณสามารถใช้ได้ทั้ง sync หรือ async functions:
async def _handle_check(raw_args: str) -> str:
result = await some_async_operation()
return f"Check result: {result}"
def register(ctx):
ctx.register_command("check", handler=_handle_check, description="Run async check"):::tip คู่มือนี้ครอบคลุม general plugins (tools, hooks, slash commands, CLI commands) สำหรับ plugin ประเภทเฉพาะทาง โปรดดูที่:
- Memory Provider Plugins — cross-session knowledge backends
- Context Engine Plugins — alternative context management strategies :::
Distribute via pip
สำหรับการแชร์ plugin สาธารณะ ให้เพิ่ม entry point ใน Python package ของคุณ:
# pyproject.toml
[project.entry-points."hermes_agent.plugins"]
my-plugin = "my_plugin_package"pip install hermes-plugin-calculator
# Plugin auto-discovered on next hermes startupCommon mistakes
Handler doesn't return JSON string:
# Wrong — returns a dict
def handler(args, **kwargs):
return {"result": 42}
# Right — returns a JSON string
def handler(args, **kwargs):
return json.dumps({"result": 42})Missing **kwargs in handler signature:
# Wrong — will break if Hermes passes extra context
def handler(args):
...
# Right
def handler(args, **kwargs):
...Handler raises exceptions:
# Wrong — exception propagates, tool call fails
def handler(args, **kwargs):
result = 1 / int(args["value"]) # ZeroDivisionError!
return json.dumps({"result": result})
# Right — catch and return error JSON
def handler(args, **kwargs):
try:
result = 1 / int(args.get("value", 0))
return json.dumps({"result": result})
except Exception as e:
return json.dumps({"error": str(e)})Schema description too vague:
# Bad — model doesn't know when to use it
"description": "Does stuff"
# Good — model knows exactly when and how
"description": "Evaluate a mathematical expression. Use for arithmetic, trig, logarithms. Supports: +, -, *, /, **, sqrt, sin, cos, log, pi, e."extent analysis
TL;DR
The issue seems to be related to a Hermes plugin development, but the exact problem is unclear due to the large amount of provided text, which appears to be a guide on how to create a Hermes plugin.
Guidance
To better assist with the issue, I would need more specific information about the problem you're encountering. However, based on the provided text, here are some general steps and considerations for developing a Hermes plugin:
- Ensure Correct Plugin Structure: Verify that your plugin directory and files are correctly structured as per the Hermes plugin development guidelines.
- Check Manifest and Schemas: Make sure your
plugin.yamland schema definitions are accurate and follow the expected format. - Handler Functions: Confirm that your handler functions are correctly defined, handle potential exceptions, and return results in the expected JSON format.
- Registration: Ensure that your plugin and its components (tools, hooks, etc.) are properly registered in the
__init__.pyfile. - Testing: Thoroughly test your plugin to identify any issues or inconsistencies in its behavior.
Example
Given the lack of specific details about the issue, it's challenging to provide a concrete code example. However, ensuring that your plugin's __init__.py correctly registers tools and handles exceptions is crucial. For instance:
def register(ctx):
# Registering a tool
ctx.register_tool(
name="my_tool",
schema=my_schema,
handler=my_handler,
)
# Registering a hook
ctx.register_hook("post_tool_call", my_hook_handler)Notes
- The provided text does not specify a particular problem or error message related to a Hermes plugin, making it difficult to offer a precise solution.
- Developing a Hermes plugin involves several steps, including defining the plugin's structure, creating tool handlers, and registering the plugin and its components.
Recommendation
Without a clear description of the
Vote matrix · Quick signals
Still need to ship something?
×6Another batch ranked right after the header list — different links, same matching logic.
TRENDING
- Feature Request: Configurable per-minute rate limiting (RPM) for models to prevent 429 errors
- Android: Hermes App + Termux install share ~/.hermes and cause silent permission loops
- hermes update emits unicode-animations ANSI demo in non-interactive logs
- hermes update downgrades aiohttp from 3.13.4 to 3.13.3
- npm install warns about deprecated @babel/plugin-proposal-private-methods
- DingTalk inbound media URLs are skipped as unreadable native image paths
- fix(dashboard): ChatPage clears header action buttons on ALL pages, not just Sessions
- [Bug]: check_web_api_key() hardcodes built-in backends — third-party web search plugins silently disabled
- Hermes Web UI 修复经验:GatewayManager 补丁、进程 D 状态、数据库升级问题
- Telegram gateway can silently drop turn after /stop with response=0 chars while internal work continues
- Bug Report: v0.14.0 上下文污染 — 历史回复碎片回注到新请求
- Bug: hermes skills search table truncates Identifier column — install fails with copied value
- [skills-index-watchdog] Skills index is stale or degraded (degraded)
- Discord approval embed not rendering on web/mobile — embed data present in API but invisible
- Idea: Discord voice-channel participation / opt-in auto-join mode
- [Feature]: Claude Code--ultrawork
- build-arm64 job deterministically fails on cold cache (Azure SAS token expires mid-build)
- [Enhancement] computer_use: action=type should fall back to key events for terminal emulators (Ghostty/Terminal.app/iTerm2)
- Feature Request: Session Recovery on Temporary Provider Outage
- [Bug]: Hermes dashboard not working on NixOS (container)
- [Feature]: Add option to ignore @all/@everyone mentions in Feishu group chats
- QQ Bot WebSocket 频繁断开:长时间工具执行阻塞 asyncio 事件循环导致心跳超时
- patch tool: new_string escape sequences (\t) get written literally
- Feature Request: i18n / 多语言支持(国际化)
- Bug: web_crawl schema lets models auto-guess "instructions" instead of asking the user via clarify
- feat: `!command` prefix for direct shell execution (like Claude Code)
- Expose currently-running cron jobs via /api/jobs (or new endpoint)
- [Bug]: Kanban parent-child handoff: scratch workspace GC destroys artifacts before child can read them
- [Bug, Windows] hermes gateway restart loses session context — planned_stop_marker not written before SIGTERM
- [Bug]: Codex→DeepSeek fallback sends assistant turns without reasoning_content → HTTP 400 (require-side cross-provider failover)
- [Bug]: Update got stuck half way, reboot it, then ModuleNotFoundError: No module named 'hermes_cli'
- Kanban dispatcher corrupt-board handling and multi-profile gateway ownership ambiguity
- Gateway can resend a short fallback message when the real final Telegram response was already delivered
- [BUG] Bedrock: Fix 'Invalid API Key format' for presigned URL tokens
- Secret redaction corrupts code syntax in tool output (write_file, execute_code, terminal)
- Unable to connect Ollama Cloud with Pro Subscription to Hermes
- feat: fuzzy substring matching for /skill autocomplete
- PRD: Autonomous market-impact prediction briefing system
- Kanban dashboard should support task/card deep links
- [Feature] Native Feishu CardKit Streaming: consolidate best-in-class implementations
- [Feature]: Inject mental model into context when using Hindsight
- Interactive CLI hides tool output despite display.tool_progress=all, and hermes chat -v does not restore it
- fix(api_server): _handle_responses drops text.format JSON schema — structured output constraints silently ignored
- state.db FTS corruption goes undetected — no integrity check, no repair path
- bug: fallback routing can select text-only models for image requests and hide the primary failure
- feat(kanban): persist worker session_id per run and pass --resume on respawn after unblock
- feat(kanban): support GitHub/OMO lifecycle bridge for Xiyou-style automation
- Expose update-safe TUI/composer hooks for voice transcript and composer events
- Hide or configure voice transcript status rows in editable dictation mode
- [Feature]: Per-Tool / Per-Toolset Approval Policies
- Context compression creates orphan sessions missing from state.db
- messaging platform
- feat: Add read-only / silent monitoring mode for WhatsApp adapter
- double-.hermes path mismatch, the HOME env var leak, and the fallback-notification UX problem
- Bug: Plattform-Bundle name `hermes-yuanbao` in `agent.disabled_toolsets` silently kills ALL tools in gateway path (Telegram + cron), CLI unaffected
- CLI /yolo (in-chat) does not bypass dangerous command approvals — env var freeze + missing enable_session_yolo call
- OpenAI Codex provider crashes with "'NoneType' object is not iterable" (HTTP None)
- DEEPSEEK_API_KEY blocked by env blocklist in gateway process — cron jobs fail with deepseek provider
- fix(feishu): Card action callback routing issues - invalid message_id and unrecognized /card command
- Discord plugin: profiles without explicit `discord:` block silently get `require_mention=true` + `auto_thread=true` (regression in cc8e5ec2a)
- [Bug]: DISCORD_ALLOWED_ROLES ignored by gateway _is_user_authorized — role-authorized users get 'Unauthorized user' rejection
- [Bug]: /new, /clear, and /reset commands freeze the terminal session
- openai-codex subscription backend returns HTTP 200 with response.output=None, causing Slack/cron failures
- RFC: Centralized Model/Provider Registry
- bug: openai-codex provider — TypeError: 'NoneType' object is not iterable on every request (gpt-5.5)
- [Feature]: Source-aware instruction gate — architectural mitigation for indirect prompt injection
- Named custom provider stale_timeout_seconds ignored because runtime provider is normalized to `custom`
- guard test (ignore)
- [Feature]: per-platform LLM request_overrides (extra_body / reasoning_effort / service_tier)
- One-shot smoke: add Flue-backed orchestration fixture
- Gateway should not treat stale Codex app-server progress as final response after post-tool silence
- `docker_run_as_host_user: true` breaks bundled skills: Hermes home is mounted into `/root/.hermes` but the container runs as a non-root user (`HOME=/home/pn`)
- [Bug]: gateway api_server streaming bypasses server-side tool-call loop when chat_template_kwargs.enable_thinking=false (model emits tool name as plain text)
- [Feature]: Pre-install python-telegram-bot in Umbrel Hermes Docker image
- YouTube Shorts filter not working in youtube-content skill
- v0.15.0 PyPI release breaks ALL platforms — plugin.yaml manifests missing from package
- RFC: On-demand tool/skill/MCP discovery — decouple schema registration from process lifecycle
- Pixshelf: local-first stock photo workflow command center
- [Bug]: baoyu infographic skill should not silently bypass image_generate
- Pixshelf v1.5: manual submission tracking for stock agencies
- `hermes config set` silently accepts unknown keys, writing them where the runtime never reads
- Honcho memory prefetch hang on fresh CLI subprocess in v0.15.0 (regression from #27190)
- [Bug] v0.15.0 Docker image: stage2-hook.sh, main-wrapper.sh missing; container_boot module removed
- Feature: Reduce cache-read token overhead for DeepSeek providers — configurable cache_ttl, skills snapshot trimming, memory compaction
- Windows: three bugs from daily use (plugin discovery, gateway exit code, Unicode decode
- holographic memory: HRR silently degrades to FTS5 when numpy is missing
- Make max_tokens configurable for aux vision calls
- Conversation compression desynchronizes session ID between agent context and gateway routing, causing silent message loss
- [Bug]: v0.15.0 Docker image:The TUI cannot be used in the dashboard.
- cron: skip_memory=True blocks fact_store/memory tools from all cron jobs
- TUI: Node.js OOM crash when agent uses browser tools repeatedly
- feat: model_profiles — per-model toolset and memory config
- Automatic background skill patching disrupts active sessions (severe impact on local models)
- ensure_hermes_home() creates root-owned dirs in profile subdirectories when kanban workers are dispatched
- Feature: opt-in webhook bypass for DISCORD_ALLOW_BOTS — allow operator-initiated probes without weakening bot-loop guard
- v0.15.0: Codex requests fail HTTP 400 when participant display_name contains non-ASCII (emoji breaks input[].name pattern)
- Architecture: State Persistence Precedence (Memory vs Skills vs Hooks)
- [Bug]: cronjob tool: create action always fails with "schedule is required for create" even when parameters are provided
- codex-oauth: 'NoneType' object is not iterable in _run_codex_stream (gpt-5.5) — every turn fails non-retryably
- Docs/Config: Plugin local scope enablement ambiguity
- [Bug]: CLI freezes after using /new command (WSL)
- Profile Codex auth can ignore global credential pool when local state is stale
- [workflow-engine] CRITICAL: variable substitution crashes on regex metachars in user input
- [workflow-engine] HIGH: loop and bash nodes leak subprocesses on timeout
- [workflow-engine] HIGH: README documents config env vars the engine never reads
- [workflow-engine] MEDIUM: workflow_run rate limit bypassable via concurrent calls (TOCTOU)
- [workflow-engine] chore: manifest gaps, side-effectful register(), dead code, unauth kanban dispatch
- [mcp_lazy] HIGH: synthetic mcp_server_<name> stub collides with a real MCP server named 'server'
- [mcp_lazy] HIGH: promote_server eager flag documented but never persisted
- [mcp_lazy] MEDIUM: _prev_mode dict leaks and goes stale; not cleared on session evict
- [mcp_lazy] MEDIUM: get_pool has unlocked check-then-set race on pool creation
- [mcp_lazy] MEDIUM: pre_tool_call gives no guidance for unpromoted server-stub calls
- [mcp_lazy] chore: undeclared pre_tool_call hook, nonexistent 'mcp_load_tools' name in docs, missing tests
- [a2a_fleet] CRITICAL: server never auto-starts — register() runs outside an event loop
- [a2a_fleet] CRITICAL: auth_required defaults to false on a cross-machine surface
- [a2a_fleet] HIGH: remove invented disable() hook — loader never calls it, port leaks on reload
- [a2a_fleet] HIGH: plugin.yaml missing kind / provides_tools / requires_env (token env undeclared)
- [a2a_fleet] MEDIUM: tighten wide-open CORS, anonymous /health peer leak, and peer-URL SSRF
- [a2a_fleet] MEDIUM: relocate tests to tests/plugins/ and cover sync-register + auth-default paths
- xai-oauth auxiliary client incorrectly uses Responses API (CodexAuxiliaryClient), causing 403 on compression/vision/web_extract
- [Bug]: Direct Copilot gpt-5.5 large resumes are killed by 12s Codex TTFB watchdog
- [Bug]: `hermes uninstall` does not work on Windows
- TUI: Thinking block leaks raw JSON and Σ character
- Hostinger VPS: migration Hermes Agent → Hermes WebUI impossible (tini + UID mismatch + sessions)
- /goal judge over-continues exploratory goals unless the assistant explicitly says the goal is complete
- /goal auto-continuation can be amplified by preflight compression/session split and resurrect stale task state
- Dashboard infinite reload loop in loopback mode — GET /api/auth/me returns 401 on every page load
- [Bug]: Provider/LLM switch leaves stale encrypted_content causing 400 errors on Telegram sessions
- [Bug]: Infinite reload loop / React state loop on Sessions tab (Firefox + Chrome) — repeated 401 on /api/auth/me (v0.15.0)
- show_reasoning should work independently of streaming in CLI mode
- Feature Request: Strip reasoning/<think> blocks from TTS preprocessing
- mcp add / mcp test raise NameError when mcp package not installed
- v0.14.0 dashboard breaks behind reverse proxies — two regressions
- Skills hub creates empty category directories when no skills installed
- [Bug]: Custom endpoint: ChatCompletions returns content, but Hermes treats response as empty (v0.14.0)
- fix: atomic_replace() fails with EXDEV when HERMES_HOME is a cross-filesystem symlink
- fix(gateway): Feishu session cancellation orphans session guard, permanently blocking messages
- Custom endpoint pricing can overestimate Crof qwen3.5-9b cost by 1,000,000x
- MCP OAuth callback: module-level port global causes port collisions and structural weaknesses vs upstream
- Bug: send_message tool bypasses validate_media_delivery_path security check
- Proposal: Add Mnemosyne to official memory provider documentation
- feat(swarm): support custom verifier/synthesizer body + skills
- Template conversion failed
- Error occurred in the operation of the agent node in the workflow.
- PubSub client overrides Sentinel client when REDIS_USE_SENTINEL is enabled
- Frontend description of the Retrieval node output does not match the actual output
- JSON type input var raise Intenal server error
- cannot extract elements from a scalar
- 负载均衡 为模型配置多组凭据,并自动调用,此功能无法选择
- add models is error
- panic: could not create filter
- Persist partially generated messages when /chat-messages/:task_id/stop is called
- MCP server connection fails with 403 — request never leaves Dify (SSRF proxy suspected)
- Support durable async execution backends for long-running workflow steps
- [Xiaomi MiMo] Credentials validation fails with 400 "Not supported model mimo-v2-flash" when using Token Plan endpoint (v0.0.7)
- After clicking preview on a parent-child segmented knowledge base, it shows 0 chunks
- Retrieval score differs between UI upload (.docx) and API upload (.txt) despite identical chunk content and embedding model
- gemini cli crash again
- Xbox gift card code damage
- Damage caused by the gemini cli crash
- ioctl(2) failed, EBADF (Bad File Descriptor)
- Feat: Support Bun as an alternative runtime/package manager for updates and extensions
- fatal error again!!!!
- ioctl error
- Critical Crash: ioctl(2) failed, EBADF in ShellExecutionService.resizePty
- ioctl(2) failed, EBADF
- v0.44.0 Regression: Critical crash with ioctl(2) failed, EBADF during PTY resize
- Crash on startup: ioctl(2) failed, EBADF in UnixTerminal.resize
- Crash: `ioctl(2) failed, EBADF` in `node-pty` during PTY resize on macOS
- Gemini CLI crashes with `ioctl(2) failed, EBADF` in `node-pty` during `resizePty`
- Remote Role
- ERROR ioctl(2) failed, EBADF /home/mich
- RangeError: Maximum call stack size exceeded
- EBADF Error during folder creationg broke session and terminal glitches
- MAIP / Gargoub Project - Mediterania - North Coast
- Gemini cli crash again in this morning
- ERROR ioctl(2) failed, EBADF
- Verified node install fails — Checksum verification failed (Cloud)
- The extended debugging key did not arrive during registration.
- CollaborationPane unmounts collaboration store on single-user instances, causing permanent "No network connection" state
- Workflow cannot be saved when the name contains "->" (Potentially malicious string)
- automation does not work and does not show an error
- Raj Ai Automation
- Default Data Loader: DOMMatrix is not defined error
- Feature: Per-node execution timestamp overlay on canvas during workflow run
- AI Agent + Vertex `gemini-3.5-flash`: 400 "missing thought_signature" on sequential multi-turn tool calls (post-#24982)
- PDF Loader in Pinecone Vector Store fails due to pdf-parse version conflict (v2 not supported)
- emailReadImap: add UID deduplication, batch size cap, and numeric uid enforcement
- Manual node execution fails with "Could not find a node" when autosave is disabled (N8N_WORKFLOWS_AUTOSAVE_DISABLED)
- Schedule Trigger stopped firing — workflow Published & active, manual executions succeed, no automated fires for 2+ hours
- [MCP SDK] create_workflow_from_code intermittently returns HTTP 500, often as a false negative (workflow persists anyway, causing duplicates on retry)
- Credential-load wedge: workflows using googleApi/jwtAuth credentials silently fail to execute after key rotation
- Google Sheets Trigger every minute is not working manual Execute is working sent email
- [BUG] Plugin marketplace MCP connector remains stuck "still connecting" when mcp-remote requires OAuth
- [redacted at user request]
- Opus 4.7 behavioral regression: loaded instruction-following discipline degraded in recent Claude Code/Cowork updates
- [BUG] Tailscale via Homebrew CLI + Mac App Store GUI, both Macs on macOS, Cowork blocked by VPN detector despite Tailscale being a mesh VPN with no traffic interception
- stopShellPty on tab switch kills active sessions (exit 143) — regression in May 27 build
- [BUG] Long URLs are broken into multiple lines and become unclickable in terminal output
- [BUG] claude rm/stop/reap SIGKILLs background session tree without SIGTERM grace, orphaning git index.lock and similar
- [BUG] Default git workflow in the system prompt was pushed without context or consent
- [MODEL] Inconsistent output quality / Ignoring instructions (overfitting and inappropriate repetition of Korean vocabulary)
- You've hit your weekly limit · resets May 31 at 5pm (Asia/Shanghai)
- Paid yearly subscription silently downgraded to Free with no user action
- [Regression v2.1.153] Plugin bash hooks fail with "echo: write error: Permission denied" on Windows (claude-mem, shell: "bash")
- [BUG] Connector toggles in conversation are not clickable — must click text label instead
- [remote-control] Input from mobile app/browser not reaching host session — output works fine
- Model fails to read/reference CLAUDE.md contents despite being loaded in context
- [BUG] Claude Desktop reinstall destroys Code chat history (transcripts + Recents) while regular Chat history, project files, and memory all survive
- Bypass mode clamps to Accept Edits even with the toggle ON (Claude Code Desktop 1.9255.2 / CC 2.1.149)
- [BUG] TUI input freezes randomly mid-typing — entire prompt becomes unresponsive for minutes
- [BUG] Cowork downloads Linux ELF binary instead of macOS binary on macOS Sonoma 14.8.7 — exit code 132 (SIGILL) on every session
- [Feature Request] Persistent project memory — sessions forget everything on close, forcing users to keep many sessions open
- [Bug] Thread context stale after sleep/resume, returns outdated date and calendar data
- [FEATURE] Add context window usage indicator and warning before auto-compaction
- [BUG] Dictation error: Invalid character in header content ["x-config-keyterms"] on Windows
- [Bug] Anthropic API Error: Server rate limiting despite normal usage
- Does delegating work to `claude -p` subprocesses reduce context accumulation in the parent session?
- [BUG] Claude Code hangs on M1 Mac when terminal says "opening browser to sign in" and browser opens
- [BUG] Claude_Preview MCP preview_start spawns dev server with main-repo cwd instead of session's worktree cwd
- [Bug] Anthropic API Error: Server rate limiting during request execution
- [Bug] Anthropic API Error: Server rate limiting on concurrent requests
- [Bug] Ultraplan ready notification fires before cloud agent completes execution
- [BUG] API 500 ERROR ALL THROUGHOUT THE DAY
- [BUG] Cowork: Live Artifacts folder path changed in 1.9255.2, no automatic migration from Documents\Claude\Artifacts
- [Bug] Auto-compact never triggers despite statusline reporting "100% context used" (v2.1.153, Max sub, 200K mode)
- [BUG] [Desktop / macOS] 'Open in → New Window' detached session: font renders smaller than main, no per-window controls, Cmd+/Cmd- keystrokes routed to main window instead
- Feature request: option to switch between classic and new minimal UI
- [Feature Request] Show timestamps for each message
- [BUG] Terminal corruption when permission prompt appears while navigating Agent Teams agent selection menu
- [FEATURE] Allow users to customize the background color of the Claude desktop app beyond the current light/dark theme presets.
- [BUG] Statusline not displaying on Windows [fixed]
- Background agent UI Stop button is a no-op for stuck agents — process keeps consuming tokens
- Background agents silently die on session pause/resume — no completion notification, no work recovery
- Add option to hide email address from welcome banner
- [BUG] SSH Remote: `projects` field in remote ~/.claude.json becomes null after desktop restart — jsonl files intact, UI shows 'No messages yet' for every session
- [Bug] Claude Code not applying fixes despite claiming to complete tasks
- billing is unfair and poorly documented
- [BUG] Claude Code on the web: declared plugins inactive on first session, require restart to fully load
- [BUG] Restore from archive deleted sessions instead of restoring them
- [BUG] M365 connector fails with AADSTS50011 in Cowork — localhost vs 127.0.0.1 redirect URI mismatch
- claude agents: workflow slash-commands missing from dispatch-input completion (regression-adjacent to #61424)
- Claude Desktop's Info.plist missing TCC usage strings, blocks all EventKit-based MCP servers
- False-positive safety blocks on self-administered governance amendments — request for owner-authority mode for verified professional users
- [BUG] Stop pushing "AUTO"-mode
- [DOCS] Plugin marketplace guide omits `skipLfs` option for git-based sources
- [DOCS] MCP docs omit combined startup notification for MCP server and connector authentication
- [DOCS] Agent view docs omit macOS Privacy & Security identity for background agents
- [DOCS] Npm update docs do not explain release-channel behavior for `claude update`
- [DOCS] Agent SDK docs omit `subagent_type: "claude"` worktree and output persistence behavior
- [DOCS] Background session docs omit `$CLAUDE_JOB_DIR` temp-file behavior
- [FR] mask env-var values in 'claude mcp get <server>' output
- [FR] subagent worktrees should not inherit stale local 'user.email' from prior dispatches
- [BUG] Windows: Grep tool leaks rg.exe + conhost.exe processes (~2000 zombies / 14 GB RAM in long sessions)
- [BUG] Stats dashboard "Peak hour" appears off by one hour
- [BUG] Diff highlight (teal SGR background) bleeds past changed text in 2.1.150–2.1.153
- [FEATURE] confirm before deleting session
- Plugin PostToolUse hooks still silently skip in Claude Desktop / Cowork (re-filing closed #51904)
- /code-review skill: silent fallback to main...HEAD reviews other people's commits, and JSON-only output is hard to read
- Monitor tool doesn't source the shell snapshot like Bash does; PATH-dependent tools (jq, sleep, etc.) fail in Monitor commands on macOS/Nix
- [Bug] Long input lines truncated with ellipsis while typing instead of wrapping in terminal UI
- [FEATURE] VS Code extension: Render submitted user messages as Markdown in chat
- OSC 52 copy from Claude TUI doesn't reach clipboard inside tmux (regression in 2.1.146–2.1.153)
- [BUG] RemoteTrigger create/update returns HTTP 400 with circular error: "event_type is required" / "unknown field event_type"
- [BUG] Option to hide or minimize the built-in "status footer" (multi-line debug/cost panel) [re-raise of #31475]
- [Bug] Feedback submissions being closed without review or action
- [FEATURE] Word-jump cursor navigation in Chat input (option+arrow / bindable actions)
- [FEATURE] ! shell mode: filesystem tab completion
- [BUG] API Error: Usage credits required for 1M context
- claude agents: OSC 52 clipboard emission broken in tmux (regression in 2.1.146–2.1.153)
- CLI crashes on macOS 15 M3 - exit code 1
- [FEATURE] Support Cmd+V image paste from clipboard
- [FEATURE] Enhance claude.ai M365 connector to support MS Planner
- [BUG] Slash command autocomplete hijacks pasted absolute file paths starting with /
- PreToolUse hook `if` filter false-positives on complex Bash commands
- [BUG] Diff panel hangs/whites out
- Feature Request: Support drag-and-drop for binary documents (.wps, .doc, .docx, .xlsx, .pdf) in VS Code extension
- [BUG] activation of 1M context in VSCode
- [FEATURE] Support i18n / language localization for built-in slash command outputs
- Ctrl+V para colar imagens deixou de funcionar no CLI (Windows, PowerShell)
- [FEATURE] Please add Norwegian (Bokmål/Nynorsk) language support to the Claude Code interface
- [BUG] OTel log events (claude_code.user_prompt, api_request_body, tool_decision, hook_execution_complete) emitted with empty trace_id/span_id while sibling spans correlate correctly
- [BUG] Cowork crashes on every message, no VM logs generated, missing AppData\Roaming\Claude
- [FEATURE] first-class session handoff + per-session token budgets for unattended runs
- [FEATURE] Smart paste: convert clipboard code to file reference chips (like Cursor)
- [Feature Request] Restore chat pin functionality to title chat submenu
- [BUG] SIGILL issues with version 2.1.153
- [BUG] Cowork plugin upload fails with generic "Plugin validation failed" when a `description` field in any SKILL.md frontmatter contains angle brackets (`<…>`)
- [BUG] Desktop App 2.1.144+: startup scanner deletes cliSessionId from claude-code-sessions local files on every launch — session not found on disk
- [Feature Request] Add keyboard shortcut to copy last message with proper formatting
- [MODEL] Opus 4.7 not 1M
- Allow naming/renaming background agents in `claude agents` view
- Stale worktrees in .claude/worktrees/ are never cleaned up, consuming massive disk space
- Agent worktrees are never cleaned up, silently consuming disk space
- Subagent worktrees not auto-cleaned when reviewer writes scratch files
- [Bug] Skill initialization hangs for extended duration in Plan Mode
- Claude Desktop writes malformed registry Run entry (nested escaped quotes) - crashes Windows Task Manager and other Run-key parsers
- IME candidate window shows at bottom-right corner instead of caret position (Windows CMD)
- [BUG] Pressing 'Escape' doesn't close the /BTW conversation when the main conversation is asking for approval
- [BUG] Opus 4.7 (1M) intermittently emits empty-string values for tool_use.input fields, killing the session
- FleetView agent UI shows "running" with incrementing elapsed time after agent has returned
- /doctor flags context-scoped cmd+c binding as macOS conflict (false positive)
- [BUG] Text Rendering in Elvish
- Desktop app: Bypass Permissions mode flips to Accept Edits on first prompt (M5 / macOS 26.5)
- [Workaround] Date-Weekday Verification Hook — Prevents Claude from writing wrong weekdays
- [BUG] Claude Code create c:/memfs directory without asking me.
- [BUG] Claude Code's Bash execution waits forever with no processes running
- [BUG] usage stays stuck waiting for 5 hr limit after upgrading to premium seat in team plan
- [Workflow tool] resume cache is unreachable for nontrivial workflows because LLM dispatchers can't transcribe args byte-exactly
- Code review (Preview): "Add a repository" shows no results for private GitHub org repos
- [BUG] /context commands blows up context
- [Feature Request] Add precache expiry hook to enable proactive compaction before token eviction
- [BUG] Context indicator shows 0% at session start despite ~20K+ tokens already loaded
- [Feature Request] Add semantic search for --resume session history
- [Feature Request] Add session search, tagging, and filtering capabilities
- [BUG] Cowork Dispatch reports "desktop not available" on Windows 11 while standard Cowork works normally
- [Bug] Claude Code provides incorrect suggestions with high confidence despite errors
- defaultMode: acceptEdits silently overrides per-path permissions.ask rules for Write/Edit
- [FEATUR configurable tip interval (e.g. tipIntervalSeconds: 30 in settings)E]
- Plugin marketplace fails to load: schema rejects 'displayName' key (v2.1.153)
- claude agents: in-session copy uses broken OSC 52 path while overview correctly uses tmux buffer
- [BUG] Plugin agent descriptions (and custom agents) load unconditionally into context — no parity with disable-model-invocation for skills
- Crashed ultrareview consumed a free credit despite producing zero findings
- [Bug] Character rendering issue - invisible or missing text display
- [BUG] Cowork: processo Claude Code encerra com código 3 — .claude.json não contém token de autenticação (Windows 11 25H2)
- [BUG] 2.1.153 silently discards tools/list response from rmcp 0.12.0 HTTP MCP server (works in 2.1.152, wire-identical handshake)
- VS Code extension: option to auto-resume last session when reopening a workspace folder
- [Bug] Conversation continuation failure
- [BUG] Cowork crashes every time I start a new chat or attempt to continue an existing one in any project. The error displayed is: "Claude Code è andato in crash
- [Bug] Unannounced quota changes
- Native update/install fails with 'socket connection was closed unexpectedly' behind proxy — undici TLS incompatibility
- [BUG] Session name reverting after manual change
- [BUG] 非正常思考,上下文过长时,一直显示思考,点击interrupt按钮失效
- Honor `tools:` frontmatter when an agent is invoked via `@mention` — strip `Task` only when the agent did not declare it
- macOS TCC popup still recurring on v2.1.153 — "2.1.153" would like to access data from other apps
- Claude Code leaks pty handles — exhausts pseudo-terminals on macOS after long session
- [Bug] Agent fails to execute or respond to user input
- [BUG] Persistent "Expecting value: line 1 column 1 (char 0)" JSON parse error after tool execution
- [Feature Request] Implement proactive unit test coverage recommendations for recurring bugs
- VS Code panel lacks status line + terminal lacks image paste in Codespaces, forcing a tradeoff
- `/powerup` only shows ~10 lessons — allow viewing the full catalog
- [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin
- [Bug] VSCode terminal output displays corrupted text with garbled symbols
- [Feature Request] Add LaTeX/KaTeX math rendering to TUI
- [Bug] Sub-agent PR review results not validated by orchestrating agent
- Subagents on Pro 1M tier: trivial probes pass, real workloads fail at first tool call (probe-vs-workload divergence)
- Path-scoped rules and subdirectory CLAUDE.md not loaded when creating new files matching the pattern
- AskUserQuestion: cancelling during extended thinking poisons the whole session with 400 'thinking blocks cannot be modified' (2.1.153); concurrent prompts overwrite each other
- Ideas Missing from Claude Cowork Menu (Windows)
- [BUG_BOUNTY_SAFE_POC_2026] Prompt Injection RCE Test - Command Execution Proof
- [BUG] Cowork scheduled task: execution history row not showing after successful run
- Resuming an extended-thinking session fails permanently with 400 "thinking blocks cannot be modified" (transcript stores thinking text as empty but keeps signature)
- [Bug] Plugin-registered CwdChanged and FileChanged hooks don't fire (settings.json works) — v2.1.153
- Auto-archive on PR merge / branch delete — clarify autoArchiveSessions semantics or add dedicated opt-out
- `claude mcp add` echoes Authorization header value verbatim to stdout, leaks bearer tokens to terminal and session transcripts
- [BUG] Bug report — /insights skill, Claude Code The /insights skill outputs a malformed file path.
- Plugin slash commands render with '*'-inline format instead of two-column, despite matching official plugin shape
- [Bug] Unexpected long text generation without user input or goal
- [Bug] Thinking blocks causing task progression blocked without user modification
- [BUG] (Critical!) contamination by an unknown session simirlar to the report => [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin #63137
- [Critical] Opus 4.7 Korean output degeneration — Korean grammar itself collapses in long contexts
- [BUG] Title: Autocompact buffer persists across /clear — wastes tokens for irrelevant old context
- [Bug] Auto-Compact loses user input before processing in conversation history
- Feature: per-invocation effort parameter + runtime session-config introspection for skills
- Auto-mode classifier mislabels Azure DevOps vote -5 as "Reject" when denying PR vote actions
- [BUG] Claude Desktop and Claude Code CLI never re-register MCP tools after OAuth 2.1 handshake on a remote HTTP server
- [BUG] Workspace file tags leak across sessions
- [BUG] Ink renderer crashes on Windows 11 build 26200 (Canary) duplicate banners, terminal mode leaks, mid-operation aborts
- [BUG] Claude Code Desktop issue
- PTY master fd leak in Claude desktop app exhausts macOS kern.tty.ptmx_max after ~2-3 days
- [BUG] Claude Code — Session Management after Unexpected Interruption
- [Windows] Cowork OpenTelemetry exporter does not initialize - zero events emitted to any destination, including loopback
- [Bug] Opus 4.7: 400 `thinking blocks ... cannot be modified` on long extended-thinking sessions, triggered by history-altering events (scheduled prompts / parallel tool-call cancellation)
- [BUG] API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
- Multi-plugin custom marketplace: only first plugin registered in installed_plugins.json, skills don't load
- [BUG] Git push through the SDK's git proxy fan-outs into ~500 GitHub REST API calls, exhausting the 5,000/hour budget after a handful of pushes
- [BUG] Claude took liberties it really shouldn't with my global config
- [BUG] Agent window focus lost after navigating with arrow keys, causing scroll deadlock
- [BUG] `--model` flag silently ignored in interactive sessions (works in `--print` only)
- [BUG] Dispatch permanently shows "desktop appears offline" on Windows 11 - never worked on first use
- feat: support per-command enableWeakerNetworkIsolation as safer alternative to dangerouslyDisableSandbox
- /code-review outputs a raw JSON array instead of readable findings
- [BUG] Cowork — Additional allowed domains ignored on Team plan; same domain works on Pro plan
- Haiku
- [Bug] False positive blocking beneficial outcomes in tool execution
- 3P Bedrock SSO: credentials silently expire without triggering re-auth on day 2+
- CLAUDE_AUTOCOMPACT_PCT_OVERRIDE in settings.json env block silently ignored by autocompact logic
- Auto-compaction deletes main session JSONL before verifying summary completion, causing data loss
- [Bug] Claude Code not executing stated actions or producing expected results
- [FEATURE] Deferred Messages — Queue Input for End of Turn
- [BUG] Up/Down arrows in input box navigate history instead of moving cursor — regression in 2.1.149+
- Cancelling a parallel tool-call batch corrupts thinking blocks -> 400 "thinking blocks cannot be modified" permanently wedges the session
- Claude Code caused data loss, then contradicted itself about recovery (two incidents, one session)
- [Bug] Unclear error messages from Claude Code CLI
- [Bug] Agent tool rejecting due to context size limit exceeded
- claude agents: daemon and bg-spare processes spin at ~100% CPU when idle
- [BUG] Compaction fails with "context window limit" error even when context usage is low (e.g., 20%) — regression in v2.1.153
- Remote Control entitlement lost after May 27-28 incident — `Error: Remote Control is not yet enabled for your account` on active Max subscription
- PreToolUse hook exit code 2 does not block Write tool
- [Bug] Thinking blocks in latest assistant message are immutable
- GUI: dispatch file:// and custom-scheme clicks to OS shell handler
- Show current model in statusLine by default
- [Bug] Agent console becomes unresponsive to keyboard input after multiple agents initialized
- [FEATURE] PreToolUse hooks should have a way of updating the environment
- [Bug] Unable to start or use Claude Code CLI
- [BUG] Repository not visible in Claude Code web repo picker
- Session permanently wedged on 400 "thinking blocks cannot be modified" after parallel tool_results
- [Bug] @ autocomplete loses sibling repos after a file edit in multi-repo workspace
- Unclear error message when creating sub-agent without authentication
- [Bug] Anthropic API errors causing frequent failures and high token usage
- [BUG] @ mention file picker only shows packages, not individual files (desktop app - Code tab)
- [Bug] TUI panel footer remains sticky and consumes excessive terminal space
- PR-status polling exhausts GitHub GraphQL rate limit on repos with many open PRs
- [BUG] Windows: welcome panel not shown in some project folders (2.1.153)
- [Bug] Anthropic API Error: thinking blocks corrupted during context compaction with extended thinking enabled
- API 400 "thinking blocks cannot be modified" permanently bricks session during agent activation (interleaved thinking + tool use)
- Right-click Copy copies the whole message instead of the selection; pasted text retains dark background
- Mid-session model switch corrupts conversation when extended thinking is enabled (API 400: 'thinking blocks cannot be modified')
- [BUG] Markdown file links in chat output do not open files when clicked (VS Code extension)
- Stuck retry loop: `400 thinking blocks cannot be modified` on large interleaved-thinking turns using AskUserQuestion
- [FEATURE] Prompt user for approval before auto-compaction proceeds
- Custom MCP connectors not attachable to scheduled routines — no UUID discovery path
- [BUG] Claude in Chrome — Navigation blocked for teams.cloud.microsoft and outlook.cloud.microsoft after Microsoft domain migration**
- [BUG] Claude Desktop — Personal plugins panel renders list but is entirely non-interactive (macOS, v1.9255.2)
- [Bug] error when using Workflows
- [BUG] Persistent "update available" notification despite being on latest version
- [BUG] Sweep Agent from /code-review never completes
- [Bug] Tool calls not executing or returning results
- [FEATURE] Cloud-synced memory and settings across machines
- [Bug] Terminal UI freezes when Ctrl+O view exits during interactive prompt in plan mode
- Continuous api errors when using claude code with Opus 4.7 with thinking on low
- [Feature Request] Add support for installing and using previous Claude Code versions
- [Bug] Extended Thinking: Summarized thinking blocks fail signature validation when resent to API
- [Bug] Anthropic API Error: 'thinking' blocks cannot be modified
- [Bug] Anthropic API Error: Thinking blocks cannot be modified with extended thinking mode
- Feature request: Lazy/on-demand MCP server connections
- [Bug] Tool Arguments Parsed as String Instead of Object
- [Bug] Anthropic API Error: Insufficient context provided
- [Bug] Claude Opus occasionally uses moskovian(russian) orthography instead of Ukrainian in system-prompted responses
- Opus 4.8: backgrounded task completions (subagents AND Bash) crash with 400 "thinking blocks cannot be modified"
- [Bug] Opus 4.7 fabricates stable preferences ("my default") to rationalize arbitrary choices when challenged
- [Bug] Unable to update Claude Code CLI
- [BUG] Desktop app: /remote-control mints link + connects bridge (main.log) but in-chat link/QR panel never renders
- Feature: sessionColor and sessionName in .claude/settings.json
- [BUG] Anthropic API error: thinking blocks
- [FEATURE] Support Remote MCPs in Cowork as in Claude Code
- [Bug] Anthropic API Error: 400 Bad Request with Redacted Thinking - 0 4.7 & 4.8
- [Bug] Anthropic API Error: Cannot modify thinking blocks from different model versions
- Interleaved thinking + multi-tool turn corrupts thinking block (text blanked, signature kept) → permanent 400 'blocks must remain as they were'
- [BUG] Mode/permission changes mid-tool-loop (effortLevel: xhigh) poisons entire session
- Session failure log: Opus 4.6 ignores its own rules for an entire session
- [BUG] "400 Guardrail was enabled" error when using Claude Opus 4.8 with AWS Bedrock
- [Feature Request] Add subagent approach selection option to avoid accidental feedback
- Persistent 400 'thinking blocks in the latest assistant message cannot be modified' — interleaved thinking persisted with empty text + signature bricks sessions
- [BUG] DesktopvsApp
- [BUG] Opus 4.7 cache hit rate collapse after May 27 incident — Messages 1.1k→88.9k in 9 minutes, $630/session
- [Bug] Anthropic API Error: Invalid thinking block format
- [BUG] FUCK CLAUDE
- Opus 4.8 extended thinking: Stop hook block re-entry corrupts thinking blocks → 400
- [Bug] 4.8 Fails when accessing previous model history
- [Bug] Unintended File Modifications During Execution
- [DOCS] Model configuration docs omit lean system prompt default scope and model exceptions
- Add "Always allow globally" option to permission prompts
- Server-side model upgrade (Opus 4.7→4.8) wedges in-flight sessions with `thinking blocks cannot be modified` 400
- [DOCS] AskUserQuestion docs missing multiple-choice prompt decision threshold
- [DOCS] Agent view docs omit shell-command background session launch syntax
- [DOCS] Agent view dispatch input docs incorrectly imply `/logout` dispatches as a prompt
- [DOCS] Claude in Chrome docs omit connected-browser selection behavior
- [DOCS] Plugin docs omit `defaultEnabled: false` for opt-in plugins
- Feature Request: Customizable chat text colors for user and assistant messages
- [DOCS] `/plugin` Discover tab docs omit directory-based suggested plugin pins
- VSCode Chrome integration silently fails: 3 distinct bugs
- [DOCS] MCP stdio docs omit session environment variables
- [Bug] Anthropic API error on second request within session with Claude Opus 4.8
- Cowork emits a blank session "index" handoff on focus when a CLI session is paused awaiting input
- [DOCS] MCP docs omit `claude mcp list/get` pending-approval output for unapproved project servers
- [BUG] /compact fails with 400 error when last assistant turn contains thinking blocks
- [DOCS] `/claude-api` docs omit Opus 4.8 migration guidance
- [DOCS] Fast mode docs still recommend deprecated Opus 4.6 override variable
- [DOCS] Bash tool docs omit `$TMPDIR` consistency across sandboxed and unsandboxed commands
- [Bug] Anthropic API Error: 400 Bad Request on Extended Thinking
- [DOCS] Background session docs omit worktree-isolation behavior for spawned subagents
- Built-in mechanistic self-verification of verifiable claims (symmetric to the auto permission gate)
- [DOCS] Worktree docs do not clarify `worktree.baseRef: "head"` inside linked worktrees
- [BUG] Excessive RAM usage with multiple parallel chats (~10 sessions → 30 GB memory pressure, macOS OOM)
- [DOCS] Managed MCP policy docs omit invalid `allowedMcpServers`/`deniedMcpServers` entry behavior
- [DOCS] Effort docs omit `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` unsupported-model behavior
- Regression (2.1.147–2.1.150?): resuming an extended-thinking session after a CC update/model-switch → unrecoverable 400, session bricked
- [DOCS] Windows updater docs omit `claude.exe` in-use recovery guidance
- [DOCS] VS Code auto mode docs still tie mode-picker visibility to bypass-permissions setting
- [DOCS] MCP docs omit `/mcp` tool list and detail rendering behavior
- [DOCS] Fine-grained tool streaming docs still describe provider opt-in behavior
- bypassPermissions: session startup reads flat pref, GUI toggle writes per-account pref — they never sync
- [BUG] Claude Desktop Code tab causes disk write limit violation — 8.5GB in 11 min, macOS kills app (M5, v1.9659.1)
- Ultrareview v2.1.96: docs describe /tasks command + claude ultrareview --json subcommand that don't exist; findings hard to read after completion
- I'd be happy to help create a GitHub issue title, but I don't see the error message in your message. Could you please share the specific error you're encountering? That way I can generate an accurate and descriptive issue title for you.
- [BUG] Claude in Chrome `file_upload` rejects all scheduled-task sessions with misleading error (real cause: INVALID_SESSION)
- Extended thinking: signed thinking block 'cannot be modified' (400) permanently wedges session
- RTL text support for Hebrew (and Arabic) in Claude Code
- [Bug] Random errors occurring across multiple operations