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.
Files changed (28) hide show
  1. code_puppy/agents/base_agent.py +37 -129
  2. code_puppy/cli_runner.py +0 -35
  3. code_puppy/command_line/add_model_menu.py +8 -9
  4. code_puppy/command_line/config_commands.py +0 -10
  5. code_puppy/command_line/mcp/catalog_server_installer.py +5 -6
  6. code_puppy/command_line/mcp/custom_server_form.py +54 -19
  7. code_puppy/command_line/mcp/custom_server_installer.py +8 -9
  8. code_puppy/command_line/mcp/handler.py +0 -2
  9. code_puppy/command_line/mcp/help_command.py +1 -5
  10. code_puppy/command_line/mcp/start_command.py +36 -18
  11. code_puppy/command_line/onboarding_slides.py +0 -1
  12. code_puppy/command_line/utils.py +54 -0
  13. code_puppy/config.py +0 -23
  14. code_puppy/mcp_/async_lifecycle.py +35 -4
  15. code_puppy/mcp_/managed_server.py +49 -20
  16. code_puppy/mcp_/manager.py +81 -52
  17. code_puppy/messaging/message_queue.py +11 -23
  18. code_puppy/summarization_agent.py +1 -11
  19. code_puppy/tools/agent_tools.py +11 -55
  20. code_puppy/tools/browser/vqa_agent.py +1 -7
  21. {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/METADATA +1 -23
  22. {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/RECORD +27 -28
  23. code_puppy/command_line/mcp/add_command.py +0 -170
  24. {code_puppy-0.0.343.data → code_puppy-0.0.345.data}/data/code_puppy/models.json +0 -0
  25. {code_puppy-0.0.343.data → code_puppy-0.0.345.data}/data/code_puppy/models_dev_api.json +0 -0
  26. {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/WHEEL +0 -0
  27. {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/entry_points.txt +0 -0
  28. {code_puppy-0.0.343.dist-info → code_puppy-0.0.345.dist-info}/licenses/LICENSE +0 -0
@@ -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
- workflow_id = None # Track for potential cancellation
498
- if get_use_dbos():
499
- # Generate a unique workflow ID for DBOS - ensures no collisions in back-to-back calls
500
- workflow_id = _generate_dbos_workflow_id(group_id)
501
- with SetWorkflowID(workflow_id):
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
- _active_subagent_tasks.add(task)
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 get_use_dbos, get_vqa_model_name
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.343
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=BQu5Sa9y_ueqtgvbmuhWS-Tmd1FAjMbhTrtjFKbVZjM,34919
7
- code_puppy/config.py,sha256=RlnrLkyFXm7h2Htf8rQA7vqoAyzLPMrESle417uLmFw,52373
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=6Pu_Wp_rF-HAhoX9u2uXTabRVkOZUYwRoMP1lzNS4ew,4485
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=QnPmROIw-rs5wopcVTZdBZusP0mGRC6EFZ7y_V00rMI,84825
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=caXxSQc6dgx0qQ68RRFrDTsiH-wZjl4nUv2r0javhaM,43262
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=qS9Cm758DPz2QGvHLhAV4Tp_Xfgo3PyoCoLDusbnmCw,25742
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=tHob7rB_n32dfjtPH-RSG0WLMjDHhlmNxfsF7WCgcVc,7191
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=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
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=vY7MAy6O92bs-gRoZOO9jVPx23omr0jpSZucfjVkeOY,6170
73
- code_puppy/command_line/mcp/custom_server_form.py,sha256=iLEe30NI_01PP7xETgckBqwlyVrPzbHmzx7by8QKiVA,22082
74
- code_puppy/command_line/mcp/custom_server_installer.py,sha256=4NhHxf4wGUh4OvdIurZAlC7TrNcmm4j8dWucIKrekWg,5733
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=S8KSgf78w7vL7_ReArdcxTgZRoIi0Z0jCksNuELnCFU,4616
77
- code_puppy/command_line/mcp/help_command.py,sha256=dU3ekOjjNKxRS-RjUXJZ7PBwmJeIe-5MhcMYCiyVu4w,5472
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=EWXc_05nZaHCAmGxjXZJngEzlwq1HzBh6SNeki7ufGI,3409
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=pTQrwQCVgjad8EJeRTSHtIeSQRgT_8r5BeLv-1SgKog,7772
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=APqFKjHtsG8iM4so1dYxvKnb0BTmppHnaY8UJ5DBE9g,14075
103
- code_puppy/mcp_/manager.py,sha256=pJ4cALicTxfwG2JIjJraLLf0Mzes-cEVAKIcUwfOoKA,29172
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=e-viZxacBoNSxRJnCJ4hU4vzsSI3oX_rN58RwhJKFfU,11825
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=snBI6FlFtR03CbYKXwu53R48c_fRSuDIwcNdVUruLcA,21020
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=DBn9HKloILqJSTSdNZzH_PYWT0B2h9VwmY6akFQI_uU,2913
178
- code_puppy-0.0.343.data/data/code_puppy/models.json,sha256=FMQdE_yvP_8y0xxt3K918UkFL9cZMYAqW1SfXcQkU_k,3105
179
- code_puppy-0.0.343.data/data/code_puppy/models_dev_api.json,sha256=wHjkj-IM_fx1oHki6-GqtOoCrRMR0ScK0f-Iz0UEcy8,548187
180
- code_puppy-0.0.343.dist-info/METADATA,sha256=cC9Qt3q-Sn2DgGTrjH_RfHN5qN8vNVzIaKafyQBeokU,27550
181
- code_puppy-0.0.343.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
182
- code_puppy-0.0.343.dist-info/entry_points.txt,sha256=Tp4eQC99WY3HOKd3sdvb22vZODRq0XkZVNpXOag_KdI,91
183
- code_puppy-0.0.343.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
184
- code_puppy-0.0.343.dist-info/RECORD,,
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