devops-bot-sdk 1.7.20__tar.gz → 1.7.33__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/PKG-INFO +3 -1
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/PKG-INFO +3 -1
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/SOURCES.txt +8 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/requires.txt +3 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/pyproject.toml +6 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/__init__.py +2 -2
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agentd.py +35 -12
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/schedules.py +56 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/cli.py +14 -9
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/config.py +3 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/git_ops.py +73 -14
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/graph_recon.py +4 -1
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/graphify.py +17 -3
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/helpdesk_kb.md +12 -1
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ipc/handlers.py +106 -16
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/log_colors.py +20 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/run_auto.py +48 -3
- devops_bot_sdk-1.7.33/sdk/schedule_timeline.py +171 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ticket_pools.py +88 -6
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/api.py +18 -2
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/dashboard.py +34 -9
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/models.py +2 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/agents.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/app.js +896 -109
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/chat.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/custom-agents.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/default-agents.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/faqs.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/help.html +6 -5
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/index.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/report.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/runs.html +2 -1
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/schedules.html +34 -13
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/setup.html +1 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/styles.css +303 -4
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/static/tickets.html +100 -26
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_run_ticket.py +62 -0
- devops_bot_sdk-1.7.33/tests/test_graph_off_by_default.py +27 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_graph_recon.py +6 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_graphify_build.py +6 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_graphify_hook_install.py +6 -0
- devops_bot_sdk-1.7.33/tests/test_pool_pr_modes.py +143 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_prd_artifact.py +6 -0
- devops_bot_sdk-1.7.33/tests/test_quiet_run_log.py +40 -0
- devops_bot_sdk-1.7.33/tests/test_schedule_timeline.py +115 -0
- devops_bot_sdk-1.7.33/tests/test_theme_switch.py +35 -0
- devops_bot_sdk-1.7.33/tests/test_ticket_detail_view.py +51 -0
- devops_bot_sdk-1.7.33/tests/test_ui_no_native_dialogs.py +18 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/README.md +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/devops_bot_sdk.egg-info/top_level.txt +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/classifier.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/collectors/common.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/collectors/linux_auditd.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/collectors/macos_eslogger.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/collectors/windows_eventlog.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/models.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/os_setup.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/recorder.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/redact.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/settings.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/shipper.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/activity/spool.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agent_sharing.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/activity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/builder.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/chat.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/connectors.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/claude_code.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/http.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/mcp.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/n8n.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/engines/shell.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/integrations.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/inventory.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/library/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/manifest.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/prompt_studio.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/prompt_template.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/prompt_vars.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/run_log.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/secrets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/ticket_run.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/usage.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/agents/varstore.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/browser_profile.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/claude_usage.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/client.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/collectors/files.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/collectors/process.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/collectors/screenshot.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/crucial.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/custom_agents.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/deferred_tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/departments.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/assets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/bootstrap.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/browser.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/compare.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/design_verify/loop.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/estimator.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/exceptions.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/fallback_handoff.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/faqs.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/firewall.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/formats.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/github_fetch.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/github_ingest.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/help_actions.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/helpdesk.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/hooks/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/hooks/crucial_guard.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/instructions_template.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/intake.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ipc/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ipc/electron_bridge.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/journal.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/local_exec.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/memory_guard.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/model_policy.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/models/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/models/envelope.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/models/requests.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/models/responses.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/models/snapshots.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/phase_timer.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/plan_run.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/platform_compat.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/prd_progress.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/proof_readers.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/providers.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/py.typed +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/resume.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/router.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/schedule_tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/scheduler.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/scope_plan.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/self_report.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/self_report_local.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/sse.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/swagger.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/task_file.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/task_types.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/test.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/test_pipeline.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ticket_board.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ticket_bulk.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ticket_fields.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ticket_plan.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/tiers/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/tiers/mini_agent.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/__init__.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/health.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/ip_allowlist.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/jobs.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/runner.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/security.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/server.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/service.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/session.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/setup_manager.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/ui/swagger.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/updater.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/url_access.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/vps_health.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/vps_identity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/sdk/write_hook.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/setup.cfg +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_claude_runs.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_collectors.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_core.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_live_tracking.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_macos.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_os_setup.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_activity_pipeline.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_activity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_activity_tracking.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_chat_features.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_crud_cli.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_listing.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_prompt_async.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_prompt_models.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_schedules.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_sharing.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agent_workspace_settings.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_agents_connectors_builder.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_allowed_tools_config.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_approval_park.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_auto_agent_dispatch.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_auto_ticket_queue.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_browser_profile.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_cheap_tier.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_claude_usage_gate.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_client_jira_projects.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_config_token_diagnostics.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_configure_token_owner.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_console_encoding.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_crash_recovery.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_create_safe_retry.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_deferred_tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_departments.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_done_transition.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_epic_decompose_run.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_epic_inherited_agent_id.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_epic_session_isolation.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_estimator.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_fallback_cli.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_fallback_cli_upgrade.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_faqs.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_firewall_open_on_update.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_formats.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_git_action.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_github_fetch.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_github_ingest.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_health.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_help_actions.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_help_attachments.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_help_questions.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_helpdesk.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_infographic_data.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_instructions_template.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_intake_job_outcome.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_intake_plan_review.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_journal.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_limit_fallback_handoff.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_local_exec_provider.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_log_colors_backlog.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_mcp_route_contract.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_memory_guard.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_model_policy.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_panel_help.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_panel_ticket_schedules.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_parallel_tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_phase_timer.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_plan_new_command.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_plan_run_activity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_pr_identity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_project_path_resolution.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_proof_readers.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_providers.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_recon_session_isolation.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_resume.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_router.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_run_auto_agent_only.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_run_outputs.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_run_verdict_is_honest.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_schedule_api.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_schedule_outputs_and_plans.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_schedule_tickets.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_scheduler.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_scheduler_transient_retry.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_self_report.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_service_token_warning.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_stale_panel_restart.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_swagger_command.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_task_file_and_plan_run.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_task_file_format_doc.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_board.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_bulk.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_cli.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_fields.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_plan.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_pools.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_run_resolve_by_id.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_schedule_and_agent.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ticket_speed_fixes.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_tier_flag_parity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ui_gate.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_ui_lifespan.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_update_timer.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_updater_extras.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_updater_ignores_cwd.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_updater_pep668.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_updater_reports_the_truth.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_url_access.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_vps_health.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_vps_only_reporting.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_windows_loop_identity.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_windows_panel_task.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_windows_stop_and_pidfile.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_windows_task_paths.py +0 -0
- {devops_bot_sdk-1.7.20 → devops_bot_sdk-1.7.33}/tests/test_write_hook.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devops-bot-sdk
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.33
|
|
4
4
|
Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
|
|
5
5
|
Author: noumanaziz2128
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -22,6 +22,8 @@ Requires-Dist: fastapi>=0.110; extra == "ui"
|
|
|
22
22
|
Requires-Dist: uvicorn>=0.29; extra == "ui"
|
|
23
23
|
Requires-Dist: psutil>=5.9; extra == "ui"
|
|
24
24
|
Requires-Dist: python-multipart>=0.0.9; extra == "ui"
|
|
25
|
+
Provides-Extra: ui-e2e
|
|
26
|
+
Requires-Dist: playwright>=1.45; extra == "ui-e2e"
|
|
25
27
|
Provides-Extra: all
|
|
26
28
|
Requires-Dist: Pillow>=10.0; extra == "all"
|
|
27
29
|
Requires-Dist: psutil>=5.9; extra == "all"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devops-bot-sdk
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.33
|
|
4
4
|
Summary: DevOps Bot Desktop SDK — thin client for the AgentOS Electron desktop app
|
|
5
5
|
Author: noumanaziz2128
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -22,6 +22,8 @@ Requires-Dist: fastapi>=0.110; extra == "ui"
|
|
|
22
22
|
Requires-Dist: uvicorn>=0.29; extra == "ui"
|
|
23
23
|
Requires-Dist: psutil>=5.9; extra == "ui"
|
|
24
24
|
Requires-Dist: python-multipart>=0.0.9; extra == "ui"
|
|
25
|
+
Provides-Extra: ui-e2e
|
|
26
|
+
Requires-Dist: playwright>=1.45; extra == "ui-e2e"
|
|
25
27
|
Provides-Extra: all
|
|
26
28
|
Requires-Dist: Pillow>=10.0; extra == "all"
|
|
27
29
|
Requires-Dist: psutil>=5.9; extra == "all"
|
|
@@ -50,6 +50,7 @@ sdk/resume.py
|
|
|
50
50
|
sdk/router.py
|
|
51
51
|
sdk/run_auto.py
|
|
52
52
|
sdk/schedule_tickets.py
|
|
53
|
+
sdk/schedule_timeline.py
|
|
53
54
|
sdk/scheduler.py
|
|
54
55
|
sdk/scope_plan.py
|
|
55
56
|
sdk/self_report.py
|
|
@@ -206,6 +207,7 @@ tests/test_formats.py
|
|
|
206
207
|
tests/test_git_action.py
|
|
207
208
|
tests/test_github_fetch.py
|
|
208
209
|
tests/test_github_ingest.py
|
|
210
|
+
tests/test_graph_off_by_default.py
|
|
209
211
|
tests/test_graph_recon.py
|
|
210
212
|
tests/test_graphify_build.py
|
|
211
213
|
tests/test_graphify_hook_install.py
|
|
@@ -231,11 +233,13 @@ tests/test_parallel_tickets.py
|
|
|
231
233
|
tests/test_phase_timer.py
|
|
232
234
|
tests/test_plan_new_command.py
|
|
233
235
|
tests/test_plan_run_activity.py
|
|
236
|
+
tests/test_pool_pr_modes.py
|
|
234
237
|
tests/test_pr_identity.py
|
|
235
238
|
tests/test_prd_artifact.py
|
|
236
239
|
tests/test_project_path_resolution.py
|
|
237
240
|
tests/test_proof_readers.py
|
|
238
241
|
tests/test_providers.py
|
|
242
|
+
tests/test_quiet_run_log.py
|
|
239
243
|
tests/test_recon_session_isolation.py
|
|
240
244
|
tests/test_resume.py
|
|
241
245
|
tests/test_router.py
|
|
@@ -245,6 +249,7 @@ tests/test_run_verdict_is_honest.py
|
|
|
245
249
|
tests/test_schedule_api.py
|
|
246
250
|
tests/test_schedule_outputs_and_plans.py
|
|
247
251
|
tests/test_schedule_tickets.py
|
|
252
|
+
tests/test_schedule_timeline.py
|
|
248
253
|
tests/test_scheduler.py
|
|
249
254
|
tests/test_scheduler_transient_retry.py
|
|
250
255
|
tests/test_self_report.py
|
|
@@ -253,9 +258,11 @@ tests/test_stale_panel_restart.py
|
|
|
253
258
|
tests/test_swagger_command.py
|
|
254
259
|
tests/test_task_file_and_plan_run.py
|
|
255
260
|
tests/test_task_file_format_doc.py
|
|
261
|
+
tests/test_theme_switch.py
|
|
256
262
|
tests/test_ticket_board.py
|
|
257
263
|
tests/test_ticket_bulk.py
|
|
258
264
|
tests/test_ticket_cli.py
|
|
265
|
+
tests/test_ticket_detail_view.py
|
|
259
266
|
tests/test_ticket_fields.py
|
|
260
267
|
tests/test_ticket_plan.py
|
|
261
268
|
tests/test_ticket_pools.py
|
|
@@ -265,6 +272,7 @@ tests/test_ticket_speed_fixes.py
|
|
|
265
272
|
tests/test_tier_flag_parity.py
|
|
266
273
|
tests/test_ui_gate.py
|
|
267
274
|
tests/test_ui_lifespan.py
|
|
275
|
+
tests/test_ui_no_native_dialogs.py
|
|
268
276
|
tests/test_update_timer.py
|
|
269
277
|
tests/test_updater_extras.py
|
|
270
278
|
tests/test_updater_ignores_cwd.py
|
|
@@ -41,6 +41,9 @@ ui = [
|
|
|
41
41
|
# raises at request time without it, so it belongs in [ui]
|
|
42
42
|
# alongside fastapi rather than in an optional extra.
|
|
43
43
|
]
|
|
44
|
+
ui-e2e = [
|
|
45
|
+
"playwright>=1.45", # tests/ui_e2e — headless-Chromium panel tests (then: python -m playwright install chromium)
|
|
46
|
+
]
|
|
44
47
|
all = [
|
|
45
48
|
"Pillow>=10.0",
|
|
46
49
|
"psutil>=5.9",
|
|
@@ -60,6 +63,9 @@ agentos-swagger = "sdk.swagger:main" # where /docs is + can you reach it
|
|
|
60
63
|
Homepage = "https://agentos.io"
|
|
61
64
|
Repository = "https://github.com/consultancy-outfit/DevOpsBot-SDK"
|
|
62
65
|
|
|
66
|
+
[tool.pytest.ini_options]
|
|
67
|
+
markers = ["ui_e2e: headless-Chromium control-panel tests (need the ui-e2e extra; skipped without it)"]
|
|
68
|
+
|
|
63
69
|
[tool.setuptools.dynamic]
|
|
64
70
|
version = { attr = "sdk.__version__" } # bump sdk/__init__.py → wheel + client + server all follow
|
|
65
71
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
|
|
2
2
|
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.33
|
|
4
4
|
|
|
5
5
|
Public surface:
|
|
6
6
|
BackendClient.from_config() — create client from ~/.agentos/config.toml
|
|
@@ -34,7 +34,7 @@ Rules:
|
|
|
34
34
|
- All data egress through submit_webhook only
|
|
35
35
|
"""
|
|
36
36
|
|
|
37
|
-
__version__ = "1.7.
|
|
37
|
+
__version__ = "1.7.33" # SINGLE SOURCE OF TRUTH — bump on every change; pyproject,
|
|
38
38
|
__author__ = "AgentOS" # sdk.client.SDK_VERSION and the UI server version all read this.
|
|
39
39
|
|
|
40
40
|
from sdk.client import BackendClient
|
|
@@ -359,21 +359,41 @@ async def _dispatch_agent_run(
|
|
|
359
359
|
manifest.integrations, available, env=secret_env,
|
|
360
360
|
)
|
|
361
361
|
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
#
|
|
365
|
-
#
|
|
366
|
-
|
|
362
|
+
# {{variables}}, most specific first: explicit run-time values (UI/API/CLI) win
|
|
363
|
+
# over the attached ticket's fields, which win over the values last saved for
|
|
364
|
+
# this agent (sdk/agents/varstore.py — what the panel's Run used). Nothing here
|
|
365
|
+
# is persisted. A person-started run (auto_approve) that would still leave a
|
|
366
|
+
# placeholder unfilled is REFUSED up front: the agent cannot do the work, so it
|
|
367
|
+
# would only spend a run asking for the values (ticket-instructions-writer,
|
|
368
|
+
# 2026-10-27, got literal {{ticket_key}} / {{repos_root}}).
|
|
369
|
+
from sdk.agents import varstore as agent_varstore
|
|
370
|
+
|
|
367
371
|
names = extract_variables(manifest.prompt)
|
|
368
|
-
|
|
369
|
-
|
|
372
|
+
used_inputs: dict[str, str] = {}
|
|
373
|
+
if names:
|
|
374
|
+
saved = {k: v for k, v in agent_varstore.load_vars(manifest.name).items()
|
|
375
|
+
if k in names and str(v).strip()}
|
|
376
|
+
values = dict(saved)
|
|
377
|
+
if task:
|
|
378
|
+
values.update({k: v for k, v in values_from_ticket(names, task).items() if str(v).strip()})
|
|
370
379
|
if extra_variables:
|
|
371
|
-
values
|
|
380
|
+
values.update({k: str(v) for k, v in extra_variables.items() if str(v).strip()})
|
|
372
381
|
resolved_prompt, missing = substitute_variables(manifest.prompt, values)
|
|
373
|
-
if
|
|
382
|
+
used_inputs = {k: v for k, v in values.items() if k in names}
|
|
383
|
+
if missing and auto_approve:
|
|
384
|
+
outcome["status"] = "missing_inputs"
|
|
385
|
+
outcome["missing"] = missing
|
|
386
|
+
outcome["error"] = (
|
|
387
|
+
f"'{manifest.name}' needs {', '.join(missing)} — fill "
|
|
388
|
+
f"{'it' if len(missing) == 1 else 'them'} in, or pick a ticket that has "
|
|
389
|
+
f"{'it' if len(missing) == 1 else 'them'}. Nothing was run."
|
|
390
|
+
)
|
|
391
|
+
logger.info("agentd.missing_inputs agent=%s missing=%s", manifest.name, missing)
|
|
392
|
+
return outcome
|
|
393
|
+
if used_inputs:
|
|
374
394
|
logger.info(
|
|
375
|
-
"agentd.vars_filled agent=%s filled=%s missing=%s",
|
|
376
|
-
manifest.name, sorted(
|
|
395
|
+
"agentd.vars_filled agent=%s filled=%s from_saved=%s missing=%s",
|
|
396
|
+
manifest.name, sorted(used_inputs), sorted(saved), sorted(missing),
|
|
377
397
|
)
|
|
378
398
|
manifest = manifest.model_copy(update={"prompt": resolved_prompt})
|
|
379
399
|
|
|
@@ -455,9 +475,12 @@ async def _dispatch_agent_run(
|
|
|
455
475
|
from sdk.agents.engines import claude_code as claude_code_engine
|
|
456
476
|
from sdk.agents import run_log
|
|
457
477
|
|
|
458
|
-
|
|
478
|
+
# A person pressed Run (auto_approve) → "run"; only an unattended
|
|
479
|
+
# trigger without a ticket is "scheduled".
|
|
480
|
+
_kind = "ticket" if task else ("run" if auto_approve else "scheduled")
|
|
459
481
|
_log_path = run_log.start_run(
|
|
460
482
|
manifest.name, scope="custom", engine=manifest.engine, kind=_kind,
|
|
483
|
+
variables=used_inputs or None,
|
|
461
484
|
)
|
|
462
485
|
run_log.log_line(_log_path, f"task_id={task_id}")
|
|
463
486
|
|
|
@@ -411,6 +411,7 @@ def mark_result(schedule_id: str, *, ok: bool, status: str = "",
|
|
|
411
411
|
if schedule is None:
|
|
412
412
|
return None
|
|
413
413
|
schedule["last_status"] = status or ("ok" if ok else "failed")
|
|
414
|
+
_append_history(schedule, ok=ok, output_file=output_file)
|
|
414
415
|
if output_file:
|
|
415
416
|
schedule["last_output_file"] = output_file
|
|
416
417
|
if delivered_to:
|
|
@@ -431,6 +432,61 @@ def mark_result(schedule_id: str, *, ok: bool, status: str = "",
|
|
|
431
432
|
return schedule
|
|
432
433
|
|
|
433
434
|
|
|
435
|
+
# Every outcome mark_result records, one JSON line each, so the Schedules page can
|
|
436
|
+
# show what ran before the latest run. Not ``*.json``: list_schedules globs those.
|
|
437
|
+
HISTORY_NAME = "history.jsonl"
|
|
438
|
+
HISTORY_MAX_LINES = 5000
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def history_path() -> Path:
|
|
442
|
+
return SCHEDULES_DIR / HISTORY_NAME
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def _append_history(schedule: dict, *, ok: bool, output_file: str = "") -> None:
|
|
446
|
+
"""Best-effort: a history failure never affects the run or the schedule."""
|
|
447
|
+
row = {
|
|
448
|
+
"at": datetime.now(timezone.utc).isoformat(timespec="seconds"),
|
|
449
|
+
"fired_at": schedule.get("last_fire_at") or "",
|
|
450
|
+
"schedule_id": schedule.get("schedule_id") or "",
|
|
451
|
+
"agent": schedule.get("agent") or "",
|
|
452
|
+
"kind": schedule.get("kind") or "agent",
|
|
453
|
+
"ok": bool(ok),
|
|
454
|
+
"status": schedule.get("last_status") or "",
|
|
455
|
+
"output_file": output_file or "",
|
|
456
|
+
}
|
|
457
|
+
try:
|
|
458
|
+
path = history_path()
|
|
459
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
460
|
+
with path.open("a", encoding="utf-8") as fh:
|
|
461
|
+
fh.write(json.dumps(row, ensure_ascii=False) + "\n")
|
|
462
|
+
if path.stat().st_size > HISTORY_MAX_LINES * 400: # trim rarely, keep the newest
|
|
463
|
+
lines = path.read_text(encoding="utf-8").splitlines()[-HISTORY_MAX_LINES:]
|
|
464
|
+
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
465
|
+
except OSError as exc:
|
|
466
|
+
logger.debug("schedules.history_write_failed err=%s", exc)
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def read_history(since: datetime | None = None) -> list[dict]:
|
|
470
|
+
"""Recorded outcomes, oldest first (optionally only those at/after ``since``)."""
|
|
471
|
+
out: list[dict] = []
|
|
472
|
+
try:
|
|
473
|
+
lines = history_path().read_text(encoding="utf-8").splitlines()
|
|
474
|
+
except OSError:
|
|
475
|
+
return out
|
|
476
|
+
for line in lines:
|
|
477
|
+
try:
|
|
478
|
+
row = json.loads(line)
|
|
479
|
+
except ValueError:
|
|
480
|
+
continue
|
|
481
|
+
if not isinstance(row, dict):
|
|
482
|
+
continue
|
|
483
|
+
at = _parse_iso(row.get("fired_at")) or _parse_iso(row.get("at"))
|
|
484
|
+
if at is None or (since is not None and at < since):
|
|
485
|
+
continue
|
|
486
|
+
out.append(row)
|
|
487
|
+
return out
|
|
488
|
+
|
|
489
|
+
|
|
434
490
|
def for_agent(agent: str) -> list[dict]:
|
|
435
491
|
return [s for s in list_schedules() if s.get("agent") == agent]
|
|
436
492
|
|
|
@@ -1264,12 +1264,12 @@ _POOL_USAGE = """usage: agentos pool <command> — up to 50 tickets you run to
|
|
|
1264
1264
|
|
|
1265
1265
|
agentos pool list # every pool, its size and last run
|
|
1266
1266
|
agentos pool show NAME # run order, each ticket's summary/status, instructions
|
|
1267
|
-
agentos pool create NAME KEY… [--instructions TEXT] [--parallel N] # new pool (keys in run order)
|
|
1267
|
+
agentos pool create NAME KEY… [--instructions TEXT] [--parallel N] [--pr-mode per_ticket|stacked|single] # new pool (keys in run order)
|
|
1268
1268
|
agentos pool add NAME KEY… [--at POS] # add tickets (at the end, or at position POS)
|
|
1269
1269
|
agentos pool remove NAME KEY… # take tickets out
|
|
1270
1270
|
agentos pool move NAME KEY POS # move one ticket to position POS (1 = first)
|
|
1271
1271
|
agentos pool order NAME KEY… # these first, in this order; the rest follow
|
|
1272
|
-
agentos pool set NAME [--instructions TEXT | --clear-instructions] [--parallel N] [--rename NEW]
|
|
1272
|
+
agentos pool set NAME [--instructions TEXT | --clear-instructions] [--parallel N] [--pr-mode MODE] [--rename NEW]
|
|
1273
1273
|
agentos pool run NAME [--parallel N] # run it now (= agentos-auto pool NAME)
|
|
1274
1274
|
agentos pool delete NAME # remove the pool (tickets are untouched)
|
|
1275
1275
|
|
|
@@ -1306,8 +1306,11 @@ def _pool_opts(args: list[str], valued: tuple[str, ...], bare: tuple[str, ...] =
|
|
|
1306
1306
|
|
|
1307
1307
|
def _pool_print(pool: dict, info: dict | None = None) -> None:
|
|
1308
1308
|
from sdk import log_colors
|
|
1309
|
+
from sdk.ticket_pools import PR_MODE_LABELS as TP_LABELS
|
|
1309
1310
|
paint = log_colors.colorize if log_colors.enabled() else (lambda x: x)
|
|
1310
|
-
|
|
1311
|
+
mode = pool.get("pr_mode") or "per_ticket"
|
|
1312
|
+
at_once = f"up to {pool.get('parallel')} at once" if mode == "per_ticket" else "one at a time"
|
|
1313
|
+
print(f"pool {pool['name']} — {len(pool['keys'])} ticket(s), {at_once}, {TP_LABELS.get(mode, mode)}"
|
|
1311
1314
|
+ (f", last run {pool['last_run_at']}" if pool.get("last_run_at") else ""))
|
|
1312
1315
|
width = max(len(k) for k in pool["keys"]) if pool["keys"] else 0
|
|
1313
1316
|
for n, k in enumerate(pool["keys"], 1):
|
|
@@ -1358,11 +1361,13 @@ def _pool_command(args: list[str]) -> None:
|
|
|
1358
1361
|
_pool_print(pool, info)
|
|
1359
1362
|
return
|
|
1360
1363
|
if sub == "create":
|
|
1361
|
-
pos, opts = _pool_opts(rest, ("--instructions", "--parallel"))
|
|
1364
|
+
pos, opts = _pool_opts(rest, ("--instructions", "--parallel", "--pr-mode"))
|
|
1362
1365
|
if len(pos) < 2:
|
|
1363
|
-
print("usage: agentos pool create NAME KEY… [--instructions TEXT] [--parallel N]"
|
|
1366
|
+
print("usage: agentos pool create NAME KEY… [--instructions TEXT] [--parallel N] "
|
|
1367
|
+
"[--pr-mode per_ticket|stacked|single]")
|
|
1364
1368
|
sys.exit(1)
|
|
1365
|
-
pool = TP.create(pos[0], pos[1:], opts.get("--instructions", ""), _parallel(opts)
|
|
1369
|
+
pool = TP.create(pos[0], pos[1:], opts.get("--instructions", ""), _parallel(opts),
|
|
1370
|
+
opts.get("--pr-mode"))
|
|
1366
1371
|
shown = f'"{pool["name"]}"' if " " in pool["name"] else pool["name"]
|
|
1367
1372
|
print(f"✓ created pool {pool['name']} with {len(pool['keys'])} ticket(s) — "
|
|
1368
1373
|
f"run it: agentos pool run {shown}")
|
|
@@ -1389,15 +1394,15 @@ def _pool_command(args: list[str]) -> None:
|
|
|
1389
1394
|
sys.exit(1)
|
|
1390
1395
|
pool = TP.order(rest[0], rest[1:])
|
|
1391
1396
|
elif sub == "set":
|
|
1392
|
-
pos, opts = _pool_opts(rest, ("--instructions", "--parallel", "--rename"),
|
|
1397
|
+
pos, opts = _pool_opts(rest, ("--instructions", "--parallel", "--rename", "--pr-mode"),
|
|
1393
1398
|
("--clear-instructions",))
|
|
1394
1399
|
if len(pos) != 1 or not opts:
|
|
1395
1400
|
print("usage: agentos pool set NAME [--instructions TEXT | --clear-instructions] "
|
|
1396
|
-
"[--parallel N] [--rename NEW]")
|
|
1401
|
+
"[--parallel N] [--pr-mode per_ticket|stacked|single] [--rename NEW]")
|
|
1397
1402
|
sys.exit(1)
|
|
1398
1403
|
instr = "" if opts.get("--clear-instructions") else opts.get("--instructions")
|
|
1399
1404
|
pool = TP.update(pos[0], instructions=instr, parallel=_parallel(opts),
|
|
1400
|
-
rename=opts.get("--rename"))
|
|
1405
|
+
rename=opts.get("--rename"), pr_mode=opts.get("--pr-mode"))
|
|
1401
1406
|
elif sub == "delete":
|
|
1402
1407
|
if not rest:
|
|
1403
1408
|
print("usage: agentos pool delete NAME")
|
|
@@ -407,6 +407,9 @@ FLAG_TIERED_ROUTING = "AGENTOS_TIERED_ROUTING"
|
|
|
407
407
|
FLAG_JOURNAL = "AGENTOS_JOURNAL"
|
|
408
408
|
#: Write the generated PRD to ``docs/prd/<KEY>.md`` in the repo.
|
|
409
409
|
FLAG_PRD_FILE = "AGENTOS_PRD_FILE"
|
|
410
|
+
#: The knowledge graph (graphify + graph recon). OFF by default since 1.7.27;
|
|
411
|
+
#: ``AGENTOS_GRAPHIFY=1`` (env or config.toml) turns it back on.
|
|
412
|
+
FLAG_GRAPHIFY = "AGENTOS_GRAPHIFY"
|
|
410
413
|
#: Supervise ``graphify watch`` instead of relying on the debounce.
|
|
411
414
|
FLAG_GRAPH_WATCH = "AGENTOS_GRAPHIFY_WATCH"
|
|
412
415
|
#: Cheap-tier mini agent (sdk/tiers/). Requires backend reachability.
|
|
@@ -80,9 +80,9 @@ _TICKET_BRANCH_RE = re.compile(r"^[A-Za-z][A-Za-z0-9]{1,9}-\d+$")
|
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
def _is_work_branch(name: str) -> bool:
|
|
83
|
-
"""True when `name` is one of OUR generated work branches (feature
|
|
84
|
-
bare ticket id) — i.e. never a legitimate base."""
|
|
85
|
-
return name.startswith("feature/") or bool(_TICKET_BRANCH_RE.match(name))
|
|
83
|
+
"""True when `name` is one of OUR generated work branches (feature/*, a pool's
|
|
84
|
+
pool/* or a bare ticket id) — i.e. never a legitimate base."""
|
|
85
|
+
return name.startswith(("feature/", "pool/")) or bool(_TICKET_BRANCH_RE.match(name))
|
|
86
86
|
|
|
87
87
|
|
|
88
88
|
async def detect_default_branch(path: str, env: dict) -> str:
|
|
@@ -163,9 +163,16 @@ async def start_branch(
|
|
|
163
163
|
github_token: str | None,
|
|
164
164
|
base: str | None = None,
|
|
165
165
|
branch_name: str | None = None,
|
|
166
|
+
continue_branch: bool = False,
|
|
166
167
|
) -> dict | None:
|
|
167
168
|
"""Create + check out a feature branch off the resolved base.
|
|
168
169
|
|
|
170
|
+
``continue_branch`` (a one-PR ticket pool, after its first ticket): check out
|
|
171
|
+
the EXISTING ``branch_name`` as it stands — local, else ``origin/`` — and bring
|
|
172
|
+
it up to date, instead of re-cutting it from ``base``; ``base`` is returned
|
|
173
|
+
unchanged so the PR keeps its target. Re-cutting would throw away the earlier
|
|
174
|
+
tickets' commits.
|
|
175
|
+
|
|
169
176
|
Branch name:
|
|
170
177
|
- `branch_name` given (an explicit name parsed from the Jira
|
|
171
178
|
humanInstructions or a configured template, e.g. the exact ticket id
|
|
@@ -196,6 +203,17 @@ async def start_branch(
|
|
|
196
203
|
return None
|
|
197
204
|
|
|
198
205
|
explicit_name = (branch_name or "").strip().lstrip("/")
|
|
206
|
+
if continue_branch and explicit_name:
|
|
207
|
+
await _run(["git", "fetch", "origin"], path, env, timeout=180.0)
|
|
208
|
+
rc, _, _ = await _run(["git", "checkout", explicit_name], path, env)
|
|
209
|
+
if rc != 0:
|
|
210
|
+
rc, _, _ = await _run(["git", "checkout", "-B", explicit_name, f"origin/{explicit_name}"], path, env)
|
|
211
|
+
if rc == 0:
|
|
212
|
+
await _run(["git", "pull", "--ff-only", "origin", explicit_name], path, env, timeout=120.0)
|
|
213
|
+
pr_base = (base or "").strip() or await detect_default_branch(path, env)
|
|
214
|
+
logger.info("git_ops.branch | %s continued (pool), PR base %s", explicit_name, pr_base)
|
|
215
|
+
return {"branch": explicit_name, "base": pr_base}
|
|
216
|
+
# Not there yet (the pool's first ticket): cut it like any named branch.
|
|
199
217
|
if explicit_name:
|
|
200
218
|
# Honour the exact name the human/convention asked for (e.g. "CD-72").
|
|
201
219
|
branch = explicit_name
|
|
@@ -212,15 +230,20 @@ async def start_branch(
|
|
|
212
230
|
# local ref of that name, then to a bare branch, if the remote lacks it.
|
|
213
231
|
await _run(["git", "fetch", "origin", explicit], path, env, timeout=120.0)
|
|
214
232
|
resolved = "main" if explicit == branch else explicit
|
|
215
|
-
|
|
216
|
-
if
|
|
217
|
-
|
|
218
|
-
|
|
233
|
+
refs = [r for r in (f"origin/{resolved}", resolved) if await _ref_exists(path, env, r)]
|
|
234
|
+
if not refs:
|
|
235
|
+
# The base does not exist anywhere (a typo, or a brand-new repo): cut
|
|
236
|
+
# from HEAD, and say which branch that really is.
|
|
219
237
|
rc, _, _ = await _run(["git", "checkout", "-B", branch], path, env)
|
|
220
|
-
|
|
238
|
+
if rc != 0:
|
|
239
|
+
return None
|
|
240
|
+
logger.warning("git_ops.branch | base %s not found — %s cut from the current checkout", resolved, branch)
|
|
241
|
+
return {"branch": branch, "base": resolved, "note": f"base {resolved} not found — cut from the current checkout"}
|
|
242
|
+
info = await _checkout_from(path, env, branch, refs)
|
|
243
|
+
if info is None:
|
|
221
244
|
return None
|
|
222
245
|
logger.info("git_ops.branch | %s ← explicit base %s", branch, resolved)
|
|
223
|
-
return {"branch": branch, "base": resolved}
|
|
246
|
+
return {"branch": branch, "base": resolved, **info}
|
|
224
247
|
|
|
225
248
|
# Default: base = the CURRENT checked-out branch (the user's working branch).
|
|
226
249
|
rc, cur, _ = await _run(["git", "rev-parse", "--abbrev-ref", "HEAD"], path, env)
|
|
@@ -238,13 +261,49 @@ async def start_branch(
|
|
|
238
261
|
resolved = await detect_default_branch(path, env)
|
|
239
262
|
if resolved == branch:
|
|
240
263
|
resolved = "main"
|
|
241
|
-
|
|
242
|
-
if
|
|
243
|
-
|
|
244
|
-
|
|
264
|
+
refs = [r for r in (f"origin/{resolved}", resolved) if await _ref_exists(path, env, r)]
|
|
265
|
+
info = await _checkout_from(path, env, branch, refs) if refs else None
|
|
266
|
+
if info is None:
|
|
267
|
+
# Never fall back to the stale work branch that is checked out: that is
|
|
268
|
+
# how one ticket's half-finished changes end up in the next one's PR.
|
|
269
|
+
logger.warning("git_ops.branch | %s: could not cut from %s (HEAD was %r)", branch, resolved, cur or "detached")
|
|
245
270
|
return None
|
|
246
271
|
logger.info("git_ops.branch | %s ← default base %s (HEAD was %r)", branch, resolved, cur or "detached")
|
|
247
|
-
return {"branch": branch, "base": resolved}
|
|
272
|
+
return {"branch": branch, "base": resolved, **info}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
async def _ref_exists(path: str, env: dict, ref: str) -> bool:
|
|
276
|
+
rc, _, _ = await _run(["git", "rev-parse", "--verify", "--quiet", ref + "^{commit}"], path, env)
|
|
277
|
+
return rc == 0
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
async def _checkout_from(path: str, env: dict, branch: str, refs: list[str]) -> dict | None:
|
|
281
|
+
"""Check ``branch`` out fresh from the first of ``refs`` that works → {} or
|
|
282
|
+
{"stashed": msg}; None when none does.
|
|
283
|
+
|
|
284
|
+
The usual reason a checkout fails is uncommitted changes in the way —
|
|
285
|
+
typically a previous ticket's half-finished work. Those are STASHED (kept, with
|
|
286
|
+
a message naming this branch; ``git stash list`` shows them) and the checkout
|
|
287
|
+
retried, instead of quietly cutting the branch from whatever is checked out —
|
|
288
|
+
which would carry those changes, and a stale codebase, into this ticket's PR.
|
|
289
|
+
"""
|
|
290
|
+
for ref in refs:
|
|
291
|
+
rc, _, _ = await _run(["git", "checkout", "-B", branch, ref], path, env)
|
|
292
|
+
if rc == 0:
|
|
293
|
+
return {}
|
|
294
|
+
if not await has_local_changes(path):
|
|
295
|
+
return None
|
|
296
|
+
msg = f"agentos: uncommitted changes set aside before {branch}"
|
|
297
|
+
rc, _, err = await _run(["git", "stash", "push", "--include-untracked", "-m", msg], path, env)
|
|
298
|
+
if rc != 0:
|
|
299
|
+
logger.warning("git_ops.stash_failed %s: %s", branch, err[:200])
|
|
300
|
+
return None
|
|
301
|
+
logger.warning("git_ops.branch | stashed uncommitted changes before %s", branch)
|
|
302
|
+
for ref in refs:
|
|
303
|
+
rc, _, _ = await _run(["git", "checkout", "-B", branch, ref], path, env)
|
|
304
|
+
if rc == 0:
|
|
305
|
+
return {"stashed": msg}
|
|
306
|
+
return None
|
|
248
307
|
|
|
249
308
|
|
|
250
309
|
async def _remote_owner_repo(path: str, env: dict) -> tuple[str, str] | None:
|
|
@@ -75,7 +75,10 @@ _CAMEL_RE = re.compile(r"[A-Z]+(?![a-z])|[A-Z][a-z0-9]*|[a-z0-9]+")
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
def _disabled() -> bool:
|
|
78
|
-
|
|
78
|
+
if os.getenv("AGENTOS_NO_GRAPH_RECON"):
|
|
79
|
+
return True
|
|
80
|
+
from sdk import graphify # no graph (off by default) → no graph recon
|
|
81
|
+
return not graphify.enabled()
|
|
79
82
|
|
|
80
83
|
|
|
81
84
|
def _split_identifier(word: str) -> list[str]:
|
|
@@ -6,8 +6,11 @@ hook**, so the agent queries the graph instead of loading whole files — keepin
|
|
|
6
6
|
large projects inside the context window.
|
|
7
7
|
|
|
8
8
|
Everything here is best-effort and never raises: if graphify is unavailable or a
|
|
9
|
-
step fails, the run continues on plain `claude`.
|
|
10
|
-
|
|
9
|
+
step fails, the run continues on plain `claude`.
|
|
10
|
+
|
|
11
|
+
OFF by default (1.7.27): nothing is installed, built or queried unless
|
|
12
|
+
``AGENTOS_GRAPHIFY=1`` is set (environment or ``config.toml``). The code stays so
|
|
13
|
+
it can be switched back on; ``AGENTOS_NO_GRAPHIFY=1`` still forces it off.
|
|
11
14
|
|
|
12
15
|
Per-project flow (called once before each local `claude` run):
|
|
13
16
|
ensure_installed() → auto-install `graphifyy` via uv → pipx → pip if missing
|
|
@@ -45,8 +48,19 @@ _SKILL_MARKER = _AGENTOS_DIR / ".graphify_skill_installed"
|
|
|
45
48
|
_STATE_FILE = _AGENTOS_DIR / "graphify_state.json"
|
|
46
49
|
|
|
47
50
|
|
|
51
|
+
def enabled() -> bool:
|
|
52
|
+
"""True only when switched on (``AGENTOS_GRAPHIFY=1``) and not forced off."""
|
|
53
|
+
if os.getenv("AGENTOS_NO_GRAPHIFY"):
|
|
54
|
+
return False
|
|
55
|
+
try:
|
|
56
|
+
from sdk import config
|
|
57
|
+
return config.flag(config.FLAG_GRAPHIFY)
|
|
58
|
+
except Exception: # noqa: BLE001 — a config hiccup leaves it off
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
|
|
48
62
|
def _disabled() -> bool:
|
|
49
|
-
return
|
|
63
|
+
return not enabled()
|
|
50
64
|
|
|
51
65
|
|
|
52
66
|
def is_available() -> bool:
|
|
@@ -170,7 +170,12 @@ never overwritten (this VPS: after-night-scans.conf, 03:30 UTC). Opt out `AGENTO
|
|
|
170
170
|
development|content|research|design|general`); only development mentions git. Generate
|
|
171
171
|
with AI: `agentos ticket gen-instructions KEY… [--kind K]`, or the ✨ button under any
|
|
172
172
|
instructions box on the panel.
|
|
173
|
-
-
|
|
173
|
+
- Run log (agentos-auto logs, panel Run & Logs): while the agent works it shows each file it edits (✎) and one progress line a minute (⋯ working 3m · 24 steps …), not every tool call — every step stays in the ticket's claude log, and AGENTOS_VERBOSE_STEPS=1 brings per-step lines back. A ticket quiet for 2+ minutes (e.g. a long test run) gets "… still working on KEY — quiet for Nm". Colours: ticket start bold cyan, edits cyan, branch blue, PR link bold green, model/RAM/internal lines dim.
|
|
174
|
+
- Running an agent with {{inputs}} (panel Run / Run on a ticket, `agentos agent run`): each input comes from the form, else the picked ticket, else the value saved from the agent's last run. If one is still missing, the run is refused before it starts — "Not run — fill in ticket_key, repos_root" — instead of spending a run that only asks for them. Run logs say "Kind: run" for a run a person started and list its inputs; "scheduled" is only an unattended trigger.
|
|
175
|
+
- Knowledge graph (graphify + graph recon) is OFF by default since 1.7.27: tickets use the AI recon pass, prompts don't mention graphify, and the Runs page hides its Knowledge graph box. Turn it back on with `AGENTOS_GRAPHIFY=1` (environment, `.env`, or `graphify = true` in ~/.agentos/config.toml); `AGENTOS_NO_GRAPHIFY=1` still forces it off.
|
|
176
|
+
- A ticket's branch always starts from its real base: if a previous run's uncommitted changes are in the way they are stashed (`agentos: uncommitted changes set aside before <branch>` — `git stash list`, `git stash pop` to restore) and the run log says so; if the base still cannot be checked out, no branch is cut.
|
|
177
|
+
- Pool PRs (`--pr-mode`, panel: pool editor → Pull requests): **per_ticket** (default) = each ticket its own branch + PR; **stacked** = each ticket branches from the previous ticket's branch in the same repo and its PR targets that branch (ticket N builds on N-1; merge them in order); **single** = every ticket commits to `pool/<name>` and the pool gets ONE PR into the usual base. stacked and single run the tickets one at a time in pool order; a ticket that changed nothing leaves the stack where it was.
|
|
178
|
+
- Panel: Tickets page has tabs **Tickets · Board · Pools**. Move tickets Jira-style: tick them and press **Move to ▾**, change **Status** in the side panel, or drag a card between columns on the **Board** (each card also has a ⋯ move menu). Lists are paged (12 per page; ticks survive paging). Schedules page has tabs **Timeline · Schedules · New schedule · Run history** — Timeline shows what already ran (result + ticket, Output opens the run) and what runs next, for 12 h / 24 h / 3 days / 7 days. Help: Enter asks, Shift+Enter = new line. Tickets list: each row shows the description preview, type, priority, points and assignee; **click a row** to open the whole ticket in a side panel (properties, full description, Human Instructions, Run / Edit / Copy / Delete; ↑↓ or j/k move between tickets, Esc closes). Also Ticket pools, **Add to pool**, **Bulk update…** (shows current values), **Bulk create from plan**. FAQs page in the sidebar (sdk/faqs.py). Light / System / Dark switch at the bottom of the sidebar (remembered per browser; System follows the computer).
|
|
174
179
|
|
|
175
180
|
## Known issues and their fixes
|
|
176
181
|
|
|
@@ -276,6 +281,12 @@ admin** = a zip of the case's diagnostics, errors and logs (no SDK source). API:
|
|
|
276
281
|
`GET /api/ui/help/case/{name}/bundle` (`sdk/ui/api.py`). It runs on the machine the
|
|
277
282
|
panel runs on, so it reads that machine's logs.
|
|
278
283
|
|
|
284
|
+
Panel dialogs: the panel never uses the browser's `confirm()` / `prompt()` any more.
|
|
285
|
+
Delete / replace / run / bulk-update / **Generate with AI** / **Insert template** ask in
|
|
286
|
+
an in-page dialog — **Esc** or **Cancel** closes it and nothing is sent; Tab stays inside
|
|
287
|
+
it. "I pressed Esc and nothing happened" is therefore the dialog being cancelled, not a
|
|
288
|
+
bug. The Tickets **Add N to pool ▾** menu is keyboard-operable (↑ ↓, Enter, Esc).
|
|
289
|
+
|
|
279
290
|
## Useful commands (all verified to exist)
|
|
280
291
|
|
|
281
292
|
```
|