Commit Graph

13 Commits

Author SHA1 Message Date
Ed Zynda 0b651a8df9 build(deps): update dependencies except fantasy
- bump bubbletea v2.0.6 -> v2.0.7, ultraviolet, acp-go-sdk v0.13.0 -> v0.13.5
- bump indirect deps x/exp, charmtone, go-runewidth
- hold fantasy at v0.25.0 (v0.29.1 requires go 1.26.4)
- add no-op Logout method to acpserver.Agent for new acp.Agent interface
2026-06-04 15:48:07 +03:00
Ed Zynda 34d5abff9c build(deps): update dependencies and implement new acp.Agent methods
- Bump fantasy v0.21.0 -> v0.23.0, mcp-go v0.49.0 -> v0.51.0,
  acp-go-sdk v0.12.0 -> v0.12.2, chroma v2.23.1 -> v2.24.1,
  fsnotify v1.9.0 -> v1.10.1, ultraviolet, AWS SDK, Google API
- Implement CloseSession and ResumeSession on acpserver.Agent to
  satisfy the expanded acp.Agent interface in acp-go-sdk v0.12.2
- Add sessionRegistry.remove helper to support session close
2026-05-04 16:23:12 +03:00
Ed Zynda 81240b075e chore: update all deps and fix acp-go-sdk v0.12.0 breaking changes
- Update all Go dependencies (bubbletea v2.0.6, fantasy v0.19.0,
  acp-go-sdk v0.12.0, mcp-go v0.49.0, and transitive deps)
- Replace SetSessionModel with SetSessionConfigOption to match new
  acp-go-sdk Agent interface (union type with ValueId/Boolean variants)
- Add ListSessions stub returning empty list (new required method)
- Refresh embedded_models.json from models.dev/api.json
- Update ACP smoke test: add initialize handshake, session/list,
  session/set_config_option, session/cancel, and fix update parsing
2026-04-22 11:55:40 +03:00
Ed Zynda b29d7d2166 refactor(acpserver): remove redundant thinking tag parsing
Remove dead code now that pkg/kit transparently handles <thinking> and
 tags at the agent layer. The ACP server no longer needs to:

- Track inThinkingTag state across chunks
- Parse and split reasoning/text from MessageUpdateEvent chunks
- Maintain tag format constants

MessageUpdateEvent now contains clean text, and ReasoningDeltaEvent
contains structured reasoning - no duplicate filtering needed.
2026-04-08 16:55:53 +03:00
Ed Zynda ef519ba517 feat(acpserver): implement session/set_model ACP method
Add SetSessionModel method to the ACP agent, allowing clients to change
the active LLM model for a session at runtime. The method looks up the
session in the registry and delegates to kit.SetModel().

Verified with smoke test: session/set_model now returns success instead
of 'Method not found' error.
2026-03-31 15:05:23 +03:00
Ed Zynda d79eb1f0fa refactor(pkg/kit): use fantasy type aliases for LLM types with clean SDK names
Replace concrete LLMMessage/LLMUsage/LLMResponse/LLMFilePart structs with
type aliases to charm.land/fantasy types, exposing them under clean
LLM-prefixed names. This gives SDK consumers full access to rich message
parts (tool calls, reasoning, tool results) without importing fantasy
directly.

Key changes:
- LLM types are now aliases: LLMMessage=fantasy.Message, etc.
- Added aliases for all part types: LLMTextPart, LLMToolCallPart, etc.
- Re-exported constructors: NewLLMUserMessage, NewLLMSystemMessage
- Removed lossy conversion helpers (llm_convert.go, fantasyMsgsToKit)
- Updated all internal packages to use aliases consistently
- Added ACP smoke test script and prompt template
- Fixed lint issues: unused vars, modernize min() usage
2026-03-31 14:26:49 +03:00
Ed Zynda 94d62a6ef0 Fix ACP thinking tag parsing to handle format
The Qwen model outputs thinking content wrapped in  tags
(not <thinking>). Updated parseThinkingTags to detect and handle
both formats:
- <thinking>...</thinking> (long format)
-   (short format)

Also removed the hasProperReasoningEvents logic that was preventing
thinking tag parsing from working correctly. Now both ReasoningDeltaEvent
(from models with proper reasoning APIs) and thinking tags in text
(from models like Qwen) are handled together, matching the TUI behavior.
2026-03-30 20:38:49 +03:00
Ed Zynda 91e6dfd2c8 Prevent double-sending of thinking content in ACP
Track whether a model sends proper ReasoningDeltaEvent events. If so,
skip parsing <thinking> tags from text to avoid sending reasoning content
twice (once as proper reasoning, once parsed from text).

Also reset the tracking state at the start of each new prompt turn.
2026-03-30 20:33:46 +03:00
Ed Zynda b6a0c4b44c Add thinking tag parsing for ACP
Parse <thinking>...</thinking> tags from models (Qwen, DeepSeek) that
wrap reasoning content in XML-style tags instead of using proper
reasoning events.

When text chunks contain thinking tags:
- Extract content between tags and send as reasoning/thought updates
- Send content outside tags as regular message text
- Track state across chunks to handle streaming properly

This mirrors the TUI's thinking tag parsing behavior.
2026-03-30 20:30:22 +03:00
Ed Zynda 8eb0fa855a Fix ACP file attachment support
- Implement proper handling for all ACP content block types:
  - ContentBlockText: extracts text content
  - ContentBlockImage: decodes base64 to LLMFilePart
  - ContentBlockAudio: decodes base64 to LLMFilePart
  - ContentBlockResource: handles text and binary embedded resources
  - ContentBlockResourceLink: reads files from disk

- Text files are now included inline in the message (not as FilePart)
  to avoid OpenAI API errors. Only binary files (images, audio, PDFs)
  are sent as FilePart attachments.

- Add fallback MIME types when not provided by client
- Add default prompt text when user attaches files without text
- Add comprehensive debug logging for content extraction
- Enable debug logging in ACP command when --debug flag is used
2026-03-30 20:28:14 +03:00
Ed Zynda c94edc929b feat: add rich tool metadata to SDK and extension events (Gaps 1-8)
Thread ToolCallID, ToolKind, ParsedArgs, FileDiff metadata, StopReason,
SessionID, and StructuredMessages across the SDK event bus, extension
wrapper, app bridge, hooks, and ACP server layers.

- Gap 1: ToolCallID from Fantasy's ToolCallContent threaded end-to-end
- Gap 2: ToolKind via static lookup (execute/edit/read/search/agent)
- Gap 3+4: FileDiffInfo with DiffBlocks via fantasy.ToolResponse.Metadata
- Gap 5: StopReason from Fantasy FinishReason on TurnEndEvent/TurnResult
- Gap 6: Subagent sessions now opt-out (NoSession); SessionID in JSON output
- Gap 7: GetStructuredMessages() returns typed ContentParts
- Gap 8: ParsedArgs map[string]any on tool events for convenience

Edit/write tools attach structured diff metadata. ACP server uses real
ToolCallIDs. Extension and SDK events kept in sync with matching fields.
2026-03-16 11:10:05 +03:00
Ed Zynda a05da5f3ab fix(auth): support OAuth credentials in ACP mode and auto-refresh tokens
Remove the early ValidateEnvironment gate from CreateProvider that only
checked env vars and --provider-api-key, blocking stored OAuth credentials
from working. Each provider creation function already handles its own auth
resolution with clear error messages.

Update ValidateEnvironment to also check stored Anthropic credentials so
the model selector UI correctly shows Anthropic models for OAuth users.

Add automatic token refresh in oauthTransport so long-lived ACP sessions
survive token renewals. Surface actionable auth error messages in ACP
session creation.

Fix pre-existing staticcheck SA5011 warnings in test files.
2026-03-15 12:38:23 +03:00
Ed Zynda e613a07773 feat: add ACP server mode (kit acp)
Implement Agent Client Protocol server allowing ACP-compatible clients
(e.g. OpenCode) to drive Kit as a remote coding agent over stdio.

- internal/acpserver/agent.go: acp.Agent implementation bridging Kit's
  LLM execution, tool system, and event bus to ACP session updates
- internal/acpserver/session.go: session registry mapping ACP sessions
  to persisted Kit JSONL tree sessions
- cmd/acp.go: cobra subcommand wiring stdio JSON-RPC connection
- Add acp-go-sdk dependency, update README with ACP docs
2026-03-09 21:41:10 +03:00