@bolloon/bolloon-agent 0.5.0 → 0.5.2

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.
Files changed (121) hide show
  1. package/README.md +39 -0
  2. package/dist/agents/agent-lang.js +101 -0
  3. package/dist/agents/agent-manifest-protocol.js +4 -0
  4. package/dist/agents/execution-supervisor.js +87 -5
  5. package/dist/agents/gateway-group.js +44 -3
  6. package/dist/agents/model-policy.js +651 -0
  7. package/dist/agents/pi-sdk-tools.js +84 -33
  8. package/dist/agents/pi-sdk.js +184 -31
  9. package/dist/agents/run-store.js +53 -0
  10. package/dist/agents/task/task-runner.js +8 -1
  11. package/dist/agents/workflow-pivot-loop.js +22 -13
  12. package/dist/cli/clipboard.js +65 -0
  13. package/dist/cli/ink-app.js +145 -17
  14. package/dist/cli/log-gate.js +386 -0
  15. package/dist/cli/mention-data.js +2 -0
  16. package/dist/cli/model-selector.js +538 -0
  17. package/dist/cli/reply-hygiene.js +54 -0
  18. package/dist/cli/setup-wizard.js +686 -69
  19. package/dist/cli/startup-notice.js +160 -0
  20. package/dist/cli/stores.js +22 -1
  21. package/dist/cli/theme.js +49 -0
  22. package/dist/cli/tui-select.js +970 -0
  23. package/dist/cli-entry.js +125 -18
  24. package/dist/efficode/compress.js +78 -0
  25. package/dist/efficode/crc32.js +38 -0
  26. package/dist/efficode/did.js +66 -0
  27. package/dist/efficode/index.js +24 -0
  28. package/dist/efficode/lz77.js +170 -0
  29. package/dist/efficode/negotiate.js +187 -0
  30. package/dist/efficode/ops.js +87 -0
  31. package/dist/efficode/packet.js +271 -0
  32. package/dist/efficode/types.js +45 -0
  33. package/dist/electron-build/agents/agent-manifest-protocol.js +4 -0
  34. package/dist/electron-build/agents/agent-manifest-protocol.js.map +1 -1
  35. package/dist/electron-build/agents/execution-supervisor.js +86 -4
  36. package/dist/electron-build/agents/execution-supervisor.js.map +1 -1
  37. package/dist/electron-build/agents/goal-store.js.map +1 -1
  38. package/dist/electron-build/agents/model-policy.js +706 -0
  39. package/dist/electron-build/agents/model-policy.js.map +1 -0
  40. package/dist/electron-build/agents/pi-sdk-tools.js +84 -33
  41. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  42. package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
  43. package/dist/electron-build/agents/pi-sdk.js +185 -31
  44. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  45. package/dist/electron-build/agents/run-store.js +55 -1
  46. package/dist/electron-build/agents/run-store.js.map +1 -1
  47. package/dist/electron-build/agents/task/task-runner.js +8 -1
  48. package/dist/electron-build/agents/task/task-runner.js.map +1 -1
  49. package/dist/electron-build/agents/workflow-pivot-loop.js +22 -13
  50. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
  51. package/dist/electron-build/llm/config-store.js +146 -6
  52. package/dist/electron-build/llm/config-store.js.map +1 -1
  53. package/dist/electron-build/llm/connection-probe.js +764 -0
  54. package/dist/electron-build/llm/connection-probe.js.map +1 -0
  55. package/dist/electron-build/llm/custom-provider-store.js +272 -0
  56. package/dist/electron-build/llm/custom-provider-store.js.map +1 -0
  57. package/dist/electron-build/llm/data/provider-catalog-baked.js +23 -0
  58. package/dist/electron-build/llm/data/provider-catalog-baked.js.map +1 -0
  59. package/dist/electron-build/llm/model-catalog.js +778 -0
  60. package/dist/electron-build/llm/model-catalog.js.map +1 -0
  61. package/dist/electron-build/llm/model-discovery.js +1202 -0
  62. package/dist/electron-build/llm/model-discovery.js.map +1 -0
  63. package/dist/electron-build/llm/model-selection.js +1315 -0
  64. package/dist/electron-build/llm/model-selection.js.map +1 -0
  65. package/dist/electron-build/llm/pi-ai.js +751 -55
  66. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  67. package/dist/electron-build/llm/provider-catalog.js +969 -0
  68. package/dist/electron-build/llm/provider-catalog.js.map +1 -0
  69. package/dist/electron-build/llm/provider-registry.js +950 -0
  70. package/dist/electron-build/llm/provider-registry.js.map +1 -0
  71. package/dist/electron-build/llm/tool-name.js +266 -0
  72. package/dist/electron-build/llm/tool-name.js.map +1 -0
  73. package/dist/electron-build/utils/dual-source-facts.js +236 -0
  74. package/dist/electron-build/utils/dual-source-facts.js.map +1 -0
  75. package/dist/electron-build/utils/dual-source.js +32 -156
  76. package/dist/electron-build/utils/dual-source.js.map +1 -1
  77. package/dist/electron-build/utils/update-manager.js +22 -72
  78. package/dist/electron-build/utils/update-manager.js.map +1 -1
  79. package/dist/electron-build/utils/update-state.js +2 -19
  80. package/dist/electron-build/utils/update-state.js.map +1 -1
  81. package/dist/electron-build/utils/version-identity.js +193 -0
  82. package/dist/electron-build/utils/version-identity.js.map +1 -0
  83. package/dist/electron-build/utils/version-info.js +47 -101
  84. package/dist/electron-build/utils/version-info.js.map +1 -1
  85. package/dist/index.js +282 -96
  86. package/dist/ios/bolloon-web.json +10 -0
  87. package/dist/ios/mobile-contacts.js +44 -11
  88. package/dist/ios/mobile-core.js +1723 -84
  89. package/dist/ios/mobile-tasks.js +339 -0
  90. package/dist/ios/mobile-update.js +1442 -0
  91. package/dist/ios/mobile.js +308 -35
  92. package/dist/ios/routes-llm-config.js +344 -52
  93. package/dist/ios/routes-mobile-tasks.js +353 -0
  94. package/dist/ios/server.js +163 -4
  95. package/dist/ios/sw.js +1 -1
  96. package/dist/llm/config-store.js +146 -6
  97. package/dist/llm/connection-probe.js +744 -0
  98. package/dist/llm/custom-provider-store.js +224 -0
  99. package/dist/llm/data/provider-catalog-baked.js +19 -0
  100. package/dist/llm/model-catalog.js +717 -0
  101. package/dist/llm/model-discovery.js +1137 -0
  102. package/dist/llm/model-selection.js +1241 -0
  103. package/dist/llm/pi-ai.js +732 -54
  104. package/dist/llm/provider-catalog.js +898 -0
  105. package/dist/llm/provider-registry.js +917 -0
  106. package/dist/llm/tool-name.js +220 -0
  107. package/dist/setup/onboard.js +34 -8
  108. package/dist/utils/dual-source-facts.js +223 -0
  109. package/dist/utils/dual-source.js +12 -141
  110. package/dist/utils/update-manager.js +16 -59
  111. package/dist/utils/update-state.js +6 -18
  112. package/dist/utils/version-identity.js +176 -0
  113. package/dist/utils/version-info.js +9 -78
  114. package/dist/web/bolloon-web.json +10 -0
  115. package/dist/web/mobile-core.js +1721 -84
  116. package/dist/web/mobile-update.js +1442 -0
  117. package/dist/web/mobile.js +372 -35
  118. package/dist/web/routes-llm-config.js +344 -52
  119. package/dist/web/sw.js +1 -1
  120. package/package.json +1 -1
  121. package/scripts/build-web.ts +36 -0
@@ -3185,9 +3185,9 @@ export function registerBuiltinTools(ctx) {
3185
3185
  });
3186
3186
  ctx.tools.set('bolloon_config_set', {
3187
3187
  name: 'bolloon_config_set',
3188
- description: '修改 Bolloon 自身配置 (~/.bolloon/bolloon-config.json). 可切换激活供应商 (provider) 或改某供应商的 model/baseUrl/temperature/enabled. 修改立即生效 (下次 LLM 调用使用新配置). 例: provider=deepseek; provider=minimax, model=MiniMax-M3; deepseek.temperature=0.3',
3188
+ description: '修改 Bolloon 自身配置 (~/.bolloon/bolloon-config.json). 可切换激活供应商 (provider) 或改某供应商的 model/baseUrl/temperature/enabled/maxTokens. 切换类改动走**统一入口** (先校验探测, 过了才落盘并重建模型运行时), 所以调用后返回的"当前生效"就是真的生效的那一份. 例: provider=deepseek; provider=minimax, model=MiniMax-M3; deepseek.temperature=0.3',
3189
3189
  parameters: {
3190
- provider: '可选: 切换激活供应商 (如 deepseek / minimax / openai / anthropic / ollama)',
3190
+ provider: '可选: 切换激活供应商 (内置的 13 家 + 已注册的自定义供应商)',
3191
3191
  'provider.key': '可选: 修改指定供应商字段, 格式 <供应商>.<字段>=<值>, 如 minimax.model=MiniMax-M3',
3192
3192
  model: '可选: 同时设置激活供应商的 model',
3193
3193
  temperature: '可选: 同时设置激活供应商的 temperature (0-2)',
@@ -3195,64 +3195,115 @@ export function registerBuiltinTools(ctx) {
3195
3195
  execute: async (args) => {
3196
3196
  try {
3197
3197
  const { llmConfigStore } = await import('../llm/config-store.js');
3198
+ const { selectModel, formatEffectiveModel, listRegisteredProviderIds } = await import('../llm/model-selection.js');
3198
3199
  await llmConfigStore.initialize();
3199
3200
  const changes = [];
3200
- // 1. 切换激活供应商
3201
- if (args.provider) {
3202
- const name = String(args.provider).trim().toLowerCase();
3203
- const known = ['openai', 'anthropic', 'ollama', 'openrouter', 'gemini', 'minimax', 'deepseek', 'kimi', 'glm', 'qwen', 'mimo', 'grok', 'local'];
3204
- if (!known.includes(name))
3205
- return { success: false, error: `未知供应商: ${name}. 可用: ${known.join(', ')}` };
3206
- await llmConfigStore.setActiveProvider(name);
3207
- changes.push(`activeProvider=${name}`);
3208
- }
3209
- // 2. 修改指定供应商字段 (provider.key=value)
3201
+ // 切换类改动累积起来**一次性**交给统一入口 (校验+探测+落盘+重建运行时都在它里面)。
3202
+ // `provider.field=` 里 model/baseUrl 是"选择自己的字段": 只在这家**正在用**时才算切换
3203
+ // (改一家没在用的供应商的地址/模型 = 配置编辑, 不该顺手把它切成激活)。
3204
+ const switchReq = {};
3205
+ const activeBefore = await llmConfigStore.getActiveProvider().catch(() => '');
3206
+ const optIn = (provider, field, val) => {
3207
+ if (!switchReq.provider)
3208
+ switchReq.provider = provider;
3209
+ if (switchReq.provider !== provider)
3210
+ return false;
3211
+ if (field === 'model')
3212
+ switchReq.model = val;
3213
+ else if (field === 'baseUrl')
3214
+ switchReq.baseUrl = val;
3215
+ else
3216
+ return false;
3217
+ return true;
3218
+ };
3219
+ const switchProvider = args.provider ? String(args.provider).trim().toLowerCase() : '';
3220
+ if (switchProvider) {
3221
+ switchReq.provider = switchProvider;
3222
+ if (args.model)
3223
+ switchReq.model = String(args.model);
3224
+ if (args.temperature !== undefined) {
3225
+ const t = Number(args.temperature);
3226
+ if (Number.isNaN(t))
3227
+ return { success: false, error: `temperature=${args.temperature} 不是数字` };
3228
+ switchReq.temperature = t;
3229
+ }
3230
+ }
3231
+ // 1. 非选择的字段 (temperature/maxTokens/enabled/apiKey) 与"没在用那家"的字段 —— 配置编辑
3210
3232
  for (const [k, v] of Object.entries(args)) {
3211
3233
  if (k === 'provider' || k === 'model' || k === 'temperature')
3212
3234
  continue;
3213
3235
  if (!k.includes('.'))
3214
3236
  continue;
3215
3237
  const [prov, field] = k.split('.');
3238
+ const p = prov.trim().toLowerCase();
3216
3239
  const val = String(v);
3240
+ const isSelectionField = field === 'model' || field === 'baseUrl';
3241
+ if (isSelectionField && (switchProvider ? switchProvider === p : activeBefore === p)) {
3242
+ optIn(p, field, val); // 改的是"正在用的那一份" → 走入口 (顺带重建运行时)
3243
+ continue;
3244
+ }
3217
3245
  if (field === 'temperature' || field === 'maxTokens') {
3218
3246
  const num = Number(val);
3219
3247
  if (Number.isNaN(num))
3220
3248
  return { success: false, error: `${k}=${val} 不是数字` };
3221
- await llmConfigStore.updateProvider(prov, { [field]: num });
3249
+ await llmConfigStore.updateProvider(p, { [field]: num });
3222
3250
  }
3223
3251
  else if (field === 'enabled') {
3224
- await llmConfigStore.updateProvider(prov, { enabled: val === 'true' || val === '1' });
3252
+ await llmConfigStore.updateProvider(p, { enabled: val === 'true' || val === '1' });
3225
3253
  }
3226
3254
  else if (field === 'apiKey') {
3227
- await llmConfigStore.updateProvider(prov, { apiKey: val });
3255
+ await llmConfigStore.updateProvider(p, { apiKey: val });
3228
3256
  }
3229
3257
  else {
3230
- await llmConfigStore.updateProvider(prov, { [field]: val });
3258
+ await llmConfigStore.updateProvider(p, { [field]: val });
3231
3259
  }
3232
- changes.push(`${prov}.${field}=${field === 'apiKey' ? '***' : val}`);
3260
+ changes.push(`${p}.${field}=${field === 'apiKey' ? '***' : val}`);
3233
3261
  }
3234
- // 3. 激活供应商的 model / temperature
3235
- if (args.model || args.temperature) {
3236
- const active = await llmConfigStore.getActiveProvider();
3237
- const patch = {};
3262
+ // 2. 选择的字段 (model/baseUrl) 单独给 activate 供应商时, 也走入口
3263
+ if (!switchProvider && (args.model || args.temperature !== undefined)) {
3264
+ switchReq.provider = activeBefore;
3238
3265
  if (args.model)
3239
- patch.model = String(args.model);
3240
- if (args.temperature) {
3266
+ switchReq.model = String(args.model);
3267
+ if (args.temperature !== undefined) {
3241
3268
  const t = Number(args.temperature);
3242
3269
  if (Number.isNaN(t))
3243
3270
  return { success: false, error: `temperature=${args.temperature} 不是数字` };
3244
- patch.temperature = t;
3271
+ switchReq.temperature = t;
3245
3272
  }
3246
- await llmConfigStore.updateProvider(active, patch);
3247
- if (args.model)
3248
- changes.push(`${active}.model=${args.model}`);
3249
- if (args.temperature)
3250
- changes.push(`${active}.temperature=${args.temperature}`);
3251
3273
  }
3252
- if (changes.length === 0)
3253
- return { success: false, error: '没有要修改的配置项. 例: provider=deepseek 或 minimax.model=MiniMax-M3' };
3254
- const cfg = await llmConfigStore.getConfig();
3255
- return { success: true, output: `✅ 配置已更新: ${changes.join(', ')}\n 当前激活: ${cfg.activeProvider}` };
3274
+ // 3. 一次性提交给统一入口 —— 它是唯一做"校验+探测+落盘+重建运行时"的地方
3275
+ if (switchReq.provider) {
3276
+ const r = await selectModel({ ...switchReq, scope: 'global' });
3277
+ if (!r.ok) {
3278
+ // 失败时入口保证"配置与运行时都没变" —— 如实说, 不假装成功
3279
+ return {
3280
+ success: false,
3281
+ error: `切换 ${switchReq.provider} 未生效 [${r.failureClass || '未知'}]: ${r.message}` +
3282
+ (r.previous ? `\n 仍在用: ${formatEffectiveModel(r.previous)}` : ''),
3283
+ };
3284
+ }
3285
+ const bits = [`activeProvider=${r.effective.provider}`];
3286
+ if (switchReq.model)
3287
+ bits.push(`model=${r.effective.model}`);
3288
+ if (switchReq.baseUrl)
3289
+ bits.push(`baseUrl=${r.effective.baseUrl}`);
3290
+ if (switchReq.temperature !== undefined)
3291
+ bits.push(`temperature=${switchReq.temperature}`);
3292
+ changes.push(...bits);
3293
+ }
3294
+ if (changes.length === 0) {
3295
+ return {
3296
+ success: false,
3297
+ error: `没有要修改的配置项. 例: provider=deepseek 或 minimax.model=MiniMax-M3. 可用供应商: ${listRegisteredProviderIds().join(', ')}`,
3298
+ };
3299
+ }
3300
+ // 结尾一律回**真正生效**的那一份 (入口写完就是它; 只有配置编辑时也从入口读, 免得各读各的)
3301
+ const { effectiveModelConfig } = await import('../llm/model-selection.js');
3302
+ const eff = await effectiveModelConfig({});
3303
+ return {
3304
+ success: true,
3305
+ output: `✅ 配置已更新: ${changes.join(', ')}\n 当前生效: ${eff ? formatEffectiveModel(eff) : '读不出来'}`,
3306
+ };
3256
3307
  }
3257
3308
  catch (e) {
3258
3309
  return { success: false, error: `bolloon_config_set 失败: ${String(e.message || e).slice(0, 200)}` };