185 Commits

Author SHA1 Message Date
quotentiroler
cc87c0ed7c Update contributing, deduplicate more functions 2026-02-09 19:21:33 -08:00
quotentiroler
53910f3643 Deduplicate more 2026-02-09 18:56:58 -08:00
Rami Abdelrazzaq
c2b2d535fb
fix: suggest /clear in context overflow error message (#12973)
* fix: suggest /reset in context overflow error message

When the context window overflows, the error message now suggests
using /reset to clear session history, giving users an actionable
recovery path instead of a dead-end error.

Closes #12940

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: suggest /reset in context overflow error message (#12973) (thanks @RamiNoodle733)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Rami Abdelrazzaq <RamiNoodle733@users.noreply.github.com>
2026-02-09 20:44:37 -06:00
max
223eee0a20
refactor: unify peer kind to ChatType, rename dm to direct (#11881)
* fix: use .js extension for ESM imports of RoutePeerKind

The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.

* fix tsconfig

* refactor: unify peer kind to ChatType, rename dm to direct

- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType

BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.

* fix tests

* test: update session key expectations for dmdirect migration

- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat

* fix: accept legacy 'dm' in session key parsing for backward compat

getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.

* test: add explicit backward compat tests for dmdirect migration

- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work

* feat: backward compat for resetByType.dm config key

* test: skip unix-path Nix tests on Windows
2026-02-09 09:20:52 +09:00
Tyler Yust
191da1feb5
fix: context overflow compaction and subagent announce improvements (#11664) (thanks @tyler6204)
* initial commit

* feat: implement deriveSessionTotalTokens function and update usage tests

* Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens.
* Updated usage tests to include cases for derived session total tokens.
* Refactored session usage calculations in multiple files to utilize the new function for improved accuracy.

* fix: restore overflow truncation fallback + changelog/test hardening (#11551) (thanks @tyler6204)
2026-02-07 20:02:32 -08:00
Tyler Yust
0deb8b0da1
fix: recover from context overflow caused by oversized tool results (#11579)
* fix: gracefully handle oversized tool results causing context overflow

When a subagent reads a very large file or gets a huge tool result (e.g.,
gh pr diff on a massive PR), it can exceed the model's context window in
a single prompt. Auto-compaction can't help because there's no older
history to compact — just one giant tool result.

This adds two layers of defense:

1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens)
   applied in the session tool result guard before persistence. This
   prevents extremely large tool results from being stored in full,
   regardless of model context window size.

2. Recovery: When context overflow is detected and compaction fails,
   scan session messages for oversized tool results relative to the
   model's actual context window (30% max share). If found, truncate
   them in the session via branching (creating a new branch with
   truncated content) and retry the prompt.

The truncation preserves the beginning of the content (most useful for
understanding what was read) and appends a notice explaining the
truncation and suggesting offset/limit parameters for targeted reads.

Includes comprehensive tests for:
- Text truncation with newline-boundary awareness
- Context-window-proportional size calculation
- In-memory message truncation
- Oversized detection heuristics
- Guard-level size capping during persistence

* fix: prep fixes for tool result truncation PR (#11579) (thanks @tyler6204)
2026-02-07 17:40:51 -08:00
Tak Hoffman
f0722498a4
Agents: include runtime shell (#1835)
* Agents: include runtime shell

* Agents: fix compact runtime build

* chore: fix CLAUDE.md formatting, security regex for secret

---------

Co-authored-by: Tak hoffman <takayukihoffman@gmail.com>
Co-authored-by: quotentiroler <max.nussbaumer@maxhealth.tech>
2026-02-07 09:32:31 -08:00
Peter Steinberger
0daf416908 fix(agents): add Opus 4.6 forward-compat fallback 2026-02-06 16:56:21 -08:00
Yida-Dev
4216449405
fix: guard resolveUserPath against undefined input (#10176)
* fix: guard resolveUserPath against undefined input

When subagent spawner omits workspaceDir, resolveUserPath receives
undefined and crashes on .trim().  Add a falsy guard that falls back
to process.cwd(), matching the behavior callers already expect.

Closes #10089

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden runner workspace fallback (#10176) (thanks @Yida-Dev)

* fix: harden workspace fallback scoping (#10176) (thanks @Yida-Dev)

* refactor: centralize workspace fallback classification and redaction (#10176) (thanks @Yida-Dev)

* test: remove explicit any from utils mock (#10176) (thanks @Yida-Dev)

* security: reject malformed agent session keys for workspace resolution (#10176) (thanks @Yida-Dev)

---------

Co-authored-by: Yida-Dev <reyifeijun@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
2026-02-06 13:16:58 -05:00
Tyler Yust
370bbcd89b
Model: add strict gpt-5.3-codex fallback for OpenAI Codex (fixes #9989) (#9995)
* Model: allow forward-compatible OpenAI Codex GPT-5 IDs

* Model: scope Codex fallback to gpt-5.3-codex

* fix: reorder codex fallback before providerCfg, add ordering test, changelog (#9989) (thanks @w1kke)

---------

Co-authored-by: Robin <4robinlehmann@gmail.com>
2026-02-05 16:23:18 -08:00
Glucksberg
d4c560853c
fix(errors): show clear billing error instead of cryptic API response (#8391)
* fix(errors): return clear billing error message instead of cryptic raw error (#8136)

When an LLM API provider returns a credit/billing-related error (HTTP 402,
insufficient credits, low balance, etc.), OpenClaw now shows a clear,
actionable message instead of passing through the raw/cryptic error text:

  ⚠️ API provider returned a billing error — your API key has run out of
  credits or has an insufficient balance. Check your provider's billing
  dashboard and top up or switch to a different API key.

Changes:
- formatAssistantErrorText: detect billing errors via isBillingErrorMessage()
  and return a user-friendly message (placed before the generic HTTP/JSON
  error fallthrough)
- sanitizeUserFacingText: same billing detection for the sanitization path
- pi-embedded-runner/run.ts: add billingFailure detection in the profile
  exhaustion fallback, so the FailoverError message is billing-specific
- Added 3 new tests for credit balance, HTTP 402, and insufficient credits

* fix: extract billing error message to shared constant
2026-02-05 13:58:43 -08:00
Glucksberg
4e1a7cd60c
fix: allow multiple compaction retries on context overflow (#8928)
Previously, overflowCompactionAttempted was a boolean flag set once, preventing
recovery when a single compaction wasn't enough. Change to a counter allowing up
to 3 attempts before giving up. Also add diagnostic logging on overflow events to
help debug early-overflow issues.

Fixes sessions that hit context overflow during long agentic turns with many tool
calls, where one compaction round isn't sufficient to bring context below limits.
2026-02-05 13:58:37 -08:00
Gustavo Madeira Santana
392bbddf29
Security: owner-only tools + command auth hardening (#9202)
* Security: gate whatsapp_login by sender auth

* Security: treat undefined senderAuthorized as unauthorized (opt-in)

* fix: gate whatsapp_login to owner senders (#8768) (thanks @victormier)

* fix: add explicit owner allowlist for tools (#8768) (thanks @victormier)

* fix: normalize escaped newlines in send actions (#8768) (thanks @victormier)

---------

Co-authored-by: Victor Mier <victormier@gmail.com>
2026-02-04 19:49:36 -05:00
Tyler Yust
64df61f697 feat(cron): enhance delivery handling and testing for isolated jobs
- Introduced new properties for explicit message targeting and message tool disabling in the EmbeddedRunAttemptParams type.
- Updated cron job tests to validate best-effort delivery behavior and handling of delivery failures.
- Added logic to clear delivery settings when switching session targets in cron jobs.
- Improved the resolution of delivery failures and best-effort logic in the isolated agent's run function.

This update enhances the flexibility and reliability of delivery mechanisms in isolated cron jobs, ensuring better handling of message delivery scenarios.
2026-02-04 01:03:59 -08:00
Tyler Yust
3f82daefd8 feat(cron): enhance delivery modes and job configuration
- Updated isolated cron jobs to support new delivery modes: `announce` and `none`, improving output management.
- Refactored job configuration to remove legacy fields and streamline delivery settings.
- Enhanced the `CronJobEditor` UI to reflect changes in delivery options, including a new segmented control for delivery mode selection.
- Updated documentation to clarify the new delivery configurations and their implications for job execution.
- Improved tests to validate the new delivery behavior and ensure backward compatibility with legacy settings.

This update provides users with greater flexibility in managing how isolated jobs deliver their outputs, enhancing overall usability and clarity in job configurations.
2026-02-04 01:03:59 -08:00
Vignesh Natarajan
9bef525944 chore: apply formatter 2026-02-02 23:45:05 -08:00
Vignesh Natarajan
5d3af3bc62 feat (memory): Implement new (opt-in) QMD memory backend 2026-02-02 23:45:05 -08:00
Justin
0da6de6624 Agent: repair malformed tool calls and session files 2026-02-02 23:56:27 +00:00
Peter Steinberger
b8174decf3 fix: resolve system prompt overrides 2026-02-02 02:10:13 -08:00
Peter Steinberger
d03eca8450 fix: harden plugin and hook install paths 2026-02-02 02:07:47 -08:00
Tyler Yust
8d2f98fb01
Fix subagent announce failover race (always emit lifecycle end + treat timeout=0 as no-timeout) (#6621)
* Fix subagent announce race and timeout handling

Bug 1: Subagent announce fires before model failover retries finish
- Problem: CLI provider emitted lifecycle error on each attempt, causing
  subagent registry to prematurely call beginSubagentCleanup() and announce
  with incorrect status before failover retries completed
- Fix: Removed lifecycle error emission from CLI provider's attempt-level
  .catch() in agent-runner-execution.ts. Errors still propagate to
  runWithModelFallback for retry, but no intermediate lifecycle events
  are emitted. Only the final outcome (after all retries) emits lifecycle
  events.

Bug 2: Hard 600s per-prompt timeout ignores runTimeoutSeconds=0
- Problem: When runTimeoutSeconds=0 (meaning 'no timeout'), the code
  returned the default 600s timeout instead of respecting the 0 setting
- Fix: Modified resolveAgentTimeoutMs() to treat 0 as 'no timeout' and
  return a very large timeout value (30 days) instead of the default.
  This avoids setTimeout issues with Infinity while effectively providing
  unlimited time for long-running tasks.

* fix: emit lifecycle:error for CLI failures (#6621) (thanks @tyler6204)

* chore: satisfy format/lint gates (#6621) (thanks @tyler6204)

* fix: restore build after upstream type changes (#6621) (thanks @tyler6204)

* test: fix createSystemPromptOverride tests to match new return type (#6621) (thanks @tyler6204)
2026-02-02 02:06:14 -08:00
Peter Steinberger
34dd7324d9 fix: restore lint/build gates 2026-02-02 01:25:40 -08:00
Tyler Yust
9ef24fd400
fix: flush block streaming on paragraph boundaries for chunkMode=newline (#7014)
* feat: Implement paragraph boundary flushing in block streaming

- Added `flushOnParagraph` option to `BlockReplyChunking` for immediate flushing on paragraph breaks.
- Updated `EmbeddedBlockChunker` to handle paragraph boundaries during chunking.
- Enhanced `createBlockReplyCoalescer` to support flushing on enqueue.
- Added tests to verify behavior of flushing with and without `flushOnEnqueue` set.
- Updated relevant types and interfaces to include `flushOnParagraph` and `flushOnEnqueue` options.

* fix: Improve streaming behavior and enhance block chunking logic

- Resolved issue with stuck typing indicator after streamed BlueBubbles replies.
- Refactored `EmbeddedBlockChunker` to streamline fence-split handling and ensure maxChars fallback for newline chunking.
- Added tests to validate new chunking behavior, including handling of paragraph breaks and fence scenarios.
- Updated changelog to reflect these changes.

* test: Add test for clamping long paragraphs in EmbeddedBlockChunker

- Introduced a new test case to verify that long paragraphs are correctly clamped to maxChars when flushOnParagraph is enabled.
- Updated logic in EmbeddedBlockChunker to handle cases where the next paragraph break exceeds maxChars, ensuring proper chunking behavior.

* refactor: streamline logging and improve error handling in message processing

- Removed verbose logging statements from the `processMessage` function to reduce clutter.
- Enhanced error handling by using `runtime.error` for typing restart failures.
- Updated the `applySystemPromptOverrideToSession` function to accept a string directly instead of a function, simplifying the prompt application process.
- Adjusted the `runEmbeddedAttempt` function to directly use the system prompt override without invoking it as a function.
2026-02-02 01:22:41 -08:00
David Iach
4e4ed2ea17
fix(security): cap Slack media downloads and validate Slack file URLs (#6639)
* Security: cap Slack media downloads and validate Slack file URLs

* Security: relax web media fetch cap for compression

* Fixes: sync pi-coding-agent options

* Fixes: align system prompt override type

* Slack: clarify fetchImpl assumptions

* fix: respect raw media fetch cap (#6639) (thanks @davidiach)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-02 00:48:07 -08:00
Mario Zechner
cf1d3f7a7c fix: update pi packages to 0.51.0, remove bogus type augmentation
- Update @mariozechner/pi-agent-core, pi-ai, pi-coding-agent, pi-tui to 0.51.0
- Delete src/types/pi-coding-agent.d.ts (declared additionalExtensionPaths which SDK never supported)
- Fix ToolDefinition.execute signature (parameter order changed in 0.51.0)
- Remove dead additionalExtensionPaths from createAgentSession calls
2026-02-02 01:52:33 +01:00
Peter Steinberger
e58291e070 fix: align embedded runner with pi-coding-agent API 2026-02-01 15:51:46 -08:00
Peter Steinberger
3367b2aa27 fix: align embedded runner with session API changes 2026-02-01 15:06:55 -08:00
Peter Steinberger
8eb11bd304
fix: wire before_tool_call hook into tool execution (#6570) (thanks @ryancnelson) (#6660) 2026-02-01 14:52:11 -08:00
Peter Steinberger
bcde2fca5a fix: align embedded agent session setup 2026-02-01 22:23:16 +00:00
Peter Steinberger
083ec9325e fix: cover OpenRouter attribution headers 2026-02-01 19:30:33 +00:00
Alex Atallah
74039fc0f1 Add openrouter attribution headers 2026-02-01 19:24:55 +00:00
Evan
5d3c898a94 fix: update compaction safeguard to respect context window tokens 2026-02-01 19:52:56 +05:30
Peter Steinberger
e4f7155369 fix(ci): repair lint/build checks 2026-02-01 10:20:27 +00:00
Mario Zechner
ba4a55f6d9 fix(agents): update cacheControlTtl to cacheRetention for pi-ai 0.50.9
- Update @mariozechner/pi-ai and pi-agent-core to 0.50.9
- Rename cacheControlTtl to cacheRetention with values none/short/long
- Add backwards compatibility mapping: 5m->short, 1h->long
- Remove dead OpenRouter check (uses openai-completions API)
- Default new configs to cacheRetention: short
2026-02-01 09:50:52 +01:00
cpojer
f06dd8df06
chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
Peter Steinberger
a42e1c82d9 fix: restore tsc build and plugin install tests 2026-01-31 07:54:15 +00:00
cpojer
952b0f8c48
chore: Fix TypeScript errors 2/n. 2026-01-31 16:42:40 +09:00
cpojer
e5eb9610dc
chore: Fix TypeScript errors 1/n. 2026-01-31 16:38:03 +09:00
cpojer
5ceff756e1
chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
cpojer
9c4cbaab7b
chore: Enable eslint/no-unused-vars. 2026-01-31 16:06:39 +09:00
cpojer
15792b153f
chore: Enable more lint rules, disable some that trigger a lot. Will clean up later. 2026-01-31 16:04:04 +09:00
Mario Zechner
cbc405c9e3 Agents: update pi-coding-agent API usage 2026-01-31 07:35:52 +01:00
Peter Steinberger
d2a852b982 fix: align embedded session setup with sdk 2026-01-31 06:22:24 +00:00
Peter Steinberger
e9f0be06eb fix: repair docker build typing 2026-01-31 06:50:56 +01:00
Peter Steinberger
08ed62852a chore: update deps and pi model discovery 2026-01-31 06:45:57 +01:00
Mario Zechner
9b1a6b30d9 Tests: update pi SDK mocks 2026-01-31 05:23:53 +01:00
Mario Zechner
c0a6e675a3 Agents: update pi dependencies to 0.50.7 2026-01-31 04:20:12 +01:00
Peter Steinberger
9a7160786a refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
Shadow
20c0d1f2c5 fix: avoid global image size regression 2026-01-27 16:02:19 -06:00
{Suksham-sharma}
b59ea0e3f3 fix: prevent infinite retry loop for images exceeding 5MB
- Change MAX_IMAGE_BYTES from 6MB to 5MB to match Anthropic API limit
- Add isImageSizeError() to detect image size errors from API
- Handle image size errors with user-friendly message instead of retry
- Prevent failover for image size errors (not retriable)

Fixes #2271
2026-01-27 16:02:19 -06:00