code-puppy 0.0.343__py3-none-any.whl → 0.0.345__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.
- code_puppy/agents/base_agent.py +37 -129
- code_puppy/cli_runner.py +0 -35
- code_puppy/command_line/add_model_menu.py +8 -9
- code_puppy/command_line/config_commands.py +0 -10
- code_puppy/command_line/mcp/catalog_server_installer.py +5 -6
- code_puppy/command_line/mcp/custom_server_form.py +54 -19
- code_puppy/command_line/mcp/custom_server_installer.py +8 -9
- code_puppy/command_line/mcp/handler.py +0 -2
- code_puppy/command_line/mcp/help_command.py +1 -5
- code_puppy/command_line/mcp/start_command.py +36 -18
- code_puppy/command_line/onboarding_slides.py +0 -1
- code_puppy/command_line/utils.py +54 -0
- code_puppy/config.py +0 -23
- code_puppy/mcp_/async_lifecycle.py +35 -4
- code_puppy/mcp_/managed_server.py +49 -20
- code_puppy/mcp_/manager.py +81 -52
- code_puppy/messaging/message_queue.py +11 -23
- code_puppy/summarization_agent.py +1 -11
- code_puppy/tools/agent_tools.py +11 -55
- code_puppy/tools/browser/vqa_agent.py +1 -7
- {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/METADATA +1 -23
- {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/RECORD +27 -28
- code_puppy/command_line/mcp/add_command.py +0 -170
- {code_puppy-0.0.343.data → code_puppy-0.0.345.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.343.data → code_puppy-0.0.345.data}/data/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/licenses/LICENSE +0 -0
code_puppy/tools/agent_tools.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# agent_tools.py
|
|
2
2
|
import asyncio
|
|
3
3
|
import hashlib
|
|
4
|
-
import itertools
|
|
5
4
|
import json
|
|
6
5
|
import pickle
|
|
7
6
|
import re
|
|
@@ -10,7 +9,6 @@ from datetime import datetime
|
|
|
10
9
|
from pathlib import Path
|
|
11
10
|
from typing import List, Set
|
|
12
11
|
|
|
13
|
-
from dbos import DBOS, SetWorkflowID
|
|
14
12
|
from pydantic import BaseModel
|
|
15
13
|
|
|
16
14
|
# Import Agent from pydantic_ai to create temporary agents for invocation
|
|
@@ -20,7 +18,6 @@ from pydantic_ai.messages import ModelMessage
|
|
|
20
18
|
from code_puppy.config import (
|
|
21
19
|
DATA_DIR,
|
|
22
20
|
get_message_limit,
|
|
23
|
-
get_use_dbos,
|
|
24
21
|
)
|
|
25
22
|
from code_puppy.messaging import (
|
|
26
23
|
SubAgentInvocationMessage,
|
|
@@ -37,27 +34,6 @@ from code_puppy.tools.common import generate_group_id
|
|
|
37
34
|
# Set to track active subagent invocation tasks
|
|
38
35
|
_active_subagent_tasks: Set[asyncio.Task] = set()
|
|
39
36
|
|
|
40
|
-
# Atomic counter for DBOS workflow IDs - ensures uniqueness even in rapid back-to-back calls
|
|
41
|
-
# itertools.count() is thread-safe for next() calls
|
|
42
|
-
_dbos_workflow_counter = itertools.count()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _generate_dbos_workflow_id(base_id: str) -> str:
|
|
46
|
-
"""Generate a unique DBOS workflow ID by appending an atomic counter.
|
|
47
|
-
|
|
48
|
-
DBOS requires workflow IDs to be unique across all executions.
|
|
49
|
-
This function ensures uniqueness by combining the base_id with
|
|
50
|
-
an atomically incrementing counter.
|
|
51
|
-
|
|
52
|
-
Args:
|
|
53
|
-
base_id: The base identifier (e.g., group_id from generate_group_id)
|
|
54
|
-
|
|
55
|
-
Returns:
|
|
56
|
-
A unique workflow ID in format: {base_id}-wf-{counter}
|
|
57
|
-
"""
|
|
58
|
-
counter = next(_dbos_workflow_counter)
|
|
59
|
-
return f"{base_id}-wf-{counter}"
|
|
60
|
-
|
|
61
37
|
|
|
62
38
|
def _generate_session_hash_suffix() -> str:
|
|
63
39
|
"""Generate a short SHA1 hash suffix based on current timestamp for uniqueness.
|
|
@@ -468,9 +444,11 @@ def register_invoke_agent(agent):
|
|
|
468
444
|
instructions = prepared.instructions
|
|
469
445
|
prompt = prepared.user_prompt
|
|
470
446
|
|
|
471
|
-
subagent_name = f"temp-invoke-agent-{session_id}"
|
|
472
447
|
model_settings = make_model_settings(model_name)
|
|
473
448
|
|
|
449
|
+
# Load MCP servers so sub-agents have access to the same tools as the main agent
|
|
450
|
+
mcp_servers = agent_config.load_mcp_servers()
|
|
451
|
+
|
|
474
452
|
temp_agent = Agent(
|
|
475
453
|
model=model,
|
|
476
454
|
instructions=instructions,
|
|
@@ -478,6 +456,7 @@ def register_invoke_agent(agent):
|
|
|
478
456
|
retries=3,
|
|
479
457
|
history_processors=[agent_config.message_history_accumulator],
|
|
480
458
|
model_settings=model_settings,
|
|
459
|
+
toolsets=mcp_servers if mcp_servers else [],
|
|
481
460
|
)
|
|
482
461
|
|
|
483
462
|
# Register the tools that the agent needs
|
|
@@ -486,44 +465,21 @@ def register_invoke_agent(agent):
|
|
|
486
465
|
agent_tools = agent_config.get_available_tools()
|
|
487
466
|
register_tools_for_agent(temp_agent, agent_tools)
|
|
488
467
|
|
|
489
|
-
if get_use_dbos():
|
|
490
|
-
from pydantic_ai.durable_exec.dbos import DBOSAgent
|
|
491
|
-
|
|
492
|
-
dbos_agent = DBOSAgent(temp_agent, name=subagent_name)
|
|
493
|
-
temp_agent = dbos_agent
|
|
494
|
-
|
|
495
468
|
# Run the temporary agent with the provided prompt as an asyncio task
|
|
496
469
|
# Pass the message_history from the session to continue the conversation
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
task = asyncio.create_task(
|
|
503
|
-
temp_agent.run(
|
|
504
|
-
prompt,
|
|
505
|
-
message_history=message_history,
|
|
506
|
-
usage_limits=UsageLimits(request_limit=get_message_limit()),
|
|
507
|
-
)
|
|
508
|
-
)
|
|
509
|
-
_active_subagent_tasks.add(task)
|
|
510
|
-
else:
|
|
511
|
-
task = asyncio.create_task(
|
|
512
|
-
temp_agent.run(
|
|
513
|
-
prompt,
|
|
514
|
-
message_history=message_history,
|
|
515
|
-
usage_limits=UsageLimits(request_limit=get_message_limit()),
|
|
516
|
-
)
|
|
470
|
+
task = asyncio.create_task(
|
|
471
|
+
temp_agent.run(
|
|
472
|
+
prompt,
|
|
473
|
+
message_history=message_history,
|
|
474
|
+
usage_limits=UsageLimits(request_limit=get_message_limit()),
|
|
517
475
|
)
|
|
518
|
-
|
|
476
|
+
)
|
|
477
|
+
_active_subagent_tasks.add(task)
|
|
519
478
|
|
|
520
479
|
try:
|
|
521
480
|
result = await task
|
|
522
481
|
finally:
|
|
523
482
|
_active_subagent_tasks.discard(task)
|
|
524
|
-
if task.cancelled():
|
|
525
|
-
if get_use_dbos() and workflow_id:
|
|
526
|
-
DBOS.cancel_workflow(workflow_id)
|
|
527
483
|
|
|
528
484
|
# Extract the response from the result
|
|
529
485
|
response = result.output
|
|
@@ -7,7 +7,7 @@ from functools import lru_cache
|
|
|
7
7
|
from pydantic import BaseModel, Field
|
|
8
8
|
from pydantic_ai import Agent, BinaryContent
|
|
9
9
|
|
|
10
|
-
from code_puppy.config import
|
|
10
|
+
from code_puppy.config import get_vqa_model_name
|
|
11
11
|
from code_puppy.model_factory import ModelFactory
|
|
12
12
|
|
|
13
13
|
|
|
@@ -50,12 +50,6 @@ def _load_vqa_agent(model_name: str) -> Agent[None, VisualAnalysisResult]:
|
|
|
50
50
|
retries=2,
|
|
51
51
|
)
|
|
52
52
|
|
|
53
|
-
if get_use_dbos():
|
|
54
|
-
from pydantic_ai.durable_exec.dbos import DBOSAgent
|
|
55
|
-
|
|
56
|
-
dbos_agent = DBOSAgent(vqa_agent, name="vqa-agent")
|
|
57
|
-
return dbos_agent
|
|
58
|
-
|
|
59
53
|
return vqa_agent
|
|
60
54
|
|
|
61
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-puppy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.345
|
|
4
4
|
Summary: Code generation agent
|
|
5
5
|
Project-URL: repository, https://github.com/mpfaffenberger/code_puppy
|
|
6
6
|
Project-URL: HomePage, https://github.com/mpfaffenberger/code_puppy
|
|
@@ -16,7 +16,6 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
16
16
|
Classifier: Topic :: Software Development :: Code Generators
|
|
17
17
|
Requires-Python: <3.14,>=3.11
|
|
18
18
|
Requires-Dist: camoufox>=0.4.11
|
|
19
|
-
Requires-Dist: dbos>=2.5.0
|
|
20
19
|
Requires-Dist: fastapi>=0.111.0
|
|
21
20
|
Requires-Dist: httpx[http2]>=0.24.1
|
|
22
21
|
Requires-Dist: json-repair>=0.46.2
|
|
@@ -174,27 +173,6 @@ These providers are automatically configured with correct OpenAI-compatible endp
|
|
|
174
173
|
- **⚠️ Unsupported Providers** - Providers like Amazon Bedrock and Google Vertex that require special authentication are clearly marked
|
|
175
174
|
- **⚠️ No Tool Calling** - Models without tool calling support show a big warning since they can't use Code Puppy's file/shell tools
|
|
176
175
|
|
|
177
|
-
### Durable Execution
|
|
178
|
-
|
|
179
|
-
Code Puppy now supports **[DBOS](https://github.com/dbos-inc/dbos-transact-py)** durable execution.
|
|
180
|
-
|
|
181
|
-
When enabled, every agent is automatically wrapped as a `DBOSAgent`, checkpointing key interactions (including agent inputs, LLM responses, MCP calls, and tool calls) in a database for durability and recovery.
|
|
182
|
-
|
|
183
|
-
You can toggle DBOS via either of these options:
|
|
184
|
-
|
|
185
|
-
- CLI config (persists): `/set enable_dbos true` (or `false` to disable)
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
Config takes precedence if set; otherwise the environment variable is used.
|
|
189
|
-
|
|
190
|
-
### Configuration
|
|
191
|
-
|
|
192
|
-
The following environment variables control DBOS behavior:
|
|
193
|
-
- `DBOS_CONDUCTOR_KEY`: If set, Code Puppy connects to the [DBOS Management Console](https://console.dbos.dev/). Make sure you first register an app named `dbos-code-puppy` on the console to generate a Conductor key. Default: `None`.
|
|
194
|
-
- `DBOS_LOG_LEVEL`: Logging verbosity: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, or `DEBUG`. Default: `ERROR`.
|
|
195
|
-
- `DBOS_SYSTEM_DATABASE_URL`: Database URL used by DBOS. Can point to a local SQLite file or a Postgres instance. Example: `postgresql://postgres:dbos@localhost:5432/postgres`. Default: `dbos_store.sqlite` file in the config directory.
|
|
196
|
-
- `DBOS_APP_VERSION`: If set, Code Puppy uses it as the [DBOS application version](https://docs.dbos.dev/architecture#application-and-workflow-versions) and automatically tries to recover pending workflows for this version. Default: Code Puppy version + Unix timestamp in millisecond (disable automatic recovery).
|
|
197
|
-
|
|
198
176
|
### Custom Commands
|
|
199
177
|
Create markdown files in `.claude/commands/`, `.github/prompts/`, or `.agents/commands/` to define custom slash commands. The filename becomes the command name and the content runs as a prompt.
|
|
200
178
|
|
|
@@ -3,8 +3,8 @@ code_puppy/__main__.py,sha256=pDVssJOWP8A83iFkxMLY9YteHYat0EyWDQqMkKHpWp4,203
|
|
|
3
3
|
code_puppy/callbacks.py,sha256=hqTV--dNxG5vwWWm3MrEjmb8MZuHFFdmHePl23NXPHk,8621
|
|
4
4
|
code_puppy/chatgpt_codex_client.py,sha256=Om0ANB_kpHubhCwNzF9ENf8RvKBqs0IYzBLl_SNw0Vk,9833
|
|
5
5
|
code_puppy/claude_cache_client.py,sha256=MLIRSJP428r9IK_aV6XyCXrCfQnNti32U60psPymLM4,14860
|
|
6
|
-
code_puppy/cli_runner.py,sha256=
|
|
7
|
-
code_puppy/config.py,sha256=
|
|
6
|
+
code_puppy/cli_runner.py,sha256=ltUZJauK-fYaRT6qxCgmbJYFtXw1wDuk1rf8eu8LmD0,33676
|
|
7
|
+
code_puppy/config.py,sha256=oCfxFfXvFgv7dEc4NObtQHvE-VG65DifEqaid342kTM,51544
|
|
8
8
|
code_puppy/error_logging.py,sha256=a80OILCUtJhexI6a9GM-r5LqIdjvSRzggfgPp2jv1X0,3297
|
|
9
9
|
code_puppy/gemini_code_assist.py,sha256=KGS7sO5OLc83nDF3xxS-QiU6vxW9vcm6hmzilu79Ef8,13867
|
|
10
10
|
code_puppy/http_utils.py,sha256=H3N5Qz2B1CcsGUYOycGWAqoNMr2P1NCVluKX3aRwRqI,10358
|
|
@@ -20,7 +20,7 @@ code_puppy/reopenable_async_client.py,sha256=pD34chyBFcC7_OVPJ8fp6aRI5jYdN-7VDyc
|
|
|
20
20
|
code_puppy/round_robin_model.py,sha256=kSawwPUiPgg0yg8r4AAVgvjzsWkptxpSORd75-HP7W4,5335
|
|
21
21
|
code_puppy/session_storage.py,sha256=T4hOsAl9z0yz2JZCptjJBOnN8fCmkLZx5eLy1hTdv6Q,9631
|
|
22
22
|
code_puppy/status_display.py,sha256=qHzIQGAPEa2_-4gQSg7_rE1ihOosBq8WO73MWFNmmlo,8938
|
|
23
|
-
code_puppy/summarization_agent.py,sha256=
|
|
23
|
+
code_puppy/summarization_agent.py,sha256=YO_B1rd8jxX9S79HDFxhiiAKgn2Uv2fnt_hRkVvJ-dU,4209
|
|
24
24
|
code_puppy/terminal_utils.py,sha256=TaS19x7EZqudlBUAQwLMzBMNxBHBNInvQQREXqRGtkM,12984
|
|
25
25
|
code_puppy/uvx_detection.py,sha256=tP9X9Nvzow--KIqtqjgrHQkSxMJ3EevfoaeoB9VLY2o,7224
|
|
26
26
|
code_puppy/version_checker.py,sha256=aq2Mwxl1CR9sEFBgrPt3OQOowLOBUp9VaQYWJhuUv8Q,1780
|
|
@@ -40,18 +40,18 @@ code_puppy/agents/agent_qa_expert.py,sha256=5Ikb4U3SZQknUEfwlHZiyZXKqnffnOTQagr_
|
|
|
40
40
|
code_puppy/agents/agent_qa_kitten.py,sha256=5PeFFSwCFlTUvP6h5bGntx0xv5NmRwBiw0HnMqY8nLI,9107
|
|
41
41
|
code_puppy/agents/agent_security_auditor.py,sha256=SpiYNA0XAsIwBj7S2_EQPRslRUmF_-b89pIJyW7DYtY,12022
|
|
42
42
|
code_puppy/agents/agent_typescript_reviewer.py,sha256=vsnpp98xg6cIoFAEJrRTUM_i4wLEWGm5nJxs6fhHobM,10275
|
|
43
|
-
code_puppy/agents/base_agent.py,sha256=
|
|
43
|
+
code_puppy/agents/base_agent.py,sha256=8ocPht_t87a83B7jVg6SExMnsq_f9qd-6KAelXoBB10,80354
|
|
44
44
|
code_puppy/agents/json_agent.py,sha256=lhopDJDoiSGHvD8A6t50hi9ZBoNRKgUywfxd0Po_Dzc,4886
|
|
45
45
|
code_puppy/agents/prompt_reviewer.py,sha256=JJrJ0m5q0Puxl8vFsyhAbY9ftU9n6c6UxEVdNct1E-Q,5558
|
|
46
46
|
code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
|
|
47
|
-
code_puppy/command_line/add_model_menu.py,sha256=
|
|
47
|
+
code_puppy/command_line/add_model_menu.py,sha256=CpURhxPvUhLHLBV_uwH1ODfJ-WAcGklvlsjEf5Vfvg4,43255
|
|
48
48
|
code_puppy/command_line/attachments.py,sha256=4Q5I2Es4j0ltnz5wjw2z0QXMsiMJvEfWRkPf_lJeITM,13093
|
|
49
49
|
code_puppy/command_line/autosave_menu.py,sha256=de7nOmFmEH6x5T7C95U8N8xgxxeF-l5lgaJzGJsF3ZY,19824
|
|
50
50
|
code_puppy/command_line/clipboard.py,sha256=oe9bfAX5RnT81FiYrDmhvHaePS1tAT-NFG1fSXubSD4,16869
|
|
51
51
|
code_puppy/command_line/colors_menu.py,sha256=LoFVfJ-Mo-Eq9hnb2Rj5mn7oBCnadAGr-8NNHsHlu18,17273
|
|
52
52
|
code_puppy/command_line/command_handler.py,sha256=CY9F27eovZJK_kpU1YmbroYLWGTCuouCOQ-TXfDp-nw,10916
|
|
53
53
|
code_puppy/command_line/command_registry.py,sha256=qFySsw1g8dol3kgi0p6cXrIDlP11_OhOoaQ5nAadWXg,4416
|
|
54
|
-
code_puppy/command_line/config_commands.py,sha256=
|
|
54
|
+
code_puppy/command_line/config_commands.py,sha256=TrTijfP98cL88XD_my6rO9mFX2DX5Glxc81Y2tPIo38,25263
|
|
55
55
|
code_puppy/command_line/core_commands.py,sha256=ujAPD4yDbXwYGJJfR2u4ei24eBV-Ps_-BVBjFMEoJy0,27668
|
|
56
56
|
code_puppy/command_line/diff_menu.py,sha256=_Gr9SP9fbItk-08dya9WTAR53s_PlyAvEnbt-8VWKPk,24141
|
|
57
57
|
code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
|
|
@@ -60,21 +60,20 @@ code_puppy/command_line/mcp_completion.py,sha256=eKzW2O7gun7HoHekOW0XVXhNS5J2xCt
|
|
|
60
60
|
code_puppy/command_line/model_picker_completion.py,sha256=nDnlf0qFCG2zAm_mWW2eMYwVC7eROVQrFe92hZqOKa8,6810
|
|
61
61
|
code_puppy/command_line/model_settings_menu.py,sha256=AI97IusDgMmWoCOp7C0Yrk_Uy6M9cmVhoZfVWgFWwXg,32392
|
|
62
62
|
code_puppy/command_line/motd.py,sha256=XuIk3UTLawwVFM-NfoaJGU5F2hPLASTFXq84UdDMT0Q,2408
|
|
63
|
-
code_puppy/command_line/onboarding_slides.py,sha256=
|
|
63
|
+
code_puppy/command_line/onboarding_slides.py,sha256=itqAsuHzjHpD_XNz6FniBIYr6dNyP1AW_XQZQ6SbVek,7125
|
|
64
64
|
code_puppy/command_line/onboarding_wizard.py,sha256=U5lV_1P3IwDYZUHar0zKgdp121zzkvOwwORvdCZwFcw,10241
|
|
65
65
|
code_puppy/command_line/pin_command_completion.py,sha256=juSvdqRpk7AdfkPy1DJx5NzfEUU5KYGlChvP0hisM18,11667
|
|
66
66
|
code_puppy/command_line/prompt_toolkit_completion.py,sha256=49GM3jVE89G1M3XroMZk2LhGgXpOO8XZ0Sg8h4a6LLw,32806
|
|
67
67
|
code_puppy/command_line/session_commands.py,sha256=Jh8GGfhlfBAEVfucKLbcZjNaXYd0twImiOwq2ZnGdQQ,9902
|
|
68
|
-
code_puppy/command_line/utils.py,sha256=
|
|
68
|
+
code_puppy/command_line/utils.py,sha256=_upMrrmDp5hteUjrRiEgVR6SoeNEPNZGXb5lOWYqcUQ,2952
|
|
69
69
|
code_puppy/command_line/mcp/__init__.py,sha256=0-OQuwjq_pLiTVJ1_NrirVwdRerghyKs_MTZkwPC7YY,315
|
|
70
|
-
code_puppy/command_line/mcp/add_command.py,sha256=iWqHReWbVOO3kuPE4NTMs3dv_BluxTBaasDPm9P1lU0,5892
|
|
71
70
|
code_puppy/command_line/mcp/base.py,sha256=pPeNnSyM0GGqD6mhYN-qA22rAT9bEapxliwH_YiIu3Q,823
|
|
72
|
-
code_puppy/command_line/mcp/catalog_server_installer.py,sha256=
|
|
73
|
-
code_puppy/command_line/mcp/custom_server_form.py,sha256=
|
|
74
|
-
code_puppy/command_line/mcp/custom_server_installer.py,sha256=
|
|
71
|
+
code_puppy/command_line/mcp/catalog_server_installer.py,sha256=G9FvQPTBB4LeJ4cOR9DvIkp82mClKRKI35KELbFLCKU,6181
|
|
72
|
+
code_puppy/command_line/mcp/custom_server_form.py,sha256=z0hsqXY1_ScJoacneyfrFHeVUlU3ZUHYt6CXV1wnJ0Y,23733
|
|
73
|
+
code_puppy/command_line/mcp/custom_server_installer.py,sha256=oLB5j07XKApdTrCDlY97GxE1NHrqupsX6DOCXzFj3TE,5744
|
|
75
74
|
code_puppy/command_line/mcp/edit_command.py,sha256=_WxxpaTgxo9pbvMogG9yvh2mcLE5SYf0Qbi8a8IpZ0k,4603
|
|
76
|
-
code_puppy/command_line/mcp/handler.py,sha256=
|
|
77
|
-
code_puppy/command_line/mcp/help_command.py,sha256=
|
|
75
|
+
code_puppy/command_line/mcp/handler.py,sha256=jwhcLi28QQ6IuE6E5IsMbU67jMZChfZW96hG9ezYgN4,4547
|
|
76
|
+
code_puppy/command_line/mcp/help_command.py,sha256=sTWecPqmmq6vmLVgZVNjBXKnziCLoJSKsugHkxiJlTI,5285
|
|
78
77
|
code_puppy/command_line/mcp/install_command.py,sha256=lmUyMUWtkGuy1SOQRHjQgt8mD3t1agVMQfEL5_TOzTM,8364
|
|
79
78
|
code_puppy/command_line/mcp/install_menu.py,sha256=GVNR7SJbheGLFc_r9N3CT1AT024ptzsEcj1cRnp4U3g,24769
|
|
80
79
|
code_puppy/command_line/mcp/list_command.py,sha256=UKQFPlhT9qGMCyG5VKjvnSMzDDtfAhIaKU_eErgZJDg,3181
|
|
@@ -83,7 +82,7 @@ code_puppy/command_line/mcp/remove_command.py,sha256=hyU_tKJWfyLnmufrFVLwlF0qFEb
|
|
|
83
82
|
code_puppy/command_line/mcp/restart_command.py,sha256=w5EcDac09iCvPBAR0u2M5KSIhASqTu5uZwsjCJ4JLhk,3588
|
|
84
83
|
code_puppy/command_line/mcp/search_command.py,sha256=mDkSz_KjPbvlO9U7oYUKJlqqY4QM90gWKO2xsH2i3SA,4244
|
|
85
84
|
code_puppy/command_line/mcp/start_all_command.py,sha256=_TVrjRR_oqJVS6qQaHssS0V_3342av1h9gz-Fxwa-Dw,4667
|
|
86
|
-
code_puppy/command_line/mcp/start_command.py,sha256=
|
|
85
|
+
code_puppy/command_line/mcp/start_command.py,sha256=XhuhyMpuo2Bkp53qxvZBSM8yRGatcwY8m-DXcQBHAZc,4344
|
|
87
86
|
code_puppy/command_line/mcp/status_command.py,sha256=NCyjFlBMURQ39T3G2dTPbyJdNC6X14FyWFzVh4BBnig,6657
|
|
88
87
|
code_puppy/command_line/mcp/stop_all_command.py,sha256=33mRvxd2cBbTXE6BSkSzFmdDOT4yCxwGEDrHczqpavw,3864
|
|
89
88
|
code_puppy/command_line/mcp/stop_command.py,sha256=iMzk9h6NuUDg0hhI5eDLem5VS8IwBC7xg8AU-7jsmBE,2679
|
|
@@ -91,7 +90,7 @@ code_puppy/command_line/mcp/test_command.py,sha256=eV8u5KKClRK1M2_os1zA78b9TDuYU
|
|
|
91
90
|
code_puppy/command_line/mcp/utils.py,sha256=0Wt4ttYgSlVvtusYmBLKXSkjAjcsDiUxcZQAoFLUNnE,3625
|
|
92
91
|
code_puppy/command_line/mcp/wizard_utils.py,sha256=M5X8RchkQujKYKORsXJnUq2kJHzmNfutIUrsHmfzi7k,11126
|
|
93
92
|
code_puppy/mcp_/__init__.py,sha256=P9bmVX5UDmzQDqHMylOxuo5Hi82E30pPSMOYw8lEx7Q,1781
|
|
94
|
-
code_puppy/mcp_/async_lifecycle.py,sha256=
|
|
93
|
+
code_puppy/mcp_/async_lifecycle.py,sha256=XVB73WOc2_sWi0ySWh_h6n5a-xtt72BGvtajyeoKW20,9014
|
|
95
94
|
code_puppy/mcp_/blocking_startup.py,sha256=27R2wwLVDu5i19IP90KmCn_zHrvVcHVNU8d9c8EcTeI,14780
|
|
96
95
|
code_puppy/mcp_/captured_stdio_server.py,sha256=t_mnCjtiopRsyi4Aa97rFzDVxEQmb-u94sWJsj2FP8k,8925
|
|
97
96
|
code_puppy/mcp_/circuit_breaker.py,sha256=a83YwXux9h4R6zBWBUrCIqtp2ffyl7JZEoK2tErG_0I,8601
|
|
@@ -99,8 +98,8 @@ code_puppy/mcp_/config_wizard.py,sha256=JNNpgnSD6PFSyS3pTdEdD164oXd2VKp4VHLSz3To
|
|
|
99
98
|
code_puppy/mcp_/dashboard.py,sha256=VtaFxLtPnbM_HL2TXRDAg6IqcM-EcFkoghGgkfhMrKI,9417
|
|
100
99
|
code_puppy/mcp_/error_isolation.py,sha256=mpPBiH17zTXPsOEAn9WmkbwQwnt4gmgiaWv87JBJbUo,12426
|
|
101
100
|
code_puppy/mcp_/health_monitor.py,sha256=n5R6EeYOYbUucUFe74qGWCU3g6Mep5UEQbLF0wbT0dU,19688
|
|
102
|
-
code_puppy/mcp_/managed_server.py,sha256=
|
|
103
|
-
code_puppy/mcp_/manager.py,sha256=
|
|
101
|
+
code_puppy/mcp_/managed_server.py,sha256=e-DetKb3bVgdLYw7miTptLAbqhRgZ1cNoTGS0fh4Noo,15371
|
|
102
|
+
code_puppy/mcp_/manager.py,sha256=_2ZRTLS8Sf3SMgEpAHl-wXBDYVqg2l-j9uI9EkfCNaE,31062
|
|
104
103
|
code_puppy/mcp_/mcp_logs.py,sha256=o4pSHwELWIjEjqhfaMMEGrBvb159-VIgUp21E707BPo,6264
|
|
105
104
|
code_puppy/mcp_/registry.py,sha256=U_t12WQ-En-KGyZoiTYdqlhp9NkDTWafu8g5InvF2NM,15774
|
|
106
105
|
code_puppy/mcp_/retry_manager.py,sha256=evVxbtrsHNyo8UoI7zpO-NVDegibn82RLlgN8VKewA8,10665
|
|
@@ -112,7 +111,7 @@ code_puppy/messaging/__init__.py,sha256=THJQDdRub3jiWIRPqF34VggXem3Y2tuUFAJGdDAL
|
|
|
112
111
|
code_puppy/messaging/bus.py,sha256=TbdltJ0D5tqnaE4irq1fcXllDYm-mQ_SiX1IFm-S4sw,21406
|
|
113
112
|
code_puppy/messaging/commands.py,sha256=77CtKVNaF5KS3Xyzd0ccDAisZWQxL3weVEt3J-SfYxo,5464
|
|
114
113
|
code_puppy/messaging/markdown_patches.py,sha256=dMIJozzJChuHa8QNMSEz_kC-dyt7kZiDLZ7rjthbcmg,1626
|
|
115
|
-
code_puppy/messaging/message_queue.py,sha256=
|
|
114
|
+
code_puppy/messaging/message_queue.py,sha256=1-5NFWIes5kpecsKnhuQQJPeT0-X102Xi1-IwXUM5_Y,11430
|
|
116
115
|
code_puppy/messaging/messages.py,sha256=F7RwMHeQrIk-8kuSSBU76wBq1NGuLb2H5cJrSMTC3XM,16464
|
|
117
116
|
code_puppy/messaging/queue_console.py,sha256=T0U_V1tdN6hd9DLokp-HCk0mhu8Ivpfajha368CBZrU,9983
|
|
118
117
|
code_puppy/messaging/renderers.py,sha256=GHVtMnxE1pJ-yrcRjacY81JcjlHRz3UVHzp-ohN-CGE,12058
|
|
@@ -159,7 +158,7 @@ code_puppy/plugins/shell_safety/command_cache.py,sha256=adYtSPNVOZfW_6dQdtEihO6E
|
|
|
159
158
|
code_puppy/plugins/shell_safety/register_callbacks.py,sha256=W3v664RR48Fdbbbltf_NnX22_Ahw2AvAOtvXvWc7KxQ,7322
|
|
160
159
|
code_puppy/prompts/codex_system_prompt.md,sha256=hEFTCziroLqZmqNle5kG34A8kvTteOWezCiVrAEKhE0,24400
|
|
161
160
|
code_puppy/tools/__init__.py,sha256=BVTZ85jLHgDANwOnUSOz3UDlp8VQDq4DoGF23BRlyWw,6032
|
|
162
|
-
code_puppy/tools/agent_tools.py,sha256=
|
|
161
|
+
code_puppy/tools/agent_tools.py,sha256=ZV2fdfBn02oj5jYA2Hg27lBAJqzwCCJXbglq20aBD60,19249
|
|
163
162
|
code_puppy/tools/command_runner.py,sha256=3qXVnVTaBPia6y2D29As47_TRKgpyCj82yMFK-8UUYc,44954
|
|
164
163
|
code_puppy/tools/common.py,sha256=IYf-KOcP5eN2MwTlpULSXNATn7GzloAKl7_M1Uyfe4Y,40360
|
|
165
164
|
code_puppy/tools/file_modifications.py,sha256=vz9n7R0AGDSdLUArZr_55yJLkyI30M8zreAppxIx02M,29380
|
|
@@ -174,11 +173,11 @@ code_puppy/tools/browser/browser_screenshot.py,sha256=7jeG5N4-OkpRPY3JMwOrsJjutY
|
|
|
174
173
|
code_puppy/tools/browser/browser_scripts.py,sha256=sNb8eLEyzhasy5hV4B9OjM8yIVMLVEMRcQ4K77ABjRI,14564
|
|
175
174
|
code_puppy/tools/browser/browser_workflows.py,sha256=nitW42vCf0ieTX1gLabozTugNQ8phtoFzZbiAhw1V90,6491
|
|
176
175
|
code_puppy/tools/browser/camoufox_manager.py,sha256=RZjGOEftE5sI_tsercUyXFSZI2wpStXf-q0PdYh2G3I,8680
|
|
177
|
-
code_puppy/tools/browser/vqa_agent.py,sha256=
|
|
178
|
-
code_puppy-0.0.
|
|
179
|
-
code_puppy-0.0.
|
|
180
|
-
code_puppy-0.0.
|
|
181
|
-
code_puppy-0.0.
|
|
182
|
-
code_puppy-0.0.
|
|
183
|
-
code_puppy-0.0.
|
|
184
|
-
code_puppy-0.0.
|
|
176
|
+
code_puppy/tools/browser/vqa_agent.py,sha256=CkGtRUPOR35383J6nrKFgcTj86RZqUpPhOdZr5xYutA,2728
|
|
177
|
+
code_puppy-0.0.345.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
|
|
178
|
+
code_puppy-0.0.345.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
|
|
179
|
+
code_puppy-0.0.345.dist-info/METADATA,sha256=GTbxQ3FIm0hBMAJpg3t38ryZxAE-1JoCt7V0n5zGir8,26014
|
|
180
|
+
code_puppy-0.0.345.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
181
|
+
code_puppy-0.0.345.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
|
|
182
|
+
code_puppy-0.0.345.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
|
|
183
|
+
code_puppy-0.0.345.dist-info/RECORD,,
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
MCP Add Command - Adds new MCP servers from JSON configuration or wizard.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import json
|
|
6
|
-
import logging
|
|
7
|
-
import os
|
|
8
|
-
from typing import List, Optional
|
|
9
|
-
|
|
10
|
-
from code_puppy.messaging import emit_error, emit_info
|
|
11
|
-
|
|
12
|
-
from .base import MCPCommandBase
|
|
13
|
-
from .wizard_utils import run_interactive_install_wizard
|
|
14
|
-
|
|
15
|
-
# Configure logging
|
|
16
|
-
logger = logging.getLogger(__name__)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class AddCommand(MCPCommandBase):
|
|
20
|
-
"""
|
|
21
|
-
Command handler for adding MCP servers.
|
|
22
|
-
|
|
23
|
-
Adds new MCP servers from JSON configuration or interactive wizard.
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
def execute(self, args: List[str], group_id: Optional[str] = None) -> None:
|
|
27
|
-
"""
|
|
28
|
-
Add a new MCP server from JSON configuration or launch wizard.
|
|
29
|
-
|
|
30
|
-
Usage:
|
|
31
|
-
/mcp add - Launch interactive wizard
|
|
32
|
-
/mcp add <json> - Add server from JSON config
|
|
33
|
-
|
|
34
|
-
Example JSON:
|
|
35
|
-
/mcp add {"name": "test", "type": "stdio", "command": "echo", "args": ["hello"]}
|
|
36
|
-
|
|
37
|
-
Args:
|
|
38
|
-
args: Command arguments - JSON config or empty for wizard
|
|
39
|
-
group_id: Optional message group ID for grouping related messages
|
|
40
|
-
"""
|
|
41
|
-
if group_id is None:
|
|
42
|
-
group_id = self.generate_group_id()
|
|
43
|
-
|
|
44
|
-
try:
|
|
45
|
-
if args:
|
|
46
|
-
# Parse JSON from arguments
|
|
47
|
-
json_str = " ".join(args)
|
|
48
|
-
|
|
49
|
-
try:
|
|
50
|
-
config_dict = json.loads(json_str)
|
|
51
|
-
except json.JSONDecodeError as e:
|
|
52
|
-
emit_info(f"Invalid JSON: {e}", message_group=group_id)
|
|
53
|
-
emit_info(
|
|
54
|
-
"Usage: /mcp add <json> or /mcp add (for wizard)",
|
|
55
|
-
message_group=group_id,
|
|
56
|
-
)
|
|
57
|
-
emit_info(
|
|
58
|
-
'Example: /mcp add {"name": "test", "type": "stdio", "command": "echo"}',
|
|
59
|
-
message_group=group_id,
|
|
60
|
-
)
|
|
61
|
-
return
|
|
62
|
-
|
|
63
|
-
# Validate required fields
|
|
64
|
-
if "name" not in config_dict:
|
|
65
|
-
emit_info("Missing required field: 'name'", message_group=group_id)
|
|
66
|
-
return
|
|
67
|
-
if "type" not in config_dict:
|
|
68
|
-
emit_info("Missing required field: 'type'", message_group=group_id)
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
# Add the server
|
|
72
|
-
success = self._add_server_from_json(config_dict, group_id)
|
|
73
|
-
|
|
74
|
-
if success:
|
|
75
|
-
# Reload MCP servers
|
|
76
|
-
try:
|
|
77
|
-
from code_puppy.agent import reload_mcp_servers
|
|
78
|
-
|
|
79
|
-
reload_mcp_servers()
|
|
80
|
-
except ImportError:
|
|
81
|
-
pass
|
|
82
|
-
|
|
83
|
-
emit_info(
|
|
84
|
-
"Use '/mcp list' to see all servers", message_group=group_id
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
else:
|
|
88
|
-
# No arguments - launch interactive wizard with server templates
|
|
89
|
-
success = run_interactive_install_wizard(self.manager, group_id)
|
|
90
|
-
|
|
91
|
-
if success:
|
|
92
|
-
# Reload the agent to pick up new server
|
|
93
|
-
try:
|
|
94
|
-
from code_puppy.agent import reload_mcp_servers
|
|
95
|
-
|
|
96
|
-
reload_mcp_servers()
|
|
97
|
-
except ImportError:
|
|
98
|
-
pass
|
|
99
|
-
|
|
100
|
-
except ImportError as e:
|
|
101
|
-
logger.error(f"Failed to import: {e}")
|
|
102
|
-
emit_info("Required module not available", message_group=group_id)
|
|
103
|
-
except Exception as e:
|
|
104
|
-
logger.error(f"Error in add command: {e}")
|
|
105
|
-
emit_error(f"Error adding server: {e}", message_group=group_id)
|
|
106
|
-
|
|
107
|
-
def _add_server_from_json(self, config_dict: dict, group_id: str) -> bool:
|
|
108
|
-
"""
|
|
109
|
-
Add a server from JSON configuration.
|
|
110
|
-
|
|
111
|
-
Args:
|
|
112
|
-
config_dict: Server configuration dictionary
|
|
113
|
-
group_id: Message group ID
|
|
114
|
-
|
|
115
|
-
Returns:
|
|
116
|
-
True if successful, False otherwise
|
|
117
|
-
"""
|
|
118
|
-
try:
|
|
119
|
-
from code_puppy.config import MCP_SERVERS_FILE
|
|
120
|
-
from code_puppy.mcp_.managed_server import ServerConfig
|
|
121
|
-
|
|
122
|
-
# Extract required fields
|
|
123
|
-
name = config_dict.pop("name")
|
|
124
|
-
server_type = config_dict.pop("type")
|
|
125
|
-
enabled = config_dict.pop("enabled", True)
|
|
126
|
-
|
|
127
|
-
# Everything else goes into config
|
|
128
|
-
server_config = ServerConfig(
|
|
129
|
-
id=f"{name}_{hash(name)}",
|
|
130
|
-
name=name,
|
|
131
|
-
type=server_type,
|
|
132
|
-
enabled=enabled,
|
|
133
|
-
config=config_dict, # Remaining fields are server-specific config
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
# Register the server
|
|
137
|
-
server_id = self.manager.register_server(server_config)
|
|
138
|
-
|
|
139
|
-
if not server_id:
|
|
140
|
-
emit_info(f"Failed to add server '{name}'", message_group=group_id)
|
|
141
|
-
return False
|
|
142
|
-
|
|
143
|
-
emit_info(
|
|
144
|
-
f"✅ Added server '{name}' (ID: {server_id})", message_group=group_id
|
|
145
|
-
)
|
|
146
|
-
|
|
147
|
-
# Save to mcp_servers.json for persistence
|
|
148
|
-
if os.path.exists(MCP_SERVERS_FILE):
|
|
149
|
-
with open(MCP_SERVERS_FILE, "r") as f:
|
|
150
|
-
data = json.load(f)
|
|
151
|
-
servers = data.get("mcp_servers", {})
|
|
152
|
-
else:
|
|
153
|
-
servers = {}
|
|
154
|
-
data = {"mcp_servers": servers}
|
|
155
|
-
|
|
156
|
-
# Add new server
|
|
157
|
-
servers[name] = config_dict.copy()
|
|
158
|
-
servers[name]["type"] = server_type
|
|
159
|
-
|
|
160
|
-
# Save back
|
|
161
|
-
os.makedirs(os.path.dirname(MCP_SERVERS_FILE), exist_ok=True)
|
|
162
|
-
with open(MCP_SERVERS_FILE, "w") as f:
|
|
163
|
-
json.dump(data, f, indent=2)
|
|
164
|
-
|
|
165
|
-
return True
|
|
166
|
-
|
|
167
|
-
except Exception as e:
|
|
168
|
-
logger.error(f"Error adding server from JSON: {e}")
|
|
169
|
-
emit_error(f"Failed to add server: {e}", message_group=group_id)
|
|
170
|
-
return False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|