Skip to content

ADFA-6311 | Add AI-Agent-Claude, a Claude backend for AI Core - #116

Merged
davidschachterADFA merged 10 commits into
mainfrom
feature/ADFA-6311-ai-agent-claude
Oct 3, 2026
Merged

davidschachterADFA merged 10 commits into
mainfrom
feature/ADFA-6311-ai-agent-claude

Conversation

@davidschachterADFA

@davidschachterADFA davidschachterADFA commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

ADFA-6311

Adds plugins/AI-Agent-Claude: a claude backend for AI Core over Anthropic's Messages API, with streaming, history, native tool calling, Stop, and a settings pane (Keystore-encrypted key, model picker from /v1/models, connection test).

Review by commit

  1. 52101c4 — mechanical: AI-Agent-OpenAI copied and renamed (package, classes, resource prefixes, Keystore alias). Skim it.
  2. 8c0a443 — the change: Messages API transport and the trimmed settings pane. Diff it against commit 1 to see exactly what Claude needs.
  3. 4a37a15 — docs: README, Tier 3 guide, overview page, root README row, skip.txt.
  4. 665bb0e — icons from the Claude symbol (Wikimedia Commons, CC0; the mark is Anthropic's trademark).
  5. 4b3a48c — found on device: a key with no workspace gets a 400 on every request; the key check called that "Unknown" and blamed a missing AI Core. Now its own failure and verdict.
  6. 383fe1d — an optional Workspace ID field, shown only after Claude refuses a key for that reason; sent as anthropic-workspace-id, saved and cleared with the key. Typed IDs are validated so a pasted value cannot add a header.
  7. b4b2703 — every prompt for the ID says it starts with wrkspc_ and is listed in the Claude Console under Workspaces.
  8. da01fac — fixes from an independent review (below).
  9. 3463594 — the docs that review flagged.
  10. 0266fc3 — the gallery card (addon.json). The addon stays held in tools/addons/skip.txt, like AI-Code-Suggestions, until AI Core is in the gallery.

Review findings and how they were handled

Finding Handling
F06/F07 per-model fields Each model's output cap, adaptive thinking and effort now come from /v1/models, stored with the model list; allow-lists cover undescribed models. Agent turns ask for adaptive thinking where it's taken (on Opus 4.x / Sonnet 4.6 an omitted thinking meant none). Dated Opus 4 / Sonnet 4 ids no longer get effort or an over-cap budget.
F08 small jobs Titles and suggestions keep the caller's budget at low effort; only the 5.x models get a 4K floor.
F09 aliases An alias matches its dated id, so a live fetch no longer swaps claude-haiku-4-5 for Opus 5.5.
F10/F15 A fallback drops the declined model's tool calls; a call cut off by max_tokens is dropped.
F11/F12 Stop Stop closes the stream's socket at once and tracks every stream.
F13 Test Connection adopts the catalog of the key it tested.
F14 A silent stream is reported as Claude stopping, not a lost connection.
F16 tests TurnAssembler (pure) decides how a turn ends; it and the retry loop are tested.
F17/F18 Docs and comments corrected.
F19 Not changed: the copy commit registers as openai, which only matters when bisecting; pushed history left alone.
F20 Decided 2026-10-02: proceed treating use of the Claude name and symbol as permitted. Anthropic's Trademark Guidelines require prior written approval and their own unaltered asset, so confirm the permission is actually in hand before the gallery listing, and swap in the supplied asset if it comes with one.

Design choices

  • Raw HttpURLConnection, no Anthropic SDK. The host loads plugins parent-first, so a bundled OkHttp collides with the host's (same reason as the OpenAI backend).
  • History is text. AI Core hands tool results back as user text, never the tool_use they answer, so they are sent as text, not tool_result blocks. Same-role turns are merged; no thinking block is ever replayed.
  • No thinking, no temperature. Both are 400s on Claude Opus 5.5, the default model. max_tokens is raised to 64K for streams because thinking counts against it.
  • Per-model fields (ClaudeModelTraits): effort: "high" where accepted; server-side fallbacks: "default" on the models whose safety classifiers can decline a request.
  • stop_reason: "refusal" is reported before any tool call in that turn runs.
  • Retries: 429/529/5xx retried twice, only before a stream has shown anything.
  • No embeddings: Anthropic has none, so this is not an EmbeddingBackend; Vector-Search still needs OpenAI or Gemini.
  • Not strict tools, no eager input streaming: contributed MCP schemas rarely meet strict mode, and calls are acted on only once complete, so eager streaming buys nothing and loses server-side input validation.

Verification

  • 161 JVM tests pass; assemblePlugin builds. Mutation checks: removing turn merging, the Haiku effort gate, the credit-balance mapping, the workspace detection, the header-safety check, alias matching, the Opus 4 cap, the fallback discard, the max_tokens drop, adaptive thinking on agent turns, low effort on small jobs, or the stall classification each fails the tests named for it.
  • On device after the review fixes (build 3463594): the live catalog's capabilities are stored and match the fallback tables; a saved claude-haiku-4-5 survives Test Connection; chat plus title request accepted on Haiku 4.5, Opus 4.8 (adaptive thinking + high effort, title at low effort) and Opus 5.5; an Opus 5.5 agent edit ran read_file → edit_file → respond; Stop closed the stream's HTTPS socket within 2 s (checked in /proc/net/tcp6).
  • On device (Galaxy Note20 Ultra, Android 13, CoGo debug 2026-10-01, with AI Core from main), against the live API:
    • Install through CoGo's installer, upgrade via "Replace", restart; backend registers. Claude icon in the Plugin Manager, day and night.
    • Invalid key: real 401, "Claude refused this key", nothing saved.
    • Key without a workspace: refused with the workspace message, field appears; with the ID, key verified. Test Connection lists 12 models.
    • Chat on claude-opus-5-5: streamed reply, end_turn. Agent edit of MainActivity.kt via search_project → read_file → edit_file → respond; the comment is on disk.
    • Stop mid-stream: turn cancelled, no error, no late completion.
    • claude-haiku-4-5: accepted without effort/fallbacks, served by claude-haiku-4-5-20251001.
    • Empty credit balance: shown as the billing message.
    • Offline save: "Save anyway" stores the key unverified; re-saved verified once online.
    • Tooltips on the key, model, Get API Key and Test Connection: Claude wording, never "n/a".
    • Font scale 1.0 and 2.0: settings pane (view and edit mode, with the workspace field) wraps and scrolls; every control reachable. Only the field's sample hint is ellipsized.

🤖 Generated with Claude Code

davidschachterADFA and others added 9 commits October 1, 2026 19:09
Mechanical: plugins/AI-Agent-OpenAI copied verbatim, with the package,
class names, resource prefixes, plugin name and Keystore alias renamed
from openai to claude. No behaviour differs from the source plugin yet,
so the next commit's diff is exactly what Claude needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the copied chat/completions transport with POST /v1/messages:
x-api-key and anthropic-version headers, the Messages event stream,
tool_use blocks in and input_schema tools out.

- History stays text: tool results arrive as user text with no tool_use
  to pair with, so same-role turns are merged and SYSTEM turns fold into
  the top-level system prompt. No thinking block is ever replayed.
- No thinking or temperature sent (both 400 on Claude Opus 5.5);
  max_tokens raised to 64K for streams since thinking shares it.
- Per-model fields from ClaudeModelTraits: effort "high" where accepted,
  fallbacks "default" plus its beta on the models with classifiers.
- stop_reason "refusal" is reported before any tool call runs.
- 429/529/5xx retried twice, only before a stream delivers anything.
- Top-level cache_control caches the system prompt and tool list.
- Settings drop the base URL, presets, cleartext and origin rules and the
  embedding picker; the key is always required. No EmbeddingBackend:
  Anthropic has no embeddings API.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README, the Tier 3 in-app guide and the overview page rewritten for
Claude; warm-palette icons so the plugin is not mistaken for the OpenAI
one in the Plugin Manager. Listed in the root README and held out of the
gallery in skip.txt, like the other AI backends, until it has an
addon.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the recoloured node glyph with the Claude symbol, from
Wikimedia Commons File:Claude_AI_symbol.svg (CC0), rendered in #D97757
at 60% of the tile on a light (day) and navy (night) rounded square
cut from the house icon shape.

The file is CC0 for copyright only; the mark itself is Anthropic's
trademark.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found on device: a key that is not scoped to a workspace gets a 400 on
every request, asking for an anthropic-workspace-id header. The key
check filed that 400 as Unknown, so the pane said "make sure the AI
Core plugin is installed" and offered "Save anyway" for a key chat can
never use. In chat the API's explanation was longer than the 160-char
reason cap, so it read only "Claude rejected the request."

Now one failure (KeyNeedsWorkspace) and one verdict (NeedsWorkspace),
matched on the header name the API's message carries. The save path
refuses to store the key; Test Connection says how to replace it. It
is a credential failure, so a chat refusal is also reported on the
settings pane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A key created outside a workspace gets a 400 on every request until it
sends anthropic-workspace-id (seen on device with a freshly made key).
The plugin cannot list workspaces with a regular key, so the user
supplies the id:

- The pane shows a Workspace ID field once Claude refuses the key for
  this, or while an id is saved; a key in a workspace never sees it.
- The id is saved with the key in one commit, sent on chat and on the
  model listing, and cleared with the key.
- WorkspaceIds accepts one printable ASCII token only, so a pasted
  value with a line break can never add a header of its own; the
  headers are built in one pure, tested place (authHeaders).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every prompt for a workspace ID now says it starts with wrkspc_ and is
listed in the Claude Console under Workspaces: the field's hint, the
save and test messages, the chat error, the tooltip, the Tier 3 guide
and the README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
From the independent review of PR #116 (F06-F16):

- F06/F07: what a model accepts now comes from the live catalog
  (/v1/models: output cap, adaptive thinking, effort), stored with the
  model list; allow-lists cover models it has not described. Agent turns
  ask for adaptive thinking where it is taken, since on Opus 4.x and
  Sonnet 4.6 an omitted `thinking` means none. Dated Opus 4 / Sonnet 4
  ids no longer get effort, and max_tokens is held to the model's cap.
- F08: requests that are not streamed (chat titles, suggestions) keep
  the caller's budget at low effort, raised to 4K only on the 5.x
  models, which think regardless.
- F09: an alias matches its dated id (claude-haiku-4-5 vs
  claude-haiku-4-5-20251001), so a live fetch no longer retires it.
  Seen on device: the saved Haiku alias was swapped for Opus 5.5.
- F10/F15: a fallback drops the declined model's tool calls; a call
  cut off by max_tokens is dropped even when its empty input parses.
- F11/F12: Stop closes the stream's socket at once, and tracks every
  stream rather than one shared job.
- F13: Test Connection adopts the catalog of the key it tested.
- F14: a stream that goes silent is reported as Claude stopping, not
  as a lost connection.
- F16: TurnAssembler (pure) now decides how a turn ends, and the retry
  loop moved into TransientRetry; both are tested. 161 tests pass; each
  fix was mutation-checked against the test named for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
F17/F18: no "strongest model" claim (Fable 5.1 is more capable); the
README lists the statuses actually retried and describes the two kinds
of turn; the guide no longer says every model thinks or that a failure
was always retried; the manifest comment gives the real reason for
26.39 (AI Core's minimum).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davidschachterADFA

Copy link
Copy Markdown
Contributor Author

CI build passed for AI-Agent-Claude at 3463594: Build plugin artifacts, run 37076228947, dispatched with plugin=AI-Agent-Claude and codeonthego_ref=stage.

  • It rebuilt plugin-api from current CoGo stage instead of using the committed libs/ jars, and produced a release .cgp.
  • It does not run unit tests. The 161 JVM tests have only run locally (../../gradlew testDebugUnitTest).

🤖 Generated with Claude Code

Proceeding on the decision (2026-10-02) to treat use of the Claude name
and symbol as permitted; see the PR for Anthropic's guidelines and the
open sign-off. The card follows the other addons' cards, licence
included. The addon stays held in skip.txt with the same reason as
AI-Code-Suggestions: it needs AI Core, which is not in the gallery yet,
so the two must publish together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@davidschachterADFA
davidschachterADFA merged commit e722e64 into main Oct 3, 2026
1 check passed
@davidschachterADFA
davidschachterADFA deleted the feature/ADFA-6311-ai-agent-claude branch October 3, 2026 00:48
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.

2 participants