index.js 1.6 KB

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