发布

  • [OPIK-6497] [SDK][FE] feat(runner): notify backend on close for instant disconnect (#6708)

    frostbyte_neo 发布于 2026-05-15 14:40:00 +00:00

    • [NA] [SDK] refactor: group opik connect/endpoint into cli/local_runner with Rich error UX

    • Move connect.py, endpoint.py, _run.py, pairing.py, error_view.py under
      cli/local_runner/ so the pairing flow is one cohesive subpackage.

    • Banner now shows Workspace alongside Opik URL and Project, with values
      rendered bold so they read before the pairing link.

    • Replace the inline error string with a Rich-rendered labelled block
      (Reason / Workspace / URL / Config / Fix / Docs / Run) via a new
      RichClickError + build_config_error_block factory. Plain text stays on
      .message for Sentry/tests; Rich output is used in .show().

    • Detect "no config file at ~/.opik.config" and surface a clear
      "run opik configure" call-to-action on every failure path.

    • Drop default values on internal kwargs that production callers always
      supply (workspace, base_url, config_file_exists, create_if_missing, etc.)
      so signatures reflect actual usage; add test helpers to keep call sites
      readable.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • [NA] [SDK][FE] feat: auto-configure on connect/endpoint + pairing context UX

    • opik connect/endpoint auto-launch opik configure when no config file
      exists. Skipped on --non-interactive, --headless, no TTY, or when an
      API key is already supplied via --api-key / OPIK_API_KEY.

    • Extract preflight helpers (should_create_project, maybe_auto_configure)
      into cli/local_runner/preflight.py so tests can target a public surface.

    • Pair URL now carries &url=<ui-url> with the /api suffix stripped, so
      the pairing page can show the user-facing instance address.

    • Pairing error screens render a labelled context card under the subtitle:
      "Workspace: X / Pairing with Opik at: " — URL is a clickable link
      that opens the Opik UI in a new tab.

    • scripts/dev-runner.{sh,ps1} export TOGGLE_FORCE_WORKSPACE_VERSION=version_2
      by default so a fresh local backend doesn't trip the "Workspace upgrade
      required" pairing screen. Override via TOGGLE_FORCE_WORKSPACE_VERSION=disabled.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • [NA] [FE] feat(pairing): reword settings card and reorder Opik URL/Workspace

    • Add caption "The CLI tried to pair using these Opik settings:" above
      the card so the framing is unambiguous — these are the values the CLI
      used, not the user's current session.

    • Rename "Pairing with Opik at" → "Opik URL" so the labels match the CLI
      banner (Opik URL / Workspace) verbatim.

    • Reorder rows: URL first, then Workspace — same order as the banner.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • [NA] [SDK][FE] feat(pairing): include project name in pair link and context card

    • CLI build_pairing_link now accepts project_name and appends a URL-encoded
      &project=<name> query param. run_pairing forwards it through.

    • PairingPage reads project from the query; PairingStatusScreen renders
      a new Project row under Workspace in the error context card.

    • Project names with spaces / / round-trip safely via percent-encoding;
      added a regression test covering the encoding shape.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • fix lint

    • fix(pairing): scheme allow-list on Opik URL link + URL-encode workspace

    Addresses PR #6691 review feedback:

    • PairingStatusScreen: validate expectedBaseUrl with URL() and only
      render it as a clickable <a> when the scheme is http/https; otherwise
      render as plain text. Prevents a crafted pair URL like
      ?url=javascript:alert(1) from producing a clickable script link.
    • PairingPage: thread expected workspace/project/baseUrl through the
      invalid_link branch as well, so the CLI context card surfaces even
      when the link fragment is malformed.
    • PairingStatusScreen: loosen showWorkspaceContext to fire when any of
      workspace/project/url is present; gate the Workspace row individually.
    • pairing.py: URL-encode the workspace query param the same way as
      url and project, so workspace names containing &/= don't split
      the query and confuse the FE's URLSearchParams parsing. Added a
      regression test covering the encoding.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • fix(tui): use solid bullet for banner mark

    The combining-enclosing-circle glyph (⠀⃝) failed to render on
    terminals that lack the combining mark, falling back to two red
    placeholder boxes before "opik". Switch to U+25CF (●), which renders
    consistently as a solid colored dot.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • refactor(preflight): skip redundant project lookup when preflight already 404'd

    should_create_project now returns (create_if_missing, known_missing) so
    the interactive path — which already observed the 404 before prompting —
    can tell resolve_project_id to skip the duplicate lookup and go straight
    to _create_project. Headless still leaves known_missing=False so the
    resolver can find an already-existing project across re-runs.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • [OPIK-6497] [SDK][FE] feat(runner): notify backend on close for instant disconnect

    • Supervisor calls disconnect_runner on shutdown (Ctrl+C, SIGTERM, 410
      eviction, clean exit) so the FE flips the runner card off before the
      heartbeat TTL expires. Best-effort: server-side cleanup is idempotent
      and the heartbeat-TTL reaper picks up anything we miss.

    • activate.py restores default signal handlers and raises KeyboardInterrupt
      on first signal so a second Ctrl+C force-exits when the child wedges on
      its own SIGINT path. Bound supervisor's graceful timeout to 5s.

    • Tighten FE poll interval to 1s so the disconnect surfaces in the runner
      card immediately.

    • Cover supervisor disconnect on shutdown, 410 eviction, ApiError tolerance,
      and end-to-end SIGINT/SIGTERM delivery via a subprocess driver.

    Implements OPIK-6497.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    • revert(activate): drop SIG_DFL + KeyboardInterrupt force-kill path

    The two-stage signal handling (raise KeyboardInterrupt on first signal,
    restore SIG_DFL so a second signal force-kills) was a safety net for
    wedged agents that swallow KeyboardInterrupt. Removing it: the supervisor's
    graceful timeout + SIGKILL escalation already covers wedged children, and
    keeping the handler purely cooperative avoids changing the SIGINT contract
    that frameworks (uvicorn, etc.) may rely on.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com


    Co-authored-by: Claude Opus 4.7 (1M context) noreply@anthropic.com

    下载附件