index.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. module.exports = async function(ctx) {
  2. const endpoints = (ctx.config || {}).endpoints || [];
  3. if (!Array.isArray(endpoints)) {
  4. throw new Error("Plugin config requires 'endpoints' array");
  5. }
  6. for (const ep of endpoints) {
  7. try {
  8. const headers = { "Content-Type": "application/json" };
  9. if (ep.apiKey) headers["Authorization"] = `Bearer ${ep.apiKey}`;
  10. const res = await fetch(`${ep.baseURL}/models`, { headers });
  11. if (!res.ok) throw new Error(`HTTP ${res.status}`);
  12. const json = await res.json();
  13. const models = (json.data || []).map(m => ({
  14. id: m.id,
  15. name: m.id,
  16. capabilities: { input: ["text"], output: "text" },
  17. limits: { context: m.context_length || 128000, output: m.max_tokens || 8192 }
  18. }));
  19. await ctx.provider.transform(editor => {
  20. editor.add({
  21. info: {
  22. id: ep.name,
  23. name: ep.name,
  24. activation: "enabled",
  25. package: "@opencode/ai/providers/openai-compatible",
  26. settings: { baseURL: ep.baseURL }
  27. },
  28. models
  29. });
  30. });
  31. ctx.log.info(`Discovered ${models.length} models from ${ep.name}`);
  32. } catch(e) {
  33. ctx.log.error(`Failed to discover from ${ep.name}: ${e.message}`);
  34. }
  35. }
  36. ctx.commands.register({
  37. id: "refresh-models",
  38. description: "Refresh all discovered models",
  39. async run() {
  40. ctx.log.info("Refreshing models...");
  41. await ctx.provider.reload();
  42. }
  43. });
  44. };