nc1709 1.15.4__py3-none-any.whl
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.
- nc1709/__init__.py +13 -0
- nc1709/agent/__init__.py +36 -0
- nc1709/agent/core.py +505 -0
- nc1709/agent/mcp_bridge.py +245 -0
- nc1709/agent/permissions.py +298 -0
- nc1709/agent/tools/__init__.py +21 -0
- nc1709/agent/tools/base.py +440 -0
- nc1709/agent/tools/bash_tool.py +367 -0
- nc1709/agent/tools/file_tools.py +454 -0
- nc1709/agent/tools/notebook_tools.py +516 -0
- nc1709/agent/tools/search_tools.py +322 -0
- nc1709/agent/tools/task_tool.py +284 -0
- nc1709/agent/tools/web_tools.py +555 -0
- nc1709/agents/__init__.py +17 -0
- nc1709/agents/auto_fix.py +506 -0
- nc1709/agents/test_generator.py +507 -0
- nc1709/checkpoints.py +372 -0
- nc1709/cli.py +3380 -0
- nc1709/cli_ui.py +1080 -0
- nc1709/cognitive/__init__.py +149 -0
- nc1709/cognitive/anticipation.py +594 -0
- nc1709/cognitive/context_engine.py +1046 -0
- nc1709/cognitive/council.py +824 -0
- nc1709/cognitive/learning.py +761 -0
- nc1709/cognitive/router.py +583 -0
- nc1709/cognitive/system.py +519 -0
- nc1709/config.py +155 -0
- nc1709/custom_commands.py +300 -0
- nc1709/executor.py +333 -0
- nc1709/file_controller.py +354 -0
- nc1709/git_integration.py +308 -0
- nc1709/github_integration.py +477 -0
- nc1709/image_input.py +446 -0
- nc1709/linting.py +519 -0
- nc1709/llm_adapter.py +667 -0
- nc1709/logger.py +192 -0
- nc1709/mcp/__init__.py +18 -0
- nc1709/mcp/client.py +370 -0
- nc1709/mcp/manager.py +407 -0
- nc1709/mcp/protocol.py +210 -0
- nc1709/mcp/server.py +473 -0
- nc1709/memory/__init__.py +20 -0
- nc1709/memory/embeddings.py +325 -0
- nc1709/memory/indexer.py +474 -0
- nc1709/memory/sessions.py +432 -0
- nc1709/memory/vector_store.py +451 -0
- nc1709/models/__init__.py +86 -0
- nc1709/models/detector.py +377 -0
- nc1709/models/formats.py +315 -0
- nc1709/models/manager.py +438 -0
- nc1709/models/registry.py +497 -0
- nc1709/performance/__init__.py +343 -0
- nc1709/performance/cache.py +705 -0
- nc1709/performance/pipeline.py +611 -0
- nc1709/performance/tiering.py +543 -0
- nc1709/plan_mode.py +362 -0
- nc1709/plugins/__init__.py +17 -0
- nc1709/plugins/agents/__init__.py +18 -0
- nc1709/plugins/agents/django_agent.py +912 -0
- nc1709/plugins/agents/docker_agent.py +623 -0
- nc1709/plugins/agents/fastapi_agent.py +887 -0
- nc1709/plugins/agents/git_agent.py +731 -0
- nc1709/plugins/agents/nextjs_agent.py +867 -0
- nc1709/plugins/base.py +359 -0
- nc1709/plugins/manager.py +411 -0
- nc1709/plugins/registry.py +337 -0
- nc1709/progress.py +443 -0
- nc1709/prompts/__init__.py +22 -0
- nc1709/prompts/agent_system.py +180 -0
- nc1709/prompts/task_prompts.py +340 -0
- nc1709/prompts/unified_prompt.py +133 -0
- nc1709/reasoning_engine.py +541 -0
- nc1709/remote_client.py +266 -0
- nc1709/shell_completions.py +349 -0
- nc1709/slash_commands.py +649 -0
- nc1709/task_classifier.py +408 -0
- nc1709/version_check.py +177 -0
- nc1709/web/__init__.py +8 -0
- nc1709/web/server.py +950 -0
- nc1709/web/templates/index.html +1127 -0
- nc1709-1.15.4.dist-info/METADATA +858 -0
- nc1709-1.15.4.dist-info/RECORD +86 -0
- nc1709-1.15.4.dist-info/WHEEL +5 -0
- nc1709-1.15.4.dist-info/entry_points.txt +2 -0
- nc1709-1.15.4.dist-info/licenses/LICENSE +9 -0
- nc1709-1.15.4.dist-info/top_level.txt +1 -0
nc1709/plugins/base.py
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base Plugin Classes for NC1709
|
|
3
|
+
Defines the plugin interface and core abstractions
|
|
4
|
+
"""
|
|
5
|
+
from abc import ABC, abstractmethod
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from typing import List, Dict, Any, Optional, Callable
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class PluginCapability(Enum):
|
|
13
|
+
"""Capabilities that plugins can provide"""
|
|
14
|
+
FILE_OPERATIONS = "file_operations" # Read, write, modify files
|
|
15
|
+
COMMAND_EXECUTION = "command_execution" # Execute shell commands
|
|
16
|
+
VERSION_CONTROL = "version_control" # Git operations
|
|
17
|
+
CONTAINER_MANAGEMENT = "container_mgmt" # Docker operations
|
|
18
|
+
CODE_GENERATION = "code_generation" # Generate code
|
|
19
|
+
CODE_ANALYSIS = "code_analysis" # Analyze code
|
|
20
|
+
PROJECT_SCAFFOLDING = "scaffolding" # Create project structure
|
|
21
|
+
TESTING = "testing" # Run tests
|
|
22
|
+
DEPLOYMENT = "deployment" # Deploy applications
|
|
23
|
+
DATABASE = "database" # Database operations
|
|
24
|
+
API_INTERACTION = "api_interaction" # External API calls
|
|
25
|
+
DOCUMENTATION = "documentation" # Generate docs
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class PluginStatus(Enum):
|
|
29
|
+
"""Plugin lifecycle states"""
|
|
30
|
+
UNLOADED = "unloaded"
|
|
31
|
+
LOADING = "loading"
|
|
32
|
+
ACTIVE = "active"
|
|
33
|
+
ERROR = "error"
|
|
34
|
+
DISABLED = "disabled"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class PluginMetadata:
|
|
39
|
+
"""Metadata describing a plugin"""
|
|
40
|
+
name: str
|
|
41
|
+
version: str
|
|
42
|
+
description: str
|
|
43
|
+
author: str = "NC1709 Team"
|
|
44
|
+
capabilities: List[PluginCapability] = field(default_factory=list)
|
|
45
|
+
dependencies: List[str] = field(default_factory=list) # Other plugin names
|
|
46
|
+
config_schema: Dict[str, Any] = field(default_factory=dict)
|
|
47
|
+
keywords: List[str] = field(default_factory=list) # For discovery
|
|
48
|
+
enabled_by_default: bool = True
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class PluginAction:
|
|
53
|
+
"""Represents an action a plugin can perform"""
|
|
54
|
+
name: str
|
|
55
|
+
description: str
|
|
56
|
+
handler: Callable
|
|
57
|
+
parameters: Dict[str, Any] = field(default_factory=dict)
|
|
58
|
+
requires_confirmation: bool = False
|
|
59
|
+
dangerous: bool = False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class ActionResult:
|
|
64
|
+
"""Result of a plugin action"""
|
|
65
|
+
success: bool
|
|
66
|
+
message: str
|
|
67
|
+
data: Optional[Any] = None
|
|
68
|
+
error: Optional[str] = None
|
|
69
|
+
execution_time: float = 0.0
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def ok(cls, message: str, data: Any = None) -> "ActionResult":
|
|
73
|
+
"""Create a successful result"""
|
|
74
|
+
return cls(success=True, message=message, data=data)
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def fail(cls, error: str, message: str = "Action failed") -> "ActionResult":
|
|
78
|
+
"""Create a failed result"""
|
|
79
|
+
return cls(success=False, message=message, error=error)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Plugin(ABC):
|
|
83
|
+
"""
|
|
84
|
+
Base class for all NC1709 plugins.
|
|
85
|
+
|
|
86
|
+
Plugins extend NC1709's capabilities by providing specialized
|
|
87
|
+
functionality for specific domains (Git, Docker, frameworks, etc.)
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
|
91
|
+
"""Initialize the plugin
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
config: Plugin-specific configuration
|
|
95
|
+
"""
|
|
96
|
+
self._config = config or {}
|
|
97
|
+
self._status = PluginStatus.UNLOADED
|
|
98
|
+
self._actions: Dict[str, PluginAction] = {}
|
|
99
|
+
self._error: Optional[str] = None
|
|
100
|
+
self._loaded_at: Optional[datetime] = None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
@abstractmethod
|
|
104
|
+
def metadata(self) -> PluginMetadata:
|
|
105
|
+
"""Return plugin metadata"""
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def status(self) -> PluginStatus:
|
|
110
|
+
"""Get current plugin status"""
|
|
111
|
+
return self._status
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def config(self) -> Dict[str, Any]:
|
|
115
|
+
"""Get plugin configuration"""
|
|
116
|
+
return self._config
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def actions(self) -> Dict[str, PluginAction]:
|
|
120
|
+
"""Get registered actions"""
|
|
121
|
+
return self._actions
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def error(self) -> Optional[str]:
|
|
125
|
+
"""Get last error message"""
|
|
126
|
+
return self._error
|
|
127
|
+
|
|
128
|
+
def configure(self, config: Dict[str, Any]) -> bool:
|
|
129
|
+
"""Update plugin configuration
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
config: New configuration values
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
True if configuration was updated successfully
|
|
136
|
+
"""
|
|
137
|
+
self._config.update(config)
|
|
138
|
+
return self.validate_config()
|
|
139
|
+
|
|
140
|
+
def validate_config(self) -> bool:
|
|
141
|
+
"""Validate current configuration
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
True if configuration is valid
|
|
145
|
+
"""
|
|
146
|
+
# Default implementation - override for custom validation
|
|
147
|
+
return True
|
|
148
|
+
|
|
149
|
+
def load(self) -> bool:
|
|
150
|
+
"""Load and initialize the plugin
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
True if loaded successfully
|
|
154
|
+
"""
|
|
155
|
+
try:
|
|
156
|
+
self._status = PluginStatus.LOADING
|
|
157
|
+
|
|
158
|
+
# Validate configuration
|
|
159
|
+
if not self.validate_config():
|
|
160
|
+
self._status = PluginStatus.ERROR
|
|
161
|
+
self._error = "Invalid configuration"
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
# Check dependencies
|
|
165
|
+
if not self._check_dependencies():
|
|
166
|
+
self._status = PluginStatus.ERROR
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
# Initialize plugin
|
|
170
|
+
if not self.initialize():
|
|
171
|
+
self._status = PluginStatus.ERROR
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
# Register actions
|
|
175
|
+
self._register_actions()
|
|
176
|
+
|
|
177
|
+
self._status = PluginStatus.ACTIVE
|
|
178
|
+
self._loaded_at = datetime.now()
|
|
179
|
+
return True
|
|
180
|
+
|
|
181
|
+
except Exception as e:
|
|
182
|
+
self._status = PluginStatus.ERROR
|
|
183
|
+
self._error = str(e)
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
def unload(self) -> bool:
|
|
187
|
+
"""Unload the plugin and cleanup resources
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
True if unloaded successfully
|
|
191
|
+
"""
|
|
192
|
+
try:
|
|
193
|
+
self.cleanup()
|
|
194
|
+
self._status = PluginStatus.UNLOADED
|
|
195
|
+
self._actions.clear()
|
|
196
|
+
return True
|
|
197
|
+
except Exception as e:
|
|
198
|
+
self._error = str(e)
|
|
199
|
+
return False
|
|
200
|
+
|
|
201
|
+
@abstractmethod
|
|
202
|
+
def initialize(self) -> bool:
|
|
203
|
+
"""Initialize plugin resources
|
|
204
|
+
|
|
205
|
+
Called during load(). Override to set up connections,
|
|
206
|
+
verify tools are installed, etc.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
True if initialization successful
|
|
210
|
+
"""
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
@abstractmethod
|
|
214
|
+
def cleanup(self) -> None:
|
|
215
|
+
"""Cleanup plugin resources
|
|
216
|
+
|
|
217
|
+
Called during unload(). Override to close connections,
|
|
218
|
+
cleanup temp files, etc.
|
|
219
|
+
"""
|
|
220
|
+
pass
|
|
221
|
+
|
|
222
|
+
@abstractmethod
|
|
223
|
+
def _register_actions(self) -> None:
|
|
224
|
+
"""Register available actions
|
|
225
|
+
|
|
226
|
+
Override to register PluginAction instances in self._actions
|
|
227
|
+
"""
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
def _check_dependencies(self) -> bool:
|
|
231
|
+
"""Check if plugin dependencies are available
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
True if all dependencies are met
|
|
235
|
+
"""
|
|
236
|
+
# This will be enhanced by PluginManager to check other plugins
|
|
237
|
+
return True
|
|
238
|
+
|
|
239
|
+
def register_action(
|
|
240
|
+
self,
|
|
241
|
+
name: str,
|
|
242
|
+
handler: Callable,
|
|
243
|
+
description: str,
|
|
244
|
+
parameters: Optional[Dict[str, Any]] = None,
|
|
245
|
+
requires_confirmation: bool = False,
|
|
246
|
+
dangerous: bool = False
|
|
247
|
+
) -> None:
|
|
248
|
+
"""Register a new action
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
name: Action name (used for invocation)
|
|
252
|
+
handler: Function to execute
|
|
253
|
+
description: Human-readable description
|
|
254
|
+
parameters: Parameter schema
|
|
255
|
+
requires_confirmation: Whether to ask user before executing
|
|
256
|
+
dangerous: Whether action can cause data loss
|
|
257
|
+
"""
|
|
258
|
+
self._actions[name] = PluginAction(
|
|
259
|
+
name=name,
|
|
260
|
+
handler=handler,
|
|
261
|
+
description=description,
|
|
262
|
+
parameters=parameters or {},
|
|
263
|
+
requires_confirmation=requires_confirmation,
|
|
264
|
+
dangerous=dangerous
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def execute(self, action_name: str, **kwargs) -> ActionResult:
|
|
268
|
+
"""Execute a plugin action
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
action_name: Name of the action to execute
|
|
272
|
+
**kwargs: Action parameters
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
ActionResult with success/failure info
|
|
276
|
+
"""
|
|
277
|
+
if self._status != PluginStatus.ACTIVE:
|
|
278
|
+
return ActionResult.fail(
|
|
279
|
+
f"Plugin not active (status: {self._status.value})"
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
if action_name not in self._actions:
|
|
283
|
+
return ActionResult.fail(
|
|
284
|
+
f"Unknown action: {action_name}",
|
|
285
|
+
f"Available actions: {list(self._actions.keys())}"
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
action = self._actions[action_name]
|
|
289
|
+
|
|
290
|
+
try:
|
|
291
|
+
import time
|
|
292
|
+
start = time.time()
|
|
293
|
+
result = action.handler(**kwargs)
|
|
294
|
+
elapsed = time.time() - start
|
|
295
|
+
|
|
296
|
+
if isinstance(result, ActionResult):
|
|
297
|
+
result.execution_time = elapsed
|
|
298
|
+
return result
|
|
299
|
+
|
|
300
|
+
# If handler returns something else, wrap it
|
|
301
|
+
return ActionResult.ok(
|
|
302
|
+
message=f"Action '{action_name}' completed",
|
|
303
|
+
data=result
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
except Exception as e:
|
|
307
|
+
return ActionResult.fail(
|
|
308
|
+
error=str(e),
|
|
309
|
+
message=f"Action '{action_name}' failed"
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
def can_handle(self, request: str) -> float:
|
|
313
|
+
"""Check if plugin can handle a user request
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
request: User's natural language request
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
Confidence score 0.0-1.0 (0 = cannot handle)
|
|
320
|
+
"""
|
|
321
|
+
# Default implementation uses keyword matching
|
|
322
|
+
request_lower = request.lower()
|
|
323
|
+
score = 0.0
|
|
324
|
+
|
|
325
|
+
for keyword in self.metadata.keywords:
|
|
326
|
+
if keyword.lower() in request_lower:
|
|
327
|
+
score += 0.2
|
|
328
|
+
|
|
329
|
+
return min(score, 1.0)
|
|
330
|
+
|
|
331
|
+
def get_help(self) -> str:
|
|
332
|
+
"""Get plugin help text
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
Formatted help string
|
|
336
|
+
"""
|
|
337
|
+
lines = [
|
|
338
|
+
f"# {self.metadata.name} v{self.metadata.version}",
|
|
339
|
+
f"",
|
|
340
|
+
f"{self.metadata.description}",
|
|
341
|
+
f"",
|
|
342
|
+
f"## Capabilities",
|
|
343
|
+
]
|
|
344
|
+
|
|
345
|
+
for cap in self.metadata.capabilities:
|
|
346
|
+
lines.append(f" - {cap.value}")
|
|
347
|
+
|
|
348
|
+
if self._actions:
|
|
349
|
+
lines.append("")
|
|
350
|
+
lines.append("## Available Actions")
|
|
351
|
+
for name, action in self._actions.items():
|
|
352
|
+
lines.append(f" - **{name}**: {action.description}")
|
|
353
|
+
if action.dangerous:
|
|
354
|
+
lines.append(f" ⚠️ This action can modify/delete data")
|
|
355
|
+
|
|
356
|
+
return "\n".join(lines)
|
|
357
|
+
|
|
358
|
+
def __repr__(self) -> str:
|
|
359
|
+
return f"<Plugin {self.metadata.name} v{self.metadata.version} [{self._status.value}]>"
|