Commit Graph

2303 Commits

Author SHA1 Message Date
Peter Steinberger
b1664ec9c7 test: rename signal reaction-only test (#637) 2026-01-10 19:19:05 +01:00
Peter Steinberger
82f71d25e5 refactor: centralize history context wrapping 2026-01-10 19:16:26 +01:00
Peter Steinberger
b977ae19af chore: fix lint and typing 2026-01-10 19:16:25 +01:00
Peter Steinberger
d41372b9d9 feat: unify provider history context 2026-01-10 19:16:25 +01:00
Peter Steinberger
8c1d39064d test: adjust tool id sanitization 2026-01-10 18:15:15 +00:00
Peter Steinberger
7c925aa5a0 style: format helper 2026-01-10 18:15:15 +00:00
Peter Steinberger
651a9e9be4 fix: restore minimax tool calling 2026-01-10 18:15:15 +00:00
Peter Steinberger
8dbb22cc93 fix: signal handle dataMessage.reaction safely (#637) (thanks @neist) 2026-01-10 19:13:23 +01:00
Kasper Neist Christjansen
59e6064006 fix(signal): handle reactions in dataMessage.reaction format (#1)
* fix(signal): handle reactions inside dataMessage.reaction

Signal reactions can arrive in two formats:
1. envelope.reactionMessage (already handled)
2. envelope.dataMessage.reaction (now handled)

The signal-cli SSE events use the second format, which was being
misinterpreted as a message with attachments, leading to 'broken
media / attachments' errors.

Changes:
- Add reaction property to SignalDataMessage type
- Check both envelope.reactionMessage and dataMessage.reaction
- Improve body content detection to properly identify reaction-only messages
- Add test for dataMessage.reaction format

* fix(signal): reaction notifications work when account is phone number

When reactionNotifications mode is 'own', notifications would never fire
because resolveSignalReactionTarget() returned a UUID but
shouldEmitSignalReactionNotification() compared it against the account
phone number, which never matched.

The fix:
- Add optional 'phone' field to SignalReactionTarget type
- Extract phone number first in resolveSignalReactionTarget(), include
  it even when UUID is present
- In shouldEmitSignalReactionNotification() 'own' mode, check phone
  match first before falling back to UUID comparison

This ensures reactions to your own messages are properly detected when
the Signal account is configured as a phone number and the reaction
event contains both targetAuthor (phone) and targetAuthorUuid.

* fix(signal): include phone in reaction target for own-mode matching

When targetAuthorUuid is present, also store targetAuthor phone number
in the reaction target. This allows own-mode reaction notifications to
match when comparing account phone against UUID-based targets.
2026-01-10 19:10:39 +01:00
Anton Sotkov
26ce65995f fix(gmail): keep tailscale serve path at root
The default Gmail hook path configured by `clawdbot hooks gmail setup` is `/gmail-pubsub`. Tailscale strips the mount path before proxying, so the request lands on `/` and the hook 404s under the default configuration.

When Tailscale is enabled, always listen on `/` internally and keep the public URL on the configured path (defaulting to `/gmail-pubsub`). This makes default and custom paths work reliably.

Alternative (not implemented here): call tailscale with a full target URL so the backend keeps the path, e.g. `tailscale funnel --set-path /gmail-pubsub http://127.0.0.1:8788/gmail-pubsub`. We did not take this path because it requires changing the CLI invocation to pass URLs (not ports) plus extra validation, which is a larger behavior change.
2026-01-10 18:51:12 +01:00
Peter Steinberger
7dd0899856 fix: voicewake respects state dir override (#666) (thanks @roshanasingh4) 2026-01-10 18:32:09 +01:00
Peter Steinberger
f1a1032cd6 fix: serialize telegram media-group processing 2026-01-10 18:31:36 +01:00
Peter Steinberger
b383fbeed3 fix: cron wakeMode now waits for heartbeat (#666) (thanks @roshanasingh4) 2026-01-10 18:31:35 +01:00
Roshan Singh
91c870a0c4 fix(cron): wait for heartbeat to complete when wakeMode is "now"
Fixes #652

When cron jobs with sessionTarget:"main" have wakeMode:"now",
they were being marked as completed immediately without waiting for the
agent to actually process the system event.

The issue was that requestHeartbeatNow() is fire-and-forget and
doesn't wait for the heartbeat to complete. The job would finish
with durationMs: 0 before the agent had a chance to run.

This fix:
- Adds runHeartbeatOnce to CronServiceDeps
- Wires it up in gateway/server.ts to load config and pass runtime
- Modifies executeJob() to call runHeartbeatOnce when wakeMode:"now"
- Waits for heartbeat to complete and maps status to cron result:
  * "ran" → "ok"
  * "skipped" → "skipped"
  * "failed" → "error"
- Falls back to old behavior for wakeMode:"next-heartbeat" or if
  runHeartbeatOnce is not available (backward compatibility)

Benefits:
- Jobs now have accurate durationMs reflecting actual processing time
- Jobs are correctly marked with "error" status if heartbeat fails
- Prevents race condition where job completes before agent runs

[AI-assisted] - Generated with z.ai GLM-4.7
[Tested: Lightly tested - Logic validated with test scenarios, code quality checks passed, integration testing requires live Clawdbot instance]
2026-01-10 18:31:35 +01:00
Peter Steinberger
5a57cbe571
Merge pull request #667 from rubyrunsstuff/fix/discord-forwarded-snapshots
Discord: include forwarded message snapshots
2026-01-10 17:31:26 +00:00
Peter Steinberger
6480ef369f fix: telegram draft chunking defaults (#667) (thanks @rubyrunsstuff) 2026-01-10 18:30:06 +01:00
Peter Steinberger
2d105d16f8 fix(opencode-zen): keep legacy aliases + rationale (#669) (thanks @magimetal) 2026-01-10 18:25:43 +01:00
Ruby
7a836c9ff0 Discord: include forwarded message snapshots 2026-01-10 18:23:30 +01:00
Magi Metal
738269eb74 feat(opencode-zen): update models with sensible defaults
- Replace model catalog with 11 current models: gpt-5.1-codex, claude-opus-4-5,
  gemini-3-pro, alpha-glm-4.7, gpt-5.1-codex-mini, gpt-5.1, glm-4.7-free,
  gemini-3-flash, gpt-5.1-codex-max, minimax-m2.1-free, gpt-5.2
- Add accurate per-token costs from OpenCode Zen pricing
- Add accurate context windows and output limits
- Update aliases for new model families (codex, glm, minimax)
- Remove deprecated models (sonnet, haiku, o-series, gemini-2.5)
2026-01-10 18:22:26 +01:00
Peter Steinberger
9b5ce2530a
Merge pull request #665 from sebslight/fix/cloud-code-assist-schema-and-tool-ids
fix(agents): harden Cloud Code Assist compatibility
2026-01-10 17:07:58 +00:00
Peter Steinberger
38d6930fbe
Merge pull request #664 from azade-c/fix/use-state-dir-for-nodes-voicewake
fix: use resolveStateDir() for node-pairing and voicewake storage
2026-01-10 17:07:28 +00:00
Peter Steinberger
0d98e93253 fix: harden cloud code assist tool schema sanitizing (#665) (thanks @sebslight) 2026-01-10 18:07:26 +01:00
Sebastian Barrios
64babcac7a fix(agents): harden Cloud Code Assist compatibility
- Expand schema scrubber to strip additional constraint keywords rejected
  by Cloud Code Assist (examples, minLength, maxLength, minimum, maximum,
  multipleOf, pattern, format, minItems, maxItems, uniqueItems,
  minProperties, maxProperties)
- Extend tool call ID sanitization to cover toolUse and toolCall block
  types (previously only functionCall was sanitized)
- Update pi-tools test to include 'examples' in unsupported keywords

Fixes 400 errors when using google-antigravity/claude-opus-4-5-thinking:
- tools.N.custom.input_schema: JSON schema is invalid
- messages.N.content.N.tool_use.id: String should match pattern
2026-01-10 18:06:35 +01:00
Peter Steinberger
464f0645a8 fix: stabilize telegram media tests (#664) (thanks @azade-c) 2026-01-10 18:06:05 +01:00
Peter Steinberger
ef08c3f038 fix(agents): stabilize cli creds cache + bash cwd 2026-01-10 18:02:21 +01:00
Azade
48ad3bbbe6 fix: use resolveStateDir() for node-pairing and voicewake storage
Both node-pairing.ts and voicewake.ts were using a local defaultBaseDir()
that hardcoded ~/.clawdbot, ignoring CLAWDBOT_STATE_DIR.

This caused nodes/paired.json and settings/voicewake.json to be stored
in ~/.clawdbot instead of the configured state directory.

Fixes the bug where paired nodes config was stored in a different
location than the rest of the gateway state.
2026-01-10 17:55:30 +01:00
Peter Steinberger
843ff5f2d4 fix(sessions): tolerate ENOENT during lock 2026-01-10 17:50:53 +01:00
Peter Steinberger
60bf349201 fix(sessions): lock store saves; wait for bash close 2026-01-10 17:47:12 +01:00
Peter Steinberger
a54706a063 fix: throttle cli credential sync 2026-01-10 17:44:03 +01:00
Peter Steinberger
12722acb55 feat: wizard model picker (#611, thanks @jonasjancarik) 2026-01-10 16:32:59 +00:00
Jonáš Jančařík
687a10b8cc fix: map opencode-zen preferred provider 2026-01-10 16:32:59 +00:00
Jonáš Jančařík
9f80d8ec7c fix: skip model picker when auth choice preset 2026-01-10 16:32:59 +00:00
Jonáš Jančařík
dcc41e932d feat: add shared model picker to configure/onboarding 2026-01-10 16:32:59 +00:00
Peter Steinberger
e3cd431551 fix(auto-reply): RawBody commands + locked session updates (#643) 2026-01-10 17:32:31 +01:00
Peter Steinberger
e2ea02160d test: add workspace path regressions 2026-01-10 17:28:43 +01:00
Peter Steinberger
a1533a17f7 fix(gateway): harden chat abort semantics 2026-01-10 17:23:27 +01:00
Peter Steinberger
84d64f9395
Merge pull request #446 from tony-freedomology/feat/human-delay
feat(agent): add human-like delay between block replies
2026-01-10 16:16:52 +00:00
Peter Steinberger
fb03149df4 fix: finalize human delay config typing (#446) (thanks @tony-freedomology) 2026-01-10 17:15:27 +01:00
Lloyd
ab994d2c63 feat(agent): add human-like delay between block replies
Adds `agent.humanDelay` config option to create natural rhythm between
streamed message bubbles. When enabled, introduces a random delay
(default 800-2500ms) between block replies, making multi-message
responses feel more like natural human texting.

Config example:
```json
{
  "agent": {
    "blockStreamingDefault": "on",
    "humanDelay": {
      "enabled": true,
      "minMs": 800,
      "maxMs": 2500
    }
  }
}
```

- First message sends immediately
- Subsequent messages wait a random delay before sending
- Works with iMessage, Signal, and Discord providers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 17:12:50 +01:00
Muhammed Mukhthar CM
de5b75eff6 fix(tools): resolve Read/Write/Edit paths against workspace directory
Previously, Read/Write/Edit tools used the global tool instances from
pi-coding-agent which had process.cwd() baked in at import time. Since
the gateway starts from /root/dev/ai/clawdbot, relative paths like
'SOUL.md' would incorrectly resolve there instead of the agent's
workspace (/root/clawd).

This fix:
- Adds workspaceDir option to createClawdbotCodingTools
- Creates fresh Read/Write/Edit tools bound to workspaceDir
- Adds cwd option to Bash tool defaults for consistency
- Passes effectiveWorkspace from pi-embedded-runner

Absolute paths and ~/... paths are unaffected. Sandboxed sessions
continue to use sandbox root as before.

Includes tests for Read/Write/Edit workspace path resolution.
2026-01-10 17:08:56 +01:00
Peter Steinberger
d1943a9337 chore: format reply session 2026-01-10 17:03:17 +01:00
Peter Steinberger
d781508952 fix: make chat.send non-blocking 2026-01-10 17:02:28 +01:00
Peter Steinberger
b7fdc266ad test(auto-reply): cover native /model session routing 2026-01-10 16:50:32 +01:00
Peter Steinberger
b99eb4c9f3 fix(auto-reply): apply native commands to target session 2026-01-10 16:48:53 +01:00
Peter Steinberger
8978ac425e fix: harden cli credential sync 2026-01-10 16:37:54 +01:00
Peter Steinberger
81f9093c3c fix(pairing): accept positional provider args 2026-01-10 16:36:43 +01:00
Peter Steinberger
41c8bdfada feat: add ZAI auth choice 2026-01-10 16:32:21 +01:00
Peter Steinberger
8b47368167 fix: harden cli credential sync 2026-01-10 16:25:40 +01:00
Peter Steinberger
e60c3fc1b3 fix: doctor ignore install dir in legacy workspace check 2026-01-10 16:23:35 +01:00
Peter Steinberger
78532d76bd test: clean up lint warnings 2026-01-10 16:17:02 +01:00
Peter Steinberger
53a0c966a5 refactor: unify configure auth choice 2026-01-10 16:14:49 +01:00
Peter Steinberger
43b530ca1c fix(agents): suppress partial replies with reasoning 2026-01-10 16:03:17 +01:00
Peter Steinberger
44564df028 refactor(sessions): add mergeSessionEntry 2026-01-10 16:03:17 +01:00
Peter Steinberger
70c1732dd1 refactor: centralize messaging dedupe helpers 2026-01-10 16:02:56 +01:00
Peter Steinberger
5a93447294 fix: prevent claude-cli oauth downgrade (#654) (thanks @radek-paclt) 2026-01-10 15:50:25 +01:00
Radek Paclt
a39951d463 fix(auth): enable OAuth refresh for Claude CLI credentials
When Claude CLI credentials (anthropic:claude-cli) expire, automatically
refresh using the stored refresh token instead of failing with
"No credentials found" error.

Changes:
- Read refreshToken from Claude CLI and store as OAuth credential type
- Implement bidirectional sync: after refresh, write new tokens back to
  Claude Code storage (file on Linux/Windows, Keychain on macOS)
- Prefer OAuth over Token credentials (enables auto-refresh capability)
- Maintain backward compatibility for credentials without refreshToken

This enables long-running agents to operate autonomously without manual
re-authentication when OAuth tokens expire.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-10 15:40:27 +01:00
Peter Steinberger
1281c1d155
Merge pull request #655 from antons/fix/reasoning-imsg
Fix reasoning in iMessage
2026-01-10 14:39:14 +00:00
Peter Steinberger
236f8560b3 fix: reasoning iMessage sessions + final reply (#655) (thanks @antons) 2026-01-10 15:31:57 +01:00
Peter Steinberger
ae3711bfbd
Merge pull request #659 from mickahouan/fix/dedupe-message-tool
Fix: avoid duplicate replies when message tool sends
2026-01-10 14:30:02 +00:00
Peter Steinberger
449bee9645 fix: bundle node runtime for mac app 2026-01-10 15:28:37 +01:00
Peter Steinberger
4d146ea2f5 fix: dedupe message tool replies (#659) (thanks @mickahouan) 2026-01-10 15:28:13 +01:00
Anton Sotkov
3b5149ca39 fix: send only final answer with reasoning
When reasoning is enabled on non‑block providers, we now ignore interim streaming chunks and send only the final assistant answer at completion, so replies aren’t partial or duplicated.
2026-01-10 15:28:04 +01:00
Anton Sotkov
4c86da044e fix(sessions): persist reasoning/elevated across DMs 2026-01-10 15:28:04 +01:00
Mickaël Ahouansou
d01e06f09a Fix: dedupe message tool sends 2026-01-10 15:25:20 +01:00
Peter Steinberger
65c2532cd5 fix: minimax apiKey optional for providers (#656) (thanks @mneves75) 2026-01-10 15:08:12 +01:00
mneves75
3e2e3eb023 Config: add MiniMax direct API authentication option
Makes apiKey optional in ModelProviderConfig so MiniMax can use auth
profiles or environment variables (MINIMAX_API_KEY) instead of requiring
explicit config.

Changes:
- src/config/types.ts: apiKey changed from required to optional
- src/config/zod-schema.ts: use z.string().min(1).optional() for validation
- src/commands/configure.ts: add minimax-api auth choice in wizard
- src/commands/onboard-auth.ts: MiniMax provider omits apiKey (uses env/auth)
- patches/@mariozechner__pi-ai@0.42.1.patch: map minimax → MINIMAX_API_KEY

Auth Resolution Order (unchanged):
1. Auth profiles (highest priority)
2. Environment variables (MINIMAX_API_KEY, etc.)
3. Custom provider apiKey from models.json (lowest priority)
2026-01-10 10:57:09 -03:00
Peter Steinberger
920b3880c1 test: add elevated mode regressions 2026-01-10 05:31:48 +01:00
Peter Steinberger
66db6c749d fix: persist elevated off override 2026-01-10 05:23:46 +01:00
Peter Steinberger
2045395ccb test(live): add optional write/bash probes 2026-01-10 04:14:39 +00:00
Peter Steinberger
d3674f4d6c test(onboard): cover remote + lan token flows 2026-01-10 04:14:39 +00:00
Peter Steinberger
cdb915d527 chore: normalize Clawdbot naming 2026-01-10 05:14:09 +01:00
Peter Steinberger
a7c8341452 feat: show more session flags 2026-01-10 05:14:07 +01:00
Peter Steinberger
7b392ca74b test(onboard): gateway token auth flow 2026-01-10 03:54:29 +00:00
Peter Steinberger
eee04fa2ce fix(onboard): persist gateway token in config 2026-01-10 03:54:25 +00:00
Peter Steinberger
4fac94f259 test(gateway): add wizard e2e + isolate live suite 2026-01-10 03:44:21 +00:00
Peter Steinberger
0f409cb99d test(telegram): force real timers for media groups 2026-01-10 03:44:21 +00:00
Peter Steinberger
241bc737cf test(telegram): deflake media groups on windows 2026-01-10 04:43:04 +01:00
Peter Steinberger
2a0d8f6e38 test(gateway): avoid real OpenAI in mock test 2026-01-10 03:25:45 +00:00
Peter Steinberger
056c4ae622 test(telegram): harden media tests 2026-01-10 04:18:05 +01:00
Peter Steinberger
6274adce3a fix(tools): keep canonical tool names for oauth 2026-01-10 04:18:00 +01:00
Peter Steinberger
4f79122068 test: stabilize gateway mock + lint 2026-01-10 03:14:13 +00:00
Peter Steinberger
7376d1e6c9 feat: improve tui status output 2026-01-10 04:07:15 +01:00
Peter Steinberger
782863ea6c test(gateway): add offline tool-calling regression 2026-01-10 03:06:02 +00:00
Peter Steinberger
cc1c5f800f fix(tools): harden schemas and oauth tool names 2026-01-10 03:05:56 +00:00
Peter Steinberger
f241859c98 fix: relax fetch typing for Bun 2026-01-10 04:01:06 +01:00
Peter Steinberger
8466e53b5d fix: restore Anthropic OAuth tool dispatch 2026-01-10 04:01:00 +01:00
Peter Steinberger
8e63cd9a76 feat: improve tui status line 2026-01-10 03:53:32 +01:00
Peter Steinberger
2cfed7952e test(telegram): relax media group timeouts on Windows 2026-01-10 02:32:03 +00:00
Peter Steinberger
8a5fb796c0 test(live): probe Read tool via gateway 2026-01-10 02:25:24 +00:00
Peter Steinberger
34664601e0 fix(auto-reply): default audioAsVoice to false 2026-01-10 02:25:19 +00:00
Peter Steinberger
d693f02fa7 fix(msteams): download image attachments reliably 2026-01-10 02:25:14 +00:00
Peter Steinberger
003cda73e8 style: fix biome formatting 2026-01-10 02:11:43 +00:00
Peter Steinberger
afe6f182ca feat: show effective config in /debug 2026-01-10 03:10:14 +01:00
Peter Steinberger
5a6ae2624e docs: add /config get alias 2026-01-10 03:10:14 +01:00
Peter Steinberger
2dc7872ad1 feat: auto-start sandbox browser 2026-01-10 02:06:21 +00:00
Peter Steinberger
8b579c91a5 feat: add /config chat config updates 2026-01-10 03:01:27 +01:00
Peter Steinberger
63b0a16357 feat(cli): colorize gateway health + daemon output 2026-01-10 03:01:27 +01:00
Peter Steinberger
f28a4a34ad refactor: unify inline directives and media fetch 2026-01-10 03:01:04 +01:00
Peter Steinberger
4075895c4c refactor: consolidate reply/media helpers 2026-01-10 02:41:16 +01:00
Peter Steinberger
9cd2662a86 refactor: centralize WhatsApp target normalization 2026-01-10 02:39:52 +01:00