73 Commits
Author SHA1 Message Date
Rudy Celekli b4875de1ac fix(gemini): send non-object tool results as an object in functionResponse 2026-10-24 00:03:44 -04:00
Rudy Celekli bfde49db9a fix(dashscope): keep steering text sent alongside tool results 2026-10-23 23:55:42 -04:00
Rudy Celekli c69a168fac fix(zhipuai): keep steering text sent alongside tool results 2026-10-23 23:52:48 -04:00
Rudy Celekli 4766bf338b fix(claude): surface mid-stream error events instead of ending the reply silently 2026-10-23 23:37:10 -04:00
Rudy CelekliandClaude Opus 5 5ff49014c9 docs: correct the orphaned-file description
pydub opens the destination wb+ before running ffmpeg, so an encoder that
exits nonzero leaves an *empty* file at that path, not a partially
written one. The leak is real either way, but only the second case -- a
failed source removal stranding the converted wav -- leaves actual audio
on disk, so the privacy note belongs there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-22 09:25:56 -04:00
Rudy CelekliandClaude Opus 5 8bcbb12f0b fix(voice): stop leaking inbound voice recordings on conversion failure
The inbound VOICE branch converts the audio to a wav sibling, transcribes
it, then deletes the temporary files. Two leaks:

The failure path reassigned the output name before the cleanup ran:

    wav_path = os.path.splitext(file_path)[0] + ".wav"
    try:
        any_to_wav(file_path, wav_path)
    except Exception as e:
        wav_path = file_path

pydub opens the destination before handing the encode to ffmpeg, so a
failing encoder leaves a partial file at the original `wav_path`. After
the reassignment nothing names that file any more, so the cleanup below
removed the source and left the half-written recording in the tmp dir
permanently. Keep `wav_path` pointing at the file that may exist and
carry the speech-to-text input in its own `stt_path`.

The two removals also shared a single `try`, so a failure on the first
skipped the second entirely. Remove each path on its own; the set
literal keeps an inbound `.wav` -- where both names are equal -- from
being removed twice.

These files are the user's own voice recordings, so a leak keeps private
audio on disk indefinitely.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-22 01:30:21 -04:00
Rudy CelekliandClaude Opus 5 9755a67014 fix(update): tolerate a corrupt worker_pid in the in-progress guard
_update_is_stale coerced the stored worker_pid with int() and no guard, so a
status file carrying a non-numeric value raised out of the "an update is
already in progress" check in start_update:

    ValueError: invalid literal for int() with base 10: 'abc'

The function exists so that a running status left behind by a dead worker
does not block every later update, which is exactly the situation where the
status file is least trustworthy. read_update_status above it already
tolerates a missing file, an OSError, invalid JSON and a non-dict payload, so
the module validated the container but not the fields it then coerced.

Fall through to the timestamp check when the pid will not parse. Reporting
the run stale instead would unblock an update that may still be running,
which is the opposite of what the guard is for: a corrupt pid is no evidence
the worker died. A fresh run therefore still blocks, and an old one is still
reported stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-22 00:31:00 -04:00
Rudy Celekli ca468f49e1 fix(web): preserve chat history when deletion fails 2026-10-21 02:03:00 -04:00
Rudy CelekliandClaude Sonnet 5.5 aab19fb66c fix(delegate): widen timeout range to 3600s and simplify the local deadline
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 09:08:09 -04:00
Rudy CelekliandClaude Sonnet 5.5 a6538a2bb7 fix(skills): report failed enable/disable and restore the previous choice
set_skill_enabled now propagates a failed config save and restores the
previous enabled value in memory. Automatic and post-install metadata
saves stay best-effort.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 09:09:00 -04:00
Rudy CelekliandClaude Sonnet 5.5 d6239f90d6 fix(slack): do not answer workspace notices as user messages
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:26:22 -04:00
Rudy CelekliandClaude Sonnet 5.5 4a6edaa6ab fix(discord): refuse oversized inbound attachments before downloading
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:25:22 -04:00
Rudy CelekliandClaude Sonnet 5.5 d1dc104bb4 fix(linkai): match group admins by exact id, not substring
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:24:39 -04:00
Rudy CelekliandClaude Sonnet 5.5 be86907f29 fix(dingtalk): keep group file uploads with the member who sent them
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:24:03 -04:00
Rudy Celekli a9d0602fd6 fix(tools): refuse special-file targets before reading or replacing them
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-13 11:02:57 -04:00
Rudy Celekli 6029a745ca fix(workspace): report failed project and session preference saves
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-13 11:02:46 -04:00
Rudy Celekli 60161b7e75 fix(web): keep system-file fallbacks in the requested agent workspace
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-13 11:02:37 -04:00
Rudy Celekli 33767891df fix(workspace): bind editor metadata to the content read
Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com>
2026-10-13 11:02:29 -04:00
Rudy Celekli 051b6275e5 fix(scheduler): commit migrated reminders before retiring legacy stores 2026-10-13 09:54:29 -04:00
Rudy Celekli 366ba041a8 fix(search): honor path globs in the Python fallback 2026-10-11 09:15:42 -04:00
Rudy Celekli 8a0d3da146 fix(minimax): align retained sessions with the chat completions schema 2026-10-11 09:14:03 -04:00
Rudy Celekli 7f5d7b98c2 fix(wechat-kf): retry cursor persistence after transient write failures 2026-10-11 09:12:21 -04:00
Rudy Celekli cd73478e46 fix(memory): isolate malformed vectors during retrieval 2026-10-11 09:12:01 -04:00
Rudy Celekli 283aafabf8 fix(evolution): give each undo snapshot a unique directory 2026-10-11 09:12:00 -04:00
Rudy Celekli d8a1cd436a fix(common): reject UTF-8 split budgets that cannot make progress 2026-10-11 09:11:59 -04:00
Rudy Celekli 6ad9a6c49f fix(models): serialize catalog edits and cache publication 2026-10-11 09:10:07 -04:00
Rudy Celekli 18421bbf96 fix(models): recover malformed catalog provider fields independently 2026-10-11 09:08:38 -04:00
Rudy Celekli 804b66cc04 fix(knowledge): exclude symlink children from tree traversal 2026-10-11 09:08:19 -04:00
Rudy Celekli db40426cb6 fix(search): skip special files before Python content reads 2026-10-11 09:07:56 -04:00
Rudy Celekli 5cc72cff23 fix(keyword): retain distinct downloaded document replies 2026-10-11 09:07:41 -04:00
Rudy Celekli 7eeef21124 fix(mcp): propagate server tool execution errors 2026-10-11 09:07:37 -04:00
Rudy Celekli 4a822a1a16 fix(mcp): follow paginated tool discovery cursors 2026-10-11 09:07:19 -04:00
Rudy Celekli 939b2f151f fix(telegram): keep link targets literal during Markdown rendering 2026-10-11 09:06:38 -04:00
Rudy Celekli b325b335fc fix(mcp): retain structured-only tool results 2026-10-11 09:05:48 -04:00
Rudy Celekli aa6aeeb5d4 fix(memory): reject incomplete or ambiguously indexed embedding batches 2026-10-11 09:05:34 -04:00
Rudy Celekli 7e3e965f22 fix(agent): preserve matched results when removing orphan blocks 2026-10-11 09:05:32 -04:00
Rudy Celekli 1afa8c0d76 fix(agent): drop tool results without a call identifier 2026-10-11 09:05:30 -04:00
Rudy Celekli c2737e56e6 fix(workspace): recover session preferences from non-object JSON 2026-10-11 09:05:27 -04:00
Rudy Celekli a2f815f5aa fix(web-fetch): bound the whole document transfer time 2026-10-11 09:05:20 -04:00
Rudy Celekli 38152a1212 fix(web-fetch): preserve literal text responses without HTML parsing 2026-10-11 09:05:00 -04:00
Rudy Celekli de89058138 fix(openai): retain JSON schema output constraints on Responses 2026-10-11 09:04:51 -04:00
Rudy Celekli d5936231b0 fix(web-fetch): tolerate malformed document length headers 2026-10-11 09:04:34 -04:00
Rudy Celekli a169aaa5f0 fix(openai): preserve function controls when adapting Responses requests 2026-10-11 09:04:06 -04:00
Rudy Celekli 3e33802166 fix(openai): frame SSE events by valid line endings 2026-10-11 09:03:01 -04:00
Rudy Celekli 8a77d0244e fix(knowledge): validate resolved import destinations before writing 2026-10-11 09:02:27 -04:00
Rudy Celekli faa554ea31 fix(bash): skip dotenv entries without values 2026-10-11 09:02:10 -04:00
Rudy Celekli b690651dd2 fix(write): preserve success when memory notification fails 2026-10-11 09:01:50 -04:00
Rudy Celekli cffc2b5faf fix(openai): close HTTP responses after failed streaming requests 2026-10-11 09:01:24 -04:00
Rudy Celekli 731eea6101 fix(common): honor one deadline across token wait notifications 2026-10-11 09:01:10 -04:00
Rudy Celekli 6558ab1290 fix(common): keep sorted mappings consistent after bulk mutations 2026-10-11 09:01:03 -04:00
Rudy Celekli 82ee04e490 fix(edit): replace nonempty whitespace instead of appending
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:57:48 -04:00
Rudy Celekli 191a3fa7cd fix(browser): use native actions for snapshot references
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:52:56 -04:00
Rudy Celekli f940a485ab fix(files): preserve suffixes of local attachment names
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:39:37 -04:00
Rudy Celekli c3542007c6 fix(office): retain PowerPoint table and grouped text
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:36:05 -04:00
Rudy Celekli b81294e3a3 fix(memory): preserve Unicode words in keyword searches
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:32:11 -04:00
Rudy Celekli 032f60a2d3 fix(search_files): preserve external filename record boundaries
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
2026-10-06 12:22:59 -04:00
Rudy Celekli 03a8777770 fix(feishu): bound remote media before reply upload 2026-09-28 00:54:40 -04:00
Rudy Celekli 781bd71243 fix(wecom_bot): bound outbound remote media downloads 2026-09-28 00:52:37 -04:00
Rudy Celekli 1ce6bc099f fix(wechatcom): bound outbound image URL downloads 2026-09-28 00:49:55 -04:00
Rudy Celekli e4463e02bb fix(feishu): tolerate temp cleanup failure 2026-09-28 00:48:35 -04:00
Rudy Celekli 76cbc51417 fix(feishu): bound inbound file and audio downloads 2026-09-28 00:47:58 -04:00
Rudy Celekli 284cf16f27 fix(wecom_bot): bound encrypted media and validate padding 2026-09-28 00:45:37 -04:00
Rudy Celekli 6cf7173cf2 fix(dingtalk): bound inbound media downloads 2026-09-28 00:43:00 -04:00
Rudy Celekli a771bdf349 fix(feishu): bound inbound image downloads 2026-09-28 00:21:57 -04:00
Rudy Celekli 2ed10c40d2 fix(slack): keep same-named inbound files separate 2026-09-28 00:15:59 -04:00
Rudy Celekli 56eeac9b37 fix(qq): bound inbound attachment downloads 2026-09-28 00:11:47 -04:00
Rudy Celekli 0196d1c406 test(subagent): wait for timed-out worker teardown 2026-09-28 00:01:30 -04:00
Rudy Celekli 0ab0b73010 test(scheduler): retain valid primary over older backup 2026-09-27 23:57:47 -04:00
Rudy Celekli 426e46c8ef fix(scheduler): recover corrupt task store from backup 2026-09-27 23:54:59 -04:00
Rudy Celekli 613e7291cf fix(wechat-kf): advance cursor after queueing messages 2026-09-27 23:48:15 -04:00
Rudy Celekli a57146cf22 fix(wechat-kf): bound remote media replies 2026-09-27 23:42:41 -04:00
Rudy Celekli 8cc47a1a17 fix(wechatmp): bound remote media downloads 2026-09-27 23:36:34 -04:00
Rudy Celekli c6c870aab6 fix(terminal): bound remote image downloads 2026-09-27 23:31:35 -04:00