Full Code of cuga-project/cuga-agent for AI

main ff961e28fdc0 cached
1049 files
21.5 MB
5.7M tokens
16689 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (22,856K chars total). Download the full file to get everything.
Repository: cuga-project/cuga-agent
Branch: main
Commit: ff961e28fdc0
Files: 1049
Total size: 21.5 MB

Directory structure:
gitextract_9yecxdwb/

├── .claude/
│   └── commands/
│       ├── cuga-commit.md
│       ├── cuga-create-pr.md
│       ├── cuga-new-feature.md
│       ├── cuga-report-bug.md
│       └── cuga-ruff-check.md
├── .cra/
│   └── .fileignore
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── documentation-request.yml
│   │   ├── feature_request.yml
│   │   └── use_case.yml
│   ├── PULL_REQUEST_TEMPLATE/
│   │   ├── bugfix.md
│   │   ├── chore.md
│   │   ├── docs.md
│   │   └── feature.md
│   └── workflows/
│       ├── deploy-image-ghcr.yml
│       ├── deploy-image.yml
│       ├── release-pr.yml
│       ├── release-tag.yml
│       ├── release.yml
│       ├── smoke-pip-install.yml
│       ├── stability-tests.yml
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── .run/
│   ├── API Registry Appworld.run.xml
│   ├── API Registry Demo.run.xml
│   ├── App World Eval.run.xml
│   └── Cuga Demo.run.xml
├── .secrets.baseline
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── .whitesource
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.ubi
├── LICENSE
├── README.md
├── __init__.py
├── deployment/
│   ├── README.md
│   ├── certs/
│   │   └── README.md
│   ├── deploy-local-postgres.sh
│   ├── deploy-local.sh
│   ├── docker-compose/
│   │   └── openlit/
│   │       ├── docker-compose.yml
│   │       ├── grafana-datasources.yaml
│   │       ├── otel-collector-config.yaml
│   │       ├── prometheus.yml
│   │       └── tempo.yaml
│   └── helm/
│       ├── cleanup-openshift.sh
│       ├── cuga/
│       │   ├── Chart.yaml
│       │   ├── templates/
│       │   │   ├── NOTES.txt
│       │   │   ├── _helpers.tpl
│       │   │   ├── deployment.yaml
│       │   │   ├── pvc.yaml
│       │   │   ├── route.yaml
│       │   │   └── service.yaml
│       │   └── values.yaml
│       ├── deploy-openshift.sh
│       ├── openshift.example.env
│       ├── postgres-pgvector/
│       │   ├── Chart.yaml
│       │   ├── README.md
│       │   ├── templates/
│       │   │   ├── NOTES.txt
│       │   │   ├── _helpers.tpl
│       │   │   ├── configmap.yaml
│       │   │   ├── deployment.yaml
│       │   │   ├── pvc.yaml
│       │   │   ├── secret.yaml
│       │   │   └── service.yaml
│       │   └── values.yaml
│       ├── status-openshift.sh
│       └── vault/
│           ├── Chart.yaml
│           ├── templates/
│           │   └── NOTES.txt
│           ├── values.openshift.yaml
│           └── values.yaml
├── design.html
├── design.md
├── docs/
│   ├── examples/
│   │   ├── cuga_as_mcp/
│   │   │   ├── .python-version
│   │   │   ├── README.md
│   │   │   ├── main.py
│   │   │   ├── mcp_servers.yaml
│   │   │   ├── pyproject.toml
│   │   │   └── tools_loader.py
│   │   ├── cuga_with_runtime_tools/
│   │   │   ├── .gitignore
│   │   │   ├── .python-version
│   │   │   ├── README.md
│   │   │   ├── fast_mcp_example.py
│   │   │   ├── langchain_example_tool.py
│   │   │   ├── main.py
│   │   │   ├── mcp_servers.yaml
│   │   │   └── pyproject.toml
│   │   ├── demo_apps/
│   │   │   └── setup/
│   │   │       ├── README.md
│   │   │       ├── cli.py
│   │   │       └── pyproject.toml
│   │   ├── digital_sales_openapi/
│   │   │   └── main.py
│   │   ├── evaluation/
│   │   │   ├── input_example.json
│   │   │   └── input_schema.json
│   │   └── langflow/
│   │       └── CUGA Langflow Demo - Conference Preparation.json
│   ├── flags.html
│   ├── memory/
│   │   └── README.md
│   └── sales_app.html
├── pyproject.toml
├── readme_cuga_lite_kaizen.md
├── ruff.toml
├── run_stability_tests.py
├── scripts/
│   ├── deploy-image.sh
│   ├── docker-entrypoint.sh
│   └── smoke_pip_install_isolated.sh
├── src/
│   ├── cuga/
│   │   ├── __init__.py
│   │   ├── backend/
│   │   │   ├── __init__.py
│   │   │   ├── activity_tracker/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── join_tool.py
│   │   │   │   ├── render_helper.py
│   │   │   │   └── tracker.py
│   │   │   ├── browser_env/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── browser/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── chat_async.py
│   │   │   │   │   ├── env.py
│   │   │   │   │   ├── extension_env_async.py
│   │   │   │   │   ├── gym_env.py
│   │   │   │   │   ├── gym_env_async.py
│   │   │   │   │   ├── gym_obs/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── extract_chrome_extension.py
│   │   │   │   │   │   ├── http_stream_comm.py
│   │   │   │   │   │   ├── javascript/
│   │   │   │   │   │   │   ├── frame_mark_elements.js
│   │   │   │   │   │   │   └── frame_unmark_elements.js
│   │   │   │   │   │   ├── obs.py
│   │   │   │   │   │   ├── obs_async.py
│   │   │   │   │   │   └── websocket_server.py
│   │   │   │   │   ├── open_ended_async.py
│   │   │   │   │   ├── utils.py
│   │   │   │   │   └── utils_async.py
│   │   │   │   ├── page_understanding/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── extension_processor.py
│   │   │   │   │   ├── extractor_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── extract_async.py
│   │   │   │   │   │   └── javascript/
│   │   │   │   │   │       ├── frame_mark_elements.js
│   │   │   │   │   │       └── frame_unmark_elements.js
│   │   │   │   │   ├── nocodeui_pu_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── model.py
│   │   │   │   │   │   ├── nocode_utils.py
│   │   │   │   │   │   └── rules.yaml
│   │   │   │   │   ├── pu_extractor.py
│   │   │   │   │   ├── pu_extractor_chrome_extension.py
│   │   │   │   │   ├── pu_processor.py
│   │   │   │   │   ├── pu_transform.py
│   │   │   │   │   ├── tranformer_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── dom_transform_utils.py
│   │   │   │   │   │   └── transform_utils.py
│   │   │   │   │   └── types/
│   │   │   │   │       ├── README.md
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── dom_tree_types.py
│   │   │   │   │       └── validate_structure.py
│   │   │   │   └── tools/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── extension_commands.py
│   │   │   │       ├── playwright_commands.py
│   │   │   │       └── providers.py
│   │   │   ├── cuga_graph/
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── graph.py
│   │   │   │   ├── nodes/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── answer/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── final_answer.py
│   │   │   │   │   │   └── final_answer_agent/
│   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │       ├── final_answer_agent.py
│   │   │   │   │   │       └── prompts/
│   │   │   │   │   │           ├── __init__.py
│   │   │   │   │   │           ├── load_prompt.py
│   │   │   │   │   │           ├── system.jinja2
│   │   │   │   │   │           ├── system_appworld.jinja2
│   │   │   │   │   │           ├── system_appworld_plain.jinja2
│   │   │   │   │   │           ├── system_concise.jinja2
│   │   │   │   │   │           ├── system_long.jinja2
│   │   │   │   │   │           ├── user_msg.jinja2
│   │   │   │   │   │           ├── user_msg_appworld.jinja2
│   │   │   │   │   │           └── user_msg_appworld_plain.jinja2
│   │   │   │   │   ├── api/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── api_agent_utils/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   └── utils.py
│   │   │   │   │   │   ├── api_code_agent.py
│   │   │   │   │   │   ├── api_code_planner.py
│   │   │   │   │   │   ├── api_code_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── api_code_planner_agent.py
│   │   │   │   │   │   │   ├── api_planner_prompt_v1.md
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.backup.jinja2
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── system_fast.jinja2
│   │   │   │   │   │   │       ├── system_high_level_no_relation_to_vars.jinja2
│   │   │   │   │   │   │       ├── test.md
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── api_planner.py
│   │   │   │   │   │   ├── api_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── api_planner_agent.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── system_hitl.jinja2
│   │   │   │   │   │   │       ├── system_long_task_good.jinja2
│   │   │   │   │   │   │       ├── system_no_few_shots_thoughts_as_list.jinja2
│   │   │   │   │   │   │       ├── system_short.jinja2
│   │   │   │   │   │   │       ├── system_success_on_long_template.jinja2
│   │   │   │   │   │   │       ├── system_v2.jinja2
│   │   │   │   │   │   │       ├── user.jinja2
│   │   │   │   │   │   │       ├── user_hitl.jinja2
│   │   │   │   │   │   │       └── user_v2.jinja2
│   │   │   │   │   │   ├── api_shortlister.py
│   │   │   │   │   │   ├── code_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── code_act_agent.py
│   │   │   │   │   │   │   ├── code_agent.py
│   │   │   │   │   │   │   ├── model.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── system_accurate.jinja2
│   │   │   │   │   │   │       ├── system_fast.jinja2
│   │   │   │   │   │   │       ├── system_no_plan.jinja2
│   │   │   │   │   │   │       ├── user.jinja2
│   │   │   │   │   │   │       └── user_no_plan.jinja2
│   │   │   │   │   │   ├── shortlister_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   ├── system_parameters.jinja2
│   │   │   │   │   │   │   │   ├── user.jinja2
│   │   │   │   │   │   │   │   └── user_parameters.jinja2
│   │   │   │   │   │   │   └── shortlister_agent.py
│   │   │   │   │   │   ├── tasks/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── reflection_system.jinja2
│   │   │   │   │   │   │   │   ├── reflection_user.jinja2
│   │   │   │   │   │   │   │   ├── summary_system.jinja2
│   │   │   │   │   │   │   │   └── summary_user.jinja2
│   │   │   │   │   │   │   ├── reflection.py
│   │   │   │   │   │   │   └── summarize_code.py
│   │   │   │   │   │   └── variables_manager/
│   │   │   │   │   │       └── tests/
│   │   │   │   │   │           ├── __init__.py
│   │   │   │   │   │           ├── data.json
│   │   │   │   │   │           ├── test_manager.py
│   │   │   │   │   │           └── test_value_preview.py
│   │   │   │   │   ├── browser/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── action.py
│   │   │   │   │   │   ├── action_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── action_agent.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   └── user.jinja2
│   │   │   │   │   │   │   ├── ranker_output.json
│   │   │   │   │   │   │   └── tools/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── alert.py
│   │   │   │   │   │   │       ├── tool_processor.py
│   │   │   │   │   │   │       └── tools.py
│   │   │   │   │   │   ├── browser_planner.py
│   │   │   │   │   │   ├── browser_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── browser_planner_agent.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── test.json
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── qa_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   └── user_msg.jinja2
│   │   │   │   │   │   │   └── qa_agent.py
│   │   │   │   │   │   └── qa_agent_node.py
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── chat.py
│   │   │   │   │   │   └── chat_agent/
│   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │       ├── chat_agent.py
│   │   │   │   │   │       └── prompts/
│   │   │   │   │   │           ├── pmt.jinja2
│   │   │   │   │   │           ├── pmt_chat.jinja2
│   │   │   │   │   │           └── pmt_with_variables_mentioning.jinja2
│   │   │   │   │   ├── cuga_lite/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── combined_tool_provider.py
│   │   │   │   │   │   ├── cuga_lite_graph.py
│   │   │   │   │   │   ├── cuga_lite_node.py
│   │   │   │   │   │   ├── direct_langchain_tools_provider.py
│   │   │   │   │   │   ├── executors/
│   │   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── base_executor.py
│   │   │   │   │   │   │   ├── code_executor.py
│   │   │   │   │   │   │   ├── common/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── benchmark_mode.py
│   │   │   │   │   │   │   │   ├── call_api_helper.py
│   │   │   │   │   │   │   │   ├── code_wrapper.py
│   │   │   │   │   │   │   │   ├── restricted_environment.py
│   │   │   │   │   │   │   │   ├── security.py
│   │   │   │   │   │   │   │   └── variable_utils.py
│   │   │   │   │   │   │   ├── docker/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── docker_executor.py
│   │   │   │   │   │   │   ├── e2b/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── e2b_executor.py
│   │   │   │   │   │   │   ├── local/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── local_executor.py
│   │   │   │   │   │   │   └── tests/
│   │   │   │   │   │   │       ├── test_api_calls_with_print.py
│   │   │   │   │   │   │       ├── test_code_executor.py
│   │   │   │   │   │   │       ├── test_e2b_direct.py
│   │   │   │   │   │   │       ├── test_e2b_lite.py
│   │   │   │   │   │   │       ├── test_extract_codeblocks.py
│   │   │   │   │   │   │       ├── test_sync_async_tools.py
│   │   │   │   │   │   │       ├── test_tool_call_timeout.py
│   │   │   │   │   │   │       └── test_variable_creation_order.py
│   │   │   │   │   │   ├── nl_auto_continue_classifier.py
│   │   │   │   │   │   ├── prompt_utils.py
│   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   ├── mcp_prompt.jinja2
│   │   │   │   │   │   │   └── shortlister/
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── reflection/
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── reflection_system.jinja2
│   │   │   │   │   │   │   │   └── reflection_user.jinja2
│   │   │   │   │   │   │   └── reflection.py
│   │   │   │   │   │   ├── tests/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── test_cuga_lite_graph_evolve_guidelines.py
│   │   │   │   │   │   │   ├── test_cuga_lite_node.py
│   │   │   │   │   │   │   └── test_tool_call_args.py
│   │   │   │   │   │   ├── tool_approval_handler.py
│   │   │   │   │   │   ├── tool_call_args.py
│   │   │   │   │   │   ├── tool_call_tracker.py
│   │   │   │   │   │   ├── tool_provider_interface.py
│   │   │   │   │   │   └── tool_registry_provider.py
│   │   │   │   │   ├── cuga_supervisor/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── a2a_protocol.py
│   │   │   │   │   │   ├── cuga_supervisor_graph.py
│   │   │   │   │   │   ├── cuga_supervisor_node.py
│   │   │   │   │   │   ├── cuga_supervisor_state.py
│   │   │   │   │   │   └── prompts/
│   │   │   │   │   │       └── supervisor_lite_prompt.jinja2
│   │   │   │   │   ├── human_in_the_loop/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── followup_model.py
│   │   │   │   │   │   ├── suggest_actions.py
│   │   │   │   │   │   └── wait_for_response.py
│   │   │   │   │   ├── save_reuse/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── save_reuse_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── explainbility.jinja2
│   │   │   │   │   │   │   │   ├── explainbility_user.jinja2
│   │   │   │   │   │   │   │   ├── save_reuse.jinja2
│   │   │   │   │   │   │   │   └── save_reuse_user.jinja2
│   │   │   │   │   │   │   ├── reuse_agent.py
│   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── export_mcp.py
│   │   │   │   │   │   │       └── save_reuse.py
│   │   │   │   │   │   └── save_reuse_node.py
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── base_agent.py
│   │   │   │   │   │   ├── base_node.py
│   │   │   │   │   │   ├── interrupt_tool_node.py
│   │   │   │   │   │   └── location_solver.py
│   │   │   │   │   └── task_decomposition_planning/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── analyze_task.py
│   │   │   │   │       ├── location_resolver_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── google_search_agent.py
│   │   │   │   │       │   └── location_resolver_agent.py
│   │   │   │   │       ├── plan_controller.py
│   │   │   │   │       ├── plan_controller_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── plan_controller_agent.py
│   │   │   │   │       │   └── prompts/
│   │   │   │   │       │       ├── __init__.py
│   │   │   │   │       │       ├── example.json
│   │   │   │   │       │       ├── load_prompt.py
│   │   │   │   │       │       ├── system.jinja2
│   │   │   │   │       │       └── user.jinja2
│   │   │   │   │       ├── task_analyzer_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── prompts/
│   │   │   │   │       │   │   ├── __init__.py
│   │   │   │   │       │   │   └── load_prompt.py
│   │   │   │   │       │   ├── task_analyzer_agent.py
│   │   │   │   │       │   └── tasks/
│   │   │   │   │       │       ├── __init__.py
│   │   │   │   │       │       ├── app_matcher.py
│   │   │   │   │       │       ├── classify_task.py
│   │   │   │   │       │       ├── navigation_paths_task.py
│   │   │   │   │       │       ├── paraphrase.py
│   │   │   │   │       │       └── prompts/
│   │   │   │   │       │           ├── app_matcher_system.jinja2
│   │   │   │   │       │           ├── app_matcher_user.jinja2
│   │   │   │   │       │           ├── classify_task_system.jinja2
│   │   │   │   │       │           ├── classify_task_user.jinja2
│   │   │   │   │       │           ├── navigation_paths_system.jinja2
│   │   │   │   │       │           ├── navigation_paths_user.jinja2
│   │   │   │   │       │           ├── paraphrase_system.jinja2
│   │   │   │   │       │           ├── paraphrase_user.jinja2
│   │   │   │   │       │           └── sitemap_gitlab.json
│   │   │   │   │       ├── task_decomposition.py
│   │   │   │   │       └── task_decomposition_agent/
│   │   │   │   │           ├── __init__.py
│   │   │   │   │           ├── prompts/
│   │   │   │   │           │   ├── __init__.py
│   │   │   │   │           │   ├── load_prompt.py
│   │   │   │   │           │   ├── system.jinja2
│   │   │   │   │           │   ├── system_multi.jinja2
│   │   │   │   │           │   ├── user_msg.jinja2
│   │   │   │   │           │   └── user_multi.jinja2
│   │   │   │   │           ├── prompts_experiments/
│   │   │   │   │           │   ├── HighLevelPrompt.jinja
│   │   │   │   │           │   ├── Prompt.jinja
│   │   │   │   │           │   ├── Task Decomposition prompt json.jinja
│   │   │   │   │           │   ├── Task Decomposition prompt.jinja
│   │   │   │   │           │   ├── Task Decomposition prompts.txt
│   │   │   │   │           │   ├── Tests_Azure_4o-mini.txt
│   │   │   │   │           │   └── Tests_Azure_4o.txt
│   │   │   │   │           └── task_decomposition_agent.py
│   │   │   │   ├── policy/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── agent.py
│   │   │   │   │   ├── cli.py
│   │   │   │   │   ├── configurable.py
│   │   │   │   │   ├── enactment.py
│   │   │   │   │   ├── examples.py
│   │   │   │   │   ├── filesystem_sync.py
│   │   │   │   │   ├── folder_loader.py
│   │   │   │   │   ├── models.py
│   │   │   │   │   ├── output_formatter_utils.py
│   │   │   │   │   ├── storage.py
│   │   │   │   │   ├── tests/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── helpers.py
│   │   │   │   │   │   ├── test_e2e_healthcare_family_claims.py
│   │   │   │   │   │   ├── test_e2e_intent_guard.py
│   │   │   │   │   │   ├── test_e2e_intent_guard_priority.py
│   │   │   │   │   │   ├── test_e2e_output_formatter.py
│   │   │   │   │   │   ├── test_e2e_playbook_guidance.py
│   │   │   │   │   │   ├── test_e2e_playbook_refinement.py
│   │   │   │   │   │   ├── test_e2e_tool_enrichment.py
│   │   │   │   │   │   ├── test_filesystem_sync.py
│   │   │   │   │   │   ├── test_keyword_operator.py
│   │   │   │   │   │   ├── test_nl_trigger_conflict_resolution.py
│   │   │   │   │   │   ├── test_similarity_integration.py
│   │   │   │   │   │   ├── test_tool_approval_full_graph.py
│   │   │   │   │   │   └── test_utils.py
│   │   │   │   │   └── utils.py
│   │   │   │   ├── state/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── agent_state.py
│   │   │   │   │   └── api_planner_history.py
│   │   │   │   └── utils/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── agent_loop.py
│   │   │   │       ├── context_management_utils.py
│   │   │   │       ├── context_summarizer.py
│   │   │   │       ├── controller.py
│   │   │   │       ├── event_porcessors/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   └── action_agent_event_processor.py
│   │   │   │       ├── message_utils.py
│   │   │   │       ├── nodes_names.py
│   │   │   │       └── token_counter.py
│   │   │   ├── evolve/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── integration.py
│   │   │   │   └── tests/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── test_integration.py
│   │   │   │       └── test_launch_config.py
│   │   │   ├── knowledge/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── auth.py
│   │   │   │   ├── awareness.py
│   │   │   │   ├── client.py
│   │   │   │   ├── config.py
│   │   │   │   ├── engine.py
│   │   │   │   ├── interprocess_lock.py
│   │   │   │   ├── mcp_server.py
│   │   │   │   ├── metadata/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── postgres_store.py
│   │   │   │   │   └── sqlite_store.py
│   │   │   │   ├── routes.py
│   │   │   │   ├── session_provider.py
│   │   │   │   ├── shopping_admin/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── sitemap.txt
│   │   │   │   │   ├── sitemap_js.txt
│   │   │   │   │   └── sitemap_md.txt
│   │   │   │   ├── storage/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── adapter.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   ├── prod.py
│   │   │   │   │   └── schema.py
│   │   │   │   ├── vector_store.py
│   │   │   │   └── vector_store_base.py
│   │   │   ├── llm/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── config.py
│   │   │   │   ├── errors.py
│   │   │   │   ├── models.py
│   │   │   │   ├── rits/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── chat_rits_llm.py
│   │   │   │   │   └── rits_llm.py
│   │   │   │   └── utils/
│   │   │   │       ├── __init__.py
│   │   │   │       └── helpers.py
│   │   │   ├── observability/
│   │   │   │   ├── __init__.py
│   │   │   │   └── openlit_init.py
│   │   │   ├── secrets/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── backends/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── aws_backend.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── db_backend.py
│   │   │   │   │   ├── env_backend.py
│   │   │   │   │   └── vault_backend.py
│   │   │   │   ├── models.py
│   │   │   │   ├── secret_resolver.py
│   │   │   │   └── seed.py
│   │   │   ├── server/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── auth/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── dependencies.py
│   │   │   │   │   ├── issuer_allowlist.py
│   │   │   │   │   ├── jwt_validator.py
│   │   │   │   │   ├── models.py
│   │   │   │   │   └── oidc_client.py
│   │   │   │   ├── config_store.py
│   │   │   │   ├── conversation_history.py
│   │   │   │   ├── debug_server.py
│   │   │   │   ├── demo_manage_setup.py
│   │   │   │   ├── demo_setup_utils/
│   │   │   │   │   └── oak_policies.json
│   │   │   │   ├── event_stream_handler.py
│   │   │   │   ├── main.py
│   │   │   │   ├── manage_routes.py
│   │   │   │   ├── managed_mcp.py
│   │   │   │   ├── mcp_servers/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── cuga.py
│   │   │   │   │   └── tests/
│   │   │   │   │       └── __init__.py
│   │   │   │   ├── secrets_routes.py
│   │   │   │   └── server-manager.sh
│   │   │   ├── storage/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── embedding/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── embedding_service.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   ├── facade.py
│   │   │   │   ├── policy/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   ├── relational/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   └── secrets_store.py
│   │   │   ├── tools_env/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── code_sandbox/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── e2b_sandbox.py
│   │   │   │   │   ├── sandbox.py
│   │   │   │   │   └── tests/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       └── test_sandbox.py
│   │   │   │   └── registry/
│   │   │   │       ├── QUICKSTART.md
│   │   │   │       ├── README.md
│   │   │   │       ├── __init__.py
│   │   │   │       ├── config/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── config_loader.py
│   │   │   │       │   ├── mcp_servers.yaml
│   │   │   │       │   ├── mcp_servers_appworld.yaml
│   │   │   │       │   ├── mcp_servers_crm.yaml
│   │   │   │       │   ├── mcp_servers_hf.yaml
│   │   │   │       │   ├── mcp_servers_wxo.yaml
│   │   │   │       │   └── supervisor_demo_crm.yaml
│   │   │   │       ├── example_api_servers/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   └── petstore.py
│   │   │   │       ├── mcp_manager/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── adapter.py
│   │   │   │       │   ├── mcp_manager.py
│   │   │   │       │   ├── openapi_parser.py
│   │   │   │       │   ├── openapi_parser_v0.py
│   │   │   │       │   ├── openapi_parser_v1.py
│   │   │   │       │   ├── response_schema.py
│   │   │   │       │   └── tests/
│   │   │   │       │       ├── __init__.py
│   │   │   │       │       ├── test_api_response.py
│   │   │   │       │       ├── test_array_handling.py
│   │   │   │       │       └── test_path_ext.py
│   │   │   │       ├── registry/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── api_registry.py
│   │   │   │       │   ├── api_registry_server.py
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── __init__.py
│   │   │   │       │   │   ├── appworld_auth_manager.py
│   │   │   │       │   │   └── base_auth_manager.py
│   │   │   │       │   └── test_naming_strategy_e2e.py
│   │   │   │       ├── tests/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── config/
│   │   │   │       │   │   └── mcp_servers_test.yaml
│   │   │   │       │   ├── data/
│   │   │   │       │   │   └── schemas/
│   │   │   │       │   │       └── openapi_nested.yaml
│   │   │   │       │   ├── e2e_helpers.py
│   │   │   │       │   ├── output_schema_server.py
│   │   │   │       │   ├── run_all_tests.py
│   │   │   │       │   ├── test_agent_registry_loading.py
│   │   │   │       │   ├── test_api_registry_error_handling.py
│   │   │   │       │   ├── test_auth/
│   │   │   │       │   │   ├── README.md
│   │   │   │       │   │   ├── __init__.py
│   │   │   │       │   │   ├── auth_server.py
│   │   │   │       │   │   ├── mcp_servers_auth_test.yaml
│   │   │   │       │   │   ├── test_apply_authentication.py
│   │   │   │       │   │   └── test_auth_e2e.py
│   │   │   │       │   ├── test_e2e_api_registry.py
│   │   │   │       │   ├── test_enum_handling.py
│   │   │   │       │   ├── test_legacy_openapi.py
│   │   │   │       │   ├── test_mcp_server.py
│   │   │   │       │   ├── test_mixed_configuration.py
│   │   │   │       │   └── test_output_schema.py
│   │   │   │       └── utils/
│   │   │   │           ├── __init__.py
│   │   │   │           ├── api_utils.py
│   │   │   │           └── types.py
│   │   │   └── utils/
│   │   │       ├── __init__.py
│   │   │       ├── code_generator.py
│   │   │       ├── consts.py
│   │   │       ├── file_utils.py
│   │   │       └── id_utils.py
│   │   ├── cli/
│   │   │   ├── __init__.py
│   │   │   ├── app_manager.py
│   │   │   └── main.py
│   │   ├── config.py
│   │   ├── configurations/
│   │   │   ├── instructions/
│   │   │   │   ├── default/
│   │   │   │   │   ├── answer.md
│   │   │   │   │   ├── api_code_planner.md
│   │   │   │   │   ├── api_planner.md
│   │   │   │   │   ├── code_agent.md
│   │   │   │   │   ├── plan_controller.md
│   │   │   │   │   ├── reflection.md
│   │   │   │   │   ├── shortlister.md
│   │   │   │   │   └── task_decomposition.md
│   │   │   │   └── instructions.toml
│   │   │   ├── instructions_manager.py
│   │   │   ├── knowledge/
│   │   │   │   ├── knowledge_instructions.md
│   │   │   │   ├── knowledge_profiles/
│   │   │   │   │   ├── balanced.toml
│   │   │   │   │   ├── max_quality.toml
│   │   │   │   │   ├── speed.toml
│   │   │   │   │   └── standard.toml
│   │   │   │   └── knowledge_settings.toml
│   │   │   ├── memory/
│   │   │   │   ├── memory_settings.mem0.toml
│   │   │   │   ├── memory_settings.milvus.toml
│   │   │   │   └── memory_settings.tips_extractor.toml
│   │   │   ├── models/
│   │   │   │   ├── settings.azure.toml
│   │   │   │   ├── settings.google.toml
│   │   │   │   ├── settings.groq.toml
│   │   │   │   ├── settings.litellm.toml
│   │   │   │   ├── settings.openai.toml
│   │   │   │   ├── settings.openrouter.toml
│   │   │   │   ├── settings.rits.toml
│   │   │   │   └── settings.watsonx.toml
│   │   │   ├── modes/
│   │   │   │   ├── accurate.toml
│   │   │   │   ├── balanced.toml
│   │   │   │   ├── custom.toml
│   │   │   │   ├── fast.toml
│   │   │   │   └── save_reuse_fast.toml
│   │   │   └── set_from_one_file.py
│   │   ├── demo_tools/
│   │   │   ├── __init__.py
│   │   │   ├── crm/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── LICENSE
│   │   │   │   ├── MANIFEST.in
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── crm_api/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── accounts.py
│   │   │   │   │   ├── contacts.py
│   │   │   │   │   ├── crud.py
│   │   │   │   │   ├── database.py
│   │   │   │   │   ├── leads.py
│   │   │   │   │   ├── main.py
│   │   │   │   │   ├── opportunities.py
│   │   │   │   │   ├── run_all.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── seed_data.py
│   │   │   │   │   └── wrap_as_mcp.py
│   │   │   │   ├── pytest.ini
│   │   │   │   ├── run.py
│   │   │   │   ├── run_tests.py
│   │   │   │   ├── tests/
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── test_contacts.py
│   │   │   │   │   └── test_workspace_workflow.py
│   │   │   │   └── wrap_as_mcp.py
│   │   │   ├── docs_mcp/
│   │   │   │   └── docs_mcp_server.py
│   │   │   ├── email_mcp/
│   │   │   │   ├── mail_sink/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   └── server.py
│   │   │   │   └── mcp_server/
│   │   │   │       ├── server.py
│   │   │   │       └── utils.py
│   │   │   ├── file_system/
│   │   │   │   └── main.py
│   │   │   ├── health/
│   │   │   │   └── README.md
│   │   │   └── huggingface/
│   │   │       ├── contacts.txt
│   │   │       ├── cuga_knowledge.md
│   │   │       ├── cuga_playbook.md
│   │   │       └── email_template.md
│   │   ├── evaluation/
│   │   │   ├── README.md
│   │   │   ├── calculate_test_score.py
│   │   │   ├── evaluate_cuga.py
│   │   │   └── langfuse/
│   │   │       └── get_langfuse_data.py
│   │   ├── frontend/
│   │   │   └── dist/
│   │   │       ├── background.js
│   │   │       ├── index.html
│   │   │       ├── main.fbff5b207d7495606137.js
│   │   │       ├── manifest.json
│   │   │       ├── tailwind.js
│   │   │       └── vendors.89d8d26b14ea275079ad.js
│   │   ├── sdk.py
│   │   ├── sdk_core/
│   │   │   └── tests/
│   │   │       ├── conversation_messages.json
│   │   │       ├── fixtures/
│   │   │       │   └── supervisor_config.yaml
│   │   │       ├── policies-export-2025-12-31.json
│   │   │       ├── test_context_summarization_sdk.py
│   │   │       ├── test_policy_loading_and_matching.py
│   │   │       ├── test_policy_reset_and_reload.py
│   │   │       ├── test_sdk_integration.py
│   │   │       ├── test_sdk_policies.py
│   │   │       ├── test_supervisor_advanced.py
│   │   │       └── test_supervisor_yaml_config.py
│   │   ├── settings.toml
│   │   └── supervisor_utils/
│   │       ├── __init__.py
│   │       └── supervisor_config.py
│   ├── frontend_workspaces/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── agentic_chat/
│   │   │   ├── global.d.ts
│   │   │   ├── package.json
│   │   │   ├── public/
│   │   │   │   └── fake_data.json
│   │   │   ├── src/
│   │   │   │   ├── AdvancedTourButton.css
│   │   │   │   ├── AdvancedTourButton.tsx
│   │   │   │   ├── AgentBehaviorConfig.tsx
│   │   │   │   ├── AgentHumanConfig.tsx
│   │   │   │   ├── App.tsx
│   │   │   │   ├── AppLayout.css
│   │   │   │   ├── CardManager.css
│   │   │   │   ├── CardManager.tsx
│   │   │   │   ├── ConfigHeader.css
│   │   │   │   ├── ConfigHeader.tsx
│   │   │   │   ├── ConfigModal.css
│   │   │   │   ├── CugaHeader.tsx
│   │   │   │   ├── CustomChat.css
│   │   │   │   ├── CustomChat.tsx
│   │   │   │   ├── CustomResponseStyles.css
│   │   │   │   ├── DebugPanel.css
│   │   │   │   ├── DebugPanel.tsx
│   │   │   │   ├── FileAutocomplete.css
│   │   │   │   ├── FileAutocomplete.tsx
│   │   │   │   ├── Followup.tsx
│   │   │   │   ├── FollowupSuggestions.css
│   │   │   │   ├── FollowupSuggestions.tsx
│   │   │   │   ├── GuidedTour.css
│   │   │   │   ├── GuidedTour.tsx
│   │   │   │   ├── KnowledgeConfig.tsx
│   │   │   │   ├── KnowledgePanel.tsx
│   │   │   │   ├── KnowledgeSidePanel.css
│   │   │   │   ├── KnowledgeSidePanel.tsx
│   │   │   │   ├── LeftSidebar.css
│   │   │   │   ├── LeftSidebar.tsx
│   │   │   │   ├── MemoryConfig.tsx
│   │   │   │   ├── ModelConfig.tsx
│   │   │   │   ├── PoliciesConfig.tsx
│   │   │   │   ├── PolicyBlockComponent.css
│   │   │   │   ├── PolicyBlockComponent.tsx
│   │   │   │   ├── PolicyPlaybookComponent.css
│   │   │   │   ├── PolicyPlaybookComponent.tsx
│   │   │   │   ├── SessionAttachments.tsx
│   │   │   │   ├── StatusBar.css
│   │   │   │   ├── StatusBar.tsx
│   │   │   │   ├── StreamManager.tsx
│   │   │   │   ├── StreamingManager.ts
│   │   │   │   ├── StreamingWorkflow.ts
│   │   │   │   ├── SubAgentsConfig.tsx
│   │   │   │   ├── ToolReview.tsx
│   │   │   │   ├── ToolsConfig.tsx
│   │   │   │   ├── VariablePopup.css
│   │   │   │   ├── VariablePopup.tsx
│   │   │   │   ├── VariablesSidebar.css
│   │   │   │   ├── VariablesSidebar.tsx
│   │   │   │   ├── WorkspacePanel.css
│   │   │   │   ├── WorkspacePanel.tsx
│   │   │   │   ├── WriteableElementExample.css
│   │   │   │   ├── action_agent.tsx
│   │   │   │   ├── action_status_component.tsx
│   │   │   │   ├── app_analyzer_component.tsx
│   │   │   │   ├── coder_agent_output.tsx
│   │   │   │   ├── constants.ts
│   │   │   │   ├── customSendMessage.ts
│   │   │   │   ├── exampleUtterances.ts
│   │   │   │   ├── final_answer_component.tsx
│   │   │   │   ├── floating/
│   │   │   │   │   └── stop_button.tsx
│   │   │   │   ├── generic_component.tsx
│   │   │   │   ├── mockApi.ts
│   │   │   │   ├── qa_agent.tsx
│   │   │   │   ├── renderUserDefinedResponse.tsx
│   │   │   │   ├── shortlister.tsx
│   │   │   │   ├── task_decomposition.tsx
│   │   │   │   ├── task_status_component.tsx
│   │   │   │   ├── useTour.ts
│   │   │   │   ├── useWorkspaceTree.ts
│   │   │   │   ├── uuid.ts
│   │   │   │   ├── workspaceService.ts
│   │   │   │   └── workspaceThrottle.ts
│   │   │   ├── tsconfig.app.json
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── extension/
│   │   │   ├── .editorconfig
│   │   │   ├── .gitignore
│   │   │   ├── constants.ts
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── readme.md
│   │   │   ├── releases/
│   │   │   │   └── chrome-mv3/
│   │   │   │       ├── assets/
│   │   │   │       │   └── sidepanel-Bm0DOHi9.css
│   │   │   │       ├── background.js
│   │   │   │       ├── chunks/
│   │   │   │       │   ├── DailyMotion-Mu-1s4ir.js
│   │   │   │       │   ├── Facebook-CbG0_jez.js
│   │   │   │       │   ├── FilePlayer-CYjbWbG8.js
│   │   │   │       │   ├── Kaltura-BDM2l5do.js
│   │   │   │       │   ├── Mixcloud-jUDy-IoK.js
│   │   │   │       │   ├── Mux-BSWrBpZP.js
│   │   │   │       │   ├── Preview-of7xUcD9.js
│   │   │   │       │   ├── SoundCloud-C1q3o5ey.js
│   │   │   │       │   ├── Streamable-BsCvFyja.js
│   │   │   │       │   ├── Twitch-K5Lc2N4C.js
│   │   │   │       │   ├── Vidyard-N6MhfVze.js
│   │   │   │       │   ├── Vimeo-C2ru3W0B.js
│   │   │   │       │   ├── Wistia-DBD0XvkL.js
│   │   │   │       │   ├── YouTube-8naRW_9O.js
│   │   │   │       │   ├── ar-BqPjhJxT.js
│   │   │   │       │   ├── ar-dz-DyZwJqCp.js
│   │   │   │       │   ├── ar-kw-0W-ym3nk.js
│   │   │   │       │   ├── ar-ly-1r7VuSmV.js
│   │   │   │       │   ├── ar-ma-C8a5fRTZ.js
│   │   │   │       │   ├── ar-sa-LX3Zlta0.js
│   │   │   │       │   ├── ar-tn-9PwKM2NI.js
│   │   │   │       │   ├── chat.export-Civ2zEoT.js
│   │   │   │       │   ├── chat.export.carbon-x9hVoQbk.js
│   │   │   │       │   ├── common-D6sVSfnG.js
│   │   │   │       │   ├── cs-C9atpGa0.js
│   │   │   │       │   ├── de-DTzGRoiG.js
│   │   │   │       │   ├── de-at-DM5xnk44.js
│   │   │   │       │   ├── de-ch-C9PZsiWh.js
│   │   │   │       │   ├── en-au-DKKQ7o_a.js
│   │   │   │       │   ├── en-ca-Bsp7ASfx.js
│   │   │   │       │   ├── en-gb-BZNi8AbR.js
│   │   │   │       │   ├── en-ie-DvDRqUel.js
│   │   │   │       │   ├── en-il-DPvmOO-u.js
│   │   │   │       │   ├── en-nz-CLOrpKu9.js
│   │   │   │       │   ├── es-_25F1VNE.js
│   │   │   │       │   ├── es-do-3T87tC4C.js
│   │   │   │       │   ├── es-us-BfRgSno2.js
│   │   │   │       │   ├── fr-C2PP_RDY.js
│   │   │   │       │   ├── fr-ca-l2g_8cqb.js
│   │   │   │       │   ├── fr-ch-Cj9LWtf4.js
│   │   │   │       │   ├── index-7KKzZJbI.js
│   │   │   │       │   ├── index-B9FHQ1q8.js
│   │   │   │       │   ├── index-aSW4scoW.js
│   │   │   │       │   ├── it-BmAWTxOq.js
│   │   │   │       │   ├── it-ch-CqrZ_w7Y.js
│   │   │   │       │   ├── ja-bDUE5UJb.js
│   │   │   │       │   ├── ko-BS2Hu1tA.js
│   │   │   │       │   ├── nl-Bgmo7MMX.js
│   │   │   │       │   ├── pt-DwX7O4_L.js
│   │   │   │       │   ├── pt-br-Gzdc6c2B.js
│   │   │   │       │   ├── sidepanel-DjwwbR2c.js
│   │   │   │       │   ├── swiper-react-1kjVGWrh.js
│   │   │   │       │   ├── sync-D0xm7If2.js
│   │   │   │       │   ├── utils-D71RtZIR.js
│   │   │   │       │   ├── zh-cn-BoLpJCZk.js
│   │   │   │       │   └── zh-tw-Ck9WD2i8.js
│   │   │   │       ├── content-scripts/
│   │   │   │       │   └── content.js
│   │   │   │       ├── fonts/
│   │   │   │       │   └── IBM-Plex-Sans/
│   │   │   │       │       └── fonts/
│   │   │   │       │           ├── complete/
│   │   │   │       │           │   ├── woff/
│   │   │   │       │           │   │   └── license.txt
│   │   │   │       │           │   └── woff2/
│   │   │   │       │           │       └── license.txt
│   │   │   │       │           └── split/
│   │   │   │       │               ├── woff/
│   │   │   │       │               │   ├── IBMPlexSans-Bold.css
│   │   │   │       │               │   ├── IBMPlexSans-BoldItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-ExtraLight.css
│   │   │   │       │               │   ├── IBMPlexSans-ExtraLightItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Italic.css
│   │   │   │       │               │   ├── IBMPlexSans-Light.css
│   │   │   │       │               │   ├── IBMPlexSans-LightItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Medium.css
│   │   │   │       │               │   ├── IBMPlexSans-MediumItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Regular.css
│   │   │   │       │               │   ├── IBMPlexSans-SemiBold.css
│   │   │   │       │               │   ├── IBMPlexSans-SemiBoldItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Text.css
│   │   │   │       │               │   ├── IBMPlexSans-TextItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Thin.css
│   │   │   │       │               │   ├── IBMPlexSans-ThinItalic.css
│   │   │   │       │               │   └── license.txt
│   │   │   │       │               └── woff2/
│   │   │   │       │                   ├── IBMPlexSans-Bold.css
│   │   │   │       │                   ├── IBMPlexSans-BoldItalic.css
│   │   │   │       │                   ├── IBMPlexSans-ExtraLight.css
│   │   │   │       │                   ├── IBMPlexSans-ExtraLightItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Italic.css
│   │   │   │       │                   ├── IBMPlexSans-Light.css
│   │   │   │       │                   ├── IBMPlexSans-LightItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Medium.css
│   │   │   │       │                   ├── IBMPlexSans-MediumItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Regular.css
│   │   │   │       │                   ├── IBMPlexSans-SemiBold.css
│   │   │   │       │                   ├── IBMPlexSans-SemiBoldItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Text.css
│   │   │   │       │                   ├── IBMPlexSans-TextItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Thin.css
│   │   │   │       │                   ├── IBMPlexSans-ThinItalic.css
│   │   │   │       │                   └── license.txt
│   │   │   │       ├── manifest.json
│   │   │   │       └── sidepanel.html
│   │   │   ├── src/
│   │   │   │   ├── content/
│   │   │   │   │   ├── frame.mark.elements.ts
│   │   │   │   │   ├── page_analysis/
│   │   │   │   │   │   ├── CachedXPathBuilder.ts
│   │   │   │   │   │   ├── DomCache.ts
│   │   │   │   │   │   ├── DomTree.ts
│   │   │   │   │   │   ├── ElementHighlighter.ts
│   │   │   │   │   │   ├── NodeElementCollector.ts
│   │   │   │   │   │   ├── NodeHelper.ts
│   │   │   │   │   │   ├── PageHighlighter.ts
│   │   │   │   │   │   ├── constants.ts
│   │   │   │   │   │   ├── dom_tree_module.ts
│   │   │   │   │   │   └── types.d.ts
│   │   │   │   │   └── worker.connection.ts
│   │   │   │   ├── entrypoints/
│   │   │   │   │   ├── background.ts
│   │   │   │   │   ├── content.tsx
│   │   │   │   │   └── sidepanel/
│   │   │   │   │       ├── index.html
│   │   │   │   │       ├── sidepanel.css
│   │   │   │   │       ├── sidepanel.tsx
│   │   │   │   │       └── tailwind.js
│   │   │   │   ├── functions.ts
│   │   │   │   ├── manifest.chrome.json
│   │   │   │   ├── manifest.firefox.json
│   │   │   │   ├── symbol.dispose.polyfill.js
│   │   │   │   ├── vite-env.d.ts
│   │   │   │   └── worker/
│   │   │   │       ├── http.stream.module.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── sidepanel.module.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   ├── vite.config.ts
│   │   │   └── wxt.config.ts
│   │   ├── frontend/
│   │   │   ├── .babelrc
│   │   │   ├── OPTIMIZATION_SUMMARY.md
│   │   │   ├── analyze-bundle.sh
│   │   │   ├── build.sh
│   │   │   ├── electron_loader/
│   │   │   │   ├── main.js
│   │   │   │   └── preload.js
│   │   │   ├── index.html
│   │   │   ├── main.js
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── AddToolModal.css
│   │   │   │   ├── AddToolModal.tsx
│   │   │   │   ├── App.tsx
│   │   │   │   ├── AuthContext.tsx
│   │   │   │   ├── ChatLanding.css
│   │   │   │   ├── ChatLanding.tsx
│   │   │   │   ├── ConfigHeader.tsx
│   │   │   │   ├── CugaHeader.css
│   │   │   │   ├── CugaHeader.tsx
│   │   │   │   ├── ManageDashboard.css
│   │   │   │   ├── ManageDashboard.tsx
│   │   │   │   ├── ManagePage.css
│   │   │   │   ├── ManagePage.tsx
│   │   │   │   ├── SecretsManager.tsx
│   │   │   │   ├── ToolsConfig.css
│   │   │   │   ├── ToolsConfig.tsx
│   │   │   │   ├── UnauthorizedPage.tsx
│   │   │   │   ├── api.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── carbon-chat/
│   │   │   │   │   ├── CarbonChat.css
│   │   │   │   │   ├── CarbonChat.tsx
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── carbonChatHelpers.ts
│   │   │   │   │   ├── customLoadHistory.ts
│   │   │   │   │   ├── customSendMessage.ts
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   └── scenarios.ts
│   │   │   │   ├── carbon.scss
│   │   │   │   ├── global.css
│   │   │   │   ├── knowledge/
│   │   │   │   │   └── useSessionKnowledgeAttachments.ts
│   │   │   │   └── types/
│   │   │   │       └── tools.ts
│   │   │   ├── static/
│   │   │   │   ├── background.js
│   │   │   │   ├── fake_data.json
│   │   │   │   ├── manifest.json
│   │   │   │   └── tailwind.js
│   │   │   ├── tsconfig.json
│   │   │   └── webpack.config.js
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── runtime/
│   │   │   ├── .eslintrc
│   │   │   ├── .gitignore
│   │   │   ├── commands.ts
│   │   │   ├── functions.ts
│   │   │   ├── index.ts
│   │   │   ├── package.json
│   │   │   ├── responses.ts
│   │   │   └── tsconfig.json
│   │   └── shared/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── constants/
│   │       │   │   ├── constants.ts
│   │       │   │   └── index.ts
│   │       │   ├── index.ts
│   │       │   ├── types/
│   │       │   │   ├── index.ts
│   │       │   │   └── sidepanel.ts
│   │       │   └── utils/
│   │       │       ├── index.ts
│   │       │       └── utils.ts
│   │       └── tsconfig.json
│   ├── scripts/
│   │   ├── __init__.py
│   │   ├── build_embedded.py
│   │   ├── build_standalone.py
│   │   ├── commands.py
│   │   ├── create_e2b_template.py
│   │   ├── draw_graph.py
│   │   ├── embed_assets.py
│   │   ├── graph_visualization/
│   │   │   ├── graph.html
│   │   │   └── graph.json
│   │   ├── preload_models.py
│   │   ├── push-to-hf.sh
│   │   ├── run_e2b_test.py
│   │   ├── run_tests.sh
│   │   └── test_e2b_ngrok.py
│   └── system_tests/
│       ├── e2e/
│       │   ├── accurate_test.py
│       │   ├── balanced_test.py
│       │   ├── base_crm_test.py
│       │   ├── base_test.py
│       │   ├── calculator_tool.py
│       │   ├── config/
│       │   │   ├── mcp_servers.yaml
│       │   │   ├── mcp_servers_crm.yaml
│       │   │   └── mcp_servers_crm_hf.yaml
│       │   ├── conftest.py
│       │   ├── crm_contacts_email_balanced_test.py
│       │   ├── crm_contacts_email_test.py
│       │   ├── crm_contacts_email_test_find_tools.py
│       │   ├── crm_followup_test.py
│       │   ├── crm_hf_utterances_test.py
│       │   ├── digital_sales_test_helpers.py
│       │   ├── fast_test.py
│       │   ├── load_test.py
│       │   ├── run_registry.sh
│       │   ├── save_reuse_test.py
│       │   ├── stability_test_config.toml
│       │   ├── test_context_summarization_e2e.py
│       │   └── test_long_output.py
│       ├── profiling/
│       │   ├── .gitignore
│       │   ├── CHANGELOG.md
│       │   ├── QUICK_START.md
│       │   ├── README.md
│       │   ├── bin/
│       │   │   ├── profile_digital_sales_tasks.py
│       │   │   ├── run_experiment.sh
│       │   │   └── run_profiling.sh
│       │   ├── config/
│       │   │   ├── default_experiment.yaml
│       │   │   ├── env_variables_example.yaml
│       │   │   ├── fast_vs_accurate.yaml
│       │   │   ├── full_matrix_comparison.yaml
│       │   │   └── providers_comparison.yaml
│       │   ├── experiments/
│       │   │   └── comparison.html
│       │   ├── run_experiment.sh
│       │   └── serve.sh
│       └── unit/
│           ├── __init__.py
│           └── test_sandbox_local.py
├── tests/
│   ├── integration/
│   │   ├── __init__.py
│   │   ├── test_context_summarization.py
│   │   ├── test_knowledge_integration.py
│   │   ├── test_llm_config_publish.py
│   │   └── test_tool_call_tracking.py
│   ├── system/
│   │   ├── README.md
│   │   └── test_manager_api_integration.py
│   ├── test_agent_tools_api.py
│   ├── test_conversation_history.py
│   ├── test_variables_manager_langgraph.py
│   ├── test_variables_manager_with_state.py
│   └── unit/
│       ├── test_chat_agent_knowledge_toggle.py
│       ├── test_chat_knowledge_mode.py
│       ├── test_context_summarizer.py
│       ├── test_cuga_lite_knowledge_scopes.py
│       ├── test_find_tools_exception.py
│       ├── test_knowledge_engine.py
│       ├── test_knowledge_manage_gate.py
│       ├── test_knowledge_routes.py
│       ├── test_knowledge_storage_vector.py
│       ├── test_llm_override.py
│       ├── test_manage_publish_sync.py
│       ├── test_plan_controller_prompt.py
│       ├── test_session_knowledge.py
│       ├── test_token_counter.py
│       └── test_tool_use_failed_recovery.py
└── todos.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/commands/cuga-commit.md
================================================
1. Commit current changes, one per file or (depends what user asks), but if its build files then all build files one commit

2. start by git status, and selectivly stage files for commit

3. follow https://www.conventionalcommits.org with scoping and for each commit add some bullet points in descrption

================================================
FILE: .claude/commands/cuga-create-pr.md
================================================

### Step 1: Validate Your Local Repository do it all against upstream `origin`

Before creating a PR, you must ensure all your changes are committed and pushed to your branch.

#### Check for Uncommitted Changes

Run the following command to check for any uncommitted files:

```bash
git status --porcelain
```

**⚠️ CRITICAL: If this command returns any output, STOP HERE!**

You have uncommitted changes that must be handled before creating a PR. You must either:
- **Commit your changes**: `git add . && git commit -m "your message"`
- **Stash your changes**: `git stash`

**Do not proceed with PR creation until this is resolved.**

#### Check for Unpushed Commits

Next, confirm that all your local commits have been pushed to the remote repository.

```bash
git rev-list --count @{u}..HEAD
```

**⚠️ CRITICAL: If the count is greater than zero, STOP HERE!**

You have commits that have not been pushed to the remote repository. You must:
- **Push your changes**: `git push origin <branch-name>`

**Do not proceed with PR creation until this is resolved.**

#### Validation Complete

Only if both checks pass (no uncommitted changes AND no unpushed commits), you are ready to create your pull request.

-----

### Step 2: Create the Pull Request

Use the GitHub CLI (`gh`) to create the pull request.

#### Choose a Template

First, identify the appropriate template from your `.github/PULL_REQUEST_TEMPLATE/` directory. Your options are typically `bugfix.md`, `feature.md`, `docs.md`, or `chore.md`.

#### Related issue (ask the user)

Ask which GitHub issue this PR closes or relates to (issue number or URL). If the user says there is none, to skip the issue, or similar, continue without one—leave **Related Issue** blank, omit that line, or write that there is no linked issue. Do not block PR creation on this.

#### Fill the Template with PR Information

Before creating the PR, you must fill out the template with relevant information about your changes:

1. **Use the correct** template:
   ```bash
    .github/PULL_REQUEST_TEMPLATE/[template].md
   ```

2. **Fill out the required sections based on current commits and changes**:
   - **Related Issue**: Link to any related GitHub issue (if applicable)
   - **Description**: Brief description of what this PR accomplishes
   - **Type of Changes**: Check the appropriate boxes
   - **Root Cause**: What was causing the issue (for bugfixes)
   - **Solution**: How this fix addresses the root cause
   - **Testing**: Check off completed testing steps
   - **Checklist**: Verify all items are completed

3. **Remember filled template**

#### Run the Command


```bash
gh pr create --base main --title "<title in commit convention>" --body "<content of .md filled>"
```

================================================
FILE: .claude/commands/cuga-new-feature.md
================================================
# Create a new issue (upstream)

1. Create the issue with the GitHub CLI (`gh issue create`).
2. Open it against the **origin** upstream (use that remote / repository—not a fork-only default).
3. Labels: run `gh label list` for that upstream repository. Only use names that appear in that output. Always pass `--label needs-triage` and add other applicable labels. Do not invent label names.
4. Choose the correct title prefix based on the issue type:

   | Prefix | When to use |
   |---|---|
   | `[Feature]` | New functionality or capability |
   | `[Design]` | Architecture, API design, or UX proposal before implementation |
   | `[Refactor]` | Internal restructuring with no behavior change |
   | `[Performance]` | Speed, memory, or efficiency improvements |
   | `[Security]` | Vulnerability, safety concern, or hardening |
   | `[Docs]` | Documentation additions or corrections |
   | `[Test]` | Missing tests, flaky tests, or test infrastructure |
   | `[Chore]` | Dependency updates, cleanup, or tooling |
   | `[Epic]` | Large body of work grouping multiple issues |
   | `[Question]` | Clarification needed, not a task |

5. Write the body using the same sections as `.github/ISSUE_TEMPLATE/feature_request.yml`: What you want and why, How it could work, Links or extra context (if any). Incorporate the user's message and any selected editor/context so the issue is concrete and complete.
6. Do not add "Made with Cursor" or similar promotional footers to the issue.


================================================
FILE: .claude/commands/cuga-report-bug.md
================================================
# Report a bug (upstream issue)

1. Create the issue with the GitHub CLI (`gh issue create`).
2. Open it against the **origin** upstream (use that remote / repository—not a fork-only default).
3. Labels: run `gh label list` for that upstream repository (same scope as the issue, e.g. `--repo owner/name` if you are not using the default remote). Only use names that appear in that output. When you run `gh issue create`, pass `--label bug` and repeat `--label <name>` for each other applicable label. Do not invent label names.
4. Write the body using the same sections as `.github/ISSUE_TEMPLATE/bug_report.yml`: What happened, How to reproduce, Environment, Logs, screenshots, or config (if any). Incorporate the user’s message and any selected editor/context so the issue is concrete and reproducible.
5. Use a sensible title consistent with the template’s title prefix.
6. Do not add “Made with Cursor” or similar promotional footers to the issue.


================================================
FILE: .claude/commands/cuga-ruff-check.md
================================================
1. Run `uv run ruff check --fix` on the project (or the files in scope).

2. Fix any issues Ruff still reports after `--fix` (manual or refactors, not suppressed without a good reason).

3. Run `uv run ruff format` so formatting matches project style.


================================================
FILE: .cra/.fileignore
================================================
docs
node_modules
Dockerfile

================================================
FILE: .dockerignore
================================================
# Logging directories and files
logs/
log/
logging/
*.log
*.log.*

# Node.js dependencies
node_modules/
**/node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Environment files
.env.local
.env.development.local
.env.test.local
.env.production.local

.venv/
**/.venv/

# IDE and editor files
.vscode/
.idea/
.cursor/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Git
.git
.gitignore

# Docker
Dockerfile*
docker-compose*
.dockerignore

# Secrets and certs
deployment/certs/*.key
deployment/certs/*.crt
.deployment/helm/*.env
!deployment/helm/openshift.example.env

# Build artifacts (KEEP frontend dist + extension releases - required for demo UI)
target/
**/__pycache__/
**/*.pyc
**/dist/
!src/cuga/frontend/dist
**/build/
**/.vite/
**/.output/
.pnpm-store/
*.egg-info/
**/*.egg-info/
**/.pytest_cache/
**/.mypy_cache/
**/playwright-report/
**/test-results/
**/blob-report/

# Cache directories
.cache/
.tmp/
temp/

# Local databases (DBS_DIR = src/cuga/dbs)
src/cuga/dbs/

# Coverage reports
coverage/
.nyc_output/


output
logging/trajectory_data
appworld/experiments/outputs
logging/code
src/cuga/logging/

src/system_tests/e2e/logs/
src/system_tests/

# Runtime/temp dirs (from .gitignore)
crm_tmp/
debug_extractions/
debug_extractions_websocket/
test_workspace/
appworld/
server_logs/
trajectory/
evaluation/results
evaluation/logs
evaluation/logger
evaluation/experiments/outputs
experiments/outputs
test_results.json
experiment_results_*
*.db
cuga.egg-info/
cuga-dashboard/

# Secrets and certs
deployment/certs/*.key
deployment/certs/*.crt
.secrets.*
!.secrets.baseline

# Documentation — demo MCP sources now live under src/cuga/demo_tools (copied with image)
docs/**
# Bundled demo tools: exclude local dev artifacts only
src/cuga/demo_tools/**/.venv/
src/cuga/demo_tools/**/build/
src/cuga/demo_tools/**/*.db
src/cuga/demo_tools/email_mcp/mcp_mail/


# Secrets and local dev
.cursor/
deployment/certs/*.key
deployment/certs/*.crt
.env
.secrets.*
!*.secrets.baseline

================================================
FILE: .gitattributes
================================================
# Shell scripts must use LF so Linux containers do not get CRLF shebangs (exec format error)
*.sh text eol=lf

# Exclude build directories from diffs and linguist statistics
src/frontend_workspaces/extension/releases/** -diff
src/frontend_workspaces/extension/releases/** linguist-vendored
src/cuga/frontend/dist/** -diff
src/cuga/frontend/dist/** linguist-vendored
src/frontend_workspaces/shared/dist/** -diff
src/frontend_workspaces/shared/dist/** linguist-vendored

# Ignore all JSON/YAML/TXT/CSV files (nested across repo)
**/*.json
**/*.yaml
**/*.yml
**/*.txt
**/*.csv

# (Optional) keep important ones
\!package.json
\!.github/workflows/*.yml


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: 🐛 Bug Report
description: Report a bug or unexpected behavior
title: "[Bug]: "
labels: ["bug", "needs-triage"]
assignees: []

body:
  - type: markdown
    attributes:
      value: |
        Include enough detail that we can reproduce the issue.

  - type: textarea
    id: summary
    attributes:
      label: What happened
      description: What you did, what you expected, and what went wrong (errors or screenshots welcome in the field below).
    validations:
      required: true

  - type: textarea
    id: reproduction
    attributes:
      label: How to reproduce
      description: Steps or commands that trigger the bug.
    validations:
      required: true

  - type: textarea
    id: environment
    attributes:
      label: Environment
      description: OS, CUGA version, and runtime versions that matter (Python, Node, browser, etc.).
    validations:
      required: true

  - type: textarea
    id: extras
    attributes:
      label: Logs, screenshots, or config
      description: Optional. Paste logs or redacted config if it helps.
    validations:
      required: false

  - type: checkboxes
    id: checklist
    attributes:
      label: Checklist
      options:
        - label: I searched existing issues and this doesn’t look like a duplicate
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false


================================================
FILE: .github/ISSUE_TEMPLATE/documentation-request.yml
================================================
name: 📚 Documentation Update
description: Suggest a fix, enhancement, or new content for the documentation.
title: "[Docs]: <Short Description>"
labels: ["documentation"]
body:
  - type: markdown
    attributes:
      value: |
        Thanks for helping improve our documentation! Please fill out the sections below.

  - type: dropdown
    id: doc_action
    attributes:
      label: Type of Change
      description: What kind of documentation work is needed?
      options:
        - Fix (Typos, broken links, factual errors)
        - Enhance (Clarify existing content, add examples)
        - Add (Create new guides, pages, or sections)
        - Other
    validations:
      required: true

  - type: input
    id: doc_action_other
    attributes:
      label: If "Other", please specify
      description: Required if you selected "Other" above. Briefly describe the type of change.
      placeholder: e.g., Reorganize navigation, Update branding, Translate content

  - type: input
    id: location
    attributes:
      label: URL / Location (Optional)
      description: Please paste the link to the specific page or section (if applicable).
      placeholder: https://docs.example.com/getting-started

  - type: textarea
    id: description
    attributes:
      label: Description of the Issue
      description: Please describe what needs to be changed and why.
      placeholder: The installation steps for Linux are currently outdated...
    validations:
      required: true

  - type: textarea
    id: current_text
    attributes:
      label: Current Text (Optional)
      description: Copy the existing text here if you are fixing or enhancing it.
      render: markdown
      placeholder: |
        To install in Linux, run `pip install cuga-agent==0.0.1-nightly`...
  
  - type: textarea
    id: suggested_text
    attributes:
      label: Suggested Text / Solution
      description: Please provide your suggested changes or the new content you wish to add.
      render: markdown
      placeholder: |
        To install in Linux, run `uv pip install cuga-agent`...
    validations:
      required: true

  - type: textarea
    id: additional_context
    attributes:
      label: Additional Context
      description: Any other details, screenshots, or mockups? _If you have a screenshot or visual aid, you can drag and drop it into the box below._


  - type: checkboxes
    id: quick_checks
    attributes:
      label: Quick Checks
      options:
        - label: I have searched existing issues to avoid duplicates
        - label: I have verified this issue exists in the latest documentation

================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: ✨ Feature / Design / Proposal
description: Suggest a new feature, design, refactor, or other improvement
title: "[Feature]: "
labels: ["enhancement", "needs-triage"]
assignees: []

body:
  - type: dropdown
    id: issue_type
    attributes:
      label: Issue type
      description: Choose the prefix that best fits. Update the title above to match (e.g. `[Design]: ...`).
      options:
        - "[Feature] – new functionality or capability"
        - "[Design] – architecture, API design, or UX proposal"
        - "[Refactor] – internal restructuring, no behavior change"
        - "[Performance] – speed, memory, or efficiency improvement"
        - "[Security] – vulnerability, safety concern, or hardening"
        - "[Docs] – documentation additions or corrections"
        - "[Test] – missing tests, flaky tests, or test infrastructure"
        - "[Chore] – dependency updates, cleanup, or tooling"
        - "[Epic] – large body of work grouping multiple issues"
        - "[Question] – clarification needed"
    validations:
      required: true

  - type: markdown
    attributes:
      value: |
        Describe the proposal and why it matters so we can evaluate it.

  - type: textarea
    id: summary
    attributes:
      label: What you want and why
      description: The feature, the problem it solves, and how you’d use it.
    validations:
      required: true

  - type: textarea
    id: proposal
    attributes:
      label: How it could work
      description: Your ideal behavior or API; optional notes on workarounds or alternatives you’ve tried.
    validations:
      required: true

  - type: textarea
    id: extras
    attributes:
      label: Links or extra context
      description: Optional. Docs, prior art, mockups, or constraints.
    validations:
      required: false

  - type: checkboxes
    id: checklist
    attributes:
      label: Checklist
      options:
        - label: I searched existing issues and this doesn’t look like a duplicate
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/use_case.yml
================================================
name: 💡 Use Case / Success Story
description: Share how you're using CUGA or showcase a successful implementation
title: "[Use Case]: "
labels: ["use-case", "community"]
assignees: []

body:
  - type: markdown
    attributes:
      value: |
        We'd love to hear about how you're using CUGA! Share your use case, success story, or interesting implementation to inspire others in the community.

  - type: textarea
    id: use-case-title
    attributes:
      label: Use Case Title
      description: Give your use case a descriptive title
      placeholder: |
        Example: "Automated Customer Service Agent for E-commerce Platform"
    validations:
      required: true

  - type: textarea
    id: overview
    attributes:
      label: Overview
      description: Provide a high-level overview of what you built or how you're using CUGA
      placeholder: |
        Example: Built an AI agent that handles customer inquiries, processes returns, and manages order status updates across multiple e-commerce platforms using CUGA's multi-tool integration.
    validations:
      required: true

  - type: dropdown
    id: category
    attributes:
      label: Category
      description: What category best describes your use case?
      options:
        - Business Automation
        - Data Processing & Analytics
        - Customer Service & Support
        - Content Creation & Management
        - Development & DevOps
        - Research & Education
        - Personal Productivity
        - Integration & Workflow
        - Other
    validations:
      required: true

  - type: textarea
    id: problem-solved
    attributes:
      label: Problem Solved
      description: What problem did CUGA help you solve?
      placeholder: |
        Example: Our customer service team was overwhelmed with repetitive inquiries about order status, returns, and product information. Manual processing was taking 2-3 hours per day.
    validations:
      required: true

  - type: textarea
    id: implementation
    attributes:
      label: Implementation Details
      description: How did you implement your solution? What tools and integrations did you use?
      placeholder: |
        Example: 
        - Used OpenAPI tools to connect to Shopify and WooCommerce APIs
        - Integrated MCP filesystem tools for order document management  
        - Created LangChain tools for email response generation
        - Set up automated workflows using CUGA's task orchestration
    validations:
      required: true

  - type: textarea
    id: tools-used
    attributes:
      label: Tools & Technologies Used
      description: List the specific tools, APIs, and technologies you integrated with CUGA
      placeholder: |
        Example:
        - CUGA Agent with browser automation
        - OpenAPI integrations: Shopify API, Stripe API
        - MCP tools: Filesystem, Database connector
        - LangChain tools: Custom email generator, sentiment analysis
        - Additional: SendGrid for email, Slack for notifications
    validations:
      required: true

  - type: textarea
    id: results
    attributes:
      label: Results & Impact
      description: What results did you achieve? Include metrics, time saved, or other benefits if possible.
      placeholder: |
        Example:
        - Reduced customer response time from 4 hours to 15 minutes
        - Automated 80% of routine customer inquiries
        - Saved 15+ hours per week of manual work
        - Improved customer satisfaction scores by 25%
    validations:
      required: true

  - type: textarea
    id: challenges
    attributes:
      label: Challenges & Solutions
      description: What challenges did you face during implementation and how did you solve them?
      placeholder: |
        Example:
        - Challenge: API rate limiting with high-volume requests
        - Solution: Implemented request batching and retry logic with exponential backoff
        
        - Challenge: Handling complex multi-step workflows
        - Solution: Used CUGA's task decomposition to break complex requests into manageable steps
    validations:
      required: false

  - type: textarea
    id: code-snippets
    attributes:
      label: Code Snippets / Configuration
      description: Share relevant code snippets, configuration files, or architecture diagrams (remove sensitive information)
      placeholder: |
        ```python
        # Example configuration or key code snippets
        from cuga import CugaAgent
        
        agent = CugaAgent()
        # Your implementation details...
        ```
        
        ```yaml
        # mcp_servers.yaml example
        services:
          - shopify_api:
              url: https://your-shop.myshopify.com/admin/api/openapi.json
        ```
    validations:
      required: false

  - type: textarea
    id: lessons-learned
    attributes:
      label: Lessons Learned / Tips
      description: What did you learn during the implementation? Any tips for others attempting similar use cases?
      placeholder: |
        Example:
        - Start with simple workflows and gradually add complexity
        - Test tool integrations individually before combining them
        - Use dummy data during development to avoid API rate limits
        - Monitor agent performance and add fallback mechanisms
    validations:
      required: false

  - type: dropdown
    id: scale
    attributes:
      label: Scale of Implementation
      description: What's the scale of your implementation?
      options:
        - Personal project / Prototype
        - Small team (2-10 users)
        - Department (10-50 users)
        - Company-wide (50+ users)
        - Production system with external users
    validations:
      required: true

  - type: checkboxes
    id: sharing-permissions
    attributes:
      label: Sharing Permissions
      description: How can the community use this information?
      options:
        - label: This use case can be featured in CUGA documentation or blog posts
          required: false
        - label: I'm open to being contacted for follow-up questions about this implementation
          required: false
        - label: I'm willing to share more detailed implementation guidance with the community
          required: false
        - label: This implementation is open source and available for others to use
          required: false

  - type: textarea
    id: additional-context
    attributes:
      label: Additional Context
      description: Any additional information, links to demos, blog posts, or repositories?
      placeholder: |
        Links to:
        - Demo videos or screenshots
        - Blog posts about your implementation
        - Open source repositories
        - Company case studies
        - Performance metrics or dashboards
    validations:
      required: false

  - type: checkboxes
    id: checklist
    attributes:
      label: Checklist
      description: Please confirm the following
      options:
        - label: I have removed any sensitive information from my submission
          required: true
        - label: I am sharing this use case to help and inspire the CUGA community
          required: true
        - label: The information provided is accurate and represents my actual experience
          required: true


================================================
FILE: .github/PULL_REQUEST_TEMPLATE/bugfix.md
================================================
## Bug fix

Fixes #

### Summary


### Testing
- [ ] Verified fix locally; tests pass


================================================
FILE: .github/PULL_REQUEST_TEMPLATE/chore.md
================================================
## Chore

Closes #

### Summary



================================================
FILE: .github/PULL_REQUEST_TEMPLATE/docs.md
================================================
## Documentation

Closes #

### Summary



================================================
FILE: .github/PULL_REQUEST_TEMPLATE/feature.md
================================================
## Feature

Closes #

### Summary


### Testing
- [ ] Tested locally; tests pass


================================================
FILE: .github/workflows/deploy-image-ghcr.yml
================================================
# Required vars: IMAGE_NAME
name: Deploy Image to GHCR

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'
  workflow_dispatch:
    inputs:
      image_tag:
        description: 'Image tag (e.g. 1.0.0). Omit to use git tag or latest.'
        required: false
        default: ''

jobs:
  deploy:
    name: Build and push image
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          ref: ${{ github.ref }}

      - name: Validate vars
        run: |
          missing=""
          [ -z "${{ vars.IMAGE_NAME }}" ] && missing="$missing IMAGE_NAME"
          if [ -n "$missing" ]; then
            echo "::error::Missing repository variables:$missing"
            echo "Set them in: Settings → Secrets and variables → Actions → Variables"
            exit 1
          fi

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract Docker metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository_owner }}/${{ vars.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}
            type=raw,value=${{ inputs.image_tag }},enable=${{ inputs.image_tag != '' }}
            type=raw,value=latest,enable=${{ inputs.image_tag == '' && github.event_name != 'push' }}
          labels: |
            org.opencontainers.image.title=${{ vars.IMAGE_NAME }}
            org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}

      - name: Build and push image to GHCR
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile.ubi
          push: true
          platforms: linux/amd64,linux/arm64
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}


================================================
FILE: .github/workflows/deploy-image.yml
================================================
# Required secret: RIS_CLOUD_ACCOUNT_API_KEY
# Required vars: IBM_CLOUD_URL, IBM_CLOUD_REGION, IBM_CLOUD_GROUP, IBM_REGISTRY_URL,
# IBM_CR_NAMESPACE, IMAGE_NAME, IMAGE_TAG
name: Deploy Image to IBM Cloud

on:
  workflow_dispatch:

jobs:
  deploy:
    name: Build and push image
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Validate vars
        run: |
          missing=""
          [ -z "${{ vars.IBM_CLOUD_URL }}" ] && missing="$missing IBM_CLOUD_URL"
          [ -z "${{ vars.IBM_CLOUD_REGION }}" ] && missing="$missing IBM_CLOUD_REGION"
          [ -z "${{ vars.IBM_CLOUD_GROUP }}" ] && missing="$missing IBM_CLOUD_GROUP"
          [ -z "${{ vars.IBM_REGISTRY_URL }}" ] && missing="$missing IBM_REGISTRY_URL"
          [ -z "${{ vars.IBM_CR_NAMESPACE }}" ] && missing="$missing IBM_CR_NAMESPACE"
          [ -z "${{ vars.IMAGE_NAME }}" ] && missing="$missing IMAGE_NAME"
          [ -z "${{ vars.IMAGE_TAG }}" ] && missing="$missing IMAGE_TAG"
          if [ -n "$missing" ]; then
            echo "::error::Missing repository variables:$missing"
            echo "Set them in: Settings → Secrets and variables → Actions → Variables"
            exit 1
          fi

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build image
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile.ubi
          push: false
          load: true
          tags: ${{ vars.IBM_REGISTRY_URL }}/${{ vars.IBM_CR_NAMESPACE }}/${{ vars.IMAGE_NAME }}:${{ vars.IMAGE_TAG }}

      - name: Install IBM Cloud CLI
        uses: IBM/actions-ibmcloud-cli@v1
        with:
          api_key: ${{ secrets.RIS_CLOUD_ACCOUNT_API_KEY }}
          region: ${{ vars.IBM_CLOUD_REGION }}
          group: ${{ vars.IBM_CLOUD_GROUP }}
          api: ${{ vars.IBM_CLOUD_URL }}
          plugins: container-registry

      - name: Deploy to IBM Cloud Registry
        env:
          RIS_CLOUD_ACCOUNT_API_KEY: ${{ secrets.RIS_CLOUD_ACCOUNT_API_KEY }}
          TARGET_IBM_CLOUD_URL: ${{ vars.IBM_CLOUD_URL }}
          TARGET_IBM_CLOUD_REGION: ${{ vars.IBM_CLOUD_REGION }}
          TARGET_IBM_CLOUD_GROUP: ${{ vars.IBM_CLOUD_GROUP }}
          TARGET_IBM_REGISTRY_URL: ${{ vars.IBM_REGISTRY_URL }}
          CR_NAMESPACE: ${{ vars.IBM_CR_NAMESPACE }}
          IMAGE_NAME: ${{ vars.IMAGE_NAME }}
          IMAGE_TAG: ${{ vars.IMAGE_TAG }}
        run: |
          chmod +x ./scripts/deploy-image.sh
          ./scripts/deploy-image.sh "$TARGET_IBM_CLOUD_URL" "$TARGET_IBM_CLOUD_REGION" "$TARGET_IBM_CLOUD_GROUP" "$TARGET_IBM_REGISTRY_URL" "$CR_NAMESPACE" "$IMAGE_NAME" "$IMAGE_TAG"


================================================
FILE: .github/workflows/release-pr.yml
================================================
name: Release PR

on:
  workflow_dispatch:
    inputs:
      bump:
        description: 'Version bump type'
        required: true
        default: 'patch'
        type: choice
        options:
          - patch
          - minor
          - major

jobs:
  release-pr:
    name: Create release PR
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - name: Install uv
        uses: astral-sh/setup-uv@v6

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Configure Git
        run: |
          git config user.name "cuga-agent[bot]"
          git config user.email "cuga-agent[bot]@users.noreply.github.com"

      - name: Create release branch and PR
        env:
          GH_TOKEN: ${{ github.token }}
          BUMP: ${{ inputs.bump }}
        run: |
          git fetch origin main
          git checkout main
          git pull origin main
          CURRENT=$(grep '^version' pyproject.toml | sed -n 's/version = "\(.*\)"/\1/p')
          MAJOR=$(echo "$CURRENT" | cut -d. -f1)
          MINOR=$(echo "$CURRENT" | cut -d. -f2)
          PATCH=$(echo "$CURRENT" | cut -d. -f3)
          case "$BUMP" in
            major) NEW_VERSION=$((MAJOR+1)).0.0 ;;
            minor) NEW_VERSION=$MAJOR.$((MINOR+1)).0 ;;
            patch) NEW_VERSION=$MAJOR.$MINOR.$((PATCH+1)) ;;
            *) echo "Invalid bump: $BUMP"; exit 1 ;;
          esac
          BRANCH="release/v$NEW_VERSION"
          git checkout -b "$BRANCH"
          sed -i "s/^version = \".*\"/version = \"$NEW_VERSION\"/" pyproject.toml
          uv sync
          git add pyproject.toml uv.lock
          git commit -m "chore: release v$NEW_VERSION"
          git push origin "$BRANCH"
          gh pr create --base main --head "$BRANCH" --title "chore: release v$NEW_VERSION" --body "Release v$NEW_VERSION. Merge to complete release, then run the Release Tag workflow."
          echo "Created PR for v$NEW_VERSION"


================================================
FILE: .github/workflows/release-tag.yml
================================================
name: Release Tag

on:
  pull_request:
    types: [closed]
    branches: [main]
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to tag (e.g. 0.2.10)'
        required: true
        type: string

jobs:
  release-tag:
    name: Create and push tag
    runs-on: ubuntu-latest
    if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.merged == true && (startsWith(github.event.pull_request.head.ref, 'release/') || contains(github.event.pull_request.title, 'release v')))
    permissions:
      contents: write
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - name: Get version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
          else
            VERSION=$(echo "${{ github.event.pull_request.title }}" | sed -n 's/.*release v\([0-9.]*\).*/\1/p')
            if [ -z "$VERSION" ]; then
              VERSION=$(echo "${{ github.event.pull_request.head.ref }}" | sed 's|release/v||')
            fi
            echo "version=$VERSION" >> $GITHUB_OUTPUT
          fi

      - name: Create and push tag
        run: |
          git fetch origin main
          git checkout main
          git pull origin main
          VERSION="${{ steps.version.outputs.version }}"
          if [ -z "$VERSION" ]; then
            echo "Could not determine version"
            exit 1
          fi
          TAG="v${VERSION}"
          git tag "$TAG"
          git push origin "$TAG"
          echo "TAG=$TAG" >> $GITHUB_ENV

      - name: Create release with auto-generated notes
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "$TAG" --generate-notes


================================================
FILE: .github/workflows/release.yml
================================================
name: Release

on:
  push:
    tags:
      - v*
  workflow_dispatch:

jobs:
  pypi:
    name: Publish to PyPI
    runs-on: ubuntu-latest
    environment:
      name: pypi
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout
        uses: actions/checkout@v5
      - name: Install uv
        uses: astral-sh/setup-uv@v6
      - name: Install Python 3.12
        run: uv python install 3.12
      - name: Build
        run: uv build
      - name: Publish
        run: uv publish

================================================
FILE: .github/workflows/smoke-pip-install.yml
================================================
name: Smoke pip install (isolated)

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]
  workflow_dispatch:

concurrency:
  group: smoke-pip-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  smoke-pip-isolated:
    name: Wheel install + demo_crm OpenAPI
    runs-on: ubuntu-latest
    timeout-minutes: 25
    env:
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      MODEL_NAME: ${{ secrets.MODEL_NAME }}
      GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
      OPENAI_BASE_URL: ${{ secrets.WATSONX_API_KEY }}
      AGENT_SETTING_CONFIG: ${{ secrets.AGENT_SETTING_CONFIG }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Install uv
        uses: astral-sh/setup-uv@v6

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Isolated wheel smoke (demo_crm → OpenAPI)
        run: bash scripts/smoke_pip_install_isolated.sh


================================================
FILE: .github/workflows/stability-tests.yml
================================================
name: Stability Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  workflow_dispatch:

jobs:
  stability-tests:
    name: Stability Tests (Python ${{ matrix.python-version }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version:
          - "3.11"
          - "3.12"
          - "3.13"

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Install uv and set the Python version
        uses: astral-sh/setup-uv@v7
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --dev

      - name: Copy huggingface examples
        run: |
          mkdir -p ./cuga_workspace
          cp -r src/cuga/demo_tools/huggingface/* ./cuga_workspace/

      - name: Run stability tests
        continue-on-error: true
        id: test-run
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          MODEL_NAME: ${{ secrets.MODEL_NAME }}
          GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
          OPENAI_BASE_URL: ${{ secrets.WATSONX_API_KEY }}
          AGENT_SETTING_CONFIG: ${{ secrets.AGENT_SETTING_CONFIG }}
          TEST_RESULTS_FILE: test_results_python_${{ matrix.python-version }}.json
          PYTHONIOENCODING: utf-8
        run: uv run run_stability_tests.py --method local

      - name: Check pass rate
        if: always()
        run: |
          results_file="test_results_python_${{ matrix.python-version }}.json"
          if [ ! -f "$results_file" ]; then
            echo "❌ Test results file not found. Tests may have failed before completion."
            exit 1
          fi
          python3 << EOF
          import json
          import sys
          with open('$results_file', 'r') as f:
              data = json.load(f)
          pass_rate = data.get('pass_rate', 0)
          if pass_rate < 88:
              print(f"❌ Pass rate is {pass_rate}%, which is below the required 88%. Failing the job.")
              sys.exit(1)
          print(f"✅ Pass rate is {pass_rate}%, which meets the required 88% threshold.")
          EOF

      - name: Upload test logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-logs-python-${{ matrix.python-version }}
          path: src/system_tests/e2e/logs/
          retention-days: 7

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-python-${{ matrix.python-version }}
          path: test_results_python_${{ matrix.python-version }}.json
          retention-days: 7

  stability-tests-windows:
    name: Stability Tests Windows (Python 3.12)
    runs-on: windows-latest
    timeout-minutes: 60
    strategy:
      fail-fast: false

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Install uv and set the Python version
        uses: astral-sh/setup-uv@v7
        with:
          python-version: "3.12"

      - name: Install dependencies
        env:
          UV_NO_PROGRESS: 1
          UV_QUIET: 1
        run: uv sync --dev

      - name: Copy huggingface examples
        run: |
          New-Item -ItemType Directory -Force -Path ./cuga_workspace
          Copy-Item -Recurse -Force src/cuga/demo_tools/huggingface/* ./cuga_workspace/

      - name: Run stability tests
        continue-on-error: true
        id: test-run
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          MODEL_NAME: ${{ secrets.MODEL_NAME }}
          GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
          OPENAI_BASE_URL: ${{ secrets.OPENAI_BASE_URL }}
          AGENT_SETTING_CONFIG: ${{ secrets.AGENT_SETTING_CONFIG }}
          TEST_RESULTS_FILE: test_results_python_3.12_windows.json
          UV_NO_PROGRESS: 1
          UV_QUIET: 1
          PYTHONIOENCODING: utf-8
        run: uv run run_stability_tests.py --method local

      - name: Check pass rate
        if: always()
        shell: pwsh
        run: |
          $resultsFile = "test_results_python_3.12_windows.json"
          if (-not (Test-Path $resultsFile)) {
            Write-Host "❌ Test results file not found. Tests may have failed before completion."
            exit 1
          }
          $results = Get-Content $resultsFile | ConvertFrom-Json
          $passRate = $results.pass_rate
          if ($passRate -lt 88) {
            Write-Host "❌ Pass rate is ${passRate}%, which is below the required 88%. Failing the job."
            exit 1
          }
          Write-Host "✅ Pass rate is ${passRate}%, which meets the required 88% threshold."

      - name: Upload test logs
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-logs-python-3.12-windows
          path: src/system_tests/e2e/logs/
          retention-days: 7

      - name: Upload test results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-results-python-3.12-windows
          path: test_results_python_3.12_windows.json
          retention-days: 7

  summary:
    name: Test Summary
    runs-on: ubuntu-latest
    needs: [stability-tests, stability-tests-windows]
    if: always()
    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Install uv
        uses: astral-sh/setup-uv@v7

      - name: Install dependencies
        run: uv sync --dev

      - name: Download test results
        uses: actions/download-artifact@v4
        with:
          pattern: test-results-python-*
          merge-multiple: true
          path: test-results

      - name: Generate summary report
        run: uv run run_stability_tests.py --generate-summary --results-dir test-results


================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  workflow_dispatch:

jobs:
  unit-tests:
    name: Unit Tests
    runs-on: ubuntu-latest
    env:
      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
      MODEL_NAME: ${{ secrets.MODEL_NAME }}
      GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
      OPENAI_BASE_URL: ${{ secrets.WATSONX_API_KEY }}
      AGENT_SETTING_CONFIG: ${{ secrets.AGENT_SETTING_CONFIG }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v5
      
      - name: Install uv
        uses: astral-sh/setup-uv@v6
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      
      - name: Install dependencies
        run: uv sync --all-extras --dev
      
      - name: Install Playwright browsers
        run: uv run playwright install --with-deps chromium
      
      - name: Run unit tests
        run: bash src/scripts/run_tests.sh --skip-stability



================================================
FILE: .gitignore
================================================
.env
__pycache__
output
*.db
cuga_workspace/
.idea
node_modules
.pnpm-store/
*.log
/frontend/dist/
src/frontend_workspaces/frontend/dist/
/frontend/node_modules/
experiment_results_*
output_graphs
*.egg-info/
backup_*
test_results.json
vendor
logs/
.milvus*
.bob
!.bob/commands/
!.bob/commands/cuga-*.md
test_workspace/
*.logs

# Test-related temporary files and folders
.cuga_*
.cuga
.cuga_test_*
policy_db_test_*.db
.policy_test_tmp_*
dist_cuga
agent-analytics
trajectory
cuga-dashboard
logging/trajectory_data
logging/
dbs/
crm_tmp/
debug_extractions/
debug_extractions_websocket/
# Ignore dynaconf secret files
.secrets.*
!.secrets.baseline
agents.egg-info
evaluation/results
evaluation/logs
evaluation/logger
evaluation_*
logging_*
evaluation/experiments/outputs/*
.DS_Store
appworld
server_logs
modes.custom.toml

experiments/outputs
/evaluation/data/tasks/
/evaluation/data/
/build/
src/cuga/demo_tools/email_mcp/mcp_mail
src/cuga/demo_tools/email_mcp/mail_sink/build
src/cuga/demo_tools/email_mcp/mcp_server/build
src/cuga/demo_tools/file_system/build
src/cuga/demo_tools/**/*.egg-info/

# Local dependencies
vendor/
cuga.egg-info

# IDE and editor files
.cursor/
!.cursor/commands/
!.cursor/commands/cuga-*.md

# Local TLS certs for HTTPS (e.g. IBM Verify)
deployment/certs/*.key
deployment/certs/*.crt
registry.env
# OpenShift env files with real secrets (keep only openshift.example.env)
deployment/helm/openshift.env
deployment/helm/*.env
!deployment/helm/openshift.example.env
KNOWLEDGE_PIPELINE.md

# Examples that use repo-root uv.lock only (see CONTRIBUTING.md)
docs/examples/cuga_as_mcp/uv.lock
docs/examples/cuga_with_runtime_tools/uv.lock

# Registry credentials (copy from registry.example.env)
scripts/registry.env

# Tracked even if core.excludesfile / global gitignore lists this basename
!scripts/smoke_pip_install_isolated.sh


================================================
FILE: .pre-commit-config.yaml
================================================
# Pre-commit hooks configuration
# See https://pre-commit.com for more information

repos:
  # Ruff - Python linting and formatting (using uv)
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.14.3
    hooks:
      # Run the linter
      - id: ruff
        name: ruff check
        args: [--fix]
        types_or: [python, pyi]
      # Run the formatter
      - id: ruff-format
        name: ruff format
        types_or: [python, pyi]

  # Standard pre-commit hooks
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v6.0.0
    hooks:
      - id: check-added-large-files
        args: ['--maxkb=2000']
        exclude: '^src/cuga/frontend/dist/'

  # Conventional Commits - validate commit message format
  - repo: https://github.com/compilerla/conventional-pre-commit
    rev: v4.3.0
    hooks:
      - id: conventional-pre-commit
        name: conventional commits
        stages: [commit-msg]
        args: []

  # Detect secrets - prevent committing sensitive information
  - repo: https://github.com/ibm/detect-secrets
    rev: 0.13.1+ibm.64.dss
    hooks:
      - id: detect-secrets
        name: detect secrets
        args: ['--baseline', '.secrets.baseline']
        exclude: package.lock.json


================================================
FILE: .python-version
================================================
3.12.7

================================================
FILE: .run/API Registry Appworld.run.xml
================================================
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="API Registry Appworld" type="PythonConfigurationType" factoryName="Python">
    <module name="AgentS" />
    <option name="ENV_FILES" value="" />
    <option name="INTERPRETER_OPTIONS" value="" />
    <option name="PARENT_ENVS" value="true" />
    <envs>
      <env name="PYTHONUNBUFFERED" value="1" />
      <env name="MCP_SERVERS_FILE" value="mcp_servers_appworld.yaml" />
    </envs>
    <option name="SDK_HOME" value="" />
    <option name="SDK_NAME" value="Python 3.12 (cuga)" />
    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
    <option name="IS_MODULE_SDK" value="false" />
    <option name="ADD_CONTENT_ROOTS" value="true" />
    <option name="ADD_SOURCE_ROOTS" value="true" />
    <EXTENSION ID="net.ashald.envfile">
+      <option name="IS_ENABLED" value="false" />
+      <option name="IS_SUBST" value="false" />
+      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
+      <option name="IS_IGNORE_MISSING_FILES" value="false" />
+      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
+      <ENTRIES>
+        <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
+      </ENTRIES>
+    </EXTENSION>
    <option name="SCRIPT_NAME" value="uvicorn" />
    <option name="PARAMETERS" value="cuga.backend.tools_env.registry.registry.api_registry_server:app --port 8001" />
    <option name="SHOW_COMMAND_LINE" value="false" />
    <option name="EMULATE_TERMINAL" value="false" />
    <option name="MODULE_MODE" value="true" />
    <option name="REDIRECT_INPUT" value="false" />
    <option name="INPUT_FILE" value="" />
    <method v="2" />
  </configuration>
</component>

================================================
FILE: .run/API Registry Demo.run.xml
================================================
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="API Registry Demo" type="PythonConfigurationType" factoryName="Python">
    <module name="AgentS" />
    <option name="ENV_FILES" value="" />
    <option name="INTERPRETER_OPTIONS" value="" />
    <option name="PARENT_ENVS" value="true" />
    <envs>
      <env name="PYTHONUNBUFFERED" value="1" />
      <env name="MCP_SERVERS_FILE" value="mcp_servers.yaml" />
    </envs>
    <option name="SDK_HOME" value="" />
    <option name="SDK_NAME" value="Python 3.12 (cuga)" />
    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
    <option name="IS_MODULE_SDK" value="false" />
    <option name="ADD_CONTENT_ROOTS" value="true" />
    <option name="ADD_SOURCE_ROOTS" value="true" />
    <EXTENSION ID="net.ashald.envfile">
+      <option name="IS_ENABLED" value="false" />
+      <option name="IS_SUBST" value="false" />
+      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
+      <option name="IS_IGNORE_MISSING_FILES" value="false" />
+      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
+      <ENTRIES>
+        <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
+      </ENTRIES>
+    </EXTENSION>
    <option name="SCRIPT_NAME" value="uvicorn" />
    <option name="PARAMETERS" value="cuga.backend.tools_env.registry.registry.api_registry_server:app --port 8001" />
    <option name="SHOW_COMMAND_LINE" value="true" />
    <option name="EMULATE_TERMINAL" value="false" />
    <option name="MODULE_MODE" value="true" />
    <option name="REDIRECT_INPUT" value="false" />
    <option name="INPUT_FILE" value="" />
    <method v="2" />
  </configuration>
</component>

================================================
FILE: .run/App World Eval.run.xml
================================================
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="App World Eval" type="PythonConfigurationType" factoryName="Python">
    <module name="AgentS" />
    <option name="ENV_FILES" value="" />
    <option name="INTERPRETER_OPTIONS" value="" />
    <option name="PARENT_ENVS" value="true" />
    <option name="SDK_HOME" value="" />
    <option name="SDK_NAME" value="Python 3.12 (cuga)" />
    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/" />
    <option name="IS_MODULE_SDK" value="false" />
    <option name="ADD_CONTENT_ROOTS" value="true" />
    <option name="ADD_SOURCE_ROOTS" value="true" />
    <EXTENSION ID="net.ashald.envfile">
      <option name="IS_ENABLED" value="false" />
      <option name="IS_SUBST" value="false" />
      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
      <option name="IS_IGNORE_MISSING_FILES" value="false" />
      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
      <ENTRIES>
        <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
      </ENTRIES>
    </EXTENSION>
    <option name="SCRIPT_NAME" value="$PROJECT_DIR$/evaluation/appworld_eval.py" />
    <option name="PARAMETERS" value="--eval_key test_normal_easy" />
    <option name="SHOW_COMMAND_LINE" value="true" />
    <option name="EMULATE_TERMINAL" value="false" />
    <option name="MODULE_MODE" value="false" />
    <option name="REDIRECT_INPUT" value="false" />
    <option name="INPUT_FILE" value="" />
    <method v="2" />
  </configuration>
</component>

================================================
FILE: .run/Cuga Demo.run.xml
================================================
<component name="ProjectRunConfigurationManager">
  <configuration default="false" name="Cuga Demo" type="PythonConfigurationType" factoryName="Python">
    <module name="AgentS" />
    <option name="ENV_FILES" value="" />
    <option name="INTERPRETER_OPTIONS" value="" />
    <option name="PARENT_ENVS" value="true" />
    <envs>
      <env name="PYTHONUNBUFFERED" value="1" />
    </envs>
    <option name="SDK_HOME" value="" />
    <option name="SDK_NAME" value="Python 3.12 (cuga)" />
    <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
    <option name="IS_MODULE_SDK" value="false" />
    <option name="ADD_CONTENT_ROOTS" value="true" />
    <option name="ADD_SOURCE_ROOTS" value="true" />
    <EXTENSION ID="net.ashald.envfile">
+      <option name="IS_ENABLED" value="false" />
+      <option name="IS_SUBST" value="false" />
+      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
+      <option name="IS_IGNORE_MISSING_FILES" value="false" />
+      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
+      <ENTRIES>
+        <ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
+      </ENTRIES>
+   </EXTENSION>
    <option name="SCRIPT_NAME" value="fastapi" />
    <option name="PARAMETERS" value="dev cuga/backend/server/main.py --no-reload --port=8005" />
    <option name="SHOW_COMMAND_LINE" value="true" />
    <option name="EMULATE_TERMINAL" value="false" />
    <option name="MODULE_MODE" value="true" />
    <option name="REDIRECT_INPUT" value="false" />
    <option name="INPUT_FILE" value="" />
    <method v="2" />
  </configuration>
</component>

================================================
FILE: .secrets.baseline
================================================
{
  "exclude": {
    "files": "(.*pnpm-lock.*|.*js.*|node_modules|.venv|.*jinja2.*|.*woff2.*)|^.secrets.baseline$|^.env$",
    "lines": null
  },
  "generated_at": "2026-04-24T11:09:02Z",
  "plugins_used": [
    {
      "name": "AWSKeyDetector"
    },
    {
      "name": "ArtifactoryDetector"
    },
    {
      "name": "AzureStorageKeyDetector"
    },
    {
      "base64_limit": 4.5,
      "name": "Base64HighEntropyString"
    },
    {
      "name": "BasicAuthDetector"
    },
    {
      "name": "BoxDetector"
    },
    {
      "name": "CloudantDetector"
    },
    {
      "ghe_instance": "github.ibm.com",
      "name": "GheDetector"
    },
    {
      "name": "GitHubTokenDetector"
    },
    {
      "hex_limit": 3,
      "name": "HexHighEntropyString"
    },
    {
      "name": "IbmCloudIamDetector"
    },
    {
      "name": "IbmCosHmacDetector"
    },
    {
      "name": "JwtTokenDetector"
    },
    {
      "keyword_exclude": null,
      "name": "KeywordDetector"
    },
    {
      "name": "MailchimpDetector"
    },
    {
      "name": "NpmDetector"
    },
    {
      "name": "PrivateKeyDetector"
    },
    {
      "name": "SlackDetector"
    },
    {
      "name": "SoftlayerDetector"
    },
    {
      "name": "SquareOAuthDetector"
    },
    {
      "name": "StripeDetector"
    },
    {
      "name": "TwilioKeyDetector"
    }
  ],
  "results": {
    ".env.example": [
      {
        "hashed_secret": "4769d33515380ef4bb5f07f86ccce38a29a1064a",
        "is_secret": false,
        "is_verified": false,
        "line_number": 4,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "5c327ea40bef3b7be6b98a2e92e290a5893c35bb",
        "is_secret": false,
        "is_verified": false,
        "line_number": 9,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "11fa7c37d697f30e6aee828b4426a10f83ab2380",
        "is_secret": false,
        "is_verified": false,
        "line_number": 14,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "c303df00cd0a72b21c62900b758b06fc541664ce",
        "is_secret": false,
        "is_verified": false,
        "line_number": 27,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "6221b3dae66c78a4e0a27e9cd696e71131e554b9",
        "is_secret": false,
        "is_verified": false,
        "line_number": 44,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    ".github/workflows/deploy-image.yml": [
      {
        "hashed_secret": "748b8787b8e7a581eb53b25da00065e059cdaac2",
        "is_secret": false,
        "is_verified": false,
        "line_number": 1,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "README.md": [
      {
        "hashed_secret": "31b39b4c464eab8599f84caec3a1140c2ba09b0f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 162,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "f23d2bcf6f76d2f36f3fe3df006bb26cf5daf394",
        "is_secret": false,
        "is_verified": false,
        "line_number": 210,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "c6bebac7ac267cd09b766423e74551efde2e8fc5",
        "is_secret": false,
        "is_verified": false,
        "line_number": 237,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "d9e9019d9eb455a3d72a3bc252c26927bb148a10",
        "is_secret": false,
        "is_verified": false,
        "line_number": 257,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "11fa7c37d697f30e6aee828b4426a10f83ab2380",
        "is_secret": false,
        "is_verified": false,
        "line_number": 269,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "49697e763a0dda5673303db0e2a91c309ed73c2d",
        "is_secret": false,
        "is_verified": false,
        "line_number": 287,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "770934e35ff179527cb9ee4cd329cabaf7ba3048",
        "is_secret": false,
        "is_verified": false,
        "line_number": 308,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/.env.example": [
      {
        "hashed_secret": "4769d33515380ef4bb5f07f86ccce38a29a1064a",
        "is_secret": false,
        "is_verified": false,
        "line_number": 4,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "a6778f1880744bd1a342a8e3789135412d8f9da2",
        "is_secret": false,
        "is_verified": false,
        "line_number": 7,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "5c327ea40bef3b7be6b98a2e92e290a5893c35bb",
        "is_secret": false,
        "is_verified": false,
        "line_number": 12,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/README.md": [
      {
        "hashed_secret": "7ff000febb6b9e7d022a01cf0e097b3864bce12e",
        "is_secret": false,
        "is_verified": false,
        "line_number": 86,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "5278a5e4617ed1e35845ffc2460653fa491bdf67",
        "is_secret": false,
        "is_verified": false,
        "line_number": 87,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "d8546aa2057245181c6e9752feb2eefd22d9de7b",
        "is_secret": false,
        "is_verified": false,
        "line_number": 110,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "4e102bd8782fca6a54e1f830dc08e005801be918",
        "is_secret": false,
        "is_verified": false,
        "line_number": 176,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "312998326bd54dbd463abda36df0bcf8c0fec0fd",
        "is_secret": false,
        "is_verified": false,
        "line_number": 177,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "c0d57bc4385e3627a78f75010f66e0ca052cad5d",
        "is_secret": false,
        "is_verified": false,
        "line_number": 182,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "ec417f567082612f8fd6afafe1abcab831fca840",
        "is_secret": false,
        "is_verified": false,
        "line_number": 228,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "9a44f1a6b92be5567dda38cf788254238da0c227",
        "is_secret": false,
        "is_verified": false,
        "line_number": 229,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "a9a12ee985985841c3d66f4de9e5811477ef00f9",
        "is_secret": false,
        "is_verified": false,
        "line_number": 351,
        "type": "Basic Auth Credentials",
        "verified_result": null
      }
    ],
    "deployment/deploy-local-postgres.sh": [
      {
        "hashed_secret": "cff0d14e4337fa8bdb68dfa906f04b0df6fad72f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 34,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/deploy-local.sh": [
      {
        "hashed_secret": "cff0d14e4337fa8bdb68dfa906f04b0df6fad72f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 52,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/helm/cleanup-openshift.sh": [
      {
        "hashed_secret": "75b08fd0503a80e9dff9529ec051878b3c156802",
        "is_secret": false,
        "is_verified": false,
        "line_number": 121,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/helm/deploy-openshift.sh": [
      {
        "hashed_secret": "1bf51b8fc49da6e36d4d73646a7061f23f4ed893",
        "is_secret": false,
        "is_verified": false,
        "line_number": 141,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "a4af39e38af95e2ba51a6ea958eaf260538973b0",
        "is_secret": false,
        "is_verified": false,
        "line_number": 142,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "75b08fd0503a80e9dff9529ec051878b3c156802",
        "is_secret": false,
        "is_verified": false,
        "line_number": 163,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "cff0d14e4337fa8bdb68dfa906f04b0df6fad72f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 206,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/helm/openshift.example.env": [
      {
        "hashed_secret": "8f20f90b7e1c2c1e0ba0771a4e33f23d106c21be",
        "is_secret": false,
        "is_verified": false,
        "line_number": 83,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "ee977806d7286510da8b9a7492ba58e2484c0ecc",
        "is_secret": false,
        "is_verified": false,
        "line_number": 98,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "deployment/helm/postgres-pgvector/README.md": [
      {
        "hashed_secret": "c35bdb821a941808a150db95d0f934f449bbff17",
        "is_secret": false,
        "is_verified": false,
        "line_number": 15,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "04a963d9980f19119d967d50afff9f2b2a203b1d",
        "is_secret": false,
        "is_verified": false,
        "line_number": 17,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "1c2b0d17c738509518ecc6efa233ee6c10e724f2",
        "is_secret": false,
        "is_verified": false,
        "line_number": 25,
        "type": "Basic Auth Credentials",
        "verified_result": null
      }
    ],
    "design.md": [
      {
        "hashed_secret": "e9e7c20cb4ce08767256cbef86437e4561b54799",
        "is_secret": false,
        "is_verified": false,
        "line_number": 161,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "docs/examples/cuga_as_mcp/.env.example": [
      {
        "hashed_secret": "018f4d7f06cb8626e1756452581373e05ae41c56",
        "is_secret": false,
        "is_verified": false,
        "line_number": 19,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "docs/examples/cuga_with_runtime_tools/.env.example": [
      {
        "hashed_secret": "018f4d7f06cb8626e1756452581373e05ae41c56",
        "is_secret": false,
        "is_verified": false,
        "line_number": 19,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "docs/examples/cuga_with_runtime_tools/README.md": [
      {
        "hashed_secret": "bfc5221616fd29387d7413aeb41401391dceefa8",
        "is_secret": false,
        "is_verified": false,
        "line_number": 283,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "docs/examples/cuga_with_runtime_tools/mcp_servers.yaml": [
      {
        "hashed_secret": "a3e14ca24483c78554c083bc907c7194c7846ef1",
        "is_secret": false,
        "is_verified": false,
        "line_number": 56,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "scripts/smoke_pip_install_isolated.sh": [
      {
        "hashed_secret": "cff0d14e4337fa8bdb68dfa906f04b0df6fad72f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 81,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/cuga/backend/llm/models.py": [
      {
        "hashed_secret": "829c3804401b0727f70f73d4415e162400cbe57b",
        "is_secret": false,
        "is_verified": false,
        "line_number": 565,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/cuga/backend/secrets/seed.py": [
      {
        "hashed_secret": "34fdaba0f5e1a8e596fd1b5464ccb26735f16124",
        "is_secret": false,
        "is_verified": false,
        "line_number": 10,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "d5c2ed8d21390c7349954b681276adabf345cd5f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 11,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "f7f71c7b39b889f796dda3ff85c60627bf327c75",
        "is_secret": false,
        "is_verified": false,
        "line_number": 12,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "c94055f8ca03dd00999828feb2eaead9acb1302e",
        "is_secret": false,
        "is_verified": false,
        "line_number": 13,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "3fd1df3d95a156a37d3edd4527feba9a820c56b8",
        "is_secret": false,
        "is_verified": false,
        "line_number": 14,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "414d33be518726d57e9c2af24a85c0f5ba6ce4ca",
        "is_secret": false,
        "is_verified": false,
        "line_number": 16,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "085f4f2247c901ccbb7612ff72b316d20492295b",
        "is_secret": false,
        "is_verified": false,
        "line_number": 17,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "9633a20f8ffd7c00aa793ca8f32f6a0afba0b3ac",
        "is_secret": false,
        "is_verified": false,
        "line_number": 18,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/cuga/backend/tools_env/registry/config/mcp_servers.yaml": [
      {
        "hashed_secret": "89a6cfe2a229151e8055abee107d45ed087bbb4f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 55,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/cuga/backend/tools_env/registry/tests/test_auth/auth_server.py": [
      {
        "hashed_secret": "d4e0e04792fd434b5dc9c4155c178f66edcf4ed3",
        "is_secret": false,
        "is_verified": false,
        "line_number": 18,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "1eac13f1578ef493b9ed5617a5f4a31b271eb667",
        "is_secret": false,
        "is_verified": false,
        "line_number": 20,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/frontend_workspaces/agentic_chat/src/ModelConfig.tsx": [
      {
        "hashed_secret": "2183e6a4e27666ce602ddf941739cf347e2362fe",
        "is_secret": false,
        "is_verified": false,
        "line_number": 148,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/frontend_workspaces/frontend/src/AddToolModal.tsx": [
      {
        "hashed_secret": "6c965552a3682c9ca3435cdfd55af289b8c3b869",
        "is_secret": false,
        "is_verified": false,
        "line_number": 30,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "77fd040d42b4e7a0ee8adf486b9e89841fba1f65",
        "is_secret": false,
        "is_verified": false,
        "line_number": 92,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "1bcc59b324708cc856541522bd845c53a709d932",
        "is_secret": false,
        "is_verified": false,
        "line_number": 107,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "d0ba47ccbefb78340565269f5b73af6f1afa4396",
        "is_secret": false,
        "is_verified": false,
        "line_number": 169,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "37478776645d473cd2ae4155f597d0fef53dcb58",
        "is_secret": false,
        "is_verified": false,
        "line_number": 394,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/frontend_workspaces/frontend/src/ManagePage.tsx": [
      {
        "hashed_secret": "1f5e25be9b575e9f5d39c82dfd1d9f4d73f1975c",
        "is_secret": false,
        "is_verified": false,
        "line_number": 141,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "d0a3e7f81a9885e99049d1cae0336d269d5e47a9",
        "is_secret": false,
        "is_verified": false,
        "line_number": 183,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "48bf2239eea43073d82dc9a4ad45200b8e297363",
        "is_secret": false,
        "is_verified": false,
        "line_number": 294,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "6947818ac409551f11fbaa78f0ea6391960aa5b8",
        "is_secret": false,
        "is_verified": false,
        "line_number": 295,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/frontend_workspaces/frontend/src/api.ts": [
      {
        "hashed_secret": "d3ecb0d890368d7659ee54010045b835dacb8efe",
        "is_secret": false,
        "is_verified": false,
        "line_number": 49,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "f5cbae85fb47446511da4c9974e2da448caee7e1",
        "is_secret": false,
        "is_verified": false,
        "line_number": 161,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "src/frontend_workspaces/frontend/src/auth.ts": [
      {
        "hashed_secret": "d3ecb0d890368d7659ee54010045b835dacb8efe",
        "is_secret": false,
        "is_verified": false,
        "line_number": 36,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "tests/integration/test_llm_config_publish.py": [
      {
        "hashed_secret": "18ddbc9bbacbf4a9baa379b0a09880dfffede940",
        "is_secret": false,
        "is_verified": false,
        "line_number": 245,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ],
    "tests/unit/test_knowledge_engine.py": [
      {
        "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684",
        "is_secret": false,
        "is_verified": false,
        "line_number": 220,
        "type": "Basic Auth Credentials",
        "verified_result": null
      }
    ],
    "tests/unit/test_llm_override.py": [
      {
        "hashed_secret": "d02a1215a382dd014f4e48cb99f6896462b12d30",
        "is_secret": false,
        "is_verified": false,
        "line_number": 104,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "68ae90e9a866a86ce4d62f491670b83b80973d3f",
        "is_secret": false,
        "is_verified": false,
        "line_number": 123,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "fc59ee2d2451a12914d0ef4029dbcb5261cf483e",
        "is_secret": false,
        "is_verified": false,
        "line_number": 128,
        "type": "Secret Keyword",
        "verified_result": null
      },
      {
        "hashed_secret": "18ddbc9bbacbf4a9baa379b0a09880dfffede940",
        "is_secret": false,
        "is_verified": false,
        "line_number": 190,
        "type": "Secret Keyword",
        "verified_result": null
      }
    ]
  },
  "version": "0.13.1+ibm.64.dss",
  "word_list": {
    "file": null,
    "hash": null
  }
}


================================================
FILE: .vscode/launch.json
================================================
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "API Registry Appworld",
      "type": "python",
      "request": "launch",
      "module": "uvicorn",
      "args": ["cuga.backend.tools_env.registry.registry.api_registry_server:app", "--port", "8001"],
      "cwd": "${workspaceFolder}/src",
      "env": {
        "PYTHONUNBUFFERED": "1",
        "MCP_SERVERS_FILE": "mcp_servers_appworld.yaml"
      },
      "console": "integratedTerminal",
      "python": "${workspaceFolder}/.venv/bin/python"
    },
    {
      "name": "API Registry Demo",
      "type": "python",
      "request": "launch",
      "module": "uvicorn",
      "args": ["cuga.backend.tools_env.registry.registry.api_registry_server:app", "--port", "8001"],
      "cwd": "${workspaceFolder}",
      "env": {
        "PYTHONUNBUFFERED": "1",
        "MCP_SERVERS_FILE": "${workspaceFolder}/src/cuga/backend/tools_env/registry/config/mcp_servers.yaml"
      },
      "console": "integratedTerminal",
      "python": "${workspaceFolder}/.venv/bin/python",
      "envFile": "${workspaceFolder}/.env",
      "stopOnEntry": false,
      "justMyCode": false,
      "redirectOutput": true,
      "showReturnValue": true,
      "subProcess": true
    },
    {
      "name": "CUGA Demo Server - Windows",
      "type": "debugpy",
      "request": "launch",
      "program": "${workspaceFolder}/src/cuga/backend/server/debug_server.py",
      "env": {
        "PYTHONPATH": "${workspaceFolder}",
        "PYTHONUNBUFFERED": "1",
        "LOGURU_LEVEL": "DEBUG"
      },
      "args": [],
      "console": "integratedTerminal",
      "envFile": "${workspaceFolder}/.env",
      "cwd": "${workspaceFolder}",
      "stopOnEntry": false,
      "justMyCode": false,
      "redirectOutput": true,
      "showReturnValue": true,
      "subProcess": true,
      "preLaunchTask": null,
      "postDebugTask": null
    },
    {
      "name": "App World Eval",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/evaluation/appworld_eval.py",
      "args": [],
      "cwd": "${workspaceFolder}",
      "env": {
        "PYTHONUNBUFFERED": "1"
      },
      "console": "integratedTerminal",
      "python": "${workspaceFolder}/.venv/bin/python"
    },
    {
      "name": "Cuga Demo",
      "type": "debugpy",
      "request": "launch",
      "module": "fastapi",
      "envFile": "${workspaceFolder}/.env",
      "args": ["dev", "src/cuga/backend/server/main.py", "--no-reload", "--port=7860"],
      "cwd": "${workspaceFolder}",
      "env": {
        "PYTHONUNBUFFERED": "1"
      },
      "console": "integratedTerminal",
      "python": "${workspaceFolder}/.venv/bin/python",
      "stopOnEntry": false,
      "justMyCode": false,
      "redirectOutput": true,
      "showReturnValue": true,
      "subProcess": true
    }
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
    "python.envFile": "${workspaceFolder}/.env",
    "debugpy.debugJustMyCode": true,
    "[python]": {
        "editor.defaultFormatter": "ms-python.black-formatter",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit",
        },
    },
    "isort.args": [
        "--profile",
        "black"
    ],
    "ruff.enable": false
}

================================================
FILE: .whitesource
================================================
{
  "settingsInheritedFrom": "whitesource-config/whitesource-config@master"
}

================================================
FILE: CONTRIBUTING.md
================================================
# Development Contributing Guide

## How to Contribute

1. Fork the repository to your own GitHub account. (not needed if you are CUGA team)
2. Create a feature branch from `main` in your fork: `git checkout -b feature/<short-topic>` (see Branch Naming Convention below).
3. Keep PRs small and focused (prefer < ~300 changed lines and limited file count).
4. Follow Conventional Commits for all commits and PR titles.
5. Run formatting, linting, and tests locally before opening a PR.
6. Open a Pull Request from your fork to `main` with a clear description and checklist results.

Notes:
- All PRs are merged using "Squash and merge". The PR title will become the final commit message — write it carefully using the Conventional Commits format.
- Prefer one topic per PR. If your changes touch many areas, split into multiple PRs.

## DCO

This repository requires a Developer's Certificate of Origin 1.1 signoff on every commit. A DCO provides your assurance to the community that you wrote the code you are contributing or have the right to pass on the code that you are contributing. It is generally used in place of a Contributor License Agreement (CLA). You can easily signoff a commit by using the -s or --signoff flag:

```bash
git commit -s -m 'This is my commit message'
```

If you are using the web interface, this should happen automatically. If you've already made a commit, you can fix it by amending the commit and force-pushing the change:

```bash
git commit --amend --no-edit --signoff
git push -f
```

This will only amend your most recent commit and will not affect the message. If there are multiple commits that need fixing, you can try:

```bash
git rebase --signoff HEAD~<n>
git push -f
```

where `<n>` is the number of commits missing signoffs.

## Commit Messages: Conventional Commits

We use the Conventional Commits specification. See the full spec at [conventionalcommits.org](https://www.conventionalcommits.org/en/v1.0.0/).

Structure:

```
<type>[optional scope]: <short description>

[optional body]

[optional footer(s)]
```

Common types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `build`, `ci`, `perf`, `style`.

Good examples:

```
feat(api): add list-accounts endpoint to registry
fix(browser): prevent crash when page has no active frame
```

Breaking change example:

```
feat(api)!: switch account id field to string

BREAKING CHANGE: API consumers must treat account ids as strings.
```

Bad examples (do not use):

```
update stuff
wip: changes
fixes
typo
```

Why this matters:
- Enables clean history and automated tooling (changelogs, versioning).
- Because we squash-merge, the PR title becomes the final commit — use Conventional Commits in the PR title too.

## Branch Naming Convention

We follow the Conventional Branch specification. See the full spec at [conventional-branch.github.io](https://conventional-branch.github.io/).

### Branch Naming Structure

```
<type>/<description>
```

### Supported Branch Types

| Type         | Good Example                | Why It's Good                   | Bad Example                  | Why It's Bad                      |
| ------------ | --------------------------- | ------------------------------- | ---------------------------- | --------------------------------- |
| Feature      | `feature/add-login-page`    | Lowercase, hyphens, descriptive | `Feature/AddLoginPage`       | Uppercase & no hyphens            |
| Fix          | `bugfix/header-bug`         | Clear, lowercase                | `feat/add_login`             | Uses underscore instead of hyphen |
| Hotfix       | `hotfix/security-patch`     | Clear, proper prefix            | `hotfix#security-patch`      | Contains invalid character `#`    |
| Release      | `release/v1.2.0`            | Correct dot usage for versions  | `release/v1..2.0`            | Consecutive dots                  |
| Chore        | `chore/update-dependencies` | Descriptive and valid           | `chore/update-dependencies-` | Trailing hyphen                   |
| Missing Desc | `feat/issue-123-new-login`  | Includes ticket, traceable      | `feature/`                   | Missing description               |

### Branch Naming Rules

1. **Use lowercase alphanumerics, hyphens, and dots**: Always use lowercase letters (`a-z`), numbers (`0-9`), and hyphens(`-`) to separate words. Avoid special characters, underscores, or spaces. For release branches, dots (`.`) may be used in the description to represent version numbers (e.g., `release/v1.2.0`).
2. **No consecutive, leading, or trailing hyphens or dots**: Ensure that hyphens and dots do not appear consecutively, nor at the start or end of the description.
3. **Keep it clear and concise**: The branch name should be descriptive yet concise, clearly indicating the purpose of the work.
4. **Include ticket numbers**: If applicable, include the ticket number from your project management tool to make tracking easier.

Why this matters:
- **Clear Communication**: The branch name alone provides a clear understanding of its purpose.
- **Automation-Friendly**: Easily hooks into automation processes (e.g., different workflows for `feature`, `release`, etc.).
- **Team Collaboration**: Encourages collaboration by making branch purpose explicit.

## Pull Request Guidelines

- Keep diffs small; avoid drive-by refactors. Separate formatting-only PRs from feature/fix PRs.
- Include a brief summary of what/why, and link related issues (e.g., `Refs: #123`).
- Add/update tests when changing behavior.
- Do not include generated files, large assets, secrets, or local config (e.g., `.env`).
- Ensure CI passes. If you see flaky tests, note it in the PR description.

### Pull Request Templates

We provide specific PR templates to help you create well-structured pull requests. When creating a PR, you can use one of these templates by adding the appropriate query parameter to the GitHub URL:

- **Feature PRs**: `?template=feature.md` - For new features and enhancements
- **Bug Fix PRs**: `?template=bugfix.md` - For bug fixes and issue resolutions
- **Documentation PRs**: `?template=docs.md` - For documentation updates and improvements
- **Chore PRs**: `?template=chore.md` - For maintenance tasks, dependency updates, and refactoring

Each template includes:
- Related issue linking
- Type of changes checkboxes
- Testing checklist
- Standard review checklist

GitHub will also automatically suggest these templates when you create a new pull request.

### Pre-PR Checklist (run locally)

Use `uv` for environment and tooling.

```
uv sync --dev
uv run ruff format
uv run ruff check --fix
# Run tests as described below
```

Must:
- If your change touches the browser/env, verify relevant demos still run.
- Update README.md or docs if only needed, discuss before

## Dependency lockfile (`uv.lock`)

Only the **repository root** `uv.lock` is committed. After changing dependencies in the root `pyproject.toml`, run `uv lock` from the repo root.

Examples under `docs/examples/cuga_as_mcp` and `docs/examples/cuga_with_runtime_tools` do **not** carry their own lockfiles: they resolve `cuga` from a path dependency and reuse the root lockfile’s resolution (including root-only `[tool.uv.dependency-metadata]`). Run commands from the example directory with `uv run --project ../../../ …` so `uv` uses the root project; see each example README.

## Security Scanning

Before committing, run security scanning to detect potential secrets:

```bash
uv pip install --upgrade "git+https://github.com/ibm/detect-secrets.git@master#egg=detect-secrets"
detect-secrets scan --update .secrets.baseline
detect-secrets audit .secrets.baseline
```

If everything passes, no need to mark secrets or false positives. This ensures no sensitive information is accidentally committed to the repository.

## Running Tests

### 1) Install dev dependencies

```bash
uv sync --dev
```


### Run tests

Comprehensive test suite including linting, unit tests, and e2e tests:

```bash
chmod +x ./src/scripts/run_tests.sh
./src/scripts/run_tests.sh
```

This will run:
- **Linting checks**: Ruff code quality and formatting validation
- **Unit tests**: Variables manager, API response handling, registry functionality
- **E2E tests**: System tests across Fast and Balanced modes for real-world scenarios


## AI Agent Commands

If you are working in an AI-assisted IDE or using an AI agent (Cursor, Claude, Bob), a set of pre-built workflow commands is available to streamline common contributor tasks. The same commands are mirrored across all three tooling directories:

| Location | For |
|---|---|
| `.cursor/commands/cuga-*.md` | Cursor agent |
| `.claude/commands/cuga-*.md` | Claude / claude-code |
| `.bob/commands/cuga-*.md` | Bob agent |

### Available Commands

| Command | What it does |
|---|---|
| `cuga-commit` | Stages and commits changes using Conventional Commits with scoped messages and bullet-point descriptions |
| `cuga-create-pr` | Validates local state, picks the right PR template, fills it out from current changes, and opens the PR via `gh` |
| `cuga-report-bug` | Creates a GitHub issue using the `bug_report.yml` template with context from the current code |
| `cuga-new-feature` | Creates a GitHub issue using the `feature_request.yml` template |
| `cuga-ruff-check` | Runs `uv run ruff check --fix` and `uv run ruff format` on the project |

These commands follow all repo conventions (Conventional Commits, `gh` CLI, no promotional footers). To invoke them, use the slash-command syntax of your tool (e.g. `/cuga-commit` in Cursor).

## IDE Setup Quick Links

First make sure that your IDE environment is properly configured
[See Python Code Formatting Guide](#python-code-formatting-guide)

# Python Code Formatting Guide
Before every commit make sure to run:
```commandline
ruff format
ruff check --fix
```

### Ruff formatter and linter installation on IDE

#### VS Code
[https://github.com/astral-sh/ruff-vscode](https://marketplace.visualstudio.com/items?itemName=charliermarsh.ruff)

#### Pycharm
https://docs.astral.sh/ruff/editors/setup/#pycharm

# IDE Debug Mode Setup

## VSCode and PyCharm Debug Mode

**Important**: Select the correct Python interpreter for debugging:

- **VS Code**: Press `Ctrl+Shift+P` → "Python: Select Interpreter" → Choose the `.venv` from your previous setup
- **PyCharm**: Go to Settings → Project → Python Interpreter → Select the uv virtual environment

## Available Configurations

### Demo Mode

For local development and testing:

1. **API Registry Demo** - Runs the API registry server for demo environment

   - Port: 8001
   - Uses: `mcp_servers.yaml`

2. **Cuga Demo** - Runs the main FastAPI server for demo
   - Port: 7860

**To run demo mode:**

1. Start "API Registry Demo" first
2. Then start "Cuga Demo"


## VSCode Instructions

1. Open VS Code's Run and Debug panel
2. Select the desired configuration from the dropdown
3. Start debugging

================================================
FILE: Dockerfile
================================================
FROM python:3.12-slim-trixie

# The installer requires curl (and certificates) to download the release archive
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Download the latest installer
ADD https://astral.sh/uv/install.sh /uv-installer.sh

# Run the installer then remove it
RUN sh /uv-installer.sh && rm /uv-installer.sh

# Ensure the installed binary is on the `PATH`
ENV PATH="/root/.local/bin/:$PATH"

# Set working directory
WORKDIR /app

# Copy dependency files
COPY pyproject.toml uv.lock ./

# Copy source code
COPY src/ ./src/
COPY docs/ ./docs/

# Install dependencies
RUN uv sync

# Create cuga_workspace directory
RUN mkdir -p /app/cuga_workspace

# Copy example files from bundled demo_tools samples
COPY src/cuga/demo_tools/huggingface/contacts.txt /app/cuga_workspace/contacts.txt
COPY src/cuga/demo_tools/huggingface/cuga_knowledge.md /app/cuga_workspace/cuga_knowledge.md
COPY src/cuga/demo_tools/huggingface/cuga_playbook.md /app/cuga_workspace/cuga_playbook.md
COPY src/cuga/demo_tools/huggingface/email_template.md /app/cuga_workspace/email_template.md

# Expose port 7860 (Hugging Face Spaces default)
EXPOSE 7860

# Set host to 0.0.0.0 to allow external connections
ENV CUGA_HOST=0.0.0.0

# Override the demo port to match HF Spaces
ENV DYNACONF_SERVER_PORTS__DEMO=7860

# Start the demo_crm service with read-only filesystem and no email services
CMD ["uv", "run", "cuga", "start", "demo_crm", "--cuga-workspace", "/app/cuga_workspace"]



================================================
FILE: Dockerfile.ubi
================================================
# Multi-stage: builder installs deps, runtime keeps only what's needed
ARG BASE_IMAGE=registry.access.redhat.com/ubi9/python-312-minimal:latest
FROM ${BASE_IMAGE} AS builder

# Use official uv image to avoid curl+tar dance
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
COPY --from=ghcr.io/astral-sh/uv:latest /uvx /usr/local/bin/uvx

ENV PATH="/usr/local/bin:$PATH"

USER root
WORKDIR /app

COPY pyproject.toml uv.lock README.md ./
COPY src/ ./src/
COPY docs/ ./docs/

# Default deps omit openlit (optional `observability` extra; keeps pip/uvx core resolvable with litellm 1.83.x).
RUN find src -name "*.egg-info" -o -name "build" -exec rm -rf {} + && uv sync --no-editable --no-dev --extra observability

# Slim down torch: remove test suite and C++ headers (not needed at runtime) ~143MB
# NOTE: torch/bin must be kept — contains torch_shm_manager required at import time
RUN rm -rf /app/.venv/lib/python3.12/site-packages/torch/test \
           /app/.venv/lib/python3.12/site-packages/torch/include

# Strip debug symbols from native .so files (saves 100-300MB, pure size optimization)
RUN find /app/.venv -type f \( -name "*.so" -o -name "*.so.*" \) -exec strip --strip-unneeded {} \; 2>/dev/null || true

# Download only the headless_shell binary (no full Chromium, no ffmpeg) — ~3x smaller than default.
RUN PLAYWRIGHT_BROWSERS_PATH=/app/.playwright uv run playwright install --only-shell chromium

# Bake ML model weights into the image for airgapped operation.
# Pinned to /app/.cache so paths survive the multi-stage copy and match runtime ENV below.
ENV FASTEMBED_CACHE_PATH=/app/.cache/fastembed \
    DOCLING_ARTIFACTS_PATH=/app/.cache/docling \
    HF_HOME=/app/.cache/huggingface
RUN uv run --no-sync python src/scripts/preload_models.py

# Remove Python bytecode cache — regenerated on first run, adds nothing at build time
RUN find /app/.venv -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true

# Runtime stage - slimmer base, copy only built artifacts
FROM ${BASE_IMAGE}

USER root
# Libs required by Chromium headless_shell on UBI9/RHEL9
# gtk3 and cups-libs intentionally omitted — not needed by headless_shell (--only-shell skips full browser stack)
RUN microdnf install -y \
        alsa-lib \
        at-spi2-atk \
        at-spi2-core \
        atk \
        cairo \
        dbus-libs \
        expat \
        glib2 \
        libdrm \
        libgbm \
        libX11 \
        libXcomposite \
        libXdamage \
        libXext \
        libXfixes \
        libXrandr \
        libxcb \
        libxkbcommon \
        mesa-libgbm \
        mesa-libGL \
        nspr \
        nss \
        nss-util \
        pango \
        --setopt=install_weak_deps=0 && \
    microdnf clean all

# Use official uv image — no tar/gzip/curl needed
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
COPY --from=ghcr.io/astral-sh/uv:latest /uvx /usr/local/bin/uvx

ENV PATH="/usr/local/bin:$PATH"

WORKDIR /app

COPY pyproject.toml uv.lock README.md ./

# 1001:0 matches USER 1001; g+rwX lets OpenShift's arbitrary UID run with GID 0 (typical restricted SCC).
RUN mkdir -p /app/cuga_workspace /app/crm_tmp /app/.cuga/knowledge /data/dbs && \
    chown -R 1001:0 /data /app/.cuga && \
    chmod -R g+rwX /app/.cuga

COPY --from=builder --chown=1001:0 --chmod=0775 /app/.venv /app/.venv
COPY --from=builder --chown=1001:0 --chmod=0775 /app/.playwright /app/.playwright
COPY --from=builder --chown=1001:0 --chmod=0775 /app/.cache /app/.cache
COPY --from=builder --chown=1001:0 --chmod=0775 /app/src /app/src
COPY --from=builder --chown=1001:0 --chmod=0775 /app/docs /app/docs
COPY --chown=1001:0 --chmod=0775 \
  src/cuga/demo_tools/huggingface/contacts.txt \
  src/cuga/demo_tools/huggingface/cuga_knowledge.md \
  src/cuga/demo_tools/huggingface/cuga_playbook.md \
  src/cuga/demo_tools/huggingface/email_template.md \
  src/cuga/demo_tools/huggingface/sovereign_core_overview.pdf \
  /app/cuga_workspace/
COPY --chown=1001:0 --chmod=0775 scripts/docker-entrypoint.sh /app/scripts/docker-entrypoint.sh

USER 1001

EXPOSE 7860

ENV USER=cuga
ENV LOGNAME=cuga
ENV CUGA_HOST=0.0.0.0
ENV DYNACONF_SERVER_PORTS__DEMO=7860
ENV CUGA_DEMO_MODE=default
ENV HOME=/tmp
ENV UV_CACHE_DIR=/tmp/uv-cache
ENV UV_TOOL_DIR=/tmp/uv-tools
ENV CUGA_LOGGING_DIR=/tmp/cuga-logging
ENV CUGA_DBS_DIR=/data/dbs
ENV DYNACONF_CRM_DB_PATH=/tmp/crm_tmp/crm_db_default
ENV PLAYWRIGHT_BROWSERS_PATH=/app/.playwright
ENV FASTEMBED_CACHE_PATH=/app/.cache/fastembed \
    DOCLING_ARTIFACTS_PATH=/app/.cache/docling \
    HF_HOME=/app/.cache/huggingface \
    HF_HUB_OFFLINE=1

ENTRYPOINT ["/bin/sh", "/app/scripts/docker-entrypoint.sh"]
CMD []


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of control, an entity
      is "controlled by" another entity if it has the power, directly or
      indirectly, to cause the direction or management of such entity,
      whether by contract or otherwise, or ownership of fifty percent (50%)
      or more of the outstanding shares, or beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (which shall not include combinations of Works unless specifically
      authorized by the License).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based upon (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of the License, a Derivative Work shall include any work that is based
      upon a copy of the existing Work.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control
      systems, and issue tracking systems that are managed by, or on behalf
      of, the Licensor for the purpose of discussing and improving the Work,
      but excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to use, reproduce, modify, create derivative works,
      distribute, sublicense, and/or sell copies of the Work, and to
      permit persons to whom the Work is furnished to do so, subject to
      the following conditions:

      The above copyright notice and this permission notice shall be
      included in all copies or substantial portions of the Work.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright notices to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Support. You may choose to offer, and to
      charge a fee for, warranty, support, indemnity or other liability
      obligations and/or rights consistent with this License. However, in
      accepting such obligations, You may act only on Your own behalf and on
      Your sole responsibility, not on behalf of any other Contributor, and
      only if You agree to indemnify, defend, and hold each Contributor
      harmless for any liability incurred by, or claims asserted against,
      such Contributor by reason of your accepting any such warranty or support.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same page as the copyright notice for easier identification within
      third-party archives.

   Copyright 2025 CUGA

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

---

# NOTICE

This project includes code from multiple open source projects:

## BrowserGym
Copyright 2024 ServiceNow
Licensed under Apache License 2.0
Source: https://github.com/ServiceNow/BrowserGym

Portions of this project are derived from BrowserGym, including:
- cuga/backend/browser_env/browser/chat_async.py
- cuga/backend/browser_env/page_understanding/tranformer_utils/transform_utils.py
- cuga/backend/browser_env/page_understanding/tranformer_utils/dom_transform_utils.py
- cuga/backend/browser_env/browser/gym_env_async.py
- cuga/backend/browser_env/browser/gym_obs/obs.py
- cuga/backend/browser_env/browser/gym_obs/obs_async.py
- cuga/backend/browser_env/browser/gym_obs/extract_chrome_extension.py
- cuga/backend/browser_env/browser/env.py
- cuga/backend/browser_env/browser/extension_env_async.py
- cuga/backend/browser_env/browser/open_ended_async.py
- cuga/backend/browser_env/browser/gym_env.py
- cuga/backend/browser_env/browser/gym_obs/javascript/frame_unmark_elements.js
- cuga/backend/browser_env/browser/gym_obs/javascript/frame_mark_elements.js
- cuga/backend/browser_env/browser/utils_async.py

## browser-use  
Copyright (c) 2024 Gregor Zunic
Licensed under MIT License
Source: https://github.com/browser-use/browser-use

Portions of this project are derived from browser-use, including:
- frontend-workspaces/extension/src/content/page_analysis/CachedXPathBuilder.ts
- frontend-workspaces/extension/src/content/page_analysis/constants.ts
- frontend-workspaces/extension/src/content/page_analysis/dom_tree_module.ts
- frontend-workspaces/extension/src/content/page_analysis/DomCache.ts
- frontend-workspaces/extension/src/content/page_analysis/DomTree.ts
- frontend-workspaces/extension/src/content/page_analysis/ElementHighlighter.ts
- frontend-workspaces/extension/src/content/page_analysis/NodeElementCollector.ts
- frontend-workspaces/extension/src/content/page_analysis/NodeHelper.ts
- frontend-workspaces/extension/src/content/page_analysis/PageHighlighter.ts
- frontend-workspaces/extension/src/content/page_analysis/types.d.ts


## LangChain
Copyright (c) 2025 LangChain
Licensed under MIT License
Source: https://github.com/langchain-ai/langgraph


Portions of this project derived from LangChain include:
- cuga/backend/cuga_graph/nodes/api/code_agent/code_act_agent.py

## Original Work
Copyright 2025 CUGA
Licensed under Apache License 2.0

All original code and modifications are licensed under Apache License 2.0.


================================================
FILE: README.md
================================================
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="/docs/images/cuga-dark.png">
  <source media="(prefers-color-scheme: light)" srcset="/docs/images/cuga-light.png">
  <img alt="CUGA" src="/docs/images/cuga-dark.png">
</picture>

<div align="center">

# CUGA: Configurable Generalist Agent — Agent Harness for the Enterprise

### Start with a generalist. Customize for your domain. Deploy faster!

Building a domain-specific enterprise agent from scratch is complex and requires significant effort: agent and tool orchestration, planning logic, safety and alignment policies, evaluation for performance/cost tradeoffs and ongoing improvements. CUGA is a state-of-the-art generalist agent designed with enterprise needs in mind, so you can focus on configuring your domain tools, policies and workflow.

---

[![🦉🤗 Try CUGA Live on Hugging Face Spaces](https://img.shields.io/badge/🦉🤗_Try_CUGA_Live_on_Hugging_Face_Spaces-FFD21E?style=for-the-badge)](https://huggingface.co/spaces/ibm-research/cuga-agent)

[![Python](https://shields.io/badge/Python-3.12-blue?logo=python&style=for-the-badge)](https://www.python.org/)
[![CugaAgent SDK](https://shields.io/badge/CugaAgent_SDK-Documentation-blue?logo=python&style=for-the-badge)](https://docs.cuga.dev/docs/sdk/cuga_agent/)
[![Status](https://shields.io/badge/Status-Active-success?logo=checkmarx&style=for-the-badge)]()
[![Documentation](https://shields.io/badge/Documentation-Available-blue?logo=gitbook&style=for-the-badge)](https://docs.cuga.dev)
[![Discord](https://shields.io/badge/Discord-Join-blue?logo=discord&style=for-the-badge)](https://discord.gg/aH6rAEEW)

[![AppWorld](https://img.shields.io/badge/%F0%9F%A5%87%20%231%20on-AppWorld-gold?style=for-the-badge)](https://appworld.dev/leaderboard)
[![WebArena](https://img.shields.io/badge/Top--tier%20on-WebArena-silver?style=for-the-badge)](https://docs.google.com/spreadsheets/d/1M801lEpBbKSNwP-vDBkC_pF7LdyGU1f_ufZb_NWNBZQ/edit?gid=0#gid=0)

</div>

---

> **🎉 NEW: CUGA Enterprise SDK with Policy System** — Build production-ready AI agents with enterprise-grade governance. Programmatically configure safety guards, workflow controls, and compliance policies via Python SDK or visual UI. Ensure consistent, secure, and compliant agent behavior across your organization.
>
> **Policy Types & Enterprise Value:**
>
> | Policy Type | Value | Use Cases |
> |------------|-------|-----------|
> | **Intent Guard** | Block unauthorized actions | Data deletion prevention, access restrictions, compliance enforcement |
> | **Playbook** | Standardize workflows | Onboarding, audit workflows, regulatory compliance |
> | **Tool Approval** | Human oversight | Financial transactions, data modifications |
> | **Tool Guide** | Domain knowledge | Compliance notes, domain context |
> | **Output Formatter** | Format, redirect, govern outputs | report generation, response routing, output masking |
>
> 📚 **Documentation**: [SDK Guide](https://docs.cuga.dev/docs/sdk/cuga_agent/) | [Policies Guide](https://docs.cuga.dev/docs/sdk/policies/) | [Quick Start →](#-using-cuga-as-a-python-sdk)

## Why CUGA?

### 🏆 Benchmark Performance

CUGA achieves state-of-the-art performance on leading benchmarks:

- 🥇 **#1 on [AppWorld](https://appworld.dev/leaderboard)** — a benchmark with 750 real-world tasks across 457 APIs
- 🥈 **Top-tier on [WebArena](https://docs.google.com/spreadsheets/d/1M801lEpBbKSNwP-vDBkC_pF7LdyGU1f_ufZb_NWNBZQ/edit?gid=0#gid=0)** (#1 from 02/25 - 09/25) — a complex benchmark for autonomous web agents across application domains

### ✨ Key Features & Capabilities

- **High-performing generalist agent** — Benchmarked on complex web and API tasks. Combines best-of-breed agentic patterns (e.g. planner-executor, code-act) with structured planning and smart variable management to prevent hallucination and handle complexity

- **Configurable reasoning modes** — Balance performance and cost/latency with flexible modes ranging from fast heuristics to deep planning, optimizing for your specific task requirements

- **Flexible agent and tool integration** — Seamlessly integrate tools via OpenAPI specs, MCP servers, and Langchain, enabling rapid connection to REST APIs, custom protocols, and Python functions

- **Integrates with Langflow** — Low-code visual build experience for designing and deploying agent workflows without extensive coding

- **Open-source and composable** — Built with modularity in mind, CUGA itself can be exposed as a tool to other agents, enabling nested reasoning and multi-agent collaboration. Evolving toward enterprise-grade reliability

- **Policy System** — Configure agent behavior with 5 policy types (Intent Guard, Playbook, Tool Approval, Tool Guide, Output Formatter) via the Python SDK or standalone UI in demo mode. Includes human-in-the-loop approval gates for safe agent behavior in enterprise contexts. See [SDK Docs](https://docs.cuga.dev/docs/sdk/cuga_agent/) and [Policies Guide](https://docs.cuga.dev/docs/sdk/policies/)

- **Save-and-reuse capabilities** _(Experimental)_ — Capture and reuse successful execution paths (plans, code, and trajectories) for faster and consistent behavior across repeated tasks

Explore the [Roadmap](#roadmap) to see what's ahead, or join the [🤝 Call for the Community](#call-for-the-community) to get involved.


## 🎬 CUGA in Action

### Hybrid Task Execution

Watch CUGA seamlessly combine web and API operations in a single workflow:

**Example Task:** `get top account by revenue from digital sales, then add it to current page`

https://github.com/user-attachments/assets/0cef8264-8d50-46d9-871a-ab3cefe1dde5

<details>
<summary><b>Would you like to test this? (Advanced Demo)</b></summary>

Experience CUGA's hybrid capabilities by combining API calls with web interactions:

### Setup Steps:

1. **Switch to hybrid mode:**

   ```bash
   # Edit ./src/cuga/settings.toml and change:
   mode = 'hybrid'  # under [advanced_features] section
   ```

2. **Install browser API support:**

   - Installs playwright browser API and Chromium browser
   - The `playwright` installer should already be included after installing with [Quick Start](#-quick-start)

   ```bash
   playwright install chromium
   ```

3. **Start the demo:**

   ```bash
   cuga start demo
   ```

4. **Enable the browser extension:**

   - Click the extension puzzle icon in your browser
   - Toggle the CUGA extension to activate it
   - This will open the CUGA side panel

5. **Open the test application:**

   - Navigate to: [Sales app](https://samimarreed.github.io/sales/)

6. **Try the hybrid task:**
   ```
   get top account by revenue from digital sales then add it to current page
   ```

🎯 **What you'll see:** CUGA will fetch data from the Digital Sales API and then interact with the web page to add the account information directly to the current page - demonstrating seamless API-to-web workflow integration!

</details>

### Human in the Loop Task Execution

Watch CUGA pause for human approval during critical decision points:

**Example Task:** `get best accounts`

https://github.com/user-attachments/assets/d103c299-3280-495a-ba66-373e72554e78

<details>
<summary><b>Would you like to try this? (HITL Demo)</b></summary>

Experience CUGA's Human-in-the-Loop capabilities where the agent pauses for human approval at key decision points:

### Setup Steps:

1. **Enable HITL mode:**

   ```bash
   # Edit ./src/cuga/settings.toml and ensure:
   api_planner_hitl = true  # under [advanced_features] section
   ```

2. **Start the demo:**

   ```bash
   cuga start demo
   ```

3. **Try the HITL task:**
   ```
   get best accounts
   ```

🎯 **What you'll see:** CUGA will pause at critical decision points, showing you the planned actions and waiting for your approval before proceeding.

</details>

## 🚀 Quick Start

<details>
<summary><em style="color: #666;">📋 Prerequisites (click to expand)</em></summary>

- **Python 3.12+** - [Download here](https://www.python.org/downloads/)
- **uv package manager** - [Installation guide](https://docs.astral.sh/uv/getting-started/installation/)

</details>

```bash
# In terminal, clone the repository and navigate into it
git clone https://github.com/cuga-project/cuga-agent.git
cd cuga-agent

# 1. Create and activate virtual environment
uv venv --python=3.12 && source .venv/bin/activate

# 2. Install dependencies
uv sync

# 3. Set up environment variables
# Create .env file with your API keys
echo "OPENAI_API_KEY=your-openai-api-key-here" > .env

# 4. Start the demo
cuga start demo_crm --read-only

# Chrome will open automatically at https://localhost:7860
# then try sending your task to CUGA: 'from contacts.txt show me which users belong to the crm system'

# 5. View agent trajectories (optional)
cuga viz

# This launches a web-based dashboard for visualizing and analyzing
# agent execution trajectories, decision-making, and tool usage

```


<details>
<summary>🤖 LLM Configuration - Advanced Options</summary>

---

Refer to: [`.env.example`](.env.example) for detailed examples.

CUGA supports multiple LLM providers with flexible configuration options. You can configure models through TOML files or override specific settings using environment variables.

## Supported Platforms

- **OpenAI** - GPT models via OpenAI API (also supports LiteLLM via base URL override)
- **IBM WatsonX** - IBM's enterprise LLM platform
- **Azure OpenAI** - Microsoft's Azure OpenAI service
- **Groq** - High-performance inference platform with fast LLM models
- **RITS** - Internal IBM research platform
- **OpenRouter** - LLM API gateway provider

## Configuration Priority

1. **Environment Variables** (highest priority)
2. **TOML Configuration** (medium priority)
3. **Default Values** (lowest priority)

### Option 1: OpenAI 🌐

**Setup Instructions:**

1. Create an account at [platform.openai.com](https://platform.openai.com)
2. Generate an API key from your [API keys page](https://platform.openai.com/api-keys)
3. Add to your `.env` file:
   ```env
   # OpenAI Configuration
   OPENAI_API_KEY=sk-...your-key-here...
   AGENT_SETTING_CONFIG="settings.openai.toml"

   # Optional overrides
   MODEL_NAME=gpt-4o                    # Override model name
   OPENAI_BASE_URL=https://api.openai.com/v1  # Override base URL
   OPENAI_API_VERSION=2024-08-06        # Override API version
   ```

**Default Values:**

- Model: `gpt-4o`
- API Version: OpenAI's default API Version
- Base URL: OpenAI's default endpoint

### Option 2: IBM WatsonX 🔵

**Setup Instructions:**

1. Access [IBM WatsonX](https://www.ibm.com/watsonx)
2. Create a project and get your credentials:
   - Project ID
   - API Key
   - Region/URL
3. Add to your `.env` file:

   ```env
   # WatsonX Configuration
   WATSONX_API_KEY=your-watsonx-api-key
   WATSONX_PROJECT_ID=your-project-id
   WATSONX_URL=https://us-south.ml.cloud.ibm.com  # or your region
   AGENT_SETTING_CONFIG="settings.watsonx.toml"

   # Optional override
   MODEL_NAME=meta-llama/llama-4-maverick-17b-128e-instruct-fp8  # Override model for all agents
   ```

**Default Values:**

- Model: `meta-llama/llama-4-maverick-17b-128e-instruct-fp8`

### Option 3: Azure OpenAI

**Setup Instructions:**

1. Add to your `.env` file:
   ```env
    AGENT_SETTING_CONFIG="settings.azure.toml"  # Default config uses ETE
    AZURE_OPENAI_API_KEY="<your azure apikey>"
    AZURE_OPENAI_ENDPOINT="<your azure endpoint>"
    OPENAI_API_VERSION="2024-08-01-preview"
   ```

### Option 4: LiteLLM Support

CUGA supports LiteLLM through the OpenAI configuration by overriding the base URL:

1. Add to your `.env` file:

   ```env
   # LiteLLM Configuration (using OpenAI settings)
   OPENAI_API_KEY=your-api-key
   AGENT_SETTING_CONFIG="settings.openai.toml"

   # Override for LiteLLM
   MODEL_NAME=Azure/gpt-4o              # Override model name
   OPENAI_BASE_URL=https://your-litellm-endpoint.com  # Override base URL
   OPENAI_API_VERSION=2024-08-06        # Override API version
   ```
### Option 5: Groq Support ⚡

**Setup Instructions:**

1. Create an account at [groq.com](https://groq.com)
2. Generate an API key from your [API keys page](https://console.groq.com/keys)
3. Add to your `.env` file:
   ```env
   # Groq Configuration
   GROQ_API_KEY=your-groq-api-key-here
   AGENT_SETTING_CONFIG="settings.groq.toml"
   
   # Optional override
   MODEL_NAME=llama-3.1-70b-versatile  # Override model name
   ```

**Default Values:**

- Model: Configured in `settings.groq.toml`
- Base URL: Groq's default endpoint

### Option 6: OpenRouter Support
**Setup Instructions:**
1. Create an account at [openrouter.ai](https://openrouter.ai)
2. Generate an API key from your account settings
3. Add to your `.env` file:
   ```env
   # OpenRouter Configuration
   OPENROUTER_API_KEY=your-openrouter-api-key
   AGENT_SETTING_CONFIG="settings.openrouter.toml"
   OPENROUTER_BASE_URL="https://openrouter.ai/api/v1"
    # Optional override
   MODEL_NAME=openai/gpt-4o                    # Override model name
    ```


## Configuration Files

CUGA uses TOML configuration files located in `src/cuga/configurations/models/`:

- `settings.openai.toml` - OpenAI configuration (also supports LiteLLM via base URL override)
- `settings.watsonx.toml` - WatsonX configuration
- `settings.azure.toml` - Azure OpenAI configuration
- `settings.groq.toml` - Groq configuration
- `settings.openrouter.toml` - OpenRouter configuration

Each file contains agent-specific model settings that can be overridden by environment variables.

</details>

<div style="margin: 20px 0; padding: 15px; border-left: 4px solid #2196F3; border-radius: 4px;">

💡 **Tip:** Want to use your own tools or add your MCP tools? Check out [`src/cuga/backend/tools_env/registry/config/mcp_servers.yaml`](src/cuga/backend/tools_env/registry/config/mcp_servers.yaml) for examples of how to configure custom tools and APIs, including those for digital sales.

</div>



## 📦 Using CUGA as a Python SDK 

CUGA can be easily integrated into your Python applications as a library. The SDK provides a clean, minimal API for creating and invoking agents with custom tools.

📚 **SDK Documentation**: [SDK Documentation](https://docs.cuga.dev/docs/sdk/cuga_agent/)

### Quick Start

```python
from cuga import CugaAgent
from langchain_core.tools import tool
import asyncio

@tool
def add_numbers(a: int, b: int) -> int:
    '''Add two numbers together'''
    return a + b

@tool
def multiply_numbers(a: int, b: int) -> int:
    '''Multiply two numbers together'''
    return a * b

# Create agent with tools
agent = CugaAgent(tools=[add_numbers, multiply_numbers])


async def main():
    # Add an Intent Guard to block specific operations
    await agent.policies.add_intent_guard(
        name="Block Delete Operations",
        description="Prevents deletion of critical data",
        keywords=["delete", "remove", "erase"],
        response="Deletion operations are not permitted for security reasons.",
        priority=100  # Higher priority = checked first
    )

    # Add a Playbook to provide step-by-step guidance for complex workflows
    await agent.policies.add_playbook(
        name="Budget Analysis Workflow",
        description="Multi-step process for analyzing financial budgets",
        natural_language_trigger=["When user asks to analyze their budget"],
        content="""# Budget Analysis Workflow

    ## Step 1: Calculate Total Expenses
    - Sum all expense categories using add_numbers
    - Document each category amount

    ## Step 2: Calculate Total Revenue
    - Sum all revenue streams using add_numbers
    - Include all income sources

    ## Step 3: Calculate Profit Margin
    - Use multiply_numbers to calculate profit (revenue - expenses)
    - Calculate margin percentage

    ## Step 4: Generate Recommendations
    - Compare against target budget
    - Identify areas for optimization
    - Provide actionable insights""",
        priority=50
    )

    result = await agent.invoke("Analyze my budget: expenses are 5000 and 3000, revenue is 12000")
    print(result.answer)  # The agent's response

if __name__ == "__main__":
    asyncio.run(main())
```

### Key Features

- **Simple API**: `CugaAgent(tools=[...])` → `await agent.invoke(message)`
- **Streaming**: Monitor execution in real-time with `agent.stream()`
- **State Isolation**: Per-user sessions with `thread_id`
- **LangGraph Integration**: Access underlying graph for advanced use cases
- **Flexible Tools**: Direct tools or custom tool providers
- **Policy System**: Comprehensive policy framework with 5 types:
  - **Intent Guard**: Block or modify specific user intents
  - **Playbook**: Step-by-step guidance for complex workflows
  - **Tool Approval**: Require human approval before executing tools
  - **Tool Guide**: Enhance tool descriptions with additional context
  - **Output Formatter**: Format agent responses based on triggers

📚 **Documentation**: [SDK Guide](https://docs.cuga.dev/docs/sdk/cuga_agent/) | [Policies Guide](https://docs.cuga.dev/docs/sdk/policies/)

### Knowledge Base

CUGA includes a built-in knowledge base powered by LangChain and local vector stores. **Docling** is integrated for document ingestion: it parses and normalizes PDFs, Office files, HTML, Markdown, images, and other supported types before chunking and embedding, so the pipeline stays self-contained with no external document services.

When enabled, the agent can search, ingest, and manage documents.

**Try the knowledge demo:** same as the main demo but with the knowledge engine on (upload documents and query them):

```bash
cuga start demo_knowledge
```

Knowledge is **enabled by default** via `settings.toml`. The SDK auto-injects knowledge tools
and awareness into the agent, so it knows what documents are available and how to search them.

#### Programmatic Access

```python
from cuga import CugaAgent
import asyncio

agent = CugaAgent(enable_knowledge=True)

async def main():
    # Ingest a document
    await agent.knowledge.ingest("/path/to/quarterly_report.pdf")

    # The agent now automatically knows about this document
    result = await agent.invoke("What does the report say about Q4 revenue?")
    print(result.answer)  # Agent searches knowledge base and answers

    # Direct search
    results = await agent.knowledge.search("Q4 revenue figures")
    for r in results:
        print(f"{r['filename']} (page {r['page']}): {r['text'][:100]}")

    # List documents
    docs = await agent.knowledge.list_documents()

    # Clean up
    await agent.aclose()

asyncio.run(main())
```

#### Session-Scoped Knowledge

Documents can be scoped to a specific conversation thread:

```python
thread_id = "user-session-123"

# Ingest into session scope (temporary, per-conversation)
await agent.knowledge.ingest("/path/to/file.pdf", scope="session", thread_id=thread_id)

# Search session documents
results = await agent.knowledge.search("query", scope="session", thread_id=thread_id)

# Agent scope (default) — permanent, shared across conversations
await agent.knowledge.ingest("/path/to/file.pdf", scope="agent")
```

#### Disabling Knowledge

```python
agent = CugaAgent(tools=[my_tools], enable_knowledge=False)
```

#### Supported Document Types

PDF, DOCX, XLSX, PPTX, HTML, Markdown, images, and more (via Docling).

---

## CugaSupervisor (Multi-Agent)

Orchestrate multiple agents with a single supervisor: delegate tasks to specialized sub-agents, mix local agents with remote A2A agents, and pass data between them.

📚 **Documentation**: [CugaSupervisor](https://docs.cuga.dev/docs/sdk/cuga_supervisor)

**Try the supervisor demo:** run the multi-agent demo (CRM + email sub-agents) with:

```bash
cuga start demo_supervisor
```

### Quick Start

```python
from cuga import CugaAgent, CugaSupervisor
from langchain_core.tools import tool
import asyncio

@tool
def get_customers(limit: int = 10) -> str:
    """Fetch top customers from CRM with name, email, and revenue. Returns a formatted string."""
    customers = [
        "Alice (alice@example.com, $250,000)",
        "Bob (bob@example.com, $180,000)",
        "Carol (carol@example.com, $120,000)",
        "Dave (dave@example.com, $95,000)",
        "Eve (eve@example.com, $88,000)",
    ]
    top = customers[: min(limit, len(customers))]
    return "Top customers by revenue: " + "; ".join(f"{i+1}. {c}" for i, c in enumerate(top))

@tool
def send_email(to: str, body: str) -> str:
    """Send an email. Returns confirmation."""
    return f"Email sent successfully to {to}"

async def main():
    crm_agent = CugaAgent(tools=[get_customers])
    crm_agent.description = "CRM and customer data"

    email_agent = CugaAgent(tools=[send_email])
    email_agent.description = "Sending emails and notifications"

    supervisor = CugaSupervisor(agents={
        "crm": crm_agent,
        "email": email_agent,
    })

    result = await supervisor.invoke("Get our top 5 customers by revenue, then send the top customer a thank-you email")
    print(result.answer)

asyncio.run(main())
```

To add a remote agent via A2A, pass an external config in `agents`: `"analytics": {"type": "external", "description": "...", "config": {"a2a_protocol": {"endpoint": "http://localhost:9999", "transport": "http"}}}`.

### Supervisor features

- **Delegation**: Supervisor hands work to sub-agents and can pass variables between them when needed.
- **Internal + external**: Combine local `CugaAgent` instances with external agents via **A2A**, task-only or variables in metadata if enabled.
- **Variable passing**: Use `variables=["var_name"]` to pass previous agent outputs or context to the next agent (for internal agents, or A2A when `pass_variables_a2a` is enabled in settings).
- **Agent cards**: For A2A agents, capabilities and description are taken from the agent card and shown in the supervisor prompt.

You can also load agents from YAML with `CugaSupervisor.from_yaml("path/to/config.yaml")`. Enable the supervisor in `settings.toml` under `[supervisor]` when using the server.

---

## Configurations

<details>
<summary>🔒 Running with a secure code sandbox</summary>

Cuga supports isolated code execution using Docker/Podman containers for enhanced security.

1. **Install container runtime**: Download and install [Rancher Desktop](https://rancherdesktop.io/) or Docker.

2. **Install sandbox dependencies**:

   ```bash
   uv sync --group sandbox
   ```

3. **Start with remote sandbox enabled**:

   ```bash
   cuga start demo --sandbox
   ```

   This automatically configures Cuga to use Docker/Podman for code execution instead of local execution.

4. **Test your sandbox setup** (optional):

   ```bash
   # Test local sandbox (default)
   cuga test-sandbox

   # Test remote sandbox with Docker/Podman
   cuga test-sandbox --remote
   ```

   You should see the output: `('test succeeded\n', {})`

**Note**: Without the `--sandbox` flag, Cuga uses local Python execution (default), which is faster but provides less isolation.

</details>

<details>
<summary>☁️ Running with E2B Cloud Sandbox</summary>

CUGA supports [E2B](https://e2b.dev) for cloud-based code execution in secure, ephemeral sandboxes. This provides better isolation than local execution while being faster than Docker/Podman containers.

### Prerequisites:

1. **Get an E2B API key**:
   - Sign up at [e2b.dev](https://e2b.dev)
   - Create an API key from your [dashboard](https://e2b.dev/dashboard)

2. **Set up the E2B template**:
   ```bash
   # Install E2B CLI
   npm install -g @e2b/cli

   # Login with your API key
   e2b auth login

   # Create a template (one-time setup)
   # This creates a 'cuga-langchain' template that CUGA uses
   e2b template build --name cuga-langchain
   ```

3. **Install E2B dependencies**:
   ```bash
   uv sync --group e2b
   ```

4. **Configure environment**:
   Add to your `.env` file:
   ```env
   E2B_API_KEY=your-e2b-api-key-here
   ```

### Exposing Registry to E2B (Required)

E2B runs in the cloud and needs to call your local API registry to execute tools. You need to expose your local registry publicly using a tunneling service like [ngrok](https://ngrok.com).

#### Option 1: Expose Registry Directly (Port 8001)

Best if you have multiple ports available:

```bash
# In a separate terminal, start ngrok tunnel to registry
ngrok http 8001

# You'll get a public URL like: https://abc123.ngrok.io
# Copy this URL
```

Then edit `./src/cuga/settings.toml`:
```toml
[server_ports]
function_call_host = "https://abc123.ngrok.io"  # Your ngrok URL
```

#### Option 2: Expose CUGA Port with Proxy (Port 7860)

Best if you're restricted to 1 port - CUGA will proxy calls to the registry:

```bash
# In a separate terminal, start ngrok tunnel to CUGA
ngrok http 7860

# You'll get a public URL like: https://xyz789.ngrok.io
# Copy this URL
```

Then edit `./src/cuga/settings.toml`:
```toml
[server_ports]
function_call_host = "https://xyz789.ngrok.io"  # Your ngrok URL
```

CUGA automatically proxies `/functions/call` requests to the registry when using the CUGA port.

### Enable E2B in Settings

Edit `./src/cuga/settings.toml`:
```toml
[advanced_features]
e2b_sandbox = true
e2b_sandbox_mode = "per-session"  # Options: "per-session" | "single" | "per-call"
e2b_sandbox_ttl = 600  # Cache TTL in seconds (10 minutes)
```

### Sandbox Modes:

- **`per-session`** (default): One sandbox per conversation thread, cached for reuse
- **`single`**: Single shared sandbox across all threads (most cost-effective)
- **`per-call`**: New sandbox for each execution (most isolated, highest cost)

### Start CUGA with E2B:

```bash
# Make sure ngrok is running in another terminal
cuga start demo
```

E2B will automatically execute code in cloud sandboxes. You'll see logs indicating "CODE SENT TO E2B SANDBOX" when E2B is active.

### Troubleshooting:

- **Error: "function_call_host not configured"**: Make sure you've set `function_call_host` in settings.toml with your ngrok URL
- **Tool execution fails**: Verify ngrok is running and the URL in settings.toml matches your ngrok URL
- **Connection timeout**: Check that your firewall allows ngrok connections

**Benefits of E2B**:
- ✅ No Docker/Podman required
- ✅ Faster than container-based sandboxing
- ✅ Cloud-native with automatic scaling
- ✅ Better isolation than local execution
- ✅ Supports per-session caching for cost optimization

**Note**: E2B is a paid service with a free tier. Check [e2b.dev/pricing](https://e2b.dev/pricing) for details.

</details>

<details>
<summary>⚙️ Reasoning modes - Switch between Fast/Balanced/Accurate modes</summary>

## Available Modes under `./src/cuga`

| Mode       | File                                   | Description                                     |
| ---------- | -------------------------------------- | ----------------------------------------------- |
| `fast`     | `./configurations/modes/fast.toml`     | Optimized for speed                             |
| `balanced` | `./configurations/modes/balanced.toml` | Balance between speed and precision _(default)_ |
| `accurate` | `./configurations/modes/accurate.toml` | Optimized for precision                         |
| `custom`   | `./configurations/modes/custom.toml`   | User-defined settings                           |

## Configuration

```
configurations/
├── modes/fast.toml
├── modes/balanced.toml
├── modes/accurate.toml
└── modes/custom.toml
```

Edit `settings.toml`:

```toml
[features]
cuga_mode = "fast"  # or "balanced" or "accurate" or "custom"
```

**Documentation:** [./docs/flags.html](./docs/flags.html)

</details>

<details>
<summary>🎯 Task Mode Configuration - Switch between API/Web/Hybrid modes</summary>

## Available Task Modes

| Mode     | Description                                                                 |
| -------- | --------------------------------------------------------------------------- |
| `api`    | API-only mode - executes API tasks _(default)_                              |
| `web`    | Web-only mode - executes web tasks using browser extension                  |
| `hybrid` | Hybrid mode - executes both API tasks and web tasks using browser extension |

## How Task Modes Work

### API Mode (`mode = 'api'`)

- Opens tasks in a regular web browser
- Best for API/Tools-focused workflows and testing

### Web Mode (`mode = 'web'`)

- Interface inside a browser extension (available next to browser)
- Optimized for web-specific tasks and interactions
- Direct access to web page content and controls

### Hybrid Mode (`mode = 'hybrid'`)

- Opens inside browser extension like web mode
- Can execute both API/Tools tasks and web page tasks simultaneously
- Starts from configurable URL defined in `demo_mode.start_url`
- Most versatile mode for complex workflows combining web and API operations

## Configuration

Edit `./src/cuga/settings.toml`:

```toml
[demo_mode]
start_url = "https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"  # Starting URL for hybrid mode


[advanced_features]
mode = 'api'  # 'api', 'web', or 'hybrid'
```

</details>

<details>
<summary>📝 Special Instructions Configuration</summary>

## How It Works

Each `.md` file contains specialized instructions that are automatically integrated into the CUGA's internal prompts when that component is active. Simply edit the markdown files to customize behavior for each node type.

**Available instruction sets:** `answer`, `api_planner`, `code_agent`, `plan_controller`, `reflection`, `shortlister`, `task_decomposition`

## Configuration

```
configurations/
└── instructions/
    ├── instructions.toml
    ├── default/
    │   ├── answer.md
    │   ├── api_planner.md
    │   ├── code_agent.md
    │   ├── plan_controller.md
    │   ├── reflection.md
    │   ├── shortlister.md
    │   └── task_decomposition.md
    └── [other instruction sets]/
```

Edit `configurations/instructions/instructions.toml`:

```toml
[instructions]
instruction_set = "default"  # or any instruction set above
```

</details>

<details>
<summary><em style="color: #666;"> 🧠 Optional: Use Evolve with CugaLite</em></summary>

Evolve can now be used with **CugaLite** to bring task-specific guidance into the prompt before execution and save completed trajectories after the run.

This flow is:

- **Opt-in** - disabled by default
- **Non-blocking** - Evolve failures do not fail the task
- **CugaLite-focused** - enabled for lite mode by default
- **Optional integration** - install `cuga[evolve]` if you want the upstream Evolve package available locally, or let `uvx` fetch it on demand

### Setup Steps:

1. Choose how Evolve will be started.
  Recommended for normal CUGA usage: let the CUGA MCP registry launch Evolve for you.
   In the manager UI, add an MCP tool with:
  - Name: `evolve`
  - Connection type: `Command (stdio)`
  - Command: `uvx`
  - Args: `--from altk-evolve --with setuptools<70 evolve-mcp`
   Important: this command starts Evolve in `stdio` mode through the upstream Evolve package. It is intended to be launched by the CUGA registry, not run manually in a separate terminal.
   Alternative for standalone/manual debugging: run Evolve yourself as an SSE server:
   If you run Evolve from a checked-out `altk-evolve` repo instead of `uvx`, install the Postgres extras first with `uv sync --extra pgvector`.
2. Add these environment values in the MCP tool UI:

```env
EVOLVE_BACKEND=postgres
EVOLVE_PG_HOST=localhost
EVOLVE_PG_PORT=5432
EVOLVE_PG_USER=postgres
EVOLVE_PG_PASSWORD=postgres
EVOLVE_PG_DBNAME=evolve
EVOLVE_MODEL_NAME=Azure/gpt-4o
OPENAI_API_KEY=env://OPENAI_API_KEY
OPENAI_BASE_URL=env://OPENAI_BASE_URL
```

Each `env://...` value tells CUGA to read the real secret or setting from its own process environment at runtime, so make sure PostgreSQL is reachable, `pgvector` is available, and the configured OpenAI/LiteLLM-compatible model is one your gateway is allowed to use.

1. **[Optional]** Edit `./src/cuga/settings.toml` and enable lite mode plus Evolve:

```toml
[advanced_features]
lite_mode = true

[evolve]
enabled = true
url = "http://127.0.0.1:8201/sse"
mode = "auto"
app_name = "evolve"
lite_mode_only = true
save_on_success = true
save_on_failure = true
async_save = true
timeout = 30.0
```

If you use the recommended registry-managed setup above, keep `mode = "auto"` or set `mode = "registry"`.

If you run Evolve manually as a standalone SSE server, keep `url = "http://127.0.0.1:8201/sse"` and set `mode = "direct"` if you want to skip registry lookup entirely.

If you use Evolve tip generation, make sure the environment for the Evolve MCP server includes the required Evolve model settings. Otherwise `save_trajectory` may fail later with a LiteLLM/OpenAI model access error even when the MCP connection itself works.

1. Start the same CRM demo with sample workspace files:

```bash
cuga start demo_crm --sample-memory-data
```

1. Run a task that routes through CugaLite, for example:

```text
Identify the common cities between my cuga_workspace/cities.txt and cuga_workspace/company.txt
```

### What happens during a run?

1. CUGA derives the task description from the current sub-task or first user message
2. CugaLite asks Evolve for relevant guidelines
3. Returned guidelines are appended to the system prompt under an `Evolve Guidelines` section
4. The task executes normally
5. The user / assistant trajectory is saved back to Evolve after completion

### Notes

- `async_save = true` saves trajectories in the background and avoids blocking the response
- `save_on_success` and `save_on_failure` let you control which runs are recorded
- `mode = "auto"` lets CUGA use a registry-managed Evolve MCP server when available and fall back to the direct SSE URL otherwise
- `mode = "registry"` is best when you want Evolve to be fully managed as a normal CUGA MCP tool
- `mode = "direct"` is best when you are manually running an SSE Evolve server outside CUGA
- If Evolve is unavailable, times out, or returns no guidance, CUGA continues normally

</details>

## 🔧 Advanced Usage

<details>
<summary><b>💾 Save & Reuse</b></summary>

## Setup

• Change `./src/cuga/settings.toml`: `cuga_mode = "save_reuse_fast"`
• Run: `cuga start demo`

## Demo Steps

• **First run**: `get top account by revenue`

- This is a new flow (first time)
- Wait for task to finish
- Approve to save the workflow
- Provide another example to help generalization of flow e.g. `get top 2 accounts by revenue`

• **Flow now will be saved**:

- May take some time
- Flow will be successfully saved

• **Verify reuse**: `get top 4 accounts by revenue`

- Should run faster using saved workflow

</details>

<details>
<summary><b>🔧 Adding Tools: Comprehensive Examples</b></summary>

CUGA supports three types of tool integrations. Each approach has its own use cases and benefits:

## 📋 **Tool Types Overview**

| Tool Type     | Best For                               | Configuration      | Runtime Loading |
| ------------- | -------------------------------------- | ------------------ | --------------- |
| **OpenAPI**   | REST APIs, existing services           | `mcp_servers.yaml` | ✅ Build        |
| **MCP**       | Custom protocols, complex integrations | `mcp_servers.yaml` | ✅ Build        |
| **LangChain** | Python functions, rapid prototyping    | Direct import      | ✅ Runtime      |

## 📚 **Additional Resources**

- **Tool Registry**: [./src/cuga/backend/tools_env/registry/README.md](./src/cuga/backend/tools_env/registry/README.md)
- **Comprehensive example with different tools + MCP**: [./docs/examples/cuga_with_runtime_tools/README.md](Adding Tools)
- **CUGA as MCP**: [./docs/examples/cuga_as_mcp/README.md](docs/examples/cuga_as_mcp)

</details>

### Test Scenarios - E2E

All tests are available through `./src/scripts/run_tests.sh`:

**Unit Tests**
- Registry: OpenAPI integration, MCP server functionality, service configurations
- Variables Manager: Core functionality, metadata handling, singleton pattern
- Code Executors: Local sandbox and E2B lite execution

**Policy Integration Tests** (`src/cuga/backend/cuga_graph/policy/tests/`)
- Intent Guard: Blocking behavior, priority resolution, multiple guard scenarios
- Playbook: Guidance injection, plan refinement, workflow execution
- Tool Approval: Human-in-the-loop approval flows (approve/deny)
- Tool Guide: Context enhancement and metadata injection
- Output Formatter: Response formatting and routing
- NL Trigger Conflict Resolution: Embedding-based similarity search with LLM conflict resolution
- Embedding Similarity: Vector search, policy matching, threshold validation
- Keyword Operators: AND/OR logic, case sensitivity, multi-keyword matching

**SDK Integration Tests** (`src/cuga/sdk_core/tests/`)
- SDK functionality: Agent invocation, streaming, tool integration
- Policy management: Policy loading, matching, and execution via SDK

**Stability Tests** (`run_stability_tests.py`)
- Fast Mode: Get top account by revenue, list accounts, find VP sales high-value accounts
- CRM Workflows: Contacts management, email operations, tool discovery
- HF Utterances: Account queries, revenue calculations, playbook execution
- Execution: Supports local and Docker execution, parallel/sequential modes, cross-version testing

## 🧪 Running Tests

Run all tests (unit, integration, and stability):

```bash
./src/scripts/run_tests.sh
```

Run unit tests only:

```bash
./src/scripts/run_tests.sh unit_tests
```

## 📊 Evaluation

For information on how to evaluate, see the [CUGA Evaluation Documentation](src/cuga/evaluation/README.md)

## 📚 Resources

- 📖 [Example applications](./docs/examples)
- 📧 Contact: [CUGA Team](https://forms.office.com/pages/responsepage.aspx?id=V3D2_MlQ1EqY8__KZK3Z6UtMUa14uFNMi1EyUFiZFGRUQklOQThLRjlYMFM2R1dYTk5GVTFMRzNZVi4u&route=shorturl)


## Call for the Community

CUGA is open source because we believe **trustworthy enterprise agents must be built together**.  
Here's how you can help:

- **Share use cases** → Show us how you'd use CUGA in real workflows.
- **Request features** → Suggest capabilities that would make it more useful.
- **Report bugs** → Help improve stability by filing clear, reproducible reports.

All contributions are welcome through [GitHub Issues](../../issues/new/choose) - whether it's sharing use cases, requesting features, or reporting bugs!

## Roadmap

Amongst other, we're exploring the following directions:

- **Policy support**: procedural SOPs, domain knowledge, input/output guards, context- and tool-based constraints
- **Performance improvements**: dynamic reasoning strategies that adapt to task complexity

### Before Submitting a PR

Please follow the contribution guide in [CONTRIBUTING.md](CONTRIBUTING.md).

---

[![Star History Chart](https://api.star-history.com/svg?repos=cuga-project/cuga-agent&type=Timeline)](https://star-history.com/#cuga-project/cuga-agent&Date)

## Contributors

[![cuga agent contributors](https://contrib.rocks/image?repo=cuga-project/cuga-agent)](https://github.com/cuga-project/cuga-agent/graphs/contributors)


================================================
FILE: __init__.py
================================================


================================================
FILE: deployment/README.md
================================================
# CUGA Helm Chart

Deploy CUGA agent to Kubernetes.

## Quick Start

```bash
# 1. Create .env with your API key
cp .env.example .env
# Or: cp deployment/.env.example deployment/.env
# Edit and set GROQ_API_KEY or OPENAI_API_KEY

# 2. Run deploy script (cleans, builds, deploys)
./deployment/deploy-local.sh

# 3. Inspect logs until ready (wait for "Manager mode. Press Ctrl+C to stop" and services table)
kubectl logs -l app.kubernetes.io/name=cuga -f

# 4. Access (in another terminal, once Demo is listed)
kubectl port-forward svc/cuga 7860:7860
# Open http://localhost:7860
```

**Options:**
```bash
./deployment/deploy-local.sh -c settings.openai.toml   # use OpenAI instead of Groq
./deployment/deploy-local.sh --help
```

Uses `deployment/.env` or `.env`. Auto-detects kind and loads image. Default: Groq.

## Prerequisites

- Helm 3
- Kubernetes cluster (Docker Desktop, minikube, kind, or cloud)

## Image: Local vs Registry

### Option 1: Local Image

Use when running on Docker Desktop, minikube, or kind with a locally built image.

**Docker Desktop:**
```bash
docker build -t cuga-agent:latest .
helm install cuga ./deployment/helm/cuga --set image.pullPolicy=Never
```

**Minikube:**
```bash
eval $(minikube docker-env)
docker build -t cuga-agent:latest .
helm install cuga ./deployment/helm/cuga --set image.pullPolicy=Never
```

**Kind:**
```bash
docker build -t cuga-agent:latest .
kind load docker-image cuga-agent:latest
helm install cuga ./deployment/helm/cuga --set image.pullPolicy=Never
```

### Option 2: Registry Image

Use for cloud clusters (GKE, EKS, AKS) or when sharing images.

```bash
# Build and push
docker build -t your-registry.io/cuga-agent:latest .
docker push your-registry.io/cuga-agent:latest

# Install
helm install cuga ./deployment/helm/cuga \
  --set image.repository=your-registry.io/cuga-agent \
  --set image.tag=latest
```

## Secrets for API Keys

API keys should not be in values files. Use a Kubernetes Secret.

### Create the secret

```bash
kubectl create secret generic cuga-secrets \
  --from-literal=OPENAI_API_KEY=sk-your-openai-key \
  --from-literal=GROQ_API_KEY=gsk-your-groq-key
```

### Use the secret in the chart

Set `existingSecret` so the chart pulls `OPENAI_API_KEY` and `GROQ_API_KEY` from the secret:

```bash
helm install cuga ./deployment/helm/cuga \
  --set existingSecret=cuga-secrets \
  --set env.MODEL_NAME=llama-3.1-70b-versatile \
  --set env.AGENT_SETTING_CONFIG=settings.groq.toml
```

The secret can contain `OPENAI_API_KEY`, `GROQ_API_KEY`, `OPENAI_BASE_URL`, or any combination. Other env vars (`MODEL_NAME`, `AGENT_SETTING_CONFIG`) come from `values.yaml` or `--set`.

### Alternative: inline env (not recommended)

For quick testing only, you can pass keys via `--set` (they will appear in `helm get values`):

```bash
helm install cuga ./deployment/helm/cuga \
  --set env.OPENAI_API_KEY=sk-xxx \
  --set env.GROQ_API_KEY=gsk_xxx
```

## Full example (local image + secrets)

```bash
# 1. Build image
docker build -t cuga-agent:latest .

# 2. Create secret
kubectl create secret generic cuga-secrets \
  --from-literal=OPENAI_API_KEY=sk-xxx \
  --from-literal=GROQ_API_KEY=gsk-xxx

# 3. Install
helm install cuga ./deployment/helm/cuga \
  --set image.pullPolicy=Never \
  --set existingSecret=cuga-secrets \
  --set env.MODEL_NAME=llama-3.1-70b-versatile \
  --set env.AGENT_SETTING_CONFIG=settings.groq.toml

# 4. Access
kubectl port-forward svc/cuga 7860:7860
# Open http://localhost:7860
```

## Viewing logs and pods

```bash
# List pods
kubectl get pods -l app.kubernetes.io/name=cuga

# Stream logs (follow)
kubectl logs -l app.kubernetes.io/name=cuga -f

# Logs from a specific pod
kubectl logs <pod-name> -f

# Pod details (events, state, restarts)
kubectl describe pod -l app.kubernetes.io/name=cuga

# Exec into a pod
kubectl exec -it <pod-name> -- /bin/sh
```

## Stop and uninstall

```bash
# Stop port-forward (if running): Ctrl+C in the terminal

# Uninstall the release (removes deployment, service, etc.)
helm uninstall cuga

# Optional: delete the secret
kubectl delete secret cuga-secrets
```

## Stop, update secrets, and rerun

```bash
# 1. Uninstall
helm uninstall cuga

# 2. Update or recreate the secret
kubectl delete secret cuga-secrets 2>/dev/null || true
kubectl create secret generic cuga-secrets \
  --from-literal=OPENAI_API_KEY=sk-new-key \
  --from-literal=GROQ_API_KEY=gsk-new-key

# 3. Reinstall
helm install cuga ./deployment/helm/cuga \
  --set image.pullPolicy=Never \
  --set existingSecret=cuga-secrets \
  --set env.MODEL_NAME=llama-3.1-70b-versatile \
  --set env.AGENT_SETTING_CONFIG=settings.groq.toml
```

## Upgrade

```bash
# After changing values or chart
helm upgrade cuga ./deployment/helm/cuga

# With new values
helm upgrade cuga ./deployment/helm/cuga \
  --set env.MODEL_NAME=gpt-4o \
  --set env.AGENT_SETTING_CONFIG=settings.openai.toml

# List releases
helm list
```

## Persistence

The `dbs` directory stores config, policies, conversation history, and memory. A PersistentVolumeClaim is enabled by default so data survives pod restarts.

```yaml
# values.yaml
persistence:
  dbs:
    enabled: true
    size: 1Gi
```

To disable (ephemeral storage): `--set persistence.dbs.enabled=false`

## Troubleshooting

**CreateContainerConfigError** – Usually means the secret doesn't exist. Create it with at least one key (OpenAI or Groq):
```bash
# Groq only
kubectl create secret generic cuga-secrets --from-literal=GROQ_API_KEY=gsk-xxx

# OpenAI only
kubectl create secret generic cuga-secrets --from-literal=OPENAI_API_KEY=sk-xxx

# Both + custom base URL
kubectl create secret generic cuga-secrets \
  --from-literal=OPENAI_API_KEY=sk-xxx \
  --from-literal=GROQ_API_KEY=gsk-xxx \
  --from-literal=OPENAI_BASE_URL=https://your-api.example.com/v1
```

**ImagePullBackOff** – For local images, add `--set image.pullPolicy=Never`. For registry images, ensure the image exists and you're logged in.

**Check pod events:**
```bash
kubectl describe pod -l app.kubernetes.io/name=cuga
```

## Environment Variables

| Variable | Description |
|----------|-------------|
| OPENAI_API_KEY | OpenAI API key (for settings.openai.toml) |
| GROQ_API_KEY | Groq API key (for settings.groq.toml) |
| OPENAI_BASE_URL | Optional. Custom OpenAI-compatible API base URL |
| MODEL_NAME | Model name (e.g. gpt-4o, llama-3.1-70b-versatile) |
| AGENT_SETTING_CONFIG | Config file (settings.groq.toml, settings.openai.toml) |

---

## ☁️ OpenShift Deployment

Deploy CUGA to an OpenShift cluster using the provided Helm chart and deployment script. Each deployment is scoped to an `INSTANCE_ID`, so multiple independent agent instances can coexist in the same namespace.

### Architecture (example: pepsi and coke in one namespace)

One namespace, one shared PostgreSQL, two agent instances (pepsi, coke). Each agent has its own secrets, route (HTTPS), and PVC; both use the same postgres and can use the same OIDC provider for auth.

**View diagram:** [architecture.html](helm/architecture.html) (open in browser)

| Resource | Purpose |
|----------|---------|
| `postgres-secret` | DB password for postgres-pgvector (shared) |
| `postgres-pgvector` | One PostgreSQL + pgvector per namespace |
| `*-icr-pull-secret` | Image pull for `us.icr.io` per instance |
| `*-env-secret` | GROQ_API_KEY, OIDC_*, DYNACONF_STORAGE__POSTGRES_URL, etc. |
| Route | Edge TLS (HTTPS), serves `/`, `/chat`, `/manage` |
| OIDC | Optional; set `DYNACONF_AUTH__ENABLED=true` and OIDC_* in env |

### Prerequisites

- `oc` or `kubectl` CLI, logged in to your cluster (`oc login ...`)
- `helm` 3 installed
- IBM Container Registry API key (for pulling `us.icr.io/nocodeui-automation/cuga`)

### Quick Start

```bash
# 1. Copy the env template and fill in your values
cp deployment/helm/openshift.example.env deployment/helm/my-instance.env
# Edit my-instance.env — set INSTANCE_ID, ICR_API_KEY, GROQ_API_KEY, etc.

# 2. Run the deploy script (local SQLite storage)
./deployment/helm/deploy-openshift.sh deployment/helm/my-instance.env

# Or deploy with PostgreSQL (one shared postgres per namespace, prod storage)
./deployment/helm/deploy-openshift.sh deployment/helm/my-instance.env --with-postgres
```

When using `--with-postgres`, set `POSTGRES_PASSWORD` in your env file. The script will create a `postgres-secret`, deploy the `postgres-pgvector` Helm chart once per namespace, and set `DYNACONF_STORAGE__MODE=prod` and the postgres URL for each cuga instance.

The script will:
1. Create the namespace (idempotent)
2. If `--with-postgres`: create `postgres-secret` and deploy `postgres-pgvector` (shared per namespace)
3. Create an image pull secret for `us.icr.io` using your `ICR_API_KEY`
4. Create a Kubernetes secret with all sensitive env vars (including postgres URL when `--with-postgres`)
5. Deploy the Helm chart (`cuga-$INSTANCE_ID`) with the correct image and config
6. Create an OpenShift Route with edge TLS (HTTPS) and print the access URLs

### Status & inspection

Use the status script to inspect pods, logs, and routes (based on your `openshift.env`):

```bash
./deployment/helm/status-openshift.sh [path/to/openshift.env] [command]
```

| Command    | Description                          |
|------------|--------------------------------------|
| `pods`     | List CUGA pods (default)              |
| `all`      | List cuga + postgres + vault pods     |
| `describe` | Describe CUGA pods                   |
| `logs`     | Pod logs (add `-f` to follow)        |
| `route`    | Show route URL and access links       |
| `events`   | Recent namespace events               |
| `status`   | Helm release status + pod summary     |

```bash
./deployment/helm/status-openshift.sh
./deployment/helm/status-openshift.sh openshift.env logs -f
./deployment/helm/status-openshift.sh openshift.env describe
```

### Access URLs

After deploy, the agent is available at:

```
https://<route-host>/        # Agent chat UI
https://<route-host>/chat    # Chat (client-side route)
https://<route-host>/manage  # Management dashboard
```

HTTP is automatically redirected to HTTPS.

### Multi-instance example

```bash
# Deploy two independent instances into the same namespace
./deployment/helm/deploy-openshift.sh deployment/helm/acme.env    # release: cuga-acme
./deployment/helm/deploy-openshift.sh deployment/helm/ibm.env     # release: cuga-ibm
```

Each instance has its own secrets, PVC, and Route — re-running a script is safe and will perform a rolling upgrade.

### PostgreSQL (shared per namespace)

Use the `--with-postgres` flag to deploy one PostgreSQL (pgvector) instance per namespace, shared by all cuga instances in that namespace. Set `POSTGRES_PASSWORD` in your env file; the script creates `postgres-secret`, deploys `postgres-pgvector`, and sets `DYNACONF_STORAGE__MODE=prod` and the connection URL for each cuga instance. The URL is built as:

`postgresql://<POSTGRES_USER>:<POSTGRES_PASSWORD>@postgres-pgvector.<NAMESPACE>.svc.cluster.local:5432/<POSTGRES_DB>`

To use an external PostgreSQL instead, leave `POSTGRES_PASSWORD` empty, do not use `--with-postgres`, set `DYNACONF_STORAGE__MODE=prod` and `DYNACONF_STORAGE__POSTGRES_URL` in your env file, and add the URL to the secret (e.g. via the existing secret flow).

### Cleanup

```bash
# Remove a specific instance (keeps namespace and postgres intact)
./deployment/helm/cleanup-openshift.sh deployment/helm/my-instance.env

# Also remove the shared postgres (postgres-pgvector + postgres-secret)
./deployment/helm/cleanup-openshift.sh deployment/helm/my-instance.env --with-postgres

# Remove instance and delete the entire namespace
./deployment/helm/cleanup-openshift.sh deployment/helm/my-instance.env --delete-namespace
```

### Configuration reference (`openshift.example.env`)

| Variable | Required | Description |
|----------|----------|-------------|
| `INSTANCE_ID` | yes | Unique name for this instance (e.g. `acme`). Names the Helm release `cuga-$INSTANCE_ID` |
| `NAMESPACE` | yes | Kubernetes namespace (default: `cuga`) |
| `ICR_API_KEY` | yes | IBM Container Registry API key for image pull secret |
| `IMAGE_REPOSITORY` | yes | Image repo (default: `us.icr.io/nocodeui-automation/cuga`) |
| `IMAGE_TAG` | yes | Image tag (default: `latest`) |
| `ROUTE_HOSTNAME` | no | Custom hostname — leave empty for OpenShift auto-assign |
| `GROQ_API_KEY` | yes | Groq API key |
| `MODEL_NAME` | yes | LLM model name |
| `AGENT_SETTING_CONFIG` | yes | Settings TOML file (e.g. `settings.groq.toml`) |
| `DYNACONF_AUTH__ENABLED` | no | Enable OIDC auth (default: `true`) |
| `DYNACONF_AUTH__REQUIRE_HTTPS` | no | Enforce HTTPS on cookies and routes (default: `false`) |
| `DYNACONF_AUTH__AUTHORIZATION_ENABLED` | no | Enable role-based authorization (default: `false`) |
| `DYNACONF_AUTH__ROLE_TOKEN_SOURCE` | no | Token used for role checks: `auto` (default), `id_token`, `access_token`, `iam_proxy` |
| `OIDC_CLIENT_ID` | no | OIDC client ID |
| `OIDC_CLIENT_SECRET` | no | OIDC client secret |
| `OIDC_DISCOVERY_URL` | no | OIDC discovery URL |
| `OIDC_REDIRECT_URI` | no | OIDC redirect URI (e.g. `https://<route-host>/manage`) |
| `DYNACONF_AUTH__IAM_PROXY_URL` | no | XPM IAM proxy base URL for service-scoped token exchange (e.g. `https://xpm.apps.example.com/api/v1/iam-proxy`) |
| `DYNACONF_AUTH__IAM_PROXY_SKIP_VERIFY` | no | Skip TLS verification for IAM proxy (dev/fyre only, default: `false`) |
| `DYNACONF_STORAGE__MODE` | no | Storage mode: `local` (default) or `prod`. Set to `prod` automatically when using `--with-postgres` |
| `POSTGRES_PASSWORD` | when `--with-postgres` | Password for the PostgreSQL DB user. Required when using `--with-postgres` |
| `POSTGRES_USER` | no | PostgreSQL username (default: `cuga`) |
| `POSTGRES_DB` | no | PostgreSQL database name (default: `cuga`) |
| `DYNACONF_STORAGE__POSTGRES_URL` | no | PostgreSQL URL. Auto-built when using `--with-postgres`; set only for an external postgres |


================================================
FILE: deployment/certs/README.md
================================================
# Local TLS certificates for HTTPS

When using OIDC (e.g. IBM Verify) with redirect URIs like `https://localhost:7860/manage`, the server must run over HTTPS.

Generate a self-signed certificate (one-time):

```bash
openssl req -x509 -newkey rsa:4096 -keyout localhost.key -out localhost.crt \
  -days 365 -nodes -subj "/CN=localhost"
```

Then set in `.env`:

- `SSL_KEYFILE="deployment/certs/localhost.key"`
- `SSL_CERTFILE="deployment/certs/localhost.crt"`

Start the demo server with `cuga start demo`; it will use TLS when these env vars are set.


================================================
FILE: deployment/deploy-local-postgres.sh
================================================
#!/usr/bin/env bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

RELEASE_NAME="postgres-pgvector"
SECRET_NAME="postgres-pgvector-secrets"

if [[ -f "$SCRIPT_DIR/.env" ]]; then
  ENV_FILE="$SCRIPT_DIR/.env"
else
  ENV_FILE="${PROJECT_ROOT}/.env"
fi

cd "$PROJECT_ROOT"

echo "==> Cleaning up..."
helm uninstall "$RELEASE_NAME" 2>/dev/null || true
kubectl delete secret "$SECRET_NAME" 2>/dev/null || true
kubectl delete pvc "$RELEASE_NAME" 2>/dev/null || true

echo "==> Loading .env from $ENV_FILE..."
if [[ ! -f "$ENV_FILE" ]]; then
  echo "Error: .env not found. Create deployment/.env or .env with POSTGRES_PASSWORD"
  echo "  cp deployment/.env.example deployment/.env"
  exit 1
fi

set -a
source "$ENV_FILE"
set +a

PASSWORD="${POSTGRES_PASSWORD:-}"

if [[ -z "$PASSWORD" ]]; then
  echo "Error: Need POSTGRES_PASSWORD in .env"
  exit 1
fi

echo "==> Creating secret..."
kubectl create secret generic "$SECRET_NAME" --from-literal=password="$PASSWORD"

echo "==> Deploying postgres-pgvector..."
helm install "$RELEASE_NAME" "$SCRIPT_DIR/helm/postgres-pgvector" \
  --set image.pullPolicy=IfNotPresent \
  --set auth.existingSecret="$SECRET_NAME" \
  --set persistence.enabled=true

echo ""
echo "==> Done. Port-forward: kubectl port-forward svc/$RELEASE_NAME 5432:5432"
echo "    postgres_url: postgresql://cuga:\$POSTGRES_PASSWORD@localhost:5432/cuga"


================================================
FILE: deployment/deploy-local.sh
================================================
#!/usr/bin/env bash
set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

AGENT_CONFIG=""
while [[ $# -gt 0 ]]; do
  case $1 in
    -c|--agent-config)
      AGENT_CONFIG="$2"
      shift 2
      ;;
    -h|--help)
      echo "Usage: $0 [-c|--agent-config CONFIG]"
      echo "  -c, --agent-config  Override AGENT_SETTING_CONFIG (e.g. settings.groq.toml, settings.openai.toml)"
      exit 0
      ;;
    *)
      echo "Unknown option: $1"
      exit 1
      ;;
  esac
done
if [[ -f "$SCRIPT_DIR/.env" ]]; then
  ENV_FILE="$SCRIPT_DIR/.env"
else
  ENV_FILE="${PROJECT_ROOT}/.env"
fi
SECRET_NAME="cuga-secrets"
RELEASE_NAME="cuga"

cd "$PROJECT_ROOT"

echo "==> Cleaning up..."
helm uninstall "$RELEASE_NAME" 2>/dev/null || true
kubectl delete secret "$SECRET_NAME" 2>/dev/null || true
kubectl delete pvc "${RELEASE_NAME}-dbs" 2>/dev/null || true

echo "==> Loading .env from $ENV_FILE..."
if [[ ! -f "$ENV_FILE" ]]; then
  echo "Error: .env not found. Create deployment/.env or .env with GROQ_API_KEY or OPENAI_API_KEY"
  echo "  cp .env.example .env   # or  cp deployment/.env.example deployment/.env"
  exit 1
fi

set -a
source "$ENV_FILE"
set +a

GROQ_KEY="${GROQ_API_KEY:-}"
OPENAI_KEY="${OPENAI_API_KEY:-}"

if [[ -z "$GROQ_KEY" && -z "$OPENAI_KEY" ]]; then
  echo "Error: Need GROQ_API_KEY (default) or OPENAI_API_KEY in .env"
  exit 1
fi

[[ -n "$GROQ_KEY" ]] && DEFAULT_AGENT_CONFIG="settings.groq.toml" || DEFAULT_AGENT_CONFIG="settings.openai.toml"

echo "==> Building image..."
docker build -t cuga-agent:latest .

if command -v kind &>/dev/null && kubectl config current-context 2>/dev/null | grep -q kind; then
  echo "==> Loading image into kind..."
  kind load docker-image cuga-agent:latest
fi

echo "==> Creating secret..."
SECRET_ARGS=()
[[ -n "$GROQ_KEY" ]] && SECRET_ARGS+=(--from-literal=GROQ_API_KEY="$GROQ_KEY")
[[ -n "$OPENAI_KEY" ]] && SECRET_ARGS+=(--from-literal=OPENAI_API_KEY="$OPENAI_KEY")
[[ -n "$OPENAI_BASE_URL" ]] && SECRET_ARGS+=(--from-literal=OPENAI_BASE_URL="$OPENAI_BASE_URL")

kubectl create secret generic "$SECRET_NAME" "${SECRET_ARGS[@]}"

AGENT_SETTING="${AGENT_CONFIG:-${AGENT_SETTING_CONFIG:-$DEFAULT_AGENT_CONFIG}}"
echo "==> Deploying (AGENT_SETTING_CONFIG=$AGENT_SETTING)..."
helm install "$RELEASE_NAME" "$SCRIPT_DIR/helm/cuga" \
  --set image.pullPolicy=Never \
  --set existingSecret="$SECRET_NAME" \
  --set env.MODEL_NAME="${MODEL_NAME:-openai/gpt-oss-120b}" \
  --set env.AGENT_SETTING_CONFIG="$AGENT_SETTING" \
  --set persistence.dbs.enabled=true

echo ""
echo "==> Done. Access with: kubectl port-forward svc/$RELEASE_NAME 7860:7860"
echo "    Then open http://localhost:7860"


================================================
FILE: deployment/docker-compose/openlit/docker-compose.yml
================================================
# Local observability stack for testing OpenLit integration with Cuga.
#
# Services:
#   otel-collector  - Receives OTLP from OpenLit, forwards traces to Tempo and metrics to Prometheus
#   tempo           - Distributed tracing backend (stores and queries traces)
#   prometheus      - Metrics backend (scrapes OTel Collector's Prometheus exporter)
#   grafana         - Visualization (pre-configured with Tempo and Prometheus datasources)
#
# Usage:
#   1. Start the stack:
#        docker compose up -d
#
#   2. Enable OpenLit in settings.toml:
#        [observability]
#        openlit = true
#
#   3. Set the OTLP endpoint in your .env:
#        OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
#
#   4. Run the agent:
#        cuga start demo_crm
#
#   5. Open Grafana at http://localhost:3000
#      - Traces: Explore → Tempo datasource
#      - Metrics: Explore → Prometheus datasource

services:
  otel-collector:
    image: otel/opentelemetry-collector-contrib
    container_name: otel-collector
    command: ["--config=/etc/otel-collector-config.yaml"]
    volumes:
      - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
    ports:
      - "4318:4318"   # OTLP HTTP receiver (OpenLit sends here)
      - "8889:8889"   # Prometheus exporter (Prometheus scrapes here)

  tempo:
    image: grafana/tempo:2.4.1  # pinned: "latest" has breaking config changes between major versions
    container_name: tempo
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
    ports:
      - "3200:3200"   # Tempo HTTP API (Grafana queries here)

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    command: ["--config.file=/etc/prometheus.yml"]
    volumes:
      - ./prometheus.yml:/etc/prometheus.yml
    ports:
      - "9090:9090"   # Prometheus UI and API

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    volumes:
      - ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
    environment:
      - GF_AUTH_ANONYMOUS_ENABLED=true
      - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
    ports:
      - "3000:3000"   # Grafana UI
    depends_on:
      - prometheus
      - tempo


================================================
FILE: deployment/docker-compose/openlit/grafana-datasources.yaml
================================================
# Grafana datasource provisioning for Cuga + OpenLit local testing stack.
#
# Pre-configures Grafana with:
#   - Tempo datasource for trace exploration (LLM call traces from OpenLit)
#   - Prometheus datasource for metrics (token usage, latency, request counts)
#
# After starting the stack, open Grafana at http://localhost:3000
# Navigate to Explore → select Tempo or Prometheus to query data.

apiVersion: 1

datasources:
  - name: Tempo
    type: tempo
    access: proxy
    url: http://tempo:3200
    isDefault: false

  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true



================================================
FILE: deployment/docker-compose/openlit/otel-collector-config.yaml
================================================
# OpenTelemetry Collector configuration for Cuga + OpenLit local testing stack.
#
# Data flow:
#   OpenLit (Cuga) --OTLP HTTP--> otel-collector:4318
#       --> traces  --> Tempo:4317  (gRPC)
#       --> metrics --> Prometheus exporter :8889 (scraped by Prometheus)

receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true
  prometheus:
    endpoint: "0.0.0.0:8889"

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp/tempo]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheus]

# Made with Bob


================================================
FILE: deployment/docker-compose/openlit/prometheus.yml
================================================
# Prometheus configuration for Cuga + OpenLit local testing stack.
#
# Scrapes LLM metrics from the OTel Collector's Prometheus exporter on port 8889.
# Metrics include token usage, latency, request counts per model/provider.

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:8889']



================================================
FILE: deployment/docker-compose/openlit/tempo.yaml
================================================
# Grafana Tempo configuration for Cuga + OpenLit local testing stack.
#
# Tempo receives traces from the OTel Collector via gRPC (OTLP) on port 4317
# and exposes its HTTP API on port 3200 (queried by Grafana).
#
# The ingester.lifecycler block is required for single-binary (monolithic) mode.
# Without it, Tempo's internal ring stays empty and queries fail with:
#   "error finding partition ring replicas: empty ring"

server:
  http_listen_port: 3200

# Register the ingester in the in-memory ring so the querier can locate it.
ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
    final_sleep: 0s
  trace_idle_period: 10s
  max_block_bytes: 1_000_000
  max_block_duration: 5m
  complete_block_timeout: 2m

compactor:
  compaction:
    compaction_window: 1h
    max_block_bytes: 100_000_000
    block_retention: 1h
    compacted_block_retention: 10m

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          endpoint: 0.0.0.0:4317

storage:
  trace:
    backend: local
    local:
      path: /tmp/tempo/blocks
    wal:
      path: /tmp/tempo/wal

# Made with Bob


================================================
FILE: deployment/helm/cleanup-openshift.sh
================================================
#!/usr/bin/env bash
set -euo pipefail

# ---------------------------------------------------------------------------
# CUGA OpenShift Cleanup Script
#
# Removes all resources deployed by deploy-openshift.sh for a given instance.
# Does NOT touch other instances or the namespace itself (unless --delete-namespace).
# Use --with-postgres to also remove the shared postgres (postgres-pgvector + postgres-secret).
#
# Usage:
#   ./cleanup-openshift.sh [path/to/openshift.env] [--with-postgres] [--delete-namespace]
# ---------------------------------------------------------------------------

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WITH_POSTGRES=false
DELETE_NAMESPACE=false
ENV_FILE=""
for arg in "$@"; do
  if [[ "$arg" == "--with-postgres" ]]; then
    WITH_POSTGRES=true
  elif [[ "$arg" == "--delete-namespace" ]]; then
    DELETE_NAMESPACE=true
  else
    [[ -z "$ENV_FILE" ]] && ENV_FILE="$arg"
  fi
done
ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/openshift.env}"

# ---------------------------------------------------------------------------
# Load environment
# ---------------------------------------------------------------------------

if [[ ! -f "$ENV_FILE" ]]; then
  echo "ERROR: env file not found: $ENV_FILE"
  echo "Usage: $0 [path/to/openshift.env] [--with-postgres] [--delete-namespace]"
  exit 1
fi

# shellcheck disable=SC1090
set -a
source "$ENV_FILE"
set +a

if [[ -z "${INSTANCE_ID:-}" ]]; then
  echo "ERROR: INSTANCE_ID is not set in $ENV_FILE"
  exit 1
fi

NAMESPACE="${NAMESPACE:-cuga}"
RELEASE_NAME="cuga-${INSTANCE_ID}"
KUBECTL_TIMEOUT="${KUBECTL_REQUEST_TIMEOUT:-120}"
HELM_TIMEOUT="${HELM_TIMEOUT:-10m}"
PULL_SECRET_NAME="${INSTANCE_ID}-icr-pull-secret"
ENV_SECRET_NAME="${INSTANCE_ID}-env-secret"

echo ""
echo "========================================"
echo "  CUGA OpenShift Cleanup"
echo "  Instance  : ${INSTANCE_ID}"
echo "  Release   : ${RELEASE_NAME}"
echo "  Namespace : ${NAMESPACE}"
if [[ "$WITH_POSTGRES" == true ]]; then
  echo "  Postgres  : will be removed (postgres-pgvector + postgres-secret)"
fi
if [[ "$DELETE_NAMESPACE" == true ]]; then
  echo "  WARNING   : Namespace will be DELETED"
fi
echo "========================================"
echo ""
read -r -p "Are you sure you want to delete all resources for instance '${INSTANCE_ID}'? [y/N] " confirm
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }
echo ""

# ---------------------------------------------------------------------------
# 1. Uninstall Helm release (removes deployment, service, route, pvc)
# ---------------------------------------------------------------------------

echo "[1/4] Uninstalling Helm release: ${RELEASE_NAME}"
if helm status "${RELEASE_NAME}" --namespace "${NAMESPACE}" &>/dev/null; then
  helm uninstall "${RELEASE_NAME}" --namespace "${NAMESPACE}" --timeout "${HELM_TIMEOUT}"
  echo "      Release ${RELEASE_NAME} uninstalled."
else
  echo "      Release ${RELEASE_NAME} not found, skipping."
fi

# ---------------------------------------------------------------------------
# 2. Delete secrets and NetworkPolicies
# ---------------------------------------------------------------------------

echo "[2/4] Deleting secrets and policies for instance: ${INSTANCE_ID}"

for secret in "${PULL_SECRET_NAME}" "${ENV_SECRET_NAME}"; do
  if kubectl get secret "${secret}" --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}" &>/dev/null; then
    kubectl delete secret "${secret}" --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}"
    echo "      Deleted secret: ${secret}"
  else
    echo "      Secret ${secret} not found, skipping."
  fi
done

if kubectl get networkpolicy "${INSTANCE_ID}-airgap-egress" --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}" &>/dev/null; then
  kubectl delete networkpolicy "${INSTANCE_ID}-airgap-egress" --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}"
  echo "      Deleted NetworkPolicy: ${INSTANCE_ID}-airgap-egress"
fi

# ---------------------------------------------------------------------------
# 3. Optionally remove postgres (shared per namespace)
# ---------------------------------------------------------------------------

if [[ "$WITH_POSTGRES" == true ]]; then
  echo "[3/4] Removing postgres (postgres-pgvector + postgres-secret)"
  if helm status postgres-pgvector --namespace "${NAMESPACE}" &>/dev/null; then
    helm uninstall postgres-pgvector --namespace "${NAMESPACE}" --timeout "${HELM_TIMEOUT}"
    echo "      Release postgres-pgvector uninstalled."
  else
    echo "      Release postgres-pgvector not found, skipping."
  fi
  if kubectl get secret postgres-secret --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}" &>/dev/null; then
    kubectl delete secret postgres-secret --namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}"
    echo "      Deleted secret: postgres-secret"
  else
    echo "      Secret postgres-secret not found, skipping."
  fi
else
  echo "[3/4] Postgres left intact (pass --with-postgres to remove it)."
fi

# ---------------------------------------------------------------------------
# 4. Optionally delete namespace
# ---------------------------------------------------------------------------

if [[ "$DELETE_NAMESPACE" == true ]]; then
  echo "[4/4] Deleting namespace: ${NAMESPACE}"
  read -r -p "This will delete the ENTIRE namespace '${NAMESPACE}' and ALL resources inside it. Confirm? [y/N] " confirm2
  if [[ "$confirm2" =~ ^[Yy]$ ]]; then
    kubectl delete namespace "${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}"
    echo "      Namespace ${NAMESPACE} deleted."
  else
    echo "      Skipped namespace deletion."
  fi
else
  echo "[4/4] Namespace '${NAMESPACE}' left intact (pass --delete-namespace to remove it)."
fi

echo ""
echo "========================================"
echo "  Cleanup complete for instance: ${INSTANCE_ID}"
echo "========================================"
echo ""


================================================
FILE: deployment/helm/cuga/Chart.yaml
================================================
apiVersion: v2
name: cuga
description: CUGA agent - generalist agent for enterprise task execution
type: application
version: 0.1.0
appVersion: "0.2.9"


================================================
FILE: deployment/helm/cuga/templates/NOTES.txt
================================================
CUGA agent has been deployed.

Access via port-forward:
  kubectl port-forward -n {{ .Release.Namespace }} svc/{{ include "cuga.fullname" . }} 7860:7860

Then open http://localhost:7860


================================================
FILE: deployment/helm/cuga/templates/_helpers.tpl
================================================
{{/*
Expand the name of the chart.
*/}}
{{- define "cuga.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
*/}}
{{- define "cuga.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "cuga.labels" -}}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/name: {{ include "cuga.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "cuga.selectorLabels" -}}
app.kubernetes.io/name: {{ include "cuga.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}


================================================
FILE: deployment/helm/cuga/templates/deployment.yaml
================================================
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "cuga.fullname" . }}
  labels:
    {{- include "cuga.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "cuga.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "cuga.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: 7860
              protocol: TCP
          env:
            {{- if .Values.persistence.dbs.enabled }}
            - name: CUGA_DBS_DIR
              value: "/data/dbs"
            {{- end }}
            {{- $secret := .Values.existingSecret }}
            {{- $sensitiveKeys := list "GROQ_API_KEY" "OIDC_CLIENT_SECRET" "OIDC_CLIENT_ID" "OIDC_DISCOVERY_URL" "OIDC_REDIRECT_URI" "DYNACONF_STORAGE__POSTGRES_URL" "VAULT_TOKEN" }}
            {{- range $key, $value := .Values.env }}
            - name: {{ $key }}
              {{- if and $secret (has $key $sensitiveKeys) }}
              valueFrom:
                secretKeyRef:
                  name: {{ $secret }}
                  key: {{ $key }}
                  optional: true
              {{- else }}
              value: {{ $value | quote }}
              {{- end }}
            {{- end }}
          livenessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 120
            periodSeconds: 15
            failureThreshold: 5
            timeoutSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 90
            periodSeconds: 10
            failureThreshold: 10
            timeoutSeconds: 10
          startupProbe:
            httpGet:
              path: /
              port: http
            initialDelaySeconds: 60
            periodSeconds: 10
            failureThreshold: 18
            timeoutSeconds: 10
          {{- with .Values.resources }}
          resources:
            {{- toYaml . | nindent 12 }}
          {{- end }}
          {{- if .Values.persistence.dbs.enabled }}
          volumeMounts:
            - name: dbs
              mountPath: /data/dbs
          {{- end }}
      {{- if .Values.persistence.dbs.enabled }}
      volumes:
        - name: dbs
          persistentVolumeClaim:
            claimName: {{ include "cuga.fullname" . }}-dbs
      {{- end }}


================================================
FILE: deployment/helm/cuga/templates/pvc.yaml
================================================
{{- if .Values.persistence.dbs.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ include "cuga.fullname" . }}-dbs
  labels:
    {{- include "cuga.labels" . | nindent 4 }}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: {{ .Values.persistence.dbs.size | default "1Gi" }}
{{- end }}


================================================
FILE: deployment/helm/cuga/templates/route.yaml
================================================
{{- if .Values.route.enabled }}
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: {{ include "cuga.fullname" . }}
  labels:
    {{- include "cuga.labels" . | nindent 4 }}
  annotations:
    # Serves /, /chat, and /manage — all client-side routes handled by the app
    haproxy.router.openshift.io/timeout: 120s
spec:
  {{- if .Values.route.hostname }}
  host: {{ .Values.route.hostname }}
  {{- end }}
  to:
    kind: Service
    name: {{ include "cuga.fullname" . }}
    weight: 100
  port:
    targetPort: http
  tls:
    termination: edge
    insecureEdgeTerminationPolicy: Redirect
  wildcardPolicy: None
{{- end }}


================================================
FILE: deployment/helm/cuga/templates/service.yaml
================================================
apiVersion: v1
kind: Service
metadata:
  name: {{ include "cuga.fullname" . }}
  labels:
    {{- include "cuga.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "cuga.selectorLabels" . | nindent 4 }}


================================================
FILE: deployment/helm/cuga/values.yaml
================================================
replicaCount: 1

image:
  repository: ghcr.io/cuga-project/cuga
  tag: latest
  pullPolicy: Always

imagePullSecrets: []

service:
  type: ClusterIP
  port: 7860

route:
  enabled: true
  hostname: ""
  # TLS is edge-terminated at the OpenShift router
  # insecureEdgeTerminationPolicy: Redirect (HTTP -> HTTPS)

env:
  UV_CACHE_DIR: "/tmp/uv-cache"
  GROQ_API_KEY: ""
  MODEL_NAME: "openai/gpt-oss-120b"
  AGENT_SETTING_CONFIG: "settings.groq.toml"
  DYNACONF_SERVICE__INSTANCE_ID: ""
  DYNACONF_SERVICE__TENANT_ID: ""
  DYNACONF_AUTH__ENABLED: "true"
  DYNACONF_AUTH__REQUIRE_HTTPS: "true"
  DYNACONF_AUTH__AUTHORIZATION_ENABLED: "false"
  DYNACONF_AUTH__ROLE_TOKEN_SOURCE: "auto"
  DYNACONF_UI__HIDE_CUGA_LOGO: "false"
  DYNACONF_UI__BRAND_NAME: ""
  CUGA_DEMO_MODE: "default"
  OIDC_CLIENT_ID: ""
  OIDC_CLIENT_SECRET: ""
  OIDC_DISCOVERY_URL: ""
  OIDC_REDIRECT_URI: ""
  DYNACONF_AUTH__OIDC_SKIP_VERIFY: "false"
  DYNACONF_AUTH__OIDC_CA_BUNDLE: ""
  DYNACONF_AUTH__IAM_PROXY_URL: ""
  DYNACONF_AUTH__IAM_PROXY_SKIP_VERIFY: "false"
  DYNACONF_STORAGE__MODE: "local"
  DYNACONF_STORAGE__POSTGRES_URL: ""
  DYNACONF_SECRETS__FORCE_ENV: "false"
  DYNACONF_SECRETS__VAULT_SKIP_VERIFY: "false"
  DYNACONF_OBSERVABILITY__OPENLIT: "false"
  OTEL_EXPORTER_OTLP_ENDPOINT: ""

# Name of an existing Secret containing sensitive env vars.
# When set, sensitive keys are sourced via secretKeyRef instead of plain value.
existingSecret: ""

resources:
  requests:
    memory: 2Gi
    cpu: 200m
  limits:
    memory: 4Gi
    cpu: "2"

persistence:
  dbs:
    enabled: true
    size: 1Gi


================================================
FILE: deployment/helm/deploy-openshift.sh
================================================
#!/usr/bin/env bash
set -euo pipefail

# ---------------------------------------------------------------------------
# CUGA OpenShift Deployment Script
#
# Usage:
#   ./deploy-openshift.sh [path/to/openshift.env] [--with-postgres] [--with-vault]
#
# Prerequisites:
#   - Logged in to OpenShift cluster via `oc login` or `kubectl` with valid kubeconfig
#   - helm 3 installed
#   - openshift.env filled in (copy from openshift.env template)
# ---------------------------------------------------------------------------

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
WITH_POSTGRES=false
WITH_VAULT=false
AIRGAPPED=false
ENV_FILE=""
for arg in "$@"; do
  if [[ "$arg" == "--with-postgres" ]]; then
    WITH_POSTGRES=true
  elif [[ "$arg" == "--with-vault" ]]; then
    WITH_VAULT=true
  elif [[ "$arg" == "--airgapped" ]]; then
    AIRGAPPED=true
  else
    [[ -z "$ENV_FILE" ]] && ENV_FILE="$arg"
  fi
done
ENV_FILE="${ENV_FILE:-${SCRIPT_DIR}/openshift.env}"

# ---------------------------------------------------------------------------
# Load environment
# ---------------------------------------------------------------------------

if [[ ! -f "$ENV_FILE" ]]; then
  echo "ERROR: env file not found: $ENV_FILE"
  echo "Usage: $0 [path/to/openshift.env]"
  exit 1
fi

# shellcheck disable=SC1090
set -a
source "$ENV_FILE"
set +a

# ---------------------------------------------------------------------------
# Validate required variables
# ---------------------------------------------------------------------------

REQUIRED_VARS=(
  INSTANCE_ID
  NAMESPACE
  ICR_API_KEY
  IMAGE_REPOSITORY
  IMAGE_TAG
  GROQ_API_KEY
  MODEL_NAME
  AGENT_SETTING_CONFIG
)

if [[ "$WITH_POSTGRES" == true ]]; then
  REQUIRED_VARS+=(POSTGRES_PASSWORD)
fi

MISSING=()
for var in "${REQUIRED_VARS[@]}"; do
  if [[ -z "${!var:-}" ]]; then
    MISSING+=("$var")
  fi
done

if [[ ${#MISSING[@]} -gt 0 ]]; then
  echo "ERROR: The following required variables are not set in $ENV_FILE:"
  for v in "${MISSING[@]}"; do
    echo "  - $v"
  done
  exit 1
fi

# Derived names — all scoped to INSTANCE_ID so multiple instances coexist
RELEASE_NAME="cuga-${INSTANCE_ID}"
PULL_SECRET_NAME="${INSTANCE_ID}-icr-pull-secret"
ENV_SECRET_NAME="${INSTANCE_ID}-env-secret"
CHART_PATH="${SCRIPT_DIR}/cuga"
KUBECTL_TIMEOUT="${KUBECTL_REQUEST_TIMEOUT:-120}"
HELM_TIMEOUT="${HELM_TIMEOUT:-10m}"
TOTAL_STEPS=6
[[ "$WITH_POSTGRES" != true ]] && TOTAL_STEPS=5
[[ "$WITH_VAULT" == true ]] && TOTAL_STEPS=$((TOTAL_STEPS + 1))

echo ""
echo "========================================"
echo "  CUGA OpenShift Deployment"
echo "  Instance  : ${INSTANCE_ID}"
echo "  Release   : ${RELEASE_NAME}"
echo "  Namespace : ${NAMESPACE}"
echo "  Hostname  : ${ROUTE_HOSTNAME:-<auto-assigned by OpenShift>}"
if [[ "$WITH_POSTGRES" == true ]]; then
  echo "  Postgres  : enabled (shared per namespace)"
  if [[ -n "${DOCKERHUB_USERNAME:-}" ]] && [[ -n "${DOCKERHUB_TOKEN:-${DOCKERHUB_PASSWORD:-}}" ]]; then
    echo "  PG image  : Docker Hub pull secret (authenticated)"
  elif [[ -n "${POSTGRES_IMAGE_PULL_SECRET:-}" ]]; then
    echo "  PG image  : imagePullSecret ${POSTGRES_IMAGE_PULL_SECRET}"
  fi
fi
if [[ "$WITH_VAULT" == true ]]; then
  echo "  Vault     : enabled"
fi
if [[ "$AIRGAPPED" == true ]]; then
  echo "  Airgapped : enabled (NetworkPolicy blocking egress applied)"
fi
echo "========================================"
echo ""

# ---------------------------------------------------------------------------
# 1. Create namespace (idempotent)
# ---------------------------------------------------------------------------

STEP=1
echo "[${STEP}/${TOTAL_STEPS}] Creating namespace: ${NAMESPACE}"
kubectl create namespace "${NAMESPACE}" \
  --dry-run=client -o yaml | kubectl apply -f - --request-timeout="${KUBECTL_TIMEOUT}"
((STEP++))

# ---------------------------------------------------------------------------
# 2. Postgres secret + Helm (when --with-postgres)
# ---------------------------------------------------------------------------

if [[ "$WITH_POSTGRES" == true ]]; then
  echo "[${STEP}/${TOTAL_STEPS}] Creating postgres secret (postgres-secret)"
  kubectl create secret generic postgres-secret \
    --from-literal=password="${POSTGRES_PASSWORD}" \
    --namespace="${NAMESPACE}" \
    --dry-run=client -o yaml | kubectl apply -f - --request-timeout="${KUBECTL_TIMEOUT}"
  ((STEP++))

  POSTGRES_PGVECTOR_HELM_EXTRA=()
  if [[ -n "${DOCKERHUB_USERNAME:-}" ]] && [[ -n "${DOCKERHUB_TOKEN:-${DOCKERHUB_PASSWORD:-}}" ]]; then
    PG_DOCKERHUB_SECRET="${POSTGRES_IMAGE_PULL_SECRET:-postgres-pgvector-dockerhub-pull}"
    DH_PASS="${DOCKERHUB_TOKEN:-${DOCKERHUB_PASSWORD}}"
    echo "  (Docker Hub pull secret for postgres image: ${PG_DOCKERHUB_SECRET})"
    kubectl create secret docker-registry "${PG_DOCKERHUB_SECRET}" \
      --docker-server=https://index.docker.io/v1/ \
      --docker-username="${DOCKERHUB_USERNAME}" \
      --docker-password="${DH_PASS}" \
      --namespace="${NAMESPACE}" \
      --dry-run=client -o yaml | kubectl apply -f - --request-timeout="${KUBECTL_TIMEOUT}"
    POSTGRES_PGVECTOR_HELM_EXTRA+=(--set "imagePullSecrets[0].name=${PG_DOCKERHUB_SECRET}")
  elif [[ -n "${POSTGRES_IMAGE_PULL_SECRET:-}" ]]; then
    POSTGRES_PGVECTOR_HELM_EXTRA+=(--set "imagePullSecrets[0].name=${POSTGRES_IMAGE_PULL_SECRET}")
  fi

  echo "[${STEP}/${TOTAL_STEPS}] Deploying postgres (postgres-pgvector)"
  helm upgrade --install postgres-pgvector "${SCRIPT_DIR}/postgres-pgvector" \
    --namespace "${NAMESPACE}" \
    --timeout "${HELM_TIMEOUT}" \
    --disable-openapi-validation \
    --set "auth.database=${POSTGRES_DB:-cuga}" \
    --set "auth.username=${POSTGRES_USER:-cuga}" \
    --set "auth.existingSecret=postgres-secret" \
    --set "auth.existingSecretKey=password" \
    ${POSTGRES_PGVECTOR_HELM_EXTRA[@]+"${POSTGRES_PGVECTOR_HELM_EXTRA[@]}"}
  ((STEP++))
fi

# ---------------------------------------------------------------------------
# 3. Image pull secret for IBM Container Registry
# ---------------------------------------------------------------------------

echo "[${STEP}/${TOTAL_STEPS}] Creating image pull secret: ${PULL_SECRET_NAME}"
kubectl create secret docker-registry "${PULL_SECRET_NAME}" \
  --docker-server=us.icr.io \
  --docker-username=iamapikey \
  --docker-password="${ICR_API_KEY}" \
  --namespace="${NAMESPACE}" \
  --dry-run=client -o yaml | kubectl apply -f - --request-timeout="${KUBECTL_TIMEOUT}"
((STEP++))

# ---------------------------------------------------------------------------
# 4. Environment secret (sensitive values only)
# ---------------------------------------------------------------------------

echo "[${STEP}/${TOTAL_STEPS}] Creating env secret: ${ENV_SECRET_NAME}"

# Build --from-literal args for sensitive keys
SECRET_ARGS=(
  "--from-literal=GROQ_API_KEY=${GROQ_API_KEY}"
)

[[ -n "${OIDC_CLIENT_ID:-}" ]]            && SECRET_ARGS+=("--from-literal=OIDC_CLIENT_ID=${OIDC_CLIENT_ID}")
[[ -n "${OIDC_CLIENT_SECRET:-}" ]]        && SECRET_ARGS+=("--from-literal=OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}")
[[ -n "${OIDC_DISCOVERY_URL:-}" ]]        && SECRET_ARGS+=("--from-literal=OIDC_DISCOVERY_URL=${OIDC_DISCOVERY_URL}")
[[ -n "${OIDC_REDIRECT_URI:-}" ]]         && SECRET_ARGS+=("--from-literal=OIDC_REDIRECT_URI=${OIDC_REDIRECT_URI}")
[[ -n "${VAULT_TOKEN:-}" ]]               && SECRET_ARGS+=("--from-literal=VAULT_TOKEN=${VAULT_TOKEN}")
[[ -n "${CUGA_SECRET_KEY:-}" ]]           && SECRET_ARGS+=("--from-literal=CUGA_SECRET_KEY=${CUGA_SECRET_KEY}")

if [[ "$WITH_POSTGRES" == true ]]; then
  PG_URL="postgresql://${POSTGRES_USER:-cuga}:${POSTGRES_PASSWORD}@postgres-pgvector.${NAMESPACE}.svc.cluster.local:5432/${POSTGRES_DB:-cuga}"
  SECRET_ARGS+=("--from-literal=DYNACONF_STORAGE__POSTGRES_URL=${PG_URL}")
else
  if [[ -n "${DYNACONF_STORAGE__POSTGRES_URL:-}" ]]; then
    SECRET_ARGS+=("--from-literal=DYNACONF_STORAGE__POSTGRES_URL=${DYNACONF_STORAGE__POSTGRES_URL}")
  elif [[ -n "${POSTGRES_PASSWORD:-}" ]]; then
    PG_URL="postgresql://${POSTGRES_USER:-cuga}:${POSTGRES_PASSWORD}@postgres-pgvector.${NAMESPACE}.svc.cluster.local:5432/${POSTGRES_DB:-cuga}"
    SECRET_ARGS+=("--from-literal=DYNACONF_STORAGE__POSTGRES_URL=${PG_URL}")
  else
    PG_PASS=$(kubectl get secret postgres-secret --namespace="${NAMESPACE}" --request-timeout="${KUBECTL_TIMEOUT}" -o jsonpath='{.data.password}' 2>/dev/null | base64 -d 2>/dev/null || true)
    if [[ -n "${PG_PASS}" ]]; then
      PG_URL="postgresql://${POSTGRES_USER:-cuga}:${PG_PASS}@postgres-pgvector.${NAMESPACE}.svc.cluster.local:5432/${POSTGRES_DB:-cuga}"
      SECRET_ARGS+=("--from-literal=DYNACONF_STORAGE__POSTGRES_URL=${PG_URL}")
    fi
  fi
fi

kubectl create secret generic "${ENV_SECRET_NAME}" \
  "${SECRET_ARGS[@]}" \
  --namespace="${NAMESPACE}" \
  --dry-run=client -o yaml | kubectl apply -f - --request-timeout="${KUBECTL_TIMEOUT}"
((STEP++))

# ---------------------------------------------------------------------------
# Optional: Vault deployment
# ---------------------------------------------------------------------------

if [[ "$WITH_VAULT" == true ]]; then
  echo "[${STEP}/${TOTAL_STEPS}] Deploying HashiCorp Vault"
  VAULT_CHART_PATH="${SCRIPT_DIR}/vault"

  helm repo add hashicorp https://helm.releases.hashicorp.com 2>/dev/null || true
  helm repo update hashicorp 2>/dev/null || true
  helm dependency update "${VAULT_CHART_PATH}" 2>/dev/null || true

  helm upgrade --install vault "${VAULT_CHART_PATH}" \
    --namespace "${NAMESPACE}" \
    --timeout "${HELM_TIMEOUT}" \
    --disable-openapi-validation \
    -f "${VAULT_CHART_PATH}/values.openshift.yaml" \
    ${VAULT_TOKEN:+--set "vault.server.extraEnvironmentVars.VAULT_DEV_ROOT_TOKEN_ID=${VAULT_TOKEN}"}
  ((STEP++))

  echo ""
  echo "  Vault deployed. Initialize it (first time only):"
  echo "    kubectl exec -n ${NAMESPACE} -it vault-0 -- vault operator init"
  echo ""
  echo "  Add to your env file:"
  echo "    VAULT_TOKEN=<root-token>"
  echo "    DYNACONF_SECRETS__MODE=vault"
  echo "    DYNACONF_SECRETS__VAULT_ADDR=http://vault.${NAMESPACE}.svc.cluster.local:8200"
  echo ""
fi

# ---------------------------------------------------------------------------
# 5. Helm deploy (cuga)
# ---------------------------------------------------------------------------

if [[ "$AIRGAPPED" == true ]]; then
  echo "[${STEP}/${TOTAL_STEPS}] Applying Airgap NetworkPolicy (deny egress)"
  # Policy logic:
  # 1. Deny all egress by default (achieved by policyTypes: [Egress] with no catch-all allow)
  # 2. Allow egress to local namespace (for postgres, internal services)
  # 3. Allow DNS (UDP/TCP 53)
  # 4. Allow Groq IPs if resolved
  
  cat <<EOF | kubectl apply -n "${NAMESPACE}" -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: "${INSTANCE_ID}-airgap-egress"
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/instance: "${RELEASE_NAME}"
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: "${NAMESPACE}"
  - ports:
    - port: 53
      protocol: UDP
    - port: 53
      protocol: TCP
EOF
fi

echo "[${STEP}/${TOTAL_STEPS}] Deploying Helm release: ${RELEASE_NAME}"

STORAGE_MODE="${DYNACONF_STORAGE__MODE:-local}"
[[ "$WITH_POSTGRES" == true ]] && STORAGE_MODE=prod

HELM_ARGS=(
  upgrade --install "${RELEASE_NAME}" "${CHART_PATH}"
  --namespace "${NAMESPACE}"
  --set "image.repository=${IMAGE_REPOSITORY}"
  --set "image.tag=${IMAGE_TAG}"
  --set "image.pullPolicy=Always"
  --set "imagePullSecrets[0].name=${PULL_SECRET_NAME}"
  --set "existingSecret=${ENV_SECRET_NAME}"
  --set "env.DYNACONF_SERVICE__INSTANCE_ID=${DYNACONF_SERVICE__INSTANCE_ID:-${INSTANCE_ID}}"
  --set "env.DYNACONF_SERVICE__TENANT_ID=${DYNACONF_SERVICE__TENANT_ID:-${NAMESPACE}}"
  --set "env.UV_CACHE_DIR=${UV_CACHE_DIR:-/tmp/uv-cache}"
  --set "env.MODEL_NAME=${MODEL_NAME}"
  --set "env.AGENT_SETTING_CONFIG=${AGENT_SETTING_CONFIG}"
  --set "env.DYNACONF_AUTH__ENABLED=${DYNACONF_AUTH__ENABLED:-true}"
  --set "env.DYNACONF_AUTH__REQUIRE_HTTPS=${DYNACONF_AUTH__REQUIRE_HTTPS:-false}"
  --set "env.DYNACONF_AUTH__AUTHORIZATION_ENABLED=${DYNACONF_AUTH__AUTHORIZATION_ENABLED:-false}"
  --set "env.DYNACONF_AUTH__OIDC_SKIP_VERIFY=${DY
Download .txt
gitextract_9yecxdwb/

├── .claude/
│   └── commands/
│       ├── cuga-commit.md
│       ├── cuga-create-pr.md
│       ├── cuga-new-feature.md
│       ├── cuga-report-bug.md
│       └── cuga-ruff-check.md
├── .cra/
│   └── .fileignore
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── documentation-request.yml
│   │   ├── feature_request.yml
│   │   └── use_case.yml
│   ├── PULL_REQUEST_TEMPLATE/
│   │   ├── bugfix.md
│   │   ├── chore.md
│   │   ├── docs.md
│   │   └── feature.md
│   └── workflows/
│       ├── deploy-image-ghcr.yml
│       ├── deploy-image.yml
│       ├── release-pr.yml
│       ├── release-tag.yml
│       ├── release.yml
│       ├── smoke-pip-install.yml
│       ├── stability-tests.yml
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .python-version
├── .run/
│   ├── API Registry Appworld.run.xml
│   ├── API Registry Demo.run.xml
│   ├── App World Eval.run.xml
│   └── Cuga Demo.run.xml
├── .secrets.baseline
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── .whitesource
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.ubi
├── LICENSE
├── README.md
├── __init__.py
├── deployment/
│   ├── README.md
│   ├── certs/
│   │   └── README.md
│   ├── deploy-local-postgres.sh
│   ├── deploy-local.sh
│   ├── docker-compose/
│   │   └── openlit/
│   │       ├── docker-compose.yml
│   │       ├── grafana-datasources.yaml
│   │       ├── otel-collector-config.yaml
│   │       ├── prometheus.yml
│   │       └── tempo.yaml
│   └── helm/
│       ├── cleanup-openshift.sh
│       ├── cuga/
│       │   ├── Chart.yaml
│       │   ├── templates/
│       │   │   ├── NOTES.txt
│       │   │   ├── _helpers.tpl
│       │   │   ├── deployment.yaml
│       │   │   ├── pvc.yaml
│       │   │   ├── route.yaml
│       │   │   └── service.yaml
│       │   └── values.yaml
│       ├── deploy-openshift.sh
│       ├── openshift.example.env
│       ├── postgres-pgvector/
│       │   ├── Chart.yaml
│       │   ├── README.md
│       │   ├── templates/
│       │   │   ├── NOTES.txt
│       │   │   ├── _helpers.tpl
│       │   │   ├── configmap.yaml
│       │   │   ├── deployment.yaml
│       │   │   ├── pvc.yaml
│       │   │   ├── secret.yaml
│       │   │   └── service.yaml
│       │   └── values.yaml
│       ├── status-openshift.sh
│       └── vault/
│           ├── Chart.yaml
│           ├── templates/
│           │   └── NOTES.txt
│           ├── values.openshift.yaml
│           └── values.yaml
├── design.html
├── design.md
├── docs/
│   ├── examples/
│   │   ├── cuga_as_mcp/
│   │   │   ├── .python-version
│   │   │   ├── README.md
│   │   │   ├── main.py
│   │   │   ├── mcp_servers.yaml
│   │   │   ├── pyproject.toml
│   │   │   └── tools_loader.py
│   │   ├── cuga_with_runtime_tools/
│   │   │   ├── .gitignore
│   │   │   ├── .python-version
│   │   │   ├── README.md
│   │   │   ├── fast_mcp_example.py
│   │   │   ├── langchain_example_tool.py
│   │   │   ├── main.py
│   │   │   ├── mcp_servers.yaml
│   │   │   └── pyproject.toml
│   │   ├── demo_apps/
│   │   │   └── setup/
│   │   │       ├── README.md
│   │   │       ├── cli.py
│   │   │       └── pyproject.toml
│   │   ├── digital_sales_openapi/
│   │   │   └── main.py
│   │   ├── evaluation/
│   │   │   ├── input_example.json
│   │   │   └── input_schema.json
│   │   └── langflow/
│   │       └── CUGA Langflow Demo - Conference Preparation.json
│   ├── flags.html
│   ├── memory/
│   │   └── README.md
│   └── sales_app.html
├── pyproject.toml
├── readme_cuga_lite_kaizen.md
├── ruff.toml
├── run_stability_tests.py
├── scripts/
│   ├── deploy-image.sh
│   ├── docker-entrypoint.sh
│   └── smoke_pip_install_isolated.sh
├── src/
│   ├── cuga/
│   │   ├── __init__.py
│   │   ├── backend/
│   │   │   ├── __init__.py
│   │   │   ├── activity_tracker/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── join_tool.py
│   │   │   │   ├── render_helper.py
│   │   │   │   └── tracker.py
│   │   │   ├── browser_env/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── browser/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── chat_async.py
│   │   │   │   │   ├── env.py
│   │   │   │   │   ├── extension_env_async.py
│   │   │   │   │   ├── gym_env.py
│   │   │   │   │   ├── gym_env_async.py
│   │   │   │   │   ├── gym_obs/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── extract_chrome_extension.py
│   │   │   │   │   │   ├── http_stream_comm.py
│   │   │   │   │   │   ├── javascript/
│   │   │   │   │   │   │   ├── frame_mark_elements.js
│   │   │   │   │   │   │   └── frame_unmark_elements.js
│   │   │   │   │   │   ├── obs.py
│   │   │   │   │   │   ├── obs_async.py
│   │   │   │   │   │   └── websocket_server.py
│   │   │   │   │   ├── open_ended_async.py
│   │   │   │   │   ├── utils.py
│   │   │   │   │   └── utils_async.py
│   │   │   │   ├── page_understanding/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── extension_processor.py
│   │   │   │   │   ├── extractor_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── extract_async.py
│   │   │   │   │   │   └── javascript/
│   │   │   │   │   │       ├── frame_mark_elements.js
│   │   │   │   │   │       └── frame_unmark_elements.js
│   │   │   │   │   ├── nocodeui_pu_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── model.py
│   │   │   │   │   │   ├── nocode_utils.py
│   │   │   │   │   │   └── rules.yaml
│   │   │   │   │   ├── pu_extractor.py
│   │   │   │   │   ├── pu_extractor_chrome_extension.py
│   │   │   │   │   ├── pu_processor.py
│   │   │   │   │   ├── pu_transform.py
│   │   │   │   │   ├── tranformer_utils/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── dom_transform_utils.py
│   │   │   │   │   │   └── transform_utils.py
│   │   │   │   │   └── types/
│   │   │   │   │       ├── README.md
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── dom_tree_types.py
│   │   │   │   │       └── validate_structure.py
│   │   │   │   └── tools/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── extension_commands.py
│   │   │   │       ├── playwright_commands.py
│   │   │   │       └── providers.py
│   │   │   ├── cuga_graph/
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── graph.py
│   │   │   │   ├── nodes/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── answer/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── final_answer.py
│   │   │   │   │   │   └── final_answer_agent/
│   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │       ├── final_answer_agent.py
│   │   │   │   │   │       └── prompts/
│   │   │   │   │   │           ├── __init__.py
│   │   │   │   │   │           ├── load_prompt.py
│   │   │   │   │   │           ├── system.jinja2
│   │   │   │   │   │           ├── system_appworld.jinja2
│   │   │   │   │   │           ├── system_appworld_plain.jinja2
│   │   │   │   │   │           ├── system_concise.jinja2
│   │   │   │   │   │           ├── system_long.jinja2
│   │   │   │   │   │           ├── user_msg.jinja2
│   │   │   │   │   │           ├── user_msg_appworld.jinja2
│   │   │   │   │   │           └── user_msg_appworld_plain.jinja2
│   │   │   │   │   ├── api/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── api_agent_utils/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   └── utils.py
│   │   │   │   │   │   ├── api_code_agent.py
│   │   │   │   │   │   ├── api_code_planner.py
│   │   │   │   │   │   ├── api_code_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── api_code_planner_agent.py
│   │   │   │   │   │   │   ├── api_planner_prompt_v1.md
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.backup.jinja2
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── system_fast.jinja2
│   │   │   │   │   │   │       ├── system_high_level_no_relation_to_vars.jinja2
│   │   │   │   │   │   │       ├── test.md
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── api_planner.py
│   │   │   │   │   │   ├── api_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── api_planner_agent.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── system_hitl.jinja2
│   │   │   │   │   │   │       ├── system_long_task_good.jinja2
│   │   │   │   │   │   │       ├── system_no_few_shots_thoughts_as_list.jinja2
│   │   │   │   │   │   │       ├── system_short.jinja2
│   │   │   │   │   │   │       ├── system_success_on_long_template.jinja2
│   │   │   │   │   │   │       ├── system_v2.jinja2
│   │   │   │   │   │   │       ├── user.jinja2
│   │   │   │   │   │   │       ├── user_hitl.jinja2
│   │   │   │   │   │   │       └── user_v2.jinja2
│   │   │   │   │   │   ├── api_shortlister.py
│   │   │   │   │   │   ├── code_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── code_act_agent.py
│   │   │   │   │   │   │   ├── code_agent.py
│   │   │   │   │   │   │   ├── model.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── system_accurate.jinja2
│   │   │   │   │   │   │       ├── system_fast.jinja2
│   │   │   │   │   │   │       ├── system_no_plan.jinja2
│   │   │   │   │   │   │       ├── user.jinja2
│   │   │   │   │   │   │       └── user_no_plan.jinja2
│   │   │   │   │   │   ├── shortlister_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   ├── system_parameters.jinja2
│   │   │   │   │   │   │   │   ├── user.jinja2
│   │   │   │   │   │   │   │   └── user_parameters.jinja2
│   │   │   │   │   │   │   └── shortlister_agent.py
│   │   │   │   │   │   ├── tasks/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── reflection_system.jinja2
│   │   │   │   │   │   │   │   ├── reflection_user.jinja2
│   │   │   │   │   │   │   │   ├── summary_system.jinja2
│   │   │   │   │   │   │   │   └── summary_user.jinja2
│   │   │   │   │   │   │   ├── reflection.py
│   │   │   │   │   │   │   └── summarize_code.py
│   │   │   │   │   │   └── variables_manager/
│   │   │   │   │   │       └── tests/
│   │   │   │   │   │           ├── __init__.py
│   │   │   │   │   │           ├── data.json
│   │   │   │   │   │           ├── test_manager.py
│   │   │   │   │   │           └── test_value_preview.py
│   │   │   │   │   ├── browser/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── action.py
│   │   │   │   │   │   ├── action_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── action_agent.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   └── user.jinja2
│   │   │   │   │   │   │   ├── ranker_output.json
│   │   │   │   │   │   │   └── tools/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── alert.py
│   │   │   │   │   │   │       ├── tool_processor.py
│   │   │   │   │   │   │       └── tools.py
│   │   │   │   │   │   ├── browser_planner.py
│   │   │   │   │   │   ├── browser_planner_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── browser_planner_agent.py
│   │   │   │   │   │   │   └── prompts/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── load_prompt.py
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       ├── test.json
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── qa_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── load_prompt.py
│   │   │   │   │   │   │   │   ├── system.jinja2
│   │   │   │   │   │   │   │   └── user_msg.jinja2
│   │   │   │   │   │   │   └── qa_agent.py
│   │   │   │   │   │   └── qa_agent_node.py
│   │   │   │   │   ├── chat/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── chat.py
│   │   │   │   │   │   └── chat_agent/
│   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │       ├── chat_agent.py
│   │   │   │   │   │       └── prompts/
│   │   │   │   │   │           ├── pmt.jinja2
│   │   │   │   │   │           ├── pmt_chat.jinja2
│   │   │   │   │   │           └── pmt_with_variables_mentioning.jinja2
│   │   │   │   │   ├── cuga_lite/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── combined_tool_provider.py
│   │   │   │   │   │   ├── cuga_lite_graph.py
│   │   │   │   │   │   ├── cuga_lite_node.py
│   │   │   │   │   │   ├── direct_langchain_tools_provider.py
│   │   │   │   │   │   ├── executors/
│   │   │   │   │   │   │   ├── README.md
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── base_executor.py
│   │   │   │   │   │   │   ├── code_executor.py
│   │   │   │   │   │   │   ├── common/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   ├── benchmark_mode.py
│   │   │   │   │   │   │   │   ├── call_api_helper.py
│   │   │   │   │   │   │   │   ├── code_wrapper.py
│   │   │   │   │   │   │   │   ├── restricted_environment.py
│   │   │   │   │   │   │   │   ├── security.py
│   │   │   │   │   │   │   │   └── variable_utils.py
│   │   │   │   │   │   │   ├── docker/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── docker_executor.py
│   │   │   │   │   │   │   ├── e2b/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── e2b_executor.py
│   │   │   │   │   │   │   ├── local/
│   │   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   │   └── local_executor.py
│   │   │   │   │   │   │   └── tests/
│   │   │   │   │   │   │       ├── test_api_calls_with_print.py
│   │   │   │   │   │   │       ├── test_code_executor.py
│   │   │   │   │   │   │       ├── test_e2b_direct.py
│   │   │   │   │   │   │       ├── test_e2b_lite.py
│   │   │   │   │   │   │       ├── test_extract_codeblocks.py
│   │   │   │   │   │   │       ├── test_sync_async_tools.py
│   │   │   │   │   │   │       ├── test_tool_call_timeout.py
│   │   │   │   │   │   │       └── test_variable_creation_order.py
│   │   │   │   │   │   ├── nl_auto_continue_classifier.py
│   │   │   │   │   │   ├── prompt_utils.py
│   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   ├── mcp_prompt.jinja2
│   │   │   │   │   │   │   └── shortlister/
│   │   │   │   │   │   │       ├── system.jinja2
│   │   │   │   │   │   │       └── user.jinja2
│   │   │   │   │   │   ├── reflection/
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── reflection_system.jinja2
│   │   │   │   │   │   │   │   └── reflection_user.jinja2
│   │   │   │   │   │   │   └── reflection.py
│   │   │   │   │   │   ├── tests/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── test_cuga_lite_graph_evolve_guidelines.py
│   │   │   │   │   │   │   ├── test_cuga_lite_node.py
│   │   │   │   │   │   │   └── test_tool_call_args.py
│   │   │   │   │   │   ├── tool_approval_handler.py
│   │   │   │   │   │   ├── tool_call_args.py
│   │   │   │   │   │   ├── tool_call_tracker.py
│   │   │   │   │   │   ├── tool_provider_interface.py
│   │   │   │   │   │   └── tool_registry_provider.py
│   │   │   │   │   ├── cuga_supervisor/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── a2a_protocol.py
│   │   │   │   │   │   ├── cuga_supervisor_graph.py
│   │   │   │   │   │   ├── cuga_supervisor_node.py
│   │   │   │   │   │   ├── cuga_supervisor_state.py
│   │   │   │   │   │   └── prompts/
│   │   │   │   │   │       └── supervisor_lite_prompt.jinja2
│   │   │   │   │   ├── human_in_the_loop/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── followup_model.py
│   │   │   │   │   │   ├── suggest_actions.py
│   │   │   │   │   │   └── wait_for_response.py
│   │   │   │   │   ├── save_reuse/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── save_reuse_agent/
│   │   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   │   ├── prompts/
│   │   │   │   │   │   │   │   ├── explainbility.jinja2
│   │   │   │   │   │   │   │   ├── explainbility_user.jinja2
│   │   │   │   │   │   │   │   ├── save_reuse.jinja2
│   │   │   │   │   │   │   │   └── save_reuse_user.jinja2
│   │   │   │   │   │   │   ├── reuse_agent.py
│   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │       ├── __init__.py
│   │   │   │   │   │   │       ├── export_mcp.py
│   │   │   │   │   │   │       └── save_reuse.py
│   │   │   │   │   │   └── save_reuse_node.py
│   │   │   │   │   ├── shared/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── base_agent.py
│   │   │   │   │   │   ├── base_node.py
│   │   │   │   │   │   ├── interrupt_tool_node.py
│   │   │   │   │   │   └── location_solver.py
│   │   │   │   │   └── task_decomposition_planning/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       ├── analyze_task.py
│   │   │   │   │       ├── location_resolver_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── google_search_agent.py
│   │   │   │   │       │   └── location_resolver_agent.py
│   │   │   │   │       ├── plan_controller.py
│   │   │   │   │       ├── plan_controller_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── plan_controller_agent.py
│   │   │   │   │       │   └── prompts/
│   │   │   │   │       │       ├── __init__.py
│   │   │   │   │       │       ├── example.json
│   │   │   │   │       │       ├── load_prompt.py
│   │   │   │   │       │       ├── system.jinja2
│   │   │   │   │       │       └── user.jinja2
│   │   │   │   │       ├── task_analyzer_agent/
│   │   │   │   │       │   ├── __init__.py
│   │   │   │   │       │   ├── prompts/
│   │   │   │   │       │   │   ├── __init__.py
│   │   │   │   │       │   │   └── load_prompt.py
│   │   │   │   │       │   ├── task_analyzer_agent.py
│   │   │   │   │       │   └── tasks/
│   │   │   │   │       │       ├── __init__.py
│   │   │   │   │       │       ├── app_matcher.py
│   │   │   │   │       │       ├── classify_task.py
│   │   │   │   │       │       ├── navigation_paths_task.py
│   │   │   │   │       │       ├── paraphrase.py
│   │   │   │   │       │       └── prompts/
│   │   │   │   │       │           ├── app_matcher_system.jinja2
│   │   │   │   │       │           ├── app_matcher_user.jinja2
│   │   │   │   │       │           ├── classify_task_system.jinja2
│   │   │   │   │       │           ├── classify_task_user.jinja2
│   │   │   │   │       │           ├── navigation_paths_system.jinja2
│   │   │   │   │       │           ├── navigation_paths_user.jinja2
│   │   │   │   │       │           ├── paraphrase_system.jinja2
│   │   │   │   │       │           ├── paraphrase_user.jinja2
│   │   │   │   │       │           └── sitemap_gitlab.json
│   │   │   │   │       ├── task_decomposition.py
│   │   │   │   │       └── task_decomposition_agent/
│   │   │   │   │           ├── __init__.py
│   │   │   │   │           ├── prompts/
│   │   │   │   │           │   ├── __init__.py
│   │   │   │   │           │   ├── load_prompt.py
│   │   │   │   │           │   ├── system.jinja2
│   │   │   │   │           │   ├── system_multi.jinja2
│   │   │   │   │           │   ├── user_msg.jinja2
│   │   │   │   │           │   └── user_multi.jinja2
│   │   │   │   │           ├── prompts_experiments/
│   │   │   │   │           │   ├── HighLevelPrompt.jinja
│   │   │   │   │           │   ├── Prompt.jinja
│   │   │   │   │           │   ├── Task Decomposition prompt json.jinja
│   │   │   │   │           │   ├── Task Decomposition prompt.jinja
│   │   │   │   │           │   ├── Task Decomposition prompts.txt
│   │   │   │   │           │   ├── Tests_Azure_4o-mini.txt
│   │   │   │   │           │   └── Tests_Azure_4o.txt
│   │   │   │   │           └── task_decomposition_agent.py
│   │   │   │   ├── policy/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── agent.py
│   │   │   │   │   ├── cli.py
│   │   │   │   │   ├── configurable.py
│   │   │   │   │   ├── enactment.py
│   │   │   │   │   ├── examples.py
│   │   │   │   │   ├── filesystem_sync.py
│   │   │   │   │   ├── folder_loader.py
│   │   │   │   │   ├── models.py
│   │   │   │   │   ├── output_formatter_utils.py
│   │   │   │   │   ├── storage.py
│   │   │   │   │   ├── tests/
│   │   │   │   │   │   ├── __init__.py
│   │   │   │   │   │   ├── helpers.py
│   │   │   │   │   │   ├── test_e2e_healthcare_family_claims.py
│   │   │   │   │   │   ├── test_e2e_intent_guard.py
│   │   │   │   │   │   ├── test_e2e_intent_guard_priority.py
│   │   │   │   │   │   ├── test_e2e_output_formatter.py
│   │   │   │   │   │   ├── test_e2e_playbook_guidance.py
│   │   │   │   │   │   ├── test_e2e_playbook_refinement.py
│   │   │   │   │   │   ├── test_e2e_tool_enrichment.py
│   │   │   │   │   │   ├── test_filesystem_sync.py
│   │   │   │   │   │   ├── test_keyword_operator.py
│   │   │   │   │   │   ├── test_nl_trigger_conflict_resolution.py
│   │   │   │   │   │   ├── test_similarity_integration.py
│   │   │   │   │   │   ├── test_tool_approval_full_graph.py
│   │   │   │   │   │   └── test_utils.py
│   │   │   │   │   └── utils.py
│   │   │   │   ├── state/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── agent_state.py
│   │   │   │   │   └── api_planner_history.py
│   │   │   │   └── utils/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── agent_loop.py
│   │   │   │       ├── context_management_utils.py
│   │   │   │       ├── context_summarizer.py
│   │   │   │       ├── controller.py
│   │   │   │       ├── event_porcessors/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   └── action_agent_event_processor.py
│   │   │   │       ├── message_utils.py
│   │   │   │       ├── nodes_names.py
│   │   │   │       └── token_counter.py
│   │   │   ├── evolve/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── integration.py
│   │   │   │   └── tests/
│   │   │   │       ├── __init__.py
│   │   │   │       ├── test_integration.py
│   │   │   │       └── test_launch_config.py
│   │   │   ├── knowledge/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── auth.py
│   │   │   │   ├── awareness.py
│   │   │   │   ├── client.py
│   │   │   │   ├── config.py
│   │   │   │   ├── engine.py
│   │   │   │   ├── interprocess_lock.py
│   │   │   │   ├── mcp_server.py
│   │   │   │   ├── metadata/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── postgres_store.py
│   │   │   │   │   └── sqlite_store.py
│   │   │   │   ├── routes.py
│   │   │   │   ├── session_provider.py
│   │   │   │   ├── shopping_admin/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── sitemap.txt
│   │   │   │   │   ├── sitemap_js.txt
│   │   │   │   │   └── sitemap_md.txt
│   │   │   │   ├── storage/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── adapter.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   ├── prod.py
│   │   │   │   │   └── schema.py
│   │   │   │   ├── vector_store.py
│   │   │   │   └── vector_store_base.py
│   │   │   ├── llm/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── config.py
│   │   │   │   ├── errors.py
│   │   │   │   ├── models.py
│   │   │   │   ├── rits/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── chat_rits_llm.py
│   │   │   │   │   └── rits_llm.py
│   │   │   │   └── utils/
│   │   │   │       ├── __init__.py
│   │   │   │       └── helpers.py
│   │   │   ├── observability/
│   │   │   │   ├── __init__.py
│   │   │   │   └── openlit_init.py
│   │   │   ├── secrets/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── backends/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── aws_backend.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── db_backend.py
│   │   │   │   │   ├── env_backend.py
│   │   │   │   │   └── vault_backend.py
│   │   │   │   ├── models.py
│   │   │   │   ├── secret_resolver.py
│   │   │   │   └── seed.py
│   │   │   ├── server/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── auth/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── dependencies.py
│   │   │   │   │   ├── issuer_allowlist.py
│   │   │   │   │   ├── jwt_validator.py
│   │   │   │   │   ├── models.py
│   │   │   │   │   └── oidc_client.py
│   │   │   │   ├── config_store.py
│   │   │   │   ├── conversation_history.py
│   │   │   │   ├── debug_server.py
│   │   │   │   ├── demo_manage_setup.py
│   │   │   │   ├── demo_setup_utils/
│   │   │   │   │   └── oak_policies.json
│   │   │   │   ├── event_stream_handler.py
│   │   │   │   ├── main.py
│   │   │   │   ├── manage_routes.py
│   │   │   │   ├── managed_mcp.py
│   │   │   │   ├── mcp_servers/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── cuga.py
│   │   │   │   │   └── tests/
│   │   │   │   │       └── __init__.py
│   │   │   │   ├── secrets_routes.py
│   │   │   │   └── server-manager.sh
│   │   │   ├── storage/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── embedding/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── embedding_service.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   ├── facade.py
│   │   │   │   ├── policy/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   ├── relational/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── base.py
│   │   │   │   │   ├── local.py
│   │   │   │   │   └── prod.py
│   │   │   │   └── secrets_store.py
│   │   │   ├── tools_env/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── code_sandbox/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── e2b_sandbox.py
│   │   │   │   │   ├── sandbox.py
│   │   │   │   │   └── tests/
│   │   │   │   │       ├── __init__.py
│   │   │   │   │       └── test_sandbox.py
│   │   │   │   └── registry/
│   │   │   │       ├── QUICKSTART.md
│   │   │   │       ├── README.md
│   │   │   │       ├── __init__.py
│   │   │   │       ├── config/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── config_loader.py
│   │   │   │       │   ├── mcp_servers.yaml
│   │   │   │       │   ├── mcp_servers_appworld.yaml
│   │   │   │       │   ├── mcp_servers_crm.yaml
│   │   │   │       │   ├── mcp_servers_hf.yaml
│   │   │   │       │   ├── mcp_servers_wxo.yaml
│   │   │   │       │   └── supervisor_demo_crm.yaml
│   │   │   │       ├── example_api_servers/
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   └── petstore.py
│   │   │   │       ├── mcp_manager/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── adapter.py
│   │   │   │       │   ├── mcp_manager.py
│   │   │   │       │   ├── openapi_parser.py
│   │   │   │       │   ├── openapi_parser_v0.py
│   │   │   │       │   ├── openapi_parser_v1.py
│   │   │   │       │   ├── response_schema.py
│   │   │   │       │   └── tests/
│   │   │   │       │       ├── __init__.py
│   │   │   │       │       ├── test_api_response.py
│   │   │   │       │       ├── test_array_handling.py
│   │   │   │       │       └── test_path_ext.py
│   │   │   │       ├── registry/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── api_registry.py
│   │   │   │       │   ├── api_registry_server.py
│   │   │   │       │   ├── authentication/
│   │   │   │       │   │   ├── __init__.py
│   │   │   │       │   │   ├── appworld_auth_manager.py
│   │   │   │       │   │   └── base_auth_manager.py
│   │   │   │       │   └── test_naming_strategy_e2e.py
│   │   │   │       ├── tests/
│   │   │   │       │   ├── README.md
│   │   │   │       │   ├── __init__.py
│   │   │   │       │   ├── config/
│   │   │   │       │   │   └── mcp_servers_test.yaml
│   │   │   │       │   ├── data/
│   │   │   │       │   │   └── schemas/
│   │   │   │       │   │       └── openapi_nested.yaml
│   │   │   │       │   ├── e2e_helpers.py
│   │   │   │       │   ├── output_schema_server.py
│   │   │   │       │   ├── run_all_tests.py
│   │   │   │       │   ├── test_agent_registry_loading.py
│   │   │   │       │   ├── test_api_registry_error_handling.py
│   │   │   │       │   ├── test_auth/
│   │   │   │       │   │   ├── README.md
│   │   │   │       │   │   ├── __init__.py
│   │   │   │       │   │   ├── auth_server.py
│   │   │   │       │   │   ├── mcp_servers_auth_test.yaml
│   │   │   │       │   │   ├── test_apply_authentication.py
│   │   │   │       │   │   └── test_auth_e2e.py
│   │   │   │       │   ├── test_e2e_api_registry.py
│   │   │   │       │   ├── test_enum_handling.py
│   │   │   │       │   ├── test_legacy_openapi.py
│   │   │   │       │   ├── test_mcp_server.py
│   │   │   │       │   ├── test_mixed_configuration.py
│   │   │   │       │   └── test_output_schema.py
│   │   │   │       └── utils/
│   │   │   │           ├── __init__.py
│   │   │   │           ├── api_utils.py
│   │   │   │           └── types.py
│   │   │   └── utils/
│   │   │       ├── __init__.py
│   │   │       ├── code_generator.py
│   │   │       ├── consts.py
│   │   │       ├── file_utils.py
│   │   │       └── id_utils.py
│   │   ├── cli/
│   │   │   ├── __init__.py
│   │   │   ├── app_manager.py
│   │   │   └── main.py
│   │   ├── config.py
│   │   ├── configurations/
│   │   │   ├── instructions/
│   │   │   │   ├── default/
│   │   │   │   │   ├── answer.md
│   │   │   │   │   ├── api_code_planner.md
│   │   │   │   │   ├── api_planner.md
│   │   │   │   │   ├── code_agent.md
│   │   │   │   │   ├── plan_controller.md
│   │   │   │   │   ├── reflection.md
│   │   │   │   │   ├── shortlister.md
│   │   │   │   │   └── task_decomposition.md
│   │   │   │   └── instructions.toml
│   │   │   ├── instructions_manager.py
│   │   │   ├── knowledge/
│   │   │   │   ├── knowledge_instructions.md
│   │   │   │   ├── knowledge_profiles/
│   │   │   │   │   ├── balanced.toml
│   │   │   │   │   ├── max_quality.toml
│   │   │   │   │   ├── speed.toml
│   │   │   │   │   └── standard.toml
│   │   │   │   └── knowledge_settings.toml
│   │   │   ├── memory/
│   │   │   │   ├── memory_settings.mem0.toml
│   │   │   │   ├── memory_settings.milvus.toml
│   │   │   │   └── memory_settings.tips_extractor.toml
│   │   │   ├── models/
│   │   │   │   ├── settings.azure.toml
│   │   │   │   ├── settings.google.toml
│   │   │   │   ├── settings.groq.toml
│   │   │   │   ├── settings.litellm.toml
│   │   │   │   ├── settings.openai.toml
│   │   │   │   ├── settings.openrouter.toml
│   │   │   │   ├── settings.rits.toml
│   │   │   │   └── settings.watsonx.toml
│   │   │   ├── modes/
│   │   │   │   ├── accurate.toml
│   │   │   │   ├── balanced.toml
│   │   │   │   ├── custom.toml
│   │   │   │   ├── fast.toml
│   │   │   │   └── save_reuse_fast.toml
│   │   │   └── set_from_one_file.py
│   │   ├── demo_tools/
│   │   │   ├── __init__.py
│   │   │   ├── crm/
│   │   │   │   ├── .gitignore
│   │   │   │   ├── LICENSE
│   │   │   │   ├── MANIFEST.in
│   │   │   │   ├── README.md
│   │   │   │   ├── __init__.py
│   │   │   │   ├── crm_api/
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── accounts.py
│   │   │   │   │   ├── contacts.py
│   │   │   │   │   ├── crud.py
│   │   │   │   │   ├── database.py
│   │   │   │   │   ├── leads.py
│   │   │   │   │   ├── main.py
│   │   │   │   │   ├── opportunities.py
│   │   │   │   │   ├── run_all.py
│   │   │   │   │   ├── schemas.py
│   │   │   │   │   ├── seed_data.py
│   │   │   │   │   └── wrap_as_mcp.py
│   │   │   │   ├── pytest.ini
│   │   │   │   ├── run.py
│   │   │   │   ├── run_tests.py
│   │   │   │   ├── tests/
│   │   │   │   │   ├── conftest.py
│   │   │   │   │   ├── test_contacts.py
│   │   │   │   │   └── test_workspace_workflow.py
│   │   │   │   └── wrap_as_mcp.py
│   │   │   ├── docs_mcp/
│   │   │   │   └── docs_mcp_server.py
│   │   │   ├── email_mcp/
│   │   │   │   ├── mail_sink/
│   │   │   │   │   ├── .gitignore
│   │   │   │   │   └── server.py
│   │   │   │   └── mcp_server/
│   │   │   │       ├── server.py
│   │   │   │       └── utils.py
│   │   │   ├── file_system/
│   │   │   │   └── main.py
│   │   │   ├── health/
│   │   │   │   └── README.md
│   │   │   └── huggingface/
│   │   │       ├── contacts.txt
│   │   │       ├── cuga_knowledge.md
│   │   │       ├── cuga_playbook.md
│   │   │       └── email_template.md
│   │   ├── evaluation/
│   │   │   ├── README.md
│   │   │   ├── calculate_test_score.py
│   │   │   ├── evaluate_cuga.py
│   │   │   └── langfuse/
│   │   │       └── get_langfuse_data.py
│   │   ├── frontend/
│   │   │   └── dist/
│   │   │       ├── background.js
│   │   │       ├── index.html
│   │   │       ├── main.fbff5b207d7495606137.js
│   │   │       ├── manifest.json
│   │   │       ├── tailwind.js
│   │   │       └── vendors.89d8d26b14ea275079ad.js
│   │   ├── sdk.py
│   │   ├── sdk_core/
│   │   │   └── tests/
│   │   │       ├── conversation_messages.json
│   │   │       ├── fixtures/
│   │   │       │   └── supervisor_config.yaml
│   │   │       ├── policies-export-2025-12-31.json
│   │   │       ├── test_context_summarization_sdk.py
│   │   │       ├── test_policy_loading_and_matching.py
│   │   │       ├── test_policy_reset_and_reload.py
│   │   │       ├── test_sdk_integration.py
│   │   │       ├── test_sdk_policies.py
│   │   │       ├── test_supervisor_advanced.py
│   │   │       └── test_supervisor_yaml_config.py
│   │   ├── settings.toml
│   │   └── supervisor_utils/
│   │       ├── __init__.py
│   │       └── supervisor_config.py
│   ├── frontend_workspaces/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── agentic_chat/
│   │   │   ├── global.d.ts
│   │   │   ├── package.json
│   │   │   ├── public/
│   │   │   │   └── fake_data.json
│   │   │   ├── src/
│   │   │   │   ├── AdvancedTourButton.css
│   │   │   │   ├── AdvancedTourButton.tsx
│   │   │   │   ├── AgentBehaviorConfig.tsx
│   │   │   │   ├── AgentHumanConfig.tsx
│   │   │   │   ├── App.tsx
│   │   │   │   ├── AppLayout.css
│   │   │   │   ├── CardManager.css
│   │   │   │   ├── CardManager.tsx
│   │   │   │   ├── ConfigHeader.css
│   │   │   │   ├── ConfigHeader.tsx
│   │   │   │   ├── ConfigModal.css
│   │   │   │   ├── CugaHeader.tsx
│   │   │   │   ├── CustomChat.css
│   │   │   │   ├── CustomChat.tsx
│   │   │   │   ├── CustomResponseStyles.css
│   │   │   │   ├── DebugPanel.css
│   │   │   │   ├── DebugPanel.tsx
│   │   │   │   ├── FileAutocomplete.css
│   │   │   │   ├── FileAutocomplete.tsx
│   │   │   │   ├── Followup.tsx
│   │   │   │   ├── FollowupSuggestions.css
│   │   │   │   ├── FollowupSuggestions.tsx
│   │   │   │   ├── GuidedTour.css
│   │   │   │   ├── GuidedTour.tsx
│   │   │   │   ├── KnowledgeConfig.tsx
│   │   │   │   ├── KnowledgePanel.tsx
│   │   │   │   ├── KnowledgeSidePanel.css
│   │   │   │   ├── KnowledgeSidePanel.tsx
│   │   │   │   ├── LeftSidebar.css
│   │   │   │   ├── LeftSidebar.tsx
│   │   │   │   ├── MemoryConfig.tsx
│   │   │   │   ├── ModelConfig.tsx
│   │   │   │   ├── PoliciesConfig.tsx
│   │   │   │   ├── PolicyBlockComponent.css
│   │   │   │   ├── PolicyBlockComponent.tsx
│   │   │   │   ├── PolicyPlaybookComponent.css
│   │   │   │   ├── PolicyPlaybookComponent.tsx
│   │   │   │   ├── SessionAttachments.tsx
│   │   │   │   ├── StatusBar.css
│   │   │   │   ├── StatusBar.tsx
│   │   │   │   ├── StreamManager.tsx
│   │   │   │   ├── StreamingManager.ts
│   │   │   │   ├── StreamingWorkflow.ts
│   │   │   │   ├── SubAgentsConfig.tsx
│   │   │   │   ├── ToolReview.tsx
│   │   │   │   ├── ToolsConfig.tsx
│   │   │   │   ├── VariablePopup.css
│   │   │   │   ├── VariablePopup.tsx
│   │   │   │   ├── VariablesSidebar.css
│   │   │   │   ├── VariablesSidebar.tsx
│   │   │   │   ├── WorkspacePanel.css
│   │   │   │   ├── WorkspacePanel.tsx
│   │   │   │   ├── WriteableElementExample.css
│   │   │   │   ├── action_agent.tsx
│   │   │   │   ├── action_status_component.tsx
│   │   │   │   ├── app_analyzer_component.tsx
│   │   │   │   ├── coder_agent_output.tsx
│   │   │   │   ├── constants.ts
│   │   │   │   ├── customSendMessage.ts
│   │   │   │   ├── exampleUtterances.ts
│   │   │   │   ├── final_answer_component.tsx
│   │   │   │   ├── floating/
│   │   │   │   │   └── stop_button.tsx
│   │   │   │   ├── generic_component.tsx
│   │   │   │   ├── mockApi.ts
│   │   │   │   ├── qa_agent.tsx
│   │   │   │   ├── renderUserDefinedResponse.tsx
│   │   │   │   ├── shortlister.tsx
│   │   │   │   ├── task_decomposition.tsx
│   │   │   │   ├── task_status_component.tsx
│   │   │   │   ├── useTour.ts
│   │   │   │   ├── useWorkspaceTree.ts
│   │   │   │   ├── uuid.ts
│   │   │   │   ├── workspaceService.ts
│   │   │   │   └── workspaceThrottle.ts
│   │   │   ├── tsconfig.app.json
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── extension/
│   │   │   ├── .editorconfig
│   │   │   ├── .gitignore
│   │   │   ├── constants.ts
│   │   │   ├── package.json
│   │   │   ├── playwright.config.ts
│   │   │   ├── readme.md
│   │   │   ├── releases/
│   │   │   │   └── chrome-mv3/
│   │   │   │       ├── assets/
│   │   │   │       │   └── sidepanel-Bm0DOHi9.css
│   │   │   │       ├── background.js
│   │   │   │       ├── chunks/
│   │   │   │       │   ├── DailyMotion-Mu-1s4ir.js
│   │   │   │       │   ├── Facebook-CbG0_jez.js
│   │   │   │       │   ├── FilePlayer-CYjbWbG8.js
│   │   │   │       │   ├── Kaltura-BDM2l5do.js
│   │   │   │       │   ├── Mixcloud-jUDy-IoK.js
│   │   │   │       │   ├── Mux-BSWrBpZP.js
│   │   │   │       │   ├── Preview-of7xUcD9.js
│   │   │   │       │   ├── SoundCloud-C1q3o5ey.js
│   │   │   │       │   ├── Streamable-BsCvFyja.js
│   │   │   │       │   ├── Twitch-K5Lc2N4C.js
│   │   │   │       │   ├── Vidyard-N6MhfVze.js
│   │   │   │       │   ├── Vimeo-C2ru3W0B.js
│   │   │   │       │   ├── Wistia-DBD0XvkL.js
│   │   │   │       │   ├── YouTube-8naRW_9O.js
│   │   │   │       │   ├── ar-BqPjhJxT.js
│   │   │   │       │   ├── ar-dz-DyZwJqCp.js
│   │   │   │       │   ├── ar-kw-0W-ym3nk.js
│   │   │   │       │   ├── ar-ly-1r7VuSmV.js
│   │   │   │       │   ├── ar-ma-C8a5fRTZ.js
│   │   │   │       │   ├── ar-sa-LX3Zlta0.js
│   │   │   │       │   ├── ar-tn-9PwKM2NI.js
│   │   │   │       │   ├── chat.export-Civ2zEoT.js
│   │   │   │       │   ├── chat.export.carbon-x9hVoQbk.js
│   │   │   │       │   ├── common-D6sVSfnG.js
│   │   │   │       │   ├── cs-C9atpGa0.js
│   │   │   │       │   ├── de-DTzGRoiG.js
│   │   │   │       │   ├── de-at-DM5xnk44.js
│   │   │   │       │   ├── de-ch-C9PZsiWh.js
│   │   │   │       │   ├── en-au-DKKQ7o_a.js
│   │   │   │       │   ├── en-ca-Bsp7ASfx.js
│   │   │   │       │   ├── en-gb-BZNi8AbR.js
│   │   │   │       │   ├── en-ie-DvDRqUel.js
│   │   │   │       │   ├── en-il-DPvmOO-u.js
│   │   │   │       │   ├── en-nz-CLOrpKu9.js
│   │   │   │       │   ├── es-_25F1VNE.js
│   │   │   │       │   ├── es-do-3T87tC4C.js
│   │   │   │       │   ├── es-us-BfRgSno2.js
│   │   │   │       │   ├── fr-C2PP_RDY.js
│   │   │   │       │   ├── fr-ca-l2g_8cqb.js
│   │   │   │       │   ├── fr-ch-Cj9LWtf4.js
│   │   │   │       │   ├── index-7KKzZJbI.js
│   │   │   │       │   ├── index-B9FHQ1q8.js
│   │   │   │       │   ├── index-aSW4scoW.js
│   │   │   │       │   ├── it-BmAWTxOq.js
│   │   │   │       │   ├── it-ch-CqrZ_w7Y.js
│   │   │   │       │   ├── ja-bDUE5UJb.js
│   │   │   │       │   ├── ko-BS2Hu1tA.js
│   │   │   │       │   ├── nl-Bgmo7MMX.js
│   │   │   │       │   ├── pt-DwX7O4_L.js
│   │   │   │       │   ├── pt-br-Gzdc6c2B.js
│   │   │   │       │   ├── sidepanel-DjwwbR2c.js
│   │   │   │       │   ├── swiper-react-1kjVGWrh.js
│   │   │   │       │   ├── sync-D0xm7If2.js
│   │   │   │       │   ├── utils-D71RtZIR.js
│   │   │   │       │   ├── zh-cn-BoLpJCZk.js
│   │   │   │       │   └── zh-tw-Ck9WD2i8.js
│   │   │   │       ├── content-scripts/
│   │   │   │       │   └── content.js
│   │   │   │       ├── fonts/
│   │   │   │       │   └── IBM-Plex-Sans/
│   │   │   │       │       └── fonts/
│   │   │   │       │           ├── complete/
│   │   │   │       │           │   ├── woff/
│   │   │   │       │           │   │   └── license.txt
│   │   │   │       │           │   └── woff2/
│   │   │   │       │           │       └── license.txt
│   │   │   │       │           └── split/
│   │   │   │       │               ├── woff/
│   │   │   │       │               │   ├── IBMPlexSans-Bold.css
│   │   │   │       │               │   ├── IBMPlexSans-BoldItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-ExtraLight.css
│   │   │   │       │               │   ├── IBMPlexSans-ExtraLightItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Italic.css
│   │   │   │       │               │   ├── IBMPlexSans-Light.css
│   │   │   │       │               │   ├── IBMPlexSans-LightItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Medium.css
│   │   │   │       │               │   ├── IBMPlexSans-MediumItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Regular.css
│   │   │   │       │               │   ├── IBMPlexSans-SemiBold.css
│   │   │   │       │               │   ├── IBMPlexSans-SemiBoldItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Text.css
│   │   │   │       │               │   ├── IBMPlexSans-TextItalic.css
│   │   │   │       │               │   ├── IBMPlexSans-Thin.css
│   │   │   │       │               │   ├── IBMPlexSans-ThinItalic.css
│   │   │   │       │               │   └── license.txt
│   │   │   │       │               └── woff2/
│   │   │   │       │                   ├── IBMPlexSans-Bold.css
│   │   │   │       │                   ├── IBMPlexSans-BoldItalic.css
│   │   │   │       │                   ├── IBMPlexSans-ExtraLight.css
│   │   │   │       │                   ├── IBMPlexSans-ExtraLightItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Italic.css
│   │   │   │       │                   ├── IBMPlexSans-Light.css
│   │   │   │       │                   ├── IBMPlexSans-LightItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Medium.css
│   │   │   │       │                   ├── IBMPlexSans-MediumItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Regular.css
│   │   │   │       │                   ├── IBMPlexSans-SemiBold.css
│   │   │   │       │                   ├── IBMPlexSans-SemiBoldItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Text.css
│   │   │   │       │                   ├── IBMPlexSans-TextItalic.css
│   │   │   │       │                   ├── IBMPlexSans-Thin.css
│   │   │   │       │                   ├── IBMPlexSans-ThinItalic.css
│   │   │   │       │                   └── license.txt
│   │   │   │       ├── manifest.json
│   │   │   │       └── sidepanel.html
│   │   │   ├── src/
│   │   │   │   ├── content/
│   │   │   │   │   ├── frame.mark.elements.ts
│   │   │   │   │   ├── page_analysis/
│   │   │   │   │   │   ├── CachedXPathBuilder.ts
│   │   │   │   │   │   ├── DomCache.ts
│   │   │   │   │   │   ├── DomTree.ts
│   │   │   │   │   │   ├── ElementHighlighter.ts
│   │   │   │   │   │   ├── NodeElementCollector.ts
│   │   │   │   │   │   ├── NodeHelper.ts
│   │   │   │   │   │   ├── PageHighlighter.ts
│   │   │   │   │   │   ├── constants.ts
│   │   │   │   │   │   ├── dom_tree_module.ts
│   │   │   │   │   │   └── types.d.ts
│   │   │   │   │   └── worker.connection.ts
│   │   │   │   ├── entrypoints/
│   │   │   │   │   ├── background.ts
│   │   │   │   │   ├── content.tsx
│   │   │   │   │   └── sidepanel/
│   │   │   │   │       ├── index.html
│   │   │   │   │       ├── sidepanel.css
│   │   │   │   │       ├── sidepanel.tsx
│   │   │   │   │       └── tailwind.js
│   │   │   │   ├── functions.ts
│   │   │   │   ├── manifest.chrome.json
│   │   │   │   ├── manifest.firefox.json
│   │   │   │   ├── symbol.dispose.polyfill.js
│   │   │   │   ├── vite-env.d.ts
│   │   │   │   └── worker/
│   │   │   │       ├── http.stream.module.ts
│   │   │   │       ├── index.ts
│   │   │   │       └── sidepanel.module.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   ├── vite.config.ts
│   │   │   └── wxt.config.ts
│   │   ├── frontend/
│   │   │   ├── .babelrc
│   │   │   ├── OPTIMIZATION_SUMMARY.md
│   │   │   ├── analyze-bundle.sh
│   │   │   ├── build.sh
│   │   │   ├── electron_loader/
│   │   │   │   ├── main.js
│   │   │   │   └── preload.js
│   │   │   ├── index.html
│   │   │   ├── main.js
│   │   │   ├── package.json
│   │   │   ├── src/
│   │   │   │   ├── AddToolModal.css
│   │   │   │   ├── AddToolModal.tsx
│   │   │   │   ├── App.tsx
│   │   │   │   ├── AuthContext.tsx
│   │   │   │   ├── ChatLanding.css
│   │   │   │   ├── ChatLanding.tsx
│   │   │   │   ├── ConfigHeader.tsx
│   │   │   │   ├── CugaHeader.css
│   │   │   │   ├── CugaHeader.tsx
│   │   │   │   ├── ManageDashboard.css
│   │   │   │   ├── ManageDashboard.tsx
│   │   │   │   ├── ManagePage.css
│   │   │   │   ├── ManagePage.tsx
│   │   │   │   ├── SecretsManager.tsx
│   │   │   │   ├── ToolsConfig.css
│   │   │   │   ├── ToolsConfig.tsx
│   │   │   │   ├── UnauthorizedPage.tsx
│   │   │   │   ├── api.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── carbon-chat/
│   │   │   │   │   ├── CarbonChat.css
│   │   │   │   │   ├── CarbonChat.tsx
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── carbonChatHelpers.ts
│   │   │   │   │   ├── customLoadHistory.ts
│   │   │   │   │   ├── customSendMessage.ts
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   └── scenarios.ts
│   │   │   │   ├── carbon.scss
│   │   │   │   ├── global.css
│   │   │   │   ├── knowledge/
│   │   │   │   │   └── useSessionKnowledgeAttachments.ts
│   │   │   │   └── types/
│   │   │   │       └── tools.ts
│   │   │   ├── static/
│   │   │   │   ├── background.js
│   │   │   │   ├── fake_data.json
│   │   │   │   ├── manifest.json
│   │   │   │   └── tailwind.js
│   │   │   ├── tsconfig.json
│   │   │   └── webpack.config.js
│   │   ├── package.json
│   │   ├── pnpm-workspace.yaml
│   │   ├── runtime/
│   │   │   ├── .eslintrc
│   │   │   ├── .gitignore
│   │   │   ├── commands.ts
│   │   │   ├── functions.ts
│   │   │   ├── index.ts
│   │   │   ├── package.json
│   │   │   ├── responses.ts
│   │   │   └── tsconfig.json
│   │   └── shared/
│   │       ├── .gitignore
│   │       ├── README.md
│   │       ├── package.json
│   │       ├── src/
│   │       │   ├── constants/
│   │       │   │   ├── constants.ts
│   │       │   │   └── index.ts
│   │       │   ├── index.ts
│   │       │   ├── types/
│   │       │   │   ├── index.ts
│   │       │   │   └── sidepanel.ts
│   │       │   └── utils/
│   │       │       ├── index.ts
│   │       │       └── utils.ts
│   │       └── tsconfig.json
│   ├── scripts/
│   │   ├── __init__.py
│   │   ├── build_embedded.py
│   │   ├── build_standalone.py
│   │   ├── commands.py
│   │   ├── create_e2b_template.py
│   │   ├── draw_graph.py
│   │   ├── embed_assets.py
│   │   ├── graph_visualization/
│   │   │   ├── graph.html
│   │   │   └── graph.json
│   │   ├── preload_models.py
│   │   ├── push-to-hf.sh
│   │   ├── run_e2b_test.py
│   │   ├── run_tests.sh
│   │   └── test_e2b_ngrok.py
│   └── system_tests/
│       ├── e2e/
│       │   ├── accurate_test.py
│       │   ├── balanced_test.py
│       │   ├── base_crm_test.py
│       │   ├── base_test.py
│       │   ├── calculator_tool.py
│       │   ├── config/
│       │   │   ├── mcp_servers.yaml
│       │   │   ├── mcp_servers_crm.yaml
│       │   │   └── mcp_servers_crm_hf.yaml
│       │   ├── conftest.py
│       │   ├── crm_contacts_email_balanced_test.py
│       │   ├── crm_contacts_email_test.py
│       │   ├── crm_contacts_email_test_find_tools.py
│       │   ├── crm_followup_test.py
│       │   ├── crm_hf_utterances_test.py
│       │   ├── digital_sales_test_helpers.py
│       │   ├── fast_test.py
│       │   ├── load_test.py
│       │   ├── run_registry.sh
│       │   ├── save_reuse_test.py
│       │   ├── stability_test_config.toml
│       │   ├── test_context_summarization_e2e.py
│       │   └── test_long_output.py
│       ├── profiling/
│       │   ├── .gitignore
│       │   ├── CHANGELOG.md
│       │   ├── QUICK_START.md
│       │   ├── README.md
│       │   ├── bin/
│       │   │   ├── profile_digital_sales_tasks.py
│       │   │   ├── run_experiment.sh
│       │   │   └── run_profiling.sh
│       │   ├── config/
│       │   │   ├── default_experiment.yaml
│       │   │   ├── env_variables_example.yaml
│       │   │   ├── fast_vs_accurate.yaml
│       │   │   ├── full_matrix_comparison.yaml
│       │   │   └── providers_comparison.yaml
│       │   ├── experiments/
│       │   │   └── comparison.html
│       │   ├── run_experiment.sh
│       │   └── serve.sh
│       └── unit/
│           ├── __init__.py
│           └── test_sandbox_local.py
├── tests/
│   ├── integration/
│   │   ├── __init__.py
│   │   ├── test_context_summarization.py
│   │   ├── test_knowledge_integration.py
│   │   ├── test_llm_config_publish.py
│   │   └── test_tool_call_tracking.py
│   ├── system/
│   │   ├── README.md
│   │   └── test_manager_api_integration.py
│   ├── test_agent_tools_api.py
│   ├── test_conversation_history.py
│   ├── test_variables_manager_langgraph.py
│   ├── test_variables_manager_with_state.py
│   └── unit/
│       ├── test_chat_agent_knowledge_toggle.py
│       ├── test_chat_knowledge_mode.py
│       ├── test_context_summarizer.py
│       ├── test_cuga_lite_knowledge_scopes.py
│       ├── test_find_tools_exception.py
│       ├── test_knowledge_engine.py
│       ├── test_knowledge_manage_gate.py
│       ├── test_knowledge_routes.py
│       ├── test_knowledge_storage_vector.py
│       ├── test_llm_override.py
│       ├── test_manage_publish_sync.py
│       ├── test_plan_controller_prompt.py
│       ├── test_session_knowledge.py
│       ├── test_token_counter.py
│       └── test_tool_use_failed_recovery.py
└── todos.md
Download .txt
Showing preview only (4,354K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (16689 symbols across 528 files)

FILE: docs/examples/cuga_as_mcp/main.py
  function run_api_task (line 16) | async def run_api_task(task: str) -> str:
  function run_web_task (line 33) | async def run_web_task(task: str, start_url: str) -> str:
  function run_hybrid_task (line 58) | async def run_hybrid_task(task: str, start_url: str) -> str:
  function main (line 82) | def main():

FILE: docs/examples/cuga_with_runtime_tools/fast_mcp_example.py
  function customize_components (line 22) | def customize_components(
  function create_mcp_server (line 38) | def create_mcp_server() -> FastMCP:
  function main (line 61) | def main():

FILE: docs/examples/cuga_with_runtime_tools/langchain_example_tool.py
  class Email (line 8) | class Email(BaseModel):
  class EmailsResponse (line 20) | class EmailsResponse(BaseModel):
  class SendEmailRequest (line 27) | class SendEmailRequest(BaseModel):
  class SendEmailResponse (line 35) | class SendEmailResponse(BaseModel):
  function read_emails (line 84) | def read_emails(limit: int = 10, unread_only: bool = False) -> EmailsRes...
  function send_email (line 100) | def send_email(recipient: str, subject: str, body: str) -> SendEmailResp...

FILE: docs/examples/cuga_with_runtime_tools/main.py
  function run_task (line 24) | async def run_task(task: str) -> AgentResult:
  function perform_task (line 38) | async def perform_task(task: str) -> str:
  function main (line 47) | async def main():

FILE: docs/examples/demo_apps/setup/cli.py
  class Colors (line 20) | class Colors:
  function _default_demo_tools_root (line 36) | def _default_demo_tools_root() -> Path:
  function cleanup (line 43) | def cleanup():
  function signal_handler (line 61) | def signal_handler(sig, frame):
  function print_header (line 71) | def print_header():
  function print_step (line 87) | def print_step(step_num: int, total: int, message: str):
  function print_success (line 92) | def print_success(message: str):
  function print_error (line 97) | def print_error(message: str):
  function print_warning (line 102) | def print_warning(message: str):
  function print_info (line 107) | def print_info(message: str):
  function is_port_in_use (line 112) | def is_port_in_use(port: int) -> Optional[Tuple[int, str]]:
  function kill_process (line 169) | def kill_process(pid: int) -> bool:
  function check_and_handle_ports (line 207) | def check_and_handle_ports(include_email: bool = False) -> bool:
  function check_prerequisites (line 269) | def check_prerequisites() -> bool:
  function create_workspace (line 324) | def create_workspace(base_path: Optional[str] = None) -> Path:
  function create_contacts_file (line 343) | def create_contacts_file(workspace: Path):
  function start_filesystem_server (line 365) | def start_filesystem_server(
  function start_crm_server (line 428) | def start_crm_server(
  function start_email_sink (line 488) | def start_email_sink(
  function start_email_server (line 548) | def start_email_server(
  function print_configuration_info (line 615) | def print_configuration_info(workspace: Path, include_email: bool = False):
  function monitor_servers (line 685) | def monitor_servers():
  function main (line 770) | def main():

FILE: docs/examples/digital_sales_openapi/main.py
  class Account (line 10) | class Account(BaseModel):
  class JobTitle (line 20) | class JobTitle(BaseModel):
  class Contact (line 26) | class Contact(BaseModel):
  class MyAccountsOutput (line 36) | class MyAccountsOutput(BaseModel):
  class AccountsOutput (line 44) | class AccountsOutput(BaseModel):
  class JobTitlesOutput (line 50) | class JobTitlesOutput(BaseModel):
  class ContactsOutput (line 56) | class ContactsOutput(BaseModel):
  function get_my_accounts (line 231) | async def get_my_accounts():
  function get_third_party_accounts (line 247) | async def get_third_party_accounts(
  function get_job_titles_by_account (line 275) | async def get_job_titles_by_account(account_id: str = Path(..., title="T...
  function get_contacts (line 292) | async def get_contacts(

FILE: run_stability_tests.py
  class PortManager (line 52) | class PortManager:
    method __init__ (line 55) | def __init__(self):
    method get_free_port (line 59) | def get_free_port(self):
    method allocate_ports (line 73) | def allocate_ports(self):
  function run_command (line 84) | def run_command(cmd, cwd=None, capture_output=False, check=True, env=None):
  function check_image_exists (line 105) | def check_image_exists(image_name):
  function build_image (line 115) | def build_image():
  function run_docker_test (line 123) | def run_docker_test(test_full_path, run_timestamp):
  function kill_process_on_port (line 175) | def kill_process_on_port(port):
  function cleanup_ports (line 267) | def cleanup_ports(env_ports):
  function run_local_test (line 282) | def run_local_test(test_full_path, run_timestamp, e2b_mode=False):
  function run_test_wrapper (line 328) | def run_test_wrapper(method, test_full_path, run_timestamp, e2b_mode=Fal...
  function generate_summary_report (line 335) | def generate_summary_report(results_dir: str = "test-results"):
  function main (line 507) | def main():

FILE: src/cuga/backend/activity_tracker/join_tool.py
  function assign_applications (line 6) | def assign_applications(tools) -> List[AppDefinition]:

FILE: src/cuga/backend/activity_tracker/render_helper.py
  function get_render_action (line 31) | def get_render_action(
  function print_keys (line 41) | def print_keys(obj):
  class RenderHelper (line 54) | class RenderHelper(object):
    method __init__ (line 57) | def __init__(self, config_file: str, result_dir: str, light_version: b...
    method render (line 70) | def render(
    method close (line 152) | def close(self) -> None:

FILE: src/cuga/backend/activity_tracker/tracker.py
  class MergeResult (line 31) | class MergeResult(BaseModel):
  class Prompt (line 36) | class Prompt(BaseModel):
  class Step (line 41) | class Step(BaseModel):
  class TasksMetadata (line 55) | class TasksMetadata(BaseModel):
  class ActivityTracker (line 63) | class ActivityTracker(object):
    method __new__ (line 91) | def __new__(cls, *args, **kwargs):
    method invoke_tool (line 96) | async def invoke_tool(self, server_name: str, tool_name: str, args: di...
    method invoke_tool_sync (line 131) | def invoke_tool_sync(self, server_name: str, tool_name: str, args: dict):
    method get_tools_by_server (line 205) | def get_tools_by_server(self, server_name: str) -> Dict[str, Dict]:
    method set_tools (line 227) | def set_tools(self, tools: List[StructuredTool]):
    method set_base_dir (line 332) | def set_base_dir(self, base_dir: str) -> None:
    method get_base_dir (line 342) | def get_base_dir(self) -> str:
    method get_current_trajectory_path (line 351) | def get_current_trajectory_path(self) -> Optional[str]:
    method generate_session_id (line 362) | def generate_session_id(self):
    method generate_run_id (line 365) | def generate_run_id(self):
    method reset (line 368) | def reset(self, intent, task_id="default"):
    method reload_steps (line 383) | def reload_steps(self, task_id: Optional[str] = None) -> bool:
    method start_experiment (line 443) | def start_experiment(
    method _initialize_experiment_files (line 487) | def _initialize_experiment_files(self, experiment_dir: str) -> None:
    method collect_prompt (line 518) | def collect_prompt(self, role: str, value: str):
    method collect_tokens_usage (line 521) | def collect_tokens_usage(self, count: int) -> None:
    method collect_image (line 530) | def collect_image(self, img: str) -> None:
    method collect_step (line 540) | def collect_step(self, step: Step) -> None:
    method collect_step_external (line 644) | def collect_step_external(self, step: Step, full_path: Optional[str] =...
    method _to_file_external_append (line 683) | def _to_file_external_append(self, full_path: str, new_step: Step):
    method collect_score (line 749) | def collect_score(self, score: float) -> None:
    method collect_step_with_pass (line 760) | def collect_step_with_pass(self) -> None:
    method to_file (line 766) | def to_file(self):
    method finish_task (line 796) | def finish_task(
    method _update_result_files (line 863) | def _update_result_files(self) -> None:
    method _save_csv (line 878) | def _save_csv(self, experiment_dir: str) -> None:
    method _add_to_progress_file (line 921) | def _add_to_progress_file(self, task_id: str) -> None:
    method update_task (line 930) | def update_task(
    method remove_task (line 988) | def remove_task(self, task_id: str) -> bool:
    method get_task (line 1005) | def get_task(self, task_id: str) -> Optional[Dict[str, Any]]:
    method get_all_tasks (line 1017) | def get_all_tasks(self) -> Dict[str, Dict[str, Any]]:
    method find_tasks_by_score (line 1026) | def find_tasks_by_score(self, score: float) -> Dict[str, Dict[str, Any]]:
    method find_tasks_by_site (line 1038) | def find_tasks_by_site(self, site: str) -> Dict[str, Dict[str, Any]]:
    method find_tasks_by_exception (line 1050) | def find_tasks_by_exception(self, exception: bool) -> Dict[str, Dict[s...
    method find_tasks_by_agent_version (line 1062) | def find_tasks_by_agent_version(self, agent_v: str) -> Dict[str, Dict[...
    method clear_all_tasks (line 1074) | def clear_all_tasks(self) -> None:
    method get_task_count (line 1084) | def get_task_count(self) -> int:
    method get_statistics (line 1093) | def get_statistics(self) -> Dict[str, Any]:
    method get_dataframe (line 1122) | def get_dataframe(self) -> pd.DataFrame:
    method _copy_task_json_files (line 1154) | def _copy_task_json_files(
    method merge_experiments (line 1206) | def merge_experiments(
    method list_experiment_folders (line 1336) | def list_experiment_folders(self, base_path: Optional[str] = None) -> ...
    method list_experiment_folders_static (line 1367) | def list_experiment_folders_static(base_path: str = "./logging/traject...
    method get_experiment_progress (line 1393) | def get_experiment_progress(self, experiment_folder_name: str) -> Dict...

FILE: src/cuga/backend/browser_env/browser/chat_async.py
  class Chat (line 24) | class Chat:
    method __init__ (line 25) | def __init__(self, headless: bool, chat_size=(500, 800), record_video_...
    method init (line 36) | async def init(self):
    method _js_user_message_received_callback (line 57) | def _js_user_message_received_callback(self, msg: str):
    method add_message (line 64) | async def add_message(
    method wait_for_user_message (line 77) | async def wait_for_user_message(self):
    method close (line 85) | async def close(self):
  function get_chatbox_modern (line 90) | def get_chatbox_modern(chatbox_dir) -> str:
  function get_chatbox_classic (line 97) | def get_chatbox_classic(chatbox_dir) -> str:

FILE: src/cuga/backend/browser_env/browser/env.py
  class BrowserEnvSimple (line 10) | class BrowserEnvSimple:
    method __init__ (line 11) | def __init__(self):
    method _wait_dom_loaded (line 21) | def _wait_dom_loaded(self):
    method _active_page_check (line 33) | def _active_page_check(self):
    method reset (line 56) | def reset(self):
    method start_browser (line 65) | def start_browser(self, headless=False):
    method navigate_to_page (line 71) | def navigate_to_page(self, url):
    method close_browser (line 79) | def close_browser(self):

FILE: src/cuga/backend/browser_env/browser/extension_env_async.py
  class ExtensionEnv (line 29) | class ExtensionEnv:
    method __init__ (line 35) | def __init__(
    method get_url (line 140) | def get_url(self) -> str | None:
    method get_title (line 143) | async def get_title(self) -> str | None:
    method close (line 146) | async def close(self):
    method reset (line 152) | async def reset(self, seed=None, **kwargs):
    method send_chat_message (line 199) | async def send_chat_message(self, role: str, content: str):
    method _send_to_chat (line 202) | async def _send_to_chat(self, content: str):
    method step (line 217) | async def step(self, action: str) -> tuple:
    method _get_obs (line 267) | async def _get_obs(self):

FILE: src/cuga/backend/browser_env/browser/gym_env.py
  function _try_to_extract_legacy_goal (line 37) | def _try_to_extract_legacy_goal(goal: list):
  class BrowserEnvGym (line 55) | class BrowserEnvGym(gym.Env, ABC):
    method __init__ (line 61) | def __init__(
    method close (line 179) | def close(self):
    method reset (line 191) | def reset(self, seed=None, *args, **kwargs):
    method step (line 379) | def step(self, action: str) -> tuple:
    method _task_validate (line 457) | def _task_validate(self):
    method _wait_for_user_message (line 474) | def _wait_for_user_message(self):
    method _wait_dom_loaded (line 479) | def _wait_dom_loaded(self):
    method _activate_page_from_js (line 491) | def _activate_page_from_js(self, page: playwright.sync_api.Page):
    method _active_page_check (line 506) | def _active_page_check(self):
    method _get_obs (line 530) | def _get_obs(self):

FILE: src/cuga/backend/browser_env/browser/gym_env_async.py
  function _try_to_extract_legacy_goal (line 38) | def _try_to_extract_legacy_goal(goal: list):
  class BrowserEnvGymAsync (line 56) | class BrowserEnvGymAsync(gym.Env, ABC):
    method __init__ (line 62) | def __init__(
    method get_title (line 198) | async def get_title(self) -> str | None:
    method close (line 201) | async def close(self):
    method reset (line 218) | async def reset(self, seed=None, **kwargs):
    method step (line 438) | async def step(self, action: str) -> tuple:
    method _task_validate (line 523) | async def _task_validate(self):
    method _wait_for_user_message (line 546) | async def _wait_for_user_message(self):
    method _wait_dom_loaded (line 552) | async def _wait_dom_loaded(self):
    method _activate_page_from_js (line 567) | async def _activate_page_from_js(self, page: Page):
    method _active_page_check (line 585) | async def _active_page_check(self):
    method get_url (line 613) | def get_url(self) -> str | None:
    method send_chat_message (line 618) | async def send_chat_message(self, role: str, content: str):
    method _get_obs (line 621) | async def _get_obs(self):

FILE: src/cuga/backend/browser_env/browser/gym_obs/extract_chrome_extension.py
  class ChromeExtensionError (line 26) | class ChromeExtensionError(Exception):
  class MarkingError (line 32) | class MarkingError(Exception):
  class ChromeExtensionExtractor (line 42) | class ChromeExtensionExtractor:
    method __init__ (line 45) | def __init__(
    method __aenter__ (line 52) | async def __aenter__(self):
    method __aexit__ (line 58) | async def __aexit__(self, exc_type, exc_val, exc_tb):
  function _pre_extract_chrome_extension (line 62) | async def _pre_extract_chrome_extension(
  function _post_extract_chrome_extension (line 84) | async def _post_extract_chrome_extension(communicator: ChromeExtensionCo...
  function extract_dom_snapshot_chrome_extension (line 96) | async def extract_dom_snapshot_chrome_extension(
  function extract_accessibility_tree_chrome_extension (line 121) | async def extract_accessibility_tree_chrome_extension(
  function extract_dom_tree_chrome_extension (line 134) | async def extract_dom_tree_chrome_extension(
  function extract_screenshot_chrome_extension (line 156) | async def extract_screenshot_chrome_extension(
  function extract_focused_element_bid_chrome_extension (line 169) | async def extract_focused_element_bid_chrome_extension(
  function extract_page_content_chrome_extension (line 183) | async def extract_page_content_chrome_extension(communicator: ChromeExte...
  function extract_page_url_chrome_extension (line 194) | async def extract_page_url_chrome_extension(communicator: ChromeExtensio...
  function extract_page_title_chrome_extension (line 202) | async def extract_page_title_chrome_extension(communicator: ChromeExtens...
  function extract_data_items_from_aria (line 210) | def extract_data_items_from_aria(string: str, log_level: int = logging.N...
  function extract_dom_extra_properties_chrome_extension (line 228) | def extract_dom_extra_properties_chrome_extension(dom_snapshot: Dict[str...
  function add_browsergym_id_to_accessibility_tree (line 343) | def add_browsergym_id_to_accessibility_tree(
  function full_extract_chrome_extension (line 415) | async def full_extract_chrome_extension(

FILE: src/cuga/backend/browser_env/browser/gym_obs/http_stream_comm.py
  class ChromeExtensionCommunicatorProtocol (line 7) | class ChromeExtensionCommunicatorProtocol(Protocol):
    method __aenter__ (line 8) | async def __aenter__(self): ...
    method __aexit__ (line 9) | async def __aexit__(self, exc_type, exc_val, exc_tb): ...
    method send_request (line 10) | async def send_request(self, data: dict, timeout: Optional[float] = No...
    method send_extraction_request (line 11) | async def send_extraction_request(
    method get_next_command (line 14) | async def get_next_command(self) -> dict: ...
    method resolve_request (line 15) | def resolve_request(self, req_id: str, result: dict): ...
    method is_connected (line 16) | def is_connected(self) -> bool: ...
    method wait_for_connection (line 17) | async def wait_for_connection(self, timeout: float = 10.0): ...
    method ping (line 18) | async def ping(self) -> bool: ...
    method extract_dom_snapshot (line 19) | async def extract_dom_snapshot(self, **kwargs) -> Dict[str, Any]: ...
    method extract_accessibility_tree (line 20) | async def extract_accessibility_tree(self) -> Dict[str, Any]: ...
    method extract_screenshot (line 21) | async def extract_screenshot(self, format: str = "png", quality: int =...
    method extract_focused_element_bid (line 22) | async def extract_focused_element_bid(self) -> str: ...
    method extract_page_content (line 23) | async def extract_page_content(self, as_text: bool = False) -> str: ...
    method extract_dom_tree (line 24) | async def extract_dom_tree(
    method get_active_tab_url (line 32) | async def get_active_tab_url(self) -> str: ...
    method get_active_tab_title (line 33) | async def get_active_tab_title(self) -> str: ...
  class ChromeExtensionCommunicatorHTTP (line 36) | class ChromeExtensionCommunicatorHTTP:
    method __init__ (line 37) | def __init__(self):
    method __aenter__ (line 42) | async def __aenter__(self):
    method __aexit__ (line 46) | async def __aexit__(self, exc_type, exc_val, exc_tb):
    method send_request (line 50) | async def send_request(self, data: dict, timeout: Optional[float] = No...
    method send_extraction_request (line 61) | async def send_extraction_request(self, request_type: str, data: Dict[...
    method get_next_command (line 72) | async def get_next_command(self) -> dict:
    method resolve_request (line 75) | def resolve_request(self, req_id: str, result: dict):
    method is_connected (line 80) | def is_connected(self) -> bool:
    method wait_for_connection (line 84) | async def wait_for_connection(self, timeout: float = 10.0):
    method ping (line 89) | async def ping(self) -> bool:
    method extract_dom_snapshot (line 97) | async def extract_dom_snapshot(self, **kwargs) -> Dict[str, Any]:
    method extract_accessibility_tree (line 102) | async def extract_accessibility_tree(self) -> Dict[str, Any]:
    method extract_screenshot (line 107) | async def extract_screenshot(self, format: str = "png", quality: int =...
    method extract_focused_element_bid (line 114) | async def extract_focused_element_bid(self) -> str:
    method extract_page_content (line 119) | async def extract_page_content(self, as_text: bool = False) -> str:
    method extract_dom_tree (line 124) | async def extract_dom_tree(
    method get_active_tab_url (line 143) | async def get_active_tab_url(self) -> str:
    method get_active_tab_title (line 148) | async def get_active_tab_title(self) -> str:
    method mark_elements (line 153) | async def mark_elements(self, tags_to_mark: str = "standard_html") -> ...
    method unmark_elements (line 158) | async def unmark_elements(self):

FILE: src/cuga/backend/browser_env/browser/gym_obs/javascript/frame_mark_elements.js
  function until (line 199) | async function until(f, timeout, interval=40) {
  function whoCapturesCenterClick (line 220) | function whoCapturesCenterClick(element){
  function push_bid_to_attribute (line 236) | function push_bid_to_attribute(bid, elem, attr){
  function elementFromPoint (line 245) | function elementFromPoint(x, y) {
  class IFrameIdGenerator (line 260) | class IFrameIdGenerator {
    method constructor (line 261) | constructor(chars = 'abcdefghijklmnopqrstuvwxyz') {
    method next (line 266) | next() {
    method _increment (line 280) | _increment() {
  method [Symbol.iterator] (line 291) | *[Symbol.iterator]() {

FILE: src/cuga/backend/browser_env/browser/gym_obs/javascript/frame_unmark_elements.js
  function pop_bid_from_attribute (line 33) | function pop_bid_from_attribute(elem, attr) {

FILE: src/cuga/backend/browser_env/browser/gym_obs/obs.py
  function _pre_extract (line 27) | def _pre_extract(page: playwright.sync_api.Page):
  function _post_extract (line 70) | def _post_extract(page: playwright.sync_api.Page):
  class GymObs (line 97) | class GymObs:
    method __init__ (line 98) | def __init__(self, page: Page, context: BrowserContext):
    method get_obs (line 103) | def get_obs(self):

FILE: src/cuga/backend/browser_env/browser/gym_obs/obs_async.py
  function _pre_extract (line 26) | async def _pre_extract(
  function _post_extract (line 80) | async def _post_extract(page: playwright.async_api.Page):
  function extract_data_items_from_aria (line 107) | def extract_data_items_from_aria(string: str, log_level: int = logging.N...
  function extract_all_frame_axtrees (line 126) | async def extract_all_frame_axtrees(page: playwright.async_api.Page):
  function extract_dom_snapshot (line 197) | async def extract_dom_snapshot(
  function extract_screenshot (line 240) | async def extract_screenshot(page: playwright.async_api.Page):
  function extract_screenshot_base64 (line 275) | async def extract_screenshot_base64(page: playwright.async_api.Page):
  function extract_focused_element_bid (line 301) | async def extract_focused_element_bid(page: playwright.async_api.Page):
  function extract_merged_axtree (line 336) | async def extract_merged_axtree(page: playwright.async_api.Page):

FILE: src/cuga/backend/browser_env/browser/gym_obs/websocket_server.py
  class ChromeExtensionWebSocketServer (line 11) | class ChromeExtensionWebSocketServer:
    method __init__ (line 16) | def __init__(self, host: str = "localhost", port: int = 9223):
    method start (line 24) | async def start(self):
    method stop (line 39) | async def stop(self):
    method handle_client (line 46) | async def handle_client(self, websocket: WebSocketServerProtocol):
    method handle_message (line 75) | async def handle_message(self, client_id: str, websocket: WebSocketSer...
    method send_message (line 118) | async def send_message(self, websocket: WebSocketServerProtocol, data:...
    method send_error (line 126) | async def send_error(self, websocket: WebSocketServerProtocol, error_m...
    method broadcast_message (line 130) | async def broadcast_message(self, data: Dict[str, Any]):
    method send_request (line 150) | async def send_request(self, data: Dict[str, Any], timeout: Optional[f...
    method is_connected (line 184) | def is_connected(self) -> bool:
    method get_connected_count (line 188) | def get_connected_count(self) -> int:
    method handle_page_extraction (line 192) | async def handle_page_extraction(self, client_id: str, data: Dict[str,...
    method _save_extraction_debug_data (line 237) | async def _save_extraction_debug_data(self, client_id: str, extraction...
    method handle_agent_query (line 300) | async def handle_agent_query(
    method get_latest_extraction_data (line 351) | def get_latest_extraction_data(self, client_id: str = None) -> Dict[st...
  class ChromeExtensionCommunicatorWebSocket (line 369) | class ChromeExtensionCommunicatorWebSocket:
    method __init__ (line 374) | def __init__(self, host: str = "localhost", port: int = 9223):
    method __aenter__ (line 379) | async def __aenter__(self):
    method __aexit__ (line 383) | async def __aexit__(self, exc_type, exc_val, exc_tb):
    method wait_for_connection (line 386) | async def wait_for_connection(self, timeout: float = 10.0):
    method send_extraction_request (line 397) | async def send_extraction_request(self, request_type: str, data: Dict[...
    method ping (line 408) | async def ping(self) -> bool:
    method extract_dom_snapshot (line 416) | async def extract_dom_snapshot(self, **kwargs) -> Dict[str, Any]:
    method extract_accessibility_tree (line 421) | async def extract_accessibility_tree(self) -> Dict[str, Any]:
    method extract_screenshot (line 426) | async def extract_screenshot(self, format: str = "png", quality: int =...
    method extract_focused_element_bid (line 433) | async def extract_focused_element_bid(self) -> str:
    method extract_page_content (line 438) | async def extract_page_content(self, as_text: bool = False) -> str:
    method get_active_tab_url (line 443) | async def get_active_tab_url(self) -> str:
    method get_active_tab_title (line 448) | async def get_active_tab_title(self) -> str:
    method mark_elements (line 453) | async def mark_elements(self, tags_to_mark: str = "standard_html") -> ...
    method unmark_elements (line 458) | async def unmark_elements(self):
  function main (line 464) | async def main():

FILE: src/cuga/backend/browser_env/browser/open_ended_async.py
  class AbstractBrowserTask (line 12) | class AbstractBrowserTask(ABC):
    method get_task_id (line 20) | def get_task_id(cls):
    method __init__ (line 23) | def __init__(self, seed: int | None) -> None:
    method setup (line 37) | async def setup(self, page: playwright.async_api.Page | None) -> tuple...
    method teardown (line 50) | async def teardown(self) -> None:
    method validate (line 57) | async def validate(
    method cheat (line 75) | async def cheat(self, page: playwright.async_api.Page, chat_messages: ...
  class OpenEndedTaskAsync (line 83) | class OpenEndedTaskAsync(AbstractBrowserTask):
    method get_task_id (line 85) | def get_task_id(cls):
    method __init__ (line 88) | def __init__(self, seed: int, start_url: str, goal: str | None = None)...
    method setup (line 100) | async def setup(self, page: playwright.async_api.Page | None) -> tuple...
    method teardown (line 105) | async def teardown(self) -> None:
    method validate (line 108) | async def validate(

FILE: src/cuga/backend/browser_env/browser/utils.py
  function highlight_by_box_async (line 6) | async def highlight_by_box_async(
  function smooth_move_visual_cursor_to_async (line 50) | async def smooth_move_visual_cursor_to_async(
  function check_for_overlay_async (line 158) | async def check_for_overlay_async(
  function add_demo_mode_effects_async (line 195) | async def add_demo_mode_effects_async(

FILE: src/cuga/backend/browser_env/browser/utils_async.py
  function _set_global_playwright_async (line 10) | def _set_global_playwright_async(pw: playwright.async_api.Playwright):
  function _get_global_playwright_async (line 15) | async def _get_global_playwright_async():

FILE: src/cuga/backend/browser_env/page_understanding/extension_processor.py
  class ExtensionProcessor (line 15) | class ExtensionProcessor:
    method __init__ (line 16) | def __init__(self, extractor: PageUnderstandingExtractorProtocol) -> N...
    method extract (line 19) | async def extract(self, config: Dict = {}) -> PUExtractedChromeExtension:
    method get_page_url (line 24) | def get_page_url(self) -> str | None:
    method get_page_title (line 31) | def get_page_title(self) -> str | None:
    method transform (line 38) | async def transform(self, **kwargs) -> PuAnswer:

FILE: src/cuga/backend/browser_env/page_understanding/extractor_utils/extract_async.py
  class MarkingError (line 25) | class MarkingError(Exception):
  function _pre_extract (line 29) | async def _pre_extract(
  function _post_extract (line 83) | async def _post_extract(page: playwright.async_api.Page):
  function pop_bids_from_attribute (line 110) | def pop_bids_from_attribute(dom_snapshot, attr: str):
  function extract_data_items_from_aria (line 144) | def extract_data_items_from_aria(string: str, log_level: int = logging.N...
  function extract_all_frame_axtrees (line 163) | async def extract_all_frame_axtrees(page: playwright.async_api.Page):
  function extract_dom_snapshot (line 234) | async def extract_dom_snapshot(
  function extract_screenshot (line 277) | async def extract_screenshot(page: playwright.async_api.Page):
  function extract_screenshot_base64 (line 312) | async def extract_screenshot_base64(page: playwright.async_api.Page):
  function extract_focused_element_bid (line 328) | async def extract_focused_element_bid(page: playwright.async_api.Page):
  function extract_merged_axtree (line 363) | async def extract_merged_axtree(page: playwright.async_api.Page):
  function extract_dom_extra_properties (line 411) | def extract_dom_extra_properties(dom_snapshot):

FILE: src/cuga/backend/browser_env/page_understanding/extractor_utils/javascript/frame_mark_elements.js
  function until (line 198) | async function until(f, timeout, interval=40) {
  function whoCapturesCenterClick (line 219) | function whoCapturesCenterClick(element){
  function push_bid_to_attribute (line 235) | function push_bid_to_attribute(bid, elem, attr){
  function elementFromPoint (line 244) | function elementFromPoint(x, y) {
  class IFrameIdGenerator (line 259) | class IFrameIdGenerator {
    method constructor (line 260) | constructor(chars = 'abcdefghijklmnopqrstuvwxyz') {
    method next (line 265) | next() {
    method _increment (line 279) | _increment() {
  method [Symbol.iterator] (line 290) | *[Symbol.iterator]() {

FILE: src/cuga/backend/browser_env/page_understanding/extractor_utils/javascript/frame_unmark_elements.js
  function pop_bid_from_attribute (line 28) | function pop_bid_from_attribute(elem, attr) {

FILE: src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/model.py
  class Rule (line 10) | class Rule(BaseModel):
  class DOMRect (line 16) | class DOMRect(BaseModel):
  class Html (line 23) | class Html(BaseModel):
  class Match (line 30) | class Match(BaseModel):
  class Text (line 35) | class Text(BaseModel):
  class ElementSelector (line 40) | class ElementSelector(BaseModel):
  class InterestingElement (line 46) | class InterestingElement(BaseModel):
  class AnalyzePageResponse (line 55) | class AnalyzePageResponse(BaseModel):
  class BrowserTab (line 60) | class BrowserTab(BaseModel):
  class StateResponse (line 69) | class StateResponse(BaseModel):
  class StateCommand (line 74) | class StateCommand(BaseModel):
    method __init__ (line 84) | def __init__(
  class Response (line 106) | class Response(BaseModel, Generic[TResponse]):

FILE: src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/nocode_utils.py
  function _ensure_worker (line 20) | async def _ensure_worker(browser_context, target_extension_id: str) -> W...
  function execute_on_extension_async (line 46) | async def execute_on_extension_async(
  function execute_command_sync (line 65) | async def execute_command_sync(
  function analyze_current_page_async (line 75) | async def analyze_current_page_async(

FILE: src/cuga/backend/browser_env/page_understanding/pu_extractor.py
  class PUExtracted (line 28) | class PUExtracted(BaseModel):
  class PageUnderstandingExtractor (line 39) | class PageUnderstandingExtractor:
    method __init__ (line 40) | def __init__(
    method extract (line 46) | async def extract(self, context: BrowserContext, page: Page, nocodeui_...

FILE: src/cuga/backend/browser_env/page_understanding/pu_extractor_chrome_extension.py
  class PUExtractedResultProtocol (line 17) | class PUExtractedResultProtocol(Protocol):
  class PageUnderstandingExtractorProtocol (line 38) | class PageUnderstandingExtractorProtocol(Protocol):
    method extract (line 44) | async def extract(self, nocodeui_pu: bool = False) -> PUExtractedResul...
    method extract_simple (line 45) | async def extract_simple(self) -> Dict: ...
    method health_check (line 46) | async def health_check(self) -> bool: ...
  class PUExtractedChromeExtension (line 49) | class PUExtractedChromeExtension(BaseModel):
  class PageUnderstandingExtractorChromeExtension (line 67) | class PageUnderstandingExtractorChromeExtension:
    method __init__ (line 72) | def __init__(
    method __aenter__ (line 82) | async def __aenter__(self):
    method __aexit__ (line 91) | async def __aexit__(self, exc_type, exc_val, exc_tb):
    method extract (line 96) | async def extract(self, nocodeui_pu: bool = False) -> PUExtractedResul...
    method extract_simple (line 158) | async def extract_simple(self) -> Dict:
    method health_check (line 168) | async def health_check(self) -> bool:

FILE: src/cuga/backend/browser_env/page_understanding/pu_processor.py
  class PageUnderstandingProcessor (line 11) | class PageUnderstandingProcessor:
    method __init__ (line 12) | def __init__(self, extractor: Any):
    method extract (line 18) | async def extract(self, context: BrowserContext, page: Page, config: D...
    method load_transformer (line 23) | def load_transformer(self, transformer_path: str, transformer_params: ...
    method transform (line 33) | async def transform(self, transformer_params: Dict = {}) -> PuAnswer:

FILE: src/cuga/backend/browser_env/page_understanding/pu_transform.py
  class PuAnswer (line 10) | class PuAnswer(BaseModel):
  class PageUnderstandingV1 (line 18) | class PageUnderstandingV1:
    method __init__ (line 19) | def __init__(self):
    method transform (line 22) | async def transform(self, pu_extracted: PUExtracted, filter_visible_on...

FILE: src/cuga/backend/browser_env/page_understanding/tranformer_utils/dom_transform_utils.py
  function flatten_domtree_to_str (line 20) | def flatten_domtree_to_str(
  function _process_bid_dom (line 196) | def _process_bid_dom(
  function _get_coord_str (line 289) | def _get_coord_str(coord, decimals):

FILE: src/cuga/backend/browser_env/page_understanding/tranformer_utils/transform_utils.py
  function flatten_axtree_to_str (line 20) | def flatten_axtree_to_str(
  function _process_bid (line 165) | def _process_bid(
  function _get_coord_str (line 249) | def _get_coord_str(coord, decimals):

FILE: src/cuga/backend/browser_env/page_understanding/types/dom_tree_types.py
  class DomTreeArgs (line 10) | class DomTreeArgs(BaseModel):
  class NodeData (line 30) | class NodeData(BaseModel):
    method __str__ (line 63) | def __str__(self) -> str:
    method to_pretty_string (line 100) | def to_pretty_string(self) -> str:
  class TextNodeData (line 108) | class TextNodeData(BaseModel):
  class DomTreeResult (line 120) | class DomTreeResult(BaseModel):
    method get_node (line 130) | def get_node(self, node_id: str) -> Optional[Union[NodeData, TextNodeD...
    method get_root_node (line 134) | def get_root_node(self) -> Optional[Union[NodeData, TextNodeData]]:
    method get_interactive_nodes (line 138) | def get_interactive_nodes(self) -> List[NodeData]:
    method get_highlighted_nodes (line 146) | def get_highlighted_nodes(self) -> List[NodeData]:
    method get_visible_text_nodes (line 154) | def get_visible_text_nodes(self) -> List[TextNodeData]:
    method get_children (line 162) | def get_children(self, node_id: str) -> List[Union[NodeData, TextNodeD...
    method traverse_tree (line 171) | def traverse_tree(self, node_id: Optional[str] = None) -> List[Union[N...
    method get_statistics (line 189) | def get_statistics(self) -> Dict[str, int]:

FILE: src/cuga/backend/browser_env/page_understanding/types/validate_structure.py
  function validate_field_mappings (line 6) | def validate_field_mappings():

FILE: src/cuga/backend/browser_env/tools/extension_commands.py
  function _get_communicator (line 24) | def _get_communicator(config: RunnableConfig | None) -> Any | None:
  function _send_browser_command (line 55) | async def _send_browser_command(command: str, args: Dict[str, Any], conf...
  function _add_animation (line 94) | async def _add_animation(
  function _get_page_data (line 115) | def _get_page_data(config: RunnableConfig | None) -> Optional[Dict[str, ...
  function _get_dom_tree (line 132) | def _get_dom_tree(config: RunnableConfig | None):
  function get_node_by_dom_tree_id (line 145) | def get_node_by_dom_tree_id(dom_tree_id: int, dom_tree: DomTreeResult) -...
  function _find_browsergym_id_in_children (line 159) | def _find_browsergym_id_in_children(
  function get_element_name_by_bid (line 198) | def get_element_name_by_bid(bid: str, page_data: dict) -> str | None:
  function _get_element_by_bid_with_validation (line 227) | async def _get_element_by_bid_with_validation(
  function click_impl (line 341) | async def click_impl(
  function type_impl (line 380) | async def type_impl(
  function select_option_impl (line 413) | async def select_option_impl(
  function open_app_impl (line 441) | async def open_app_impl(*, app_name: str, config: RunnableConfig | None ...
  function open_dropdown_impl (line 450) | async def open_dropdown_impl(
  function go_back_impl (line 461) | async def go_back_impl(config: RunnableConfig | None = None):

FILE: src/cuga/backend/browser_env/tools/playwright_commands.py
  function get_elem_by_bid_async (line 29) | async def get_elem_by_bid_async(page, bid, scroll_into_view: bool = Fals...
  function add_animation (line 53) | async def add_animation(page: Page, elem: Any, icon_type: str, banner_te...
  function clear_animations (line 157) | async def clear_animations(page: Page) -> None:
  function schedule_clear_animations (line 185) | def schedule_clear_animations(page: Page, delay_seconds: float = 6.0) ->...
  function check_for_alert (line 210) | async def check_for_alert(page: Page) -> Optional[str]:
  function click_impl (line 227) | async def click_impl(
  function type_impl (line 252) | async def type_impl(
  function select_option_impl (line 279) | async def select_option_impl(
  function open_app_impl (line 311) | async def open_app_impl(*, app_name: str, config: RunnableConfig | None ...
  function open_dropdown_impl (line 318) | async def open_dropdown_impl(*, bid: str, config: RunnableConfig | None ...
  function go_back_impl (line 323) | def go_back_impl(state) -> str:

FILE: src/cuga/backend/browser_env/tools/providers.py
  class BrowserToolImplProvider (line 15) | class BrowserToolImplProvider(Protocol):
    method implementations (line 25) | def implementations(self) -> Dict[str, Callable[..., Any]]:
  class ExtensionToolImplProvider (line 30) | class ExtensionToolImplProvider(BrowserToolImplProvider):
    method implementations (line 33) | def implementations(self) -> Dict[str, Callable[..., Any]]:
  class PlaywrightToolImplProvider (line 46) | class PlaywrightToolImplProvider(BrowserToolImplProvider):
    method implementations (line 49) | def implementations(self) -> Dict[str, Callable[..., Any]]:
  function get_default_provider (line 62) | def get_default_provider(use_extension: bool) -> BrowserToolImplProvider:

FILE: src/cuga/backend/cuga_graph/graph.py
  class DynamicAgentGraph (line 62) | class DynamicAgentGraph:
    method __init__ (line 63) | def __init__(
    method build_graph (line 111) | async def build_graph(self):
    method get_config_with_policy (line 125) | def get_config_with_policy(self, base_config: dict = None) -> dict:
    method add_nodes (line 142) | async def add_nodes(self, graph):
    method add_edges (line 384) | def add_edges(self, graph):

FILE: src/cuga/backend/cuga_graph/nodes/answer/final_answer.py
  class HumanInTheLoopHandler (line 26) | class HumanInTheLoopHandler:
    method __init__ (line 29) | def __init__(self):
    method handle_human_response (line 35) | def handle_human_response(self, state: AgentState, node_name: str) -> ...
    method add_action_handler (line 45) | def add_action_handler(self, action_id: str, handler: Callable):
    method _handle_save_reuse (line 49) | def _handle_save_reuse(self, state: AgentState, node_name: str) -> Com...
    method _handle_save_reuse_intent (line 55) | def _handle_save_reuse_intent(self, state: AgentState, node_name: str)...
  class FinalAnswerNode (line 61) | class FinalAnswerNode(BaseNode):
    method __init__ (line 62) | def __init__(self, final_answer_agent: FinalAnswerAgent):
    method node_handler (line 78) | async def node_handler(
    method _generate_final_answer (line 163) | async def _generate_final_answer(state: AgentState, agent: FinalAnswer...

FILE: src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/final_answer_agent.py
  class FinalAnswerAgent (line 31) | class FinalAnswerAgent(BaseAgent):
    method __init__ (line 32) | def __init__(
    method default_answer_parser (line 60) | def default_answer_parser(result: AIMessage, name):
    method output_parser (line 67) | def output_parser(result: Union[FinalAnswerOutput, FinalAnswerAppworld...
    method run (line 71) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 98) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/load_prompt.py
  class FinalAnswerOutput (line 16) | class FinalAnswerOutput(BaseModel):
  class FinalAnswerAppworldOutput (line 22) | class FinalAnswerAppworldOutput(BaseModel):
  function load_appworld_final_answer_prompt (line 43) | def load_appworld_final_answer_prompt(model_config: Optional[Any] = None...
  function load_appworld_plain_final_answer_prompt (line 53) | def load_appworld_plain_final_answer_prompt(model_config: Optional[Any] ...
  function parse_appworld_plain_completion (line 63) | def parse_appworld_plain_completion(raw: str) -> str:
  function appworld_plain_llm_to_structured (line 75) | def appworld_plain_llm_to_structured(msg: Any) -> FinalAnswerAppworldOut...
  function appworld_plain_post_llm_runnable (line 93) | def appworld_plain_post_llm_runnable() -> RunnableLambda:

FILE: src/cuga/backend/cuga_graph/nodes/api/api_code_agent.py
  class ApiCoder (line 21) | class ApiCoder(BaseNode):
    method __init__ (line 22) | def __init__(self, code_agent: CodeAgent):
    method node_handler (line 33) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/api/api_code_planner.py
  class ApiCodePlanner (line 20) | class ApiCodePlanner(BaseNode):
    method __init__ (line 21) | def __init__(self, code_agent: APICodePlannerAgent):
    method node_handler (line 32) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/api_code_planner_agent.py
  function report_missing_api (line 22) | def report_missing_api(message: str):
  class APICodePlannerAgent (line 30) | class APICodePlannerAgent(BaseAgent):
    method __init__ (line 31) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 37) | def output_parser(result: AIMessage, name) -> Any:
    method run (line 41) | async def run(self, input_variables: AgentState) -> BaseMessage:
    method create (line 60) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/load_prompt.py
  class Step (line 11) | class Step(BaseModel):
  class Metadata (line 22) | class Metadata(BaseModel):
  class NextAgentPlan (line 33) | class NextAgentPlan(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/api/api_planner.py
  function _parse_planner_output_or_raise (line 41) | def _parse_planner_output_or_raise(raw: str) -> APIPlannerOutput:
  function think (line 80) | def think(thought: str):
  class ApiPlanner (line 89) | class ApiPlanner(BaseNode):
    method __init__ (line 90) | def __init__(self, router_agent: APIPlannerAgent):
    method collect_history (line 103) | def collect_history(state: AgentState, action: str, step: APIPlannerIn...
    method should_use_fast_mode_early (line 108) | def should_use_fast_mode_early(state: AgentState) -> bool:
    method count_tools_for_app (line 128) | async def count_tools_for_app(app_name: str) -> int:
    method node_handler (line 147) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/api_planner_agent.py
  function _get_model_identifier (line 40) | def _get_model_identifier(llm: BaseChatModel) -> Optional[str]:
  class APIPlannerAgent (line 72) | class APIPlannerAgent(BaseAgent):
    method __init__ (line 73) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 87) | def output_parser(result: AIMessage, name) -> Any:
    method run (line 91) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 128) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/prompts/load_prompt.py
  class ActionName (line 19) | class ActionName(str, Enum):
  class ActionNameNoHITL (line 28) | class ActionNameNoHITL(str, Enum):
  class ConcludeTaskStatus (line 36) | class ConcludeTaskStatus(str, Enum):
  class ApiDescription (line 43) | class ApiDescription(BaseModel):
  class CoderAgentInput (line 54) | class CoderAgentInput(BaseModel):
  class ApiShortlistingAgentInput (line 62) | class ApiShortlistingAgentInput(BaseModel):
  class ConcludeTaskInput (line 69) | class ConcludeTaskInput(BaseModel):
  class ConsultWithHumanInput (line 77) | class ConsultWithHumanInput(BaseModel):
  class APIPlannerOutput (line 97) | class APIPlannerOutput(BaseModel):
  class APIPlannerOutputLite (line 112) | class APIPlannerOutputLite(BaseModel):
  class APIPlannerOutputWX (line 124) | class APIPlannerOutputWX(BaseModel):
  class APIPlannerOutputNoHITL (line 139) | class APIPlannerOutputNoHITL(BaseModel):
  class APIPlannerOutputLiteNoHITL (line 153) | class APIPlannerOutputLiteNoHITL(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/api/api_shortlister.py
  class ApiShortlister (line 21) | class ApiShortlister(BaseNode):
    method __init__ (line 22) | def __init__(self, code_agent: ShortlisterAgent):
    method merge_apis (line 33) | def merge_apis(new_apis, all_apis):
    method get_reasoning_by_api_name (line 51) | def get_reasoning_by_api_name(result: ShortListerOutput, api_name: str):
    method node_handler (line 58) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/api/code_agent/code_act_agent.py
  function extract_and_combine_codeblocks (line 33) | def extract_and_combine_codeblocks(text: str) -> str:
  function check_if_asking_to_proceed (line 104) | async def check_if_asking_to_proceed(content: str) -> bool:
  class CodeActState (line 154) | class CodeActState(MessagesState):
  function create_default_prompt (line 167) | def create_default_prompt(tools: list[StructuredTool], base_prompt: Opti...
  function create_codeact (line 193) | def create_codeact(

FILE: src/cuga/backend/cuga_graph/nodes/api/code_agent/code_agent.py
  class CodeAgent (line 22) | class CodeAgent(BaseAgent):
    method __init__ (line 23) | def __init__(self, llm: BaseChatModel, tools: Any = None):
    method output_parser (line 44) | def output_parser(result: BaseMessage, name) -> BaseMessage:
    method get_last_nonempty_line (line 48) | def get_last_nonempty_line(self, text, limit=5):
    method extract_inner_text (line 91) | def extract_inner_text(self, data):
    method extract_from_json_marker (line 102) | def extract_from_json_marker(self, text):
    method extract_code_from_response (line 111) | def extract_code_from_response(self, text: str) -> str:
    method run (line 150) | async def run(self, input_variables: AgentState = None) -> AIMessage:
    method create (line 232) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/api/code_agent/model.py
  class CodeAgentOutput (line 6) | class CodeAgentOutput(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/api/shortlister_agent/prompts/load_prompt.py
  class APIDetails (line 11) | class APIDetails(BaseModel):
  class ShortListerOutput (line 26) | class ShortListerOutput(BaseModel):
  class ShortListerOutputLite (line 31) | class ShortListerOutputLite(BaseModel):
  class Metadata (line 35) | class Metadata(BaseModel):
  class NextAgentPlan (line 46) | class NextAgentPlan(BaseModel):
  class ExplicitParameterItem (line 58) | class ExplicitParameterItem(BaseModel):
  class ImplicitParameterItem (line 67) | class ImplicitParameterItem(BaseModel):
  class Parameters (line 78) | class Parameters(BaseModel):
  class ParameterAnalysisOutput (line 91) | class ParameterAnalysisOutput(BaseModel):
  class Tool (line 102) | class Tool(BaseModel):
  class FindToolsOutput (line 115) | class FindToolsOutput(BaseModel):
  function find_tools (line 128) | def find_tools(query: str) -> FindToolsOutput:

FILE: src/cuga/backend/cuga_graph/nodes/api/shortlister_agent/shortlister_agent.py
  class ShortlisterAgent (line 29) | class ShortlisterAgent(BaseAgent):
    method __init__ (line 30) | def __init__(
    method get_function_names (line 42) | def get_function_names(res, apis):
    method output_parser (line 55) | def output_parser(result: ShortListerOutput, name) -> Any:
    method filter_by_api_names (line 60) | def filter_by_api_names(data: dict, target_api_names: list) -> dict:
    method run (line 84) | async def run(self, input_variables: AgentState) -> AIMessage:
    method get_shortlisted_apis (line 101) | async def get_shortlisted_apis(self, input_variables: AgentState, app_...
    method build_api_results (line 115) | def build_api_results(app_name: str, shortlisted_apis: List[APIDetails...
    method create (line 122) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/api/tasks/reflection.py
  function reflection_task (line 9) | def reflection_task(llm, enable_format=False) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/api/tasks/summarize_code.py
  function summarize_steps (line 9) | def summarize_steps(llm, enable_format=False) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/api/variables_manager/tests/test_manager.py
  class TestVariablesManager (line 4) | class TestVariablesManager:
    method test_independent_instances (line 7) | def test_independent_instances(self):
    method test_add_variable_with_description (line 24) | def test_add_variable_with_description(self):
    method test_last_n_variables_functionality (line 52) | def test_last_n_variables_functionality(self):
    method test_variable_formatting (line 92) | def test_variable_formatting(self):
    method test_variables_summary_with_metadata (line 111) | def test_variables_summary_with_metadata(self):
    method test_boolean_handling (line 122) | def test_boolean_handling(self):
    method test_reset_keep_last_n_functionality (line 136) | def test_reset_keep_last_n_functionality(self):
    method test_reset_keep_last_n_edge_cases (line 176) | def test_reset_keep_last_n_edge_cases(self):
    method test_reset_functionality (line 196) | def test_reset_functionality(self):

FILE: src/cuga/backend/cuga_graph/nodes/api/variables_manager/tests/test_value_preview.py
  function extract_preview_for (line 8) | def extract_preview_for(vm: VariablesManager, name: str, max_length: int...
  function test_preview_long_string_truncated (line 16) | def test_preview_long_string_truncated():
  function test_preview_long_list_truncated_items (line 27) | def test_preview_long_list_truncated_items():
  function test_preview_nested_dict_preserves_keys_and_truncates_arrays (line 37) | def test_preview_nested_dict_preserves_keys_and_truncates_arrays():
  function test_preview_deep_nesting_shows_full_when_fits (line 52) | def test_preview_deep_nesting_shows_full_when_fits():
  function test_preview_extremely_deep_nesting_capped (line 63) | def test_preview_extremely_deep_nesting_capped():
  function test_playground_scenario_data_json_integration (line 86) | def test_playground_scenario_data_json_integration():

FILE: src/cuga/backend/cuga_graph/nodes/browser/action.py
  function is_valid_element (line 25) | def is_valid_element(element: Any) -> bool:
  function extract_element_predicted (line 38) | def extract_element_predicted(action_state: Union[Dict[str, Any], Any]) ...
  function process_element (line 47) | def process_element(element: str) -> Union[str, int, None]:
  function element_fixing_attempt (line 68) | def element_fixing_attempt(element: Any) -> Union[str, int, None]:
  function update_call_with_fixed_element (line 85) | def update_call_with_fixed_element(call: Dict[str, Any]) -> Dict[str, Any]:
  class ActionNode (line 116) | class ActionNode(BaseNode):
    method __init__ (line 117) | def __init__(self, action_agent: ActionAgent):
    method node_handler (line 129) | def node_handler(state: AgentState, agent: ActionAgent, name: str) -> ...

FILE: src/cuga/backend/cuga_graph/nodes/browser/action_agent/action_agent.py
  class ActionAgent (line 17) | class ActionAgent(BaseAgent):
    method __init__ (line 18) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 26) | def output_parser(result: BaseMessage, name) -> BaseMessage:
    method run (line 30) | def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 40) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/browser/action_agent/tools/alert.py
  class Alert (line 4) | class Alert(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/browser/action_agent/tools/tool_processor.py
  function transform_action (line 8) | def transform_action(action):

FILE: src/cuga/backend/cuga_graph/nodes/browser/action_agent/tools/tools.py
  function get_params_and_values_except (line 16) | def get_params_and_values_except(func, exclude_param, *args, **kwargs):
  function _retrieve_impl (line 33) | def _retrieve_impl(config: RunnableConfig, tool_name: str):
  function go_back (line 40) | async def go_back(config: RunnableConfig | None = None):
  function open_app (line 51) | async def open_app(
  function click (line 73) | async def click(
  function select_option (line 92) | async def select_option(bid: str, options: str | list[str], config: Runn...
  function type (line 101) | async def type(bid: str, value: str, press_enter: bool, config: Runnable...
  function format_tools (line 116) | def format_tools(tools: List[ToolCall]):
  function memorize (line 125) | async def memorize(information: str):
  function human_in_the_loop (line 137) | def human_in_the_loop(state, message: str) -> str:
  function scroll (line 162) | def scroll(state) -> str:
  function setup_tools (line 182) | def setup_tools() -> Dict[str, BaseTool]:

FILE: src/cuga/backend/cuga_graph/nodes/browser/browser_planner.py
  class PlannerNode (line 28) | class PlannerNode(BaseNode):
    method __init__ (line 29) | def __init__(self, planner_agent: BrowserPlannerAgent):
    method node_handler (line 39) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/browser/browser_planner_agent/browser_planner_agent.py
  class BrowserPlannerAgent (line 23) | class BrowserPlannerAgent(BaseAgent):
    method __init__ (line 24) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 31) | def output_parser(result: NextAgentPlan, name) -> Any:
    method run (line 35) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 55) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/browser/browser_planner_agent/prompts/load_prompt.py
  class Step (line 11) | class Step(BaseModel):
  class Metadata (line 22) | class Metadata(BaseModel):
  class NextAgentPlan (line 33) | class NextAgentPlan(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/browser/qa_agent/prompts/load_prompt.py
  class QaAgentOutput (line 7) | class QaAgentOutput(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/browser/qa_agent/qa_agent.py
  class QaAgent (line 19) | class QaAgent(BaseAgent):
    method __init__ (line 20) | def __init__(
    method output_parser (line 34) | def output_parser(result: QaAgentOutput, name) -> Any:
    method run (line 38) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 42) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/browser/qa_agent_node.py
  class QaNode (line 15) | class QaNode(BaseNode):
    method __init__ (line 16) | def __init__(self, qa_agent: QaAgent):
    method node_handler (line 22) | async def node_handler(state: AgentState, agent: QaAgent, name: str):

FILE: src/cuga/backend/cuga_graph/nodes/chat/chat.py
  class ChatHumanInTheLoopHandler (line 28) | class ChatHumanInTheLoopHandler:
    method __init__ (line 31) | def __init__(self):
    method handle_human_response (line 39) | def handle_human_response(self, state: AgentState, node_name: str) -> ...
    method add_action_handler (line 49) | def add_action_handler(self, action_id: str, handler: Callable):
    method _handle_tool_execute (line 53) | def _handle_tool_execute(self, state: AgentState, node_name: str) -> C...
    method _handle_chat_continue (line 58) | def _handle_chat_continue(self, state: AgentState, node_name: str) -> ...
  class ChatNode (line 64) | class ChatNode(BaseNode):
    method __init__ (line 65) | def __init__(self):
    method create (line 72) | async def create(cls):
    method _execute_direct_tool_calls (line 88) | async def _execute_direct_tool_calls(
    method format_function_call (line 123) | def format_function_call(func_dict):
    method node_handler (line 139) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/chat/chat_agent/chat_agent.py
  function execute_task (line 33) | def execute_task(task: str, relevant_variables: List[str]) -> str:
  function run_new_flow (line 44) | def run_new_flow(user_task: str) -> str:
  function check_sse_availability (line 53) | async def check_sse_availability(url: str, timeout: int = 5) -> bool:
  class ChatAgent (line 73) | class ChatAgent(BaseAgent):
    method __init__ (line 74) | def __init__(
    method setup (line 100) | async def setup(self):
    method _dedupe_tools (line 168) | def _dedupe_tools(tools: List[BaseTool]) -> List[BaseTool]:
    method should_auto_execute_tool (line 182) | def should_auto_execute_tool(tool_name: Optional[str]) -> bool:
    method requires_human_approval (line 186) | def requires_human_approval(tool_name: Optional[str]) -> bool:
    method _load_knowledge_instructions (line 190) | def _load_knowledge_instructions() -> str:
    method _knowledge_enabled (line 205) | def _knowledge_enabled(app_state: Any) -> bool:
    method _serialize_tool_result (line 211) | def _serialize_tool_result(result: Any) -> str:
    method _build_runtime_context (line 220) | async def _build_runtime_context(self, state: AgentState) -> tuple[Lis...
    method _build_bound_agent (line 283) | async def _build_bound_agent(self, state: AgentState):
    method _is_session_valid (line 291) | def _is_session_valid(self) -> bool:
    method execute_tool (line 305) | async def execute_tool(self, tool_call: ToolCall):
    method invoke (line 342) | async def invoke(self, chat_messages: List[BaseMessage], state: AgentS...
    method map_chat_messages (line 369) | def map_chat_messages(self, chat_messages: List[BaseMessage]):
    method _run_regular (line 411) | async def _run_regular(self, chat_messages: List[BaseMessage], state: ...
    method _run_mcp_client (line 438) | async def _run_mcp_client(self, chat_messages: List[BaseMessage], stat...
    method run (line 442) | async def run(self, chat_messages: List[BaseMessage], state: AgentStat...
    method cleanup (line 452) | async def cleanup(self):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/combined_tool_provider.py
  function create_tool_from_tracker (line 28) | def create_tool_from_tracker(tool_name: str, tool_def: Dict[str, Any], a...
  class CombinedToolProvider (line 181) | class CombinedToolProvider(ToolProviderInterface):
    method __init__ (line 188) | def __init__(
    method initialize (line 212) | async def initialize(self):
    method reset (line 261) | def reset(self) -> None:
    method get_apps (line 268) | async def get_apps(self) -> List[AppDefinition]:
    method _filter_tools_by_include (line 305) | def _filter_tools_by_include(
    method get_tools (line 321) | async def get_tools(self, app_name: str) -> List[StructuredTool]:
    method get_all_tools (line 429) | async def get_all_tools(self) -> List[StructuredTool]:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/cuga_lite_graph.py
  function _get_knowledge_tool_scope_context (line 115) | def _get_knowledge_tool_scope_context(
  function _knowledge_scope_instruction (line 133) | def _knowledge_scope_instruction(allowed_scopes: tuple[str, ...], thread...
  function _decorate_knowledge_tool (line 157) | def _decorate_knowledge_tool(tool: Any, allowed_scopes: tuple[str, ...],...
  function make_tool_awaitable (line 169) | def make_tool_awaitable(func):
  class CugaLiteState (line 216) | class CugaLiteState(BaseModel):
    class Config (line 278) | class Config:
    method variables_manager (line 282) | def variables_manager(self):
  function _reflection_current_task (line 292) | def _reflection_current_task(state: CugaLiteState) -> str:
  function extract_and_combine_codeblocks (line 306) | def extract_and_combine_codeblocks(text: str) -> str:
  function append_chat_messages_with_step_limit (line 332) | def append_chat_messages_with_step_limit(
  function create_error_command (line 366) | def create_error_command(
  class Todo (line 397) | class Todo(BaseModel):
  class TodosInput (line 407) | class TodosInput(BaseModel):
  class TodosOutput (line 413) | class TodosOutput(BaseModel):
  function _try_parse_todos_payload (line 419) | def _try_parse_todos_payload(value: Any) -> Optional[List[Dict[str, Any]]]:
  function extract_task_todos_from_new_vars (line 432) | def extract_task_todos_from_new_vars(new_vars: dict[str, Any]) -> Option...
  function format_current_plan_section (line 440) | def format_current_plan_section(task_todos: List[Dict[str, Any]]) -> str:
  function _first_user_message_text (line 449) | def _first_user_message_text(chat_messages: Optional[List[BaseMessage]])...
  function _compose_find_tools_shortlister_query (line 460) | def _compose_find_tools_shortlister_query(query: str, initial_user_messa...
  function create_find_tools_tool (line 468) | async def create_find_tools_tool(
  function create_update_todos_tool (line 548) | async def create_update_todos_tool(agent_state: Optional['AgentState'] =...
  function create_cuga_lite_graph (line 612) | def create_cuga_lite_graph(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/cuga_lite_node.py
  class CugaLiteHumanInTheLoopHandler (line 26) | class CugaLiteHumanInTheLoopHandler:
    method __init__ (line 29) | def __init__(self):
    method handle_human_response (line 34) | def handle_human_response(self, state: AgentState, node_name: str) -> ...
    method add_action_handler (line 49) | def add_action_handler(self, action_id: str, handler: Callable):
    method _handle_tool_approval (line 53) | def _handle_tool_approval(self, state: AgentState, node_name: str) -> ...
  function _convert_sets_to_lists (line 88) | def _convert_sets_to_lists(value: Any) -> Any:
  class CugaLiteOutput (line 100) | class CugaLiteOutput(BaseModel):
  class CugaLiteNode (line 111) | class CugaLiteNode(BaseNode):
    method __init__ (line 114) | def __init__(self, langfuse_handler: Optional[Any] = None, prompt_temp...
    method read_text_file (line 123) | async def read_text_file(file_path: str) -> Optional[str]:
    method _get_new_variable_names (line 159) | def _get_new_variable_names(state: AgentState, initial_var_names: List...
    method _log_variable_changes (line 174) | def _log_variable_changes(state: AgentState, initial_var_names: List[s...
    method _generate_fallback_answer (line 189) | def _generate_fallback_answer(self, state: AgentState, new_var_names: ...
    method _has_error (line 220) | def _has_error(answer: str) -> bool:
    method node (line 235) | async def node(
    method _apply_output_formatter (line 341) | async def _apply_output_formatter(
    method callback_node (line 360) | async def callback_node(
    method _process_results (line 430) | async def _process_results(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/direct_langchain_tools_provider.py
  class DirectLangChainToolsProvider (line 17) | class DirectLangChainToolsProvider(ToolProviderInterface):
    method __init__ (line 38) | def __init__(self, tools: Optional[List[BaseTool]] = None, app_name: s...
    method _validate_tools (line 52) | def _validate_tools(self):
    method initialize (line 75) | async def initialize(self):
    method get_apps (line 89) | async def get_apps(self) -> List[AppDefinition]:
    method get_tools (line 108) | async def get_tools(self, app_name: str) -> List[StructuredTool]:
    method get_all_tools (line 127) | async def get_all_tools(self) -> List[StructuredTool]:
    method add_tool (line 139) | def add_tool(self, tool: BaseTool):
    method add_tools (line 152) | def add_tools(self, tools: List[BaseTool]):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/base_executor.py
  class BaseExecutor (line 6) | class BaseExecutor(ABC):
    method execute (line 10) | async def execute(
    method format_error (line 32) | def format_error(self, error: Exception) -> str:
  class RemoteExecutor (line 44) | class RemoteExecutor(ABC):
    method execute_for_cuga_lite (line 48) | async def execute_for_cuga_lite(
    method execute_for_code_agent (line 71) | async def execute_for_code_agent(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/code_executor.py
  function is_find_tools_listing_markdown (line 16) | def is_find_tools_listing_markdown(value: Any) -> bool:
  function _omit_find_tools_listing_vars (line 23) | def _omit_find_tools_listing_vars(new_vars: Dict[str, Any]) -> Dict[str,...
  function format_execution_output (line 27) | def format_execution_output(output: str, max_length: Optional[int] = Non...
  class CodeExecutor (line 49) | class CodeExecutor:
    method _get_local_executor (line 57) | def _get_local_executor(cls) -> BaseExecutor:
    method _get_e2b_executor (line 64) | def _get_e2b_executor(cls) -> RemoteExecutor:
    method _get_docker_executor (line 71) | def _get_docker_executor(cls) -> RemoteExecutor:
    method eval_with_tools_async (line 78) | async def eval_with_tools_async(
    method _wrap_code_for_code_agent (line 177) | def _wrap_code_for_code_agent(cls, code: str, fake_datetime: Optional[...
    method _prepare_locals_for_code_agent (line 195) | def _prepare_locals_for_code_agent(cls, state: AgentState) -> dict[str...
    method _execute_remotely_for_code_agent (line 210) | async def _execute_remotely_for_code_agent(
    method _execute_locally_for_code_agent (line 231) | async def _execute_locally_for_code_agent(
    method eval_for_code_agent (line 249) | async def eval_for_code_agent(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/benchmark_mode.py
  function is_benchmark_mode (line 4) | def is_benchmark_mode() -> bool:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/call_api_helper.py
  class CallApiHelper (line 8) | class CallApiHelper:
    method get_function_call_url (line 12) | def get_function_call_url() -> str:
    method get_trajectory_path (line 27) | def get_trajectory_path() -> str:
    method create_local_call_api_function (line 36) | def create_local_call_api_function() -> Callable:
    method create_remote_call_api_code (line 147) | def create_remote_call_api_code(function_call_url: str = None, traject...
    method create_call_api_code (line 215) | def create_call_api_code(function_call_url: str, trajectory_path: str ...

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/code_wrapper.py
  class CodeWrapper (line 4) | class CodeWrapper:
    method create_datetime_mock (line 8) | def create_datetime_mock(fake_datetime: Optional[str] = None) -> str:
    method wrap_code (line 81) | def wrap_code(code: str, fake_datetime: Optional[str] = None) -> str:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/restricted_environment.py
  class RestrictedEnvironment (line 6) | class RestrictedEnvironment:
    method is_benchmark_mode (line 10) | def is_benchmark_mode() -> bool:
    method create_restricted_import (line 19) | def create_restricted_import(allowed_modules: set):
    method create_safe_builtins (line 43) | def create_safe_builtins(restricted_import_func) -> dict:
    method create_restricted_globals (line 125) | def create_restricted_globals(safe_builtins: dict, safe_locals: dict) ...

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/security.py
  class SecurityValidator (line 9) | class SecurityValidator:
    method validate_imports (line 100) | def validate_imports(code: str) -> None:
    method _check_module (line 127) | def _check_module(module_name: str) -> None:
    method validate_dangerous_modules (line 142) | def validate_dangerous_modules(wrapped_code: str) -> None:
    method validate_wrapped_code (line 167) | def validate_wrapped_code(wrapped_code: str) -> None:
    method filter_safe_locals (line 198) | def filter_safe_locals(locals_dict: dict) -> dict:
    method assert_safe_globals (line 213) | def assert_safe_globals(restricted_globals: dict) -> None:
    method validate_context_usage (line 230) | def validate_context_usage(code: str, context_locals: dict) -> None:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/common/variable_utils.py
  class VariableUtils (line 6) | class VariableUtils:
    method is_serializable (line 10) | def is_serializable(value: Any) -> bool:
    method filter_new_variables (line 55) | def filter_new_variables(
    method reorder_variables_by_print (line 91) | def reorder_variables_by_print(new_vars: dict[str, Any], code: str) ->...
    method filter_single_letter_variables (line 129) | def filter_single_letter_variables(new_vars: dict[str, Any]) -> dict[s...
    method limit_variables_to_keep (line 145) | def limit_variables_to_keep(new_vars: dict[str, Any], keep_last_n: int...
    method add_variables_to_manager (line 174) | def add_variables_to_manager(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/docker/docker_executor.py
  class DockerExecutor (line 11) | class DockerExecutor(RemoteExecutor):
    method __init__ (line 14) | def __init__(self):
    method _get_docker_client (line 18) | def _get_docker_client(self):
    method execute_for_cuga_lite (line 35) | async def execute_for_cuga_lite(
    method execute_for_code_agent (line 62) | async def execute_for_code_agent(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/e2b/e2b_executor.py
  class E2BExecutor (line 12) | class E2BExecutor(RemoteExecutor):
    method execute_for_cuga_lite (line 38) | async def execute_for_cuga_lite(
    method execute_for_code_agent (line 110) | async def execute_for_code_agent(
    method _serialize_tools (line 155) | def _serialize_tools(self, locals_dict: dict[str, Any], apps_list: Opt...
    method _serialize_knowledge_tool_stub (line 210) | def _serialize_knowledge_tool_stub(self, tool_name: str, tool_func: An...
    method _parse_execution_output (line 243) | def _parse_execution_output(self, raw_output: str) -> tuple[str, dict[...

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/local/local_executor.py
  class LocalExecutor (line 13) | class LocalExecutor(BaseExecutor):
    method execute (line 35) | async def execute(
    method format_error (line 89) | def format_error(self, error: Exception) -> str:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_api_calls_with_print.py
  function mock_state (line 12) | def mock_state():
  function test_api_calls_with_print_dict (line 20) | async def test_api_calls_with_print_dict(mock_state):
  function test_api_calls_with_separate_prints (line 74) | async def test_api_calls_with_separate_prints(mock_state):
  function test_api_calls_with_print_and_variable_access (line 119) | async def test_api_calls_with_print_and_variable_access(mock_state):
  function test_api_calls_with_nested_dict_print (line 158) | async def test_api_calls_with_nested_dict_print(mock_state):
  function test_api_calls_with_error_handling_and_print (line 217) | async def test_api_calls_with_error_handling_and_print(mock_state):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_code_executor.py
  function mock_state (line 10) | def mock_state():
  function test_basic_execution_local (line 18) | async def test_basic_execution_local(mock_state):
  function test_execution_with_variables (line 34) | async def test_execution_with_variables(mock_state):
  function test_async_tool_execution (line 50) | async def test_async_tool_execution(mock_state):
  function test_dangerous_import_blocked (line 71) | async def test_dangerous_import_blocked(mock_state):
  function test_allowed_import_works (line 87) | async def test_allowed_import_works(mock_state):
  function test_pandas_support (line 102) | async def test_pandas_support(mock_state):
  function test_variable_reordering (line 120) | async def test_variable_reordering(mock_state):
  function test_variable_reordering_long_name (line 137) | async def test_variable_reordering_long_name(mock_state):
  function test_timeout_handling (line 153) | async def test_timeout_handling(mock_state):
  function test_expression_auto_print (line 167) | async def test_expression_auto_print(mock_state):
  function test_mode_auto_detection (line 181) | async def test_mode_auto_detection(mock_state):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_e2b_direct.py
  function test_e2b_direct_with_variables_and_tools (line 16) | async def test_e2b_direct_with_variables_and_tools():
  function _serialize_variables (line 147) | def _serialize_variables(variables: dict) -> str:
  function _serialize_tools (line 173) | def _serialize_tools(tools: dict) -> str:
  function _indent_code (line 201) | def _indent_code(code: str, levels: int = 1) -> str:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_e2b_lite.py
  class TestFilterNewVariables (line 12) | class TestFilterNewVariables:
    method test_filter_basic_serializable_types (line 15) | def test_filter_basic_serializable_types(self):
    method test_filter_collections (line 36) | def test_filter_collections(self):
    method test_filter_excludes_internal_variables (line 54) | def test_filter_excludes_internal_variables(self):
    method test_filter_excludes_non_serializable_types (line 69) | def test_filter_excludes_non_serializable_types(self):
    method test_filter_empty_new_vars (line 95) | def test_filter_empty_new_vars(self):
  class TestExecuteInE2BSandbox (line 105) | class TestExecuteInE2BSandbox:
    method test_import_error_handling (line 109) | async def test_import_error_handling(self):
    method test_successful_execution_with_output (line 116) | async def test_successful_execution_with_output(self):
    method test_execution_error_handling (line 129) | async def test_execution_error_handling(self):
    method test_empty_locals_handling (line 142) | async def test_empty_locals_handling(self):
  class TestEvalWithToolsAsyncE2B (line 153) | class TestEvalWithToolsAsyncE2B:
    method test_eval_with_e2b_enabled (line 157) | async def test_eval_with_e2b_enabled(self):
    method test_eval_with_e2b_disabled (line 196) | async def test_eval_with_e2b_disabled(self):
    method test_eval_filters_internal_variables (line 228) | async def test_eval_filters_internal_variables(self):
  class TestE2BWithVariablesAndTools (line 254) | class TestE2BWithVariablesAndTools:
    method test_e2b_with_variables_and_tools (line 258) | async def test_e2b_with_variables_and_tools(self):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_extract_codeblocks.py
  class TestExtractAndCombineCodeblocks (line 4) | class TestExtractAndCombineCodeblocks:
    method test_plain_identifier (line 7) | def test_plain_identifier(self):
    method test_plain_number (line 12) | def test_plain_number(self):
    method test_invalid_syntax (line 17) | def test_invalid_syntax(self):
    method test_function_call (line 22) | def test_function_call(self):
    method test_assignment (line 27) | def test_assignment(self):
    method test_multiple_statements (line 32) | def test_multiple_statements(self):
    method test_function_definition (line 37) | def test_function_definition(self):
    method test_simple_markdown_block (line 42) | def test_simple_markdown_block(self):
    method test_text_before_markdown (line 47) | def test_text_before_markdown(self):
    method test_text_before_markdown_with_newline (line 52) | def test_text_before_markdown_with_newline(self):
    method test_text_and_markdown (line 57) | def test_text_and_markdown(self):
    method test_markdown_with_text_after (line 62) | def test_markdown_with_text_after(self):
    method test_markdown_with_text (line 67) | def test_markdown_with_text(self):
    method test_text_markdown_text (line 72) | def test_text_markdown_text(self):
    method test_full_example_with_loop (line 79) | def test_full_example_with_loop(self):
    method test_two_markdown_blocks (line 86) | def test_two_markdown_blocks(self):
    method test_two_blocks_with_text (line 93) | def test_two_blocks_with_text(self):
    method test_function_in_markdown (line 100) | def test_function_in_markdown(self):
    method test_empty_string (line 107) | def test_empty_string(self):
    method test_whitespace_only (line 112) | def test_whitespace_only(self):
    method test_markdown_without_python_tag (line 117) | def test_markdown_without_python_tag(self):
    method test_incomplete_markdown_block (line 122) | def test_incomplete_markdown_block(self):
    method test_nested_code_structures (line 127) | def test_nested_code_structures(self):
    method test_code_with_strings_containing_backticks (line 137) | def test_code_with_strings_containing_backticks(self):
    method test_markdown_with_empty_code_block (line 142) | def test_markdown_with_empty_code_block(self):
    method test_class_definition (line 147) | def test_class_definition(self):
    method test_import_statements (line 157) | def test_import_statements(self):
    method test_markdown_with_class_definition (line 162) | def test_markdown_with_class_definition(self):
    method test_multiple_functions_in_markdown (line 169) | def test_multiple_functions_in_markdown(self):
    method test_async_await_statement (line 180) | def test_async_await_statement(self):
    method test_async_await_statement_without_variable (line 187) | def test_async_await_statement_without_variable(self):
    method test_async_await_in_mid_of_code (line 192) | def test_async_await_in_mid_of_code(self):
    method test_string_array_should_not_be_code (line 202) | def test_string_array_should_not_be_code(self):
    method test_email_array_should_not_be_code (line 208) | def test_email_array_should_not_be_code(self):
    method test_number_array_should_not_be_code (line 214) | def test_number_array_should_not_be_code(self):
    method test_mixed_constant_array_should_not_be_code (line 220) | def test_mixed_constant_array_should_not_be_code(self):
    method test_single_boolean_true_should_not_be_code (line 226) | def test_single_boolean_true_should_not_be_code(self):
    method test_single_boolean_false_should_not_be_code (line 231) | def test_single_boolean_false_should_not_be_code(self):
    method test_single_string_constant_should_not_be_code (line 236) | def test_single_string_constant_should_not_be_code(self):
    method test_single_word_without_spaces_should_not_be_code (line 241) | def test_single_word_without_spaces_should_not_be_code(self):
    method test_decimal_number_should_not_be_code (line 246) | def test_decimal_number_should_not_be_code(self):
    method test_multiline_json_array_with_script_true (line 251) | def test_multiline_json_array_with_script_true(self):
    method test_multiline_json_array_should_not_be_code (line 265) | def test_multiline_json_array_should_not_be_code(self):
    method test_multiline_emails (line 275) | def test_multiline_emails(self):
    method test_multiline_json_object_should_not_be_code (line 285) | def test_multiline_json_object_should_not_be_code(self):
    method test_print_with_mismatched_brackets (line 295) | def test_print_with_mismatched_brackets(self):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_sync_async_tools.py
  function mock_state (line 18) | def mock_state():
  function sync_tool (line 26) | def sync_tool():
  function async_tool (line 38) | def async_tool():
  function test_sync_tool_with_await (line 51) | async def test_sync_tool_with_await(mock_state, sync_tool):
  function test_async_tool_with_await (line 83) | async def test_async_tool_with_await(mock_state, async_tool):
  function test_both_sync_and_async_tools_together (line 124) | async def test_both_sync_and_async_tools_together(mock_state, sync_tool,...
  function test_sync_tool_from_structured_tool_directly (line 176) | async def test_sync_tool_from_structured_tool_directly(mock_state):
  function test_async_tool_from_structured_tool_directly (line 218) | async def test_async_tool_from_structured_tool_directly(mock_state):
  function test_sync_tool_from_function_single_param (line 258) | async def test_sync_tool_from_function_single_param(mock_state):
  function test_async_tool_from_function_single_param (line 296) | async def test_async_tool_from_function_single_param(mock_state):
  class UserData (line 334) | class UserData(BaseModel):
  function sync_tool_with_pydantic (line 343) | def sync_tool_with_pydantic():
  function async_tool_with_pydantic (line 355) | def async_tool_with_pydantic():
  function test_sync_tool_with_pydantic_model_conversion (line 368) | async def test_sync_tool_with_pydantic_model_conversion(mock_state, sync...
  function test_async_tool_with_pydantic_model_conversion (line 409) | async def test_async_tool_with_pydantic_model_conversion(mock_state, asy...
  function test_tool_with_non_pydantic_return_value (line 453) | async def test_tool_with_non_pydantic_return_value(mock_state):
  function test_sync_tool_returns_regular_dict (line 487) | async def test_sync_tool_returns_regular_dict(mock_state):
  function test_async_tool_returns_regular_dict (line 523) | async def test_async_tool_returns_regular_dict(mock_state):
  function test_sync_tool_returns_none (line 568) | async def test_sync_tool_returns_none(mock_state):
  function test_async_tool_returns_none (line 603) | async def test_async_tool_returns_none(mock_state):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_tool_call_timeout.py
  function mock_state (line 15) | def mock_state():
  function test_code_execution_timeout (line 23) | async def test_code_execution_timeout(mock_state):
  function test_tool_call_timeout_with_default_timeout (line 46) | async def test_tool_call_timeout_with_default_timeout(mock_state):
  function test_call_api_timeout (line 78) | async def test_call_api_timeout():

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/executors/tests/test_variable_creation_order.py
  class TestVariableCreationOrder (line 14) | class TestVariableCreationOrder:
    method test_variable_creation_order_preserved (line 15) | async def test_variable_creation_order_preserved(self):
    method test_variable_creation_order_with_existing_vars (line 86) | async def test_variable_creation_order_with_existing_vars(self):
    method test_variable_creation_order_multiple_sequential_creations (line 151) | async def test_variable_creation_order_multiple_sequential_creations(s...
    method test_results_is_last_variable_with_missing_dependencies (line 222) | async def test_results_is_last_variable_with_missing_dependencies(self):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/nl_auto_continue_classifier.py
  function build_combined_content_and_reasoning (line 33) | def build_combined_content_and_reasoning(visible: str, reasoning: str) -...
  function normalize_assistant_text (line 48) | def normalize_assistant_text(content: Any) -> str:
  function parse_auto_continue_json (line 71) | def parse_auto_continue_json(raw: str) -> Optional[bool]:
  function classify_nl_auto_continue (line 95) | async def classify_nl_auto_continue(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/prompt_utils.py
  class Tool (line 16) | class Tool(BaseModel):
  class FindToolsOutput (line 45) | class FindToolsOutput(BaseModel):
  class PromptUtils (line 58) | class PromptUtils:
    method get_tool_params_str (line 62) | def get_tool_params_str(tool: StructuredTool) -> str:
    method get_tool_docs (line 113) | def get_tool_docs(tool: StructuredTool) -> tuple[str, str]:
    method find_tools (line 174) | async def find_tools(
    method create_find_tools_bound (line 367) | def create_find_tools_bound(all_tools: List[StructuredTool], all_apps:...
  function format_apps_for_prompt (line 390) | def format_apps_for_prompt(apps) -> list:
  function create_mcp_prompt (line 410) | def create_mcp_prompt(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/reflection/reflection.py
  function reflection_task (line 9) | def reflection_task(llm, enable_format=False) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tests/test_cuga_lite_graph_evolve_guidelines.py
  class _EmptyToolProvider (line 16) | class _EmptyToolProvider(ToolProviderInterface):
    method initialize (line 17) | async def initialize(self):
    method get_apps (line 20) | async def get_apps(self):
    method get_tools (line 23) | async def get_tools(self, app_name: str):
    method get_all_tools (line 26) | async def get_all_tools(self):
  class _CapturingModel (line 30) | class _CapturingModel:
    method __init__ (line 31) | def __init__(self):
    method ainvoke (line 34) | async def ainvoke(self, messages, config=None):
  function test_cuga_lite_evolve_guidelines_are_injected_independently_of_legacy_memory (line 40) | async def test_cuga_lite_evolve_guidelines_are_injected_independently_of...

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tests/test_cuga_lite_node.py
  function test_callback_node_does_not_require_agent_state_error_field (line 13) | async def test_callback_node_does_not_require_agent_state_error_field():
  function test_callback_node_async_save_uses_chat_message_snapshot (line 47) | async def test_callback_node_async_save_uses_chat_message_snapshot():

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tests/test_tool_call_args.py
  function test_single_dict_unpacks_to_named_params (line 4) | def test_single_dict_unpacks_to_named_params():
  function test_single_dict_extra_keys_stripped (line 10) | def test_single_dict_extra_keys_stripped():
  function test_positional_mapping_unchanged (line 16) | def test_positional_mapping_unchanged():
  function test_unknown_dict_assigned_to_first_param (line 21) | def test_unknown_dict_assigned_to_first_param():
  function test_kwargs_merged (line 27) | def test_kwargs_merged():

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tool_approval_handler.py
  class ToolApprovalHandler (line 20) | class ToolApprovalHandler:
    method should_skip_policy_check (line 24) | def should_skip_policy_check(state: "CugaLiteState") -> bool:
    method is_returning_from_approval (line 40) | def is_returning_from_approval(state: "CugaLiteState") -> bool:
    method extract_approved_code (line 53) | def extract_approved_code(state: "CugaLiteState") -> Optional[str]:
    method clean_approval_metadata (line 86) | def clean_approval_metadata(metadata: dict) -> dict:
    method handle_approval_resumption (line 110) | def handle_approval_resumption(state: "CugaLiteState") -> Optional[Com...
    method check_and_create_approval_interrupt (line 153) | async def check_and_create_approval_interrupt(
    method _create_approval_interrupt (line 226) | def _create_approval_interrupt(
    method _generate_approval_message (line 306) | def _generate_approval_message(
    method handle_denial (line 353) | def handle_denial(state: "CugaLiteState") -> Optional[Command]:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tool_call_args.py
  function merge_tool_call_args (line 8) | def merge_tool_call_args(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tool_call_tracker.py
  class ToolCallTracker (line 35) | class ToolCallTracker:
    method is_enabled (line 39) | def is_enabled() -> bool:
    method start_tracking (line 44) | def start_tracking(enabled: bool = True) -> None:
    method stop_tracking (line 56) | def stop_tracking() -> List[Dict[str, Any]]:
    method record_call (line 68) | def record_call(
    method get_current_calls (line 109) | def get_current_calls() -> List[Dict[str, Any]]:
  function tracked_tool (line 116) | def tracked_tool(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tool_provider_interface.py
  class AppDefinition (line 13) | class AppDefinition(BaseModel):
  class ToolProviderInterface (line 22) | class ToolProviderInterface(ABC):
    method get_apps (line 32) | async def get_apps(self) -> List[AppDefinition]:
    method get_tools (line 42) | async def get_tools(self, app_name: str) -> List[StructuredTool]:
    method get_all_tools (line 55) | async def get_all_tools(self) -> List[StructuredTool]:
    method initialize (line 65) | async def initialize(self):

FILE: src/cuga/backend/cuga_graph/nodes/cuga_lite/tool_registry_provider.py
  function call_api (line 24) | async def call_api(
  function _convert_openapi_params_to_json_schema (line 102) | def _convert_openapi_params_to_json_schema(parameters: List[Dict[str, An...
  function create_tool_from_api_dict (line 144) | def create_tool_from_api_dict(
  class ToolRegistryProvider (line 257) | class ToolRegistryProvider(ToolProviderInterface):
    method __init__ (line 265) | def __init__(self, app_names: Optional[List[str]] = None, agent_id: Op...
    method initialize (line 279) | async def initialize(self):
    method get_apps (line 308) | async def get_apps(self) -> List[AppDefinition]:
    method get_tools (line 314) | async def get_tools(self, app_name: str) -> List[StructuredTool]:
    method get_all_tools (line 351) | async def get_all_tools(self) -> List[StructuredTool]:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_supervisor/a2a_protocol.py
  function _agent_card_description (line 42) | def _agent_card_description(agent_card: "AgentCard") -> str:
  function format_agent_card_for_prompt (line 57) | def format_agent_card_for_prompt(agent_card: "AgentCard") -> str:
  function fetch_agent_card (line 89) | async def fetch_agent_card(
  function delegate_task_via_a2a_sdk (line 111) | async def delegate_task_via_a2a_sdk(
  class A2AProtocol (line 158) | class A2AProtocol:
    method __init__ (line 164) | def __init__(
    method connect (line 179) | async def connect(self) -> None:
    method disconnect (line 212) | async def disconnect(self) -> None:
    method _get_auth_headers (line 226) | def _get_auth_headers(self) -> Dict[str, str]:
    method delegate_task (line 232) | async def delegate_task(
    method share_result (line 281) | async def share_result(
    method discover_capabilities (line 317) | async def discover_capabilities(self, agent_name: str) -> List[str]:
    method get_agent_status (line 354) | async def get_agent_status(self, agent_name: str) -> Dict[str, Any]:

FILE: src/cuga/backend/cuga_graph/nodes/cuga_supervisor/cuga_supervisor_graph.py
  function _resolve_names_from_caller_frame (line 38) | def _resolve_names_from_caller_frame(variable_names: List[str]) -> Dict[...
  function extract_and_combine_codeblocks (line 61) | def extract_and_combine_codeblocks(text: str) -> str:
  function make_tool_awaitable (line 90) | def make_tool_awaitable(func):
  function append_chat_messages_with_step_limit (line 102) | def append_chat_messages_with_step_limit(
  function create_error_command (line 127) | def create_error_command(
  function create_cuga_supervisor_graph (line 148) | def create_cuga_supervisor_graph(
  function _create_supervisor_conversational_graph (line 165) | def _create_supervisor_conversational_graph(

FILE: src/cuga/backend/cuga_graph/nodes/cuga_supervisor/cuga_supervisor_node.py
  class CugaSupervisorNode (line 15) | class CugaSupervisorNode(BaseNode):
    method __init__ (line 18) | def __init__(self, langfuse_handler: Optional[Any] = None):
    method set_subgraph (line 24) | def set_subgraph(self, subgraph):
    method node (line 28) | async def node(self, state: AgentState, config: Optional[RunnableConfi...
    method callback_node (line 198) | async def callback_node(self, state: AgentState, config: Optional[Runn...

FILE: src/cuga/backend/cuga_graph/nodes/cuga_supervisor/cuga_supervisor_state.py
  class AgentInfo (line 12) | class AgentInfo(BaseModel):
  class CugaSupervisorState (line 22) | class CugaSupervisorState(AgentState):
    class Config (line 57) | class Config:
    method supervisor_variables_manager (line 61) | def supervisor_variables_manager(self):

FILE: src/cuga/backend/cuga_graph/nodes/human_in_the_loop/followup_model.py
  class ActionType (line 10) | class ActionType(str, Enum):
  class SelectOption (line 22) | class SelectOption(BaseModel):
  class AdditionalData (line 31) | class AdditionalData(BaseModel):
  class FollowUpAction (line 35) | class FollowUpAction(BaseModel):
  function create_save_reuse_action (line 71) | def create_save_reuse_action():
  function create_flow_approve (line 82) | def create_flow_approve(tool: Any):
  function create_new_flow_approve (line 95) | def create_new_flow_approve(tool: Any):
  function create_get_more_utterances (line 108) | def create_get_more_utterances():
  function create_tool_approval_action (line 118) | def create_tool_approval_action(
  function create_agent_approval_action (line 176) | def create_agent_approval_action(
  class ActionResponse (line 225) | class ActionResponse(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/human_in_the_loop/suggest_actions.py
  class SuggestHumanActions (line 14) | class SuggestHumanActions(BaseNode):
    method __init__ (line 15) | def __init__(self):
    method node_handler (line 24) | async def node_handler(state: AgentState, name: str) -> Command[Litera...

FILE: src/cuga/backend/cuga_graph/nodes/human_in_the_loop/wait_for_response.py
  class WaitForResponse (line 17) | class WaitForResponse(BaseNode):
    method __init__ (line 18) | def __init__(self):
    method node_handler (line 26) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/save_reuse/save_reuse_agent/reuse_agent.py
  function ensure_parent_directory_exists (line 25) | def ensure_parent_directory_exists(file_path):
  class ReuseAgent (line 33) | class ReuseAgent(BaseAgent):
    method __init__ (line 34) | def __init__(
    method output_parser (line 66) | def output_parser(self, result: AIMessage, name) -> Any:
    method get_text_after_last_backticks (line 70) | def get_text_after_last_backticks(self, text):
    method save_html_to_file (line 80) | def save_html_to_file(self, html_content, filename):
    method run (line 93) | async def run(self, input_variables: AgentState, additional_utterance=...
    method create (line 169) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/save_reuse/save_reuse_agent/utils/export_mcp.py
  function extract_python_code_blocks (line 18) | def extract_python_code_blocks(text_content: str) -> List[str]:
  function extract_imports_and_functions_from_code (line 24) | def extract_imports_and_functions_from_code(code_string: str) -> Tuple[L...
  function parse_existing_server (line 68) | def parse_existing_server(server_file: Path) -> Tuple[List[str], List[st...
  function validate_python_code (line 99) | def validate_python_code(code_string: str) -> bool:
  function generate_or_update_server (line 109) | def generate_or_update_server(
  function process_text_file (line 211) | def process_text_file(
  function main (line 256) | def main():

FILE: src/cuga/backend/cuga_graph/nodes/save_reuse/save_reuse_agent/utils/save_reuse.py
  function get_python_content_from_trajectory (line 15) | def get_python_content_from_trajectory():
  function read_python_files (line 27) | def read_python_files(file_pattern="f*.py"):
  function consolidate_flow (line 45) | async def consolidate_flow(chain, user_intent, file_pattern="f*.py", dyn...

FILE: src/cuga/backend/cuga_graph/nodes/save_reuse/save_reuse_node.py
  class SaveReuseNode (line 18) | class SaveReuseNode(BaseNode):
    method __init__ (line 19) | def __init__(self, agent: ReuseAgent):
    method node_handler (line 30) | async def node_handler(state: AgentState, agent: ReuseAgent, name: str...

FILE: src/cuga/backend/cuga_graph/nodes/shared/base_agent.py
  function create_partial (line 45) | def create_partial(func, **kwargs):
  class BaseAgent (line 55) | class BaseAgent(ABC):
    method __init__ (line 56) | def __init__(self):
    method validate_and_retry_output (line 60) | def validate_and_retry_output(output, schema):
    method create_validated_structured_output_chain (line 73) | def create_validated_structured_output_chain(
    method get_format_instructions (line 104) | def get_format_instructions(parser: PydanticOutputParser) -> str:
    method get_chain (line 129) | def get_chain(

FILE: src/cuga/backend/cuga_graph/nodes/shared/base_node.py
  class BaseNode (line 1) | class BaseNode:
    method __init__ (line 2) | def __init__(self):

FILE: src/cuga/backend/cuga_graph/nodes/shared/interrupt_tool_node.py
  class InterruptToolNode (line 12) | class InterruptToolNode(BaseNode):
    method __init__ (line 13) | def __init__(self):
    method node_handler (line 22) | async def node_handler(state: AgentState, name: str, config: RunnableC...

FILE: src/cuga/backend/cuga_graph/nodes/shared/location_solver.py
  class LocationSolver (line 13) | class LocationSolver(BaseNode):
    method __init__ (line 14) | def __init__(self, agent: LocationResolverAgent):
    method node_handler (line 25) | async def node_handler(state: AgentState, agent: LocationResolverAgent...

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/analyze_task.py
  class TaskAnalyzer (line 29) | class TaskAnalyzer(BaseNode):
    method __init__ (line 30) | def __init__(self, task_analyzer_agent: TaskAnalyzerAgent):
    method find_by_attribute (line 41) | def find_by_attribute(items: List[BaseModel], attr_name: str, attr_val...
    method match_apps (line 49) | async def match_apps(
    method call_authenticate_apps (line 114) | async def call_authenticate_apps(apps: List[str]):
    method should_use_supervisor_mode (line 126) | async def should_use_supervisor_mode(state: AgentState) -> bool:
    method should_use_fast_mode_early (line 144) | async def should_use_fast_mode_early(state: AgentState) -> bool:
    method node_handler (line 178) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/location_resolver_agent/google_search_agent.py
  class GoogleSearchAgent (line 19) | class GoogleSearchAgent(BaseAgent):
    method __init__ (line 20) | def __init__(self, prompt_template: Optional[ChatPromptTemplate], llm:...
    method output_parser (line 57) | def output_parser(result: FinalAnswerOutput, name) -> Any:
    method run (line 61) | async def run(self, question: str) -> AIMessage:
    method create (line 65) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/location_resolver_agent/location_resolver_agent.py
  function search_google (line 30) | async def search_google(implicit_location: str, config: RunnableConfig):
  class LocationResolverAgent (line 46) | class LocationResolverAgent(BaseAgent):
    method __init__ (line 47) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 76) | def output_parser(result: FinalAnswerOutput, name) -> Any:
    method run (line 80) | async def run(self, intent) -> AIMessage:
    method create (line 101) | def create():
  function run_internal_mapping_tests (line 110) | async def run_internal_mapping_tests():
  function main (line 179) | async def main():

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/plan_controller.py
  function find_substring (line 25) | def find_substring(string_array, target_string):
  class PlanControllerNode (line 43) | class PlanControllerNode(BaseNode):
    method __init__ (line 44) | def __init__(self, plan_controller_agent: PlanControllerAgent):
    method node_handler (line 54) | async def node_handler(

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/plan_controller_agent/plan_controller_agent.py
  class PlanControllerAgent (line 27) | class PlanControllerAgent(BaseAgent):
    method __init__ (line 28) | def __init__(self, prompt_template: ChatPromptTemplate, llm: BaseChatM...
    method output_parser (line 41) | def output_parser(result: PlanControllerOutput, name) -> Any:
    method run (line 48) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 93) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/plan_controller_agent/prompts/load_prompt.py
  class PlanControllerOutput (line 6) | class PlanControllerOutput(BaseModel):
    method convert_empty_to_none (line 23) | def convert_empty_to_none(cls, v):
    method validate_api_task_has_app (line 29) | def validate_api_task_has_app(self):

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/prompts/load_prompt.py
  class AnalyzeTaskOutput (line 13) | class AnalyzeTaskOutput(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/task_analyzer_agent.py
  class TaskAnalyzerAgent (line 31) | class TaskAnalyzerAgent(BaseAgent):
    method __init__ (line 32) | def __init__(self):
    method run (line 41) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 96) | def create():

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/tasks/app_matcher.py
  class AppMatch (line 13) | class AppMatch(BaseModel):
  function match_apps_for_intent (line 20) | def match_apps_for_intent(model_config) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/tasks/classify_task.py
  class Attributes (line 13) | class Attributes(BaseModel):
  function classify_task (line 21) | def classify_task(model_config) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/tasks/navigation_paths_task.py
  class Approach (line 13) | class Approach(BaseModel):
  class Approaches (line 19) | class Approaches(BaseModel):
  function navigation_paths_task (line 24) | def navigation_paths_task(model_config) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_analyzer_agent/tasks/paraphrase.py
  class Paraphrase (line 13) | class Paraphrase(BaseModel):
  function paraphrase_task (line 18) | def paraphrase_task(model_config) -> Runnable:

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_decomposition.py
  class TaskDecompositionNode (line 21) | class TaskDecompositionNode(BaseNode):
    method __init__ (line 22) | def __init__(self, task_decomposition_agent: TaskDecompositionAgent):
    method node_handler (line 32) | async def node_handler(state: AgentState, agent: TaskDecompositionAgen...

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_decomposition_agent/prompts/load_prompt.py
  class DecomposedTask (line 7) | class DecomposedTask(BaseModel):
  class TaskDecompositionPlan (line 13) | class TaskDecompositionPlan(BaseModel):
    method format_as_list (line 17) | def format_as_list(self):
  class TaskDecompositionMultiOutput (line 26) | class TaskDecompositionMultiOutput(BaseModel):

FILE: src/cuga/backend/cuga_graph/nodes/task_decomposition_planning/task_decomposition_agent/task_decomposition_agent.py
  class TaskDecompositionAgent (line 26) | class TaskDecompositionAgent(BaseAgent):
    method __init__ (line 27) | def __init__(self, prompt_template: ChatPromptTemplate, llm: ChatOpenA...
    method output_parser (line 49) | def output_parser(result: TaskDecompositionPlan, name) -> Any:
    method run (line 53) | async def run(self, input_variables: AgentState) -> AIMessage:
    method create (line 66) | def create():

FILE: src/cuga/backend/cuga_graph/policy/agent.py
  class PlaybookEnactment (line 34) | class PlaybookEnactment(BaseModel):
  class PolicyConflictResolution (line 43) | class PolicyConflictResolution(BaseModel):
  class PolicyContext (line 63) | class PolicyContext(BaseModel):
    method get_target_text (line 78) | def get_target_text(self, target: str) -> str:
    method get_query_text (line 105) | def get_query_text(self) -> Optional[str]:
    method to_context_string (line 126) | def to_context_string(self) -> str:
  class PolicyAgent (line 146) | class PolicyAgent:
    method __init__ (line 149) | def __init__(
    method _check_trigger (line 167) | async def _check_trigger(self, trigger: Trigger, context: PolicyContex...
    method _check_policy_triggers (line 323) | async def _check_policy_triggers(
    method _create_policy_action (line 363) | async def _create_policy_action(self, policy: Policy, confidence: floa...
    method _build_conflict_resolution_user_prompt (line 478) | def _build_conflict_resolution_user_prompt(
    method _resolve_nl_trigger_conflicts (line 518) | async def _resolve_nl_trigger_conflicts(
    method _evaluate_keyword_triggered_policies (line 681) | async def _evaluate_keyword_triggered_policies(
    method _evaluate_natural_language_policies (line 763) | async def _evaluate_natural_language_policies(
    method match_policy (line 925) | async def match_policy(
    method match_policies_by_type (line 1033) | async def match_policies_by_type(
    method explain_match (line 1093) | async def explain_match(self, policy_match: PolicyMatch) -> str:
    method enact_playbook (line 1124) | async def enact_playbook(self, playbook: Playbook, context: PolicyCont...
    method _refine_playbook_plan (line 1158) | async def _refine_playbook_plan(self, playbook: Playbook, context: Pol...
    method check_tool_guide_policies (line 1224) | async def check_tool_guide_policies(self, context: PolicyContext) -> L...
    method check_tool_approval_for_code (line 1279) | async def check_tool_approval_for_code(self, code: str, context: Polic...
    method _check_code_uses_tools (line 1351) | def _check_code_uses_tools(

FILE: src/cuga/backend/cuga_graph/policy/cli.py
  function get_storage (line 27) | async def get_storage(policy_db_path: Optional[str] = None) -> PolicySto...
  function list_policies (line 40) | def list_policies(
  function show_policy (line 89) | def show_policy(
  function delete_policy (line 123) | def delete_policy(
  function load_from_file (line 159) | def load_from_file(
  function export_to_file (line 177) | def export_to_file(
  function backup (line 202) | def backup(
  function restore (line 225) | def restore(
  function stats (line 243) | def stats(
  function test_match (line 270) | def test_match(
  function validate (line 324) | def validate(

FILE: src/cuga/backend/cuga_graph/policy/configurable.py
  class PolicyConfigurable (line 17) | class PolicyConfigurable:
    method __init__ (line 42) | def __init__(
    method get_instance (line 64) | def get_instance(cls) -> "PolicyConfigurable":
    method from_config (line 71) | def from_config(cls, config: RunnableConfig) -> "PolicyConfigurable":
    method initialize (line 92) | async def initialize(
    method match_policy (line 204) | async def match_policy(
    method match_policies_by_type (line 224) | async def match_policies_by_type(
    method to_config_dict (line 242) | def to_config_dict(self) -> Dict[str, Any]:
    method create_context_from_state (line 252) | def create_context_from_state(
  function check_policy_in_node (line 349) | async def check_policy_in_node(state: Any, config: RunnableConfig) -> Op...

FILE: src/cuga/backend/cuga_graph/policy/enactment.py
  class PolicyEnactment (line 24) | class PolicyEnactment:
    method check_and_enact (line 28) | async def check_and_enact(
    method _merge_guide_metadata (line 148) | def _merge_guide_metadata(guide_matches: List[PolicyMatch]) -> Dict[st...
    method _enact_policy_action (line 185) | async def _enact_policy_action(
    method _enact_block_intent (line 231) | def _enact_block_intent(state: Any, policy_match: PolicyMatch) -> tupl...
    method _enact_guide_prompt (line 269) | async def _enact_guide_prompt(
    method _enact_modify_tools (line 325) | def _enact_modify_tools(state: Any, policy_match: PolicyMatch) -> tupl...
    method _enact_inject_context (line 353) | def _enact_inject_context(state: Any, policy_match: PolicyMatch) -> tu...
    method _enact_log_only (line 379) | def _enact_log_only(state: Any, policy_match: PolicyMatch) -> tuple[No...
    method inject_playbook_into_prompt (line 404) | def inject_playbook_into_prompt(base_prompt: str, metadata: Optional[D...
    method apply_tool_restrictions (line 441) | def apply_tool_restrictions(tools: list, metadata: Optional[Dict[str, ...
    method get_restriction_message (line 466) | def get_restriction_message(metadata: Optional[Dict[str, Any]]) -> Opt...
    method _enact_tool_guide (line 482) | def _enact_tool_guide(state: Any, policy_match: PolicyMatch) -> tuple[...
    method _enact_tool_approval (line 512) | def _enact_tool_approval(state: Any, policy_match: PolicyMatch) -> tup...
    method apply_tool_guide (line 543) | def apply_tool_guide(tools: list, metadata: Optional[Dict[str, Any]]) ...
    method check_tool_approval_required (line 668) | def check_tool_approval_required(
    method check_code_for_tool_approval (line 699) | def check_code_for_tool_approval(code: str, metadata: Optional[Dict[st...
    method _enact_format_output (line 754) | async def _enact_format_output(

FILE: src/cuga/backend/cuga_graph/policy/examples.py
  function create_example_playbook (line 23) | async def create_example_playbook() -> Playbook:
  function create_example_intent_guard (line 113) | async def create_example_intent_guard() -> IntentGuard:
  function create_example_custom_policy (line 151) | async def create_example_custom_policy() -> CustomPolicy:
  function setup_example_policies (line 175) | async def setup_example_policies(storage: PolicyStorage, embedding_funct...
  function example_usage_in_node (line 202) | async def example_usage_in_node(state, config: RunnableConfig):
  function example_standalone_usage (line 252) | async def example_standalone_usage():

FILE: src/cuga/backend/cuga_graph/policy/filesystem_sync.py
  class PolicyFilesystemSync (line 27) | class PolicyFilesystemSync:
    method __init__ (line 37) | def __init__(self, cuga_folder: str = ".cuga"):
    method _ensure_folder_structure (line 47) | def _ensure_folder_structure(self):
    method _get_subfolder_for_policy (line 61) | def _get_subfolder_for_policy(self, policy: Policy) -> str:
    method _policy_to_markdown (line 81) | def _policy_to_markdown(self, policy: Policy) -> str:
    method save_policy_to_file (line 166) | def save_policy_to_file(self, policy: Policy) -> str:
    method delete_policy_file (line 203) | def delete_policy_file(self, policy_id: str) -> bool:
    method _find_policy_file (line 234) | def _find_policy_file(self, policy_id: str) -> Optional[str]:
    method get_filesystem_policy_ids (line 255) | def get_filesystem_policy_ids(self) -> Set[str]:
    method sync_removals (line 294) | async def sync_removals(self, storage) -> List[str]:

FILE: src/cuga/backend/cuga_graph/policy/folder_loader.py
  function parse_markdown_with_frontmatter (line 27) | def parse_markdown_with_frontmatter(file_path: str) -> tuple[Dict[str, A...
  function create_triggers_from_metadata (line 65) | def create_triggers_from_metadata(triggers_config: Dict[str, Any]) -> Li...
  function create_playbook_from_markdown (line 106) | def create_playbook_from_markdown(
  function create_output_formatter_from_markdown (line 143) | def create_output_formatter_from_markdown(
  function create_tool_guide_from_markdown (line 184) | def create_tool_guide_from_markdown(
  function create_intent_guard_from_markdown (line 227) | def create_intent_guard_from_markdown(
  function create_tool_approval_from_markdown (line 271) | def create_tool_approval_from_markdown(
  function load_policies_from_folder (line 319) | async def load_policies_from_folder(

FILE: src/cuga/backend/cuga_graph/policy/models.py
  class PolicyType (line 9) | class PolicyType(str, Enum):
  class PolicyActionType (line 20) | class PolicyActionType(str, Enum):
  class NaturalLanguageTrigger (line 35) | class NaturalLanguageTrigger(BaseModel):
  class KeywordTrigger (line 51) | class KeywordTrigger(BaseModel):
  class AppTrigger (line 67) | class AppTrigger(BaseModel):
  class StateTrigger (line 74) | class StateTrigger(BaseModel):
  class ToolTrigger (line 83) | class ToolTrigger(BaseModel):
  class AlwaysTrigger (line 93) | class AlwaysTrigger(BaseModel):
  class PlaybookStep (line 111) | class PlaybookStep(BaseModel):
  class Playbook (line 120) | class Playbook(BaseModel):
    method validate_trigger_targets (line 137) | def validate_trigger_targets(self):
  class IntentGuardResponse (line 158) | class IntentGuardResponse(BaseModel):
  class IntentGuard (line 168) | class IntentGuard(BaseModel):
    method validate_trigger_targets (line 183) | def validate_trigger_targets(self):
  class ToolGuide (line 204) | class ToolGuide(BaseModel):
  class ToolApproval (line 223) | class ToolApproval(BaseModel):
  class OutputFormatter (line 254) | class OutputFormatter(BaseModel):
    method validate_trigger_targets (line 283) | def validate_trigger_targets(self):
  class CustomPolicy (line 304) | class CustomPolicy(BaseModel):
  class PolicyAction (line 323) | class PolicyAction(BaseModel):
  class PolicyMatch (line 336) | class PolicyMatch(BaseModel):

FILE: src/cuga/backend/cuga_graph/policy/output_formatter_utils.py
  function apply_output_formatter_policies (line 19) | async def apply_output_formatter_policies(
  function _update_output_formatter_metadata (line 65) | def _update_output_formatter_metadata(state: AgentState, metadata: dict,...

FILE: src/cuga/backend/cuga_graph/policy/storage.py
  class PolicyStorage (line 26) | class PolicyStorage:
    method __init__ (line 29) | def __init__(
    method connect (line 55) | async def connect(self) -> None:
    method disconnect (line 59) | async def disconnect(self) -> None:
    method _create_collection (line 63) | async def _create_collection(self) -> None:
    method embedding_provider (line 67) | def embedding_provider(self) -> str:
    method _initialize_embedding_function (line 73) | async def _initialize_embedding_function(self):
    method initialize_async (line 110) | async def initialize_async(self):
    method _generate_policy_embedding (line 121) | async def _generate_policy_embedding(self, policy: Policy) -> List[flo...
    method _policy_to_dict (line 242) | def _policy_to_dict(self, policy: Policy) -> Dict:
    method _dict_to_policy (line 256) | def _dict_to_policy(self, data: Dict) -> Policy:
    method add_policy (line 347) | async def add_policy(self, policy: Policy, embedding: Optional[List[fl...
    method update_policy (line 366) | async def update_policy(self, policy: Policy, embedding: Optional[List...
    method delete_policy (line 370) | async def delete_policy(self, policy_id: str):
    method get_policy (line 380) | async def get_policy(self, policy_id: str) -> Optional[Policy]:
    method search_policies (line 392) | async def search_policies(
    method list_policies (line 415) | async def list_policies(
    method count_policies (line 432) | async def count_policies(self, policy_type: Optional[PolicyType] = Non...

FILE: src/cuga/backend/cuga_graph/policy/tests/helpers.py
  function setup_policy_storage (line 22) | async def setup_policy_storage(
  function setup_llm_manager (line 80) | async def setup_llm_manager(model_type: str = "chat") -> Any:
  function setup_langfuse_tracing (line 102) | def setup_langfuse_tracing() -> Optional[Any]:
  function setup_policy_system (line 122) | async def setup_policy_system(
  function setup_cuga_lite_graph (line 146) | async def setup_cuga_lite_graph(
  function create_initial_state (line 172) | def create_initial_state(
  function create_graph_config (line 197) | def create_graph_config(
  function run_graph_execution (line 232) | async def run_graph_execution(
  class MinimalToolProvider (line 263) | class MinimalToolProvider(ToolProviderInterface):
    method initialize (line 266) | async def initialize(self):
    method get_apps (line 269) | async def get_apps(self):
    method get_all_tools (line 272) | async def get_all_tools(self):
    method get_tools (line 275) | async def get_tools(self, app_name):
  function setup_full_agent_graph (line 282) | async def setup_full_agent_graph(
  function add_tool_approval_policy (line 307) | async def add_tool_approval_policy(
  function add_tool_guide_policy (line 347) | async def add_tool_guide_policy(
  function create_agent_initial_state (line 392) | def create_agent_initial_state(
  function run_graph_until_interrupt (line 420) | async def run_graph_until_interrupt(
  function resume_graph_with_response (line 449) | async def resume_graph_with_response(
  function run_full_graph_to_completion (line 483) | async def run_full_graph_to_completion(

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_healthcare_family_claims.py
  function test_healthcare_family_claims_e2e_with_tools (line 25) | async def test_healthcare_family_claims_e2e_with_tools():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_intent_guard.py
  function test_e2e_intent_guard_blocks_in_cuga_lite (line 26) | async def test_e2e_intent_guard_blocks_in_cuga_lite():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_intent_guard_priority.py
  function test_intent_guard_priority_over_playbook (line 28) | async def test_intent_guard_priority_over_playbook():
  function test_multiple_intent_guards_all_checked (line 185) | async def test_multiple_intent_guards_all_checked():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_output_formatter.py
  function test_e2e_output_formatter_with_keyword_trigger (line 34) | async def test_e2e_output_formatter_with_keyword_trigger():
  function test_e2e_output_formatter_with_natural_language_trigger (line 189) | async def test_e2e_output_formatter_with_natural_language_trigger():
  function test_e2e_output_formatter_no_trigger (line 340) | async def test_e2e_output_formatter_no_trigger():
  function test_e2e_output_formatter_json_schema_structured_output (line 478) | async def test_e2e_output_formatter_json_schema_structured_output():
  function test_e2e_output_formatter_sensitive_data_blocking (line 660) | async def test_e2e_output_formatter_sensitive_data_blocking():
  function test_e2e_output_formatter_sdk_integration (line 878) | async def test_e2e_output_formatter_sdk_integration():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_playbook_guidance.py
  function test_e2e_playbook_guides_execution_in_cuga_lite (line 21) | async def test_e2e_playbook_guides_execution_in_cuga_lite():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_playbook_refinement.py
  function test_e2e_playbook_refinement_with_progress (line 25) | async def test_e2e_playbook_refinement_with_progress():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_e2e_tool_enrichment.py
  function test_tool_guide_with_keyword_trigger (line 25) | async def test_tool_guide_with_keyword_trigger():
  function test_tool_guide_multiple_keywords (line 274) | async def test_tool_guide_multiple_keywords():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_filesystem_sync.py
  function test_tool (line 36) | def test_tool(input_data: str) -> str:
  function temp_cuga_folder (line 42) | def temp_cuga_folder():
  function clean_policy_storage (line 55) | async def clean_policy_storage():
  class TestFilesystemSyncBasics (line 70) | class TestFilesystemSyncBasics:
    method test_policy_filesystem_sync_initialization (line 74) | async def test_policy_filesystem_sync_initialization(self, temp_cuga_f...
    method test_save_policy_to_filesystem (line 148) | async def test_save_policy_to_filesystem(
    method test_delete_policy_file (line 168) | async def test_delete_policy_file(self, temp_cuga_folder):
    method test_get_filesystem_policy_ids (line 188) | async def test_get_filesystem_policy_ids(self, temp_cuga_folder):
  class TestSDKFilesystemSync (line 219) | class TestSDKFilesystemSync:
    method test_auto_save_on_add_policy (line 253) | async def test_auto_save_on_add_policy(self, temp_cuga_folder, add_met...
    method test_auto_delete_from_filesystem (line 270) | async def test_auto_delete_from_filesystem(self, temp_cuga_folder):
    method test_filesystem_sync_disabled (line 297) | async def test_filesystem_sync_disabled(self, temp_cuga_folder):
  class TestAutoLoadPolicies (line 318) | class TestAutoLoadPolicies:
    method test_auto_load_from_folder (line 322) | async def test_auto_load_from_folder(self, temp_cuga_folder):
    method test_auto_load_multiple_policy_types (line 352) | async def test_auto_load_multiple_policy_types(self, temp_cuga_folder):
    method test_auto_load_disabled (line 403) | async def test_auto_load_disabled(self, temp_cuga_folder):
  class TestBidirectionalSync (line 431) | class TestBidirectionalSync:
    method test_validation_adds_fs_policies_to_db (line 435) | async def test_validation_adds_fs_policies_to_db(self, temp_cuga_folder):
    method test_validation_saves_db_policies_to_fs (line 465) | async def test_validation_saves_db_policies_to_fs(self, temp_cuga_fold...
    method test_validation_removes_deleted_fs_policies_from_db (line 498) | async def test_validation_removes_deleted_fs_policies_from_db(self, te...
  class TestLoadFromFolder (line 541) | class TestLoadFromFolder:
    method test_load_from_folder_manual (line 545) | async def test_load_from_folder_manual(self, temp_cuga_folder):
    method test_load_from_folder_clear_existing (line 578) | async def test_load_from_folder_clear_existing(self, temp_cuga_folder):
  class TestGlobalSettings (line 624) | class TestGlobalSettings:
    method test_agent_uses_default_settings (line 628) | async def test_agent_uses_default_settings(self):
    method test_agent_overrides_settings (line 639) | async def test_agent_overrides_settings(self, temp_cuga_folder):
  class TestEdgeCases (line 654) | class TestEdgeCases:
    method test_missing_cuga_folder (line 658) | async def test_missing_cuga_folder(self):
    method test_empty_cuga_folder (line 674) | async def test_empty_cuga_folder(self, temp_cuga_folder):
    method test_multiple_agents_same_folder (line 687) | async def test_multiple_agents_same_folder(self, temp_cuga_folder):
    method test_invalid_policy_file_ignored (line 716) | async def test_invalid_policy_file_ignored(self, temp_cuga_folder):

FILE: src/cuga/backend/cuga_graph/policy/tests/test_keyword_operator.py
  function test_keyword_trigger_and_operator (line 11) | async def test_keyword_trigger_and_operator():
  function test_keyword_trigger_or_operator (line 97) | async def test_keyword_trigger_or_operator():
  function test_keyword_operator_case_sensitivity (line 202) | async def test_keyword_operator_case_sensitivity():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_nl_trigger_conflict_resolution.py
  function test_nl_trigger_conflict_playbook_vs_intent_guard (line 27) | async def test_nl_trigger_conflict_playbook_vs_intent_guard():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_similarity_integration.py
  function storage (line 30) | async def storage():
  function policy_agent (line 67) | async def policy_agent(storage):
  function test_similarity_integration (line 78) | async def test_similarity_integration(storage, policy_agent):
  function main (line 382) | async def main():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_tool_approval_full_graph.py
  function _pending_tool_approval_code (line 28) | def _pending_tool_approval_code(state: AgentState) -> str:
  function create_digital_sales_tool_provider (line 56) | def create_digital_sales_tool_provider() -> ToolProviderInterface:
  function test_tool_approval_approve_flow (line 103) | async def test_tool_approval_approve_flow():
  function test_tool_approval_deny_flow (line 235) | async def test_tool_approval_deny_flow():
  function test_tool_approval_modification_flow (line 351) | async def test_tool_approval_modification_flow():

FILE: src/cuga/backend/cuga_graph/policy/tests/test_utils.py
  function test_validate_output_formatter_valid (line 6) | def test_validate_output_formatter_valid():
  function test_validate_output_formatter_missing_required (line 18) | def test_validate_output_formatter_missing_required():
  function test_validate_output_formatter_empty_triggers (line 24) | def test_validate_output_formatter_empty_triggers():
  function test_validate_output_formatter_invalid_format_type (line 36) | def test_validate_output_formatter_invalid_format_type():
  function test_validate_output_formatter_json_schema_invalid_json (line 49) | def test_validate_output_formatter_json_schema_invalid_json():
  function test_validate_output_formatter_json_schema_valid (line 62) | def test_validate_output_formatter_json_schema_valid():

FILE: src/cuga/backend/cuga_graph/policy/utils.py
  function get_embedding_dimension (line 22) | def get_embedding_dimension(provider: str = "auto", model_name: Optional...
  function parse_markdown_to_steps (line 29) | def parse_markdown_to_steps(markdown_content: str) -> List[Dict[str, Any]]:
  function validate_output_formatter (line 79) | def validate_output_formatter(data: Dict[str, Any]) -> List[str]:
  function apply_policies_data_to_storage (line 113) | async def apply_policies_data_to_storage(
  function load_policies_from_json (line 283) | async def load_policies_from_json(
  function export_policies_to_json (line 344) | async def export_policies_to_json(
  function backup_policies (line 376) | async def backup_policies(storage: PolicyStorage, backup_dir: str) -> bool:
  function restore_policies (line 404) | async def restore_policies(storage: PolicyStorage, backup_dir: str) -> int:
  function validate_policy (line 437) | def validate_policy(policy: Policy) -> tuple[bool, List[str]]:
  function get_policy_statistics (line 477) | async def get_policy_statistics(storage: PolicyStorage) -> Dict[str, Any]:
  function format_policy_summary (line 515) | def format_policy_summary(policy: Policy) -> str:

FILE: src/cuga/backend/cuga_graph/state/agent_state.py
  class ToolCallRecord (line 29) | class ToolCallRecord(BaseModel):
  class VariableMetadata (line 42) | class VariableMetadata:
    method __init__ (line 43) | def __init__(self, value: Any, description: Optional[str] = None, crea...
    method _calculate_count (line 50) | def _calculate_count(self, value: Any) -> int:
    method to_dict (line 66) | def to_dict(
  class VariablesManager (line 83) | class VariablesManager(object):
    method __init__ (line 86) | def __init__(self):
    method _initialize_logging (line 95) | def _initialize_logging(self):
    method _get_caller_info (line 109) | def _get_caller_info(self, skip_frames=2) -> str:
    method _log_operation (line 123) | def _log_operation(self, operation: str, details: str, extra_info: Opt...
    method add_variable (line 143) | def add_variable(self, value: Any, name: Optional[str] = None, descrip...
    method get_variable (line 207) | def get_variable(self, name: str) -> Any:
    method get_variable_metadata (line 220) | def get_variable_metadata(self, name: str) -> Optional[VariableMetadata]:
    method get_all_variables_metadata (line 232) | def get_all_variables_metadata(
    method get_variables_summary (line 250) | def get_variables_summary(
    method _get_value_preview (line 330) | def _get_value_preview(self, value: Any, max_length: int = 5000) -> str:
    method get_variables_formatted (line 436) | def get_variables_formatted(self) -> str:
    method get_variables_as_json (line 453) | def get_variables_as_json(self) -> str:
    method get_last_variable (line 474) | def get_last_variable(self) -> tuple[str, VariableMetadata]:
    method present_variable (line 489) | def present_variable(self, variable_name):
    method get_last_variable_metadata (line 565) | def get_last_variable_metadata(self) -> tuple[str, VariableMetadata]:
    method get_variable_names (line 580) | def get_variable_names(self) -> list[str]:
    method get_last_n_variable_names (line 589) | def get_last_n_variable_names(self, n: int) -> list[str]:
    method remove_variable (line 603) | def remove_variable(self, name: str) -> bool:
    method update_variable_description (line 638) | def update_variable_description(self, name: str, description: str) -> ...
    method get_variables_by_type (line 654) | def get_variables_by_type(self, type_name: str) -> Dict[str, Any]:
    method replace_variables_placeholders (line 668) | def replace_variables_placeholders(self, text: str):
    method reset (line 675) | def reset(self) -> None:
    method reset_keep_last_n (line 700) | def reset_keep_last_n(self, n: int) -> None:
    method get_variable_count (line 755) | def get_variable_count(self) -> int:
    method __str__ (line 764) | def __str__(self) -> str:
    method __repr__ (line 768) | def __repr__(self) -> str:
  class StateVariablesManager (line 773) | class StateVariablesManager(VariablesManager):
    method __init__ (line 776) | def __init__(self, state: 'AgentState'):
    method variables (line 782) | def variables(self) -> Dict[str, VariableMetadata]:
    method variables (line 796) | def variables(self, value: Dict[str, VariableMetadata]):
    method variable_counter (line 811) | def variable_counter(self) -> int:
    method variable_counter (line 815) | def variable_counter(self, value: int):
    method _creation_order (line 819) | def _creation_order(self) -> list:
    method _creation_order (line 823) | def _creation_order(self, value: list):
    method add_variable (line 826) | def add_variable(self, value: Any, name: Optional[str] = None, descrip...
    method remove_variable (line 861) | def remove_variable(self, name: str) -> bool:
  function default_state (line 898) | def default_state(page, observation, goal, chat_messages=None):
  class SubTaskHistory (line 908) | class SubTaskHistory(BaseModel):
  class AnalyzeTaskAppsOutput (line 914) | class AnalyzeTaskAppsOutput(BaseModel):
  class AgentState (line 921) | class AgentState(BaseModel):
    method variables_manager (line 1002) | def variables_manager(self) -> 'StateVariablesManager':
    method append_to_last_chat_message (line 1011) | def append_to_last_chat_message(self, value: str):
    method apply_message_sliding_window (line 1016) | def apply_message_sliding_window(self):
    method format_subtask (line 1038) | def format_subtask(self):
    method manage_message_context (line 1041) | async def manage_message_context(
    method _summarize_message_list (line 1106) | async def _summarize_message_list(
    method manage_rolling_window (line 1173) | async def manage_rolling_window(self):

FILE: src/cuga/backend/cuga_graph/state/api_planner_history.py
  class ConcludeTaskStatus (line 7) | class ConcludeTaskStatus(str, Enum):
  class VariableMetadata (line 14) | class VariableMetadata(BaseModel):
  class VariableSummaryEntry (line 27) | class VariableSummaryEntry(BaseModel):
  class CoderAgentHistoricalOutput (line 36) | class CoderAgentHistoricalOutput(BaseModel):
  class FilteredApiEntry (line 43) | class FilteredApiEntry(BaseModel):
  class ApiFilteringAgentHistoricalOutput (line 53) | class ApiFilteringAgentHistoricalOutput(BaseModel):
  class ConcludeTaskHistoricalOutput (line 63) | class ConcludeTaskHistoricalOutput(BaseModel):
  class HistoricalAction (line 83) | class HistoricalAction(BaseModel):

FILE: src/cuga/backend/cuga_graph/utils/agent_loop.py
  class OutputFormat (line 38) | class OutputFormat(str, Enum):
  class TokenUsageTracker (line 43) | class TokenUsageTracker(AsyncCallbackHandler):
    method __init__ (line 44) | def __init__(self, tracker: ActivityTracker):
    method on_llm_end (line 47) | async def on_llm_end(self, response: LLMResult, **kwargs):
    method split_system_human (line 52) | def split_system_human(self, text):
    method on_llm_start (line 97) | async def on_llm_start(
  class AgentLoopAnswer (line 118) | class AgentLoopAnswer(BaseModel):
  class StreamEvent (line 131) | class StreamEvent(BaseModel):
    method format_data (line 140) | def format_data(data_str: str) -> str:
    method parse (line 160) | def parse(formatted_str: str) -> 'StreamEvent':
    method format_event (line 209) | def format_event(raw_event: str) -> str:
    method prepare_message (line 234) | def prepare_message(event, thread_id):
    method format (line 245) | def format(self, format: OutputFormat = None, **kwargs) -> str:
  class AgentLoop (line 262) | class AgentLoop:
    method __init__ (line 268) | def __init__(
    method stream_event (line 298) | async def stream_event(self, event: StreamEvent) -> Generator[str, Non...
    method get_event_message (line 301) | def get_event_message(self, event) -> StreamEvent:
    method get_stream (line 478) | def get_stream(self, state, resume=None):
    method get_langfuse_trace_id (line 518) | def get_langfuse_trace_id(self) -> Optional[str]:
    method get_output (line 524) | def get_output(self, event):
    method run_stream (line 668) | async def run_stream(self, state: Optional[AgentState] = None, resume=...
    method get_output_of_obj (line 690) | def get_output_of_obj(self, dict):
    method show_chat_even (line 700) | async def show_chat_even(self, event: StreamEvent):
    method run (line 735) | async def run(self, state: Optional[AgentState] = None, resume=None):

FILE: src/cuga/backend/cuga_graph/utils/context_management_utils.py
  function apply_context_summarization (line 17) | async def apply_context_summarization(
  function _log_and_track_metrics (line 94) | def _log_and_track_metrics(

FILE: src/cuga/backend/cuga_graph/utils/context_summarizer.py
  class ContextSummarizer (line 32) | class ContextSummarizer:
    method __init__ (line 42) | def __init__(
    method _init_middleware (line 66) | def _init_middleware(self):
    method _setup_model_profile (line 84) | def _setup_model_profile(self):
    method _build_trigger_config (line 107) | def _build_trigger_config(self):
    method _build_middleware_kwargs (line 131) | def _build_middleware_kwargs(self, trigger, keep_config):
    method should_summarize (line 161) | def should_summarize(
    method _calculate_metrics (line 201) | def _calculate_metrics(
    method _check_trigger_conditions (line 238) | def _check_trigger_conditions(
    method _count_messages_since_last_summary (line 275) | def _count_messages_since_last_summary(self, messages: List[BaseMessag...
    method summarize_messages (line 294) | async def summarize_messages(
    method _sanitize_content (line 339) | def _sanitize_content(self, content: Any) -> str:
    method _convert_messages_to_typed (line 369) | def _convert_messages_to_typed(self, messages: List[BaseMessage]) -> L...
    method _invoke_middleware (line 394) | async def _invoke_middleware(
    method _extract_new_messages (line 448) | def _extract_new_messages(
    method _calculate_summary_metrics (line 476) | def _calculate_summary_metrics(
    method _is_summary_message (line 521) | def _is_summary_message(message: BaseMessage) -> bool:

FILE: src/cuga/backend/cuga_graph/utils/controller.py
  class ExperimentResult (line 39) | class ExperimentResult(BaseModel):
  class AgentRunner (line 47) | class AgentRunner:
    method __init__ (line 48) | def __init__(self, browser_enabled=True, thread_id: str = "1"):
    method process_event_async (line 58) | async def process_event_async(
    method initialize_webarena_env (line 83) | async def initialize_webarena_env(self, task_id):
    method setup_page_info (line 103) | async def setup_page_info(self, state: AgentState, env):
    method initialize_appworld_env (line 119) | async def initialize_appworld_env(self):
    method initialize_freemode_env (line 133) | async def initialize_freemode_env(
    method browser_update_state (line 150) | async def browser_update_state(self, state: AgentState):
    method get_current_state (line 163) | def get_current_state(self) -> AgentState:
    method run_task_generic (line 180) | async def run_task_generic(
    method run_task_generic_yield (line 280) | async def run_task_generic_yield(
  function main (line 391) | async def main():

FILE: src/cuga/backend/cuga_graph/utils/event_porcessors/action_agent_event_processor.py
  class ActionAgentEventProcessor (line 23) | class ActionAgentEventProcessor:
    method __init__ (line 24) | def __init__(self, page, tool_handlers: Dict[str, Callable[[Any], None...
    method get_element_name (line 36) | def get_element_name(elements, element_bid):
    method process_action_agent (line 41) | def process_action_agent(
    method process_action_agent_async (line 66) | async def process_action_agent_async(
    method clean_tool_calls (line 107) | def clean_tool_calls(tool_calls, event=None):
    method play_tool_async (line 160) | async def play_tool_async(
    method collect_feedback (line 222) | def collect_feedback(

FILE: src/cuga/backend/cuga_graph/utils/message_utils.py
  function convert_to_proper_message_type (line 19) | def convert_to_proper_message_type(message: BaseMessage) -> BaseMessage:

FILE: src/cuga/backend/cuga_graph/utils/nodes_names.py
  class NodeNames (line 7) | class NodeNames:
  class ActionIds (line 29) | class ActionIds:
  class MessagePrefixes (line 42) | class MessagePrefixes:

FILE: src/cuga/backend/cuga_graph/utils/token_counter.py
  class TokenCounter (line 292) | class TokenCounter:
    method __init__ (line 300) | def __init__(
    method count_message_tokens (line 327) | def count_message_tokens(self, messages: List[BaseMessage]) -> int:
    method count_tool_tokens (line 366) | def count_tool_tokens(self, tools: Optional[List[Any]]) -> int:
    method count_total_context_tokens (line 422) | def count_total_context_tokens(
    method get_model_context_size (line 459) | def get_model_context_size(self, model: Optional[Any] = None) -> int: ...
    method _get_profile_limits (line 513) | def _get_profile_limits(model: Any) -> Optional[int]:  # BaseChatModel
    method calculate_usage_percentage (line 540) | def calculate_usage_percentage(
    method get_cumulative_usage (line 563) | def get_cumulative_usage(self) -> int:
    method estimate_tokens (line 577) | def estimate_tokens(self, text: str) -> int:

FILE: src/cuga/backend/evolve/integration.py
  class EvolveIntegration (line 20) | class EvolveIntegration:
    method _get_mode (line 24) | def _get_mode() -> str:
    method _get_app_name (line 29) | def _get_app_name() -> str:
    method is_enabled (line 33) | def is_enabled(cls) -> bool:
    method get_guidelines (line 42) | async def get_guidelines(cls, task: str) -> Optional[str]:
    method save_trajectory (line 58) | async def save_trajectory(
    method _convert_messages (line 101) | def _convert_messages(chat_messages: List[BaseMessage]) -> list:
    method _call_tool (line 122) | async def _call_tool(cls, tool_name: str, args: dict):
    method _registry_has_app (line 141) | async def _registry_has_app(cls, app_name: str) -> bool:
    method _call_tool_via_registry (line 149) | async def _call_tool_via_registry(cls, tool_name: str, args: dict):
    method _call_tool_direct (line 189) | async def _call_tool_direct(cls, tool_name: str, args: dict):

FILE: src/cuga/backend/evolve/tests/test_integration.py
  class TestIsEnabled (line 20) | class TestIsEnabled:
    method test_disabled_when_evolve_not_enabled (line 24) | def test_disabled_when_evolve_not_enabled(self, mock_settings):
    method test_enabled_when_evolve_enabled_and_lite_mode (line 31) | def test_enabled_when_evolve_enabled_and_lite_mode(self, mock_settings):
    method test_disabled_when_lite_mode_only_but_not_in_lite_mode (line 38) | def test_disabled_when_lite_mode_only_but_not_in_lite_mode(self, mock_...
    method test_enabled_when_lite_mode_only_is_false (line 45) | def test_enabled_when_lite_mode_only_is_false(self, mock_settings):
  class TestConvertMessages (line 52) | class TestConvertMessages:
    method test_converts_human_and_ai_messages (line 55) | def test_converts_human_and_ai_messages(self):
    method test_skips_system_messages (line 68) | def test_skips_system_messages(self):
    method test_skips_empty_content (line 77) | def test_skips_empty_content(self):
    method test_empty_message_list (line 86) | def test_empty_message_list(self):
    method test_handles_non_string_content (line 90) | def test_handles_non_string_content(self):
  class TestGetGuidelines (line 100) | class TestGetGuidelines:
    method test_returns_none_when_disabled (line 105) | async def test_returns_none_when_disabled(self, mock_settings):
    method test_returns_guidelines_when_available (line 113) | async def test_returns_guidelines_when_available(self, mock_settings, ...
    method test_returns_none_on_empty_result (line 124) | async def test_returns_none_on_empty_result(self, mock_settings, mock_...
    method test_returns_none_on_error_gracefully (line 134) | async def test_returns_none_on_error_gracefully(self, mock_settings, m...
    method test_returns_none_on_timeout (line 144) | async def test_returns_none_on_timeout(self, mock_settings, mock_call_...
  class TestToolDispatch (line 154) | class TestToolDispatch:
    method test_auto_mode_prefers_registry (line 161) | async def test_auto_mode_prefers_registry(self, mock_settings, mock_re...
    method test_auto_mode_falls_back_to_direct (line 177) | async def test_auto_mode_falls_back_to_direct(self, mock_settings, moc...
    method test_registry_mode_does_not_fallback (line 193) | async def test_registry_mode_does_not_fallback(self, mock_settings, mo...
    method test_registry_call_skips_when_app_missing (line 207) | async def test_registry_call_skips_when_app_missing(self, mock_setting...
  class TestSaveTrajectory (line 215) | class TestSaveTrajectory:
    method test_skips_when_disabled (line 220) | async def test_skips_when_disabled(self, mock_settings):
    method test_skips_when_save_on_success_false_and_success (line 227) | async def test_skips_when_save_on_success_false_and_success(self, mock...
    method test_skips_when_save_on_failure_false_and_failure (line 238) | async def test_skips_when_save_on_failure_false_and_failure(self, mock...
    method test_saves_on_success (line 249) | async def test_saves_on_success(self, mock_settings, mock_call_tool):
    method test_skips_empty_messages (line 270) | async def test_skips_empty_messages(self, mock_settings, mock_call_tool):
    method test_handles_error_gracefully (line 281) | async def test_handles_error_gracefully(self, mock_settings, mock_call...
    method test_handles_timeout_gracefully (line 292) | async def test_handles_timeout_gracefully(self, mock_settings, mock_ca...

FILE: src/cuga/backend/evolve/tests/test_launch_config.py
  function _repo_root (line 5) | def _repo_root() -> Path:
  function test_pyproject_does_not_export_local_evolve_launcher (line 9) | def test_pyproject_does_not_export_local_evolve_launcher() -> None:
  function test_evolve_templates_use_upstream_package_entrypoint (line 16) | def test_evolve_templates_use_upstream_package_entrypoint() -> None:

FILE: src/cuga/backend/knowledge/__init__.py
  function __getattr__ (line 8) | def __getattr__(name: str):

FILE: src/cuga/backend/knowledge/auth.py
  class KnowledgeIdentity (line 24) | class KnowledgeIdentity:
  function _scope_enabled_for_request (line 35) | def _scope_enabled_for_request(scope: str, request: Request | None) -> b...
  function _scope_disabled_detail (line 53) | def _scope_disabled_detail(scope: str) -> str:
  function ensure_agent_knowledge_manage_access (line 59) | def ensure_agent_knowledge_manage_access(identity: KnowledgeIdentity) ->...
  function ensure_agent_scope_manage_if_needed (line 84) | def ensure_agent_scope_manage_if_needed(identity: KnowledgeIdentity, sco...
  function require_internal_or_auth (line 89) | async def require_internal_or_auth(request: Request) -> KnowledgeIdentity:
  function resolve_collection (line 156) | def resolve_collection(identity: KnowledgeIdentity, scope: str, request:...
  function _sanitize (line 201) | def _sanitize(value: str) -> str:
  function require_knowledge_agent_manage_identity (line 205) | async def require_knowledge_agent_manage_identity(

FILE: src/cuga/backend/knowledge/awareness.py
  function _agent_collection_name (line 20) | def _agent_collection_name(agent_id: str, config_hash: str | None = None...
  function _format_doc_line (line 28) | def _format_doc_line(doc: Any) -> str:
  function get_knowledge_summary (line 40) | async def get_knowledge_summary(
  function get_engine_from_app_state (line 118) | def get_engine_from_app_state() -> KnowledgeEngine | None:
  function format_knowledge_context (line 133) | def format_knowledge_context(

FILE: src/cuga/backend/knowledge/client.py
  class KnowledgeClient (line 15) | class KnowledgeClient:
    method __init__ (line 18) | def __init__(
    method allowed_scopes (line 28) | def allowed_scopes(self) -> tuple[str, ...]:
    method _require_scope_enabled (line 40) | def _require_scope_enabled(self, scope: str) -> None:
    method _resolve_collection (line 47) | def _resolve_collection(self, scope: str, thread_id: str | None = None...
    method search (line 60) | async def search(
    method ingest (line 73) | async def ingest(
    method ingest_url (line 86) | async def ingest_url(
    method list_documents (line 96) | async def list_documents(
    method delete_document (line 115) | async def delete_document(
    method get_settings (line 126) | def get_settings(self) -> dict[str, Any]:
    method update_settings (line 130) | def update_settings(self, **kwargs) -> dict[str, Any]:
    method get_langchain_tools (line 134) | def get_langchain_tools(self, thread_id: str | None = None) -> list:
    method close (line 267) | async def close(self) -> None:

FILE: src/cuga/backend/knowledge/config.py
  function knowledge_vector_backend_for_settings (line 18) | def knowledge_vector_backend_for_settings(settings: Any) -> str:
  function load_profile (line 26) | def load_profile(profile_name: str) -> dict[str, Any]:
  function list_profiles (line 41) | def list_profiles() -> dict[str, dict[str, Any]]:
  class KnowledgeConfig (line 59) | class KnowledgeConfig:
    method to_dict (line 103) | def to_dict(self) -> dict[str, Any]:
    method vector_config_hash (line 107) | def vector_config_hash(self) -> str:
    method validate (line 125) | def validate(self) -> None:
    method coerce_and_validate (line 149) | def coerce_and_validate(
    method from_settings (line 200) | def from_settings(cls, settings) -> KnowledgeConfig:

FILE: src/cuga/backend/knowledge/engine.py
  function _iter_exception_messages (line 46) | def _iter_exception_messages(exc: BaseException) -> list[str]:
  function _translate_document_load_error (line 71) | def _translate_document_load_error(file_path: Path, exc: BaseException) ...
  function _page_from_docling_dl_meta (line 85) | def _page_from_docling_dl_meta(dl_meta: Any) -> int | None:
  class SearchResult (line 119) | class SearchResult:
  class DocInfo (line 127) | class DocInfo:
  class ReindexBusyError (line 138) | class ReindexBusyError(Exception):
    method __init__ (line 141) | def __init__(self, pending_count: int):
  class ReindexInProgressError (line 146) | class ReindexInProgressError(Exception):
  class PreparedKnowledgeUpdate (line 156) | class PreparedKnowledgeUpdate:
  class _FastEmbedEmbeddings (line 171) | class _FastEmbedEmbeddings(Embeddings):
    method __init__ (line 174) | def __init__(self, model_name: str):
    method embed_documents (line 186) | def embed_documents(self, texts: list[str]) -> list[list[float]]:
    method embed_query (line 189) | def embed_query(self, text: str) -> list[float]:
  function _fastembed_docling_seq_limit (line 193) | def _fastembed_docling_seq_limit(model_name: str) -> int:
  function _fastembed_docling_tokenizer_cls (line 202) | def _fastembed_docling_tokenizer_cls():
  function create_embeddings (line 231) | def create_embeddings(config: "KnowledgeConfig") -> Embeddings:
  function _get_embedding_dim (line 284) | def _get_embedding_dim(embeddings: Embeddings) -> int:
  class KnowledgeEngine (line 293) | class KnowledgeEngine:
    method __init__ (line 296) | def __init__(self, config: KnowledgeConfig):
    method start_background_tasks (line 360) | def start_background_tasks(self, loop: asyncio.AbstractEventLoop | Non...
    method _ensure_metadata_ready (line 382) | async def _ensure_metadata_ready(self) -> None:
    method aclose (line 398) | async def aclose(self) -> None:
    method shutdown (line 404) | def shutdown(self) -> None:
    method _ensure_embeddings (line 418) | def _ensure_embeddings(self) -> None:
    method warmup (line 429) | async def warmup(self) -> dict[str, Any]:
    method _knowledge_vector_backend (line 439) | def _knowledge_vector_backend(self) -> str:
    method _get_record_manager (line 446) | def _get_record_manager(self, collection: str) -> InMemoryRecordManager:
    method _resolve_embeddings_for_collection (line 453) | async def _resolve_embeddings_for_collection(self, collection: str) ->...
    method _create_vector_adapter (line 472) | def _create_vector_adapter(self, collection: str, embeddings: Embeddin...
    method _vector_cache_put (line 484) | def _vector_cache_put(self, collection: str, adapter: VectorStoreAdapt...
    method _ensure_vector_store_cached (line 490) | async def _ensure_vector_store_cached(self, collection: str) -> None:
    method _ensure_collection_config (line 506) | async def _ensure_collection_config(self, collection: str) -> None:
    method _get_collection_lock (line 516) | def _get_collection_lock(self, collection: str) -> asyncio.Lock:
    method _sanitize_and_validate (line 523) | async def _sanitize_and_validate(
    method _create_task_entry (line 551) | async def _create_task_entry(self, collection: str, filename: str) -> ...
    method _create_reindex_task_entry (line 557) | async def _create_reindex_task_entry(self, collection: str, filename: ...
    method _create_task_entry_internal (line 560) | async def _create_task_entry_internal(self, collection: str, filename:...
    method _run_ingest (line 565) | async def _run_ingest(
    method ingest (line 598) | async def ingest(
    method _ingest_inner (line 615) | async def _ingest_inner(
    method _insert_documents_async (line 768) | async def _insert_documents_async(
    method ingest_url (line 830) | async def ingest_url(self, collection: str, url: str) -> dict[str, Any]:
    method delete_document (line 892) | async def delete_document(self, collection: str, filename: str) -> None:
    method _delete_vector_and_file (line 910) | def _delete_vector_and_file(self, collection: str, filename: str) -> N...
    method _finalize_stale_delete (line 930) | async def _finalize_stale_delete(self, collection: str, filename: str)...
    method _reconcile_deletes (line 942) | async def _reconcile_deletes(self) -> None:
    method _cleanup_expired_sessions (line 948) | async def _cleanup_expired_sessions(self, max_age_days: int = 7) -> None:
    method search (line 968) | async def search(
    method list_documents (line 1018) | async def list_documents(self, collection: str) -> list[DocInfo]:
    method get_document_file_path (line 1025) | def get_document_file_path(self, collection: str, filename: str) -> Path:
    method get_tasks (line 1036) | async def get_tasks(self, collection: str | None = None) -> list[dict[...
    method get_task (line 1040) | async def get_task(self, task_id: str) -> dict[str, Any] | None:
    method cancel_task (line 1044) | async def cancel_task(self, task_id: str) -> dict[str, Any] | None:
    method prepare_knowledge_update (line 1068) | def prepare_knowledge_update(self, knowledge_cfg: dict) -> PreparedKno...
    method commit_knowledge_update (line 1128) | def commit_knowledge_update(self, prepared: PreparedKnowledgeUpdate) -...
    method apply_knowledge_config (line 1154) | def apply_knowledge_config(self, knowledge_cfg: dict) -> dict[str, Any]:
    method get_knowledge_config (line 1161) | def get_knowledge_config(self) -> dict[str, Any]:
    method get_settings (line 1164) | def get_settings(self) -> dict[str, Any]:
    method update_settings (line 1196) | def update_settings(self, **kwargs) -> dict[str, Any]:
    method health (line 1202) | async def health(self, collection: str | None = None) -> dict[str, Any]:
    method drop_collection (line 1230) | async def drop_collection(self, collection: str) -> None:
    method drop_collection_vectors (line 1251) | async def drop_collection_vectors(self, collection: str) -> None:
    method copy_source_files (line 1273) | async def copy_source_files(self, source_collection: str, target_colle...
    method reindex (line 1298) | async def reindex(self, collection: str) -> dict[str, Any]:
    method _get_effective_chunk_settings (line 1386) | def _get_effective_chunk_settings(self) -> tuple[int, int]:
    method _build_docling_chunker (line 1390) | def _build_docling_chunker(self, chunk_size: int):
    method _get_docling_converter (line 1443) | def _get_docling_converter(self):
    method _load_document (line 1462) | def _load_document(self, file_path: Path) -> list[Document]:
    method _validate_url (line 1545) | def _validate_url(self, url: str) -> None:
  function _sanitize_collection (line 1574) | def _sanitize_collection(name: str) -> str:
  function _sanitize_filename (line 1578) | def _sanitize_filename(name: str) -> str:
  class IngestionQueueFullError (line 1590) | class IngestionQueueFullError(Exception):
    method __init__ (line 1591) | def __init__(self, max_pending: int):
  class DocumentExistsError (line 1596) | class DocumentExistsError(Exception):
    method __init__ (line 1597) | def __init__(self, filename: str):
  class DocumentNotFoundError (line 1602) | class DocumentNotFoundError(Exception):
    method __init__ (line 1603) | def __init__(self, filename: str):
  class FileTooLargeError (line 1608) | class FileTooLargeError(Exception):
    method __init__ (line 1609) | def __init__(self, size: int, max_size: int):

FILE: src/cuga/backend/knowledge/interprocess_lock.py
  function acquire_exclusive_nonblocking (line 9) | def acquire_exclusive_nonblocking(lock_file: IO) -> None:
  function release_exclusive (line 21) | def release_exclusive(lock_file: IO) -> None:

FILE: src/cuga/backend/knowledge/mcp_server.py
  function _resolve_env (line 23) | def _resolve_env(key: str, default: str) -> str:
  function _get_token (line 51) | def _get_token() -> str:
  function _reload_token (line 60) | def _reload_token() -> str:
  function _read_token_file (line 67) | def _read_token_file() -> str:
  function _get_client (line 85) | def _get_client() -> httpx.AsyncClient:
  function _request (line 96) | async def _request(method: str, path: str, **kwargs) -> httpx.Response:
  function _get_agent_id (line 116) | def _get_agent_id() -> str:
  function _identity_headers (line 135) | def _identity_headers(agent_id: str = "", thread_id: str = "") -> dict[s...
  function search_knowledge (line 153) | async def search_knowledge(
  function ingest_knowledge (line 175) | async def ingest_knowledge(
  function ingest_knowledge_url (line 205) | async def ingest_knowledge_url(
  function list_knowledge_documents (line 226) | async def list_knowledge_documents(
  function delete_knowledge_document (line 246) | async def delete_knowledge_document(
  function get_ingestion_status (line 266) | async def get_ingestion_status(
  function get_knowledge_status (line 283) | async def get_knowledge_status(
  function run_http (line 298) | def run_http(host: str = "127.0.0.1", port: int = 8113):

FILE: src/cuga/backend/knowledge/metadata/__init__.py
  function create_knowledge_metadata (line 15) | def create_knowledge_metadata(persist_dir: Path, *, mode: str, postgres_...

FILE: src/cuga/backend/knowledge/metadata/base.py
  function utc_now_iso (line 9) | def utc_now_iso() -> str:
  function iso_cutoff_days_ago (line 13) | def iso_cutoff_days_ago(days: int) -> str:
  class KnowledgeMetadataStore (line 17) | class KnowledgeMetadataStore(Protocol):
    method ensure_ready (line 18) | async def ensure_ready(self) -> None: ...
    method close (line 19) | async def close(self) -> None: ...
    method add_document (line 20) | async def add_document(
    method mark_deleting (line 23) | async def mark_deleting(self, collection: str, filename: str) -> bool:...
    method remove_document (line 24) | async def remove_document(self, collection: str, filename: str) -> Non...
    method list_documents (line 25) | async def list_documents(self, collection: str) -> list[dict[str, Any]...
    method get_deleting_documents (line 26) | async def get_deleting_documents(self) -> list[dict[str, Any]]: ...
    method document_exists (line 27) | async def document_exists(self, collection: str, filename: str) -> boo...
    method create_task (line 28) | async def create_task(
    method get_task (line 31) | async def get_task(self, task_id: str) -> dict[str, Any] | None: ...
    method update_task (line 32) | async def update_task(self, task_id: str, **kwargs: Any) -> None: ...
    method list_tasks (line 33) | async def list_tasks(self, collection: str | None = None) -> list[dict...
    method recover_stale_tasks (line 34) | async def recover_stale_tasks(self) -> int: ...
    method purge_old_tasks (line 35) | async def purge_old_tasks(self, max_age_days: int = 7) -> int: ...
    method get_collection_config (line 36) | async def get_collection_config(self, collection: str) -> dict[str, An...
    method set_collection_config (line 37) | async def set_collection_config(
    method list_all_collection_configs (line 40) | async def list_all_collection_configs(self) -> list[str]: ...
    method delete_collection_metadata (line 41) | async def delete_collection_metadata(self, collection: str) -> None: ...
    method get_setting (line 42) | async def get_setting(self, key: str, default: str = "") -> str: ...
    method set_setting (line 43) | async def set_setting(self, key: str, value: str) -> None: ...
    method get_all_settings (line 44) | async def get_all_settings(self) -> dict[str, str]: ...

FILE: src/cuga/backend/knowledge/metadata/postgres_store.py
  class PostgresKnowledgeMetadata (line 78) | class PostgresKnowledgeMetadata(ProdRelationalStore):
    method __init__ (line 79) | def __init__(self, postgres_url: str):
    method ensure_ready (line 84) | async def ensure_ready(self) -> None:
    method add_document (line 95) | async def add_document(self, collection: str, filename: str, chunk_cou...
    method mark_deleting (line 111) | async def mark_deleting(self, collection: str, filename: str) -> bool:
    method remove_document (line 120) | async def remove_document(self, collection: str, filename: str) -> None:
    method list_documents (line 127) | async def list_documents(self, collection: str) -> list[dict[str, Any]]:
    method get_deleting_documents (line 134) | async def get_deleting_documents(self) -> list[dict[str, Any]]:
    method document_exists (line 137) | async def document_exists(self, collection: str, filename: str) -> bool:
    method create_task (line 145) | async def create_task(
    method get_task (line 161) | async def get_task(self, task_id: str) -> dict[str, Any] | None:
    method update_task (line 169) | async def update_task(self, task_id: str, **kwargs: Any) -> None:
    method list_tasks (line 182) | async def list_tasks(self, collection: str | None = None) -> list[dict...
    method recover_stale_tasks (line 197) | async def recover_stale_tasks(self) -> int:
    method purge_old_tasks (line 218) | async def purge_old_tasks(self, max_age_days: int = 7) -> int:
    method get_collection_config (line 225) | async def get_collection_config(self, collection: str) -> dict[str, An...
    method set_collection_config (line 228) | async def set_collection_config(
    method list_all_collection_configs (line 242) | async def list_all_collection_configs(self) -> list[str]:
    method delete_collection_metadata (line 246) | async def delete_collection_metadata(self, collection: str) -> None:
    method get_setting (line 252) | async def get_setting(self, key: str, default: str = "") -> str:
    method set_setting (line 256) | async def set_setting(self, key: str, value: str) -> None:
    method get_all_settings (line 266) | async def get_all_settings(self) -> dict[str, str]:
  function truncate_knowledge_metadata_tables (line 271) | def truncate_knowledge_metadata_tables(postgres_url: str) -> None:

FILE: src/cuga/backend/knowledge/metadata/sqlite_store.py
  class SqliteKnowledgeMetadata (line 18) | class SqliteKnowledgeMetadata(LocalRelationalStore):
    method __init__ (line 19) | def __init__(self, db_path: Path):
    method _on_connection_opened (line 25) | def _on_connection_opened(self, conn: sqlite3.Connection) -> None:
    method _init_schema (line 29) | def _init_schema(self) -> None:
    method ensure_ready (line 80) | async def ensure_ready(self) -> None:
    method add_document (line 83) | async def add_document(self, collection: str, filename: str, chunk_cou...
    method mark_deleting (line 92) | async def mark_deleting(self, collection: str, filename: str) -> bool:
    method remove_document (line 101) | async def remove_document(self, collection: str, filename: str) -> None:
    method list_documents (line 108) | async def list_documents(self, collection: str) -> list[dict[str, Any]]:
    method get_deleting_documents (line 116) | async def get_deleting_documents(self) -> list[dict[str, Any]]:
    method document_exists (line 122) | async def document_exists(self, collection: str, filename: str) -> bool:
    method create_task (line 129) | async def create_task(
    method get_task (line 142) | async def get_task(self, task_id: str) -> dict[str, Any] | None:
    method update_task (line 150) | async def update_task(self, task_id: str, **kwargs: Any) -> None:
    method list_tasks (line 160) | async def list_tasks(self, collection: str | None = None) -> list[dict...
    method recover_stale_tasks (line 175) | async def recover_stale_tasks(self) -> int:
    method purge_old_tasks (line 196) | async def purge_old_tasks(self, max_age_days: int = 7) -> int:
    method get_collection_config (line 205) | async def get_collection_config(self, collection: str) -> dict[str, An...
    method set_collection_config (line 208) | async def set_collection_config(
    method list_all_collection_configs (line 220) | async def list_all_collection_configs(self) -> list[str]:
    method delete_collection_metadata (line 224) | async def delete_collection_metadata(self, collection: str) -> None:
    method get_setting (line 230) | async def get_setting(self, key: str, default: str = "") -> str:
    method set_setting (line 234) | async def set_setting(self, key: str, value: str) -> None:
    method get_all_settings (line 241) | async def get_all_settings(self) -> dict[str, str]:

FILE: src/cuga/backend/knowledge/routes.py
  function _get_engine (line 45) | def _get_engine(request: Request) -> KnowledgeEngine:
  function _ensure_enabled (line 54) | def _ensure_enabled(engine: KnowledgeEngine) -> None:
  function _extract_task_error (line 60) | def _extract_task_error(task: dict[str, Any], fallback: str = "Ingestion...
  function enable_knowledge (line 76) | async def enable_knowledge(request: Request):
  function health (line 106) | async def health(request: Request):
  function get_settings (line 154) | async def get_settings(request: Request):
  function update_settings (line 160) | async def update_settings(request: Request):
  function search (line 171) | async def search(
  function upload_documents (line 205) | async def upload_documents(
  function ingest_url (line 284) | async def ingest_url(
  function list_documents (line 309) | async def list_documents(
  function get_document_file (line 332) | async def get_document_file(
  function delete_document (line 355) | async def delete_document(
  function delete_session_collection (line 377) | async def delete_session_collection(
  function reindex_collection (line 399) | async def reindex_collection(
  function list_tasks (line 422) | async def list_tasks(
  function get_task (line 434) | async def get_task(
  function cancel_task (line 461) | async def cancel_task(

FILE: src/cuga/backend/knowledge/session_provider.py
  function session_prefix (line 29) | def session_prefix(thread_id: str) -> str:
  function agent_prefix (line 36) | def agent_prefix(agent_id: str, config_version: str) -> str:
  class SessionKnowledgeState (line 42) | class SessionKnowledgeState:
    method to_dict (line 55) | def to_dict(self) -> dict[str, Any]:
    method from_dict (line 59) | def from_dict(cls, data: dict[str, Any]) -> SessionKnowledgeState:
  class AgentKnowledgeState (line 72) | class AgentKnowledgeState:
    method key (line 82) | def key(self) -> str:
    method prefix (line 86) | def prefix(self) -> str:
    method to_dict (line 89) | def to_dict(self) -> dict[str, Any]:
    method from_dict (line 93) | def from_dict(cls, data: dict[str, Any]) -> AgentKnowledgeState:
  function _deep_merge (line 103) | def _deep_merge(base: dict, patch: dict) -> dict:
  class SessionProvider (line 113) | class SessionProvider:
    method __init__ (line 116) | def __init__(self) -> None:
    method get_session (line 122) | def get_session(self, thread_id: str) -> SessionKnowledgeState | None:
    method get_or_create_session (line 125) | def get_or_create_session(
    method check_session_access (line 140) | def check_session_access(
    method save_session (line 157) | def save_session(self, thread_id: str, state: SessionKnowledgeState) -...
    method delete_session (line 160) | def delete_session(self, thread_id: str) -> None:
    method list_sessions (line 163) | def list_sessions(self) -> dict[str, SessionKnowledgeState]:
    method collect_expired_sessions (line 166) | def collect_expired_sessions(self, max_age_seconds: float = 7 * 24 * 3...
    method patch_session_overrides (line 183) | def patch_session_overrides(
    method get_agent (line 198) | def get_agent(self, key: str) -> AgentKnowledgeState | None:
    method get_or_create_agent (line 202) | def get_or_create_agent(self, agent_id: str, config_version: str) -> A...
    method save_agent (line 212) | def save_agent(self, state: AgentKnowledgeState) -> None:
    method list_agents (line 215) | def list_agents(self) -> dict[str, AgentKnowledgeState]:
  class PersistentSessionProvider (line 219) | class PersistentSessionProvider(SessionProvider):
    method __init__ (line 226) | def __init__(self, path: Path) -> None:
    method _load (line 231) | def _load(self) -> None:
    method _persist (line 249) | def _persist(self) -> None:
    method save_session (line 263) | def save_session(self, thread_id: str, state: SessionKnowledgeState) -...
    method delete_session (line 267) | def delete_session(self, thread_id: str) -> None:
    method patch_session_overrides (line 271) | def patch_session_overrides(
    method save_agent (line 282) | def save_agent(self, state: AgentKnowledgeState) -> None:

FILE: src/cuga/backend/knowledge/storage/adapter.py
  class StorageBackedKnowledgeVectorStore (line 20) | class StorageBackedKnowledgeVectorStore(VectorStoreAdapter):
    method __init__ (line 23) | def __init__(
    method _scope (line 48) | def _scope(self) -> dict[str, str]:
    method _ensure_store (line 51) | def _ensure_store(self) -> None:
    method _run_embedding_coro (line 72) | def _run_embedding_coro(self, coro):
    method _l2_similarity (line 97) | def _l2_similarity(self, distance: float) -> float:
    method _cosine_similarity (line 103) | def _cosine_similarity(distance: float) -> float:
    method add_documents (line 107) | def add_documents(self, documents: list[Document]) -> dict[str, int]:
    method search (line 150) | def search(self, query: str, k: int = 10) -> list[tuple[Document, floa...
    method delete_by_source (line 183) | def delete_by_source(self, source_id: str) -> None:
    method drop (line 205) | def drop(self) -> None:

FILE: src/cuga/backend/knowledge/storage/local.py
  function create_storage_local_knowledge_store (line 11) | def create_storage_local_knowledge_store(

FILE: src/cuga/backend/knowledge/storage/prod.py
  function create_storage_prod_knowledge_store (line 11) | def create_storage_prod_knowledge_store(

FILE: src/cuga/backend/knowledge/storage/schema.py
  function knowledge_embedding_schema (line 8) | def knowledge_embedding_schema(embedding_dim: int) -> EmbeddingSchemaCon...

FILE: src/cuga/backend/knowledge/vector_store.py
  function create_vector_store (line 27) | def create_vector_store(

FILE: src/cuga/backend/knowledge/vector_store_base.py
  class VectorStoreAdapter (line 10) | class VectorStoreAdapter(ABC):
    method add_documents (line 14) | def add_documents(self, documents: list[Document]) -> dict[str, int]:
    method search (line 18) | def search(self, query: str, k: int = 10) -> list[tuple[Document, floa...
    method delete_by_source (line 22) | def delete_by_source(self, source_id: str) -> None:
    method drop (line 26) | def drop(self) -> None:

FILE: src/cuga/backend/llm/config.py
  class LLMConfig (line 7) | class LLMConfig(BaseModel):
    class Config (line 57) | class Config:
  class LiteLLMConfig (line 62) | class LiteLLMConfig(LLMConfig):
  class OpenAIConfig (line 78) | class OpenAIConfig(LLMConfig):
  class GroqConfig (line 86) | class GroqConfig(LLMConfig):

FILE: src/cuga/backend/llm/errors.py
  function _parse_failed_generation_json (line 13) | def _parse_failed_generation_json(raw_fg: str) -> Optional[dict]:
  function _parse_tool_use_failed_from_body (line 23) | def _parse_tool_use_failed_from_body(body: Any) -> Optional[dict]:
  function is_tool_choice_none_tool_use_failed (line 40) | def is_tool_choice_none_tool_use_failed(err: Any) -> bool:
  function ainvoke_with_retry_on_tool_choice_none (line 50) | async def ainvoke_with_retry_on_tool_choice_none(
  function parse_tool_use_failed_generation (line 68) | def parse_tool_use_failed_generation(err: Any) -> Optional[dict]:
  function failed_gen_to_code (line 101) | def failed_gen_to_code(failed_gen: dict) -> Optional[str]:
  function extract_code_from_tool_use_failed (line 123) | def extract_code_from_tool_use_failed(err: Any) -> Optional[str]:

FILE: src/cuga/backend/llm/models.py
  function _normalize_secret (line 21) | def _normalize_secret(val: Optional[str]) -> Optional[str]:
  function get_current_llm_override (line 40) | def get_current_llm_override() -> Optional[Dict[str, Any]]:
  function set_current_llm_override (line 44) | def set_current_llm_override(override: Optional[Dict[str, Any]]) -> None:
  class _ModelSettingsWrap (line 49) | class _ModelSettingsWrap:
    method __init__ (line 50) | def __init__(self, d: dict):
    method get (line 53) | def get(self, k: str, default: Any = None) -> Any:
    method to_dict (line 56) | def to_dict(self) -> dict:
  class LLMManager (line 79) | class LLMManager:
    method __new__ (line 85) | def __new__(cls):
    method __init__ (line 93) | def __init__(self):
    method convert_dates_to_strings (line 99) | def convert_dates_to_strings(self, obj):
    method set_llm (line 109) | def set_llm(self, model: BaseChatModel) -> None:
    method _update_model_parameters (line 121) | def _update_model_parameters(
    method clear_pre_instantiated_model (line 184) | def clear_pre_instantiated_model(self) -> None:
    method _create_cache_key (line 189) | def _create_cache_key(self, model_settings: Dict[str, Any]) -> str:
    method _get_model_name (line 209) | def _get_model_name(self, model_settings: Dict[str, Any], platform: st...
    method _get_api_version (line 317) | def _get_api_version(self, model_settings: Dict[str, Any], platform: s...
    method _get_auth_headers (line 348) | def _get_auth_headers(self, model_settings: Dict[str, Any], platform: ...
    method _get_base_url (line 404) | def _get_base_url(self, model_settings: Dict[str, Any], platform: str)...
    method _get_ssl_verify (line 464) | def _get_ssl_verify(self, model_settings: Dict[str, Any]) -> "bool | s...
    method _is_reasoning_model (line 507) | def _is_reasoning_model(self, model_name: str) -> bool:
    method _create_llm_instance (line 517) | def _create_llm_instance(self, model_settings: Dict[str, Any]):
    method get_model (line 735) | def get_model(self, model_settings: Dict[str, Any]):
  function create_llm_from_config (line 790) | def create_llm_from_config(llm_cfg: dict) -> BaseChatModel:

FILE: src/cuga/backend/llm/rits/chat_rits_llm.py
  function _convert_message_to_dict (line 24) | def _convert_message_to_dict(message: BaseMessage) -> dict:
  function _convert_dict_to_message (line 45) | def _convert_dict_to_message(response_dict: Dict[str, Any]) -> BaseMessage:
  class ChatRITS (line 69) | class ChatRITS(BaseChatModel):
    method validate_environment (line 113) | def validate_environment(cls, values: Dict) -> Dict:
    method _default_params (line 122) | def _default_params(self) -> Dict[str, Any]:
    method _llm_type (line 142) | def _llm_type(self) -> str:
    method _convert_messages_to_dicts (line 147) | def _convert_messages_to_dicts(messages: list[BaseMessage]) -> list[di...
    method _create_chat_result (line 151) | def _create_chat_result(self, response: Dict) -> ChatResult:
    method bind_tools (line 170) | def bind_tools(
    method _generate (line 178) | def _generate(

FILE: src/cuga/backend/llm/rits/rits_llm.py
  class RITS (line 10) | class RITS(LLM):
    method validate_environment (line 54) | def validate_environment(cls, values: Dict) -> Dict:
    method _default_params (line 63) | def _default_params(self) -> Dict[str, Any]:
    method _llm_type (line 83) | def _llm_type(self) -> str:
    method _call (line 87) | def _call(

FILE: src/cuga/backend/llm/utils/helpers.py
  function get_caller_directory_path (line 21) | def get_caller_directory_path():
  function load_prompt_chat (line 60) | def load_prompt_chat(system_path, relative_to_caller=True):
  function load_prompt_with_image (line 81) | def load_prompt_with_image(
  function load_one_prompt (line 117) | def load_one_prompt(pmt_path, relative_to_caller=True) -> PromptTemplate:
  function load_prompt_simple (line 125) | def load_prompt_simple(
  function create_chat_prompt_from_templates (line 153) | def create_chat_prompt_from_templates(

FILE: src/cuga/backend/observability/openlit_init.py
  function _merge_otel_resource_attributes (line 58) | def _merge_otel_resource_attributes(existing: str, new_attrs: dict[str, ...
  class SessionSpanProcessor (line 149) | class SessionSpanProcessor(SpanProcessor):  # type: ignore[misc]
    method on_start (line 157) | def on_start(self, span: "ReadableSpan", parent_context: "Context | No...
    method on_end (line 168) | def on_end(self, span: "ReadableSpan") -> None:
    method shutdown (line 172) | def shutdown(self) -> None:
    method force_flush (line 176) | def force_flush(self, timeout_millis: int = 30000) -> bool:
  function init_openlit (line 181) | def init_openlit() -> None:
  function set_session_attribute (line 300) | def set_session_attribute(session_id: str) -> None:

FILE: src/cuga/backend/secrets/backends/aws_backend.py
  function _get_client (line 8) | def _get_client():
  class AwsBackend (line 28) | class AwsBackend:
    method __init__ (line 31) | def __init__(self):
    method _client_or_none (line 34) | def _client_or_none(self):
    method available (line 39) | def available(self) -> bool:
    method get (line 46) | def get(

FILE: src/cuga/backend/secrets/backends/base.py
  class AbstractSecretBackend (line 4) | class AbstractSecretBackend(Protocol):
    method get (line 7) | def get(

FILE: src/cuga/backend/secrets/backends/db_backend.py
  function _path_to_slug (line 9) | def _path_to_slug(path: str) -> str:
  class EnvOverrideBackend (line 15) | class EnvOverrideBackend:
    method available (line 20) | def available(self) -> bool:
    method get (line 25) | def get(
  class DbBackend (line 44) | class DbBackend:
    method available (line 47) | def available(self) -> bool:
    method get (line 52) | def get(

FILE: src/cuga/backend/secrets/backends/env_backend.py
  class EnvBackend (line 5) | class EnvBackend:
    method get (line 8) | def get(

FILE: src/cuga/backend/secrets/backends/vault_backend.py
  function _env_truthy (line 9) | def _env_truthy(name: str) -> bool:
  function _vault_verify (line 13) | def _vault_verify(sec: Any) -> bool | str:
  function _vault_addr_and_auth (line 28) | def _vault_addr_and_auth(sec: Any) -> tuple[str, str | None]:
  function _get_client (line 39) | def _get_client():
  function _parse_vault_path (line 111) | def _parse_vault_path(path: str) -> tuple[str, str | None]:
  function _normalize_kv_v2_data_prefix (line 118) | def _normalize_kv_v2_data_prefix(rest: str) -> str:
  function _split_mount_and_path (line 124) | def _split_mount_and_path(
  function _merge_vault_secret_base (line 140) | def _merge_vault_secret_base(path_arg: str, vault_secret_path: str) -> str:
  function _vault_list_prefix (line 148) | def _vault_list_prefix(vault_secret_path: str, mount_point: str, kv_vers...
  function _resolve_vault_path (line 160) | def _resolve_vault_path(
  class VaultBackend (line 201) | class VaultBackend:
    method __init__ (line 204) | def __init__(self):
    method _client_or_none (line 207) | def _client_or_none(self):
    method available (line 212) | def available(self) -> bool:
    method list (line 215) | def list(self, mount: str | None = None) -> list[str]:
    method set (line 246) | def set(
    method get (line 293) | def get(
    method delete (line 356) | def delete(self, path: str) -> bool:

FILE: src/cuga/backend/secrets/models.py
  class SecretRef (line 5) | class SecretRef:

FILE: src/cuga/backend/secrets/secret_resolver.py
  function parse_ref (line 11) | def parse_ref(ref: str) -> Tuple[str, str]:
  function _get_secrets_settings (line 32) | def _get_secrets_settings():
  function _active_backends (line 41) | def _active_backends():
  function resolve_secret (line 88) | def resolve_secret(

FILE: src/cuga/backend/secrets/seed.py
  function _env_var_to_slug (line 39) | def _env_var_to_slug(env_var: str) -> str:
  function _build_dynamic_seed_map (line 43) | def _build_dynamic_seed_map() -> dict[str, str]:
  function _build_seed_map (line 57) | def _build_seed_map() -> dict[str, str]:
  function get_slug_for_env_var (line 66) | def get_slug_for_env_var(env_var: str) -> str | None:
  function _secrets_mode (line 70) | def _secrets_mode() -> str:
  function seed_secrets_from_env (line 80) | async def seed_secrets_from_env() -> None:
  function seed_secrets_from_env_sync (line 118) | def seed_secrets_from_env_sync() -> None:
  function resolve_llm_api_key_ref (line 127) | def resolve_llm_api_key_ref() -> str:

FILE: src/cuga/backend/server/auth/dependencies.py
  function _auth_enabled (line 18) | def _auth_enabled() -> bool:
  function _authorization_enabled (line 33) | def _authorization_enabled() -> bool:
  function _get_manage_roles (line 48) | def _get_manage_roles() -> list[str]:
  function _get_chat_roles (line 62) | def _get_chat_roles() -> list[str]:
  function _session_cookie_name (line 76) | def _session_cookie_name() -> str:
  function _get_tls_settings (line 86) | def _get_tls_settings() -> tuple[bool, Optional[str]]:
  function _discover_jwks_for_issuer (line 101) | async def _discover_jwks_for_issuer(issuer: str) -> Optional[str]:
  function _get_validator_for_token (line 126) | async def _get_validator_for_token(token: str) -> Optional[JWTValidator]:
  function _get_validator (line 172) | async def _get_validator() -> Optional[JWTValidator]:
  function get_current_user (line 212) | async def get_current_user(request: Request) -> Optional[UserInfo]:
  function require_auth (line 255) | async def require_auth(request: Request) -> Optional[UserInfo]:
  function require_manage_access (line 262) | async def require_manage_access(request: Request) -> Optional[UserInfo]:
  function require_chat_access (line 286) | async def require_chat_access(request: Request) -> Optional[UserInfo]:

FILE: src/cuga/backend/server/auth/issuer_allowlist.py
  function normalize_https_issuer_url (line 11) | def normalize_https_issuer_url(value: str) -> Optional[str]:
  function discovery_url_to_issuer_base (line 30) | def discovery_url_to_issuer_base(discovery_url: str) -> Optional[str]:
  function normalize_issuer_for_discovery (line 48) | def normalize_issuer_for_discovery(issuer_raw: str) -> Optional[str]:
  function normalize_discovery_url (line 60) | def normalize_discovery_url(discovery_url: str) -> Optional[str]:

FILE: src/cuga/backend/server/auth/jwt_validator.py
  class JWTValidator (line 13) | class JWTValidator:
    method __init__ (line 14) | def __init__(
    method validate_and_decode (line 32) | def validate_and_decode(
    method _extract_roles (line 60) | def _extract_roles(payload: dict[str, Any]) -> Optional[list[str]]:
    method _normalize_https_url (line 79) | def _normalize_https_url(value: str) -> Optional[str]:
    method to_user_info (line 91) | def to_user_info(self, payload: dict[str, Any]) -> UserInfo:
  function validate_iam_token (line 106) | async def validate_iam_token(
  function _assert_iam_token_bound_to_instance (line 189) | def _assert_iam_token_bound_to_instance(payload: dict[str, Any], instanc...

FILE: src/cuga/backend/server/auth/models.py
  class UserInfo (line 6) | class UserInfo(BaseModel):
  class TokenResponse (line 14) | class TokenResponse(BaseModel):

FILE: src/cuga/backend/server/auth/oidc_client.py
  function _pkce_pair (line 16) | def _pkce_pair() -> tuple[str, str]:
  class OIDCClient (line 24) | class OIDCClient:
    method __init__ (line 25) | def __init__(
    method get_discovery (line 53) | async def get_discovery(self) -> dict[str, Any]:
    method _get_validator (line 66) | def _get_validator(self, jwks_uri: str, issuer: Optional[str]) -> JWTV...
    method get_authorization_url (line 77) | async def get_authorization_url(self, state: Optional[str] = None) -> ...
    method _prune_expired_pkce_verifiers (line 96) | def _prune_expired_pkce_verifiers(self) -> None:
    method exchange_code (line 102) | async def exchange_code(self, code: str, state: str) -> tuple[TokenRes...
    method exchange_service_token (line 176) | async def exchange_service_token(self, access_token: str, instance_id:...
  function get_oidc_client (line 224) | def get_oidc_client() -> Optional[OIDCClient]:

FILE: src/cuga/backend/server/config_store.py
  function _parse_agent_id (line 24) | def _parse_agent_id(agent_id: str) -> str:
  function _get_store (line 30) | def _get_store():
  function _instance_id (line 34) | def _instance_id() -> str:
  function _tenant_id (line 38) | def _tenant_id() -> str:
  function _ensure_schema (line 42) | async def _ensure_schema(store) -> None:
  function normalize_policies_for_save (line 78) | def normalize_policies_for_save(config: dict[str, Any]) -> None:
  function save_config (line 96) | async def save_config(config: dict[str, Any], agent_id: str = "cuga-defa...
  function update_published_config_at_version (line 129) | async def update_published_config_at_version(config: dict[str, Any], age...
  function load_config (line 154) | async def load_config(
  function list_versions (line 186) | async def list_versions(agent_id: str = "cuga-default") -> list[dict[str...
  function get_latest_version (line 212) | async def get_latest_version(agent_id: str = "cuga-default") -> tuple[st...
  function save_draft (line 236) | async def save_draft(config: dict[str, Any], agent_id: str = "cuga-defau...
  function load_draft (line 259) | async def load_draft(agent_id: str = "cuga-default") -> dict[str, Any] |...
  function get_agent_tools (line 278) | async def get_agent_tools(agent_id: str, version: str = "draft") -> list...
  function list_agents_with_configs (line 289) | async def list_agents_with_configs() -> list[dict[str, Any]]:
  function delete_all_configs (line 316) | async def delete_all_configs(agent_id: str = "cuga-default") -> int:
  function reset_config_db (line 333) | def reset_config_db() -> None:

FILE: src/cuga/backend/server/conversation_history.py
  class ConversationMessage (line 20) | class ConversationMessage(BaseModel):
  class StreamEvent (line 27) | class StreamEvent(BaseModel):
  class ConversationHistory (line 34) | class ConversationHistory(BaseModel):
  class ConversationStreamHistory (line 44) | class ConversationStreamHistory(BaseModel):
  function _instance_id (line 53) | def _instance_id() -> str:
  function _tenant_id (line 57) | def _tenant_id() -> str:
  class ConversationHistoryDB (line 61) | class ConversationHistoryDB:
    method __init__ (line 62) | def __init__(self, db_path: Optional[str] = None):
    method _get_store (line 65) | def _get_store(self):
    method _ensure_schema (line 68) | async def _ensure_schema(self):
    method save_conversation (line 114) | async def save_conversation(
    method get_conversation (line 158) | async def get_conversation(
    method get_thread_history (line 192) | async def get_thread_history(
    method get_latest_version (line 239) | async def get_latest_version(self, agent_id: str, thread_id: str, user...
    method delete_conversation (line 261) | async def delete_conversation(self, agent_id: str, thread_id: str, ver...
    method delete_stream_events (line 283) | async def delete_stream_events(self, agent_id: str, thread_id: str, us...
    method delete_thread (line 302) | async def delete_thread(self, agent_id: str, thread_id: str, user_id: ...
    method get_all_threads_for_agent (line 325) | async def get_all_threads_for_agent(self, agent_id: str, user_id: str)...
    method save_stream_events (line 397) | async def save_stream_events(
    method get_stream_events (line 442) | async def get_stream_events(
    method append_stream_event (line 474) | async def append_stream_event(
  function get_conversation_db (line 503) | def get_conversation_db() -> ConversationHistoryDB:

FILE: src/cuga/backend/server/debug_server.py
  function main (line 5) | def main():

FILE: src/cuga/backend/server/demo_manage_setup.py
  function _get_filesystem_tool (line 27) | def _get_filesystem_tool() -> dict[str, Any]:
  function _get_email_tool (line 37) | def _get_email_tool() -> dict[str, Any]:
  function _get_crm_tool (line 47) | def _get_crm_tool() -> dict[str, Any]:
  function _get_digital_sales_tool (line 57) | def _get_digital_sales_tool() -> dict[str, Any]:
  function _get_knowledge_tool (line 66) | def _get_knowledge_tool() -> dict[str, Any]:
  function _knowledge_configured (line 82) | def _knowledge_configured() -> bool:
  function _get_oak_health_tool (line 115) | def _get_oak_health_tool() -> dict[str, Any]:
  function load_oak_policy_entries (line 133) | def load_oak_policy_entries() -> list[dict[str, Any]]:
  function _get_docs_tool (line 139) | def _get_docs_tool() -> dict[str, Any]:
  function build_tools_from_apps (line 153) | def build_tools_from_apps(
  function get_default_apps_for_preset (line 307) | def get_default_apps_for_preset(preset: str) -> dict[str, bool]:
  function setup_demo_manage_config (line 372) | def setup_demo_manage_config(
  function _resolve_oobe_knowledge_pdf_path (line 636) | def _resolve_oobe_knowledge_pdf_path() -> Path | None:
  function _demo_backend_base_url (line 649) | def _demo_backend_base_url(demo_port: int) -> str:
  function seed_demo_knowledge_oobe_pdf_if_needed (line 664) | def seed_demo_knowledge_oobe_pdf_if_needed(demo_port: int, agent_id: str...

FILE: src/cuga/backend/server/main.py
  function _session_knowledge_collection (line 74) | def _session_knowledge_collection(thread_id: str) -> str:
  function _delete_session_knowledge_for_thread (line 78) | async def _delete_session_knowledge_for_thread(app_state: "AppState", th...
  function _knowledge_enabled_for_app_state (line 91) | def _knowledge_enabled_for_app_state(app_state: "AppState" | None) -> bool:
  function _knowledge_scope_enabled_for_app_state (line 97) | def _knowledge_scope_enabled_for_app_state(app_state: "AppState" | None,...
  class AppState (line 153) | class AppState:
    method __init__ (line 156) | def __init__(self):
    method set_subsystem_status (line 207) | def set_subsystem_status(
    method get_subsystem_status (line 221) | def get_subsystem_status(self, name: str) -> Dict[str, Any]:
    method get_subsystem_statuses (line 232) | def get_subsystem_statuses(self) -> Dict[str, Dict[str, Any]]:
    method initialize_sdk (line 235) | def initialize_sdk(self):
  class DraftAppState (line 252) | class DraftAppState:
    method __init__ (line 255) | def __init__(self):
  class ChatRequest (line 270) | class ChatRequest(BaseModel):
  class AttachmentSnapshotItem (line 275) | class AttachmentSnapshotItem(BaseModel):
  function format_time_custom (line 283) | def format_time_custom():
  function manage_save_reuse_server (line 289) | async def manage_save_reuse_server():
  function lifespan (line 327) | async def lifespan(app: FastAPI):
  function get_element_names (line 819) | def get_element_names(tool_calls, elements):
  function copy_file_async (line 829) | async def copy_file_async(file_path, new_name):
  function validate_and_sync_policies (line 846) | async def validate_and_sync_policies(storage, filesystem_sync):
  function setup_page_info (line 903) | async def setup_page_info(state: AgentState, env: ExtensionEnv | Browser...
  function _save_conversation_and_events_async (line 920) | async def _save_conversation_and_events_async(
  function save_conversation_to_db (line 945) | async def save_conversation_to_db(
  function _next_event_or_stop (line 1074) | async def _next_event_or_stop(stream, stop_event):
  function event_stream (line 1100) | async def event_stream(
  function health (line 1565) | async def health():
  function readiness (line 1570) | async def readiness(subsystem: Optional[str] = Query(None)):
  function auth_config (line 1603) | async def auth_config():
  function ui_config (line 1608) | async def ui_config():
  function auth_login (line 1616) | async def auth_login(request: Request):
  function _jwt_payload_unverified (line 1642) | def _jwt_payload_unverified(token: Optional[str]) -> Optional[Dict[str, ...
  function _payload_has_role_claims (line 1653) | def _payload_has_role_claims(payload: Dict[str, Any]) -> bool:
  function _session_token_for_auto_role_source (line 1666) | def _session_token_for_auto_role_source(token_response: TokenResponse) -...
  function auth_callback (line 1677) | async def auth_callback(request: Request):
  function auth_logout (line 1792) | async def auth_logout():
  function auth_userinfo (line 1818) | async def auth_userinfo(request: Request):
  function get_communicator (line 1832) | def get_communicator() -> ChromeExtensionCommunicatorProtocol:
  function extension_command_stream (line 1842) | async def extension_command_stream():
  function extension_command_result (line 1853) | async def extension_command_result(request: Request):
  function extension_agent_query (line 1861) | async def extension_agent_query(request: Request):
  function stream (line 1916) | async def stream(
  function stop (line 1967) | async def stop(request: Request, current_user: Optional[UserInfo] = Depe...
  function reset_agent_state (line 1994) | async def reset_agent_state(
  function get_conversation_threads (line 2043) | async def get_conversation_threads(
  function get_conversation_messages (line 2059) | async def get_conversation_messages(
  function get_conversation_stream_events (line 2088) | async def get_conversation_stream_events(
  function get_tools_config (line 2114) | async def get_tools_config(current_user: Optional[UserInfo] = Depends(re...
  function save_tools_config (line 2137) | async def save_tools_config(
  function get_model_config (line 2162) | async def get_model_config(current_user: Optional[UserInfo] = Depends(re...
  function save_model_config (line 2172) | async def save_model_config(
  function get_conversations (line 2192) | async def get_conversations(
  function create_conversation (line 2226) | async def create_conversation(
  function delete_conversation (line 2248) | async def delete_conversation(
  function get_memory_config (line 2272) | async def get_memory_config(current_user: Optional[UserInfo] = Depends(r...
  function save_memory_config (line 2282) | async def save_memory_config(
  function get_policies_config (line 2297) | async def get_policies_config(
  function save_policies_config (line 2395) | async def save_policies_config(
  function get_tools_list (line 2519) | async def get_tools_list(
  function get_tools_status (line 2591) | async def get_tools_status(current_user: Optional[UserInfo] = Depends(re...
  function save_mode_config (line 2632) | async def save_mode_config(
  function get_agent_state (line 2658) | async def get_agent_state(
  function get_subagents_config (line 2725) | async def get_subagents_config(current_user: Optional[UserInfo] = Depend...
  function get_apps_endpoint (line 2851) | async def get_apps_endpoint(current_user: Optional[UserInfo] = Depends(r...
  function get_app_tools (line 2871) | async def get_app_tools(
  function save_subagents_config (line 2892) | async def save_subagents_config(
  function save_agent_mode_config (line 2907) | async def save_agent_mode_config(
  function get_agents_list (line 2923) | async def get_agents_list(current_user: Optional[UserInfo] = Depends(req...
  function get_agent_context (line 2981) | async def get_agent_context(current_user: Optional[UserInfo] = Depends(r...
  function get_workspace_tree (line 2995) | async def get_workspace_tree(current_user: Optional[UserInfo] = Depends(...
  function get_workspace_file (line 3033) | async def get_workspace_file(
  function download_workspace_file (line 3080) | async def download_workspace_file(
  function proxy_function_call (line 3194) | async def proxy_function_call(
  function validate_input_length (line 3240) | def validate_input_length(text: str) -> None:
  function get_query (line 3258) | async def get_query(request: Request) -> Union[str, ActionResponse]:
  function get_attachment_snapshot (line 3297) | async def get_attachment_snapshot(request: Request) -> Optional[List[Dic...
  function serve_flows (line 3320) | async def serve_flows(full_path: str, request: Request):
  function serve_react (line 3329) | async def serve_react(full_path: str, request: Request):

FILE: src/cuga/backend/server/manage_routes.py
  function _app_state (line 21) | def _app_state(request: Request):
  function _extract_agent_feature_overrides (line 25) | def _extract_agent_feature_overrides(config: dict[str, Any]) -> dict[str...
  function _merge_feature_flags_defaults (line 61) | def _merge_feature_flags_defaults(config: dict[str, Any]) -> None:
  function _merge_mcp_yaml_into_config (line 81) | def _merge_mcp_yaml_into_config(config: dict[str, Any]) -> None:
  function _apply_published_config (line 103) | async def _apply_published_config(app_state: Any, config: dict[str, Any]...
  function _apply_llm_to_state (line 200) | def _apply_llm_to_state(state: Any, llm_cfg: dict) -> None:
  function _apply_llm_to_draft_state (line 253) | def _apply_llm_to_draft_state(state: Any, llm_cfg: dict) -> None:
  function _load_and_patch_draft (line 275) | async def _load_and_patch_draft(agent_id: str, section: str, value: Any)...
  function get_manage_config (line 285) | async def get_manage_config(
  function list_llm_models (line 333) | async def list_llm_models(
  function save_manage_config_draft (line 503) | async def save_manage_config_draft(request: Request, agent_id: Optional[...
  function patch_draft_llm (line 714) | async def patch_draft_llm(request: Request, agent_id: Optional[str] = No...
  function patch_draft_tools (line 735) | async def patch_draft_tools(request: Request, agent_id: Optional[str] = ...
  function patch_draft_agent (line 813) | async def patch_draft_agent(request: Request, agent_id: Optional[str] = ...
  function patch_draft_policies (line 832) | async def patch_draft_policies(request: Request, agent_id: Optional[str]...
  function patch_draft_knowledge (line 867) | async def patch_draft_knowledge(request: Request, agent_id: Optional[str...
  function save_manage_config_publish (line 944) | async def save_manage_config_publish(request: Request, agent_id: Optiona...
  function get_manage_config_history (line 1279) | async def get_manage_config_history(agent_id: Optional[str] = None):
  function delete_manage_config (line 1294) | async def delete_manage_config(agent_id: Optional[str] = None, reset_db:...

FILE: src/cuga/backend/server/managed_mcp.py
  function get_managed_mcp_path (line 12) | def get_managed_mcp_path() -> str:
  function ensure_managed_mcp_file_exists (line 30) | def ensure_managed_mcp_file_exists(path: str | None = None) -> str:
  function tools_to_registry_yaml (line 39) | def tools_to_registry_yaml(tools: list[dict[str, Any]]) -> dict[str, Any]:
  function read_managed_mcp_servers (line 71) | def read_managed_mcp_servers(path: str | None = None) -> dict[str, dict[...
  function _merge_existing_mcp_servers (line 84) | def _merge_existing_mcp_servers(new_data: dict[str, Any], path: str) -> ...
  function write_managed_mcp_yaml (line 117) | def write_managed_mcp_yaml(config: dict[str, Any], path: str | None = No...
  function get_tools_from_agent_config (line 134) | async def get_tools_from_agent_config(agent_id: str) -> list[dict[str, A...
  function get_registry_yaml_from_agent_config (line 163) | async def get_registry_yaml_from_agent_config(agent_id: str) -> dict[str...
  function write_registry_yaml_from_agent_config (line 169) | async def write_registry_yaml_from_agent_config(agent_id: str, path: str...

FILE: src/cuga/backend/server/mcp_servers/cuga.py
  function run_task (line 14) | async def run_task(task: str, start_url: str):
  function perform_ui_task (line 27) | async def perform_ui_task(start_url: str, task: str) -> str:

FILE: src/cuga/backend/server/secrets_routes.py
  function _user_id (line 23) | def _user_id(user: Optional[UserInfo]) -> str:
  class SecretCreate (line 27) | class SecretCreate(BaseModel):
  class SecretUpdate (line 36) | class SecretUpdate(BaseModel):
  function list_secrets (line 45) | async def list_secrets(
  function get_secrets_config (line 111) | async def get_secrets_confi
Copy disabled (too large) Download .json
Condensed preview — 1049 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (23,436K chars).
[
  {
    "path": ".claude/commands/cuga-commit.md",
    "chars": 303,
    "preview": "1. Commit current changes, one per file or (depends what user asks), but if its build files then all build files one com"
  },
  {
    "path": ".claude/commands/cuga-create-pr.md",
    "chars": 2730,
    "preview": "\n### Step 1: Validate Your Local Repository do it all against upstream `origin`\n\nBefore creating a PR, you must ensure a"
  },
  {
    "path": ".claude/commands/cuga-new-feature.md",
    "chars": 1481,
    "preview": "# Create a new issue (upstream)\n\n1. Create the issue with the GitHub CLI (`gh issue create`).\n2. Open it against the **o"
  },
  {
    "path": ".claude/commands/cuga-report-bug.md",
    "chars": 952,
    "preview": "# Report a bug (upstream issue)\n\n1. Create the issue with the GitHub CLI (`gh issue create`).\n2. Open it against the **o"
  },
  {
    "path": ".claude/commands/cuga-ruff-check.md",
    "chars": 252,
    "preview": "1. Run `uv run ruff check --fix` on the project (or the files in scope).\n\n2. Fix any issues Ruff still reports after `--"
  },
  {
    "path": ".cra/.fileignore",
    "chars": 28,
    "preview": "docs\nnode_modules\nDockerfile"
  },
  {
    "path": ".dockerignore",
    "chars": 2054,
    "preview": "# Logging directories and files\nlogs/\nlog/\nlogging/\n*.log\n*.log.*\n\n# Node.js dependencies\nnode_modules/\n**/node_modules/"
  },
  {
    "path": ".gitattributes",
    "chars": 649,
    "preview": "# Shell scripts must use LF so Linux containers do not get CRLF shebangs (exec format error)\n*.sh text eol=lf\n\n# Exclude"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1302,
    "preview": "name: 🐛 Bug Report\ndescription: Report a bug or unexpected behavior\ntitle: \"[Bug]: \"\nlabels: [\"bug\", \"needs-triage\"]\nass"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 28,
    "preview": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation-request.yml",
    "chars": 2619,
    "preview": "name: 📚 Documentation Update\ndescription: Suggest a fix, enhancement, or new content for the documentation.\ntitle: \"[Doc"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "chars": 2017,
    "preview": "name: ✨ Feature / Design / Proposal\ndescription: Suggest a new feature, design, refactor, or other improvement\ntitle: \"["
  },
  {
    "path": ".github/ISSUE_TEMPLATE/use_case.yml",
    "chars": 7331,
    "preview": "name: 💡 Use Case / Success Story\ndescription: Share how you're using CUGA or showcase a successful implementation\ntitle:"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/bugfix.md",
    "chars": 86,
    "preview": "## Bug fix\n\nFixes #\n\n### Summary\n\n\n### Testing\n- [ ] Verified fix locally; tests pass\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/chore.md",
    "chars": 33,
    "preview": "## Chore\n\nCloses #\n\n### Summary\n\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/docs.md",
    "chars": 41,
    "preview": "## Documentation\n\nCloses #\n\n### Summary\n\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE/feature.md",
    "chars": 81,
    "preview": "## Feature\n\nCloses #\n\n### Summary\n\n\n### Testing\n- [ ] Tested locally; tests pass\n"
  },
  {
    "path": ".github/workflows/deploy-image-ghcr.yml",
    "chars": 2205,
    "preview": "# Required vars: IMAGE_NAME\nname: Deploy Image to GHCR\n\non:\n  push:\n    tags:\n      - 'v[0-9]+.[0-9]+.[0-9]+'\n  workflow"
  },
  {
    "path": ".github/workflows/deploy-image.yml",
    "chars": 2705,
    "preview": "# Required secret: RIS_CLOUD_ACCOUNT_API_KEY\n# Required vars: IBM_CLOUD_URL, IBM_CLOUD_REGION, IBM_CLOUD_GROUP, IBM_REGI"
  },
  {
    "path": ".github/workflows/release-pr.yml",
    "chars": 2117,
    "preview": "name: Release PR\n\non:\n  workflow_dispatch:\n    inputs:\n      bump:\n        description: 'Version bump type'\n        requ"
  },
  {
    "path": ".github/workflows/release-tag.yml",
    "chars": 1836,
    "preview": "name: Release Tag\n\non:\n  pull_request:\n    types: [closed]\n    branches: [main]\n  workflow_dispatch:\n    inputs:\n      v"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 517,
    "preview": "name: Release\n\non:\n  push:\n    tags:\n      - v*\n  workflow_dispatch:\n\njobs:\n  pypi:\n    name: Publish to PyPI\n    runs-o"
  },
  {
    "path": ".github/workflows/smoke-pip-install.yml",
    "chars": 1039,
    "preview": "name: Smoke pip install (isolated)\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main, devel"
  },
  {
    "path": ".github/workflows/stability-tests.yml",
    "chars": 5805,
    "preview": "name: Stability Tests\n\non:\n  push:\n    branches: [ main, develop ]\n  pull_request:\n    branches: [ main, develop ]\n  wor"
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 1016,
    "preview": "name: Tests\n\non:\n  push:\n    branches: [ main, develop ]\n  pull_request:\n    branches: [ main, develop ]\n  workflow_disp"
  },
  {
    "path": ".gitignore",
    "chars": 1851,
    "preview": ".env\n__pycache__\noutput\n*.db\ncuga_workspace/\n.idea\nnode_modules\n.pnpm-store/\n*.log\n/frontend/dist/\nsrc/frontend_workspac"
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 1236,
    "preview": "# Pre-commit hooks configuration\n# See https://pre-commit.com for more information\n\nrepos:\n  # Ruff - Python linting and"
  },
  {
    "path": ".python-version",
    "chars": 6,
    "preview": "3.12.7"
  },
  {
    "path": ".run/API Registry Appworld.run.xml",
    "chars": 1728,
    "preview": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"API Registry Appworld\" type=\"Py"
  },
  {
    "path": ".run/API Registry Demo.run.xml",
    "chars": 1714,
    "preview": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"API Registry Demo\" type=\"Python"
  },
  {
    "path": ".run/App World Eval.run.xml",
    "chars": 1555,
    "preview": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"App World Eval\" type=\"PythonCon"
  },
  {
    "path": ".run/Cuga Demo.run.xml",
    "chars": 1621,
    "preview": "<component name=\"ProjectRunConfigurationManager\">\n  <configuration default=\"false\" name=\"Cuga Demo\" type=\"PythonConfigur"
  },
  {
    "path": ".secrets.baseline",
    "chars": 20617,
    "preview": "{\n  \"exclude\": {\n    \"files\": \"(.*pnpm-lock.*|.*js.*|node_modules|.venv|.*jinja2.*|.*woff2.*)|^.secrets.baseline$|^.env$"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 2834,
    "preview": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"API Registry Appworld\",\n      \"type\": \"python\",\n     "
  },
  {
    "path": ".vscode/settings.json",
    "chars": 403,
    "preview": "{\n    \"python.envFile\": \"${workspaceFolder}/.env\",\n    \"debugpy.debugJustMyCode\": true,\n    \"[python]\": {\n        \"edito"
  },
  {
    "path": ".whitesource",
    "chars": 77,
    "preview": "{\n  \"settingsInheritedFrom\": \"whitesource-config/whitesource-config@master\"\n}"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 10913,
    "preview": "# Development Contributing Guide\n\n## How to Contribute\n\n1. Fork the repository to your own GitHub account. (not needed i"
  },
  {
    "path": "Dockerfile",
    "chars": 1542,
    "preview": "FROM python:3.12-slim-trixie\n\n# The installer requires curl (and certificates) to download the release archive\nRUN apt-g"
  },
  {
    "path": "Dockerfile.ubi",
    "chars": 4659,
    "preview": "# Multi-stage: builder installs deps, runtime keeps only what's needed\nARG BASE_IMAGE=registry.access.redhat.com/ubi9/py"
  },
  {
    "path": "LICENSE",
    "chars": 13776,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 38985,
    "preview": "<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"/docs/images/cuga-dark.png\">\n  <source media=\"(prefers-"
  },
  {
    "path": "__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "deployment/README.md",
    "chars": 13929,
    "preview": "# CUGA Helm Chart\n\nDeploy CUGA agent to Kubernetes.\n\n## Quick Start\n\n```bash\n# 1. Create .env with your API key\ncp .env."
  },
  {
    "path": "deployment/certs/README.md",
    "chars": 552,
    "preview": "# Local TLS certificates for HTTPS\n\nWhen using OIDC (e.g. IBM Verify) with redirect URIs like `https://localhost:7860/ma"
  },
  {
    "path": "deployment/deploy-local-postgres.sh",
    "chars": 1425,
    "preview": "#!/usr/bin/env bash\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/."
  },
  {
    "path": "deployment/deploy-local.sh",
    "chars": 2691,
    "preview": "#!/usr/bin/env bash\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPROJECT_ROOT=\"$(cd \"$SCRIPT_DIR/."
  },
  {
    "path": "deployment/docker-compose/openlit/docker-compose.yml",
    "chars": 2213,
    "preview": "# Local observability stack for testing OpenLit integration with Cuga.\n#\n# Services:\n#   otel-collector  - Receives OTLP"
  },
  {
    "path": "deployment/docker-compose/openlit/grafana-datasources.yaml",
    "chars": 637,
    "preview": "# Grafana datasource provisioning for Cuga + OpenLit local testing stack.\n#\n# Pre-configures Grafana with:\n#   - Tempo d"
  },
  {
    "path": "deployment/docker-compose/openlit/otel-collector-config.yaml",
    "chars": 715,
    "preview": "# OpenTelemetry Collector configuration for Cuga + OpenLit local testing stack.\n#\n# Data flow:\n#   OpenLit (Cuga) --OTLP"
  },
  {
    "path": "deployment/docker-compose/openlit/prometheus.yml",
    "chars": 368,
    "preview": "# Prometheus configuration for Cuga + OpenLit local testing stack.\n#\n# Scrapes LLM metrics from the OTel Collector's Pro"
  },
  {
    "path": "deployment/docker-compose/openlit/tempo.yaml",
    "chars": 1161,
    "preview": "# Grafana Tempo configuration for Cuga + OpenLit local testing stack.\n#\n# Tempo receives traces from the OTel Collector "
  },
  {
    "path": "deployment/helm/cleanup-openshift.sh",
    "chars": 5930,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\n# ---------------------------------------------------------------------------\n# C"
  },
  {
    "path": "deployment/helm/cuga/Chart.yaml",
    "chars": 152,
    "preview": "apiVersion: v2\nname: cuga\ndescription: CUGA agent - generalist agent for enterprise task execution\ntype: application\nver"
  },
  {
    "path": "deployment/helm/cuga/templates/NOTES.txt",
    "chars": 186,
    "preview": "CUGA agent has been deployed.\n\nAccess via port-forward:\n  kubectl port-forward -n {{ .Release.Namespace }} svc/{{ includ"
  },
  {
    "path": "deployment/helm/cuga/templates/_helpers.tpl",
    "chars": 1000,
    "preview": "{{/*\nExpand the name of the chart.\n*/}}\n{{- define \"cuga.name\" -}}\n{{- default .Chart.Name .Values.nameOverride | trunc "
  },
  {
    "path": "deployment/helm/cuga/templates/deployment.yaml",
    "chars": 2748,
    "preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"cuga.fullname\" . }}\n  labels:\n    {{- include \"cuga.l"
  },
  {
    "path": "deployment/helm/cuga/templates/pvc.yaml",
    "chars": 341,
    "preview": "{{- if .Values.persistence.dbs.enabled }}\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: {{ include \"cuga."
  },
  {
    "path": "deployment/helm/cuga/templates/route.yaml",
    "chars": 634,
    "preview": "{{- if .Values.route.enabled }}\napiVersion: route.openshift.io/v1\nkind: Route\nmetadata:\n  name: {{ include \"cuga.fullnam"
  },
  {
    "path": "deployment/helm/cuga/templates/service.yaml",
    "chars": 352,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: {{ include \"cuga.fullname\" . }}\n  labels:\n    {{- include \"cuga.labels\" ."
  },
  {
    "path": "deployment/helm/cuga/values.yaml",
    "chars": 1577,
    "preview": "replicaCount: 1\n\nimage:\n  repository: ghcr.io/cuga-project/cuga\n  tag: latest\n  pullPolicy: Always\n\nimagePullSecrets: []"
  },
  {
    "path": "deployment/helm/deploy-openshift.sh",
    "chars": 16983,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\n# ---------------------------------------------------------------------------\n# C"
  },
  {
    "path": "deployment/helm/openshift.example.env",
    "chars": 4399,
    "preview": "# OpenShift deployment configuration\n# Copy this file to openshift.env (or any name), fill in values, and pass it to dep"
  },
  {
    "path": "deployment/helm/postgres-pgvector/Chart.yaml",
    "chars": 218,
    "preview": "apiVersion: v2\nname: postgres-pgvector\ndescription: PostgreSQL with pgvector extension for Cuga agent production storage"
  },
  {
    "path": "deployment/helm/postgres-pgvector/README.md",
    "chars": 1226,
    "preview": "# postgres-pgvector\n\nPostgreSQL with pgvector extension for Cuga agent production storage (policies, embeddings).\n\n## In"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/NOTES.txt",
    "chars": 745,
    "preview": "PostgreSQL with pgvector has been deployed.\n\n1. Get the application URL:\n   export POSTGRES_HOST={{ include \"postgres-pg"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/_helpers.tpl",
    "chars": 1078,
    "preview": "{{/*\nExpand the name of the chart.\n*/}}\n{{- define \"postgres-pgvector.name\" -}}\n{{- default .Chart.Name .Values.nameOver"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/configmap.yaml",
    "chars": 244,
    "preview": "apiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: {{ include \"postgres-pgvector.fullname\" . }}-init\n  labels:\n    {{- inc"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/deployment.yaml",
    "chars": 2667,
    "preview": "apiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: {{ include \"postgres-pgvector.fullname\" . }}\n  labels:\n    {{- in"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/pvc.yaml",
    "chars": 356,
    "preview": "{{- if .Values.persistence.enabled }}\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  name: {{ include \"postgres-"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/secret.yaml",
    "chars": 315,
    "preview": "{{- if and .Values.auth.password (not .Values.auth.existingSecret) }}\napiVersion: v1\nkind: Secret\nmetadata:\n  name: {{ i"
  },
  {
    "path": "deployment/helm/postgres-pgvector/templates/service.yaml",
    "chars": 399,
    "preview": "apiVersion: v1\nkind: Service\nmetadata:\n  name: {{ include \"postgres-pgvector.fullname\" . }}\n  labels:\n    {{- include \"p"
  },
  {
    "path": "deployment/helm/postgres-pgvector/values.yaml",
    "chars": 491,
    "preview": "image:\n  repository: pgvector/pgvector\n  tag: pg16\n  pullPolicy: IfNotPresent\n\n# Optional (e.g. Docker Hub authenticated"
  },
  {
    "path": "deployment/helm/status-openshift.sh",
    "chars": 8167,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\n# ---------------------------------------------------------------------------\n# C"
  },
  {
    "path": "deployment/helm/vault/Chart.yaml",
    "chars": 253,
    "preview": "apiVersion: v2\nname: vault\ndescription: HashiCorp Vault sub-chart for CUGA secret management\ntype: application\nversion: "
  },
  {
    "path": "deployment/helm/vault/templates/NOTES.txt",
    "chars": 583,
    "preview": "HashiCorp Vault has been deployed.\n\nTo initialize and unseal Vault (first time only):\n  kubectl exec -n {{ .Release.Name"
  },
  {
    "path": "deployment/helm/vault/values.openshift.yaml",
    "chars": 793,
    "preview": "# OpenShift-specific overrides for the vault sub-chart.\n# Use: helm upgrade --install vault ./vault -f values.openshift."
  },
  {
    "path": "deployment/helm/vault/values.yaml",
    "chars": 1482,
    "preview": "# Default values for HashiCorp Vault deployment alongside CUGA.\n# Override per environment using values.openshift.yaml o"
  },
  {
    "path": "design.html",
    "chars": 41755,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  },
  {
    "path": "design.md",
    "chars": 12530,
    "preview": "# CugaSupervisor Design Document\n\n## Overview\n\nThis document describes the CugaSupervisor feature implementation - a sub"
  },
  {
    "path": "docs/examples/cuga_as_mcp/.python-version",
    "chars": 5,
    "preview": "3.12\n"
  },
  {
    "path": "docs/examples/cuga_as_mcp/README.md",
    "chars": 5383,
    "preview": "# CUGA as MCP Server\n\nThis example demonstrates how to run CUGA (Computer Using Generalist Agent) as a Model Context Pro"
  },
  {
    "path": "docs/examples/cuga_as_mcp/main.py",
    "chars": 3043,
    "preview": "from cuga.backend.activity_tracker.tracker import ActivityTracker\nfrom cuga.backend.cuga_graph.utils.controller import A"
  },
  {
    "path": "docs/examples/cuga_as_mcp/mcp_servers.yaml",
    "chars": 932,
    "preview": "# OpenAPI direct integration\nservices:\n  - digital_sales:\n      url: https://digitalsales.19pc1vtv090u.us-east.codeengin"
  },
  {
    "path": "docs/examples/cuga_as_mcp/pyproject.toml",
    "chars": 384,
    "preview": "[project]\nname = \"test-cuga-package-2\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\n"
  },
  {
    "path": "docs/examples/cuga_as_mcp/tools_loader.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/.gitignore",
    "chars": 7,
    "preview": "logging"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/.python-version",
    "chars": 5,
    "preview": "3.12\n"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/README.md",
    "chars": 9363,
    "preview": "# CUGA Tool Integration Examples\n\nThis directory demonstrates **three types of tool integrations** that CUGA supports, s"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/fast_mcp_example.py",
    "chars": 1894,
    "preview": "\"\"\"\nFastMCP Example - Digital Sales API Integration\n\nThis example demonstrates how to create an MCP server from an OpenA"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/langchain_example_tool.py",
    "chars": 3947,
    "preview": "from langchain_core.tools import StructuredTool\nfrom pydantic import BaseModel\nfrom typing import List, Optional\nfrom da"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/main.py",
    "chars": 1873,
    "preview": "\"\"\"\nMain application for running tasks with CugaAgent and MCP integration.\n\nThis example demonstrates how to use the Cug"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/mcp_servers.yaml",
    "chars": 2361,
    "preview": "# CUGA Tool Integration Configuration\n# This file demonstrates three types of tool integrations:\n# 1. OpenAPI Tools (RES"
  },
  {
    "path": "docs/examples/cuga_with_runtime_tools/pyproject.toml",
    "chars": 382,
    "preview": "[project]\nname = \"test-cuga-package\"\nversion = \"0.1.0\"\ndescription = \"Add your description here\"\nreadme = \"README.md\"\nli"
  },
  {
    "path": "docs/examples/demo_apps/setup/README.md",
    "chars": 921,
    "preview": "# CUGA Demo Setup\n\n## Installation\n```bash\nuvx --from git+https://github.com/cuga-project/cuga-agent.git#subdirectory=do"
  },
  {
    "path": "docs/examples/demo_apps/setup/cli.py",
    "chars": 29737,
    "preview": "#!/usr/bin/env python3\n\"\"\"\nCUGA Demo Setup CLI\nA one-command solution to set up and run the CUGA Agent demo\n\"\"\"\n\nimport "
  },
  {
    "path": "docs/examples/demo_apps/setup/pyproject.toml",
    "chars": 433,
    "preview": "[build-system]\nrequires = [\"setuptools>=45\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[project]\nname = \"create-"
  },
  {
    "path": "docs/examples/digital_sales_openapi/main.py",
    "chars": 14227,
    "preview": "import random\nfrom typing import Dict, List, Optional, Set\n\nfrom fastapi import FastAPI, Path, Query\nfrom pydantic impor"
  },
  {
    "path": "docs/examples/evaluation/input_example.json",
    "chars": 2578,
    "preview": "[\n  {\n    \"name\": \"digital-sales\",\n    \"test_cases\": [\n      {\n        \"name\": \"test_get_top_account\",\n        \"descript"
  },
  {
    "path": "docs/examples/evaluation/input_schema.json",
    "chars": 1489,
    "preview": "{\n  \"name\": \"name for the test suite\",\n  \"title\": \"TestCases\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"test_cases\": {"
  },
  {
    "path": "docs/examples/langflow/CUGA Langflow Demo - Conference Preparation.json",
    "chars": 391249,
    "preview": "{\n  \"data\": {\n    \"edges\": [\n      {\n        \"animated\": false,\n        \"className\": \"\",\n        \"data\": {\n          \"so"
  },
  {
    "path": "docs/flags.html",
    "chars": 42999,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-w"
  },
  {
    "path": "docs/memory/README.md",
    "chars": 2100,
    "preview": "# Memory for CUGA\n\nThis document explains how to enable the use of the memory feature in CUGA.\n\n## 🎯 Overview\n\nCUGA exec"
  },
  {
    "path": "docs/sales_app.html",
    "chars": 21332,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width"
  },
  {
    "path": "pyproject.toml",
    "chars": 9183,
    "preview": "[project]\nname = \"cuga\"\nversion = \"0.2.24\"\ndescription = \"CUGA is an open-source generalist agent for the enterprise, su"
  },
  {
    "path": "readme_cuga_lite_kaizen.md",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ruff.toml",
    "chars": 1325,
    "preview": "# Exclude a variety of commonly ignored directories.\nexclude = [\n    \".bzr\",\n    \".direnv\",\n    \".eggs\",\n    \".git\",\n   "
  },
  {
    "path": "run_stability_tests.py",
    "chars": 28655,
    "preview": "import os\nimport subprocess\nfrom datetime import datetime\nfrom dynaconf import Dynaconf\nimport sys\nimport argparse\nimpor"
  },
  {
    "path": "scripts/deploy-image.sh",
    "chars": 1047,
    "preview": "#!/usr/bin/env bash\n\necho \"--------------------------------------------------------------\"\necho 'Commencing image push t"
  },
  {
    "path": "scripts/docker-entrypoint.sh",
    "chars": 905,
    "preview": "#!/bin/sh\nset -e\n\nMODE=\"${CUGA_DEMO_MODE:-default}\"\n\n# Use the cuga binary directly from the venv to avoid uv reinstalli"
  },
  {
    "path": "scripts/smoke_pip_install_isolated.sh",
    "chars": 3862,
    "preview": "#!/usr/bin/env bash\n# Build cuga wheel and install it with uv pip from an empty /tmp directory (no project context).\n# T"
  },
  {
    "path": "src/cuga/__init__.py",
    "chars": 1123,
    "preview": "\"\"\"\nCUGA: The Configurable Generalist Agent\n\nCUGA is a state-of-the-art generalist agent designed for enterprise needs,\n"
  },
  {
    "path": "src/cuga/backend/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/activity_tracker/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/activity_tracker/join_tool.py",
    "chars": 3606,
    "preview": "from typing import List\n\nfrom cuga.backend.tools_env.registry.utils.types import AppDefinition\n\n\ndef assign_applications"
  },
  {
    "path": "src/cuga/backend/activity_tracker/render_helper.py",
    "chars": 6702,
    "preview": "import argparse\nimport json\nimport os\nimport re\nfrom json import JSONDecodeError\nfrom pathlib import Path\n\nfrom cuga.bac"
  },
  {
    "path": "src/cuga/backend/activity_tracker/tracker.py",
    "chars": 55920,
    "preview": "import copy\nimport json\nimport os\nimport shutil\nfrom datetime import datetime\nfrom typing import Any, Dict, List, Option"
  },
  {
    "path": "src/cuga/backend/browser_env/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/browser/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/browser/chat_async.py",
    "chars": 4214,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/env.py",
    "chars": 3135,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/extension_env_async.py",
    "chars": 14430,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_env.py",
    "chars": 26288,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_env_async.py",
    "chars": 32260,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\nimport "
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/extract_chrome_extension.py",
    "chars": 18784,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/http_stream_comm.py",
    "chars": 6433,
    "preview": "import asyncio\nimport uuid\nfrom typing import Any, Dict, Optional, Protocol, runtime_checkable\n\n\n@runtime_checkable\nclas"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/javascript/frame_mark_elements.js",
    "chars": 12433,
    "preview": "/*\n * Copyright 2024 ServiceNow\n * Modifications Copyright 2025 CUGA\n * Licensed under the Apache License, Version 2.0\n "
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/javascript/frame_unmark_elements.js",
    "chars": 1653,
    "preview": "/*\n * Copyright 2024 ServiceNow\n * Modifications Copyright 2025 CUGA\n * Licensed under the Apache License, Version 2.0\n "
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/obs.py",
    "chars": 6128,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/obs_async.py",
    "chars": 13677,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/gym_obs/websocket_server.py",
    "chars": 21130,
    "preview": "import asyncio\nimport json\nimport uuid\nfrom typing import Any, Dict, Optional\n\nimport websockets\nfrom loguru import logg"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/open_ended_async.py",
    "chars": 3609,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nfrom a"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/utils.py",
    "chars": 8327,
    "preview": "from typing import Literal\n\nimport playwright.async_api\n\n\nasync def highlight_by_box_async(\n    page: playwright.async_a"
  },
  {
    "path": "src/cuga/backend/browser_env/browser/utils_async.py",
    "chars": 502,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/extension_processor.py",
    "chars": 2569,
    "preview": "from cuga.backend.browser_env.page_understanding.pu_extractor_chrome_extension import (\n    PUExtractedChromeExtension,\n"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/extractor_utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/extractor_utils/extract_async.py",
    "chars": 22134,
    "preview": "import base64\nimport io\nimport logging\nimport pkgutil\nimport re\nfrom typing import Literal\n\nimport numpy as np\nimport PI"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/extractor_utils/javascript/frame_mark_elements.js",
    "chars": 12478,
    "preview": "/**\n * Go through all DOM elements in the frame (including shadowDOMs), give them unique browsergym\n * identifiers (bid)"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/extractor_utils/javascript/frame_unmark_elements.js",
    "chars": 1530,
    "preview": "/**\n * Go through all DOM elements in the frame (including shadowDOMs),\n * and cleanup previously stored data in ARIA at"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/model.py",
    "chars": 2714,
    "preview": "import uuid\nfrom typing import Any, Generic, Optional, TypeVar\n\nfrom pydantic import BaseModel, ConfigDict, Field\n\nTComm"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/nocode_utils.py",
    "chars": 3106,
    "preview": "import json\nimport os\nfrom typing import Any\n\nimport yaml\nfrom playwright.async_api import BrowserContext as BrowserExte"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/nocodeui_pu_utils/rules.yaml",
    "chars": 1781,
    "preview": "- name: misc_rule\n  selector: .modal-container,[accessible-role=\"Dialog\"],[role=\"dialog\"],.slds-modal__container\n  color"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/pu_extractor.py",
    "chars": 4024,
    "preview": "import asyncio\nfrom typing import Dict, Literal, Optional\n\nfrom markdownify import markdownify\nfrom loguru import logger"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/pu_extractor_chrome_extension.py",
    "chars": 6477,
    "preview": "from typing import Dict, Literal, Optional, Protocol, runtime_checkable\n\nfrom markdownify import markdownify\nfrom loguru"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/pu_processor.py",
    "chars": 1846,
    "preview": "import importlib\nfrom typing import Any, Dict\n\nfrom playwright.async_api import BrowserContext, Page\n\nfrom cuga.config i"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/pu_transform.py",
    "chars": 1286,
    "preview": "import logging\nfrom typing import Optional\n\nfrom pydantic import BaseModel\n\nfrom cuga.backend.browser_env.page_understan"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/tranformer_utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/tranformer_utils/dom_transform_utils.py",
    "chars": 11205,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/tranformer_utils/transform_utils.py",
    "chars": 9158,
    "preview": "# Copyright 2024 ServiceNow\n# Modifications Copyright 2025 CUGA\n# Licensed under the Apache License, Version 2.0\n\nimport"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/types/README.md",
    "chars": 4753,
    "preview": "# DOM Tree Types\n\nPydantic models for DOM tree extraction results from the Chrome extension.\n\n## Overview\n\nThe DOM tree "
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/types/__init__.py",
    "chars": 287,
    "preview": "\"\"\"\nType definitions for page understanding components\n\"\"\"\n\nfrom .dom_tree_types import (\n    DomTreeArgs,\n    NodeData,"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/types/dom_tree_types.py",
    "chars": 8214,
    "preview": "\"\"\"\nPydantic models for DOM tree extraction results from Chrome extension\n\"\"\"\n\nimport json\nfrom typing import Dict, List"
  },
  {
    "path": "src/cuga/backend/browser_env/page_understanding/types/validate_structure.py",
    "chars": 3365,
    "preview": "\"\"\"\nValidate the structure and field mappings without requiring pydantic\n\"\"\"\n\n\ndef validate_field_mappings():\n    \"\"\"\n  "
  },
  {
    "path": "src/cuga/backend/browser_env/tools/__init__.py",
    "chars": 286,
    "preview": "from .providers import (\n    BrowserToolImplProvider,\n    ExtensionToolImplProvider,\n    PlaywrightToolImplProvider,\n   "
  },
  {
    "path": "src/cuga/backend/browser_env/tools/extension_commands.py",
    "chars": 16094,
    "preview": "\"\"\"\nExtension-based implementations of browser interaction commands.\n\nThese helpers are invoked when the Chrome extensio"
  },
  {
    "path": "src/cuga/backend/browser_env/tools/playwright_commands.py",
    "chars": 14099,
    "preview": "\"\"\"\nPlaywright-based implementations of browser interaction commands.\n\nThese helpers are used when *not* running with th"
  },
  {
    "path": "src/cuga/backend/browser_env/tools/providers.py",
    "chars": 2390,
    "preview": "\"\"\"\nProviders that expose concrete implementations for browser tools.\n\nThis module defines a protocol and two implementa"
  },
  {
    "path": "src/cuga/backend/cuga_graph/README.md",
    "chars": 3982,
    "preview": "## CUGA's Nodes\n---\n\n### **ChatAgent | Chat**\n\nThis agent manages follow-up questions and handles conversations that tri"
  },
  {
    "path": "src/cuga/backend/cuga_graph/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/graph.py",
    "chars": 20357,
    "preview": "from typing import Optional\n\nfrom langgraph.checkpoint.memory import MemorySaver\nfrom langgraph.constants import END, ST"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer.py",
    "chars": 8841,
    "preview": "import json\nfrom typing import Literal, Dict, Callable\n\nfrom langchain_core.messages import AIMessage\nfrom langgraph.typ"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/final_answer_agent.py",
    "chars": 5251,
    "preview": "import json\nfrom typing import Any, Literal, Union\n\nfrom langchain_core.language_models import BaseChatModel\nfrom langch"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/load_prompt.py",
    "chars": 3212,
    "preview": "import re\nfrom typing import List, Literal, Any, Optional\n\nfrom langchain_core.output_parsers import PydanticOutputParse"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/system.jinja2",
    "chars": 1876,
    "preview": "You are an expert answer generation system. Your goal is to refine an initial draft answer into a very concise, informat"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/system_appworld.jinja2",
    "chars": 11707,
    "preview": "You're an AI assistant that processes user intents and the corresponding system answers. Your task is to analyze the inp"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/system_appworld_plain.jinja2",
    "chars": 8018,
    "preview": "You turn a **user intent** plus a **system answer** into a single final value for downstream completion checks. Do **not"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/system_concise.jinja2",
    "chars": 1795,
    "preview": "You are an expert answer generation system. Your goal is to refine an initial draft answer into a very concise, informat"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/system_long.jinja2",
    "chars": 5351,
    "preview": "You are an intelligent final answer agent as part of a web agent system that can perform tasks on behalf of a user. Your"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/user_msg.jinja2",
    "chars": 107,
    "preview": "user_intent: {{input}}\ninitial_draft_answer: {{last_planner_answer}}\nvariable_summary: {{variable_summary}}"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/user_msg_appworld.jinja2",
    "chars": 67,
    "preview": "`user_intent`: {{input}}\n`system_answer`: {{ last_planner_answer }}"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/answer/final_answer_agent/prompts/user_msg_appworld_plain.jinja2",
    "chars": 68,
    "preview": "`user_intent`: {{input}}\n`system_answer`: {{ last_planner_answer }}\n"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_agent_utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_agent_utils/utils.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_agent.py",
    "chars": 2055,
    "preview": "import json\nfrom typing import Literal\n\nfrom cuga.backend.activity_tracker.tracker import ActivityTracker, Step\nfrom cug"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner.py",
    "chars": 2485,
    "preview": "import json\nfrom typing import Literal\n\nfrom cuga.backend.activity_tracker.tracker import ActivityTracker, Step\nfrom cug"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/api_code_planner_agent.py",
    "chars": 3427,
    "preview": "from typing import Any\n\nfrom langchain_core.messages import AIMessage, BaseMessage\nfrom langchain_core.prompts import Ch"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/api_planner_prompt_v1.md",
    "chars": 7253,
    "preview": "You are a Strategic Planner Agent. Your purpose is to translate a user's goal into a clear, narrative-style, step-by-ste"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/load_prompt.py",
    "chars": 1238,
    "preview": "from typing import List, Literal\n\nfrom langchain_core.output_parsers import PydanticOutputParser\nfrom pydantic import Ba"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/system.backup.jinja2",
    "chars": 17268,
    "preview": "You are a Strategic Planner Agent. Your purpose is to translate a user's goal into a clear, narrative-style, step-by-ste"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/system.jinja2",
    "chars": 30439,
    "preview": "You are a Strategic Planner Agent. Your purpose is to translate a user's goal into a clear, narrative-style, step-by-ste"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/system_fast.jinja2",
    "chars": 13230,
    "preview": "# Strategic Planner Agent\n\nYou are a Strategic Planner Agent responsible for translating user goals into clear, executab"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/system_high_level_no_relation_to_vars.jinja2",
    "chars": 13600,
    "preview": "You are a Code Planner Agent. Your purpose is to translate a user's goal into a clear, narrative-style, step-by-step pla"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/test.md",
    "chars": 11469,
    "preview": "Of course. The issue you've highlighted is a classic example of an agent making a faulty assumption. It incorrectly infe"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_code_planner_agent/prompts/user.jinja2",
    "chars": 307,
    "preview": "* **User Goal:** {{coder_task}}\n\n{% if instructions -%}\n\n## Special Instructions\n{{ instructions }}\n\n{%- endif %}\n\n* **R"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner.py",
    "chars": 13629,
    "preview": "import json\nimport re\nfrom typing import Literal\n\n\nfrom cuga.backend.activity_tracker.tracker import ActivityTracker, St"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/api_planner_agent.py",
    "chars": 5712,
    "preview": "from typing import Any, Optional\n\nfrom langchain_core.messages import AIMessage\nfrom langchain_core.prompts import ChatP"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/prompts/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/prompts/load_prompt.py",
    "chars": 5187,
    "preview": "from typing import List\n\nfrom pydantic import BaseModel, Field\n\nfrom cuga.backend.activity_tracker.tracker import Activi"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/prompts/system.jinja2",
    "chars": 17854,
    "preview": "You are APIPlanner, an advanced AI agent responsible for orchestrating tasks to achieve a user's goal. Your primary func"
  },
  {
    "path": "src/cuga/backend/cuga_graph/nodes/api/api_planner_agent/prompts/system_hitl.jinja2",
    "chars": 15201,
    "preview": "You are APIPlanner, an advanced AI agent responsible for orchestrating tasks to achieve a user's goal. Your primary func"
  }
]

// ... and 849 more files (download for full content)

About this extraction

This page contains the full source code of the cuga-project/cuga-agent GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1049 files (21.5 MB), approximately 5.7M tokens, and a symbol index with 16689 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!