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.
- package/bin/bone.js +39 -0
- package/package.json +25 -39
- package/LICENSE +0 -21
- package/README.md +0 -184
- package/bin/npm-wrapper.js +0 -235
- package/bin/rg +0 -0
- package/bin/rg.exe +0 -0
- package/config.yaml.example +0 -141
- package/prompts/main/ask_questions.md +0 -31
- package/prompts/main/batch_independent_calls.md +0 -5
- package/prompts/main/casual_interactions.md +0 -11
- package/prompts/main/code_references.md +0 -8
- package/prompts/main/communication_style.md +0 -12
- package/prompts/main/context_reliability.md +0 -12
- package/prompts/main/conversational_tool_calling.md +0 -15
- package/prompts/main/dream.md +0 -36
- package/prompts/main/editing_pattern.md +0 -13
- package/prompts/main/error_handling.md +0 -6
- package/prompts/main/exploration_pattern.md +0 -21
- package/prompts/main/intro.md +0 -1
- package/prompts/main/obsidian.md +0 -16
- package/prompts/main/obsidian_project.md +0 -79
- package/prompts/main/professional_objectivity.md +0 -3
- package/prompts/main/targeted_searching.md +0 -10
- package/prompts/main/task_lists_pattern.md +0 -8
- package/prompts/main/temp_folder.md +0 -9
- package/prompts/main/think_before_acting.md +0 -10
- package/prompts/main/tone_and_style.md +0 -4
- package/prompts/main/tool_preferences.md +0 -24
- package/prompts/main/trust_subagent_context.md +0 -21
- package/prompts/main/when_to_use_sub_agent.md +0 -7
- package/prompts/micro/ask_questions.md +0 -1
- package/prompts/micro/batch_independent_calls.md +0 -1
- package/prompts/micro/casual_interactions.md +0 -1
- package/prompts/micro/code_references.md +0 -1
- package/prompts/micro/communication_style.md +0 -1
- package/prompts/micro/context_reliability.md +0 -1
- package/prompts/micro/conversational_tool_calling.md +0 -1
- package/prompts/micro/editing_pattern.md +0 -1
- package/prompts/micro/error_handling.md +0 -1
- package/prompts/micro/exploration_pattern.md +0 -1
- package/prompts/micro/intro.md +0 -1
- package/prompts/micro/obsidian.md +0 -4
- package/prompts/micro/obsidian_project.md +0 -5
- package/prompts/micro/professional_objectivity.md +0 -1
- package/prompts/micro/targeted_searching.md +0 -1
- package/prompts/micro/task_lists_pattern.md +0 -1
- package/prompts/micro/temp_folder.md +0 -1
- package/prompts/micro/think_before_acting.md +0 -5
- package/prompts/micro/tone_and_style.md +0 -1
- package/prompts/micro/tool_preferences.md +0 -1
- package/prompts/micro/trust_subagent_context.md +0 -1
- package/prompts/micro/when_to_use_sub_agent.md +0 -1
- package/requirements.txt +0 -9
- package/src/__init__.py +0 -11
- package/src/core/__init__.py +0 -1
- package/src/core/agentic.py +0 -985
- package/src/core/chat_manager.py +0 -1564
- package/src/core/config_manager.py +0 -253
- package/src/core/cron.py +0 -582
- package/src/core/cron_allowlist.py +0 -118
- package/src/core/memory.py +0 -145
- package/src/core/retry.py +0 -71
- package/src/core/sub_agent.py +0 -326
- package/src/core/tool_approval.py +0 -220
- package/src/core/tool_feedback.py +0 -778
- package/src/exceptions.py +0 -79
- package/src/llm/__init__.py +0 -1
- package/src/llm/client.py +0 -171
- package/src/llm/config.py +0 -492
- package/src/llm/prompts.py +0 -489
- package/src/llm/providers.py +0 -436
- package/src/llm/streaming.py +0 -163
- package/src/llm/token_tracker.py +0 -384
- package/src/tools/__init__.py +0 -212
- package/src/tools/constants.py +0 -59
- package/src/tools/create_file.py +0 -136
- package/src/tools/directory.py +0 -389
- package/src/tools/edit.py +0 -545
- package/src/tools/file_reader.py +0 -322
- package/src/tools/helpers/__init__.py +0 -105
- package/src/tools/helpers/base.py +0 -550
- package/src/tools/helpers/converters.py +0 -44
- package/src/tools/helpers/file_helpers.py +0 -189
- package/src/tools/helpers/formatters.py +0 -411
- package/src/tools/helpers/loader.py +0 -231
- package/src/tools/helpers/parallel_executor.py +0 -231
- package/src/tools/helpers/path_resolver.py +0 -232
- package/src/tools/helpers/plugin_manifest.py +0 -156
- package/src/tools/obsidian.py +0 -96
- package/src/tools/review_sub_agent.py +0 -189
- package/src/tools/rg_search.py +0 -460
- package/src/tools/search_plugins.py +0 -109
- package/src/tools/select_option.py +0 -600
- package/src/tools/shell.py +0 -302
- package/src/tools/sub_agent.py +0 -139
- package/src/tools/task_list.py +0 -269
- package/src/tools/web_search.py +0 -61
- package/src/ui/__init__.py +0 -1
- package/src/ui/banner.py +0 -87
- package/src/ui/commands.py +0 -2809
- package/src/ui/displays.py +0 -214
- package/src/ui/loader.py +0 -284
- package/src/ui/main.py +0 -647
- package/src/ui/prompt_utils.py +0 -113
- package/src/ui/setting_selector.py +0 -590
- package/src/ui/setup_wizard.py +0 -294
- package/src/ui/sub_agent_panel.py +0 -234
- package/src/ui/tool_confirmation.py +0 -215
- package/src/utils/__init__.py +0 -1
- package/src/utils/citation_parser.py +0 -199
- package/src/utils/editor.py +0 -158
- package/src/utils/gitignore_filter.py +0 -149
- package/src/utils/logger.py +0 -254
- package/src/utils/paths.py +0 -30
- package/src/utils/result_parsers.py +0 -108
- package/src/utils/safe_commands.py +0 -243
- package/src/utils/settings.py +0 -191
- package/src/utils/user_message_logger.py +0 -120
- package/src/utils/validation.py +0 -191
- package/src/utils/web_search.py +0 -173
package/src/exceptions.py
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"""Custom exception hierarchy for bone-agent."""
|
|
2
|
-
|
|
3
|
-
class BoneAgentError(Exception):
|
|
4
|
-
"""Base exception for all bone-agent application errors.
|
|
5
|
-
|
|
6
|
-
All custom exceptions should inherit from this class.
|
|
7
|
-
Provides consistent error handling and allows catching
|
|
8
|
-
all bone-agent-specific errors with a single except clause.
|
|
9
|
-
"""
|
|
10
|
-
def __init__(self, message: str, *, details: dict = None):
|
|
11
|
-
"""Initialize exception with optional details.
|
|
12
|
-
|
|
13
|
-
Args:
|
|
14
|
-
message: Human-readable error message
|
|
15
|
-
details: Optional dictionary with additional error context
|
|
16
|
-
"""
|
|
17
|
-
super().__init__(message)
|
|
18
|
-
self.details = details or {}
|
|
19
|
-
|
|
20
|
-
def __str__(self):
|
|
21
|
-
base_msg = super().__str__()
|
|
22
|
-
if self.details:
|
|
23
|
-
# Skip multi-line values from the compact string representation
|
|
24
|
-
# (they're included separately in detailed error formatting)
|
|
25
|
-
single_line_details = {k: v for k, v in self.details.items() if "\n" not in str(v)}
|
|
26
|
-
if single_line_details:
|
|
27
|
-
details_str = ", ".join(f"{k}={v}" for k, v in single_line_details.items())
|
|
28
|
-
return f"{base_msg} ({details_str})"
|
|
29
|
-
return base_msg
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class ConfigurationError(BoneAgentError):
|
|
33
|
-
"""Raised when configuration is invalid, missing, or cannot be loaded."""
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class LLMError(BoneAgentError):
|
|
38
|
-
"""Raised when LLM API communication fails or returns unexpected data."""
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
class LLMConnectionError(LLMError):
|
|
43
|
-
"""Raised when network connection to LLM provider fails."""
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class LLMResponseError(LLMError):
|
|
48
|
-
"""Raised when LLM response is malformed or invalid."""
|
|
49
|
-
pass
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
class ToolExecutionError(BoneAgentError):
|
|
53
|
-
"""Raised when tool execution fails."""
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class CommandExecutionError(ToolExecutionError):
|
|
58
|
-
"""Raised when shell command execution fails."""
|
|
59
|
-
pass
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class FileEditError(ToolExecutionError):
|
|
63
|
-
"""Raised when file edit operation fails."""
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class ValidationError(BoneAgentError):
|
|
68
|
-
"""Raised when input validation fails."""
|
|
69
|
-
pass
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
class PathValidationError(ValidationError):
|
|
73
|
-
"""Raised when path validation fails (blocked by gitignore, etc.)."""
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class CommandValidationError(ValidationError):
|
|
78
|
-
"""Raised when command validation fails (dangerous operators, etc.)."""
|
|
79
|
-
pass
|
package/src/llm/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""LLM integration layer for bone-agent."""
|
package/src/llm/client.py
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
"""LLM client for making API requests to various providers."""
|
|
2
|
-
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
import requests
|
|
6
|
-
from llm import config as config_module
|
|
7
|
-
from llm.config import PROVIDER_REGISTRY, get_provider_config, get_providers
|
|
8
|
-
from llm.providers import get_handler
|
|
9
|
-
from exceptions import LLMConnectionError, LLMResponseError, ConfigurationError
|
|
10
|
-
from utils.validation import validate_api_url
|
|
11
|
-
|
|
12
|
-
logger = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
# Connection/read timeouts (seconds)
|
|
15
|
-
_CONNECT_TIMEOUT = 10
|
|
16
|
-
_READ_TIMEOUT = 120
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class StreamWrapper:
|
|
20
|
-
"""Wraps streaming response generator with cleanup capability."""
|
|
21
|
-
|
|
22
|
-
def __init__(self, response, generator):
|
|
23
|
-
self._response = response
|
|
24
|
-
self._generator = generator
|
|
25
|
-
|
|
26
|
-
def __iter__(self):
|
|
27
|
-
return self
|
|
28
|
-
|
|
29
|
-
def __next__(self):
|
|
30
|
-
return next(self._generator)
|
|
31
|
-
|
|
32
|
-
def close(self):
|
|
33
|
-
"""Close underlying HTTP connection."""
|
|
34
|
-
if self._response:
|
|
35
|
-
self._response.close()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class LLMClient:
|
|
39
|
-
def __init__(self, provider=None):
|
|
40
|
-
"""Initialize LLM client.
|
|
41
|
-
|
|
42
|
-
Args:
|
|
43
|
-
provider: Provider name. If None, uses global LLM_PROVIDER from config.
|
|
44
|
-
"""
|
|
45
|
-
self.provider = provider or config_module.LLM_PROVIDER
|
|
46
|
-
self.handler = get_handler(self.provider)
|
|
47
|
-
self.config = self._get_provider_config()
|
|
48
|
-
|
|
49
|
-
@property
|
|
50
|
-
def model(self) -> str:
|
|
51
|
-
"""Return configured model name, if any."""
|
|
52
|
-
return str(self.config.get("payload", {}).get("model") or "")
|
|
53
|
-
|
|
54
|
-
def _get_provider_config(self):
|
|
55
|
-
"""Build provider config from PROVIDER_REGISTRY."""
|
|
56
|
-
registry = get_provider_config(self.provider)
|
|
57
|
-
if not registry:
|
|
58
|
-
raise ConfigurationError(f"Unknown provider: {self.provider}")
|
|
59
|
-
|
|
60
|
-
# Build headers using handler
|
|
61
|
-
headers = self.handler.build_headers(registry)
|
|
62
|
-
|
|
63
|
-
# Build payload with model name
|
|
64
|
-
payload = {}
|
|
65
|
-
model_name = registry.get("api_model") or registry.get("model")
|
|
66
|
-
if model_name:
|
|
67
|
-
payload["model"] = model_name
|
|
68
|
-
|
|
69
|
-
url = f"{registry['api_base']}{registry['endpoint']}"
|
|
70
|
-
valid, err = validate_api_url(url)
|
|
71
|
-
if not valid:
|
|
72
|
-
raise ConfigurationError(
|
|
73
|
-
f"Insecure API endpoint for provider '{self.provider}': {err}"
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
"url": url,
|
|
78
|
-
"headers": headers,
|
|
79
|
-
"payload": payload,
|
|
80
|
-
"error_prefix": registry["error_prefix"],
|
|
81
|
-
"registry": registry
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
def chat_completion(self, messages, stream=True, tools=None):
|
|
85
|
-
"""Make a chat completion request.
|
|
86
|
-
|
|
87
|
-
Args:
|
|
88
|
-
messages: List of message dicts
|
|
89
|
-
stream: Whether to stream the response
|
|
90
|
-
tools: Optional list of tool definitions
|
|
91
|
-
|
|
92
|
-
Returns:
|
|
93
|
-
StreamWrapper if stream=True, else response dict
|
|
94
|
-
"""
|
|
95
|
-
config = self.config
|
|
96
|
-
registry = config["registry"]
|
|
97
|
-
|
|
98
|
-
# Build payload using handler
|
|
99
|
-
payload = self.handler.build_payload(registry, messages, tools, stream)
|
|
100
|
-
|
|
101
|
-
try:
|
|
102
|
-
response = requests.post(
|
|
103
|
-
config["url"],
|
|
104
|
-
headers=config["headers"],
|
|
105
|
-
json=payload,
|
|
106
|
-
stream=stream,
|
|
107
|
-
verify=True,
|
|
108
|
-
timeout=(_CONNECT_TIMEOUT, _READ_TIMEOUT),
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
# For better debugging, include response text on 4xx errors
|
|
112
|
-
if not response.ok:
|
|
113
|
-
error_details = response.text if response.text else str(response.status_code)
|
|
114
|
-
raise LLMConnectionError(
|
|
115
|
-
f"Error communicating with {config['error_prefix']}",
|
|
116
|
-
details={
|
|
117
|
-
"provider": self.provider,
|
|
118
|
-
"original_error": error_details,
|
|
119
|
-
"status_code": response.status_code,
|
|
120
|
-
}
|
|
121
|
-
)
|
|
122
|
-
response.raise_for_status()
|
|
123
|
-
|
|
124
|
-
if stream:
|
|
125
|
-
return StreamWrapper(
|
|
126
|
-
response,
|
|
127
|
-
self.handler.parse_stream(response)
|
|
128
|
-
)
|
|
129
|
-
else:
|
|
130
|
-
response_json = response.json()
|
|
131
|
-
return self.handler.parse_response(response_json)
|
|
132
|
-
|
|
133
|
-
except requests.exceptions.RequestException as e:
|
|
134
|
-
raise LLMConnectionError(
|
|
135
|
-
f"Error communicating with {config['error_prefix']}",
|
|
136
|
-
details={"provider": self.provider, "original_error": str(e)}
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
def switch_provider(self, new_provider):
|
|
140
|
-
"""Switch to a different provider.
|
|
141
|
-
|
|
142
|
-
Args:
|
|
143
|
-
new_provider: Name of the provider to switch to.
|
|
144
|
-
|
|
145
|
-
Returns:
|
|
146
|
-
True if successful, False if provider not found.
|
|
147
|
-
"""
|
|
148
|
-
if new_provider in get_providers():
|
|
149
|
-
self.provider = new_provider
|
|
150
|
-
self.handler = get_handler(new_provider)
|
|
151
|
-
self.config = self._get_provider_config()
|
|
152
|
-
return True
|
|
153
|
-
return False
|
|
154
|
-
|
|
155
|
-
def sync_provider_from_config(self):
|
|
156
|
-
"""Sync this client's provider and config with the current config.
|
|
157
|
-
|
|
158
|
-
This should be called after config is reloaded from disk.
|
|
159
|
-
"""
|
|
160
|
-
current_provider = config_module.LLM_PROVIDER
|
|
161
|
-
if self.provider != current_provider:
|
|
162
|
-
self.provider = current_provider
|
|
163
|
-
self.handler = get_handler(current_provider)
|
|
164
|
-
self.config = self._get_provider_config()
|
|
165
|
-
return True
|
|
166
|
-
# Even if provider hasn't changed, config values (model, api_key) might have
|
|
167
|
-
self.config = self._get_provider_config()
|
|
168
|
-
return False
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
__all__ = ['LLMClient']
|