leotwang
910c654807
test(config): add schema regression tests for browser.extraArgs
2026-03-02 13:47:59 +00:00
leotwang
925117d277
config: add extraArgs to browser zod schema
2026-03-02 13:47:59 +00:00
Peter Steinberger
b02b94673f
refactor: dedupe runtime and helper flows
2026-03-02 12:55:47 +00:00
Peter Steinberger
8e0ca219a4
test(perf): precreate plugin config validation fixtures
2026-03-02 12:06:48 +00:00
Peter Steinberger
43bffe7bdc
test(perf): cache plugin fixtures and streamline shell tests
2026-03-02 11:35:13 +00:00
Peter Steinberger
f5a265a51a
test(sessions): normalize cross-agent path assertions
2026-03-02 10:08:52 +00:00
Peter Steinberger
fd4d157e45
test(config): reuse fixtures for faster validation
2026-03-02 09:47:29 +00:00
Vincent Koc
5d53b61d9e
fix(browser): honor profile attachOnly for loopback CDP ( #31429 )
...
* config(browser): allow profile attachOnly field
* config(schema): accept profile attachOnly
* browser(config): resolve per-profile attachOnly
* browser(runtime): honor profile attachOnly checks
* browser(routes): expose profile attachOnly in status
* config(labels): add browser profile attachOnly label
* config(help): document browser profile attachOnly
* test(config): cover profile attachOnly resolution
* test(browser): cover profile attachOnly runtime path
* test(config): include profile attachOnly help target
* changelog: note profile attachOnly override
* browser(runtime): prioritize attachOnly over loopback ownership error
* test(browser): cover attachOnly ws-failure ownership path
2026-03-02 00:49:57 -08:00
Vincent Koc
22be0c5801
fix(browser): support configurable CDP auto-port range start ( #31352 )
...
* config(browser): add cdpPortRangeStart type
* config(schema): validate browser.cdpPortRangeStart
* config(labels): add browser.cdpPortRangeStart label
* config(help): document browser.cdpPortRangeStart
* browser(config): resolve custom cdp port range start
* browser(profiles): allocate ports from resolved CDP range
* test(browser): cover cdpPortRangeStart config behavior
* test(browser): cover cdpPortRangeStart profile allocation
* test(browser): include CDP range fields in remote tab harness
* test(browser): include CDP range fields in ensure-tab harness
* test(browser): include CDP range fields in bridge auth config
* build(browser): add resolved CDP range metadata
* fix(browser): fallback CDP port allocation to derived range
* test(browser): cover missing resolved CDP range fallback
* fix(browser): remove duplicate resolved CDP range fields
* fix(agents): provide resolved CDP range in sandbox browser config
* chore(browser): format sandbox bridge resolved config
* chore(browser): reformat sandbox imports to satisfy oxfmt
2026-03-01 23:50:50 -08:00
Tyler Yust
d0ac1b0195
feat: add PDF analysis tool with native provider support ( #31319 )
...
* feat: add PDF analysis tool with native provider support
New `pdf` tool for analyzing PDF documents with model-powered analysis.
Architecture:
- Native PDF path: sends raw PDF bytes directly to providers that support
inline document input (Anthropic via DocumentBlockParam, Google Gemini
via inlineData with application/pdf MIME type)
- Extraction fallback: for providers without native PDF support, extracts
text via pdfjs-dist and rasterizes pages to images via @napi-rs/canvas,
then sends through the standard vision/text completion path
Key features:
- Single PDF (`pdf` param) or multiple PDFs (`pdfs` array, up to 10)
- Page range selection (`pages` param, e.g. "1-5", "1,3,7-9")
- Model override (`model` param) and file size limits (`maxBytesMb`)
- Auto-detects provider capability and falls back gracefully
- Same security patterns as image tool (SSRF guards, sandbox support,
local path roots, workspace-only policy)
Config (agents.defaults):
- pdfModel: primary/fallbacks (defaults to imageModel, then session model)
- pdfMaxBytesMb: max PDF file size (default: 10)
- pdfMaxPages: max pages to process (default: 20)
Model catalog:
- Extended ModelInputType to include "document" alongside "text"/"image"
- Added modelSupportsDocument() capability check
Files:
- src/agents/tools/pdf-tool.ts - main tool factory
- src/agents/tools/pdf-tool.helpers.ts - helpers (page range, config, etc.)
- src/agents/tools/pdf-native-providers.ts - direct API calls for Anthropic/Google
- src/agents/tools/pdf-tool.test.ts - 43 tests covering all paths
- Modified: model-catalog.ts, openclaw-tools.ts, config schema/types/labels/help
* fix: prepare pdf tool for merge (#31319 ) (thanks @tyler6204)
2026-03-01 22:39:12 -08:00
Sid
3002f13ca7
feat(config): add openclaw config validate and improve startup error messages ( #31220 )
...
Merged via squash.
Prepared head SHA: 4598f2a541f0bde300a096ef51638408d273c4bd
Co-authored-by: Sid-Qin <201593046+Sid-Qin@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-02 00:45:51 -05:00
Nikolay Petrov
a9f1188785
sessions_spawn: inline attachments with redaction, lifecycle cleanup, and docs ( #16761 )
...
Add inline file attachment support for sessions_spawn (subagent runtime only):
- Schema: attachments[] (name, content, encoding, mimeType) and attachAs.mountPath hint
- Materialization: files written to .openclaw/attachments/<uuid>/ with manifest.json
- Validation: strict base64 decode, filename checks, size limits, duplicate detection
- Transcript redaction: sanitizeToolCallInputs redacts attachment content from persisted transcripts
- Lifecycle cleanup: safeRemoveAttachmentsDir with symlink-safe path containment check
- Config: tools.sessions_spawn.attachments (enabled, maxFiles, maxFileBytes, maxTotalBytes, retainOnSessionKeep)
- Registry: attachmentsDir/attachmentsRootDir/retainAttachmentsOnKeep on SubagentRunRecord
- ACP rejection: attachments rejected for runtime=acp with clear error message
- Docs: updated tools/index.md, concepts/session-tool.md, configuration-reference.md
- Tests: 85 new/updated tests across 5 test files
Fixes:
- Guard fs.rm in materialization catch block with try/catch (review concern #1 )
- Remove unreachable fallback in safeRemoveAttachmentsDir (review concern #7 )
- Move attachment cleanup out of retry path to avoid timing issues with announce loop
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
Co-authored-by: napetrov <napetrov@users.noreply.github.com>
2026-03-01 21:33:51 -08:00
Peter Steinberger
656121a12b
test: micro-optimize hot unit test files
2026-03-02 05:33:07 +00:00
Peter Steinberger
41537e9303
fix(channels): add optional defaultAccount routing
2026-03-02 04:03:46 +00:00
Mark L
5b06c8c6e3
fix(config): normalize gateway bind host aliases during migration ( #30855 )
...
* fix(config): normalize gateway bind host aliases during migration [AI-assisted]
* config(legacy): detect gateway.bind host aliases as legacy
* config(legacy): sanitize bind alias migration log output
* test(config): cover bind alias legacy detection and log escaping
* config(legacy): add source-literal gate to legacy rules
* config(legacy): make issue detection source-aware
* config(legacy): require source-literal gateway.bind alias detection
* config(io): pass parsed source to legacy issue detection
* test(config): cover resolved-only gateway.bind alias legacy detection
* changelog: format after #30855 rebase conflict resolution
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-01 19:53:00 -08:00
Sid
c9f0d6ac8e
feat(agents): support thinkingDefault: "adaptive" for Anthropic models ( #31227 )
...
* feat(agents): support `thinkingDefault: "adaptive"` for Anthropic models
Anthropic's Opus 4.6 and Sonnet 4.6 support adaptive thinking where the
model dynamically decides when and how much to think. This is now
Anthropic's recommended mode and `budget_tokens` is deprecated on these
models.
Add "adaptive" as a valid thinking level:
- Config: `agents.defaults.thinkingDefault: "adaptive"`
- CLI: `/think adaptive` or `/think auto`
- Pi SDK mapping: "adaptive" → "medium" effort at the pi-agent-core
layer, which the Anthropic provider translates to
`thinking.type: "adaptive"` with `output_config.effort: "medium"`
- Provider fallbacks: OpenRouter and Google map "adaptive" to their
respective "medium" equivalents
Closes #30880
Made-with: Cursor
* style(changelog): format changelog with oxfmt
* test(types): fix strict typing in runtime/plugin-context tests
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-03-02 03:52:02 +00:00
Ayaan Zaidi
c13b35b83d
feat(telegram): improve DM topics support ( #30579 ) (thanks @kesor)
2026-03-02 09:06:45 +05:30
Peter Steinberger
cc0806dfab
docs(discord): standardize eventQueue timeout guidance
2026-03-02 02:22:59 +00:00
Jose E Velez
0c8fa63b93
feat: lightweight bootstrap context mode for heartbeat/cron runs (openclaw#26064) thanks @jose-velez
...
Verified:
- pnpm build
- pnpm check (fails on pre-existing unrelated repo issues in extensions/diffs and src/agents/tools/nodes-tool.test.ts)
- pnpm vitest run src/agents/bootstrap-files.test.ts src/infra/heartbeat-runner.model-override.test.ts src/cli/cron-cli.test.ts
- pnpm test:macmini (fails on pre-existing extensions/diffs import errors; touched suites pass)
Co-authored-by: jose-velez <10926182+jose-velez@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-01 20:13:24 -06:00
Glucksberg
a25a73e707
discord: expose EventQueue listenerTimeout as configurable option ( fixes #24458 )
2026-03-02 02:06:24 +00:00
Ash (Bug Lab)
5b64b96c6c
fix(discord): add ackReactionScope channel override + off/none values ( #28268 )
2026-03-02 02:04:39 +00:00
Shawn
654f63e8f8
fix(signal): prevent sentTranscript sync messages from bypassing loop protection ( #31093 )
...
* fix(signal): prevent sentTranscript sync messages from bypassing loop protection
Issue: #31084
On daemon restart, sentTranscript sync messages could bypass loop protection
because the syncMessage check happened before the sender validation. This
reorganizes the checks to:
1. First resolve the sender (phone or UUID)
2. Check if the message is from our own account (both phone and UUID)
3. Only skip sync messages from other sources after confirming not own account
This ensures that sync messages from the own account are properly filtered
to prevent self-reply loops, while still allowing messages synced from other
devices to be processed.
Added optional accountUuid config field for UUID-based account identification.
* fix(signal): cover UUID-only own-message loop protection
* build: regenerate host env security policy swift
---------
Co-authored-by: Kevin Wang <kevin@example.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-03-02 01:11:22 +00:00
Peter Steinberger
cef5fae0a2
refactor(gateway): dedupe origin seeding and plugin route auth matching
2026-03-02 00:42:22 +00:00
Peter Steinberger
fbd832d64f
refactor(config): share byte-size parsing for memory flush
2026-03-02 00:32:33 +00:00
Peter Steinberger
53d10f8688
fix(gateway): land access/auth/config migration cluster
...
Land #28960 by @Glucksberg (Tailscale origin auto-allowlist).
Land #29394 by @synchronic1 (allowedOrigins upgrade migration).
Land #29198 by @Mariana-Codebase (plugin HTTP auth guard + route precedence).
Land #30910 by @liuxiaopai-ai (tailscale bind/config.patch guard).
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: synchronic1 <synchronic1@users.noreply.github.com>
Co-authored-by: Mariana Sinisterra <mariana.data@outlook.com>
Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
2026-03-02 00:10:51 +00:00
Peter Steinberger
41cc46bbb4
feat(diagnostics): add configurable stuck-session warning threshold
2026-03-02 00:07:29 +00:00
Peter Steinberger
d729ab2150
fix(session): harden usage accounting and memory flush recovery
2026-03-02 00:07:29 +00:00
Peter Steinberger
0f5348acb2
test(config): reject discord open DM with empty allowFrom
2026-03-01 23:08:37 +00:00
Onur
8292401719
ACP: rename stream char limits to output/sessionUpdate
2026-03-01 20:39:24 +01:00
Onur
053e5eb506
ACP: remove maxMetaEventsPerTurn limit
2026-03-01 20:39:24 +01:00
Onur
43c57005a6
ACP: start typing lifecycle at turn start and harden delivery
2026-03-01 20:39:24 +01:00
Onur
c8b958e573
ACP: add hidden-boundary separator for hidden tool events
2026-03-01 20:39:24 +01:00
Onur
c3a1fe01ae
ACP: make final_only defer all projected output
2026-03-01 20:39:24 +01:00
Onur
4e2efaf659
ACP: simplify stream config to repeatSuppression
2026-03-01 20:39:24 +01:00
Onur
2466a9bb13
ACP: carry dedupe/projector updates onto configurable acpx branch
2026-03-01 20:39:24 +01:00
Peter Machona
dfbdab5a29
fix(slack): map legacy streaming=false to off (openclaw#26020) thanks @chilu18
...
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: chilu18 <7957943+chilu18@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-01 10:21:25 -06:00
François Martin
53d6e07a60
fix(sessions): set transcriptPath to agent sessions directory (openclaw#24775) thanks @martinfrancois
...
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: martinfrancois <14319020+martinfrancois@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-01 09:41:06 -06:00
0xbrak
4637b90c07
feat(cron): configurable failure alerts for repeated job errors (openclaw#24789) thanks @0xbrak
...
Verified:
- pnpm install --frozen-lockfile
- pnpm check
- pnpm test -- --run src/cron/service.failure-alert.test.ts src/cli/cron-cli.test.ts src/gateway/protocol/cron-validators.test.ts
Co-authored-by: 0xbrak <181251288+0xbrak@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-01 08:18:15 -06:00
NIO
ea3955cd78
fix(cron): add retry policy for one-shot jobs on transient errors ( #24355 ) (openclaw#24435) thanks @hugenshen
...
Verified:
- pnpm install --frozen-lockfile
- pnpm check
- pnpm test -- --run src/cron/service.issue-regressions.test.ts src/config/config-misc.test.ts
Co-authored-by: hugenshen <16300669+hugenshen@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-01 06:58:03 -06:00
Vignesh Natarajan
c58d2aa99e
Sessions: fix sessions_list transcriptPath path resolution
2026-02-28 14:42:14 -08:00
Vincent Koc
f16ecd1dac
fix(ollama): unify context window handling across discovery, merge, and OpenAI-compat transport ( #29205 )
...
* fix(ollama): inject num_ctx for OpenAI-compatible transport
* fix(ollama): discover per-model context and preserve higher limits
* fix(agents): prefer matching provider model for fallback limits
* fix(types): require numeric token limits in provider model merge
* fix(types): accept unknown payload in ollama num_ctx wrapper
* fix(types): simplify ollama settled-result extraction
* config(models): add provider flag for Ollama OpenAI num_ctx injection
* config(schema): allow provider num_ctx injection flag
* config(labels): label provider num_ctx injection flag
* config(help): document provider num_ctx injection flag
* agents(ollama): gate OpenAI num_ctx injection with provider config
* tests(ollama): cover provider num_ctx injection flag behavior
* docs(config): list provider num_ctx injection option
* docs(ollama): document OpenAI num_ctx injection toggle
* docs(config): clarify merge token-limit precedence
* config(help): note merge uses higher model token limits
* fix(ollama): cap /api/show discovery concurrency
* fix(ollama): restrict num_ctx injection to OpenAI compat
* tests(ollama): cover ipv6 and compat num_ctx gating
* fix(ollama): detect remote compat endpoints for ollama-labeled providers
* fix(ollama): cap per-model /api/show lookups to bound discovery load
2026-02-27 17:20:47 -08:00
Rodrigo Uroz
0fe6cf06b2
Compaction: preserve opaque identifiers in summaries (openclaw#25553) thanks @rodrigouroz
...
Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini
Co-authored-by: rodrigouroz <384037+rodrigouroz@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-02-27 08:14:05 -06:00
Onur Solmaz
a7929abad8
Discord: thread bindings idle + max-age lifecycle ( #27845 ) (thanks @osolmaz)
...
* refactor discord thread bindings to idle and max-age lifecycle
* fix: migrate legacy thread binding expiry and reduce hot-path disk writes
* refactor: remove remaining thread-binding ttl legacy paths
* fix: harden thread-binding lifecycle persistence
* Discord: fix thread binding types in message/reply paths
* Infra: handle win32 unknown inode in file identity checks
* Infra: relax win32 guarded-open identity checks
* Config: migrate threadBindings ttlHours to idleHours
* Revert "Infra: relax win32 guarded-open identity checks"
This reverts commit de94126771db072ecda6a014e80700310e76df61.
* Revert "Infra: handle win32 unknown inode in file identity checks"
This reverts commit 96fc5ddfb39762aa078d70dd4b4d3754e49a159b.
* Discord: re-read live binding state before sweep unbind
* fix: add changelog note for thread binding lifecycle update (#27845 ) (thanks @osolmaz)
---------
Co-authored-by: Onur Solmaz <onur@textcortex.com>
2026-02-27 10:02:39 +01:00
Peter Steinberger
1d43202930
fix: repair Telegram allowlist DM migrations ( #27936 ) (thanks @widingmarcus-cyber)
2026-02-26 22:53:13 +00:00
Peter Steinberger
45d868685f
fix: enforce dm allowFrom inheritance across account channels ( #27936 ) (thanks @widingmarcus-cyber)
2026-02-26 22:04:16 +00:00
Marcus Widing
0fdac31383
fix: skip allowFrom validation at account level (inherits from parent)
...
Account configs inherit channel-level fields at runtime (e.g.,
resolveTelegramAccount shallow-merges top-level and account values).
An account can set dmPolicy='allowlist' and rely on the parent's
allowFrom, so validating allowFrom on the account object alone
incorrectly rejects valid multi-account configs.
Removes requireAllowlistAllowFrom and requireOpenAllowFrom from all
account-level schemas (Telegram, Signal, IRC, iMessage, BlueBubbles).
Top-level config schemas still enforce the validation.
Addresses Codex review feedback on #27936 .
2026-02-26 22:04:16 +00:00
Marcus Widing
cbed0e065c
fix: reject dmPolicy="allowlist" with empty allowFrom across all channels
...
When dmPolicy is set to "allowlist" but allowFrom is missing or empty,
all DMs are silently dropped because no sender can match the empty
allowlist. This is a common pitfall after upgrades that change how
allowlist files are handled (e.g., external allowlist-dm.json files
being deprecated in favor of inline allowFrom arrays).
Changes:
- Add requireAllowlistAllowFrom schema refinement (zod-schema.core.ts)
- Apply validation to all channel schemas: Telegram, Discord, Slack,
Signal, IRC, iMessage, BlueBubbles, MS Teams, Google Chat, WhatsApp
- Add detectEmptyAllowlistPolicy to doctor-config-flow.ts so
"openclaw doctor" surfaces a clear warning with remediation steps
- Add 12 test cases covering reject/accept for multiple channels
Fixes #27892
2026-02-26 22:04:16 +00:00
Peter Steinberger
38b6cee020
feat(config): add embedded pi project settings policy
2026-02-26 21:46:39 +01:00
Peter Steinberger
344f54b84d
refactor(config): dedupe model api definitions
2026-02-26 20:00:11 +01:00
Peter Steinberger
ac03803d12
fix: align codex model api schema/type coverage ( #27501 ) (thanks @AytuncYildizli)
2026-02-26 18:51:04 +00:00