PicoClaw

PicoClaw stops presenting inert LINE webhook settings as real

PicoClaw proposes warnings for LINE webhook host and port settings that the runtime never consumes, documents the underlying bug and adds prompt-cache token accounting to provider debug output. The cluster makes effective configuration and hidden cost visible.

← Back to homeOriginal source ↗

sipeed/picoclaw PR #3329 is the inspected primary source: “fix(line): warn on inert webhook_host / webhook_port instead of seeding them.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- sipeed/picoclaw PR #3329 was created 2026-08-11T16:48:45Z and was open at inspection; its title is “fix(line): warn on inert webhook_host / webhook_port instead of seeding them.” - sipeed/picoclaw issue #3328 was created 2026-08-11T04:59:23Z and was open at inspection; its title is “[BUG] line.settings.webhook_host / webhook_port are never read — they have defaults and docs but no consumer.” - sipeed/picoclaw PR #3317 was created 2026-08-04T08:27:12Z and was open at inspection; its title is “feat(providers): log prompt cache tokens in LLM response debug output.” - The repository reported 29845 stars, 51 open issues, default branch main, and last push 2026-08-07T18:18:20Z. - The latest tagged-release baseline checked was nightly published 2026-07-02T01:26:53Z.

What changed

sipeed/picoclaw PR #3329 reports: Fixes #3328. Problem line.settings.webhook_host / webhook_port are declared, defaulted, and env-bound, but nothing reads them. The LINE channel implements WebhookPath() and is mounted as a handler on the **shared** gateway HTTP server (pkg/channels/manager.go, m.mux.Handle(wh.WebhookPath(), wh)) — it has no listener of its own, so there is no port for it to bind. The only other references are the openclaw importer, a test fixture, and a Web UI label. The webhook is actually served on gateway.port (default **18790**), while every fresh config was seeded with webhook_port: 18791. Both numbers are plausible and adjacent, and nothing distinguishes them. Anyone putting a reverse proxy or tunnel in front of PicoClaw reads the config, points at 18791, and gets a listener that never answers — while channel-enabled, process-healthy, tunnel-connected, and credentials-valid all report fine. The failure surfaces only as webhooks silently 404ing. Change Option (1) from the issue — stop listed them — plus the warning the issue suggests for configs that already set them. **Defaults** (pkg/config/defaults.go): drop both keys from the LINE channel, so new configs no longer

sipeed/picoclaw issue #3328 reports: Summary channel_list.line.settings.webhook_host and webhook_port exist in the config struct, are given defaults, and are documented — but nothing in the codebase reads them. Setting either has no effect, and there is no warning to say so. Evidence Declared: pkg/config/config.go:606-607 — WebhookHost string, WebhookPort int, both with json: tags and env: bindings pkg/config/defaults.go:546-547 — defaults "webhook_host": "0.0.0.0", "webhook_port": 18791 docs/channels/line/README.md documents them as configurable Consumed: nowhere. grep -rn "WebhookPort\|WebhookHost" --include=*.go pkg/channels/ returns no reads. The LINE channel only implements WebhookPath() (pkg/channels/line/line.go:126-132) and is mounted as a handler on the **shared** HTTP server (pkg/channels/manager.go:1144, m.mux.Handle(wh.WebhookPath(), wh)). There is no per-channel listener, so there is no port for the channel to bind. The port that actually serves the webhook is gateway.port (pkg/config/defaults.go:302, default 18790). Why this is worth fixing rather than documenting On a deployed device the config read "webhook_port": 18791 while the process was listening on 18790: Both numbers are plausible, adjacent, and neither the config nor the logs indicate which one is real. Anyone setting up a reverse proxy or tunnel in front of this reads

sipeed/picoclaw PR #3317 reports: Problem The gateway logs only prompt_tokens / completion_tokens / total_tokens on its "LLM response" debug line. Providers like DeepSeek (via Cloudflare AI Gateway) report cache metadata in the same usage object: This metadata is parsed but then discarded: UsageInfo has no fields for it, and the debug log line never emits it. Any token-usage collector consuming the log therefore cannot report the real cache hit/miss split — it can only estimate (or treat cache as unknown). Fix 1. **pkg/providers/protocoltypes/types.go** — extend UsageInfo with: PromptCacheHitTokens *int (prompt_cache_hit_tokens, DeepSeek-style) PromptCacheMissTokens *int (prompt_cache_miss_tokens) PromptTokensDetails *PromptTokensDetails (prompt_tokens_details.cached_tokens, OpenAI-compatible style) Pointers distinguish "provider did not report" (nil) from a real zero (cold cache). 2. **pkg/agent/pipeline_llm.go** — surface those fields on the LLM response debug log line when present. No provider behavior changes; purely additive logging. Verified against a live DeepSeek-via-AIG call and a full rebuild on linux/arm64.

Why it matters

Accepted-but-ignored settings are operational lies. The same applies to cache accounting: operators need to see what the runtime actually used, not merely what a file or UI allowed them to enter. The operator test is whether visible output, retained state and authority still describe the same event after retries, background work or restart.

Current

The primary record was open when captured on 2026-08-12. The tagged-release baseline was nightly published 2026-07-02T01:26:53Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/sipeed/picoclaw/pull/3329. Supporting records are https://github.com/sipeed/picoclaw/issues/3328 and https://github.com/sipeed/picoclaw/pull/3317. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Reject or clearly mark inert keys, expose one effective-config view, and keep token diagnostics structured enough to compare configured intent with provider behavior. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.