Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: 19PINE-AI/pine-assistant-python
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: 19PINE-AI/pine-assistant-python
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feat/protocol-scope
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 1 commit
  • 55 files changed
  • 2 contributors

Commits on Aug 8, 2026

  1. feat(protocol)!: align the SDK to the supported protocol scope

    The SDK modelled 33 server-to-client events selected from roughly 60 the
    backend emits, with nothing marking which of them carry a compatibility
    guarantee. The supported scope names 19, and the two sets were not in a
    containment relationship.
    
    ## Protocol surface
    
    The modelled surface is now the supported scope and nothing else.
    
    Four supported events were absent and are added, with models:
    `session:llm_thinking`, `session:tool_status`, `session:required_action` and
    `session:restriction`. Between them they carry what a task is doing and why it
    stopped. The reasoning stream previously ran on `session:work_log`, which is
    outside the scope and is a distinct event from `session:llm_thinking` rather
    than a former name for it.
    
    Events outside the scope are unmodelled but still delivered, unchanged and in
    order. `is_supported_event()` distinguishes the two surfaces and
    `emit_event()` sends an unmodelled event. This follows the scope's own
    position: tolerating an unsupported event is required, depending on one is not.
    
    ## Requirements
    
    Three requirements the scope states as MUST were unmet:
    
    - **Recovery.** `session:join` now carries `since_revision` `"0"` and ignores
      the incremental-synchronisation fields. `rebuild()` pages through history
      until the cursor is exhausted, on every join and every reconnect. A short or
      empty page does not indicate exhaustion.
    - **Deduplication.** Events are keyed on the event identifier together with the
      message type. Identifiers collide across types, so keying on the identifier
      alone discards valid events.
    - **Blocking conditions.** `InputState` exposes the reason from
      `session:input_state`, including the two conditions the scope calls out.
    
    Turn control no longer depends on unsupported events. It previously hinged on
    `session:ask_for_location`, `session:interactive_auth_confirmation`,
    `session:three_way_call` and `session:reward`.
    
    ## Tests
    
    Three layers. `tests/protocol/fixtures` holds one envelope per supported event,
    with provenance recorded — 14 captured from live sessions, 4 derived from the
    protocol definition for conditions an ordinary session does not reach.
    `test_contract.py` validates one envelope at a time. `test_flow.py` drives
    sequences through the real transport and pins each MUST by name, including that
    an unrecognised event arrives verbatim without disturbing ordering.
    
    `tests/integration` was two overlapping copies of one live script, one of which
    asserted behaviour the SDK had already dropped. It is now a single suite that
    also serves as the fixture recorder. It places one call to a number in the
    range NANP reserves for fiction, which is what makes `session:task_ready`,
    `session:tool_status` and `session:task_finished` observable. It stays out of
    CI: it requires a token and consumes credits.
    
    CI gains a lint step. `ruff` was configured but never invoked.
    
    ## Fixed
    
    Sessions joined through `join_session()` were never re-joined after a
    reconnect. Membership was tracked on the fire-and-forget emit path, while
    joining is a request/response call.
    
    ## Breaking
    
    `send_auth_confirmation()`, `send_location_response()` and
    `send_location_selection()` are removed, along with `NotificationEvent`, the
    `session:reward` and `session:payment` models, the unsupported event constants,
    the `action` argument on `chat()`, and `request_work_log` on `get_history()`.
    Each remains reachable through `emit_event()`.
    
    `pine-mcp-server` calls the three removed methods and depends on
    `pine-assistant>=0.3.2`. It requires a corresponding change.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
    a7vinx and claude committed Aug 8, 2026
    Configuration menu
    Copy the full SHA
    329b16d View commit details
    Browse the repository at this point in the history
Loading