{"_id":"@302ai/studio-plugin-sdk","_rev":"2-ef10fffe02cffb837e9c7b246a08c166","name":"@302ai/studio-plugin-sdk","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@302ai/studio-plugin-sdk","version":"1.0.0","keywords":["302ai","plugin","sdk","ai","chat","provider","extension"],"author":{"name":"302.AI"},"license":"MIT","_id":"@302ai/studio-plugin-sdk@1.0.0","maintainers":[{"name":"mthezi","email":"mthezi@163.com"}],"homepage":"https://github.com/302ai/302-AI-Studio-SV/tree/main/packages/plugin-sdk","bugs":{"url":"https://github.com/302ai/302-AI-Studio-SV/issues"},"dist":{"shasum":"23f6fe9783a667765d76abbf4fa238a739d4152a","tarball":"https://registry.npmjs.org/@302ai/studio-plugin-sdk/-/studio-plugin-sdk-1.0.0.tgz","fileCount":5,"integrity":"sha512-ZGYGHtqOA6M7v6FMqfjodDV1VqmHGN1nvt2XEk+YQ6U5CIH0hO8EOTeKsO5iGj+pXgk0kwpDRCvhVhepfTKLnw==","signatures":[{"sig":"MEUCICc+tH7f9wHbsrsjPBnegyeHtwnswU7eRF/DTz9agt6jAiEA7fagKj2rkP1LM1E1n4WfFRydC4aEPS5V4xoImj5EHpI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57391},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"bbe24a00e46cbeca23b1e400b4ab69e52d9a72e9","scripts":{"dev":"tsup --watch","build":"tsup","clean":"rm -rf dist"},"_npmUser":{"name":"mthezi","email":"mthezi@163.com"},"repository":{"url":"git+https://github.com/302ai/302-AI-Studio-SV.git","type":"git","directory":"packages/plugin-sdk"},"_npmVersion":"11.5.1","description":"Plugin SDK for 302.AI Studio - Build plugins for AI chat application","directories":{},"_nodeVersion":"24.5.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"peerDependencies":{"ai":">=5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/studio-plugin-sdk_1.0.0_1761621668976_0.4584480120551866","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-10-28T03:21:08.827Z","modified":"2026-02-10T11:40:11.603Z","1.0.0":"2025-10-28T03:21:09.181Z"},"bugs":{"url":"https://github.com/302ai/302-AI-Studio-SV/issues"},"author":{"name":"302.AI"},"license":"MIT","homepage":"https://github.com/302ai/302-AI-Studio-SV/tree/main/packages/plugin-sdk","keywords":["302ai","plugin","sdk","ai","chat","provider","extension"],"repository":{"url":"git+https://github.com/302ai/302-AI-Studio-SV.git","type":"git","directory":"packages/plugin-sdk"},"description":"Plugin SDK for 302.AI Studio - Build plugins for AI chat application","maintainers":[{"email":"ji4jun0097@gmail.com","name":"trashcodermaker"}],"readme":"# @302ai/studio-plugin-sdk\n\nPlugin SDK for 302.AI Studio - Build powerful AI provider plugins with ease.\n\n[![npm version](https://badge.fury.io/js/@302ai%2Fstudio-plugin-sdk.svg)](https://www.npmjs.com/package/@302ai/studio-plugin-sdk)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Overview\n\nThe 302.AI Studio Plugin SDK allows developers to create custom AI provider plugins that integrate seamlessly with the 302.AI Studio desktop application. Build plugins to add support for new AI providers, customize message processing, or extend functionality with hooks.\n\n## Features\n\n- 🎯 **Type-Safe API** - Full TypeScript support with comprehensive type definitions\n- 🧩 **BaseProviderPlugin** - Abstract base class with common utilities\n- 🪝 **Hook System** - Intercept and modify messages, responses, and errors\n- 💾 **Storage API** - Persist plugin configuration and data\n- 🌐 **HTTP Client** - Built-in authenticated HTTP requests\n- 🎨 **UI Integration** - Show notifications, dialogs, and custom components\n- 📝 **Logging** - Structured logging with plugin context\n- 🌍 **i18n Support** - Built-in internationalization capabilities\n\n## Installation\n\n```bash\n# Using npm\nnpm install @302ai/studio-plugin-sdk\n\n# Using pnpm\npnpm add @302ai/studio-plugin-sdk\n\n# Using yarn\nyarn add @302ai/studio-plugin-sdk\n```\n\n## Quick Start\n\n### Creating a Basic Provider Plugin\n\n```typescript\nimport { BaseProviderPlugin, type Model, type ModelProvider } from \"@302ai/studio-plugin-sdk\";\n\nexport class MyProviderPlugin extends BaseProviderPlugin {\n\tprotected providerId = \"my-provider\";\n\tprotected providerName = \"My AI Provider\";\n\tprotected apiType = \"openai\";\n\tprotected defaultBaseUrl = \"https://api.example.com/v1\";\n\n\tprotected websites = {\n\t\tofficial: \"https://example.com\",\n\t\tapiKey: \"https://example.com/api-keys\",\n\t\tdocs: \"https://docs.example.com\",\n\t\tmodels: \"https://docs.example.com/models\",\n\t};\n\n\tasync onFetchModels(provider: ModelProvider): Promise<Model[]> {\n\t\tconst url = this.buildApiUrl(provider, \"models\");\n\t\tconst response = await this.httpRequest<{ data: any[] }>(url, {\n\t\t\tmethod: \"GET\",\n\t\t\tprovider,\n\t\t});\n\n\t\treturn response.data.map((model) => ({\n\t\t\tid: model.id,\n\t\t\tname: model.name,\n\t\t\tremark: `${this.providerName} ${model.id}`,\n\t\t\tproviderId: this.providerId,\n\t\t\tcapabilities: this.parseModelCapabilities(model.id),\n\t\t\ttype: \"language\",\n\t\t\tcustom: false,\n\t\t\tenabled: true,\n\t\t\tcollected: false,\n\t\t}));\n\t}\n}\n\nexport default MyProviderPlugin;\n```\n\n### Plugin Configuration\n\nCreate a `plugin.json` file in your plugin directory:\n\n```json\n{\n\t\"id\": \"com.example.my-provider\",\n\t\"name\": \"My AI Provider\",\n\t\"version\": \"1.0.0\",\n\t\"type\": \"provider\",\n\t\"description\": \"Integration with My AI Provider API\",\n\t\"author\": \"Your Name\",\n\t\"permissions\": [\"network\", \"storage\"],\n\t\"compatibleVersion\": \">=1.0.0\",\n\t\"main\": \"main/index.js\",\n\t\"builtin\": false,\n\t\"configSchema\": {\n\t\t\"type\": \"object\",\n\t\t\"properties\": {\n\t\t\t\"apiKey\": {\n\t\t\t\t\"type\": \"string\",\n\t\t\t\t\"title\": \"API Key\",\n\t\t\t\t\"description\": \"Your API key for authentication\"\n\t\t\t}\n\t\t},\n\t\t\"required\": [\"apiKey\"]\n\t}\n}\n```\n\n## Core Concepts\n\n### BaseProviderPlugin\n\nThe `BaseProviderPlugin` abstract class provides:\n\n- **Authentication** - Default API key validation\n- **HTTP Utilities** - Authenticated requests with proper headers\n- **Model Parsing** - Capability and type detection\n- **Error Handling** - Common error scenarios (401, 429, timeout)\n- **Logging & Notifications** - Built-in logging and user notifications\n\n**Required Methods:**\n\n- `onFetchModels(provider: ModelProvider): Promise<Model[]>` - Fetch available models\n\n**Optional Overrides:**\n\n- `getIconUrl()` - Custom provider icon\n- `getConfigSchema()` - Custom configuration schema\n- `testConnection(provider)` - Connection validation\n- `getAuthHeaders(provider)` - Custom authentication headers\n\n### Hook System\n\nPlugins can implement hooks to customize behavior:\n\n#### onBeforeSendMessage\n\nModify messages before sending to the AI:\n\n```typescript\nasync onBeforeSendMessage(context: MessageContext): Promise<MessageContext> {\n  // Add system prompt\n  context.messages.unshift({\n    role: \"system\",\n    content: \"You are a helpful assistant.\",\n  });\n  return context;\n}\n```\n\n#### onAfterSendMessage\n\nProcess responses after receiving:\n\n```typescript\nasync onAfterSendMessage(context: MessageContext, response: AIResponse): Promise<void> {\n  this.log(\"info\", `Used ${response.usage?.totalTokens} tokens`);\n}\n```\n\n#### onStreamChunk\n\nModify streaming response chunks:\n\n```typescript\nasync onStreamChunk(chunk: StreamChunk): Promise<StreamChunk> {\n  if (chunk.type === \"text\" && chunk.text) {\n    chunk.text = chunk.text.toUpperCase(); // Example modification\n  }\n  return chunk;\n}\n```\n\n#### onError\n\nHandle errors with retry logic:\n\n```typescript\nasync onError(context: ErrorContext): Promise<ErrorHandleResult> {\n  if (context.error.message.includes(\"429\")) {\n    return {\n      handled: true,\n      retry: true,\n      retryDelay: 5000,\n      message: \"Rate limit exceeded. Retrying in 5 seconds...\",\n    };\n  }\n  return { handled: false };\n}\n```\n\n### Plugin API\n\nThe `PluginAPI` is injected during initialization:\n\n#### Storage\n\n```typescript\n// Configuration (visible in UI)\nawait this.api.storage.setConfig(\"apiKey\", \"sk-...\");\nconst apiKey = await this.api.storage.getConfig<string>(\"apiKey\");\n\n// Private data (not visible in UI)\nawait this.api.storage.setData(\"cache\", { timestamp: Date.now() });\nconst cache = await this.api.storage.getData(\"cache\");\n```\n\n#### HTTP Client\n\n```typescript\n// GET request\nconst models = await this.api.http.get<ModelList>(\"https://api.example.com/models\");\n\n// POST request with body\nconst result = await this.api.http.post(\"https://api.example.com/chat\", {\n  messages: [...],\n});\n```\n\n#### UI Integration\n\n```typescript\n// Show notification\nthis.api.ui.showNotification(\"Model loaded successfully\", \"success\");\n\n// Show dialog\nconst result = await this.api.ui.showDialog({\n\ttitle: \"Confirm Action\",\n\tmessage: \"Are you sure?\",\n\ttype: \"question\",\n\tbuttons: [\"Yes\", \"No\"],\n});\n```\n\n#### Logging\n\n```typescript\nthis.api.logger.debug(\"Debug information\");\nthis.api.logger.info(\"Informational message\");\nthis.api.logger.warn(\"Warning message\");\nthis.api.logger.error(\"Error message\");\n```\n\n## Advanced Usage\n\n### Custom Authentication\n\nOverride `getAuthHeaders` for custom auth:\n\n```typescript\nprotected getAuthHeaders(provider: ModelProvider): Record<string, string> {\n  return {\n    \"X-API-Key\": provider.apiKey,\n    \"X-Custom-Header\": \"value\",\n  };\n}\n```\n\n### Capability Detection\n\nCustomize model capability parsing:\n\n```typescript\nprotected parseModelCapabilities(modelId: string): Set<string> {\n  const capabilities = new Set<string>();\n\n  if (modelId.includes(\"vision\")) {\n    capabilities.add(\"vision\");\n  }\n\n  if (modelId.includes(\"function\")) {\n    capabilities.add(\"function_call\");\n  }\n\n  return capabilities;\n}\n```\n\n### Direct ProviderPlugin Implementation\n\nFor full control, implement `ProviderPlugin` directly:\n\n```typescript\nimport type { ProviderPlugin, PluginAPI } from \"@302ai/studio-plugin-sdk\";\n\nexport class CustomPlugin implements ProviderPlugin {\n\tapi?: PluginAPI;\n\n\tasync initialize(api: PluginAPI): Promise<void> {\n\t\tthis.api = api;\n\t}\n\n\tgetProviderDefinition() {\n\t\treturn {\n\t\t\tid: \"custom\",\n\t\t\tname: \"Custom Provider\",\n\t\t\t// ... other properties\n\t\t};\n\t}\n\n\tasync onAuthenticate(context) {\n\t\t// Custom auth logic\n\t}\n\n\tasync onFetchModels(provider) {\n\t\t// Custom model fetching\n\t}\n}\n```\n\n## Type Reference\n\n### Core Types\n\n- `Model` - AI model definition\n- `ModelProvider` - Provider configuration\n- `ChatMessage` - Chat message structure\n- `PluginMetadata` - Plugin metadata from plugin.json\n\n### Hook Types\n\n- `MessageContext` - Message hook context\n- `StreamChunk` - Streaming response chunk\n- `AIResponse` - Complete AI response\n- `ErrorContext` - Error hook context\n- `AuthContext` - Authentication hook context\n\n### API Types\n\n- `PluginAPI` - Main plugin API\n- `PluginStorageAPI` - Storage operations\n- `PluginHttpAPI` - HTTP client\n- `PluginUIAPI` - UI operations\n- `PluginLoggerAPI` - Logging utilities\n\n## Examples\n\nCheck the `plugins/builtin/` directory in the main repository for complete examples:\n\n- **OpenAI Plugin** - Standard OpenAI API integration\n- **Anthropic Plugin** - Claude models with custom headers\n- **Google Plugin** - Gemini models with custom parsing\n- **Debug Plugin** - Full hook implementation example\n\n## Publishing Your Plugin\n\n### Package Structure\n\n```\nmy-plugin/\n├── plugin.json          # Plugin metadata\n├── main/\n│   └── index.ts        # Main plugin code\n├── package.json        # npm package config\n└── README.md           # Plugin documentation\n```\n\n### Build Script\n\n```json\n{\n\t\"scripts\": {\n\t\t\"build\": \"tsc && cp plugin.json dist/\"\n\t}\n}\n```\n\n### Publishing to npm\n\n```bash\nnpm publish --access public\n```\n\nUsers can then install your plugin via URL in 302.AI Studio.\n\n## Development Tips\n\n1. **Use TypeScript** - Full type safety and autocomplete\n2. **Test Thoroughly** - Test authentication, model fetching, and message sending\n3. **Handle Errors** - Implement proper error handling and retry logic\n4. **Log Appropriately** - Use appropriate log levels for debugging\n5. **Document Config** - Provide clear configuration schema and defaults\n6. **Version Compatibility** - Specify compatible app versions in plugin.json\n\n## API Compatibility\n\nThis SDK follows semantic versioning. The API is stable for v1.x releases.\n\n## License\n\nMIT License - see LICENSE file for details\n\n## Support\n\n- 📖 [Documentation](https://github.com/302ai/302-AI-Studio-SV)\n- 🐛 [Issue Tracker](https://github.com/302ai/302-AI-Studio-SV/issues)\n- 💬 [Discussions](https://github.com/302ai/302-AI-Studio-SV/discussions)\n\n## Contributing\n\nContributions are welcome! Please read our contributing guidelines before submitting PRs.\n\n---\n\nBuilt with ❤️ by [302.AI](https://302.ai)\n","readmeFilename":"README.md"}