bone-agent 1.3.3 → 2.0.0

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/bin/bone.js +39 -0
  2. package/package.json +25 -39
  3. package/LICENSE +0 -21
  4. package/README.md +0 -184
  5. package/bin/npm-wrapper.js +0 -235
  6. package/bin/rg +0 -0
  7. package/bin/rg.exe +0 -0
  8. package/config.yaml.example +0 -141
  9. package/prompts/main/ask_questions.md +0 -31
  10. package/prompts/main/batch_independent_calls.md +0 -5
  11. package/prompts/main/casual_interactions.md +0 -11
  12. package/prompts/main/code_references.md +0 -8
  13. package/prompts/main/communication_style.md +0 -12
  14. package/prompts/main/context_reliability.md +0 -12
  15. package/prompts/main/conversational_tool_calling.md +0 -15
  16. package/prompts/main/dream.md +0 -36
  17. package/prompts/main/editing_pattern.md +0 -13
  18. package/prompts/main/error_handling.md +0 -6
  19. package/prompts/main/exploration_pattern.md +0 -21
  20. package/prompts/main/intro.md +0 -1
  21. package/prompts/main/obsidian.md +0 -16
  22. package/prompts/main/obsidian_project.md +0 -79
  23. package/prompts/main/professional_objectivity.md +0 -3
  24. package/prompts/main/targeted_searching.md +0 -10
  25. package/prompts/main/task_lists_pattern.md +0 -8
  26. package/prompts/main/temp_folder.md +0 -9
  27. package/prompts/main/think_before_acting.md +0 -10
  28. package/prompts/main/tone_and_style.md +0 -4
  29. package/prompts/main/tool_preferences.md +0 -24
  30. package/prompts/main/trust_subagent_context.md +0 -21
  31. package/prompts/main/when_to_use_sub_agent.md +0 -7
  32. package/prompts/micro/ask_questions.md +0 -1
  33. package/prompts/micro/batch_independent_calls.md +0 -1
  34. package/prompts/micro/casual_interactions.md +0 -1
  35. package/prompts/micro/code_references.md +0 -1
  36. package/prompts/micro/communication_style.md +0 -1
  37. package/prompts/micro/context_reliability.md +0 -1
  38. package/prompts/micro/conversational_tool_calling.md +0 -1
  39. package/prompts/micro/editing_pattern.md +0 -1
  40. package/prompts/micro/error_handling.md +0 -1
  41. package/prompts/micro/exploration_pattern.md +0 -1
  42. package/prompts/micro/intro.md +0 -1
  43. package/prompts/micro/obsidian.md +0 -4
  44. package/prompts/micro/obsidian_project.md +0 -5
  45. package/prompts/micro/professional_objectivity.md +0 -1
  46. package/prompts/micro/targeted_searching.md +0 -1
  47. package/prompts/micro/task_lists_pattern.md +0 -1
  48. package/prompts/micro/temp_folder.md +0 -1
  49. package/prompts/micro/think_before_acting.md +0 -5
  50. package/prompts/micro/tone_and_style.md +0 -1
  51. package/prompts/micro/tool_preferences.md +0 -1
  52. package/prompts/micro/trust_subagent_context.md +0 -1
  53. package/prompts/micro/when_to_use_sub_agent.md +0 -1
  54. package/requirements.txt +0 -9
  55. package/src/__init__.py +0 -11
  56. package/src/core/__init__.py +0 -1
  57. package/src/core/agentic.py +0 -985
  58. package/src/core/chat_manager.py +0 -1564
  59. package/src/core/config_manager.py +0 -253
  60. package/src/core/cron.py +0 -582
  61. package/src/core/cron_allowlist.py +0 -118
  62. package/src/core/memory.py +0 -145
  63. package/src/core/retry.py +0 -71
  64. package/src/core/sub_agent.py +0 -326
  65. package/src/core/tool_approval.py +0 -220
  66. package/src/core/tool_feedback.py +0 -778
  67. package/src/exceptions.py +0 -79
  68. package/src/llm/__init__.py +0 -1
  69. package/src/llm/client.py +0 -171
  70. package/src/llm/config.py +0 -492
  71. package/src/llm/prompts.py +0 -489
  72. package/src/llm/providers.py +0 -436
  73. package/src/llm/streaming.py +0 -163
  74. package/src/llm/token_tracker.py +0 -384
  75. package/src/tools/__init__.py +0 -212
  76. package/src/tools/constants.py +0 -59
  77. package/src/tools/create_file.py +0 -136
  78. package/src/tools/directory.py +0 -389
  79. package/src/tools/edit.py +0 -545
  80. package/src/tools/file_reader.py +0 -322
  81. package/src/tools/helpers/__init__.py +0 -105
  82. package/src/tools/helpers/base.py +0 -550
  83. package/src/tools/helpers/converters.py +0 -44
  84. package/src/tools/helpers/file_helpers.py +0 -189
  85. package/src/tools/helpers/formatters.py +0 -411
  86. package/src/tools/helpers/loader.py +0 -231
  87. package/src/tools/helpers/parallel_executor.py +0 -231
  88. package/src/tools/helpers/path_resolver.py +0 -232
  89. package/src/tools/helpers/plugin_manifest.py +0 -156
  90. package/src/tools/obsidian.py +0 -96
  91. package/src/tools/review_sub_agent.py +0 -189
  92. package/src/tools/rg_search.py +0 -460
  93. package/src/tools/search_plugins.py +0 -109
  94. package/src/tools/select_option.py +0 -600
  95. package/src/tools/shell.py +0 -302
  96. package/src/tools/sub_agent.py +0 -139
  97. package/src/tools/task_list.py +0 -269
  98. package/src/tools/web_search.py +0 -61
  99. package/src/ui/__init__.py +0 -1
  100. package/src/ui/banner.py +0 -87
  101. package/src/ui/commands.py +0 -2809
  102. package/src/ui/displays.py +0 -214
  103. package/src/ui/loader.py +0 -284
  104. package/src/ui/main.py +0 -647
  105. package/src/ui/prompt_utils.py +0 -113
  106. package/src/ui/setting_selector.py +0 -590
  107. package/src/ui/setup_wizard.py +0 -294
  108. package/src/ui/sub_agent_panel.py +0 -234
  109. package/src/ui/tool_confirmation.py +0 -215
  110. package/src/utils/__init__.py +0 -1
  111. package/src/utils/citation_parser.py +0 -199
  112. package/src/utils/editor.py +0 -158
  113. package/src/utils/gitignore_filter.py +0 -149
  114. package/src/utils/logger.py +0 -254
  115. package/src/utils/paths.py +0 -30
  116. package/src/utils/result_parsers.py +0 -108
  117. package/src/utils/safe_commands.py +0 -243
  118. package/src/utils/settings.py +0 -191
  119. package/src/utils/user_message_logger.py +0 -120
  120. package/src/utils/validation.py +0 -191
  121. package/src/utils/web_search.py +0 -173
package/src/llm/config.py DELETED
@@ -1,492 +0,0 @@
1
- import os
2
- import platform
3
- from pathlib import Path
4
- import yaml
5
-
6
- # Provider selection - loaded from config (see after PROVIDER_REGISTRY definition)
7
-
8
- def resolve_config_path() -> Path:
9
- """Resolve config.yaml path.
10
-
11
- Resolution order:
12
- 1. BONE_CONFIG_PATH — explicit user config path (set by npm wrapper)
13
- 2. ~/.bone/config.yaml — user home dotfile (dev and npm installs)
14
- """
15
- _user_cfg = os.environ.get('BONE_CONFIG_PATH')
16
- if _user_cfg:
17
- return Path(_user_cfg).resolve()
18
- return Path.home() / '.bone' / 'config.yaml'
19
-
20
- # Module-level config path (single source of truth)
21
- CONFIG_PATH = resolve_config_path()
22
-
23
- # Environment variable names for API keys (env vars take precedence over config file)
24
- ENV_API_KEYS = {
25
- 'ANTHROPIC_API_KEY': os.environ.get('ANTHROPIC_API_KEY'),
26
- 'OPENAI_API_KEY': os.environ.get('OPENAI_API_KEY'),
27
- 'GLM_PLAN_API_KEY': os.environ.get('GLM_PLAN_API_KEY'),
28
- 'GLM_API_KEY': os.environ.get('GLM_API_KEY'),
29
- 'GEMINI_API_KEY': os.environ.get('GEMINI_API_KEY'),
30
- 'OPENROUTER_API_KEY': os.environ.get('OPENROUTER_API_KEY'),
31
- 'KIMI_API_KEY': os.environ.get('KIMI_API_KEY'),
32
- 'MINIMAX_PLAN_API_KEY': os.environ.get('MINIMAX_PLAN_API_KEY'),
33
- 'MINIMAX_API_KEY': os.environ.get('MINIMAX_API_KEY'),
34
- 'BONE_PROXY_API_KEY': os.environ.get('BONE_PROXY_API_KEY'),
35
- }
36
-
37
- # Detect platform for llama.cpp paths
38
- _IS_WINDOWS = platform.system() == "Windows"
39
- _IS_LINUX = platform.system() == "Linux"
40
-
41
- # Set llama.cpp paths based on platform
42
- if _IS_WINDOWS:
43
- _LLAMA_SERVER_NAME = "llama-server.exe"
44
- _LLAMA_BUILD_DIR = "build"
45
- elif _IS_LINUX:
46
- _LLAMA_SERVER_NAME = "llama-server"
47
- _LLAMA_BUILD_DIR = "build-linux"
48
- else:
49
- # Fallback for macOS or other platforms
50
- _LLAMA_SERVER_NAME = "llama-server"
51
- _LLAMA_BUILD_DIR = "build"
52
-
53
- def _load_config():
54
- """Load config from YAML file, with environment variable overrides for API keys.
55
-
56
- Environment variables take precedence over values in config.yaml.
57
- """
58
- config_path = resolve_config_path()
59
- if not config_path.exists():
60
- return {}
61
- try:
62
- config = yaml.safe_load(config_path.read_text(encoding="utf-8-sig")) or {}
63
- except yaml.YAMLError:
64
- config = {}
65
-
66
- # Override API keys from environment variables (env vars take precedence)
67
- for key, env_value in ENV_API_KEYS.items():
68
- if env_value: # Only override if env var is set and non-empty
69
- config[key] = env_value
70
-
71
- return config
72
-
73
-
74
- _CONFIG = _load_config()
75
-
76
- # Cache for provider registry (built once at module load)
77
- _provider_registry_cache = None
78
- _cached_provider = None
79
-
80
-
81
- def get_model_cost(model_name: str, config: dict | None = None) -> tuple[float, float]:
82
- """Get model-specific (cost_in, cost_out) per 1M tokens from MODEL_PRICES.
83
-
84
- Shared utility — used by both the provider registry builder and config_manager.
85
- Returns (0.0, 0.0) for unknown models.
86
-
87
- Args:
88
- model_name: Model name to look up.
89
- config: Optional config dict (defaults to _CONFIG). Pass a fresh config
90
- after runtime edits to get up-to-date pricing.
91
- """
92
- model_prices = (config if config is not None else _CONFIG).get("MODEL_PRICES", {})
93
- if model_name in model_prices:
94
- mc = model_prices[model_name]
95
- return float(mc.get("cost_in", 0.0)), float(mc.get("cost_out", 0.0))
96
- return 0.0, 0.0
97
-
98
-
99
- def _model_cost(model_config_key):
100
- """Return {cost_in, cost_out} dict for use in provider registry via **spread.
101
-
102
- Reads from module-level _CONFIG (not an injected config). Safe because
103
- reload_config() invalidates the provider registry cache, forcing a rebuild.
104
- """
105
- ci, co = get_model_cost(_CONFIG.get(model_config_key, ""))
106
- return {"cost_in": ci, "cost_out": co}
107
-
108
-
109
- def _get_provider_registry():
110
- """Build PROVIDER_REGISTRY from current config (cached)."""
111
- global _provider_registry_cache
112
- if _provider_registry_cache is not None:
113
- return _provider_registry_cache
114
-
115
- _provider_registry_cache = {
116
- "local": {
117
- "type": "local",
118
- "api_key": None,
119
- "model": _CONFIG.get("LOCAL_MODEL_PATH", ""),
120
- "api_model": "model",
121
- "api_base": "http://127.0.0.1:8080",
122
- "endpoint": "/v1/chat/completions",
123
- "error_prefix": "local server",
124
- "config_keys": {
125
- "LOCAL_MODEL_PATH": "",
126
- "LOCAL_SERVER_PATH": str(
127
- Path(__file__).resolve().parents[2] /
128
- f"llama.cpp/{_LLAMA_BUILD_DIR}/bin/{_LLAMA_SERVER_NAME}"
129
- ),
130
- },
131
- "extra": {
132
- "host": "127.0.0.1",
133
- "port": 8080,
134
- },
135
- "default_temperature": 0.1,
136
- "default_top_p": 0.9,
137
- "allow_top_p": True,
138
- "allow_temperature": True,
139
- "cost_in": 0.0,
140
- "cost_out": 0.0
141
- },
142
- "openrouter": {
143
- "type": "api",
144
- "api_key": _CONFIG.get("OPENROUTER_API_KEY", ""),
145
- "model": _CONFIG.get("OPENROUTER_MODEL", ""),
146
- "api_base": _CONFIG.get("OPENROUTER_API_BASE", "https://openrouter.ai/api/v1"),
147
- "endpoint": "/chat/completions",
148
- "error_prefix": "OpenRouter",
149
- "headers_extra": {
150
- "HTTP-Referer": "http://localhost:8080",
151
- "X-Title": "Chat App"
152
- },
153
- "config_keys": {
154
- "OPENROUTER_API_KEY": "",
155
- "OPENROUTER_MODEL": "",
156
- "OPENROUTER_API_BASE": "https://openrouter.ai/api/v1",
157
- },
158
- "default_temperature": 0.1,
159
- "default_top_p": 0.9,
160
- "allow_top_p": True,
161
- "allow_temperature": True,
162
- **_model_cost("OPENROUTER_MODEL"),
163
- },
164
- "glm_plan": {
165
- "type": "api",
166
- "api_key": _CONFIG.get("GLM_PLAN_API_KEY", ""),
167
- "model": _CONFIG.get("GLM_PLAN_MODEL", ""),
168
- "api_base": _CONFIG.get("GLM_PLAN_API_BASE", "https://open.bigmodel.cn/api/paas/v4"),
169
- "endpoint": "/chat/completions",
170
- "error_prefix": "GLM",
171
- "config_keys": {
172
- "GLM_PLAN_API_KEY": "",
173
- "GLM_PLAN_MODEL": "",
174
- "GLM_PLAN_API_BASE": "https://open.bigmodel.cn/api/paas/v4",
175
- },
176
- "default_temperature": 0.1,
177
- "default_top_p": 0.9,
178
- "allow_top_p": True,
179
- "allow_temperature": True,
180
- **_model_cost("GLM_PLAN_MODEL"),
181
- },
182
- "glm": {
183
- "type": "api",
184
- "api_key": _CONFIG.get("GLM_API_KEY", ""),
185
- "model": _CONFIG.get("GLM_MODEL", ""),
186
- "api_base": _CONFIG.get("GLM_API_BASE", "https://open.bigmodel.cn/api/paas/v4"),
187
- "endpoint": "/chat/completions",
188
- "error_prefix": "GLM",
189
- "config_keys": {
190
- "GLM_API_KEY": "",
191
- "GLM_MODEL": "",
192
- "GLM_API_BASE": "https://open.bigmodel.cn/api/paas/v4",
193
- },
194
- "default_temperature": 0.1,
195
- "default_top_p": 0.9,
196
- "allow_top_p": True,
197
- "allow_temperature": True,
198
- **_model_cost("GLM_MODEL"),
199
- },
200
- "openai": {
201
- "type": "api",
202
- "api_key": _CONFIG.get("OPENAI_API_KEY", ""),
203
- "model": _CONFIG.get("OPENAI_MODEL", ""),
204
- "api_base": _CONFIG.get("OPENAI_API_BASE", "https://api.openai.com/v1"),
205
- "endpoint": "/chat/completions",
206
- "error_prefix": "OpenAI",
207
- "config_keys": {
208
- "OPENAI_API_KEY": "",
209
- "OPENAI_MODEL": "",
210
- "OPENAI_API_BASE": "https://api.openai.com/v1",
211
- },
212
- "default_temperature": 0.1,
213
- "default_top_p": 0.9,
214
- "allow_top_p": False,
215
- "allow_temperature": False,
216
- **_model_cost("OPENAI_MODEL"),
217
- },
218
- "gemini": {
219
- "type": "api",
220
- "api_key": _CONFIG.get("GEMINI_API_KEY", ""),
221
- "model": _CONFIG.get("GEMINI_MODEL", ""),
222
- "api_base": _CONFIG.get("GEMINI_API_BASE", "https://generativelanguage.googleapis.com/v1beta"),
223
- "endpoint": "/chat/completions",
224
- "error_prefix": "Gemini",
225
- "config_keys": {
226
- "GEMINI_API_KEY": "",
227
- "GEMINI_MODEL": "",
228
- "GEMINI_API_BASE": "https://generativelanguage.googleapis.com/v1beta",
229
- },
230
- "default_temperature": 0.1,
231
- "default_top_p": 0.9,
232
- "allow_top_p": True,
233
- "allow_temperature": True,
234
- **_model_cost("GEMINI_MODEL"),
235
- },
236
- "minimax_plan": {
237
- "type": "api",
238
- "api_key": _CONFIG.get("MINIMAX_PLAN_API_KEY", ""),
239
- "model": _CONFIG.get("MINIMAX_PLAN_MODEL", ""),
240
- "api_base": _CONFIG.get("MINIMAX_PLAN_API_BASE", "https://api.minimax.io/anthropic/v1"),
241
- "endpoint": "/messages",
242
- "error_prefix": "MiniMax",
243
- "config_keys": {
244
- "MINIMAX_PLAN_API_KEY": "",
245
- "MINIMAX_PLAN_MODEL": "",
246
- "MINIMAX_PLAN_API_BASE": "https://api.minimax.io/anthropic/v1",
247
- },
248
- "default_temperature": 0.1,
249
- "default_top_p": 0.9,
250
- "allow_top_p": False,
251
- "allow_temperature": True,
252
- "max_tokens": 4096,
253
- **_model_cost("MINIMAX_PLAN_MODEL"),
254
- },
255
- "minimax": {
256
- "type": "api",
257
- "api_key": _CONFIG.get("MINIMAX_API_KEY", ""),
258
- "model": _CONFIG.get("MINIMAX_MODEL", ""),
259
- "api_base": _CONFIG.get("MINIMAX_API_BASE", "https://api.minimax.io/anthropic/v1"),
260
- "endpoint": "/messages",
261
- "error_prefix": "MiniMax",
262
- "config_keys": {
263
- "MINIMAX_API_KEY": "",
264
- "MINIMAX_MODEL": "",
265
- "MINIMAX_API_BASE": "https://api.minimax.io/anthropic/v1",
266
- },
267
- "default_temperature": 0.1,
268
- "default_top_p": 0.9,
269
- "allow_top_p": False,
270
- "allow_temperature": True,
271
- "max_tokens": 4096,
272
- **_model_cost("MINIMAX_MODEL"),
273
- },
274
- "anthropic": {
275
- "type": "api",
276
- "api_key": _CONFIG.get("ANTHROPIC_API_KEY", ""),
277
- "model": _CONFIG.get("ANTHROPIC_MODEL", ""),
278
- "api_base": _CONFIG.get("ANTHROPIC_API_BASE", "https://api.anthropic.com/v1"),
279
- "endpoint": "/messages",
280
- "error_prefix": "Anthropic",
281
- "headers_extra": {
282
- "anthropic-version": "2023-06-01"
283
- },
284
- "config_keys": {
285
- "ANTHROPIC_API_KEY": "",
286
- "ANTHROPIC_MODEL": "",
287
- "ANTHROPIC_API_BASE": "https://api.anthropic.com/v1",
288
- },
289
- "default_temperature": 0.1,
290
- "default_top_p": 0.9,
291
- "allow_top_p": False,
292
- "allow_temperature": True,
293
- "max_tokens": 4096,
294
- **_model_cost("ANTHROPIC_MODEL"),
295
- },
296
- "kimi": {
297
- "type": "api",
298
- "api_key": _CONFIG.get("KIMI_API_KEY", ""),
299
- "model": _CONFIG.get("KIMI_MODEL", ""),
300
- "api_base": _CONFIG.get("KIMI_API_BASE", "https://api.moonshot.cn/v1"),
301
- "endpoint": "/chat/completions",
302
- "error_prefix": "Kimi",
303
- "config_keys": {
304
- "KIMI_API_KEY": "",
305
- "KIMI_MODEL": "",
306
- "KIMI_API_BASE": "https://api.moonshot.cn/v1",
307
- },
308
- "default_temperature": 0.1,
309
- "default_top_p": 0.9,
310
- "allow_top_p": True,
311
- "allow_temperature": True,
312
- **_model_cost("KIMI_MODEL"),
313
- },
314
- "bone": {
315
- "type": "api",
316
- "api_key": _CONFIG.get("BONE_PROXY_API_KEY", ""),
317
- "model": _CONFIG.get("BONE_PROXY_MODEL", "openai/gpt-4o-mini"),
318
- "api_base": _CONFIG.get("BONE_PROXY_API_BASE", "https://api.vmcode.dev"),
319
- "endpoint": "/v1/chat/completions",
320
- "error_prefix": "bone-agent Proxy",
321
- "config_keys": {
322
- "BONE_PROXY_API_KEY": "",
323
- "BONE_PROXY_MODEL": "openai/gpt-4o-mini",
324
- "BONE_PROXY_API_BASE": "https://api.vmcode.dev",
325
- },
326
- "default_temperature": 0.1,
327
- "default_top_p": 0.9,
328
- "allow_top_p": True,
329
- "allow_temperature": True,
330
- **_model_cost("BONE_PROXY_MODEL"),
331
- },
332
- }
333
- return _provider_registry_cache
334
-
335
-
336
- def _get_provider():
337
- """Get the current provider from config (cached)."""
338
- global _cached_provider
339
- if _cached_provider is not None:
340
- return _cached_provider
341
-
342
- last_provider = _CONFIG.get("LAST_PROVIDER")
343
- if last_provider and last_provider in _provider_registry_cache:
344
- _cached_provider = last_provider
345
- return _cached_provider
346
- _cached_provider = "glm_plan"
347
- return _cached_provider
348
-
349
-
350
- def reload_config():
351
- """Reload config from disk and invalidate caches.
352
-
353
- Reloads both the config.yaml file and environment variables.
354
-
355
- Note: This is a manual operation - call after config changes.
356
- """
357
- global _CONFIG, _provider_registry_cache, _cached_provider, PROVIDER_REGISTRY, LLM_PROVIDER, STATUS_BAR_SETTINGS, MEMORY_SETTINGS
358
- _CONFIG = _load_config()
359
- _provider_registry_cache = None
360
- _cached_provider = None
361
- # Rebuild module-level variables
362
- PROVIDER_REGISTRY = _get_provider_registry()
363
- LLM_PROVIDER = _get_provider()
364
- # Rebuild status bar settings
365
- STATUS_BAR_SETTINGS = _build_status_bar_settings()
366
- # Rebuild memory settings
367
- MEMORY_SETTINGS = _build_memory_settings()
368
-
369
-
370
- def _build_status_bar_settings():
371
- """Build STATUS_BAR_SETTINGS dict from current _CONFIG."""
372
- sbs = _CONFIG.get("STATUS_BAR_SETTINGS", {})
373
- return {
374
- "show_curr_tokens": sbs.get("show_curr_tokens", True),
375
- "show_in_tokens": sbs.get("show_in_tokens", True),
376
- "show_out_tokens": sbs.get("show_out_tokens", True),
377
- "show_total_tokens": sbs.get("show_total_tokens", True),
378
- "show_cost": sbs.get("show_cost", True),
379
- }
380
-
381
-
382
- def _build_memory_settings():
383
- """Build MEMORY_SETTINGS dict from current _CONFIG."""
384
- ms = _CONFIG.get("MEMORY_SETTINGS", {})
385
- return {
386
- "enabled": ms.get("enabled", True),
387
- }
388
-
389
-
390
- def update_memory_settings(settings_dict):
391
- """Update MEMORY_SETTINGS at runtime.
392
-
393
- Returns:
394
- Updated MEMORY_SETTINGS dict
395
- """
396
- global MEMORY_SETTINGS
397
- MEMORY_SETTINGS.update(settings_dict)
398
- return MEMORY_SETTINGS
399
-
400
-
401
- def update_status_bar_settings(settings_dict):
402
- """Update STATUS_BAR_SETTINGS at runtime.
403
-
404
- Args:
405
- settings_dict: Dict of settings to update (e.g., {"show_cost": False})
406
-
407
- Returns:
408
- Updated STATUS_BAR_SETTINGS dict
409
- """
410
- global STATUS_BAR_SETTINGS
411
- STATUS_BAR_SETTINGS.update(settings_dict)
412
- return STATUS_BAR_SETTINGS
413
-
414
-
415
- def get_providers():
416
- """Get list of available providers.
417
-
418
- Returns:
419
- list: List of provider names from PROVIDER_REGISTRY.
420
- """
421
- return list(PROVIDER_REGISTRY.keys())
422
-
423
-
424
- # ============================================================================
425
- # PROVIDER REGISTRY - Centralized provider configuration
426
- # ============================================================================
427
-
428
- # Build provider registry and export as module-level constants (loaded once)
429
- PROVIDER_REGISTRY = _get_provider_registry()
430
- LLM_PROVIDER = _get_provider()
431
-
432
-
433
- __all__ = [
434
- "CONFIG_PATH",
435
- "PROVIDER_REGISTRY",
436
- "get_providers",
437
- "get_model_cost",
438
- "LLM_PROVIDER",
439
- "TOOLS_ENABLED",
440
- "TOOLS_REQUIRE_CONFIRMATION",
441
- "WEB_SEARCH_REQUIRE_CONFIRMATION",
442
- "APPROVE_MODES",
443
- "APPROVE_MODE_LABELS",
444
-
445
- "get_provider_config",
446
- "generate_config_template",
447
- "reload_config",
448
- "STATUS_BAR_SETTINGS",
449
- "update_status_bar_settings",
450
- "MEMORY_SETTINGS",
451
- "update_memory_settings",
452
- ]
453
-
454
-
455
- def generate_config_template():
456
- """Generate default template for config.json from provider registry."""
457
- template = {}
458
- for provider, config in PROVIDER_REGISTRY.items():
459
- if "config_keys" in config:
460
- template.update(config["config_keys"])
461
- return template
462
-
463
- # Tooling configuration
464
- TOOLS_ENABLED = True
465
- TOOLS_REQUIRE_CONFIRMATION = False
466
- WEB_SEARCH_REQUIRE_CONFIRMATION = False
467
-
468
- # Status bar configuration
469
- STATUS_BAR_SETTINGS = _build_status_bar_settings()
470
-
471
- # Memory configuration
472
- MEMORY_SETTINGS = _build_memory_settings()
473
-
474
- # Tool approval modes
475
- APPROVE_MODES = ("safe", "accept_edits", "danger")
476
- CYCLEABLE_APPROVE_MODES = ("safe", "accept_edits")
477
- APPROVE_MODE_LABELS = {
478
- "safe": "Safe",
479
- "accept_edits": "Accept Edits",
480
- "danger": "Danger",
481
- }
482
-
483
- def get_provider_config(provider: str):
484
- """Retrieve the configuration dictionary for a given provider.
485
-
486
- Args:
487
- provider (str): Provider name (e.g., 'local', 'openrouter', 'glm', 'openai').
488
-
489
- Returns:
490
- dict: Provider config from the PROVIDER_REGISTRY.
491
- """
492
- return PROVIDER_REGISTRY.get(provider, {})