@ycodium-ai/plugin-im 0.2.3635 → 0.2.3681

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/index.js CHANGED
@@ -133127,6 +133127,20 @@ var parseModelValue = (value2) => {
133127
133127
  };
133128
133128
  var modelValue = (selection) => selection === null ? "" : `${selection.instanceId}/${selection.model}`;
133129
133129
  var isModelCatalogComplete = (instances) => instances !== null && instances.every((instance) => !instance.enabled || instance.models !== void 0);
133130
+ var isProviderSelectionError = (error) => typeof error === "object" && error !== null && "_tag" in error && error._tag === "ProviderSelectionError";
133131
+ var pickableInstances = async (providers, instances) => Promise.all(
133132
+ instances.map(async (instance) => {
133133
+ if (!instance.enabled || instance.models === void 0) return instance;
133134
+ const visible = await providers.models.list({ instanceId: instance.instanceId }).then((result2) => new Set(result2.models.map((model) => model.slug))).catch(() => null);
133135
+ if (visible === null) return instance;
133136
+ const shown = instance.models.filter((model) => visible.has(model.slug));
133137
+ const fallback = instance.models.find((model) => model.isDefault) ?? instance.models[0];
133138
+ return {
133139
+ ...instance,
133140
+ models: shown.length > 0 || fallback === void 0 ? shown : [fallback]
133141
+ };
133142
+ })
133143
+ );
133130
133144
  var modelChoices = (instances) => instances.flatMap(
133131
133145
  (instance) => instance.enabled ? (instance.models ?? []).map(
133132
133146
  (model) => ({
@@ -134818,7 +134832,11 @@ var makeReasoningCommand = (core, currentModel) => {
134818
134832
  const readOptions = async (binding) => {
134819
134833
  const resolved = await currentModel(binding);
134820
134834
  const selection = resolved.selection;
134821
- const catalog = selection === null ? null : await host.providers.models.list({ instanceId: selection.instanceId });
134835
+ const catalog = selection === null ? null : await host.providers.models.list({
134836
+ instanceId: selection.instanceId,
134837
+ // 当前型号被藏起来了也要能读到它的档位。
134838
+ includeHidden: true
134839
+ });
134822
134840
  const model = catalog?.models.find((entry) => entry.slug === selection?.model);
134823
134841
  return { ...resolved, option: model === void 0 ? void 0 : reasoningOption(model) };
134824
134842
  };
@@ -134997,7 +135015,7 @@ var makePermissionCommand = (core) => {
134997
135015
  // package.json
134998
135016
  var package_default = {
134999
135017
  name: "@ycodium-ai/plugin-im",
135000
- version: "0.2.3635",
135018
+ version: "0.2.3681",
135001
135019
  description: "Talk to your agents from Telegram, WeCom, Lark, or WeChat (experimental).",
135002
135020
  keywords: [
135003
135021
  "im",
@@ -147560,7 +147578,7 @@ var en_default = {
147560
147578
  },
147561
147579
  reasoning: {
147562
147580
  current: "Current reasoning effort: {{value}}",
147563
- currentUnlisted: "Current reasoning effort: {{value}} (no longer in the list; it stays in effect until you change it)",
147581
+ currentUnlisted: "Current reasoning effort: {{value}} (not supported by this model, so the model default is used; the setting is kept)",
147564
147582
  resetNow: "Reasoning effort reset to the model default. The current session uses it from the next turn; new sessions in this chat use it too.",
147565
147583
  resetNext: "Reasoning effort reset to the model default. New sessions in this chat will use it.",
147566
147584
  notFound: '"{{query}}" is not an available reasoning effort.',
@@ -147575,7 +147593,7 @@ var en_default = {
147575
147593
  setFailed: "Switching the reasoning effort failed. Try again in a moment.",
147576
147594
  setNow: "Reasoning effort set to {{value}}. The current session uses it from the next turn; new sessions in this chat use it too.",
147577
147595
  setNext: "Reasoning effort set to {{value}}. New sessions in this chat will use it.",
147578
- cleared: "The new model does not support the previous reasoning effort ({{value}}). It was cleared; the model default will be used.",
147596
+ unsupportedKept: "This model does not support the reasoning effort {{value}}, so it runs on the model default. The setting is kept and comes back if you switch back.",
147579
147597
  noModel: "This chat has no model yet. Pick one with /model first.",
147580
147598
  switchReadFailed: "Could not read the new model's reasoning efforts, so the model was not switched. Try again in a moment.",
147581
147599
  listTitlePlain: "Available reasoning efforts:"
@@ -148619,7 +148637,7 @@ var zh_CN_default = {
148619
148637
  },
148620
148638
  reasoning: {
148621
148639
  current: "\u5F53\u524D\u601D\u8003\u5F3A\u5EA6\uFF1A{{value}}",
148622
- currentUnlisted: "\u5F53\u524D\u601D\u8003\u5F3A\u5EA6\uFF1A{{value}}\uFF08\u5DF2\u4E0D\u5728\u53EF\u9009\u5217\u8868\uFF0C\u6362\u6389\u4E4B\u524D\u4ECD\u751F\u6548\uFF09",
148640
+ currentUnlisted: "\u5F53\u524D\u601D\u8003\u5F3A\u5EA6\uFF1A{{value}}\uFF08\u6B64\u578B\u53F7\u4E0D\u652F\u6301\uFF0C\u6309\u6A21\u578B\u9ED8\u8BA4\u8FD0\u884C\uFF1B\u8BBE\u7F6E\u4FDD\u7559\uFF09",
148623
148641
  resetNow: "\u601D\u8003\u5F3A\u5EA6\u5DF2\u6062\u590D\u4E3A\u6A21\u578B\u9ED8\u8BA4\uFF0C\u5F53\u524D\u4F1A\u8BDD\u4ECE\u4E0B\u4E00\u8F6E\u8D77\u4F7F\u7528\u5B83\uFF0C\u8FD9\u4E2A\u804A\u5929\u7684\u65B0\u4F1A\u8BDD\u4E5F\u4F7F\u7528\u5B83\u3002",
148624
148642
  resetNext: "\u601D\u8003\u5F3A\u5EA6\u5DF2\u6062\u590D\u4E3A\u6A21\u578B\u9ED8\u8BA4\uFF0C\u8FD9\u4E2A\u804A\u5929\u7684\u65B0\u4F1A\u8BDD\u5C06\u4F7F\u7528\u5B83\u3002",
148625
148643
  notFound: "\u300C{{query}}\u300D\u4E0D\u662F\u53EF\u9009\u7684\u601D\u8003\u5F3A\u5EA6\u3002",
@@ -148634,7 +148652,7 @@ var zh_CN_default = {
148634
148652
  setFailed: "\u5207\u6362\u601D\u8003\u5F3A\u5EA6\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
148635
148653
  setNow: "\u601D\u8003\u5F3A\u5EA6\u5DF2\u8BBE\u4E3A {{value}}\uFF0C\u5F53\u524D\u4F1A\u8BDD\u4ECE\u4E0B\u4E00\u8F6E\u8D77\u4F7F\u7528\u5B83\uFF0C\u8FD9\u4E2A\u804A\u5929\u7684\u65B0\u4F1A\u8BDD\u4E5F\u4F7F\u7528\u5B83\u3002",
148636
148654
  setNext: "\u601D\u8003\u5F3A\u5EA6\u5DF2\u8BBE\u4E3A {{value}}\uFF0C\u8FD9\u4E2A\u804A\u5929\u7684\u65B0\u4F1A\u8BDD\u5C06\u4F7F\u7528\u5B83\u3002",
148637
- cleared: "\u65B0\u6A21\u578B\u4E0D\u652F\u6301\u539F\u6765\u7684\u601D\u8003\u5F3A\u5EA6\uFF08{{value}}\uFF09\uFF0C\u5DF2\u6E05\u9664\uFF0C\u6539\u7528\u6A21\u578B\u9ED8\u8BA4\u3002",
148655
+ unsupportedKept: "\u6B64\u578B\u53F7\u4E0D\u652F\u6301\u601D\u8003\u5F3A\u5EA6 {{value}}\uFF0C\u6309\u6A21\u578B\u9ED8\u8BA4\u8FD0\u884C\u3002\u539F\u8BBE\u7F6E\u4FDD\u7559\uFF0C\u6362\u56DE\u539F\u578B\u53F7\u4F1A\u6062\u590D\u3002",
148638
148656
  noModel: "\u8FD9\u4E2A\u804A\u5929\u8FD8\u6CA1\u6709\u6A21\u578B\uFF0C\u5148\u7528 /model \u9009\u4E00\u4E2A\u3002",
148639
148657
  switchReadFailed: "\u6682\u65F6\u8BFB\u4E0D\u5230\u65B0\u6A21\u578B\u7684\u601D\u8003\u5F3A\u5EA6\u9009\u9879\uFF0C\u6A21\u578B\u6CA1\u6709\u5207\u6362\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
148640
148658
  listTitlePlain: "\u53EF\u9009\u601D\u8003\u5F3A\u5EA6\uFF1A"
@@ -150046,7 +150064,7 @@ var makeModelPlan = (core) => {
150046
150064
  };
150047
150065
  const handleModel = async (binding, arg) => {
150048
150066
  const instances = await host.providers.instances.list({}).catch(() => null);
150049
- const choices = instances === null ? [] : modelChoices(instances);
150067
+ const choices = instances === null ? [] : modelChoices(await pickableInstances(host.providers, instances));
150050
150068
  if (arg === "") {
150051
150069
  await deliver(binding, formatModels(await currentModelOf(binding, instances), choices, t));
150052
150070
  return;
@@ -150065,27 +150083,54 @@ var makeModelPlan = (core) => {
150065
150083
  onReadError: () => null
150066
150084
  });
150067
150085
  const previous = selectedReasoning(current);
150068
- let carried;
150086
+ let carried = (current?.options ?? []).filter(
150087
+ (entry) => typeof entry.value !== "string" || entry.value.trim() !== ""
150088
+ );
150069
150089
  if (previous !== void 0) {
150070
150090
  try {
150071
- const catalog = await host.providers.models.list({ instanceId: picked.instanceId });
150091
+ const catalog = await host.providers.models.list({
150092
+ instanceId: picked.instanceId,
150093
+ includeHidden: true
150094
+ });
150072
150095
  const model = catalog.models.find((entry) => entry.slug === picked.model);
150073
150096
  const option2 = model === void 0 ? void 0 : reasoningOption(model);
150074
150097
  if (option2 !== void 0 && option2.values.includes(previous.value))
150075
- carried = { id: option2.id, value: previous.value };
150098
+ carried = carried.map(
150099
+ (entry) => entry.id === previous.id ? { id: option2.id, value: previous.value } : entry
150100
+ );
150076
150101
  } catch {
150077
150102
  host.log.warn("chat could not read reasoning options for a model switch");
150078
150103
  await deliver(binding, t("reasoning.switchReadFailed"));
150079
150104
  return;
150080
150105
  }
150081
150106
  }
150082
- const selection = {
150083
- instanceId: picked.instanceId,
150084
- model: picked.model,
150085
- ...carried === void 0 ? {} : { options: [carried] }
150086
- };
150087
- const cleared = previous !== void 0 && carried === void 0 ? [t("reasoning.cleared", { value: previous.value })] : [];
150088
- if (!await saveModelSelection(core, binding, threadId, selection)) {
150107
+ let resolved;
150108
+ try {
150109
+ resolved = await host.providers.selection.resolve({
150110
+ base: {
150111
+ instanceId: picked.instanceId,
150112
+ model: picked.model,
150113
+ ...carried.length === 0 ? {} : { options: carried }
150114
+ },
150115
+ instanceId: picked.instanceId,
150116
+ model: picked.model,
150117
+ purpose: "dispatch-existing"
150118
+ });
150119
+ } catch (error) {
150120
+ if (isProviderSelectionError(error)) {
150121
+ await deliver(binding, t("model.notFound", { query: arg }));
150122
+ return;
150123
+ }
150124
+ host.log.warn("chat could not resolve the model for a model switch", {
150125
+ error: describeError(error)
150126
+ });
150127
+ await deliver(binding, t("model.setFailed"));
150128
+ return;
150129
+ }
150130
+ const unsupported = (resolved.hints ?? []).flatMap(
150131
+ (hint) => hint.kind === "option-unsupported" && isReasoningOption(hint.optionId) ? [t("reasoning.unsupportedKept", { value: String(hint.stored) })] : []
150132
+ );
150133
+ if (!await saveModelSelection(core, binding, threadId, resolved.modelSelection)) {
150089
150134
  await deliver(binding, t("model.setFailed"));
150090
150135
  return;
150091
150136
  }
@@ -150093,7 +150138,7 @@ var makeModelPlan = (core) => {
150093
150138
  binding,
150094
150139
  [
150095
150140
  t(threadId === null ? "model.setNext" : "model.setNow", { model: modelLabel(picked) }),
150096
- ...cleared
150141
+ ...unsupported
150097
150142
  ].join("\n")
150098
150143
  );
150099
150144
  };
@@ -157181,7 +157226,7 @@ var makeWecomAppAdapter = (deps) => {
157181
157226
  // src/index.ts
157182
157227
  var definition = {
157183
157228
  id: "im",
157184
- apiVersion: 50,
157229
+ apiVersion: 52,
157185
157230
  // 第二个参数只给插件自己的测试夹具:换掉文件 IO 与派发重试的等待。宿主只传 ctx。
157186
157231
  activate: async (ctx, testing = {}) => {
157187
157232
  const { dispatchSleep } = testing;
package/locales/en.json CHANGED
@@ -437,7 +437,7 @@
437
437
  },
438
438
  "reasoning": {
439
439
  "current": "Current reasoning effort: {{value}}",
440
- "currentUnlisted": "Current reasoning effort: {{value}} (no longer in the list; it stays in effect until you change it)",
440
+ "currentUnlisted": "Current reasoning effort: {{value}} (not supported by this model, so the model default is used; the setting is kept)",
441
441
  "resetNow": "Reasoning effort reset to the model default. The current session uses it from the next turn; new sessions in this chat use it too.",
442
442
  "resetNext": "Reasoning effort reset to the model default. New sessions in this chat will use it.",
443
443
  "notFound": "\"{{query}}\" is not an available reasoning effort.",
@@ -452,7 +452,7 @@
452
452
  "setFailed": "Switching the reasoning effort failed. Try again in a moment.",
453
453
  "setNow": "Reasoning effort set to {{value}}. The current session uses it from the next turn; new sessions in this chat use it too.",
454
454
  "setNext": "Reasoning effort set to {{value}}. New sessions in this chat will use it.",
455
- "cleared": "The new model does not support the previous reasoning effort ({{value}}). It was cleared; the model default will be used.",
455
+ "unsupportedKept": "This model does not support the reasoning effort {{value}}, so it runs on the model default. The setting is kept and comes back if you switch back.",
456
456
  "noModel": "This chat has no model yet. Pick one with /model first.",
457
457
  "switchReadFailed": "Could not read the new model's reasoning efforts, so the model was not switched. Try again in a moment.",
458
458
  "listTitlePlain": "Available reasoning efforts:"
@@ -437,7 +437,7 @@
437
437
  },
438
438
  "reasoning": {
439
439
  "current": "当前思考强度:{{value}}",
440
- "currentUnlisted": "当前思考强度:{{value}}(已不在可选列表,换掉之前仍生效)",
440
+ "currentUnlisted": "当前思考强度:{{value}}(此型号不支持,按模型默认运行;设置保留)",
441
441
  "resetNow": "思考强度已恢复为模型默认,当前会话从下一轮起使用它,这个聊天的新会话也使用它。",
442
442
  "resetNext": "思考强度已恢复为模型默认,这个聊天的新会话将使用它。",
443
443
  "notFound": "「{{query}}」不是可选的思考强度。",
@@ -452,7 +452,7 @@
452
452
  "setFailed": "切换思考强度失败,请稍后重试。",
453
453
  "setNow": "思考强度已设为 {{value}},当前会话从下一轮起使用它,这个聊天的新会话也使用它。",
454
454
  "setNext": "思考强度已设为 {{value}},这个聊天的新会话将使用它。",
455
- "cleared": "新模型不支持原来的思考强度({{value}}),已清除,改用模型默认。",
455
+ "unsupportedKept": "此型号不支持思考强度 {{value}},按模型默认运行。原设置保留,换回原型号会恢复。",
456
456
  "noModel": "这个聊天还没有模型,先用 /model 选一个。",
457
457
  "switchReadFailed": "暂时读不到新模型的思考强度选项,模型没有切换,请稍后重试。",
458
458
  "listTitlePlain": "可选思考强度:"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/plugin-im",
3
- "version": "0.2.3635",
3
+ "version": "0.2.3681",
4
4
  "description": "Talk to your agents from Telegram, WeCom, Lark, or WeChat (experimental).",
5
5
  "keywords": [
6
6
  "im",
@@ -32,8 +32,8 @@
32
32
  "markdown-it": "^15.0.2",
33
33
  "react": "19.2.6",
34
34
  "vite-plus": "0.2.2",
35
- "ycodium-react-test-harness": "0.0.0",
36
- "@ycodium-ai/plugin-api": "0.2.3635"
35
+ "@ycodium-ai/plugin-api": "0.2.3681",
36
+ "ycodium-react-test-harness": "0.0.0"
37
37
  },
38
38
  "ycodium": {
39
39
  "plugin": "./dist/index.js",