| feat(gateway): hot-reload extension changes without transcript replay
Temporarily ignore project-local YAML so global config stays authoritative while cached sessions can pick up config and plugin or skill updates on the next turn without rereading transcripts.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 19 天前 |
| fix(gateway): harden MCP timeout recovery, soften router config, expand web_search
- mcp: on -32001 Request timed out, recycle the stdio transport so the
next call respawns the subprocess. Stops @playwright/mcp-style
wedges where the server-side page.goto keeps running and every
follow-up call from the same session also times out.
- router: stop treating a partial router: block from the UI as fatal.
parseRouterConfig now keeps the rest of the config when scenarios
is absent; ensureRouterConfig fills scenarios.default from
agent.model so RouterRuntime always sees a valid map.
- web_search: route tools.webSearch.{apiKey,endpoint} from yaml into
the builtin tool; add hostname-based auth-mode auto-detection so
*.serp.hk / *.serp.global endpoints use POST + Bearer (their
current API shape) while SerpAPI keeps the legacy GET ?api_key=.
- ui/server: add POST /api/config/test-web-search mirroring the same
dialect rules so the Settings → Search Test button probes the exact
shape the agent tool will use.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 18 天前 |
| refactor: rename Polit/PolitDeck to Pilot/PilotDeck across entire codebase
Automated global rename covering all case variants:
- PolitDeck → PilotDeck, politdeck → pilotdeck, POLITDECK → PILOTDECK
- Polit → Pilot, polit → pilot, POLIT → PILOT, politDeck → pilotDeck
Includes:
- 648 content replacements across 200+ source files
- 24 file renames + 3 directory renames (src/polit→pilot, tests/polit→pilot, docs/polit-config→pilot-config)
- package.json name, bin, env vars updated
- package-lock.json regenerated
- "Politely" in server-manager.ts preserved via placeholder mechanism
- All 587 unit tests pass, tsc --noEmit clean
- E2E tests verified against real OpenRouter API (model, tool-use, context, lifecycle hooks)
Co-authored-by: Cursor <cursoragent@cursor.com>
| 24 天前 |
| fix(gateway): harden MCP timeout recovery, soften router config, expand web_search
- mcp: on -32001 Request timed out, recycle the stdio transport so the
next call respawns the subprocess. Stops @playwright/mcp-style
wedges where the server-side page.goto keeps running and every
follow-up call from the same session also times out.
- router: stop treating a partial router: block from the UI as fatal.
parseRouterConfig now keeps the rest of the config when scenarios
is absent; ensureRouterConfig fills scenarios.default from
agent.model so RouterRuntime always sees a valid map.
- web_search: route tools.webSearch.{apiKey,endpoint} from yaml into
the builtin tool; add hostname-based auth-mode auto-detection so
*.serp.hk / *.serp.global endpoints use POST + Bearer (their
current API shape) while SerpAPI keeps the legacy GET ?api_key=.
- ui/server: add POST /api/config/test-web-search mirroring the same
dialect rules so the Settings → Search Test button probes the exact
shape the agent tool will use.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 18 天前 |
| fix(config): soft-recover agent.model vs router.scenarios.default conflict
Previously fatal: if a user updated agent.model through onboarding/UI
without touching the router block, the gateway refused to boot and
reinstalling didn't help because ~/.pilotdeck/pilotdeck.yaml survives.
- loadPilotConfig: downgrade CONFIG_MODEL_CONFLICT from fatal to a
warning and auto-align router.scenarios.default with agent.model
(agent.model is the canonical source of truth)
- ui/pilotdeckConfig: introduce syncAgentModelWithRouter() and run it
inside writePilotDeckConfig so the on-disk yaml stays consistent
whenever the UI or raw-yaml editor writes a new agent.model
- add load-pilot-config test for the soft-recovery path
Co-authored-by: Cursor <cursoragent@cursor.com>
| 7 天前 |
| refactor: rename Polit/PolitDeck to Pilot/PilotDeck across entire codebase
Automated global rename covering all case variants:
- PolitDeck → PilotDeck, politdeck → pilotdeck, POLITDECK → PILOTDECK
- Polit → Pilot, polit → pilot, POLIT → PILOT, politDeck → pilotDeck
Includes:
- 648 content replacements across 200+ source files
- 24 file renames + 3 directory renames (src/polit→pilot, tests/polit→pilot, docs/polit-config→pilot-config)
- package.json name, bin, env vars updated
- package-lock.json regenerated
- "Politely" in server-manager.ts preserved via placeholder mechanism
- All 587 unit tests pass, tsc --noEmit clean
- E2E tests verified against real OpenRouter API (model, tool-use, context, lifecycle hooks)
Co-authored-by: Cursor <cursoragent@cursor.com>
| 24 天前 |
| feat(channel): refactor platforms into per-channel folders + Feishu stream mode
Migrate all 16 legacy platform adapters from BasePlatformAdapter to the
ChannelAdapter pattern, one folder per channel (matching feishu/weixin layout).
Each new folder contains <Name>Channel.ts, <Name>SessionMapper.ts, and
<name>-render.ts; transport SDKs are imported lazily so they remain optional.
Telegram, Discord, Slack, Matrix, Mattermost, Signal, WhatsApp, BlueBubbles,
DingTalk, WeCom, WeCom Callback, Email, SMS, HomeAssistant, ApiServer, Webhook
all flow through gateway.submitTurn() and render GatewayEvents back to the
platform via their existing transport.
FeishuChannel gains:
- Lark Open API outbound (tenant_access_token cache + im/v1/messages)
- WSClient stream mode (default) — no public URL needed, mirrors weixin-ilink
- Webhook fallback with url_verification, encryptKey AES-256-CBC, verifyToken
- Event dedupe by event_id (LRU 2000)
- Per-chat concurrency guard
Config wiring:
- adapters.feishu now reads appId/appSecret/connectionMode/domainName
- adapters.weixin gated by enabled: true (no more unconditional QR login)
- New PilotPlatformAdapterConfig schema for the 16 platform channels
- loadEnabledChannels(adapters) lazily instantiates the matching channel
- pilotdeckServer.ts threads PilotConfig into channel.start({ config })
Drop the entire src/adapters/channel/platforms/ subtree.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 8 天前 |
| fix(context): add timeout and abort propagation for memory and subagents
Prevent turns from hanging in memory retrieval and forked subagent execution by wiring abort signals end-to-end, adding configurable timeout guards, and covering the new failure paths with regression tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 16 天前 |
| feat(tools): add configurable web search providers
Add GLM, Tavily, and custom provider support for the web_search tool so deployments can choose a single search backend from settings.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 15 天前 |
| refactor: rename Polit/PolitDeck to Pilot/PilotDeck across entire codebase
Automated global rename covering all case variants:
- PolitDeck → PilotDeck, politdeck → pilotdeck, POLITDECK → PILOTDECK
- Polit → Pilot, polit → pilot, POLIT → PILOT, politDeck → pilotDeck
Includes:
- 648 content replacements across 200+ source files
- 24 file renames + 3 directory renames (src/polit→pilot, tests/polit→pilot, docs/polit-config→pilot-config)
- package.json name, bin, env vars updated
- package-lock.json regenerated
- "Politely" in server-manager.ts preserved via placeholder mechanism
- All 587 unit tests pass, tsc --noEmit clean
- E2E tests verified against real OpenRouter API (model, tool-use, context, lifecycle hooks)
Co-authored-by: Cursor <cursoragent@cursor.com>
| 24 天前 |
| feat(channel): refactor platforms into per-channel folders + Feishu stream mode
Migrate all 16 legacy platform adapters from BasePlatformAdapter to the
ChannelAdapter pattern, one folder per channel (matching feishu/weixin layout).
Each new folder contains <Name>Channel.ts, <Name>SessionMapper.ts, and
<name>-render.ts; transport SDKs are imported lazily so they remain optional.
Telegram, Discord, Slack, Matrix, Mattermost, Signal, WhatsApp, BlueBubbles,
DingTalk, WeCom, WeCom Callback, Email, SMS, HomeAssistant, ApiServer, Webhook
all flow through gateway.submitTurn() and render GatewayEvents back to the
platform via their existing transport.
FeishuChannel gains:
- Lark Open API outbound (tenant_access_token cache + im/v1/messages)
- WSClient stream mode (default) — no public URL needed, mirrors weixin-ilink
- Webhook fallback with url_verification, encryptKey AES-256-CBC, verifyToken
- Event dedupe by event_id (LRU 2000)
- Per-chat concurrency guard
Config wiring:
- adapters.feishu now reads appId/appSecret/connectionMode/domainName
- adapters.weixin gated by enabled: true (no more unconditional QR login)
- New PilotPlatformAdapterConfig schema for the 16 platform channels
- loadEnabledChannels(adapters) lazily instantiates the matching channel
- pilotdeckServer.ts threads PilotConfig into channel.start({ config })
Drop the entire src/adapters/channel/platforms/ subtree.
Co-authored-by: Cursor <cursoragent@cursor.com>
| 8 天前 |