Commit Graph
1280 Commits
Author SHA1 Message Date
Mario Zechner 283f02cd97 Add reference to #330 (Dynamic Context Pruning) in plan
Documents why context event was added and notes the type
inconsistency between ContextEvent (AgentMessage[]) and
ContextEventResult (Message[])
2025-12-30 22:42:22 +01:00
Mario Zechner 8a573b514d Add investigation item for context event vs before_agent_start
Reference: #324

Documents:
- Current context event behavior (AgentMessage[], transient)
- Proposed before_agent_start event (persistent, TUI visible)
- Key differences table
- Open design questions
- Need to verify AgentMessage vs Message abstraction level
2025-12-30 22:42:22 +01:00
Mario Zechner 4ab5610d89 Mark Hook API Changes as complete in plan 2025-12-30 22:42:21 +01:00
Mario Zechner 482dae1643 Add BranchSummaryMessageComponent, unify styling with hook messages
- CompactionSummaryMessageComponent now extends Box, uses customMessageBg
- New BranchSummaryMessageComponent for branch summaries
- Both use same background color as HookMessageComponent for consistency
- Added Spacer before compaction/branch components in chat
2025-12-30 22:42:21 +01:00
Mario Zechner f5f9dab09d Use exhaustive switch on message.role throughout coding-agent
- addMessageToChat: exhaustive switch for all AgentMessage roles
- renderSessionContext: delegates to addMessageToChat, special handling for assistant tool calls and tool results
- export-html formatMessage: exhaustive switch for all AgentMessage roles
- Removed isHookMessage, isBashExecutionMessage type guards in favor of role checks
- Fixed imports and removed unused getLatestCompactionEntry
2025-12-30 22:42:21 +01:00
Mario Zechner 9ccd8ddf47 Fix hook message duplication in TUI
Two bugs:
1. createCustomMessage was returning role: 'user' instead of preserving
   the hook message structure (role: 'hookMessage', customType, etc.)
2. rebuildChatFromMessages wasn't clearing the container before rebuilding
2025-12-30 22:42:21 +01:00
Mario Zechner 0e5c0fd745 Clean-up 2025-12-30 22:42:21 +01:00
Mario Zechner 74daac9f27 Update Changelog and Releasing sections in AGENTS.md 2025-12-30 22:42:21 +01:00
Mario Zechner 643cbf8062 Simplify Publishing section in README.md 2025-12-30 22:42:21 +01:00
Mario Zechner a79fabb324 Remove proxy package
The proxy functionality is now handled by web-ui's createStreamFn
with external proxy servers.
2025-12-30 22:42:21 +01:00
Mario Zechner ee8dd7f182 Add release script
Usage: npm run release:patch|minor|major

Automates:
- Check for uncommitted changes
- Bump version
- Update CHANGELOGs: [Unreleased] -> [version] - date
- Commit and tag
- Publish to npm
- Add new [Unreleased] sections
- Push
2025-12-30 22:42:21 +01:00
Mario Zechner 4cccafc7d6 Use queueMessage for notifications in example 2025-12-30 22:42:21 +01:00
Mario Zechner 73a75485e4 Add CHANGELOG.md for web-ui package 2025-12-30 22:42:21 +01:00
Mario Zechner cbc96f7374 AgentInterface sets default streamFn and getApiKey
- Make Agent.streamFn and Agent.getApiKey public
- AgentInterface sets defaults if not already set
- Example no longer needs to configure these
2025-12-30 22:42:21 +01:00
Mario Zechner 30b45d28b3 Allow async streamFn for dynamic proxy settings
- StreamFn type now allows returning Promise
- agent-loop awaits streamFn result
- createStreamFn takes getProxyUrl callback, reads settings on each call
2025-12-30 22:42:21 +01:00
Mario Zechner a340916bd6 Add createStreamFn for CORS proxy support
- createStreamFn(proxyUrl?) returns a sync streamFn that applies proxy
- Example reads proxy settings once when creating Agent
- Matches old ProviderTransport behavior
2025-12-30 22:42:21 +01:00
Mario Zechner d43e63b8fd Set isStreaming=false on agent_end event, before emitting to listeners
Was only setting in finally block, after event was emitted.
2025-12-30 22:42:21 +01:00
Mario Zechner e9ac16142d Clear streaming container on agent_end 2025-12-30 22:42:21 +01:00
Mario Zechner 16374b6e61 Fix AgentInterface to requestUpdate on all message lifecycle events
Was only handling message_update, now also handles message_start,
message_end, turn_start, turn_end, agent_start, agent_end.
2025-12-30 22:42:21 +01:00
Mario Zechner d731bb59ef Add getApiKey to web-ui example Agent config
Provides API keys from the provider keys store, matching old ProviderTransport behavior.
2025-12-30 22:42:21 +01:00
Mario Zechner 6a529da099 Use dynamic import for http module in OAuth files
Prevents browser bundles from failing on import.
The http module is only loaded when login functions are actually called.
2025-12-30 22:42:21 +01:00
Mario Zechner 9495f69ae7 Fix Buffer usage in github-copilot.ts - use atob() 2025-12-30 22:42:21 +01:00
Mario Zechner a2e800c4a5 Use Web Crypto API for OAuth PKCE, remove Node.js crypto dependency
- Add pkce.ts with generatePKCE() using Web Crypto API
- Update anthropic.ts, google-gemini-cli.ts, google-antigravity.ts
- Replace Buffer.from() with atob() for base64 decoding
- Works in both Node.js 20+ and browsers

The OAuth modules still use Node.js http.createServer for callbacks,
so they only work in CLI environments, but they no longer crash on
import in browser bundles.
2025-12-30 22:42:21 +01:00
Mario Zechner 98a4f7bb46 Rename customMessageTransformer to customConvertToLlm 2025-12-30 22:42:20 +01:00
Mario Zechner d03e0d72a3 Add defaultConvertToLlm to web-ui, simplify example
- web-ui exports: defaultConvertToLlm, convertAttachments, isUserMessageWithAttachments, isArtifactMessage
- defaultConvertToLlm handles UserMessageWithAttachments and filters ArtifactMessage
- Example's customMessageTransformer now extends defaultConvertToLlm
- Removes duplicated attachment conversion logic from example
2025-12-30 22:42:20 +01:00
Mario Zechner 101e91ebf0 Fix web-ui and example for new agent API
- AgentInterface composes UserMessageWithAttachments for attachments
- Updated example to use convertToLlm instead of transport/messageTransformer
- Fixed declaration merging: target pi-agent-core, add path to example tsconfig
- Fixed typo in CustomAgentMessages key (user-with-attachment -> user-with-attachments)
- customMessageTransformer properly converts UserMessageWithAttachments to content blocks
2025-12-30 22:42:20 +01:00
Mario Zechner e8947026a8 WIP: Major cleanup - move Attachment to consumers, simplify agent API
- Removed Attachment from agent package (now in web-ui/coding-agent)
- Agent.prompt now takes (text, images?: ImageContent[])
- Removed transports from web-ui (duplicate of agent package)
- Updated coding-agent to use local message types
- Updated mom package for new agent API

Remaining: Fix AgentInterface.ts to compose UserMessageWithAttachments
2025-12-30 22:42:20 +01:00
Mario Zechner 0fc7a56502 Expand README with AgentMessage/LLM conversion, event semantics, partial messages
- Explain AgentMessage vs LLM Message separation and why it's needed
- Document conversion flow: AgentMessage -> transformContext -> convertToLlm -> LLM
- Clarify that prompt/queueMessage/continue must convert to user or toolResult
- Document message_start/end events for prompt() and queued messages
- Explain message_update is assistant-only with partial content
- Add pattern for handling partial messages in reactive UIs
- Document agent.state.streamMessage for accessing current partial
2025-12-30 22:42:20 +01:00
Mario Zechner b781a24740 Fix README: prompt takes ImageContent[], not Attachment[] 2025-12-30 22:42:20 +01:00
Mario Zechner 1d43c9d751 Add CHANGELOG.md to agent package with refactor details 2025-12-30 22:42:20 +01:00
Mario Zechner f7f648eacc Add CHANGELOG entry for agent API move to pi-agent-core 2025-12-30 22:42:20 +01:00
Mario Zechner 0ac8e459fe Update READMEs: remove agent section from pi-ai, rewrite pi-agent-core
- Removed Agent API section from pi-ai README (moved to agent package)
- Rewrote agent package README for new architecture:
  - No more transports (ProviderTransport, AppTransport removed)
  - Uses streamFn directly with streamProxy for proxy usage
  - Documents convertToLlm and transformContext
  - Documents low-level agentLoop/agentLoopContinue API
  - Updated custom message types documentation
2025-12-30 22:42:20 +01:00
Mario Zechner 6be6cad52c WIP: Refactor agent package - not compiling
- Renamed AppMessage to AgentMessage throughout
- New agent-loop.ts with AgentLoopContext, AgentLoopConfig
- Removed transport abstraction, Agent now takes streamFn directly
- Extracted streamProxy to proxy.ts utility
- Removed agent-loop from pi-ai (now in agent package)
- Updated consumers (coding-agent, mom) for AgentMessage rename
- Tests updated but some consumers still need migration

Known issues:
- AgentTool, AgentToolResult not exported from pi-ai
- Attachment not exported from pi-agent-core
- ProviderTransport removed but still referenced
- messageTransformer -> convertToLlm migration incomplete
- CustomMessages declaration merging not working properly
2025-12-30 22:42:20 +01:00
Mario Zechner a554b86a16 Fix: transform userMessage in _runAgentLoop before passing to transport
HookMessage (role: hookMessage) was being passed directly to transport
without transformation. Now it's transformed via messageTransformer
which converts it to a proper user message for the LLM.
2025-12-30 22:42:20 +01:00
Mario Zechner 49d23abead Fix import path in hook-message.ts 2025-12-30 22:42:20 +01:00
Mario Zechner e89a30b28a Fix messageTransformer to normalize HookMessage string content to array
HookMessage.content can be string or array, but LLM Message.content
must be an array. This was causing 'messages: at least one message
is required' errors when hooks sent string content.
2025-12-30 22:42:20 +01:00
Mario Zechner 6a877bb501 Cleanup: unify HookMessage naming and simplify SessionContext
- Rename HookAppMessage to HookMessage, isHookAppMessage to isHookMessage
- Remove entries array from SessionContext (use isHookMessage type guard instead)
- HookMessage.content now accepts string directly (not just array)
- Fix streamMessage type in AgentState (AppMessage, not Message)
- Rename CustomMessageComponent to HookMessageComponent
- Fix test hook to use pi.sendMessage
2025-12-30 22:42:20 +01:00
Mario Zechner b4806b3b90 Wire context event to preprocessor for per-LLM-call execution
- Change from contextTransform (runs once at agent start) to preprocessor
- preprocessor runs before EACH LLM call inside the agent loop
- ContextEvent now uses Message[] (pi-ai format) instead of AppMessage[]
- Deep copy handled by pi-ai preprocessor, not Agent

This enables:
- Pruning rules applied on every turn (not just agent start)
- /prune during long agent loop takes effect immediately
- Compaction can use same transforms (future work)
2025-12-30 22:42:20 +01:00
Mario Zechner 2e435b7343 Add context event for non-destructive message modification before LLM calls
- Add contextTransform option to Agent (runs before messageTransformer)
- Deep copy messages before passing to contextTransform (modifications are ephemeral)
- Add ContextEvent and ContextEventResult types
- Add emitContext() to HookRunner (chains multiple handlers)
- Wire up in sdk.ts when creating Agent with hooks

Enables dynamic context pruning: hooks can modify messages sent to LLM
without changing session data. See discussion #330.
2025-12-30 22:42:20 +01:00
Mario Zechner 0eaba6e91d Add context event TODO with dynamic context pruning example
Reference: https://github.com/badlogic/pi-mono/discussions/330
2025-12-30 22:42:20 +01:00
Mario Zechner 5a4a85a927 Fix snake border alignment using visibleWidth for proper ANSI length calculation 2025-12-30 22:42:20 +01:00
Mario Zechner 7a6b70c99c Snake: add full border frame and pause/resume with session persistence
- Full box border around title, game area, and instructions
- ESC pauses and saves state to session via pi.appendEntry()
- Resume shows 'PAUSED - press any key to continue'
- Q quits and clears saved state
- High score persists across games
2025-12-30 22:42:20 +01:00
Mario Zechner c65ca451fb Fix snake velocity: render cells as 2 chars wide for square aspect
Terminal cells are ~2:1 aspect ratio, so movement appeared faster
vertically. Now each game cell is 2 characters wide.
2025-12-30 22:42:19 +01:00
Mario Zechner ab95f049ab Improve snake game visuals
- Rounded box corners (╭╮╰╯)
- Better characters: ● head, ○ body, ◆ food, · empty
- Colored title with emoji
- Dimmed borders and help text
- Bold highlights for score and controls
2025-12-30 22:42:19 +01:00
Mario Zechner fd044441ff Add immediate flag to hook commands for non-queued execution
Commands with immediate: true run right away even during streaming.
Used for UI-only commands like /snake that don't interact with LLM.
2025-12-30 22:42:19 +01:00
Mario Zechner 2bc6459827 Fix snake.ts: use key helpers from pi-tui for ESC and arrow keys 2025-12-30 22:42:19 +01:00
Mario Zechner 0a55cd295a Add ui.custom() for custom hook components with keyboard focus
- Add custom() to HookUIContext: returns { close, requestRender }
- Component receives keyboard input via handleInput()
- CustomMessageComponent default rendering now limits to 5 lines when collapsed
- Add snake.ts example hook with /snake command
2025-12-30 22:42:19 +01:00
Mario Zechner 63e0c0f6ca Refactor: shared exec utility, rename CustomMessageRenderer to HookMessageRenderer
- Extract execCommand to src/core/exec.ts, shared by hooks and custom-tools
- Rename CustomMessageRenderer -> HookMessageRenderer
- Rename registerCustomMessageRenderer -> registerMessageRenderer
- Renderer now receives HookMessage instead of CustomMessageEntry
- CustomMessageComponent now has setExpanded() and responds to Ctrl+E toggle
- Re-export ExecOptions/ExecResult from exec.ts for backward compatibility
2025-12-30 22:42:19 +01:00
Mario Zechner 4bc010f052 Fix tests for sessionManager/modelRegistry on context
- compaction-hooks-example.test.ts: get sessionManager/modelRegistry from ctx
- compaction-hooks.test.ts:
  - Pass sessionManager/modelRegistry to HookRunner constructor
  - Remove setSessionFile call
  - Update tests to use session.sessionManager instead of event.sessionManager
2025-12-30 22:42:19 +01:00
Mario Zechner d1ecb8aee3 Move exec to HookAPI, sessionManager/modelRegistry to HookEventContext
Breaking changes:
- HookEventContext now has sessionManager and modelRegistry (moved from SessionEventBase)
- HookAPI now has exec() method (moved from HookEventContext/HookCommandContext)
- HookRunner constructor takes sessionManager and modelRegistry as required params
- Session events no longer include sessionManager/modelRegistry fields

Hook code migration:
- event.sessionManager -> ctx.sessionManager
- event.modelRegistry -> ctx.modelRegistry
- ctx.exec() -> pi.exec()

Updated:
- src/core/hooks/types.ts - type changes
- src/core/hooks/runner.ts - constructor, createContext
- src/core/hooks/loader.ts - add exec to HookAPI
- src/core/sdk.ts - pass sessionManager/modelRegistry to HookRunner
- src/core/agent-session.ts - remove sessionManager/modelRegistry from events
- src/modes/* - remove setSessionFile calls, update events
- examples/hooks/* - update to new API
2025-12-30 22:42:19 +01:00