Skip to content

fix: add RPC callback support for sendUserMessage in RPC mode - #7

Open
vers-landing-github-prod[bot] wants to merge 2816 commits into
mainfrom
fix/rpc-reminder-callback
Open

fix: add RPC callback support for sendUserMessage in RPC mode#7
vers-landing-github-prod[bot] wants to merge 2816 commits into
mainfrom
fix/rpc-reminder-callback

Conversation

@vers-landing-github-prod

Copy link
Copy Markdown

Problem

When punkin runs in --mode rpc (as a reef agent), the remind_me tool's reminders never fire. There are two compounding issues:

  1. The pi process is ephemeral — reef kills it with SIGTERM on agent_end. Any in-process timers are destroyed.
  2. Even if alive, sendUserMessage calls this.prompt() which starts a new agent turn internally, but the RPC caller isn't listening for unsolicited events.

The reminders extension in reef fires timers and calls pi.sendUserMessage(msg, { deliverAs: "followUp" }). In RPC mode, this call silently does nothing useful.

Fix

Add RPC callback support to sendUserMessage() in AgentSession.

When PUNKIN_RPC_CALLBACK_URL env var is set, instead of calling this.prompt() directly, POST the message to {PUNKIN_RPC_CALLBACK_URL}/tasks:

{
  "prompt": "<the reminder message>",
  "source": "reminder",
  "agentName": "<from VERS_AGENT_NAME or PUNKIN_AGENT_NAME env, optional>"
}

This lets the RPC caller (reef) receive the callback and schedule a new task turn — which is the correct mechanism in RPC mode.

Key properties

  • Backward compatible: if PUNKIN_RPC_CALLBACK_URL is not set, sendUserMessage works exactly as before
  • Fire-and-forget: the POST is non-blocking; errors are logged to stderr but don't throw
  • Debuggable: logs a message to stdout when using the callback path
  • No new dependencies: uses the built-in fetch API

Usage

The companion reef PR sets PUNKIN_RPC_CALLBACK_URL when launching punkin agents in RPC mode, pointing to reef's /tasks endpoint. Reef's task handler then creates a new agent turn with the reminder message as the prompt.

Files changed

  • packages/coding-agent/src/core/agent-session.tssendUserMessage() method: check for PUNKIN_RPC_CALLBACK_URL and POST to it if set

- Add adaptive thinking mode (type: 'adaptive') for Opus 4.6+
- Add effort parameter ('low', 'medium', 'high', 'max') for adaptive thinking
- thinkingEnabled now auto-detects: adaptive for 4.6+, budget-based for older
- streamSimple/completeSimple map ThinkingLevel to effort levels for Opus 4.6
- Add tests for Opus 4.6 adaptive thinking and GPT-5.3 Codex
- Update @anthropic-ai/sdk to 0.73.0
- Update @aws-sdk/client-bedrock-runtime to 3.983.0
- Update @google/genai to 1.40.0
- Remove fast-xml-parser override (no longer needed)
- anthropic: claude-opus-4-5 → claude-opus-4-6
- openai-codex: gpt-5.2-codex → gpt-5.3-codex
- amazon-bedrock: us.anthropic.claude-opus-4-20250514-v1:0 → us.anthropic.claude-opus-4-6-v1:0
- vercel-ai-gateway: anthropic/claude-opus-4.5 → anthropic/claude-opus-4-6
- opencode: claude-opus-4-5 → claude-opus-4-6
…and add EU profile

- Remove :0 suffix from Opus 4.6 Bedrock model IDs (not valid for this model)
- Fix us/eu Opus 4.6 cache pricing (0.5/6.25 instead of 1.5/18.75)
- Add missing eu.anthropic.claude-opus-4-6-v1 inference profile
- Fix coding-agent default Bedrock model ID to match catalog
…tings extensions paths

collectAutoExtensionEntries now checks if the directory itself has a
package.json with pi.extensions (or index.ts) before scanning children.
This fixes duplicate extension loading when a manifest-aware directory
is specified directly in settings.json extensions array.

Fixes #1274
cartazio and others added 28 commits March 7, 2026 20:44
Added to all three auth paths (API key, OAuth, Copilot):
- Connection: close header to force server to close connection
- fetchOptions: { keepalive: false } to prevent client-side connection pooling

This should prevent connection reuse bugs that may cause empty responses.
Covers OpenRouter and all OpenAI-compatible providers.
…pection CLI

Bug fixes:
- max_tokens: read per-model limits from ~/.agent/settings.toml
  [modelMaxTokens.anthropic] instead of hardcoded model.maxTokens/3
  (~1.3K). Fallback: 128K for Opus 4.6, 64K for all others.
  max_tokens is a per-turn output cap, not context window.
- budget_tokens: only set when explicitly configured via
  thinkingBudgetTokens. Was silently defaulting to 1024 (minimum),
  starving the model of thinking capacity.
- Wire maxEmptyRetries/maxEmptyRetryTimeMs from AgentOptions through
  to AgentLoopConfig for empty response retry control.

New features:
- --dump-settings-template: print ~/.agent/settings_template.toml
- --promote-settings: print effective merged settings as TOML candidate
- SettingsManager.getResolvedSettings(): expose merged settings

Files: agent.ts, anthropic.ts, args.ts, settings-manager.ts, main.ts
* uses pre-exchanged-api key
* anthropic only atm
- basic text gen, tool calling, streaming (sonnet-4-6 + haiku-4-5)
- thinking with budget tokens (sonnet-4-6)
- model registry verification
- all 9 tests passing against tokens.vers.sh
When terminal is resized smaller than buildInfo width, the repeat()
call would receive a negative argument causing RangeError. Now properly
guards the condition and truncates when needed.
- Add alwaysHas1MContext() to detect opus-4-6, sonnet-4-6
- Update effectiveContextWindow() to return 1M unconditionally for 4.6 models
- Fixes context pressure showing 60% when actual usage is 25% of 1M
koffi is only used for Windows VT input, but the top-level import
causes module load failures on non-Node runtimes. Move to a dynamic
require inside enableWindowsVTInput() which already guards on
win32 and has a try/catch.
When punkin runs in --mode rpc (as a reef agent), the remind_me tool's
reminders never fire properly. The pi process is ephemeral — reef kills
it with SIGTERM on agent_end — so calling this.prompt() directly has no
effect after the process exits.

Fix: in sendUserMessage(), check for PUNKIN_RPC_CALLBACK_URL env var.
When set, POST the message to `{url}/tasks` instead of calling prompt().
The RPC caller (reef) receives the callback and schedules a new task turn.

The POST body is:
  { "prompt": "<message>", "source": "reminder", "agentName": "<optional>" }

agentName is read from VERS_AGENT_NAME or PUNKIN_AGENT_NAME env vars.

Backward compatibility is preserved — if PUNKIN_RPC_CALLBACK_URL is not
set, sendUserMessage() works exactly as before.

A companion reef PR passes the callback URL to punkin when launching
agents in RPC mode.
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.