feat: Example Anthropic provider plugin + plugin-registered provider adapter - #30
Closed
TheArchitectit wants to merge 16 commits into
Closed
feat: Example Anthropic provider plugin + plugin-registered provider adapter#30TheArchitectit wants to merge 16 commits into
TheArchitectit wants to merge 16 commits into
Conversation
Implements the core plugin provider infrastructure: - Add ProviderRegistry singleton for named provider lookup - Wire plugin providers into chatCompletion and escalation flows - Support plugin manifest `providers` field in loader - Register openai_compat and ollama providers on startup Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implements a decorator-style provider that wraps any registered provider and injects custom content into system prompts. Supports prepend, append, and replace positions. Inner provider is lazily resolved from the ProviderRegistry at first chat() call. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds plugin init/shutdown lifecycle and hook events for LLM request interception: - `init` / `shutdown` manifest fields for startup/teardown handlers - `pre_request`, `post_request`, `on_error` hook events in chat path - `session_start`, `session_end` events (wired at session boundaries) - `runInit()`, `runShutdown()`, `runHooks()` methods on PluginLoader - Hook event validation with warning for unknown events Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds support for: - `permissions` manifest field (read/write/execute/network) - `mcpServers` manifest field for declaring bundled MCP servers - `capabilities` field on provider declarations (passed to registry) - getPermissions(), hasPermission(), getMCPServers() accessors - Default permissions: read-only, no write/execute/network Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PROVIDER_TOOLS was defined but not included in module.exports, causing TypeError: PROVIDER_TOOLS is not iterable in smallcode.js. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Add provider-wizard plugin: /provider command for interactive setup of LLM providers (LM Studio, Ollama, OpenRouter, OpenAI, Anthropic, DeepSeek, custom). Includes /provider status tool and configure tool with validation and discovery. - Add plugin install scopes (project/user/global) via --scope flag with per-scope add/remove commands - Fix plugin command dispatch: strip leading slash before lookup - Fix symlink handling in plugin loader: readdirSync with withFileTypes doesn't follow symlinks, so isDirectory() returns false for them Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves the provider wizard out of the plugin system (.smallcode/plugins/provider-wizard/) into bin/provider-wizard/ as a built-in feature. This makes the wizard always available without requiring plugin install, and gives the PR its own clear identity. Changes: - bin/provider-wizard/ - wizard, status, tool-configure, tool-status (moved from plugin) - bin/commands.js - /provider command wired directly (not via plugin dispatch) - bin/executor.js - configure_provider + provider_status tool cases added - bin/tools.js - PROVIDER_TOOLS schema array (configure_provider, provider_status) - bin/smallcode.js - ALL_TOOLS includes PROVIDER_TOOLS - .smallcode/plugins/provider-wizard/ - removed (no longer a plugin) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The model gate at startup was blocking all commands including /provider. Now /provider commands are dispatched before the model check so users can configure a provider even with no model set. Also changes the no-model path to always show the setup TUI instead of only when a plugin command was registered (provider is now built-in). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Only ollama and LM Studio are truly key-free. Custom endpoints often need an API key (e.g. vLLM with auth, proxied APIs). Changed custom provider keyEnv from null to 'SMALLCODE_API_KEY' so the wizard prompts for it. Also fixed validateApiKey to accept the actual base URL instead of always using the provider's defaultUrl (which is empty for custom). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The wizard previously only wrote to project .env, causing re-prompting when switching projects. Now writes to ~/.config/smallcode/.env which the startup loader already checks as a global fallback. Project .env still gets written too if it exists, so project-level overrides work. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The loader used `break` after finding the first .env, so if a project had its own .env, the global ~/.config/smallcode/.env was never loaded. This caused provider config to disappear when switching projects. Now loads all env files with project-level values taking priority. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The os module was never imported, causing 'os is not defined' fatal error when the wizard tried to write to ~/.config/smallcode/. This meant the global env file was never created and provider config couldn't persist across projects. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The /provider wizard stores the API key as SMALLCODE_API_KEY but the HTTP auth code only checked OPENAI_API_KEY, ANTHROPIC_API_KEY, and DEEPSEEK_API_KEY — so custom endpoint keys were never sent, causing 401 Unauthorized on every request. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The /provider command was only dispatched when no model was set. This adds a handler before the positional prompt branch so users can reconfigure their provider even after one is already set. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
End-to-end demonstration plugin implementing all 7 features: - adapter.js: IModelProvider for Anthropic Messages API (tools, vision) - init.js: API key validation on startup - cleanup.js: shutdown hook - pre-request.js / post-request.js / on-error.js: lifecycle hooks - plugin.json: full manifest with permissions, providers, capabilities Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is PR 3 of 3 in a stacked PR chain implementing the plugin-provider architecture for SmallCode.
This PR adds an example Anthropic provider plugin that demonstrates the full plugin-provider lifecycle, plus a generic adapter for plugin-registered providers.
Changes
Anthropic provider plugin (
.smallcode/plugins/anthropic-provider/)plugin.json— manifest with tools, hooks, permissions, and provider declarationsadapter.js—AnthropicProviderAdapterwraps the Anthropic API with SmallCode'sIModelProviderinterfacepre-request.js— transforms SmallCode chat format to Anthropic API format (converts tool definitions, adds system messages)post-request.js— normalizes Anthropic responses back to SmallCode formaton-error.js— handles Anthropic-specific errors (rate limits, auth failures)init.js— plugin initializationcleanup.js— plugin cleanupProvider adapter (
src/compiled/providers/openai_compat.ts)PluginProviderAdapterthat wraps plugin-registered providersHow it works
providersin its manifestPluginLoader.loadAll()callsproviderRegistry.register()for each declared providerresolveProvider()inindex.tschecks the registry before falling back to OpenAI-compatWhy this PR exists
The Anthropic provider plugin serves as:
Plugin structure
Stacked with:
🤖 Generated with Claude Code