oh-my-opencode-kikokikok 2.15.8 → 2.15.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -2253,7 +2253,7 @@ var require_picocolors = __commonJS((exports, module) => {
2253
2253
  var require_package = __commonJS((exports, module) => {
2254
2254
  module.exports = {
2255
2255
  name: "oh-my-opencode-kikokikok",
2256
- version: "2.15.8",
2256
+ version: "2.15.9",
2257
2257
  description: "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
2258
2258
  main: "dist/index.js",
2259
2259
  types: "dist/index.d.ts",
@@ -3,11 +3,20 @@ export declare class LettaAdapter {
3
3
  private config;
4
4
  private endpoint;
5
5
  private agentCache;
6
- private detectedEmbeddingModel;
7
- private modelDetectionPromise;
6
+ private modelCache;
7
+ private modelCachePromise;
8
+ private resolvedEmbeddingModel;
9
+ private resolvedLlmModel;
8
10
  constructor(config: LettaConfig);
9
- private detectEmbeddingModel;
10
- private normalizeModelHandle;
11
+ private getModels;
12
+ /**
13
+ * Resolves user model name to Letta handle. Letta requires exact handle matches
14
+ * AND valid provider prefix (letta/, openai/). Models with other prefixes like
15
+ * openai-proxy/ will fail agent creation even if registered in the model list.
16
+ */
17
+ private resolveModelHandle;
18
+ private getEmbeddingModel;
19
+ private getLlmModel;
11
20
  add(input: AddMemoryInput): Promise<Memory>;
12
21
  search(input: SearchMemoryInput): Promise<MemorySearchResult[]>;
13
22
  get(id: string): Promise<Memory | null>;
package/dist/index.js CHANGED
@@ -43783,29 +43783,28 @@ var DEFAULT_ENDPOINT2 = "http://localhost:8283";
43783
43783
  var DEFAULT_AGENT_PREFIX = "opencode";
43784
43784
  var DEFAULT_LLM_MODEL = "letta/letta-free";
43785
43785
  var DEFAULT_EMBEDDING_MODEL = "letta/letta-free";
43786
+ var VALID_PROVIDERS = ["letta", "openai"];
43786
43787
 
43787
43788
  class LettaAdapter {
43788
43789
  config;
43789
43790
  endpoint;
43790
43791
  agentCache = new Map;
43791
- detectedEmbeddingModel = null;
43792
- modelDetectionPromise = null;
43792
+ modelCache = null;
43793
+ modelCachePromise = null;
43794
+ resolvedEmbeddingModel = null;
43795
+ resolvedLlmModel = null;
43793
43796
  constructor(config3) {
43794
43797
  this.config = config3;
43795
43798
  this.endpoint = config3.endpoint ?? DEFAULT_ENDPOINT2;
43796
43799
  }
43797
- async detectEmbeddingModel() {
43798
- if (this.config.embeddingModel) {
43799
- return this.normalizeModelHandle(this.config.embeddingModel);
43800
- }
43801
- if (this.detectedEmbeddingModel) {
43802
- return this.detectedEmbeddingModel;
43800
+ async getModels() {
43801
+ if (this.modelCache) {
43802
+ return this.modelCache;
43803
43803
  }
43804
- if (this.modelDetectionPromise) {
43805
- await this.modelDetectionPromise;
43806
- return this.detectedEmbeddingModel ?? DEFAULT_EMBEDDING_MODEL;
43804
+ if (this.modelCachePromise) {
43805
+ return this.modelCachePromise;
43807
43806
  }
43808
- this.modelDetectionPromise = (async () => {
43807
+ this.modelCachePromise = (async () => {
43809
43808
  try {
43810
43809
  const response2 = await fetch(`${this.endpoint}/v1/models`, {
43811
43810
  method: "GET",
@@ -43813,26 +43812,89 @@ class LettaAdapter {
43813
43812
  signal: AbortSignal.timeout(1e4)
43814
43813
  });
43815
43814
  if (!response2.ok) {
43816
- return;
43815
+ return [];
43817
43816
  }
43818
43817
  const models = await response2.json();
43819
- const proxyEmbeddingModels = models.filter((m) => m.name.includes("embedding") && m.model_endpoint.includes("host.docker.internal") && m.provider_name === "openai");
43820
- if (proxyEmbeddingModels.length > 0) {
43821
- const preferredName = this.config.preferredEmbeddingModel ?? "text-embedding-3-small";
43822
- const preferred = proxyEmbeddingModels.find((m) => m.name.includes(preferredName));
43823
- const model = preferred ?? proxyEmbeddingModels[0];
43824
- this.detectedEmbeddingModel = model.handle;
43825
- }
43826
- } catch {}
43818
+ this.modelCache = models;
43819
+ return models;
43820
+ } catch {
43821
+ return [];
43822
+ }
43827
43823
  })();
43828
- await this.modelDetectionPromise;
43829
- return this.detectedEmbeddingModel ?? DEFAULT_EMBEDDING_MODEL;
43824
+ return this.modelCachePromise;
43830
43825
  }
43831
- normalizeModelHandle(model) {
43832
- if (model.startsWith("openai/") && !model.startsWith("openai-proxy/")) {
43833
- return model.replace("openai/", "openai-proxy/");
43826
+ async resolveModelHandle(requestedModel, isEmbedding = false) {
43827
+ const models = await this.getModels();
43828
+ if (models.length === 0) {
43829
+ return requestedModel;
43830
+ }
43831
+ const hasValidProvider = (handle) => {
43832
+ const provider = handle.split("/")[0];
43833
+ return VALID_PROVIDERS.includes(provider);
43834
+ };
43835
+ const exactMatch = models.find((m) => m.handle === requestedModel && hasValidProvider(m.handle));
43836
+ if (exactMatch) {
43837
+ return exactMatch.handle;
43838
+ }
43839
+ const requestedName = requestedModel.includes("/") ? requestedModel.split("/").pop() : requestedModel;
43840
+ const candidates = models.filter((m) => {
43841
+ if (!hasValidProvider(m.handle)) {
43842
+ return false;
43843
+ }
43844
+ if (isEmbedding && !m.name.includes("embedding")) {
43845
+ return false;
43846
+ }
43847
+ return m.name.includes(requestedName) || m.handle.includes(requestedName);
43848
+ });
43849
+ if (candidates.length > 0) {
43850
+ const proxyModel = candidates.find((m) => m.model_endpoint?.includes("host.docker.internal"));
43851
+ return proxyModel?.handle ?? candidates[0].handle;
43852
+ }
43853
+ if (isEmbedding) {
43854
+ const validEmbeddingModels = models.filter((m) => m.name.includes("embedding") && hasValidProvider(m.handle));
43855
+ if (validEmbeddingModels.length > 0) {
43856
+ const preferredName = this.config.preferredEmbeddingModel ?? "text-embedding-3-small";
43857
+ const preferred = validEmbeddingModels.find((m) => m.name.includes(preferredName));
43858
+ return preferred?.handle ?? validEmbeddingModels[0].handle;
43859
+ }
43860
+ }
43861
+ return isEmbedding ? DEFAULT_EMBEDDING_MODEL : DEFAULT_LLM_MODEL;
43862
+ }
43863
+ async getEmbeddingModel() {
43864
+ if (this.resolvedEmbeddingModel) {
43865
+ return this.resolvedEmbeddingModel;
43866
+ }
43867
+ const configModel = this.config.embeddingModel;
43868
+ if (configModel) {
43869
+ this.resolvedEmbeddingModel = await this.resolveModelHandle(configModel, true);
43870
+ } else {
43871
+ const models = await this.getModels();
43872
+ const hasValidProvider = (handle) => {
43873
+ const provider = handle.split("/")[0];
43874
+ return VALID_PROVIDERS.includes(provider);
43875
+ };
43876
+ const validEmbeddingModels = models.filter((m) => m.name.includes("embedding") && hasValidProvider(m.handle));
43877
+ if (validEmbeddingModels.length > 0) {
43878
+ const preferredName = this.config.preferredEmbeddingModel ?? "text-embedding-3-small";
43879
+ const preferred = validEmbeddingModels.find((m) => m.name.includes(preferredName));
43880
+ this.resolvedEmbeddingModel = preferred?.handle ?? validEmbeddingModels[0].handle;
43881
+ } else {
43882
+ this.resolvedEmbeddingModel = DEFAULT_EMBEDDING_MODEL;
43883
+ }
43884
+ }
43885
+ return this.resolvedEmbeddingModel;
43886
+ }
43887
+ async getLlmModel() {
43888
+ if (this.resolvedLlmModel) {
43889
+ return this.resolvedLlmModel;
43890
+ }
43891
+ const configModel = this.config.llmModel;
43892
+ if (configModel) {
43893
+ this.resolvedLlmModel = await this.resolveModelHandle(configModel, false);
43894
+ } else {
43895
+ this.resolvedLlmModel = DEFAULT_LLM_MODEL;
43834
43896
  }
43835
- return model;
43897
+ return this.resolvedLlmModel;
43836
43898
  }
43837
43899
  async add(input) {
43838
43900
  if (!this.config.enabled) {
@@ -44015,8 +44077,8 @@ class LettaAdapter {
44015
44077
  }
44016
44078
  return existing;
44017
44079
  }
44018
- const embeddingModel = await this.detectEmbeddingModel();
44019
- const llmModel = this.normalizeModelHandle(this.config.llmModel ?? DEFAULT_LLM_MODEL);
44080
+ const embeddingModel = await this.getEmbeddingModel();
44081
+ const llmModel = await this.getLlmModel();
44020
44082
  const agentName = this.getAgentName(layer);
44021
44083
  const response2 = await this.request("/v1/agents", {
44022
44084
  method: "POST",
@@ -44047,7 +44109,7 @@ class LettaAdapter {
44047
44109
  if (!embeddingHandle)
44048
44110
  return false;
44049
44111
  if (embeddingHandle === "letta/letta-free") {
44050
- const detected = await this.detectEmbeddingModel();
44112
+ const detected = await this.getEmbeddingModel();
44051
44113
  return detected !== "letta/letta-free";
44052
44114
  }
44053
44115
  return false;
@@ -44055,8 +44117,8 @@ class LettaAdapter {
44055
44117
  async recreateAgentWithCorrectEmbedding(existingAgent, layer) {
44056
44118
  await this.request(`/v1/agents/${existingAgent.id}`, { method: "DELETE" }).catch(() => {});
44057
44119
  this.agentCache.delete(layer);
44058
- const embeddingModel = await this.detectEmbeddingModel();
44059
- const llmModel = this.normalizeModelHandle(this.config.llmModel ?? DEFAULT_LLM_MODEL);
44120
+ const embeddingModel = await this.getEmbeddingModel();
44121
+ const llmModel = await this.getLlmModel();
44060
44122
  const agentName = this.getAgentName(layer);
44061
44123
  const response2 = await this.request("/v1/agents", {
44062
44124
  method: "POST",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode-kikokikok",
3
- "version": "2.15.8",
3
+ "version": "2.15.9",
4
4
  "description": "OpenCode plugin - custom agents (oracle, librarian) and enhanced features",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",