devops-bot-sdk 1.6.32__tar.gz → 1.6.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.6.32 → devops_bot_sdk-1.6.33}/PKG-INFO +1 -1
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/PKG-INFO +1 -1
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/__init__.py +2 -2
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/self_report.py +33 -14
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_self_report.py +23 -1
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/README.md +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/SOURCES.txt +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/dependency_links.txt +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/entry_points.txt +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/requires.txt +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/top_level.txt +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/pyproject.toml +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agentd.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/activity.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/builder.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/chat.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/connectors.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/claude_code.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/http.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/mcp.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/n8n.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/engines/shell.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/integrations.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/inventory.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/library/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/manifest.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/prompt_studio.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/prompt_template.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/prompt_vars.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/run_log.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/schedules.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/secrets.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/ticket_run.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/usage.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/agents/varstore.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/browser_profile.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/cli.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/client.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/collectors/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/collectors/files.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/collectors/process.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/collectors/screenshot.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/config.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/crucial.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/departments.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/assets.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/bootstrap.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/browser.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/compare.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/design_verify/loop.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/exceptions.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/formats.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/git_ops.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/github_ingest.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/graph_recon.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/graphify.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/hooks/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/hooks/crucial_guard.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/intake.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ipc/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ipc/electron_bridge.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ipc/handlers.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/local_exec.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/models/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/models/envelope.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/models/requests.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/models/responses.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/models/snapshots.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/phase_timer.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/plan_run.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/platform_compat.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/proof_readers.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/py.typed +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/run_auto.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/scheduler.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/self_report_local.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/sse.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/task_file.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/test.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/test_pipeline.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ticket_fields.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/__init__.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/api.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/dashboard.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/health.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/ip_allowlist.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/jobs.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/models.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/runner.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/security.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/server.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/service.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/session.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/setup_manager.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/agents.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/app.js +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/chat.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/custom-agents.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/default-agents.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/index.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/login.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/report.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/runs.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/schedules.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/setup.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/styles.css +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/ui/static/tickets.html +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/updater.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/url_access.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/sdk/vps_health.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/setup.cfg +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_activity.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_activity_tracking.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_chat_features.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_listing.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_prompt_async.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_prompt_models.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_run_ticket.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_schedules.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agent_workspace_settings.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_agents_connectors_builder.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_allowed_tools_config.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_auto_agent_dispatch.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_browser_profile.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_client_jira_projects.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_config_token_diagnostics.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_configure_token_owner.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_console_encoding.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_departments.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_epic_decompose_run.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_epic_inherited_agent_id.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_epic_session_isolation.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_formats.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_git_action.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_github_ingest.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_graph_recon.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_graphify_build.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_graphify_hook_install.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_health.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_intake_plan_review.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_otp_login.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_phase_timer.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_plan_new_command.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_plan_run_activity.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_proof_readers.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_recon_session_isolation.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_run_auto_agent_only.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_run_outputs.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_schedule_api.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_scheduler.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_service_token_warning.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_task_file_and_plan_run.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_task_file_format_doc.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_ticket_fields.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_ticket_run_resolve_by_id.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_ticket_speed_fixes.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_update_timer.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_updater_extras.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_url_access.py +0 -0
- {devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/tests/test_vps_health.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""AgentOS Desktop SDK — thin HTTPS/SSE client for the Electron app.
|
|
2
2
|
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.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.6.
|
|
37
|
+
__version__ = "1.6.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
|
|
@@ -467,9 +467,17 @@ async def submit_and_evaluate(
|
|
|
467
467
|
# PR, an Outlook thread or an internal dashboard comes back 404 and is
|
|
468
468
|
# scored `unverifiable` — the work punished for where its evidence lives.
|
|
469
469
|
# This machine is the one with the credentials, so it reads the page and
|
|
470
|
-
#
|
|
471
|
-
#
|
|
472
|
-
|
|
470
|
+
# sends what it read INSTEAD of the link.
|
|
471
|
+
#
|
|
472
|
+
# Instead, not as well as. Sending both means the backend still fetches
|
|
473
|
+
# the URL, still 404s on it, and the submission carries two contradictory
|
|
474
|
+
# judgements of one piece of evidence: the link "unverifiable" beside the
|
|
475
|
+
# text of that same link "supports". That is not merely noisy — the
|
|
476
|
+
# evaluator reads the phantom failure as missing evidence and marks the
|
|
477
|
+
# criterion PARTIAL for it, so a link that WAS read costs score for not
|
|
478
|
+
# having been read. A URL that could not be resolved here still travels,
|
|
479
|
+
# because the backend may reach something this machine cannot.
|
|
480
|
+
extra, notes, urls = await _resolve_link_proofs(client, urls)
|
|
473
481
|
files.extend(extra)
|
|
474
482
|
for note in notes:
|
|
475
483
|
mirror(note)
|
|
@@ -671,15 +679,21 @@ def _link_slug(url: str) -> str:
|
|
|
671
679
|
|
|
672
680
|
async def _resolve_link_proofs(
|
|
673
681
|
client: Any, urls: list[str],
|
|
674
|
-
) -> tuple[list[tuple[str, bytes, str]], list[str]]:
|
|
675
|
-
"""Read each URL proof with this machine's credentials.
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
682
|
+
) -> tuple[list[tuple[str, bytes, str]], list[str], list[str]]:
|
|
683
|
+
"""Read each URL proof with this machine's credentials.
|
|
684
|
+
|
|
685
|
+
Returns ``(files, notes, unresolved)`` — the pages that were read, anything
|
|
686
|
+
worth telling the operator, and the URLs to still send AS urls because
|
|
687
|
+
nothing here could open them.
|
|
688
|
+
|
|
689
|
+
Each link that opens becomes a ``text/plain`` file proof carrying the page and
|
|
690
|
+
a header naming the source and the route that read it, and is then dropped
|
|
691
|
+
from the URL list. That shape is deliberate: the backend already stores file
|
|
692
|
+
proofs and already extracts them, so evidence the SDK gathered flows through
|
|
693
|
+
exactly the pipeline evidence the person uploaded does — no new route, no new
|
|
694
|
+
contract, and it keeps working against a backend that has never heard of this
|
|
695
|
+
module. The link itself is not lost: it is the ``Source:`` line of the file
|
|
696
|
+
and the file's own name.
|
|
683
697
|
|
|
684
698
|
Sequential, not gathered. The browser route drives ONE ``agent-browser``
|
|
685
699
|
daemon through a stateful open-then-snapshot pair; two concurrent resolutions
|
|
@@ -690,7 +704,7 @@ async def _resolve_link_proofs(
|
|
|
690
704
|
the behaviour that existed before this, so the worst case is the old one.
|
|
691
705
|
"""
|
|
692
706
|
if not urls or not resolve_links_enabled():
|
|
693
|
-
return [], []
|
|
707
|
+
return [], [], list(urls)
|
|
694
708
|
|
|
695
709
|
from sdk import url_access
|
|
696
710
|
|
|
@@ -707,6 +721,7 @@ async def _resolve_link_proofs(
|
|
|
707
721
|
|
|
708
722
|
files: list[tuple[str, bytes, str]] = []
|
|
709
723
|
notes: list[str] = []
|
|
724
|
+
unresolved: list[str] = []
|
|
710
725
|
loop = asyncio.get_running_loop()
|
|
711
726
|
deadline = loop.time() + _RESOLVE_BUDGET_S
|
|
712
727
|
for index, url in enumerate(urls, start=1):
|
|
@@ -715,6 +730,7 @@ async def _resolve_link_proofs(
|
|
|
715
730
|
notes.append(f"Proof link {url} was left for the backend to fetch — the "
|
|
716
731
|
f"{int(_RESOLVE_BUDGET_S)}s budget for reading links locally "
|
|
717
732
|
f"was already spent.")
|
|
733
|
+
unresolved.append(url)
|
|
718
734
|
continue
|
|
719
735
|
try:
|
|
720
736
|
res = await asyncio.wait_for(
|
|
@@ -723,15 +739,18 @@ async def _resolve_link_proofs(
|
|
|
723
739
|
except asyncio.TimeoutError:
|
|
724
740
|
logger.info("self_report.resolve_timeout url=%s", url)
|
|
725
741
|
notes.append(f"Proof link {url} timed out being read locally.")
|
|
742
|
+
unresolved.append(url)
|
|
726
743
|
continue
|
|
727
744
|
except Exception as exc: # noqa: BLE001 — resolve_url is not supposed to
|
|
728
745
|
logger.warning("self_report.resolve_failed url=%s err=%s", url, exc)
|
|
729
746
|
notes.append(f"Proof link could not be read locally ({url}) — {exc}")
|
|
747
|
+
unresolved.append(url)
|
|
730
748
|
continue
|
|
731
749
|
if not res.ok:
|
|
732
750
|
logger.info("self_report.link_unresolved url=%s tried=%s reason=%s",
|
|
733
751
|
url, ",".join(res.attempts), res.reason)
|
|
734
752
|
notes.append(f"Proof link {url} {res.reason}")
|
|
753
|
+
unresolved.append(url)
|
|
735
754
|
continue
|
|
736
755
|
body = res.text[:_RESOLVED_MAX_CHARS]
|
|
737
756
|
truncated = "\n\n[truncated — the page was longer than this excerpt]" \
|
|
@@ -746,7 +765,7 @@ async def _resolve_link_proofs(
|
|
|
746
765
|
files.append((f"link-{index}-{_link_slug(url)}.txt", content, "text/plain"))
|
|
747
766
|
logger.info("self_report.link_resolved url=%s via=%s chars=%d",
|
|
748
767
|
url, res.via, len(body))
|
|
749
|
-
return files, notes
|
|
768
|
+
return files, notes, unresolved
|
|
750
769
|
|
|
751
770
|
|
|
752
771
|
def _proof_record(p: Proof) -> dict[str, Any]:
|
|
@@ -1109,7 +1109,6 @@ class TestLinkProofsAreResolvedLocally:
|
|
|
1109
1109
|
backend, _ = self._submit()
|
|
1110
1110
|
|
|
1111
1111
|
sent = backend.submits[0]
|
|
1112
|
-
assert sent["proof_urls"] == [self.URL], "the link a human would click was dropped"
|
|
1113
1112
|
assert len(sent["files"]) == 1, "the page the SDK read was not attached"
|
|
1114
1113
|
name, body, ctype = sent["files"][0]
|
|
1115
1114
|
text = body.decode()
|
|
@@ -1120,6 +1119,29 @@ class TestLinkProofsAreResolvedLocally:
|
|
|
1120
1119
|
assert f"Source: {self.URL}" in text
|
|
1121
1120
|
assert "via: github-api" in text
|
|
1122
1121
|
|
|
1122
|
+
def test_a_resolved_link_is_NOT_also_sent_as_a_url(self, monkeypatch):
|
|
1123
|
+
"""The regression: sending both made one link two contradictory proofs.
|
|
1124
|
+
|
|
1125
|
+
The backend fetches proof URLs server-side and anonymously. Left in the
|
|
1126
|
+
list, a link that WAS read here is fetched there, 404s, and lands beside
|
|
1127
|
+
its own successfully-read text as `unverifiable` — and the evaluator
|
|
1128
|
+
marks the criterion PARTIAL for the missing evidence, so a link that was
|
|
1129
|
+
read costs score for not having been read.
|
|
1130
|
+
"""
|
|
1131
|
+
from sdk.url_access import Resolved
|
|
1132
|
+
|
|
1133
|
+
self._resolver(monkeypatch, Resolved(text="pull #118 … merged", via="github-api"))
|
|
1134
|
+
backend, _ = self._submit()
|
|
1135
|
+
|
|
1136
|
+
sent = backend.submits[0]
|
|
1137
|
+
assert sent["proof_urls"] == [], (
|
|
1138
|
+
"the resolved link was also sent as a URL — the backend will 404 on it "
|
|
1139
|
+
"and contradict the evidence the SDK just read")
|
|
1140
|
+
# …and the link is still recoverable, from the name and from the file.
|
|
1141
|
+
name, body, _ = sent["files"][0]
|
|
1142
|
+
assert self.URL.rsplit("/", 1)[-1] in name # …/pull/115 -> "…-115.txt"
|
|
1143
|
+
assert self.URL in body.decode()
|
|
1144
|
+
|
|
1123
1145
|
def test_a_link_that_stays_shut_changes_nothing(self, monkeypatch):
|
|
1124
1146
|
"""The old behaviour is the floor: the backend still gets the URL."""
|
|
1125
1147
|
from sdk.url_access import Resolved
|
|
File without changes
|
|
File without changes
|
{devops_bot_sdk-1.6.32 → devops_bot_sdk-1.6.33}/devops_bot_sdk.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|