sgar 0.1.3__tar.gz
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.
- sgar-0.1.3/LICENSE +6 -0
- sgar-0.1.3/MANIFEST.in +7 -0
- sgar-0.1.3/PKG-INFO +90 -0
- sgar-0.1.3/README.md +52 -0
- sgar-0.1.3/core/__init__.py +7 -0
- sgar-0.1.3/core/cc/__init__.py +119 -0
- sgar-0.1.3/core/cc/agents/__init__.py +10 -0
- sgar-0.1.3/core/cc/agents/agent_tool.py +320 -0
- sgar-0.1.3/core/cc/agents/backends/__init__.py +11 -0
- sgar-0.1.3/core/cc/agents/backends/base.py +62 -0
- sgar-0.1.3/core/cc/agents/backends/in_process.py +126 -0
- sgar-0.1.3/core/cc/agents/backends/local_subprocess.py +332 -0
- sgar-0.1.3/core/cc/agents/definitions.py +25 -0
- sgar-0.1.3/core/cc/agents/runtime.py +208 -0
- sgar-0.1.3/core/cc/agents/runtime_registry.py +88 -0
- sgar-0.1.3/core/cc/agents/runtime_transport.py +66 -0
- sgar-0.1.3/core/cc/agents/swarm/__init__.py +3 -0
- sgar-0.1.3/core/cc/agents/swarm/mailbox.py +310 -0
- sgar-0.1.3/core/cc/agents/task_manager.py +101 -0
- sgar-0.1.3/core/cc/agents/task_model.py +106 -0
- sgar-0.1.3/core/cc/agents/task_state_store.py +149 -0
- sgar-0.1.3/core/cc/api.py +413 -0
- sgar-0.1.3/core/cc/artifact_state.py +156 -0
- sgar-0.1.3/core/cc/audit.py +255 -0
- sgar-0.1.3/core/cc/command_runner.py +331 -0
- sgar-0.1.3/core/cc/config.py +830 -0
- sgar-0.1.3/core/cc/conversation/__init__.py +47 -0
- sgar-0.1.3/core/cc/conversation/agent_mode_strategy.py +129 -0
- sgar-0.1.3/core/cc/conversation/compact.py +69 -0
- sgar-0.1.3/core/cc/conversation/context_assembler.py +142 -0
- sgar-0.1.3/core/cc/conversation/llm_adapter.py +410 -0
- sgar-0.1.3/core/cc/conversation/message_store.py +98 -0
- sgar-0.1.3/core/cc/conversation/middleware.py +288 -0
- sgar-0.1.3/core/cc/conversation/mode_strategy.py +280 -0
- sgar-0.1.3/core/cc/conversation/models.py +73 -0
- sgar-0.1.3/core/cc/conversation/prompt_builder.py +162 -0
- sgar-0.1.3/core/cc/conversation/prompt_catalog.py +98 -0
- sgar-0.1.3/core/cc/conversation/protocol.py +28 -0
- sgar-0.1.3/core/cc/conversation/query_engine.py +483 -0
- sgar-0.1.3/core/cc/conversation/query_loop.py +1173 -0
- sgar-0.1.3/core/cc/conversation/query_loop_followup.py +105 -0
- sgar-0.1.3/core/cc/conversation/query_loop_implementation_sync.py +95 -0
- sgar-0.1.3/core/cc/conversation/query_loop_mode_transitions.py +127 -0
- sgar-0.1.3/core/cc/conversation/query_loop_tool_events.py +94 -0
- sgar-0.1.3/core/cc/conversation/session.py +119 -0
- sgar-0.1.3/core/cc/conversation/session_journal.py +70 -0
- sgar-0.1.3/core/cc/conversation/strategy_common.py +93 -0
- sgar-0.1.3/core/cc/conversation/tool_ledger.py +179 -0
- sgar-0.1.3/core/cc/conversation/turn_pipeline.py +315 -0
- sgar-0.1.3/core/cc/editing/__init__.py +16 -0
- sgar-0.1.3/core/cc/editing/facade.py +288 -0
- sgar-0.1.3/core/cc/editing/file_state.py +61 -0
- sgar-0.1.3/core/cc/editing/requests.py +76 -0
- sgar-0.1.3/core/cc/editing/rollback.py +150 -0
- sgar-0.1.3/core/cc/editing/validator.py +107 -0
- sgar-0.1.3/core/cc/engine_factory.py +116 -0
- sgar-0.1.3/core/cc/errors.py +46 -0
- sgar-0.1.3/core/cc/jsonl.py +105 -0
- sgar-0.1.3/core/cc/llm.py +112 -0
- sgar-0.1.3/core/cc/memory/__init__.py +26 -0
- sgar-0.1.3/core/cc/memory/base.py +40 -0
- sgar-0.1.3/core/cc/memory/extractor.py +257 -0
- sgar-0.1.3/core/cc/memory/models.py +133 -0
- sgar-0.1.3/core/cc/memory/noop_provider.py +51 -0
- sgar-0.1.3/core/cc/memory/policy.py +70 -0
- sgar-0.1.3/core/cc/memory/registry.py +30 -0
- sgar-0.1.3/core/cc/memory/runtime.py +289 -0
- sgar-0.1.3/core/cc/memory/serializer.py +53 -0
- sgar-0.1.3/core/cc/observability.py +54 -0
- sgar-0.1.3/core/cc/plan.py +99 -0
- sgar-0.1.3/core/cc/prompt_cc_review.md +100 -0
- sgar-0.1.3/core/cc/prompts/agents/worker.en.md +3 -0
- sgar-0.1.3/core/cc/prompts/agents/worker.zh.md +3 -0
- sgar-0.1.3/core/cc/prompts/system/agent_mode.en.md +34 -0
- sgar-0.1.3/core/cc/prompts/system/agent_mode.zh.md +34 -0
- sgar-0.1.3/core/cc/prompts/system/agent_mode_followup.en.md +8 -0
- sgar-0.1.3/core/cc/prompts/system/agent_mode_followup.zh.md +8 -0
- sgar-0.1.3/core/cc/prompts/system/ask_mode.en.md +30 -0
- sgar-0.1.3/core/cc/prompts/system/ask_mode.zh.md +30 -0
- sgar-0.1.3/core/cc/prompts/system/code_build.en.md +36 -0
- sgar-0.1.3/core/cc/prompts/system/code_build.zh.md +36 -0
- sgar-0.1.3/core/cc/prompts/system/coordinator.en.md +3 -0
- sgar-0.1.3/core/cc/prompts/system/coordinator.zh.md +3 -0
- sgar-0.1.3/core/cc/prompts/system/default.en.md +36 -0
- sgar-0.1.3/core/cc/prompts/system/default.zh.md +36 -0
- sgar-0.1.3/core/cc/prompts/system/doc_mode.en.md +37 -0
- sgar-0.1.3/core/cc/prompts/system/doc_mode.zh.md +37 -0
- sgar-0.1.3/core/cc/prompts/system/implementation_followup.en.md +6 -0
- sgar-0.1.3/core/cc/prompts/system/implementation_followup.zh.md +6 -0
- sgar-0.1.3/core/cc/prompts/system/implementation_task_sync_followup.en.md +8 -0
- sgar-0.1.3/core/cc/prompts/system/implementation_task_sync_followup.zh.md +8 -0
- sgar-0.1.3/core/cc/prompts/system/plan_implementation.en.md +32 -0
- sgar-0.1.3/core/cc/prompts/system/plan_implementation.zh.md +32 -0
- sgar-0.1.3/core/cc/prompts/system/plan_mode.en.md +52 -0
- sgar-0.1.3/core/cc/prompts/system/plan_mode.zh.md +52 -0
- sgar-0.1.3/core/cc/prompts/system/query_continue.en.md +1 -0
- sgar-0.1.3/core/cc/prompts/system/query_continue.zh.md +1 -0
- sgar-0.1.3/core/cc/prompts/system/render_followup.en.md +5 -0
- sgar-0.1.3/core/cc/prompts/system/render_followup.zh.md +5 -0
- sgar-0.1.3/core/cc/prompts/system/spec_mode.en.md +41 -0
- sgar-0.1.3/core/cc/prompts/system/spec_mode.zh.md +41 -0
- sgar-0.1.3/core/cc/prompts/system/spec_render.en.md +35 -0
- sgar-0.1.3/core/cc/prompts/system/spec_render.zh.md +35 -0
- sgar-0.1.3/core/cc/prompts/system/swarm_planner.en.md +35 -0
- sgar-0.1.3/core/cc/prompts/system/swarm_planner.zh.md +35 -0
- sgar-0.1.3/core/cc/prompts/system/tool_followup.en.md +1 -0
- sgar-0.1.3/core/cc/prompts/system/tool_followup.zh.md +1 -0
- sgar-0.1.3/core/cc/prompts/tools/file_edit.en.md +3 -0
- sgar-0.1.3/core/cc/prompts/tools/file_edit.zh.md +3 -0
- sgar-0.1.3/core/cc/providers.py +215 -0
- sgar-0.1.3/core/cc/runtime.py +29 -0
- sgar-0.1.3/core/cc/safety/__init__.py +11 -0
- sgar-0.1.3/core/cc/safety/classifier.py +82 -0
- sgar-0.1.3/core/cc/safety/command_rules.py +170 -0
- sgar-0.1.3/core/cc/safety/decision.py +17 -0
- sgar-0.1.3/core/cc/safety/file_rules.py +32 -0
- sgar-0.1.3/core/cc/safety/permission_mode.py +35 -0
- sgar-0.1.3/core/cc/specs.py +99 -0
- sgar-0.1.3/core/cc/structured_flow.py +548 -0
- sgar-0.1.3/core/cc/tools/__init__.py +59 -0
- sgar-0.1.3/core/cc/tools/base.py +94 -0
- sgar-0.1.3/core/cc/tools/builtin.py +80 -0
- sgar-0.1.3/core/cc/tools/context.py +73 -0
- sgar-0.1.3/core/cc/tools/enter_plan_mode.py +68 -0
- sgar-0.1.3/core/cc/tools/enter_spec_mode.py +68 -0
- sgar-0.1.3/core/cc/tools/executor.py +107 -0
- sgar-0.1.3/core/cc/tools/exit_plan_mode.py +95 -0
- sgar-0.1.3/core/cc/tools/exit_spec_mode.py +95 -0
- sgar-0.1.3/core/cc/tools/file_edit.py +124 -0
- sgar-0.1.3/core/cc/tools/file_read.py +139 -0
- sgar-0.1.3/core/cc/tools/file_write.py +105 -0
- sgar-0.1.3/core/cc/tools/glob_tool.py +79 -0
- sgar-0.1.3/core/cc/tools/grep_tool.py +453 -0
- sgar-0.1.3/core/cc/tools/memory.py +145 -0
- sgar-0.1.3/core/cc/tools/memory_fact.py +114 -0
- sgar-0.1.3/core/cc/tools/memory_search.py +62 -0
- sgar-0.1.3/core/cc/tools/memory_status.py +49 -0
- sgar-0.1.3/core/cc/tools/memory_store.py +72 -0
- sgar-0.1.3/core/cc/tools/orchestrator.py +249 -0
- sgar-0.1.3/core/cc/tools/plan_artifact_write.py +210 -0
- sgar-0.1.3/core/cc/tools/powershell.py +65 -0
- sgar-0.1.3/core/cc/tools/registry.py +29 -0
- sgar-0.1.3/core/cc/tools/result_mapper.py +47 -0
- sgar-0.1.3/core/cc/tools/run_tests.py +118 -0
- sgar-0.1.3/core/cc/tools/send_message.py +87 -0
- sgar-0.1.3/core/cc/tools/shell.py +113 -0
- sgar-0.1.3/core/cc/tools/spec_artifact_write.py +159 -0
- sgar-0.1.3/core/cc/tools/task_stop.py +77 -0
- sgar-0.1.3/core/cc/tools/todo_write.py +84 -0
- sgar-0.1.3/core/cc/tools/worktree.py +152 -0
- sgar-0.1.3/core/cc/usage.md +370 -0
- sgar-0.1.3/core/ccx/__init__.py +46 -0
- sgar-0.1.3/core/ccx/agents/__init__.py +17 -0
- sgar-0.1.3/core/ccx/agents/cc_agent.py +1149 -0
- sgar-0.1.3/core/ccx/agents/ccx_research_tool.py +304 -0
- sgar-0.1.3/core/ccx/agents/ccx_sgar_tool.py +278 -0
- sgar-0.1.3/core/ccx/agents/ccx_spawn_tool.py +357 -0
- sgar-0.1.3/core/ccx/agents/ccx_tool.py +571 -0
- sgar-0.1.3/core/ccx/agents/ctx_search_tool.py +372 -0
- sgar-0.1.3/core/ccx/agents/event_bridge.py +305 -0
- sgar-0.1.3/core/ccx/agents/goal_prompts.py +260 -0
- sgar-0.1.3/core/ccx/agents/governed_goal.py +1388 -0
- sgar-0.1.3/core/ccx/agents/governed_run.py +444 -0
- sgar-0.1.3/core/ccx/agents/governed_spawn.py +470 -0
- sgar-0.1.3/core/ccx/agents/metadata_inheritance.py +143 -0
- sgar-0.1.3/core/ccx/agents/read_only_runner.py +178 -0
- sgar-0.1.3/core/ccx/agents/research_runner.py +340 -0
- sgar-0.1.3/core/ccx/agents/subagent.py +216 -0
- sgar-0.1.3/core/ccx/agents/swarm/__init__.py +18 -0
- sgar-0.1.3/core/ccx/agents/swarm/coordinator.py +379 -0
- sgar-0.1.3/core/ccx/agents/swarm/mailbox_bridge.py +155 -0
- sgar-0.1.3/core/ccx/agents/swarm/team_runtime.py +365 -0
- sgar-0.1.3/core/ccx/agents/task_manager.py +402 -0
- sgar-0.1.3/core/ccx/api.py +2346 -0
- sgar-0.1.3/core/ccx/audit/__init__.py +95 -0
- sgar-0.1.3/core/ccx/audit/check_template.py +61 -0
- sgar-0.1.3/core/ccx/audit/code_task.py +320 -0
- sgar-0.1.3/core/ccx/audit/contract.py +95 -0
- sgar-0.1.3/core/ccx/audit/finding_ledger.py +143 -0
- sgar-0.1.3/core/ccx/audit/gitdiff.py +208 -0
- sgar-0.1.3/core/ccx/audit/ledger.py +92 -0
- sgar-0.1.3/core/ccx/audit/mutation.py +258 -0
- sgar-0.1.3/core/ccx/audit/regression_capture.py +276 -0
- sgar-0.1.3/core/ccx/audit/wiring.py +119 -0
- sgar-0.1.3/core/ccx/conversation/__init__.py +15 -0
- sgar-0.1.3/core/ccx/llm_monitor.py +1002 -0
- sgar-0.1.3/core/ccx/memory/__init__.py +36 -0
- sgar-0.1.3/core/ccx/memory/inject.py +32 -0
- sgar-0.1.3/core/ccx/memory/models.py +292 -0
- sgar-0.1.3/core/ccx/memory/recall.py +146 -0
- sgar-0.1.3/core/ccx/memory/store.py +272 -0
- sgar-0.1.3/core/ccx/memory/summarizer.py +174 -0
- sgar-0.1.3/core/ccx/modes/__init__.py +50 -0
- sgar-0.1.3/core/ccx/modes/_goal.py +19 -0
- sgar-0.1.3/core/ccx/modes/_paths.py +14 -0
- sgar-0.1.3/core/ccx/modes/_sgar_command_helpers.py +611 -0
- sgar-0.1.3/core/ccx/modes/_text_masking.py +83 -0
- sgar-0.1.3/core/ccx/modes/agent.py +245 -0
- sgar-0.1.3/core/ccx/modes/artifacts.py +189 -0
- sgar-0.1.3/core/ccx/modes/ask.py +256 -0
- sgar-0.1.3/core/ccx/modes/blueprint.py +82 -0
- sgar-0.1.3/core/ccx/modes/diagnostics.py +259 -0
- sgar-0.1.3/core/ccx/modes/doc.py +4825 -0
- sgar-0.1.3/core/ccx/modes/llm_client.py +223 -0
- sgar-0.1.3/core/ccx/modes/parsing.py +216 -0
- sgar-0.1.3/core/ccx/modes/plan.py +550 -0
- sgar-0.1.3/core/ccx/modes/prompts/__init__.py +234 -0
- sgar-0.1.3/core/ccx/modes/prompts/agent.toml +13 -0
- sgar-0.1.3/core/ccx/modes/prompts/doc_decompose.toml +71 -0
- sgar-0.1.3/core/ccx/modes/prompts/doc_investigator.toml +293 -0
- sgar-0.1.3/core/ccx/modes/prompts/doc_prose_to_json.toml +85 -0
- sgar-0.1.3/core/ccx/modes/prompts/doc_surveyor.toml +103 -0
- sgar-0.1.3/core/ccx/modes/prompts/plan.toml +40 -0
- sgar-0.1.3/core/ccx/modes/prompts/spec.toml +28 -0
- sgar-0.1.3/core/ccx/modes/prompts/watch_analyzer.toml +179 -0
- sgar-0.1.3/core/ccx/modes/prompts/watch_fixer.toml +74 -0
- sgar-0.1.3/core/ccx/modes/sgarx.py +83 -0
- sgar-0.1.3/core/ccx/modes/spec.py +375 -0
- sgar-0.1.3/core/ccx/modes/watch.py +2220 -0
- sgar-0.1.3/core/ccx/modes/watch_checks.py +786 -0
- sgar-0.1.3/core/ccx/mypy.ini +32 -0
- sgar-0.1.3/core/ccx/prompt_ccx_self_review.md +103 -0
- sgar-0.1.3/core/ccx/prompts.py +42 -0
- sgar-0.1.3/core/ccx/report.py +950 -0
- sgar-0.1.3/core/ccx/runtime.py +1015 -0
- sgar-0.1.3/core/ccx/services/__init__.py +27 -0
- sgar-0.1.3/core/ccx/services/cost_events.py +60 -0
- sgar-0.1.3/core/ccx/services/findings_collector.py +83 -0
- sgar-0.1.3/core/ccx/services/governance_events.py +132 -0
- sgar-0.1.3/core/ccx/services/repository_outline.py +152 -0
- sgar-0.1.3/core/ccx/services/steer_inbox.py +140 -0
- sgar-0.1.3/core/ccx/sgar/__init__.py +53 -0
- sgar-0.1.3/core/ccx/sgar/__main__.py +5 -0
- sgar-0.1.3/core/ccx/sgar/autobuild.py +189 -0
- sgar-0.1.3/core/ccx/sgar/checks.py +302 -0
- sgar-0.1.3/core/ccx/sgar/cli.py +325 -0
- sgar-0.1.3/core/ccx/sgar/missions.py +474 -0
- sgar-0.1.3/core/ccx/sgar/models.py +208 -0
- sgar-0.1.3/core/ccx/sgar/runtime.py +906 -0
- sgar-0.1.3/core/ccx/sgar/store.py +381 -0
- sgar-0.1.3/core/ccx/sgar/tracing.py +212 -0
- sgar-0.1.3/core/ccx/sgar/validation.py +247 -0
- sgar-0.1.3/core/ccx/sgarx/__init__.py +13 -0
- sgar-0.1.3/core/ccx/sgarx/runtime.py +661 -0
- sgar-0.1.3/core/ccx/sgarx/store.py +26 -0
- sgar-0.1.3/core/ccx/structured_flow.py +346 -0
- sgar-0.1.3/core/ccx/templates/report.html.j2 +547 -0
- sgar-0.1.3/core/ccx/watch.py +1326 -0
- sgar-0.1.3/core/deepstack_v5/__init__.py +66 -0
- sgar-0.1.3/core/deepstack_v5/config.py +97 -0
- sgar-0.1.3/core/deepstack_v5/control/__init__.py +0 -0
- sgar-0.1.3/core/deepstack_v5/control/budget.py +141 -0
- sgar-0.1.3/core/deepstack_v5/control/controller.py +159 -0
- sgar-0.1.3/core/deepstack_v5/control/escalation.py +109 -0
- sgar-0.1.3/core/deepstack_v5/engine.py +1530 -0
- sgar-0.1.3/core/deepstack_v5/events.py +164 -0
- sgar-0.1.3/core/deepstack_v5/execution/__init__.py +0 -0
- sgar-0.1.3/core/deepstack_v5/execution/assignment.py +121 -0
- sgar-0.1.3/core/deepstack_v5/execution/dispatch_context.py +94 -0
- sgar-0.1.3/core/deepstack_v5/execution/dispatcher.py +764 -0
- sgar-0.1.3/core/deepstack_v5/execution/graph.py +346 -0
- sgar-0.1.3/core/deepstack_v5/execution/node.py +214 -0
- sgar-0.1.3/core/deepstack_v5/execution/toolcall.py +152 -0
- sgar-0.1.3/core/deepstack_v5/knowledge/__init__.py +0 -0
- sgar-0.1.3/core/deepstack_v5/knowledge/claims.py +254 -0
- sgar-0.1.3/core/deepstack_v5/knowledge/compaction.py +209 -0
- sgar-0.1.3/core/deepstack_v5/memory/__init__.py +48 -0
- sgar-0.1.3/core/deepstack_v5/memory/content_store.py +816 -0
- sgar-0.1.3/core/deepstack_v5/memory/priority.py +122 -0
- sgar-0.1.3/core/deepstack_v5/memory/resume.py +128 -0
- sgar-0.1.3/core/deepstack_v5/memory/snapshot.py +262 -0
- sgar-0.1.3/core/deepstack_v5/persistence/__init__.py +31 -0
- sgar-0.1.3/core/deepstack_v5/persistence/db.py +436 -0
- sgar-0.1.3/core/deepstack_v5/persistence/file_backend.py +512 -0
- sgar-0.1.3/core/deepstack_v5/persistence/outbox.py +98 -0
- sgar-0.1.3/core/deepstack_v5/persistence/stores.py +1094 -0
- sgar-0.1.3/core/deepstack_v5/runtime.py +210 -0
- sgar-0.1.3/core/deepstack_v5/types.py +454 -0
- sgar-0.1.3/core/llms/__init__.py +1 -0
- sgar-0.1.3/core/llms/_deepseek_stream.py +400 -0
- sgar-0.1.3/core/llms/_llm_api_client.py +600 -0
- sgar-0.1.3/core/llms/ali_deep_seek_client.py +16 -0
- sgar-0.1.3/core/llms/ali_deep_seek_r1_client.py +16 -0
- sgar-0.1.3/core/llms/ark_client.py +16 -0
- sgar-0.1.3/core/llms/aws_deepseek_client.py +18 -0
- sgar-0.1.3/core/llms/aws_deepseek_r1_client.py +19 -0
- sgar-0.1.3/core/llms/azure_deep_seek_client.py +132 -0
- sgar-0.1.3/core/llms/baichuan_client.py +129 -0
- sgar-0.1.3/core/llms/bce_deep_seek_client.py +20 -0
- sgar-0.1.3/core/llms/bce_deep_seek_r1_client.py +20 -0
- sgar-0.1.3/core/llms/claude_aws_client.py +676 -0
- sgar-0.1.3/core/llms/claude_client.py +365 -0
- sgar-0.1.3/core/llms/deepbricks_client.py +16 -0
- sgar-0.1.3/core/llms/doubao_client.py +238 -0
- sgar-0.1.3/core/llms/dummy_client.py +32 -0
- sgar-0.1.3/core/llms/ernie_client.py +277 -0
- sgar-0.1.3/core/llms/fallback_client.py +181 -0
- sgar-0.1.3/core/llms/gemini2_client.py +385 -0
- sgar-0.1.3/core/llms/gemini_client.py +596 -0
- sgar-0.1.3/core/llms/gemini_pro_client.py +18 -0
- sgar-0.1.3/core/llms/glm_client.py +469 -0
- sgar-0.1.3/core/llms/glm_free_client.py +14 -0
- sgar-0.1.3/core/llms/glm_openai_client.py +19 -0
- sgar-0.1.3/core/llms/healer_alpha_client.py +16 -0
- sgar-0.1.3/core/llms/hunter_alpha_client.py +16 -0
- sgar-0.1.3/core/llms/hunyuan_client.py +266 -0
- sgar-0.1.3/core/llms/infini_deep_seek_client.py +23 -0
- sgar-0.1.3/core/llms/infini_deep_seek_r1_client.py +19 -0
- sgar-0.1.3/core/llms/kimi_client.py +21 -0
- sgar-0.1.3/core/llms/llm_factory.py +98 -0
- sgar-0.1.3/core/llms/mi_client.py +21 -0
- sgar-0.1.3/core/llms/mimo_client.py +16 -0
- sgar-0.1.3/core/llms/mini_max_client.py +308 -0
- sgar-0.1.3/core/llms/mini_max_pro.py +174 -0
- sgar-0.1.3/core/llms/mini_max_text_client.py +11 -0
- sgar-0.1.3/core/llms/minimax_r1_client.py +19 -0
- sgar-0.1.3/core/llms/minmax_m2_client.py +21 -0
- sgar-0.1.3/core/llms/moonshot_client.py +359 -0
- sgar-0.1.3/core/llms/multi_claude.py +456 -0
- sgar-0.1.3/core/llms/ollama_ds32b_client.py +21 -0
- sgar-0.1.3/core/llms/open_router_client.py +16 -0
- sgar-0.1.3/core/llms/openai_client.py +555 -0
- sgar-0.1.3/core/llms/openai_http_client.py +806 -0
- sgar-0.1.3/core/llms/ppio_claude_client.py +19 -0
- sgar-0.1.3/core/llms/ppio_claude_sonnet_client.py +19 -0
- sgar-0.1.3/core/llms/ppio_client.py +18 -0
- sgar-0.1.3/core/llms/ppio_cluade_opus_client.py +19 -0
- sgar-0.1.3/core/llms/ppio_deep_seek_client.py +18 -0
- sgar-0.1.3/core/llms/ppio_deep_seek_r1_cleint.py +19 -0
- sgar-0.1.3/core/llms/ppio_gemini_pro_client.py +19 -0
- sgar-0.1.3/core/llms/ppio_openai_client.py +19 -0
- sgar-0.1.3/core/llms/ppio_r_client.py +19 -0
- sgar-0.1.3/core/llms/px_client.py +442 -0
- sgar-0.1.3/core/llms/qianwen14_client.py +15 -0
- sgar-0.1.3/core/llms/qianwen32_client.py +15 -0
- sgar-0.1.3/core/llms/qianwen_client.py +442 -0
- sgar-0.1.3/core/llms/qianwen_coder_client.py +16 -0
- sgar-0.1.3/core/llms/qianwen_coder_plus_client.py +15 -0
- sgar-0.1.3/core/llms/qianwen_coder_turbo_client.py +15 -0
- sgar-0.1.3/core/llms/qianwen_plus.py +17 -0
- sgar-0.1.3/core/llms/qianwen_qwq_client.py +15 -0
- sgar-0.1.3/core/llms/qianwen_turbo.py +26 -0
- sgar-0.1.3/core/llms/qiniu_deep_seek_client.py +27 -0
- sgar-0.1.3/core/llms/qiniu_deep_seek_r1_client.py +23 -0
- sgar-0.1.3/core/llms/qwq_client.py +18 -0
- sgar-0.1.3/core/llms/sense_deep_seek_client.py +20 -0
- sgar-0.1.3/core/llms/sense_deep_seek_r1_client.py +24 -0
- sgar-0.1.3/core/llms/silicon_deep_seek_client.py +18 -0
- sgar-0.1.3/core/llms/silicon_deep_seek_r1_client.py +19 -0
- sgar-0.1.3/core/llms/simple_azure.py +336 -0
- sgar-0.1.3/core/llms/simple_claude.py +389 -0
- sgar-0.1.3/core/llms/simple_deep_seek_client.py +846 -0
- sgar-0.1.3/core/llms/simple_deep_seek_client_chat.py +116 -0
- sgar-0.1.3/core/llms/simple_deep_seek_client_reasoning.py +88 -0
- sgar-0.1.3/core/llms/simple_deep_seek_client_speciale.py +20 -0
- sgar-0.1.3/core/llms/simple_doubao_client.py +241 -0
- sgar-0.1.3/core/llms/spark_client.py +16 -0
- sgar-0.1.3/core/llms/tencent_deep_seek_client.py +21 -0
- sgar-0.1.3/core/llms/tencent_deep_seek_r1_client.py +23 -0
- sgar-0.1.3/core/llms/volc_deep_seek_client.py +19 -0
- sgar-0.1.3/core/llms/volc_deep_seek_r1_client.py +19 -0
- sgar-0.1.3/core/llms/zero1_improver_client.py +17 -0
- sgar-0.1.3/core/utils/CODE_MODIFICATION_TOOLS.md +628 -0
- sgar-0.1.3/core/utils/CODE_UPDATE_QUICKSTART.md +409 -0
- sgar-0.1.3/core/utils/FEE_READER_USAGE.md +270 -0
- sgar-0.1.3/core/utils/FIX_LLM_CLIENT_CHAT_METHOD.md +257 -0
- sgar-0.1.3/core/utils/UNIFIED_LOGGER_README.md +278 -0
- sgar-0.1.3/core/utils/__init__.py +43 -0
- sgar-0.1.3/core/utils/_legacy/llm_ast_editor.md +943 -0
- sgar-0.1.3/core/utils/autonomous_code_agent.md +558 -0
- sgar-0.1.3/core/utils/code_editor.md +340 -0
- sgar-0.1.3/core/utils/common.py +47 -0
- sgar-0.1.3/core/utils/config_setting.py +52 -0
- sgar-0.1.3/core/utils/editor_fallback.py +84 -0
- sgar-0.1.3/core/utils/error_classifier_helper.py +353 -0
- sgar-0.1.3/core/utils/handle_max_tokens.py +63 -0
- sgar-0.1.3/core/utils/how_to_use_code_editor.md +792 -0
- sgar-0.1.3/core/utils/json_from_text.py +694 -0
- sgar-0.1.3/core/utils/llm_block_editor.py +3204 -0
- sgar-0.1.3/core/utils/llm_block_editor_lnfree.py +1096 -0
- sgar-0.1.3/core/utils/llm_code_editor.py +1447 -0
- sgar-0.1.3/core/utils/log.py +250 -0
- sgar-0.1.3/core/utils/prompt_language.py +81 -0
- sgar-0.1.3/core/utils/rate_limit.py +35 -0
- sgar-0.1.3/core/utils/retry.py +19 -0
- sgar-0.1.3/core/utils/robust_llm_editor.py +1009 -0
- sgar-0.1.3/core/utils/single_ton.py +25 -0
- sgar-0.1.3/core/utils/smart_llm_editor_v2.py +1565 -0
- sgar-0.1.3/core/utils/source_code_manager.py +363 -0
- sgar-0.1.3/pyproject.toml +52 -0
- sgar-0.1.3/requirements.txt +24 -0
- sgar-0.1.3/setting.ini.template +131 -0
- sgar-0.1.3/setup.cfg +4 -0
- sgar-0.1.3/setup.py +5 -0
- sgar-0.1.3/sgar/__init__.py +3 -0
- sgar-0.1.3/sgar/__main__.py +5 -0
- sgar-0.1.3/sgar.egg-info/PKG-INFO +90 -0
- sgar-0.1.3/sgar.egg-info/SOURCES.txt +400 -0
- sgar-0.1.3/sgar.egg-info/dependency_links.txt +1 -0
- sgar-0.1.3/sgar.egg-info/entry_points.txt +2 -0
- sgar-0.1.3/sgar.egg-info/requires.txt +27 -0
- sgar-0.1.3/sgar.egg-info/top_level.txt +2 -0
sgar-0.1.3/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Copyright (c) 2026 wxy2ab. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is distributed as a proprietary, internal package ("sgar").
|
|
4
|
+
No license to use, copy, modify, or distribute is granted except by explicit
|
|
5
|
+
written permission of the copyright holder. Replace this file with the license
|
|
6
|
+
of your choice before any external distribution.
|
sgar-0.1.3/MANIFEST.in
ADDED
sgar-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sgar
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: SGAR — ccx 治理化 agent 运行时(自 llm_dealer 导出的独立分发)
|
|
5
|
+
Author: wxy2ab
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Keywords: ccx,sgar,agent,llm,governance
|
|
8
|
+
Requires-Python: >=3.12
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: anthropic
|
|
12
|
+
Requires-Dist: azure-ai-inference
|
|
13
|
+
Requires-Dist: boto3
|
|
14
|
+
Requires-Dist: colorlog
|
|
15
|
+
Requires-Dist: dashscope
|
|
16
|
+
Requires-Dist: google-generativeai
|
|
17
|
+
Requires-Dist: grep-ast
|
|
18
|
+
Requires-Dist: httpx
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Requires-Dist: numpy
|
|
21
|
+
Requires-Dist: openai
|
|
22
|
+
Requires-Dist: pandas
|
|
23
|
+
Requires-Dist: pillow
|
|
24
|
+
Requires-Dist: rank-bm25
|
|
25
|
+
Requires-Dist: ratelimit
|
|
26
|
+
Requires-Dist: regex
|
|
27
|
+
Requires-Dist: requests
|
|
28
|
+
Requires-Dist: tenacity
|
|
29
|
+
Requires-Dist: tencentcloud-sdk-python
|
|
30
|
+
Requires-Dist: tree-sitter
|
|
31
|
+
Requires-Dist: tree-sitter-python
|
|
32
|
+
Requires-Dist: volcengine-python-sdk[ark]
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest; extra == "dev"
|
|
35
|
+
Requires-Dist: mypy; extra == "dev"
|
|
36
|
+
Requires-Dist: ruff; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# sgar
|
|
40
|
+
|
|
41
|
+
`ccx` 治理化 agent 运行时,从 `llm_dealer` 仓库中按 `core/ccx` 的依赖闭包自动导出的
|
|
42
|
+
独立、可 pip 安装项目。
|
|
43
|
+
|
|
44
|
+
本目录由 `task/copy/ccx_out.py` 生成:包含 321 个源文件、61 个运行期资源文件,
|
|
45
|
+
覆盖子包 `core.cc`, `core.ccx`, `core.deepstack_v5`, `core.llms`, `core.utils`。
|
|
46
|
+
|
|
47
|
+
> 注意:分发名是 `sgar`,但可导入的顶层包是 `core`(保留原命名空间以免改写大量
|
|
48
|
+
> `import core.*`)。
|
|
49
|
+
|
|
50
|
+
## 安装
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install -e .
|
|
54
|
+
# 或
|
|
55
|
+
pip install .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
需要 Python >=3.12。
|
|
59
|
+
|
|
60
|
+
## 配置
|
|
61
|
+
|
|
62
|
+
复制配置模板并填入你的密钥:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cp setting.ini.template setting.ini
|
|
66
|
+
$EDITOR setting.ini
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
所有键也可以用同名大写的环境变量提供(见 `core/utils/config_setting.py`)。
|
|
70
|
+
`setting.ini` 含密钥,已在 `.gitignore` 中忽略,请勿提交。
|
|
71
|
+
|
|
72
|
+
## 使用
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
sgar --help # 安装后提供的命令行入口
|
|
76
|
+
python -m sgar --help
|
|
77
|
+
python -m core.ccx.sgar --help
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from core.ccx.api import AgentRunRequest # 程序化入口
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## 自动发布
|
|
85
|
+
|
|
86
|
+
- 每次 push 到 `main` 后,GitHub Actions 会自动将 `pyproject.toml` 的 patch 版本加 `1`。
|
|
87
|
+
- 版本 bump 成功后,会自动构建并发布到 PyPI。
|
|
88
|
+
- 如需手动发布,可在 GitHub Actions 里运行 `Publish sgar to PyPI`,并选择 `pypi` 或 `testpypi`。
|
|
89
|
+
- 正式发布使用 GitHub Repository Secret `PYPI_API_TOKEN`。
|
|
90
|
+
- 如需手动发布到 TestPyPI,请额外配置 `TEST_PYPI_API_TOKEN`。
|
sgar-0.1.3/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# sgar
|
|
2
|
+
|
|
3
|
+
`ccx` 治理化 agent 运行时,从 `llm_dealer` 仓库中按 `core/ccx` 的依赖闭包自动导出的
|
|
4
|
+
独立、可 pip 安装项目。
|
|
5
|
+
|
|
6
|
+
本目录由 `task/copy/ccx_out.py` 生成:包含 321 个源文件、61 个运行期资源文件,
|
|
7
|
+
覆盖子包 `core.cc`, `core.ccx`, `core.deepstack_v5`, `core.llms`, `core.utils`。
|
|
8
|
+
|
|
9
|
+
> 注意:分发名是 `sgar`,但可导入的顶层包是 `core`(保留原命名空间以免改写大量
|
|
10
|
+
> `import core.*`)。
|
|
11
|
+
|
|
12
|
+
## 安装
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install -e .
|
|
16
|
+
# 或
|
|
17
|
+
pip install .
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
需要 Python >=3.12。
|
|
21
|
+
|
|
22
|
+
## 配置
|
|
23
|
+
|
|
24
|
+
复制配置模板并填入你的密钥:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cp setting.ini.template setting.ini
|
|
28
|
+
$EDITOR setting.ini
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
所有键也可以用同名大写的环境变量提供(见 `core/utils/config_setting.py`)。
|
|
32
|
+
`setting.ini` 含密钥,已在 `.gitignore` 中忽略,请勿提交。
|
|
33
|
+
|
|
34
|
+
## 使用
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
sgar --help # 安装后提供的命令行入口
|
|
38
|
+
python -m sgar --help
|
|
39
|
+
python -m core.ccx.sgar --help
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from core.ccx.api import AgentRunRequest # 程序化入口
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 自动发布
|
|
47
|
+
|
|
48
|
+
- 每次 push 到 `main` 后,GitHub Actions 会自动将 `pyproject.toml` 的 patch 版本加 `1`。
|
|
49
|
+
- 版本 bump 成功后,会自动构建并发布到 PyPI。
|
|
50
|
+
- 如需手动发布,可在 GitHub Actions 里运行 `Publish sgar to PyPI`,并选择 `pypi` 或 `testpypi`。
|
|
51
|
+
- 正式发布使用 GitHub Repository Secret `PYPI_API_TOKEN`。
|
|
52
|
+
- 如需手动发布到 TestPyPI,请额外配置 `TEST_PYPI_API_TOKEN`。
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# ---------------------------------------------------------------------------
|
|
2
|
+
# Public API (stable, recommended for external integrations)
|
|
3
|
+
# ---------------------------------------------------------------------------
|
|
4
|
+
from .audit import (
|
|
5
|
+
RuntimeAuditQuery,
|
|
6
|
+
RuntimeAuditSnapshot,
|
|
7
|
+
RuntimeAuditSummary,
|
|
8
|
+
query_runtime_audit,
|
|
9
|
+
read_runtime_audit,
|
|
10
|
+
summarize_runtime_audit,
|
|
11
|
+
)
|
|
12
|
+
from .api import (
|
|
13
|
+
AgentRunRequest,
|
|
14
|
+
AgentRunResult,
|
|
15
|
+
CodeAgent,
|
|
16
|
+
CodeBuildRequest,
|
|
17
|
+
build_code_with_agent,
|
|
18
|
+
run_code_agent,
|
|
19
|
+
)
|
|
20
|
+
from .config import CCConfig, load_cc_config
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Advanced API (stable but lower-level; for fine-grained session control)
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
from .llm import DefaultLLMClientProvider, LLMClientProvider
|
|
26
|
+
from .runtime import build_default_query_engine
|
|
27
|
+
from .conversation.query_engine import QueryEngine
|
|
28
|
+
from .conversation.session import QuerySession, SessionFactory
|
|
29
|
+
from .conversation.models import SessionEvent, SessionMessage
|
|
30
|
+
|
|
31
|
+
# ---------------------------------------------------------------------------
|
|
32
|
+
# Middleware pipeline (composable cross-cutting concerns)
|
|
33
|
+
# ---------------------------------------------------------------------------
|
|
34
|
+
from .conversation.middleware import (
|
|
35
|
+
RetryPolicy,
|
|
36
|
+
TurnHooks,
|
|
37
|
+
TurnMiddleware,
|
|
38
|
+
TurnRunner,
|
|
39
|
+
apply as apply_middleware,
|
|
40
|
+
pipe as pipe_middleware,
|
|
41
|
+
with_compaction,
|
|
42
|
+
with_hooks,
|
|
43
|
+
with_persistence,
|
|
44
|
+
with_retry,
|
|
45
|
+
with_turn_tracking,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
# Environment providers (injectable filesystem / shell abstractions)
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
from .providers import (
|
|
52
|
+
CommandProvider,
|
|
53
|
+
Environment,
|
|
54
|
+
FileSystemProvider,
|
|
55
|
+
LocalCommandProvider,
|
|
56
|
+
LocalFileSystemProvider,
|
|
57
|
+
default_environment,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# ---------------------------------------------------------------------------
|
|
61
|
+
# Errors
|
|
62
|
+
# ---------------------------------------------------------------------------
|
|
63
|
+
from .errors import (
|
|
64
|
+
CCError,
|
|
65
|
+
ConfigError,
|
|
66
|
+
ToolExecutionError,
|
|
67
|
+
ToolValidationError,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
__all__ = [
|
|
71
|
+
# -- Public API --
|
|
72
|
+
"AgentRunRequest",
|
|
73
|
+
"AgentRunResult",
|
|
74
|
+
"CCConfig",
|
|
75
|
+
"CodeAgent",
|
|
76
|
+
"CodeBuildRequest",
|
|
77
|
+
"RuntimeAuditQuery",
|
|
78
|
+
"RuntimeAuditSnapshot",
|
|
79
|
+
"RuntimeAuditSummary",
|
|
80
|
+
"build_code_with_agent",
|
|
81
|
+
"load_cc_config",
|
|
82
|
+
"query_runtime_audit",
|
|
83
|
+
"read_runtime_audit",
|
|
84
|
+
"run_code_agent",
|
|
85
|
+
"summarize_runtime_audit",
|
|
86
|
+
# -- Advanced API --
|
|
87
|
+
"DefaultLLMClientProvider",
|
|
88
|
+
"LLMClientProvider",
|
|
89
|
+
"QueryEngine",
|
|
90
|
+
"QuerySession",
|
|
91
|
+
"SessionEvent",
|
|
92
|
+
"SessionFactory",
|
|
93
|
+
"SessionMessage",
|
|
94
|
+
"build_default_query_engine",
|
|
95
|
+
# -- Middleware pipeline --
|
|
96
|
+
"RetryPolicy",
|
|
97
|
+
"TurnHooks",
|
|
98
|
+
"TurnMiddleware",
|
|
99
|
+
"TurnRunner",
|
|
100
|
+
"apply_middleware",
|
|
101
|
+
"pipe_middleware",
|
|
102
|
+
"with_compaction",
|
|
103
|
+
"with_hooks",
|
|
104
|
+
"with_persistence",
|
|
105
|
+
"with_retry",
|
|
106
|
+
"with_turn_tracking",
|
|
107
|
+
# -- Environment providers --
|
|
108
|
+
"CommandProvider",
|
|
109
|
+
"Environment",
|
|
110
|
+
"FileSystemProvider",
|
|
111
|
+
"LocalCommandProvider",
|
|
112
|
+
"LocalFileSystemProvider",
|
|
113
|
+
"default_environment",
|
|
114
|
+
# -- Errors --
|
|
115
|
+
"CCError",
|
|
116
|
+
"ConfigError",
|
|
117
|
+
"ToolExecutionError",
|
|
118
|
+
"ToolValidationError",
|
|
119
|
+
]
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
from typing import Any
|
|
7
|
+
import asyncio
|
|
8
|
+
|
|
9
|
+
from ..agents.backends import InProcessBackend, LocalSubprocessBackend, RuntimeBackend
|
|
10
|
+
from ..config import CCConfig
|
|
11
|
+
from ..conversation.session import QuerySession, SessionFactory
|
|
12
|
+
from ..llm import DefaultLLMClientProvider, LLMClientProvider
|
|
13
|
+
from ..observability import EventRecord, JsonlAuditLogger
|
|
14
|
+
from ..tools.base import BaseTool, ToolCall, ToolResult, ToolSpec, ValidationResult
|
|
15
|
+
from ..tools.context import ToolUseContext
|
|
16
|
+
from .definitions import AgentDefinition
|
|
17
|
+
from .runtime import AgentRuntime
|
|
18
|
+
from .runtime_registry import InProcessRuntimeRegistry, get_in_process_runtime_registry
|
|
19
|
+
from .task_manager import TaskManager
|
|
20
|
+
from .task_model import AgentTask, AgentTaskStatus
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Maximum recursion depth for the ``agent`` tool. With cc_query_loop as the
|
|
27
|
+
# default ccx runner kind, every agent node can call ``agent`` to spawn a
|
|
28
|
+
# child runtime, which itself can call ``agent``, and so on. Each level
|
|
29
|
+
# multiplies the cost by the per-node fan-out, so an unconstrained recursion
|
|
30
|
+
# of depth 4 with fan-out 3 is already 81 leaves. The cap here is the only
|
|
31
|
+
# mechanical (non-prompt) backstop — LLMs can't reliably stay within a
|
|
32
|
+
# nominal budget via prompt instructions, but the runtime can refuse the
|
|
33
|
+
# call.
|
|
34
|
+
#
|
|
35
|
+
# Depth 0 = the top-level cc engine driven by ccx's CcAgentRunner; depth 1
|
|
36
|
+
# = its first helper; depth 2 = a helper-of-helper. The default of 3 keeps
|
|
37
|
+
# room for a real "lead → researcher → reviewer" pattern without permitting
|
|
38
|
+
# unbounded chains. Override via the ``CC_MAX_AGENT_RECURSION_DEPTH``
|
|
39
|
+
# environment variable for unusual workloads.
|
|
40
|
+
_DEFAULT_MAX_AGENT_RECURSION_DEPTH = 3
|
|
41
|
+
_RECURSION_DEPTH_STATE_KEY = "agent_recursion_depth"
|
|
42
|
+
_AGENT_SPAWN_REFUSED_ERROR_CODE = "AT1100"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _resolve_max_recursion_depth() -> int:
|
|
46
|
+
raw = os.environ.get("CC_MAX_AGENT_RECURSION_DEPTH")
|
|
47
|
+
if not raw:
|
|
48
|
+
return _DEFAULT_MAX_AGENT_RECURSION_DEPTH
|
|
49
|
+
try:
|
|
50
|
+
value = int(raw)
|
|
51
|
+
except ValueError:
|
|
52
|
+
logger.warning(
|
|
53
|
+
"CC_MAX_AGENT_RECURSION_DEPTH=%r is not an int; using default %d",
|
|
54
|
+
raw, _DEFAULT_MAX_AGENT_RECURSION_DEPTH,
|
|
55
|
+
)
|
|
56
|
+
return _DEFAULT_MAX_AGENT_RECURSION_DEPTH
|
|
57
|
+
if value < 0:
|
|
58
|
+
logger.warning(
|
|
59
|
+
"CC_MAX_AGENT_RECURSION_DEPTH=%d is negative; using default %d",
|
|
60
|
+
value, _DEFAULT_MAX_AGENT_RECURSION_DEPTH,
|
|
61
|
+
)
|
|
62
|
+
return _DEFAULT_MAX_AGENT_RECURSION_DEPTH
|
|
63
|
+
return value
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass(slots=True)
|
|
67
|
+
class AgentToolRequest:
|
|
68
|
+
description: str
|
|
69
|
+
prompt: str
|
|
70
|
+
subagent_type: str | None = None
|
|
71
|
+
backend: str | None = None
|
|
72
|
+
model: str | None = None
|
|
73
|
+
run_in_background: bool = False
|
|
74
|
+
name: str | None = None
|
|
75
|
+
team_name: str | None = None
|
|
76
|
+
mode: str | None = None
|
|
77
|
+
isolation: str | None = None
|
|
78
|
+
cwd: str | None = None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class AgentTool(BaseTool):
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
llm_client_provider: LLMClientProvider | None = None,
|
|
85
|
+
runtime_registry: InProcessRuntimeRegistry | None = None,
|
|
86
|
+
) -> None:
|
|
87
|
+
super().__init__(
|
|
88
|
+
ToolSpec(
|
|
89
|
+
name="agent",
|
|
90
|
+
description="Spawn a child agent to work on a sub-task and return its result.",
|
|
91
|
+
input_schema={
|
|
92
|
+
"type": "object",
|
|
93
|
+
"properties": {
|
|
94
|
+
"description": {"type": "string"},
|
|
95
|
+
"prompt": {"type": "string"},
|
|
96
|
+
"subagent_type": {"type": "string"},
|
|
97
|
+
"backend": {"type": "string"},
|
|
98
|
+
"run_in_background": {"type": "boolean"},
|
|
99
|
+
"cwd": {"type": "string"},
|
|
100
|
+
},
|
|
101
|
+
"required": ["description", "prompt"],
|
|
102
|
+
},
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
self.llm_client_provider = llm_client_provider or DefaultLLMClientProvider()
|
|
106
|
+
self.runtime_registry = runtime_registry
|
|
107
|
+
|
|
108
|
+
def validate_input(self, arguments: dict[str, Any]) -> ValidationResult:
|
|
109
|
+
if not arguments.get("description"):
|
|
110
|
+
return ValidationResult(ok=False, message="description is required.")
|
|
111
|
+
if not arguments.get("prompt"):
|
|
112
|
+
return ValidationResult(ok=False, message="prompt is required.")
|
|
113
|
+
backend = arguments.get("backend")
|
|
114
|
+
if backend and str(backend) not in {"in_process", "local_subprocess"}:
|
|
115
|
+
return ValidationResult(ok=False, message=f"Unsupported backend: {backend}")
|
|
116
|
+
return ValidationResult(ok=True)
|
|
117
|
+
|
|
118
|
+
async def execute(self, tool_call: ToolCall, ctx: ToolUseContext) -> ToolResult:
|
|
119
|
+
request = AgentToolRequest(
|
|
120
|
+
description=str(tool_call.arguments["description"]),
|
|
121
|
+
prompt=str(tool_call.arguments["prompt"]),
|
|
122
|
+
subagent_type=tool_call.arguments.get("subagent_type"),
|
|
123
|
+
backend=tool_call.arguments.get("backend"),
|
|
124
|
+
run_in_background=bool(tool_call.arguments.get("run_in_background", False)),
|
|
125
|
+
cwd=tool_call.arguments.get("cwd"),
|
|
126
|
+
)
|
|
127
|
+
# Recursion depth check (Tier 1 backstop against runaway sub-agent
|
|
128
|
+
# spawning when cc_query_loop is the default ccx runner). Read the
|
|
129
|
+
# parent's depth from session metadata.state, refuse if we'd exceed
|
|
130
|
+
# the cap, and emit an audit event either way so deep chains are
|
|
131
|
+
# debuggable post-hoc.
|
|
132
|
+
parent_session = ctx.metadata.get("session")
|
|
133
|
+
parent_depth = 0
|
|
134
|
+
if parent_session is not None:
|
|
135
|
+
parent_depth = int(
|
|
136
|
+
(parent_session.metadata.state or {}).get(
|
|
137
|
+
_RECURSION_DEPTH_STATE_KEY, 0,
|
|
138
|
+
) or 0
|
|
139
|
+
)
|
|
140
|
+
max_depth = _resolve_max_recursion_depth()
|
|
141
|
+
runtime_root_for_audit = ctx.config.runtime_root_path(ctx.cwd)
|
|
142
|
+
agent_audit_logger = JsonlAuditLogger(
|
|
143
|
+
runtime_root_for_audit / "audit" / "agent_events.jsonl"
|
|
144
|
+
)
|
|
145
|
+
prospective_child_depth = parent_depth + 1
|
|
146
|
+
if prospective_child_depth > max_depth:
|
|
147
|
+
agent_audit_logger.append(EventRecord(
|
|
148
|
+
event_type="agent_spawn_refused_recursion_cap",
|
|
149
|
+
session_id=getattr(parent_session, "session_id", None),
|
|
150
|
+
tool_name="agent",
|
|
151
|
+
success=False,
|
|
152
|
+
error_code=_AGENT_SPAWN_REFUSED_ERROR_CODE,
|
|
153
|
+
details={
|
|
154
|
+
"parent_depth": parent_depth,
|
|
155
|
+
"prospective_child_depth": prospective_child_depth,
|
|
156
|
+
"max_depth": max_depth,
|
|
157
|
+
"description": (request.description or "")[:200],
|
|
158
|
+
"tool_use_id": tool_call.tool_use_id,
|
|
159
|
+
},
|
|
160
|
+
))
|
|
161
|
+
logger.warning(
|
|
162
|
+
"agent tool refused: parent_depth=%d would exceed max_depth=%d "
|
|
163
|
+
"(description=%r). Set CC_MAX_AGENT_RECURSION_DEPTH to raise the cap.",
|
|
164
|
+
parent_depth, max_depth, (request.description or "")[:120],
|
|
165
|
+
)
|
|
166
|
+
return ToolResult(
|
|
167
|
+
tool_use_id=tool_call.tool_use_id,
|
|
168
|
+
tool_name=tool_call.tool_name,
|
|
169
|
+
success=False,
|
|
170
|
+
content=(
|
|
171
|
+
f"agent spawn refused: recursion depth {prospective_child_depth} "
|
|
172
|
+
f"would exceed cap {max_depth}. Complete this task with the "
|
|
173
|
+
f"context you already have, or finalize and return."
|
|
174
|
+
),
|
|
175
|
+
error_code=_AGENT_SPAWN_REFUSED_ERROR_CODE,
|
|
176
|
+
data={
|
|
177
|
+
"parent_depth": parent_depth,
|
|
178
|
+
"max_depth": max_depth,
|
|
179
|
+
"refused": True,
|
|
180
|
+
},
|
|
181
|
+
)
|
|
182
|
+
# Approaching-cap warning (one less than max). Distinct event type
|
|
183
|
+
# so dashboards can flag chains that get close without firing on
|
|
184
|
+
# every spawn.
|
|
185
|
+
if prospective_child_depth == max_depth:
|
|
186
|
+
agent_audit_logger.append(EventRecord(
|
|
187
|
+
event_type="agent_collaboration_depth_warning",
|
|
188
|
+
session_id=getattr(parent_session, "session_id", None),
|
|
189
|
+
tool_name="agent",
|
|
190
|
+
success=None,
|
|
191
|
+
details={
|
|
192
|
+
"parent_depth": parent_depth,
|
|
193
|
+
"child_depth": prospective_child_depth,
|
|
194
|
+
"max_depth": max_depth,
|
|
195
|
+
"description": (request.description or "")[:200],
|
|
196
|
+
"tool_use_id": tool_call.tool_use_id,
|
|
197
|
+
},
|
|
198
|
+
))
|
|
199
|
+
|
|
200
|
+
definition = self.resolve_agent_definition(request)
|
|
201
|
+
backend_name = self.resolve_backend_name(request, ctx)
|
|
202
|
+
backend = self.resolve_backend(backend_name)
|
|
203
|
+
runtime_root = ctx.config.runtime_root_path(ctx.cwd)
|
|
204
|
+
runtime_registry = self.runtime_registry or get_in_process_runtime_registry(runtime_root)
|
|
205
|
+
task_manager = TaskManager(runtime_root / "tasks")
|
|
206
|
+
task = task_manager.create_task(
|
|
207
|
+
AgentTask.create(
|
|
208
|
+
agent_type=definition.agent_id,
|
|
209
|
+
backend=backend_name,
|
|
210
|
+
prompt_language=ctx.prompt_language,
|
|
211
|
+
title=request.description,
|
|
212
|
+
input_payload={
|
|
213
|
+
"description": request.description,
|
|
214
|
+
"prompt": request.prompt,
|
|
215
|
+
},
|
|
216
|
+
)
|
|
217
|
+
)
|
|
218
|
+
child_session = self.build_child_session(
|
|
219
|
+
parent_session=ctx.metadata["session"],
|
|
220
|
+
task=task,
|
|
221
|
+
agent_definition=definition,
|
|
222
|
+
cwd=request.cwd or ctx.cwd,
|
|
223
|
+
)
|
|
224
|
+
# Stamp the child's depth so its own ``agent`` tool calls see a
|
|
225
|
+
# bumped value and the cap composes across levels.
|
|
226
|
+
child_session.metadata.state[_RECURSION_DEPTH_STATE_KEY] = prospective_child_depth
|
|
227
|
+
from ..runtime import build_default_query_engine
|
|
228
|
+
|
|
229
|
+
runtime = AgentRuntime(
|
|
230
|
+
definition=definition,
|
|
231
|
+
task=task,
|
|
232
|
+
query_engine=build_default_query_engine(
|
|
233
|
+
cwd=child_session.cwd,
|
|
234
|
+
config=child_session.config,
|
|
235
|
+
llm_client_provider=self.llm_client_provider,
|
|
236
|
+
session=child_session,
|
|
237
|
+
),
|
|
238
|
+
task_manager=task_manager,
|
|
239
|
+
)
|
|
240
|
+
controller = await backend.create_controller(
|
|
241
|
+
runtime=runtime,
|
|
242
|
+
run_in_background=request.run_in_background,
|
|
243
|
+
runtime_root=runtime_root,
|
|
244
|
+
)
|
|
245
|
+
runtime_registry.register(controller)
|
|
246
|
+
if request.run_in_background:
|
|
247
|
+
if backend_name == "in_process":
|
|
248
|
+
task_manager.update_task_status(task.task_id, AgentTaskStatus.RUNNING)
|
|
249
|
+
background_task = asyncio.create_task(controller.start(request.prompt))
|
|
250
|
+
runtime_registry.register_background_task(task.runtime_id, background_task)
|
|
251
|
+
launch_result = {
|
|
252
|
+
"task_id": task.task_id,
|
|
253
|
+
"runtime_id": task.runtime_id,
|
|
254
|
+
"status": task.status.value,
|
|
255
|
+
"background": True,
|
|
256
|
+
"backend": backend_name,
|
|
257
|
+
}
|
|
258
|
+
else:
|
|
259
|
+
launch_result = await controller.start(request.prompt)
|
|
260
|
+
return ToolResult(
|
|
261
|
+
tool_use_id=tool_call.tool_use_id,
|
|
262
|
+
tool_name=tool_call.tool_name,
|
|
263
|
+
success=True,
|
|
264
|
+
content="Agent launched in background mode.",
|
|
265
|
+
data=launch_result,
|
|
266
|
+
)
|
|
267
|
+
result = await controller.start(request.prompt)
|
|
268
|
+
return ToolResult(
|
|
269
|
+
tool_use_id=tool_call.tool_use_id,
|
|
270
|
+
tool_name=tool_call.tool_name,
|
|
271
|
+
success=True,
|
|
272
|
+
content=result["final_text"],
|
|
273
|
+
data=result,
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
def resolve_backend_name(self, request: AgentToolRequest, ctx: ToolUseContext) -> str:
|
|
277
|
+
return str(request.backend or request.mode or ctx.config.default_backend or "in_process")
|
|
278
|
+
|
|
279
|
+
def resolve_backend(self, backend_name: str) -> RuntimeBackend:
|
|
280
|
+
if backend_name == "in_process":
|
|
281
|
+
return InProcessBackend()
|
|
282
|
+
if backend_name == "local_subprocess":
|
|
283
|
+
return LocalSubprocessBackend()
|
|
284
|
+
raise ValueError(f"Unsupported backend: {backend_name}")
|
|
285
|
+
|
|
286
|
+
def resolve_agent_definition(self, request: AgentToolRequest) -> AgentDefinition:
|
|
287
|
+
agent_id = request.subagent_type or "worker"
|
|
288
|
+
return AgentDefinition(
|
|
289
|
+
agent_id=agent_id,
|
|
290
|
+
name=request.name or agent_id,
|
|
291
|
+
description=request.description,
|
|
292
|
+
prompt_key="agents.worker",
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
def build_child_session(
|
|
296
|
+
self,
|
|
297
|
+
*,
|
|
298
|
+
parent_session: QuerySession,
|
|
299
|
+
task: AgentTask,
|
|
300
|
+
agent_definition: AgentDefinition,
|
|
301
|
+
cwd: str,
|
|
302
|
+
) -> QuerySession:
|
|
303
|
+
child_config = CCConfig.from_mapping(
|
|
304
|
+
{
|
|
305
|
+
**parent_session.config.to_dict(),
|
|
306
|
+
"agent_mode": "",
|
|
307
|
+
}
|
|
308
|
+
)
|
|
309
|
+
child_factory = SessionFactory(child_config)
|
|
310
|
+
child_session = child_factory.create(
|
|
311
|
+
cwd=cwd,
|
|
312
|
+
model_name=parent_session.model_name,
|
|
313
|
+
agent_id=agent_definition.agent_id,
|
|
314
|
+
parent_task_id=task.task_id,
|
|
315
|
+
)
|
|
316
|
+
child_session.prompt_language = parent_session.prompt_language
|
|
317
|
+
child_session.permission_mode = parent_session.permission_mode
|
|
318
|
+
child_session.agent_mode = ""
|
|
319
|
+
child_session.metadata.state["spawned_by_agent_mode"] = parent_session.agent_mode
|
|
320
|
+
return child_session
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from .base import BackendHandle, RuntimeBackend, RuntimeController
|
|
2
|
+
from .in_process import InProcessBackend
|
|
3
|
+
from .local_subprocess import LocalSubprocessBackend
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"BackendHandle",
|
|
7
|
+
"InProcessBackend",
|
|
8
|
+
"LocalSubprocessBackend",
|
|
9
|
+
"RuntimeBackend",
|
|
10
|
+
"RuntimeController",
|
|
11
|
+
]
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Any, Protocol, TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from ..runtime import AgentMessage, AgentRuntime
|
|
9
|
+
from ..task_model import AgentTask
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(slots=True)
|
|
13
|
+
class BackendHandle:
|
|
14
|
+
runtime_id: str
|
|
15
|
+
backend_name: str
|
|
16
|
+
process_id: int | None = None
|
|
17
|
+
endpoint: str | None = None
|
|
18
|
+
output_path: str | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class RuntimeController(Protocol):
|
|
22
|
+
task: "AgentTask"
|
|
23
|
+
handle: BackendHandle
|
|
24
|
+
|
|
25
|
+
async def start(self, prompt: str) -> dict[str, Any]:
|
|
26
|
+
...
|
|
27
|
+
|
|
28
|
+
async def send_message(
|
|
29
|
+
self,
|
|
30
|
+
message: "AgentMessage",
|
|
31
|
+
*,
|
|
32
|
+
timeout_seconds: float | None = None,
|
|
33
|
+
) -> dict[str, Any]:
|
|
34
|
+
...
|
|
35
|
+
|
|
36
|
+
async def stop(self, reason: str) -> None:
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
async def collect_status(self) -> dict[str, Any]:
|
|
40
|
+
...
|
|
41
|
+
|
|
42
|
+
async def apply_shared_state(
|
|
43
|
+
self,
|
|
44
|
+
*,
|
|
45
|
+
shared_context: dict[str, Any],
|
|
46
|
+
shared_allowed_paths: list[str],
|
|
47
|
+
timeout_seconds: float | None = None,
|
|
48
|
+
) -> dict[str, Any]:
|
|
49
|
+
...
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class RuntimeBackend(Protocol):
|
|
53
|
+
name: str
|
|
54
|
+
|
|
55
|
+
async def create_controller(
|
|
56
|
+
self,
|
|
57
|
+
*,
|
|
58
|
+
runtime: "AgentRuntime",
|
|
59
|
+
run_in_background: bool,
|
|
60
|
+
runtime_root: Path,
|
|
61
|
+
) -> RuntimeController:
|
|
62
|
+
...
|