Skip to content

fix: reconcile engine, TUI, Tower and Remote Control fixes - #377

Merged
elkaix merged 33 commits into
mainfrom
fix/reconcile-2026-10-15
Oct 15, 2026
Merged

elkaix merged 33 commits into
mainfrom
fix/reconcile-2026-10-15

Conversation

@elkaix

@elkaix elkaix commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Requirement or Bug

A set of fixes and features across the engine, TUI, gateway, Tower, Remote Control and the VS Code extension.

Bug Reproduction Steps

Each fix has a regression test. The main ones:

  • Re-import a provider registry with pythinker provider → the default model and provider are cleared.
  • Cancel a background agent → the TUI does not show it as stopped.
  • Resume a session that used image or video tools → the media tools are gone.
  • Fork a subagent → its request prefix differs from the parent, so the prompt cache misses.
  • Press Ctrl+C while shutdown hooks run → no progress, no forced exit.
  • Remote Control response over 10 MiB → rejected.

Root Cause

Each commit fixes its own root cause; see the commit messages. All are fundamental fixes, not workarounds.

Code Changes

32 commits, one per change, so they can be reviewed one at a time:

  • Engine (agent-core-v2): mid-turn progress notes and calmer NotifyUser nudges, media tools restored after resume, fork subagent prefix parity (plus a prompt-cache probe that reports it), PYTHINKER_CODE_LLM_HEADERS_TIMEOUT_MS, select_tools explanations, plugin skills under qualified names, [mcp] default_deferred, a todo-list nudge, subagent tool descriptions that match what the subagent can use, model migration metadata from provider registries.
  • Tower (experimental): missions are merged and reviewed through deterministic git checks; new TowerComplete and TowerRebase tools; a bash guard blocks destructive commands in the main checkout; tower.base state is removed.
  • TUI / CLI: Working… spinner label, shutdown progress with forced exit on a second Ctrl+C, inline skill-prompt tokens and steering, the previous answer stays visible after task-notification turns, the git-status footer no longer blocks (chokidar watcher), command lookup skips workspace binaries instead of failing, cumulative survey turn counts.
  • Gateway: agent hooks run in the session's working directory.
  • Remote Control: pythinker web exits when the relay takes the device offline; responses over 10 MiB are sent as 5 MiB response_chunk frames (up to about 100 MiB), and a relay abort cancels a transfer. The relay already accepts response_chunk frames (deployed before this merges).
  • Providers: Gemini 4 uses thinking levels; "off" maps to LOW.
  • Removed: the unused packages/pyaos package, the never-implemented MCP executor = "pyaos" option (and its "kaos" alias), the SDK pyaos session options and RPCs, and the ssh2 overrides. flake.nix workspace lists and the pnpmDeps hash are updated.
  • VS Code: Back navigation in multi-question AskUserQuestion prompts.
  • Docs: Tower guide, NotifyUser, MCP "Loading tools on demand", provider registry upgrade metadata.

Behavior Changes and Affected Users

Behavior Before After Who relies on the old behavior Escape hatch
Plugin skill invocation by bare name /skill:review ran a plugin's review skill Only /skill:<plugin-id>:review runs it Users, saved prompts and scripts that call plugin skills by short name None (maintainer sign-off below); use the qualified name
Plugin name validation Lowercase only Uppercase, dots and an @ suffix allowed Nobody (it only widens accepted input) n/a
MCP stdio executor = "pyaos" / "kaos" Accepted (kaos normalized to pyaos), never implemented Config fails validation at load time Configs that set it; it never had any effect Remove the key
SDK pyaos / persistencePyaos session options Accepted and ignored Stripped before the RPC; the *WithPyaos RPCs are gone SDK hosts that pass them (still ignored, no crash) n/a
Agent hook working directory (web/desktop) Gateway process cwd Session working directory Hook scripts that assumed the gateway cwd Use absolute paths in the hook
Command lookup finds a binary inside the workspace Lookup failed Binary skipped; search continues on PATH; also when cwd is / Nobody relied on the failure n/a
Tower shell in the main checkout Any command allowed Destructive commands blocked Tower users (experimental flag) Tower is off unless PYTHINKER_CODE_EXPERIMENTAL_TOWER=1
tower_mode.enter records with base base stored in tower.base Field dropped on replay (zod strips unknown keys) Sessions that entered Tower before this change Resume works; verified
Default model when a registry retires it Kept the retired model Switches to the declared replacement and shows migration notes Users whose default model the registry retires None
Registry re-import Cleared default model and provider Keeps them Nobody n/a
Remote Control response > 10 MiB Rejected Sent in chunks up to about 100 MiB Relays without response_chunk support (ours is updated) n/a
pythinker web when the relay takes the device offline Kept running Exits Users who expected it to keep serving locally None
Gemini 4 thinking Thinking budget Thinking level; off → LOW Gemini 4 users n/a
MCP deferred loading Per-server deferred only Plus global [mcp] default_deferred (needs tool-select flag) Nobody (default off) n/a
Prompt text: NotifyUser / progress notes Discouraged short notes between tool calls Allows them; reminders counted per round of tool calls Every session n/a
Prompt text: todo nudge No nudge Reminder when todo items stay open for several steps Every session with a todo list n/a
Prompt text: subagent tool descriptions Listed tools the subagent could not use Lists only available tools Sessions that spawn subagents n/a

Maintainer sign-off needed: the plugin-skill bare-name removal has no escape hatch. Approved by the maintainer for this PR.

Contract files touched and their consumers:

  • config-manifest.toml: new [mcp] default_deferred, new registry upgrade object. Additive; old configs load unchanged.
  • state-manifest.d.ts: tower.base removed, llmRequester.lastTurnRequest added. Old journals replay (unknown key dropped).
  • wire-manifest.d.ts: tower_mode.enter drops base. Older records still parse.
  • features/externalHooks/: hook cwd change above.
  • apps/pythinker-code/src/cli/: provider refresh now goes through the engine; web exits on relay offline.
  • packages/node-sdk: pyaos options and RPCs removed (SDK is internal; the CLI is the only published consumer).

Tests: every row above has a test in the touched package. Full gates: build, typecheck, lint, sherif, all tests, VS Code typecheck and tests, Nix workspace check, web bundle check, nix build .#pythinker-code.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue (external PRs: issue must have a maintainer's /approve).
  • I have added tests that prove my feature works.
  • The behavior-change table above is complete, and every removed behavior or flipped default is named in the changeset and either has an escape hatch or was explicitly approved by a maintainer in this PR.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

elkaix added 30 commits October 15, 2026 14:20
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 375 files, which is 275 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration
  • Configuration used: Repository: PyModel/pythinker-code/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: dd6d3110-0d68-4577-9746-76a4be641757
📥 Commits

Reviewing files that changed from the base of the PR and between e1791a6 and c97b96e.

⛔ Files ignored due to path filters: 1
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/pnpm-lock.yaml
📒 Files selected for processing: 375
  • .agents/skills/gen-changesets/SKILL.md
  • .changeset/calm-progress-nudges.md
  • .changeset/cancel-video-uploads.md
  • .changeset/command-lookup-workspace.md
  • .changeset/footer-git-refresh.md
  • .changeset/fork-subagent-cache-prefix.md
  • .changeset/gemini-thinking-level.md
  • .changeset/hooks-session-cwd.md
  • .changeset/inline-skill-prompts.md
  • .changeset/llm-headers-timeout.md
  • .changeset/mcp-default-deferred.md
  • .changeset/media-tools-after-resume.md
  • .changeset/model-migration.md
  • .changeset/notify-user-title.md
  • .changeset/plugin-skill-qualified-names.md
  • .changeset/registry-reimport-default.md
  • .changeset/relay-offline-exit.md
  • .changeset/remote-control-large-transfers.md
  • .changeset/remove-mcp-pyaos-executor.md
  • .changeset/select-tools-errors.md
  • .changeset/shutdown-progress.md
  • .changeset/subagent-tool-descriptions.md
  • .changeset/task-notification-answer.md
  • .changeset/todo-list-nudge.md
  • .changeset/tower-deterministic-missions.md
  • .changeset/vscode-question-back.md
  • .changeset/working-spinner-label.md
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • apps/pythinker-code/dist-web/.web-bundle-manifest.json
  • apps/pythinker-code/package.json
  • apps/pythinker-code/src/cli/sub/provider.ts
  • apps/pythinker-code/src/cli/sub/web/remote-control.ts
  • apps/pythinker-code/src/cli/sub/web/run.ts
  • apps/pythinker-code/src/constant/app.ts
  • apps/pythinker-code/src/tui/commands/config.ts
  • apps/pythinker-code/src/tui/commands/dispatch.ts
  • apps/pythinker-code/src/tui/commands/provider.ts
  • apps/pythinker-code/src/tui/commands/resolve.ts
  • apps/pythinker-code/src/tui/commands/tower.ts
  • apps/pythinker-code/src/tui/commands/web.ts
  • apps/pythinker-code/src/tui/components/chrome/footer.ts
  • apps/pythinker-code/src/tui/components/chrome/notify-panel.ts
  • apps/pythinker-code/src/tui/components/dialogs/choice-picker.ts
  • apps/pythinker-code/src/tui/components/messages/agent-dynamic-workflow-progress.ts
  • apps/pythinker-code/src/tui/components/messages/background-agent-status.ts
  • apps/pythinker-code/src/tui/components/messages/sticky-user-message.ts
  • apps/pythinker-code/src/tui/components/messages/tool-call.ts
  • apps/pythinker-code/src/tui/components/messages/user-message.ts
  • apps/pythinker-code/src/tui/constant/pythinker-tui.ts
  • apps/pythinker-code/src/tui/controllers/auth-flow.ts
  • apps/pythinker-code/src/tui/controllers/btw-panel.ts
  • apps/pythinker-code/src/tui/controllers/cache-hint-controller.ts
  • apps/pythinker-code/src/tui/controllers/editor-keyboard.ts
  • apps/pythinker-code/src/tui/controllers/model-migration.ts
  • apps/pythinker-code/src/tui/controllers/notify.ts
  • apps/pythinker-code/src/tui/controllers/session-event-handler.ts
  • apps/pythinker-code/src/tui/controllers/session-replay.ts
  • apps/pythinker-code/src/tui/controllers/staging-leases.ts
  • apps/pythinker-code/src/tui/controllers/subagent-event-handler.ts
  • apps/pythinker-code/src/tui/controllers/survey-controller.ts
  • apps/pythinker-code/src/tui/pythinker-tui.ts
  • apps/pythinker-code/src/tui/types.ts
  • apps/pythinker-code/src/tui/utils/background-agent-status.ts
  • apps/pythinker-code/src/tui/utils/image-attachment-store.ts
  • apps/pythinker-code/src/tui/utils/image-placeholder.ts
  • apps/pythinker-code/src/tui/utils/inline-skill-tokens.ts
  • apps/pythinker-code/src/tui/utils/message-replay.ts
  • apps/pythinker-code/src/tui/utils/model-switch.ts
  • apps/pythinker-code/src/tui/utils/refresh-providers.ts
  • apps/pythinker-code/src/tui/utils/survey-policy.ts
  • apps/pythinker-code/src/utils/git/git-status.ts
  • apps/pythinker-code/src/utils/model-migration-state.ts
  • apps/pythinker-code/src/utils/paths.ts
  • apps/pythinker-code/src/utils/process/resolve-command.ts
  • apps/pythinker-code/test/cli/web/remote-control.test.ts
  • apps/pythinker-code/test/cli/web/web.test.ts
  • apps/pythinker-code/test/tui/commands/provider.test.ts
  • apps/pythinker-code/test/tui/commands/resolve.test.ts
  • apps/pythinker-code/test/tui/commands/tower.test.ts
  • apps/pythinker-code/test/tui/commands/web.test.ts
  • apps/pythinker-code/test/tui/components/chrome/footer.test.ts
  • apps/pythinker-code/test/tui/components/chrome/welcome.test.ts
  • apps/pythinker-code/test/tui/components/dialogs/choice-picker.test.ts
  • apps/pythinker-code/test/tui/components/messages/sticky-user-message.test.ts
  • apps/pythinker-code/test/tui/components/messages/tool-call.test.ts
  • apps/pythinker-code/test/tui/components/messages/user-message.test.ts
  • apps/pythinker-code/test/tui/components/panels/notify-panel.test.ts
  • apps/pythinker-code/test/tui/controllers/cache-hint-controller.test.ts
  • apps/pythinker-code/test/tui/controllers/editor-keyboard.test.ts
  • apps/pythinker-code/test/tui/controllers/notify.test.ts
  • apps/pythinker-code/test/tui/controllers/session-event-handler-background-task.test.ts
  • apps/pythinker-code/test/tui/controllers/staging-leases.test.ts
  • apps/pythinker-code/test/tui/controllers/subagent-event-handler.test.ts
  • apps/pythinker-code/test/tui/controllers/survey-controller.test.ts
  • apps/pythinker-code/test/tui/input/image-placeholder.test.ts
  • apps/pythinker-code/test/tui/message-replay.test.ts
  • apps/pythinker-code/test/tui/pythinker-tui-message-flow.test.ts
  • apps/pythinker-code/test/tui/pythinker-tui-startup.test.ts
  • apps/pythinker-code/test/tui/utils/refresh-providers.test.ts
  • apps/pythinker-code/test/utils/git/git-status.test.ts
  • apps/pythinker-code/test/utils/model-migration-state.test.ts
  • apps/pythinker-code/test/utils/process/resolve-command.test.ts
  • apps/vscode/scripts/watch-extension.mjs
  • apps/vscode/src/runtime/replay-adapter.ts
  • apps/vscode/test/replay-adapter.test.ts
  • apps/vscode/test/webview/QuestionDialog.test.tsx
  • apps/vscode/tsdown.config.ts
  • apps/vscode/webview-ui/src/components/QuestionDialog.tsx
  • architecture-policy.yaml
  • docs/.vitepress/config.ts
  • docs/configuration/config-files.md
  • docs/configuration/env-vars.md
  • docs/configuration/providers.md
  • docs/customization/agents.md
  • docs/customization/mcp.md
  • docs/customization/plugins.md
  • docs/guides/interaction.md
  • docs/guides/tower.md
  • docs/guides/web.md
  • docs/reference/server-api.md
  • docs/reference/slash-commands.md
  • docs/reference/tools.md
  • flake.nix
  • packages/agent-core-v2/docs/config-manifest.toml
  • packages/agent-core-v2/docs/state-manifest.d.ts
  • packages/agent-core-v2/docs/wire-manifest.d.ts
  • packages/agent-core-v2/src/agent/contextMemory/contextMemory.ts
  • packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts
  • packages/agent-core-v2/src/agent/llmRequester/llmRequester.ts
  • packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts
  • packages/agent-core-v2/src/agent/mcp/mcpService.ts
  • packages/agent-core-v2/src/agent/media/mediaToolsRegistrar.ts
  • packages/agent-core-v2/src/agent/modeMutex/modeMutexService.ts
  • packages/agent-core-v2/src/agent/profile/profileService.ts
  • packages/agent-core-v2/src/agent/task/taskService.ts
  • packages/agent-core-v2/src/agent/toolActivation/toolActivationService.ts
  • packages/agent-core-v2/src/agent/toolActivation/toolAvailability.ts
  • packages/agent-core-v2/src/agent/toolPolicy/toolPolicy.ts
  • packages/agent-core-v2/src/agent/toolPolicy/toolPolicyService.ts
  • packages/agent-core-v2/src/agent/toolSelect/dynamicTools.ts
  • packages/agent-core-v2/src/agent/toolSelect/toolSelect.ts
  • packages/agent-core-v2/src/agent/toolSelect/toolSelectService.ts
  • packages/agent-core-v2/src/agent/tools/agent/agentTool.ts
  • packages/agent-core-v2/src/agent/tools/read-media-file/readMediaFileTool.ts
  • packages/agent-core-v2/src/agent/tools/select-tools/selectToolsTool.ts
  • packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait-subagent.md
  • packages/agent-core-v2/src/agent/tools/task/task-wait/taskWaitTool.ts
  • packages/agent-core-v2/src/agent/usage/cacheProbeService.ts
  • packages/agent-core-v2/src/agent/usage/usageEvents.ts
  • packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts
  • packages/agent-core-v2/src/app/agentProfileCatalog/profile-shared.ts
  • packages/agent-core-v2/src/app/agentProfileCatalog/system.md
  • packages/agent-core-v2/src/app/kosongConfig/configSection.ts
  • packages/agent-core-v2/src/app/kosongConfig/discovery.ts
  • packages/agent-core-v2/src/app/kosongConfig/discoveryService.ts
  • packages/agent-core-v2/src/app/mcpConfig/configSection.ts
  • packages/agent-core-v2/src/app/mcpManagement/mcpManagementService.ts
  • packages/agent-core-v2/src/app/plugin/types.ts
  • packages/agent-core-v2/src/app/telemetry/events.ts
  • packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooksService.ts
  • packages/agent-core-v2/src/features/notify/notifyUserNudge.ts
  • packages/agent-core-v2/src/features/notify/notifyUserNudgeService.ts
  • packages/agent-core-v2/src/features/notify/tools/notify-user/notify-user.md
  • packages/agent-core-v2/src/features/notify/tools/notify-user/notify-user.ts
  • packages/agent-core-v2/src/features/notify/tools/notify-user/notifyUserTool.ts
  • packages/agent-core-v2/src/features/plan/profile/plan.ts
  • packages/agent-core-v2/src/features/skill/catalog/registry.ts
  • packages/agent-core-v2/src/features/skill/skill.ts
  • packages/agent-core-v2/src/features/skill/skillService.ts
  • packages/agent-core-v2/src/features/skill/tools/skill.ts
  • packages/agent-core-v2/src/features/todo/todoItem.ts
  • packages/agent-core-v2/src/features/todo/todoListReminder.ts
  • packages/agent-core-v2/src/features/todo/todoService.ts
  • packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list-write-reminder.md
  • packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.md
  • packages/agent-core-v2/src/features/todo/tools/todo-list/todoListTool.ts
  • packages/agent-core-v2/src/features/tower/bashGuard.ts
  • packages/agent-core-v2/src/features/tower/injection/tower-mode-full-reminder.md
  • packages/agent-core-v2/src/features/tower/injection/tower-mode-sparse-reminder.md
  • packages/agent-core-v2/src/features/tower/injection/towerModeInjection.ts
  • packages/agent-core-v2/src/features/tower/protocol/git.ts
  • packages/agent-core-v2/src/features/tower/protocol/index.ts
  • packages/agent-core-v2/src/features/tower/protocol/missionGate.ts
  • packages/agent-core-v2/src/features/tower/protocol/store.ts
  • packages/agent-core-v2/src/features/tower/protocol/types.ts
  • packages/agent-core-v2/src/features/tower/tools/complete/complete.md
  • packages/agent-core-v2/src/features/tower/tools/complete/complete.ts
  • packages/agent-core-v2/src/features/tower/tools/complete/completeTool.ts
  • packages/agent-core-v2/src/features/tower/tools/delivery.ts
  • packages/agent-core-v2/src/features/tower/tools/finding/findingTool.ts
  • packages/agent-core-v2/src/features/tower/tools/inbox/inbox.md
  • packages/agent-core-v2/src/features/tower/tools/inbox/inbox.ts
  • packages/agent-core-v2/src/features/tower/tools/inbox/inboxTool.ts
  • packages/agent-core-v2/src/features/tower/tools/init/init.md
  • packages/agent-core-v2/src/features/tower/tools/init/init.ts
  • packages/agent-core-v2/src/features/tower/tools/init/initTool.ts
  • packages/agent-core-v2/src/features/tower/tools/merge/merge.md
  • packages/agent-core-v2/src/features/tower/tools/merge/mergeTool.ts
  • packages/agent-core-v2/src/features/tower/tools/mission/mission.md
  • packages/agent-core-v2/src/features/tower/tools/mission/mission.ts
  • packages/agent-core-v2/src/features/tower/tools/plan/plan.md
  • packages/agent-core-v2/src/features/tower/tools/plan/plan.ts
  • packages/agent-core-v2/src/features/tower/tools/rebase/rebase.md
  • packages/agent-core-v2/src/features/tower/tools/rebase/rebase.ts
  • packages/agent-core-v2/src/features/tower/tools/rebase/rebaseTool.ts
  • packages/agent-core-v2/src/features/tower/tools/review/review.md
  • packages/agent-core-v2/src/features/tower/tools/review/reviewTool.ts
  • packages/agent-core-v2/src/features/tower/tools/send/send.md
  • packages/agent-core-v2/src/features/tower/tools/send/sendTool.ts
  • packages/agent-core-v2/src/features/tower/tools/spawn/spawn.md
  • packages/agent-core-v2/src/features/tower/tools/spawn/spawnTool.ts
  • packages/agent-core-v2/src/features/tower/tools/status/status.md
  • packages/agent-core-v2/src/features/tower/tools/status/statusReader.ts
  • packages/agent-core-v2/src/features/tower/tools/status/statusTool.ts
  • packages/agent-core-v2/src/features/tower/tools/support.ts
  • packages/agent-core-v2/src/features/tower/tower-worker-overlay.md
  • packages/agent-core-v2/src/features/tower/tower.ts
  • packages/agent-core-v2/src/features/tower/towerFeature.ts
  • packages/agent-core-v2/src/features/tower/towerOps.ts
  • packages/agent-core-v2/src/features/tower/towerService.ts
  • packages/agent-core-v2/src/features/tower/workerProfile.ts
  • packages/agent-core-v2/src/human/llm/requester/bases/anthropic/requester.ts
  • packages/agent-core-v2/src/human/llm/requester/bases/google-genai/format.ts
  • packages/agent-core-v2/src/human/llm/requester/bases/openai-responses/requester.ts
  • packages/agent-core-v2/src/human/llm/requester/bases/openai/requester.ts
  • packages/agent-core-v2/src/human/llm/requester/timeout.ts
  • packages/agent-core-v2/src/human/test/llm/errors.test.ts
  • packages/agent-core-v2/src/human/test/llm/headers-timeout.test.ts
  • packages/agent-core-v2/src/human/test/llm/trait.test.ts
  • packages/agent-core-v2/src/llm-adapter/model/catalog.ts
  • packages/agent-core-v2/src/llm-adapter/model/model.ts
  • packages/agent-core-v2/src/mcpCore/client-stdio.ts
  • packages/agent-core-v2/src/mcpCore/config-schema.ts
  • packages/agent-core-v2/src/mcpCore/connection-manager.ts
  • packages/agent-core-v2/src/session/agentLifecycle/profile/explore-overlay.md
  • packages/agent-core-v2/src/session/mcp/mergedConnectionView.ts
  • packages/agent-core-v2/src/session/subagent/subagentService.ts
  • packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcpService.ts
  • packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfig.ts
  • packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfigService.ts
  • packages/agent-core-v2/test/agent/contextMemory/stubs.ts
  • packages/agent-core-v2/test/agent/fullCompaction/fullCompaction.test.ts
  • packages/agent-core-v2/test/agent/llmRequester/llmRequester.test.ts
  • packages/agent-core-v2/test/agent/llmRequester/llmRequesterService.test.ts
  • packages/agent-core-v2/test/agent/loop/loop.test.ts
  • packages/agent-core-v2/test/agent/mcp/mcp.test.ts
  • packages/agent-core-v2/test/agent/media/tools/read-media.test.ts
  • packages/agent-core-v2/test/agent/modeMutex/modeMutex.test.ts
  • packages/agent-core-v2/test/agent/profile/binding.test.ts
  • packages/agent-core-v2/test/agent/profile/profileOps.test.ts
  • packages/agent-core-v2/test/agent/task/taskService.test.ts
  • packages/agent-core-v2/test/agent/toolActivation/toolActivationService.test.ts
  • packages/agent-core-v2/test/agent/toolPolicy/toolPolicyService.test.ts
  • packages/agent-core-v2/test/agent/toolSelect/dynamicTools.test.ts
  • packages/agent-core-v2/test/agent/toolSelect/toolSelect.e2e.test.ts
  • packages/agent-core-v2/test/agent/toolSelect/toolSelectService.test.ts
  • packages/agent-core-v2/test/agent/usage/usage.test.ts
  • packages/agent-core-v2/test/app/agentProfileCatalog/profile-shared.test.ts
  • packages/agent-core-v2/test/app/plugin/types.test.ts
  • packages/agent-core-v2/test/features/externalHooks/integration.test.ts
  • packages/agent-core-v2/test/features/notify/notifyUserNudge.test.ts
  • packages/agent-core-v2/test/features/notify/notifyUserNudgeService.test.ts
  • packages/agent-core-v2/test/features/notify/tools/notify-user.test.ts
  • packages/agent-core-v2/test/features/skill/activateSkill.test.ts
  • packages/agent-core-v2/test/features/skill/catalog/registry.test.ts
  • packages/agent-core-v2/test/features/skill/workspace/skillCatalog.test.ts
  • packages/agent-core-v2/test/features/todo/sessionTodo.test.ts
  • packages/agent-core-v2/test/features/todo/todoListReminder.test.ts
  • packages/agent-core-v2/test/features/todo/tools/todo-list.test.ts
  • packages/agent-core-v2/test/features/tower/store.test.ts
  • packages/agent-core-v2/test/features/tower/tools/spawnTool.test.ts
  • packages/agent-core-v2/test/features/tower/tools/towerTools.test.ts
  • packages/agent-core-v2/test/features/tower/towerFeature.test.ts
  • packages/agent-core-v2/test/features/tower/towerService.test.ts
  • packages/agent-core-v2/test/features/tower/workerProfile.test.ts
  • packages/agent-core-v2/test/lint/import-boundaries.test.ts
  • packages/agent-core-v2/test/llm-adapter/model/catalog.test.ts
  • packages/agent-core-v2/test/mcpCore/client-stdio.test.ts
  • packages/agent-core-v2/test/mcpCore/connection-manager.test.ts
  • packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts
  • packages/agent-core-v2/test/session/subagent/forkParity.test.ts
  • packages/agent-core-v2/test/session/subagent/subagentScopeCache.test.ts
  • packages/agent-core-v2/test/state/builtinReplayableKeys.ts
  • packages/agent-core-v2/test/stubs.ts
  • packages/agent-core-v2/test/wire/resume.test.ts
  • packages/agent-core-v2/test/workspace/workspaceMcpConfig/workspaceMcpConfig.test.ts
  • packages/agent-gateway/src/protocol/events-zod.ts
  • packages/agent-gateway/src/routes/modelCatalog.ts
  • packages/agent-gateway/src/transport/ws/v1/events.ts
  • packages/agent-gateway/src/transport/ws/v1/sessionEventBroadcaster.ts
  • packages/agent-gateway/test/modelCatalog.test.ts
  • packages/agent-gateway/test/modelCatalogProviderWrite.test.ts
  • packages/agent-gateway/test/sessionEventBroadcaster.test.ts
  • packages/klient/scripts/run-docker-e2e.sh
  • packages/klient/src/contract/agent/schemas.ts
  • packages/klient/src/contract/global/auth.ts
  • packages/klient/src/contract/global/catalog.ts
  • packages/klient/src/contract/global/events.ts
  • packages/klient/src/contract/global/providerDiscovery.ts
  • packages/klient/src/contract/mcp.ts
  • packages/klient/test/contract.test.ts
  • packages/klient/test/e2e/invalid-input-matrix.test.ts
  • packages/klient/test/facade.test.ts
  • packages/klient/test/helpers/conformance.ts
  • packages/kosong/src/providers/google-genai.ts
  • packages/kosong/test/google-genai.test.ts
  • packages/node-sdk/api-extractor.json
  • packages/node-sdk/package.json
  • packages/node-sdk/scripts/build-dts.mjs
  • packages/node-sdk/src/config/schema.ts
  • packages/node-sdk/src/config/toml.ts
  • packages/node-sdk/src/pythinker-harness.ts
  • packages/node-sdk/src/replay.ts
  • packages/node-sdk/src/rpc.ts
  • packages/node-sdk/src/sdk-rpc-client-v2.ts
  • packages/node-sdk/src/session.ts
  • packages/node-sdk/src/types.ts
  • packages/node-sdk/src/v2/resume-replay.ts
  • packages/node-sdk/test/config.test.ts
  • packages/node-sdk/test/replay.test.ts
  • packages/node-sdk/test/sdk-rpc-client-v2.test.ts
  • packages/node-sdk/test/session-prompt-events.test.ts
  • packages/node-sdk/test/session-skills.test.ts
  • packages/node-sdk/tsconfig.dts.json
  • packages/node-sdk/tsdown.config.ts
  • packages/oauth/src/custom-registry.ts
  • packages/oauth/src/model-alias-merge.ts
  • packages/oauth/src/provider-config.ts
  • packages/oauth/src/refreshProviderModels.ts
  • packages/oauth/test/custom-registry.test.ts
  • packages/oauth/test/refreshProviderModels.test.ts
  • packages/pyaos/CHANGELOG.md
  • packages/pyaos/README.md
  • packages/pyaos/package.json
  • packages/pyaos/src/current.ts
  • packages/pyaos/src/environment.ts
  • packages/pyaos/src/errors.ts
  • packages/pyaos/src/index.ts
  • packages/pyaos/src/internal.ts
  • packages/pyaos/src/local.ts
  • packages/pyaos/src/login-shell-path.ts
  • packages/pyaos/src/process.ts
  • packages/pyaos/src/pyaos.ts
  • packages/pyaos/src/shell-path-bridge.ts
  • packages/pyaos/src/ssh.ts
  • packages/pyaos/src/types.ts
  • packages/pyaos/test/cmd.test.ts
  • packages/pyaos/test/current.test.ts
  • packages/pyaos/test/e2e/concurrent-operations.test.ts
  • packages/pyaos/test/e2e/exec-edge-cases.test.ts
  • packages/pyaos/test/e2e/glob-boundaries-parity.test.ts
  • packages/pyaos/test/e2e/process-lifecycle.test.ts
  • packages/pyaos/test/e2e/ssh-mock.test.ts
  • packages/pyaos/test/e2e/ssh-resolve-path.test.ts
  • packages/pyaos/test/e2e/symlink-stat-parity.test.ts
  • packages/pyaos/test/environment.test.ts
  • packages/pyaos/test/fixtures/killtree.cjs
  • packages/pyaos/test/internal.test.ts
  • packages/pyaos/test/local.test.ts
  • packages/pyaos/test/login-shell-path.test.ts
  • packages/pyaos/test/setup.ts
  • packages/pyaos/test/shell-path-bridge.test.ts
  • packages/pyaos/test/shell.test.ts
  • packages/pyaos/test/spawn-options.test.ts
  • packages/pyaos/test/ssh-create.test.ts
  • packages/pyaos/test/ssh-process.test.ts
  • packages/pyaos/test/ssh.test.ts
  • packages/pyaos/tsconfig.json
  • packages/pyaos/tsdown.config.ts
  • packages/pyaos/vitest.config.ts
  • packages/remote-control/src/remote-control.ts
  • packages/remote-control/test/remote-control.test.ts
  • pnpm-workspace.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@pymodel/pythinker-code@c97b96e
npx https://pkg.pr.new/@pymodel/pythinker-code@c97b96e

commit: c97b96e

@elkaix
elkaix enabled auto-merge (squash) October 15, 2026 19:40
Provider replace and delete looked up provider ids on a plain object, so
inherited names such as `constructor` or `__proto__` resolved to
Object.prototype members: PUT reported success without writing a provider
and DELETE returned 204 for a provider that does not exist. Use own-property
lookups and build the provider sections with Object.fromEntries.

Remote Control trimmed trailing slashes and found the <head> tag with
regexes that run in quadratic time on hostile input, and inlined the relay
prefix into a <script> block without escaping `</script>`. Trim with a loop,
find the head tag with a linear scan, and escape `<`, `>`, `/`, U+2028 and
U+2029 in the inlined prefix.
@elkaix
elkaix merged commit 9e30eed into main Oct 15, 2026
25 checks passed
@elkaix
elkaix deleted the fix/reconcile-2026-10-15 branch October 15, 2026 20:07
elkaix pushed a commit that referenced this pull request Oct 15, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @pymodel/pythinker-code@2.7.0

### Minor Changes

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - When a provider registry
retires your default model, switch to the replacement it declares and
show its migration notes.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Tower now merges and
reviews missions through deterministic git checks, adds the
TowerComplete and TowerRebase tools, and blocks destructive shell
commands in the main checkout. Enable Tower with
PYTHINKER_CODE_EXPERIMENTAL_TOWER=1.

### Patch Changes

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Stop discouraging short
progress notes between tool calls, and count NotifyUser reminders per
round of tool calls.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Cancel in-flight video
uploads when a media read is interrupted.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Skip executables inside
the workspace during command lookup instead of failing, including when
the working directory is the filesystem root.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Stop the footer from
waiting on git status; it now refreshes when the repository changes.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep forked subagent
requests on the same prefix as the parent so they reuse the prompt
cache.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Use thinking levels for
Gemini 4 models, and send the lowest level when thinking is off.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Run agent hooks in the
session's working directory in the web and desktop apps.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show skills invoked in a
prompt as highlighted tokens in the message, and let Ctrl+S steer a
skill prompt into a running turn.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Add
PYTHINKER_CODE_LLM_HEADERS_TIMEOUT_MS to set how long a request waits
for LLM response headers, for slow non-streaming thinking.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Add `default_deferred`
under `[mcp]` in config.toml to load the tools of every MCP server on
demand; it requires the experimental tool-select feature.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Restore the image and
video reading tools after resuming a session.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Give NotifyUser updates
an optional one-line title in the Updates panel. Enable NotifyUser with
PYTHINKER_CODE_EXPERIMENTAL_NOTIFY_USER=1.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Register plugin skills as
`<plugin-id>:<skill-name>`; a bare skill name no longer runs a plugin
skill and there is no setting to restore that, so use
`/skill:<plugin-id>:<skill-name>`. Plugin names can now contain
uppercase letters, dots, and an `@` suffix.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep the default model
and provider when re-importing a provider registry.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Exit `pythinker web` when
the Remote Control relay takes the device offline.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remote Control now sends
HTTP responses larger than 10 MiB in 5 MiB chunks, up to about 100 MiB,
and cancels a transfer when the relay aborts it.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remove the
never-implemented `executor = "pyaos"` option (and its old `"kaos"`
alias) from MCP stdio server configuration; configs that use it now fail
validation at load time.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Explain why select_tools
cannot load a tool, and report tools that are not available in the
current session separately.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show shutdown progress
while shutdown hooks run, and exit at once when you press Ctrl+C again.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Describe only the tools a
subagent can actually use.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep the previous answer
visible when a background task notification turn ends, and show
cancelled background agents as stopped.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remind the agent to
update its todo list when items stay open for several steps.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show Working… instead of
Thinking… in the status spinner while the model thinks.
## @pymodel/pythinker-desktop@1.8.0

### Minor Changes

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - When a provider registry
retires your default model, switch to the replacement it declares and
show its migration notes.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Tower now merges and
reviews missions through deterministic git checks, adds the
TowerComplete and TowerRebase tools, and blocks destructive shell
commands in the main checkout. Enable Tower with
PYTHINKER_CODE_EXPERIMENTAL_TOWER=1.

### Patch Changes

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Stop discouraging short
progress notes between tool calls, and count NotifyUser reminders per
round of tool calls.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Cancel in-flight video
uploads when a media read is interrupted.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Skip executables inside
the workspace during command lookup instead of failing, including when
the working directory is the filesystem root.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Stop the footer from
waiting on git status; it now refreshes when the repository changes.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep forked subagent
requests on the same prefix as the parent so they reuse the prompt
cache.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Use thinking levels for
Gemini 4 models, and send the lowest level when thinking is off.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Run agent hooks in the
session's working directory in the web and desktop apps.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show skills invoked in a
prompt as highlighted tokens in the message, and let Ctrl+S steer a
skill prompt into a running turn.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Add
PYTHINKER_CODE_LLM_HEADERS_TIMEOUT_MS to set how long a request waits
for LLM response headers, for slow non-streaming thinking.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Add `default_deferred`
under `[mcp]` in config.toml to load the tools of every MCP server on
demand; it requires the experimental tool-select feature.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Restore the image and
video reading tools after resuming a session.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Give NotifyUser updates
an optional one-line title in the Updates panel. Enable NotifyUser with
PYTHINKER_CODE_EXPERIMENTAL_NOTIFY_USER=1.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Register plugin skills as
`<plugin-id>:<skill-name>`; a bare skill name no longer runs a plugin
skill and there is no setting to restore that, so use
`/skill:<plugin-id>:<skill-name>`. Plugin names can now contain
uppercase letters, dots, and an `@` suffix.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep the default model
and provider when re-importing a provider registry.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Exit `pythinker web` when
the Remote Control relay takes the device offline.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remote Control now sends
HTTP responses larger than 10 MiB in 5 MiB chunks, up to about 100 MiB,
and cancels a transfer when the relay aborts it.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remove the
never-implemented `executor = "pyaos"` option (and its old `"kaos"`
alias) from MCP stdio server configuration; configs that use it now fail
validation at load time.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Explain why select_tools
cannot load a tool, and report tools that are not available in the
current session separately.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show shutdown progress
while shutdown hooks run, and exit at once when you press Ctrl+C again.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Describe only the tools a
subagent can actually use.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Keep the previous answer
visible when a background task notification turn ends, and show
cancelled background agents as stopped.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Remind the agent to
update its todo list when items stay open for several steps.

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Show Working… instead of
Thinking… in the status spinner while the model thinks.
## pythinker@0.9.9

### Patch Changes

- [#377](#377)
[`9e30eed`](9e30eed)
Thanks [@elkaix](https://github.com/elkaix)! - Add Back navigation to
multi-question prompts and keep earlier answers while moving between
questions.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant