Skip to content

chore: publish new package versions#4578

Merged
balegas merged 1 commit into
mainfrom
changeset-release/main
Jun 15, 2026
Merged

chore: publish new package versions#4578
balegas merged 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@electric-ax/agents-runtime@0.4.0

Minor Changes

  • c48c1a8: Stream model reasoning / extended-thinking content into the UI. While
    the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
    reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
    now shows the live reasoning text faded above the answer, with the
    existing Thinking shimmer heading and an elapsed-time ticker. Once
    the reasoning settles it collapses to ▸ Thought for 12s — click to
    expand. Multiple reasoning rows per run are rendered independently in
    order, so tool-using turns show each step's reasoning separately.

    Implementation:

    • Schemareasoning row gains run_id, encrypted (Anthropic
      redacted-thinking opaque payload, must round-trip back to the model
      verbatim), and summary_title (extracted at write time for
      providers that emit a bolded heading). New reasoningDeltas
      collection mirrors textDeltas for streamed content.
    • BridgeOutboundBridge gains onReasoningStart /
      onReasoningDelta / onReasoningEnd, parallel to the text path.
    • Adapterpi-adapter.ts routes pi-ai's thinking_start /
      thinking_delta / thinking_end events to the bridge, parses the
      **Title**\n\n<body> heading (OpenAI Responses only) once at
      thinking_end so the UI doesn't re-parse on every render.
    • TimelineEntityTimelineRunRow gains a live
      reasoning: Collection<EntityTimelineReasoningItem> with content
      built from a delta-join, mirroring EntityTimelineTextItem.
    • UI — New <ReasoningSection> component renders above the
      answer in AgentResponseLive. Live shows faded markdown via
      Streamdown with ThinkingIndicator heading + summary title +
      elapsed-time ticker. Settled collapses to Thought for Ns with
      click-to-expand. Redacted Anthropic blocks render a single muted
      line — content is opaque, but the encrypted payload is still
      persisted server-side so the model gets it back next turn.

    Providers without reasoning emit nothing → no reasoning section
    rendered. Historical responses recorded before this PR have no
    closure cue, same as today.

    Anthropic extended thinking is now always-on for reasoning-capable
    models: reasoningEffort: auto maps to the minimal budget
    (1024 tokens), matching the OpenAI branch where auto already
    defaulted to minimal. Explicit low/medium/high scale the
    budget as before.

Patch Changes

  • 708c946: Add /goal slash command to Horton sessions. Lets the user set an
    objective with an optional token budget; the agent works autonomously
    toward the goal and stops when it calls mark_goal_complete or when
    the run exceeds the budget.

    /goal set "ship feature X" --tokens 50k   # default 50k tokens
    /goal set "explore" --unlimited           # opt out of the cap
    /goal show                                 # current state
    /goal complete                             # mark done manually
    /goal clear                                # remove the goal
    

    Behaviour

    • One goal per session, persisted as a kind: 'goal' entry on the
      manifests collection — resumes automatically across desktop
      restarts.
    • Mid-run token enforcement: an onStepEnd hook on the outbound
      bridge surfaces per-step token counts; Horton accumulates them and
      aborts the active ctx.agent.run() via an AbortController once
      tokensUsed >= tokenBudget. The cap counts new input (fresh +
      cache-write tokens) + output
      per step — prompt-cache reads (which
      re-count the whole conversation on every warm step) are excluded, so
      the budget tracks new work rather than context size.
    • Live progress: the goal banner ticks up after each step. The
      manifest update is written via writeEvent directly (not the
      wake-session's staged manifest transaction, which only commits at
      end-of-wake — too late for a long-running run).
    • mark_goal_complete tool: registered on Horton's tool list.
      Flips status to complete, surfaces in the chat as an ordinary
      agent reply via the new ctx.replyText helper.
    • State-changing /goal commands interrupt the active run
      typing /goal complete, /goal clear, or /goal set while a run
      is in flight signals SIGINT alongside sending the message, so the
      prior run aborts instead of finishing the old work first. /goal show is read-only and does not interrupt.
    • Budget-limited stop message: when the cap is hit mid-run, the
      agent posts a synthetic reply explaining what happened and
      suggesting a larger budget to resume.

    Plumbing

    • entity-schema.ts — new ManifestGoalEntryValue (objective,
      status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
      manifest discriminated union.
    • goal-api.ts (new) — setGoal / clearGoal / getGoal /
      markGoalComplete / updateGoalUsage. All goal mutations share a
      single ordered write channel (direct writeEvent upserts, live for
      the UI) plus an in-wake read-your-writes cache, so a mutation firing
      mid-run can never snapshot — and replay — a stale tokensUsed over
      a fresher one. updateGoalUsage additionally never decreases the
      counter.
    • goal-command.ts (new) — /goal parser (--tokens N|50k|1.2m| unlimited, --unlimited flag, subcommand aliases done/status)
      and dispatcher.
    • tools/goal-tools.ts (new) — createMarkGoalCompleteTool exposes
      the completion signal to the LLM.
    • outbound-bridge.ts — new optional OutboundBridgeHooks.onStepEnd
      callback, threaded through pi-adapter and the AgentConfig passed
      to useAgent.
    • context-factory.tsAgentHandle.run now accepts an optional
      abortSignal and combines it with the runtime's runSignal. New
      ctx.replyText(text) writes a complete runs + texts + textDeltas
      sequence so synthetic replies render in the chat. New goal-related
      methods exposed on HandlerContext.
    • horton.tstryHandleSlashCommand intercepts /goal * before
      the LLM; /goal set enqueues a one-shot kickoff so the agent starts
      immediately; assistantHandler wires the budget-enforcing
      onStepEnd, aborts on overflow, and posts the explanation reply.
    • agents-server-ui — new GoalBanner component above the timeline
      (objective + budget bar + status badge). MessageInput aborts the
      active run when a state-changing /goal command is submitted.
      EntityTimeline / EntityContextDrawer handle the new goal
      manifest kind.
  • 8bc630a: Add generic externally-writable custom collections for agent entity state: collections opt in via externallyWritable, writes go through an authenticated schema-validated endpoint that stamps the principal into a read-only _principal column, and createEntityTimelineQuery can project them into the timeline via customSources. Comments are reimplemented as one such collection, gated per agent type through a reserved comments/v1 contract that the UI keys its comment affordances on. External writes are restricted to a per-collection operations allowlist (insert-only by default), and comments are insert-only.

  • c1f3aac: Show only uncached input tokens in the per-response token usage label.

    The input side previously summed input + cacheRead + cacheWrite, so
    on warm-cache turns the meta row re-counted the entire conversation on
    every step and ballooned into a cumulative number that said nothing
    about the work the response actually did. The adapter now surfaces the
    uncached side only — fresh prompt tokens plus cache writes, with
    prompt-cache reads excluded. (cacheWrite is counted because
    cache-enabled providers report newly appended prompt tokens there,
    with input collapsing to ~0.)

    Steps recorded before this change keep their stored cache-inclusive
    totals — both step fields are optional and the display just sums
    what's persisted, so no migration is needed.

@electric-ax/agents@0.4.18

Patch Changes

  • 708c946: Add /goal slash command to Horton sessions. Lets the user set an
    objective with an optional token budget; the agent works autonomously
    toward the goal and stops when it calls mark_goal_complete or when
    the run exceeds the budget.

    /goal set "ship feature X" --tokens 50k   # default 50k tokens
    /goal set "explore" --unlimited           # opt out of the cap
    /goal show                                 # current state
    /goal complete                             # mark done manually
    /goal clear                                # remove the goal
    

    Behaviour

    • One goal per session, persisted as a kind: 'goal' entry on the
      manifests collection — resumes automatically across desktop
      restarts.
    • Mid-run token enforcement: an onStepEnd hook on the outbound
      bridge surfaces per-step token counts; Horton accumulates them and
      aborts the active ctx.agent.run() via an AbortController once
      tokensUsed >= tokenBudget. The cap counts new input (fresh +
      cache-write tokens) + output
      per step — prompt-cache reads (which
      re-count the whole conversation on every warm step) are excluded, so
      the budget tracks new work rather than context size.
    • Live progress: the goal banner ticks up after each step. The
      manifest update is written via writeEvent directly (not the
      wake-session's staged manifest transaction, which only commits at
      end-of-wake — too late for a long-running run).
    • mark_goal_complete tool: registered on Horton's tool list.
      Flips status to complete, surfaces in the chat as an ordinary
      agent reply via the new ctx.replyText helper.
    • State-changing /goal commands interrupt the active run
      typing /goal complete, /goal clear, or /goal set while a run
      is in flight signals SIGINT alongside sending the message, so the
      prior run aborts instead of finishing the old work first. /goal show is read-only and does not interrupt.
    • Budget-limited stop message: when the cap is hit mid-run, the
      agent posts a synthetic reply explaining what happened and
      suggesting a larger budget to resume.

    Plumbing

    • entity-schema.ts — new ManifestGoalEntryValue (objective,
      status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
      manifest discriminated union.
    • goal-api.ts (new) — setGoal / clearGoal / getGoal /
      markGoalComplete / updateGoalUsage. All goal mutations share a
      single ordered write channel (direct writeEvent upserts, live for
      the UI) plus an in-wake read-your-writes cache, so a mutation firing
      mid-run can never snapshot — and replay — a stale tokensUsed over
      a fresher one. updateGoalUsage additionally never decreases the
      counter.
    • goal-command.ts (new) — /goal parser (--tokens N|50k|1.2m| unlimited, --unlimited flag, subcommand aliases done/status)
      and dispatcher.
    • tools/goal-tools.ts (new) — createMarkGoalCompleteTool exposes
      the completion signal to the LLM.
    • outbound-bridge.ts — new optional OutboundBridgeHooks.onStepEnd
      callback, threaded through pi-adapter and the AgentConfig passed
      to useAgent.
    • context-factory.tsAgentHandle.run now accepts an optional
      abortSignal and combines it with the runtime's runSignal. New
      ctx.replyText(text) writes a complete runs + texts + textDeltas
      sequence so synthetic replies render in the chat. New goal-related
      methods exposed on HandlerContext.
    • horton.tstryHandleSlashCommand intercepts /goal * before
      the LLM; /goal set enqueues a one-shot kickoff so the agent starts
      immediately; assistantHandler wires the budget-enforcing
      onStepEnd, aborts on overflow, and posts the explanation reply.
    • agents-server-ui — new GoalBanner component above the timeline
      (objective + budget bar + status badge). MessageInput aborts the
      active run when a state-changing /goal command is submitted.
      EntityTimeline / EntityContextDrawer handle the new goal
      manifest kind.
  • 8bc630a: Add generic externally-writable custom collections for agent entity state: collections opt in via externallyWritable, writes go through an authenticated schema-validated endpoint that stamps the principal into a read-only _principal column, and createEntityTimelineQuery can project them into the timeline via customSources. Comments are reimplemented as one such collection, gated per agent type through a reserved comments/v1 contract that the UI keys its comment affordances on. External writes are restricted to a per-collection operations allowlist (insert-only by default), and comments are insert-only.

  • 6fc36d8: Embedder customization hooks for the built-in agents:

    • BuiltinAgentHandlerOptions.dockerSandbox ({ image, allowFloatingTag, env, extraMounts }) threads into the built-in docker sandbox profile. These are embedder/operator-trust inputs: extraMounts is subject to the runtime's docker-socket guard and env is passed verbatim into the container.
    • AgentHandlerResult.modelCatalog exposes the resolved model catalog so embedders can register sibling agent types with the same model resolution.
    • New exports: resolveBuiltinModelConfig, and types BuiltinModelCatalog, BuiltinAgentModelConfig, BuiltinDockerSandboxOptions, BuiltinDockerSandboxMount.
  • c48c1a8: Stream model reasoning / extended-thinking content into the UI. While
    the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
    reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
    now shows the live reasoning text faded above the answer, with the
    existing Thinking shimmer heading and an elapsed-time ticker. Once
    the reasoning settles it collapses to ▸ Thought for 12s — click to
    expand. Multiple reasoning rows per run are rendered independently in
    order, so tool-using turns show each step's reasoning separately.

    Implementation:

    • Schemareasoning row gains run_id, encrypted (Anthropic
      redacted-thinking opaque payload, must round-trip back to the model
      verbatim), and summary_title (extracted at write time for
      providers that emit a bolded heading). New reasoningDeltas
      collection mirrors textDeltas for streamed content.
    • BridgeOutboundBridge gains onReasoningStart /
      onReasoningDelta / onReasoningEnd, parallel to the text path.
    • Adapterpi-adapter.ts routes pi-ai's thinking_start /
      thinking_delta / thinking_end events to the bridge, parses the
      **Title**\n\n<body> heading (OpenAI Responses only) once at
      thinking_end so the UI doesn't re-parse on every render.
    • TimelineEntityTimelineRunRow gains a live
      reasoning: Collection<EntityTimelineReasoningItem> with content
      built from a delta-join, mirroring EntityTimelineTextItem.
    • UI — New <ReasoningSection> component renders above the
      answer in AgentResponseLive. Live shows faded markdown via
      Streamdown with ThinkingIndicator heading + summary title +
      elapsed-time ticker. Settled collapses to Thought for Ns with
      click-to-expand. Redacted Anthropic blocks render a single muted
      line — content is opaque, but the encrypted payload is still
      persisted server-side so the model gets it back next turn.

    Providers without reasoning emit nothing → no reasoning section
    rendered. Historical responses recorded before this PR have no
    closure cue, same as today.

    Anthropic extended thinking is now always-on for reasoning-capable
    models: reasoningEffort: auto maps to the minimal budget
    (1024 tokens), matching the OpenAI branch where auto already
    defaulted to minimal. Explicit low/medium/high scale the
    budget as before.

  • Updated dependencies [708c946]

  • Updated dependencies [8bc630a]

  • Updated dependencies [c48c1a8]

  • Updated dependencies [c1f3aac]

    • @electric-ax/agents-runtime@0.4.0

@electric-ax/agents-server@0.5.0

Patch Changes

  • 8bc630a: Add generic externally-writable custom collections for agent entity state: collections opt in via externallyWritable, writes go through an authenticated schema-validated endpoint that stamps the principal into a read-only _principal column, and createEntityTimelineQuery can project them into the timeline via customSources. Comments are reimplemented as one such collection, gated per agent type through a reserved comments/v1 contract that the UI keys its comment affordances on. External writes are restricted to a per-collection operations allowlist (insert-only by default), and comments are insert-only.
  • Updated dependencies [708c946]
  • Updated dependencies [8bc630a]
  • Updated dependencies [c48c1a8]
  • Updated dependencies [c1f3aac]
    • @electric-ax/agents-runtime@0.4.0

electric-ax@0.2.18

Patch Changes

  • Updated dependencies [708c946]
  • Updated dependencies [8bc630a]
  • Updated dependencies [6fc36d8]
  • Updated dependencies [c48c1a8]
  • Updated dependencies [c1f3aac]
    • @electric-ax/agents-runtime@0.4.0
    • @electric-ax/agents@0.4.18

@electric-ax/agents-server-ui@0.5.0

Minor Changes

  • c48c1a8: Stream model reasoning / extended-thinking content into the UI. While
    the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
    reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
    now shows the live reasoning text faded above the answer, with the
    existing Thinking shimmer heading and an elapsed-time ticker. Once
    the reasoning settles it collapses to ▸ Thought for 12s — click to
    expand. Multiple reasoning rows per run are rendered independently in
    order, so tool-using turns show each step's reasoning separately.

    Implementation:

    • Schemareasoning row gains run_id, encrypted (Anthropic
      redacted-thinking opaque payload, must round-trip back to the model
      verbatim), and summary_title (extracted at write time for
      providers that emit a bolded heading). New reasoningDeltas
      collection mirrors textDeltas for streamed content.
    • BridgeOutboundBridge gains onReasoningStart /
      onReasoningDelta / onReasoningEnd, parallel to the text path.
    • Adapterpi-adapter.ts routes pi-ai's thinking_start /
      thinking_delta / thinking_end events to the bridge, parses the
      **Title**\n\n<body> heading (OpenAI Responses only) once at
      thinking_end so the UI doesn't re-parse on every render.
    • TimelineEntityTimelineRunRow gains a live
      reasoning: Collection<EntityTimelineReasoningItem> with content
      built from a delta-join, mirroring EntityTimelineTextItem.
    • UI — New <ReasoningSection> component renders above the
      answer in AgentResponseLive. Live shows faded markdown via
      Streamdown with ThinkingIndicator heading + summary title +
      elapsed-time ticker. Settled collapses to Thought for Ns with
      click-to-expand. Redacted Anthropic blocks render a single muted
      line — content is opaque, but the encrypted payload is still
      persisted server-side so the model gets it back next turn.

    Providers without reasoning emit nothing → no reasoning section
    rendered. Historical responses recorded before this PR have no
    closure cue, same as today.

    Anthropic extended thinking is now always-on for reasoning-capable
    models: reasoningEffort: auto maps to the minimal budget
    (1024 tokens), matching the OpenAI branch where auto already
    defaulted to minimal. Explicit low/medium/high scale the
    budget as before.

Patch Changes

  • 708c946: Add /goal slash command to Horton sessions. Lets the user set an
    objective with an optional token budget; the agent works autonomously
    toward the goal and stops when it calls mark_goal_complete or when
    the run exceeds the budget.

    /goal set "ship feature X" --tokens 50k   # default 50k tokens
    /goal set "explore" --unlimited           # opt out of the cap
    /goal show                                 # current state
    /goal complete                             # mark done manually
    /goal clear                                # remove the goal
    

    Behaviour

    • One goal per session, persisted as a kind: 'goal' entry on the
      manifests collection — resumes automatically across desktop
      restarts.
    • Mid-run token enforcement: an onStepEnd hook on the outbound
      bridge surfaces per-step token counts; Horton accumulates them and
      aborts the active ctx.agent.run() via an AbortController once
      tokensUsed >= tokenBudget. The cap counts new input (fresh +
      cache-write tokens) + output
      per step — prompt-cache reads (which
      re-count the whole conversation on every warm step) are excluded, so
      the budget tracks new work rather than context size.
    • Live progress: the goal banner ticks up after each step. The
      manifest update is written via writeEvent directly (not the
      wake-session's staged manifest transaction, which only commits at
      end-of-wake — too late for a long-running run).
    • mark_goal_complete tool: registered on Horton's tool list.
      Flips status to complete, surfaces in the chat as an ordinary
      agent reply via the new ctx.replyText helper.
    • State-changing /goal commands interrupt the active run
      typing /goal complete, /goal clear, or /goal set while a run
      is in flight signals SIGINT alongside sending the message, so the
      prior run aborts instead of finishing the old work first. /goal show is read-only and does not interrupt.
    • Budget-limited stop message: when the cap is hit mid-run, the
      agent posts a synthetic reply explaining what happened and
      suggesting a larger budget to resume.

    Plumbing

    • entity-schema.ts — new ManifestGoalEntryValue (objective,
      status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
      manifest discriminated union.
    • goal-api.ts (new) — setGoal / clearGoal / getGoal /
      markGoalComplete / updateGoalUsage. All goal mutations share a
      single ordered write channel (direct writeEvent upserts, live for
      the UI) plus an in-wake read-your-writes cache, so a mutation firing
      mid-run can never snapshot — and replay — a stale tokensUsed over
      a fresher one. updateGoalUsage additionally never decreases the
      counter.
    • goal-command.ts (new) — /goal parser (--tokens N|50k|1.2m| unlimited, --unlimited flag, subcommand aliases done/status)
      and dispatcher.
    • tools/goal-tools.ts (new) — createMarkGoalCompleteTool exposes
      the completion signal to the LLM.
    • outbound-bridge.ts — new optional OutboundBridgeHooks.onStepEnd
      callback, threaded through pi-adapter and the AgentConfig passed
      to useAgent.
    • context-factory.tsAgentHandle.run now accepts an optional
      abortSignal and combines it with the runtime's runSignal. New
      ctx.replyText(text) writes a complete runs + texts + textDeltas
      sequence so synthetic replies render in the chat. New goal-related
      methods exposed on HandlerContext.
    • horton.tstryHandleSlashCommand intercepts /goal * before
      the LLM; /goal set enqueues a one-shot kickoff so the agent starts
      immediately; assistantHandler wires the budget-enforcing
      onStepEnd, aborts on overflow, and posts the explanation reply.
    • agents-server-ui — new GoalBanner component above the timeline
      (objective + budget bar + status badge). MessageInput aborts the
      active run when a state-changing /goal command is submitted.
      EntityTimeline / EntityContextDrawer handle the new goal
      manifest kind.
  • 0b26edf: Bring session sharing to mobile (desktop ShareEntityDialog parity, mobile-first UX):

    • Share session screen. A modal route opened from the session menu's new Share entry. It exposes a link pill (abbreviated session web URL — one tap opens the native OS share sheet, which includes Copy), a "People with access" list with a pinned Owner row, a Google-Drive-style "General access" section for the workspace-wide All users grant, and a search-first "Add people" section. Roles (View / Chat / Manage, same permission sets and glyphs as desktop) commit per row through a bottom-sheet picker with a destructive Remove access action — no deferred Grant/Update button. The grant list comes from the manage-protected REST GET /grants endpoint (the synced effective-permissions shape is scoped to the current principal, so it can't list other people's access); non-managers still get the link actions and see a manage-required message below.
    • Copy session id. The session menu's status header and the long-press row sheet now render the id with a tap-to-copy affordance (copy→check icon swap, mirroring the desktop entity header), via a new expo-clipboard dependency.
    • Session web links. sessionWebUrl() builds {serverUrl}/__agent_ui/#/entity/{id} directly — targeting the web UI path rather than the server root, whose absolute-path redirect would drop a Cloud /t/<service-id>/v1 tenant prefix.

    The desktop dialog's userDisplay()/initials() helpers move into agents-server-ui's lib/userDisplay.ts so mobile deep-imports them instead of duplicating. Grant-diffing, removal, and access-model grouping logic is ported into a pure, unit-tested entityGrants module. No server API changes.

  • 8bc630a: Add generic externally-writable custom collections for agent entity state: collections opt in via externallyWritable, writes go through an authenticated schema-validated endpoint that stamps the principal into a read-only _principal column, and createEntityTimelineQuery can project them into the timeline via customSources. Comments are reimplemented as one such collection, gated per agent type through a reserved comments/v1 contract that the UI keys its comment affordances on. External writes are restricted to a per-collection operations allowlist (insert-only by default), and comments are insert-only.

  • 8b1d39f: Hide the per-response token-usage label when the combined input + output
    count falls below a threshold (SHOW_USAGE_THRESHOLD, currently 1000).
    Tiny tool-only steps and one-line replies no longer clutter the meta row
    with noise like 47 ↑ 12 ↓; the threshold lives in a single constant so
    it's easy to tune.

  • c1f3aac: Show only uncached input tokens in the per-response token usage label.

    The input side previously summed input + cacheRead + cacheWrite, so
    on warm-cache turns the meta row re-counted the entire conversation on
    every step and ballooned into a cumulative number that said nothing
    about the work the response actually did. The adapter now surfaces the
    uncached side only — fresh prompt tokens plus cache writes, with
    prompt-cache reads excluded. (cacheWrite is counted because
    cache-enabled providers report newly appended prompt tokens there,
    with input collapsing to ~0.)

    Steps recorded before this change keep their stored cache-inclusive
    totals — both step fields are optional and the display just sums
    what's persisted, so no migration is needed.

  • Updated dependencies [708c946]

  • Updated dependencies [8bc630a]

  • Updated dependencies [c48c1a8]

  • Updated dependencies [c1f3aac]

    • @electric-ax/agents-runtime@0.4.0

@electric-ax/example-agents-chat-starter@0.1.9

Patch Changes

  • Updated dependencies [708c946]
  • Updated dependencies [8bc630a]
  • Updated dependencies [c48c1a8]
  • Updated dependencies [c1f3aac]
    • @electric-ax/agents-runtime@0.4.0

@electric-ax/example-agents-walkthrough@0.1.6

Patch Changes

  • Updated dependencies [708c946]
  • Updated dependencies [8bc630a]
  • Updated dependencies [c48c1a8]
  • Updated dependencies [c1f3aac]
    • @electric-ax/agents-runtime@0.4.0

@electric-ax/example-deep-survey@0.1.25

Patch Changes

  • Updated dependencies [708c946]
  • Updated dependencies [8bc630a]
  • Updated dependencies [c48c1a8]
  • Updated dependencies [c1f3aac]
    • @electric-ax/agents-runtime@0.4.0

@electric-ax/agents-desktop@0.1.18

Patch Changes

  • c48c1a8: Stream model reasoning / extended-thinking content into the UI. While
    the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
    reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
    now shows the live reasoning text faded above the answer, with the
    existing Thinking shimmer heading and an elapsed-time ticker. Once
    the reasoning settles it collapses to ▸ Thought for 12s — click to
    expand. Multiple reasoning rows per run are rendered independently in
    order, so tool-using turns show each step's reasoning separately.

    Implementation:

    • Schemareasoning row gains run_id, encrypted (Anthropic
      redacted-thinking opaque payload, must round-trip back to the model
      verbatim), and summary_title (extracted at write time for
      providers that emit a bolded heading). New reasoningDeltas
      collection mirrors textDeltas for streamed content.
    • BridgeOutboundBridge gains onReasoningStart /
      onReasoningDelta / onReasoningEnd, parallel to the text path.
    • Adapterpi-adapter.ts routes pi-ai's thinking_start /
      thinking_delta / thinking_end events to the bridge, parses the
      **Title**\n\n<body> heading (OpenAI Responses only) once at
      thinking_end so the UI doesn't re-parse on every render.
    • TimelineEntityTimelineRunRow gains a live
      reasoning: Collection<EntityTimelineReasoningItem> with content
      built from a delta-join, mirroring EntityTimelineTextItem.
    • UI — New <ReasoningSection> component renders above the
      answer in AgentResponseLive. Live shows faded markdown via
      Streamdown with ThinkingIndicator heading + summary title +
      elapsed-time ticker. Settled collapses to Thought for Ns with
      click-to-expand. Redacted Anthropic blocks render a single muted
      line — content is opaque, but the encrypted payload is still
      persisted server-side so the model gets it back next turn.

    Providers without reasoning emit nothing → no reasoning section
    rendered. Historical responses recorded before this PR have no
    closure cue, same as today.

    Anthropic extended thinking is now always-on for reasoning-capable
    models: reasoningEffort: auto maps to the minimal budget
    (1024 tokens), matching the OpenAI branch where auto already
    defaulted to minimal. Explicit low/medium/high scale the
    budget as before.

@electric-ax/agents-mobile@0.0.16

Patch Changes

  • 0b26edf: Bring session sharing to mobile (desktop ShareEntityDialog parity, mobile-first UX):

    • Share session screen. A modal route opened from the session menu's new Share entry. It exposes a link pill (abbreviated session web URL — one tap opens the native OS share sheet, which includes Copy), a "People with access" list with a pinned Owner row, a Google-Drive-style "General access" section for the workspace-wide All users grant, and a search-first "Add people" section. Roles (View / Chat / Manage, same permission sets and glyphs as desktop) commit per row through a bottom-sheet picker with a destructive Remove access action — no deferred Grant/Update button. The grant list comes from the manage-protected REST GET /grants endpoint (the synced effective-permissions shape is scoped to the current principal, so it can't list other people's access); non-managers still get the link actions and see a manage-required message below.
    • Copy session id. The session menu's status header and the long-press row sheet now render the id with a tap-to-copy affordance (copy→check icon swap, mirroring the desktop entity header), via a new expo-clipboard dependency.
    • Session web links. sessionWebUrl() builds {serverUrl}/__agent_ui/#/entity/{id} directly — targeting the web UI path rather than the server root, whose absolute-path redirect would drop a Cloud /t/<service-id>/v1 tenant prefix.

    The desktop dialog's userDisplay()/initials() helpers move into agents-server-ui's lib/userDisplay.ts so mobile deep-imports them instead of duplicating. Grant-diffing, removal, and access-model grouping logic is ported into a pure, unit-tested entityGrants module. No server API changes.

  • Updated dependencies [708c946]

  • Updated dependencies [0b26edf]

  • Updated dependencies [8bc630a]

  • Updated dependencies [c48c1a8]

  • Updated dependencies [8b1d39f]

  • Updated dependencies [c1f3aac]

    • @electric-ax/agents-server-ui@0.5.0
    • @electric-ax/agents-runtime@0.4.0

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 5 times, most recently from 5a2fe80 to e4c386a Compare June 15, 2026 12:18
@github-actions
github-actions Bot force-pushed the changeset-release/main branch from e4c386a to fe35aae Compare June 15, 2026 12:58
@balegas
balegas merged commit 992e2f3 into main Jun 15, 2026
5 checks passed
@balegas
balegas deleted the changeset-release/main branch June 15, 2026 12:59
KyleAMathews pushed a commit that referenced this pull request Jun 15, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @electric-ax/agents-runtime@0.4.0

### Minor Changes

- c48c1a8: Stream model reasoning / extended-thinking content into the
UI. While
  the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
  reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
  now shows the live reasoning text faded above the answer, with the
  existing `Thinking` shimmer heading and an elapsed-time ticker. Once
  the reasoning settles it collapses to `▸ Thought for 12s` — click to
  expand. Multiple reasoning rows per run are rendered independently in
  order, so tool-using turns show each step's reasoning separately.

  Implementation:
  - **Schema** — `reasoning` row gains `run_id`, `encrypted` (Anthropic
    redacted-thinking opaque payload, must round-trip back to the model
    verbatim), and `summary_title` (extracted at write time for
    providers that emit a bolded heading). New `reasoningDeltas`
    collection mirrors `textDeltas` for streamed content.
  - **Bridge** — `OutboundBridge` gains `onReasoningStart` /
    `onReasoningDelta` / `onReasoningEnd`, parallel to the text path.
  - **Adapter** — `pi-adapter.ts` routes pi-ai's `thinking_start` /
    `thinking_delta` / `thinking_end` events to the bridge, parses the
    `**Title**\n\n<body>` heading (OpenAI Responses only) once at
    `thinking_end` so the UI doesn't re-parse on every render.
  - **Timeline** — `EntityTimelineRunRow` gains a live
    `reasoning: Collection<EntityTimelineReasoningItem>` with content
    built from a delta-join, mirroring `EntityTimelineTextItem`.
  - **UI** — New `<ReasoningSection>` component renders above the
    answer in `AgentResponseLive`. Live shows faded markdown via
    `Streamdown` with `ThinkingIndicator` heading + summary title +
    elapsed-time ticker. Settled collapses to `Thought for Ns` with
    click-to-expand. Redacted Anthropic blocks render a single muted
    line — content is opaque, but the encrypted payload is still
    persisted server-side so the model gets it back next turn.

  Providers without reasoning emit nothing → no reasoning section
  rendered. Historical responses recorded before this PR have no
  closure cue, same as today.

  Anthropic extended thinking is now always-on for reasoning-capable
  models: `reasoningEffort: auto` maps to the minimal budget
  (1024 tokens), matching the OpenAI branch where `auto` already
  defaulted to `minimal`. Explicit `low`/`medium`/`high` scale the
  budget as before.

### Patch Changes

- 708c946: Add `/goal` slash command to Horton sessions. Lets the user
set an
  objective with an optional token budget; the agent works autonomously
  toward the goal and stops when it calls `mark_goal_complete` or when
  the run exceeds the budget.

  ```text
  /goal set "ship feature X" --tokens 50k   # default 50k tokens
  /goal set "explore" --unlimited           # opt out of the cap
  /goal show                                 # current state
  /goal complete                             # mark done manually
  /goal clear                                # remove the goal
  ```

  ## Behaviour
  - **One goal per session**, persisted as a `kind: 'goal'` entry on the
    `manifests` collection — resumes automatically across desktop
    restarts.
  - **Mid-run token enforcement**: an `onStepEnd` hook on the outbound
    bridge surfaces per-step token counts; Horton accumulates them and
    aborts the active `ctx.agent.run()` via an `AbortController` once
    `tokensUsed >= tokenBudget`. The cap counts **new input (fresh +
    cache-write tokens) + output** per step — prompt-cache reads (which
    re-count the whole conversation on every warm step) are excluded, so
    the budget tracks new work rather than context size.
  - **Live progress**: the goal banner ticks up after each step. The
    manifest update is written via `writeEvent` directly (not the
    wake-session's staged manifest transaction, which only commits at
    end-of-wake — too late for a long-running run).
  - **`mark_goal_complete` tool**: registered on Horton's tool list.
    Flips status to `complete`, surfaces in the chat as an ordinary
    agent reply via the new `ctx.replyText` helper.
  - **State-changing `/goal` commands interrupt the active run** —
    typing `/goal complete`, `/goal clear`, or `/goal set` while a run
    is in flight signals SIGINT alongside sending the message, so the
    prior run aborts instead of finishing the old work first. `/goal
show` is read-only and does not interrupt.
  - **Budget-limited stop message**: when the cap is hit mid-run, the
    agent posts a synthetic reply explaining what happened and
    suggesting a larger budget to resume.

  ## Plumbing
  - `entity-schema.ts` — new `ManifestGoalEntryValue` (objective,
    status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
    manifest discriminated union.
  - `goal-api.ts` (new) — `setGoal` / `clearGoal` / `getGoal` /
    `markGoalComplete` / `updateGoalUsage`. All goal mutations share a
    single ordered write channel (direct `writeEvent` upserts, live for
    the UI) plus an in-wake read-your-writes cache, so a mutation firing
    mid-run can never snapshot — and replay — a stale `tokensUsed` over
    a fresher one. `updateGoalUsage` additionally never decreases the
    counter.
  - `goal-command.ts` (new) — `/goal` parser (`--tokens N|50k|1.2m|
unlimited`, `--unlimited` flag, subcommand aliases `done`/`status`)
    and dispatcher.
  - `tools/goal-tools.ts` (new) — `createMarkGoalCompleteTool` exposes
    the completion signal to the LLM.
  - `outbound-bridge.ts` — new optional `OutboundBridgeHooks.onStepEnd`
    callback, threaded through `pi-adapter` and the `AgentConfig` passed
    to `useAgent`.
  - `context-factory.ts` — `AgentHandle.run` now accepts an optional
    `abortSignal` and combines it with the runtime's `runSignal`. New
    `ctx.replyText(text)` writes a complete runs + texts + textDeltas
    sequence so synthetic replies render in the chat. New goal-related
    methods exposed on `HandlerContext`.
  - `horton.ts` — `tryHandleSlashCommand` intercepts `/goal *` before
    the LLM; `/goal set` enqueues a one-shot kickoff so the agent starts
    immediately; `assistantHandler` wires the budget-enforcing
    `onStepEnd`, aborts on overflow, and posts the explanation reply.
  - `agents-server-ui` — new `GoalBanner` component above the timeline
    (objective + budget bar + status badge). `MessageInput` aborts the
    active run when a state-changing `/goal` command is submitted.
    `EntityTimeline` / `EntityContextDrawer` handle the new `goal`
    manifest kind.

- 8bc630a: Add generic externally-writable custom collections for agent
entity state: collections opt in via `externallyWritable`, writes go
through an authenticated schema-validated endpoint that stamps the
principal into a read-only `_principal` column, and
`createEntityTimelineQuery` can project them into the timeline via
`customSources`. Comments are reimplemented as one such collection,
gated per agent type through a reserved `comments/v1` contract that the
UI keys its comment affordances on. External writes are restricted to a
per-collection operations allowlist (insert-only by default), and
comments are insert-only.
- c1f3aac: Show only uncached input tokens in the per-response token
usage label.

  The input side previously summed `input + cacheRead + cacheWrite`, so
  on warm-cache turns the meta row re-counted the entire conversation on
  every step and ballooned into a cumulative number that said nothing
  about the work the response actually did. The adapter now surfaces the
  uncached side only — fresh prompt tokens plus cache writes, with
  prompt-cache reads excluded. (`cacheWrite` is counted because
  cache-enabled providers report newly appended prompt tokens there,
  with `input` collapsing to ~0.)

  Steps recorded before this change keep their stored cache-inclusive
  totals — both step fields are optional and the display just sums
  what's persisted, so no migration is needed.
## @electric-ax/agents@0.4.18

### Patch Changes

- 708c946: Add `/goal` slash command to Horton sessions. Lets the user
set an
  objective with an optional token budget; the agent works autonomously
  toward the goal and stops when it calls `mark_goal_complete` or when
  the run exceeds the budget.

  ```text
  /goal set "ship feature X" --tokens 50k   # default 50k tokens
  /goal set "explore" --unlimited           # opt out of the cap
  /goal show                                 # current state
  /goal complete                             # mark done manually
  /goal clear                                # remove the goal
  ```

  ## Behaviour
  - **One goal per session**, persisted as a `kind: 'goal'` entry on the
    `manifests` collection — resumes automatically across desktop
    restarts.
  - **Mid-run token enforcement**: an `onStepEnd` hook on the outbound
    bridge surfaces per-step token counts; Horton accumulates them and
    aborts the active `ctx.agent.run()` via an `AbortController` once
    `tokensUsed >= tokenBudget`. The cap counts **new input (fresh +
    cache-write tokens) + output** per step — prompt-cache reads (which
    re-count the whole conversation on every warm step) are excluded, so
    the budget tracks new work rather than context size.
  - **Live progress**: the goal banner ticks up after each step. The
    manifest update is written via `writeEvent` directly (not the
    wake-session's staged manifest transaction, which only commits at
    end-of-wake — too late for a long-running run).
  - **`mark_goal_complete` tool**: registered on Horton's tool list.
    Flips status to `complete`, surfaces in the chat as an ordinary
    agent reply via the new `ctx.replyText` helper.
  - **State-changing `/goal` commands interrupt the active run** —
    typing `/goal complete`, `/goal clear`, or `/goal set` while a run
    is in flight signals SIGINT alongside sending the message, so the
    prior run aborts instead of finishing the old work first. `/goal
show` is read-only and does not interrupt.
  - **Budget-limited stop message**: when the cap is hit mid-run, the
    agent posts a synthetic reply explaining what happened and
    suggesting a larger budget to resume.

  ## Plumbing
  - `entity-schema.ts` — new `ManifestGoalEntryValue` (objective,
    status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
    manifest discriminated union.
  - `goal-api.ts` (new) — `setGoal` / `clearGoal` / `getGoal` /
    `markGoalComplete` / `updateGoalUsage`. All goal mutations share a
    single ordered write channel (direct `writeEvent` upserts, live for
    the UI) plus an in-wake read-your-writes cache, so a mutation firing
    mid-run can never snapshot — and replay — a stale `tokensUsed` over
    a fresher one. `updateGoalUsage` additionally never decreases the
    counter.
  - `goal-command.ts` (new) — `/goal` parser (`--tokens N|50k|1.2m|
unlimited`, `--unlimited` flag, subcommand aliases `done`/`status`)
    and dispatcher.
  - `tools/goal-tools.ts` (new) — `createMarkGoalCompleteTool` exposes
    the completion signal to the LLM.
  - `outbound-bridge.ts` — new optional `OutboundBridgeHooks.onStepEnd`
    callback, threaded through `pi-adapter` and the `AgentConfig` passed
    to `useAgent`.
  - `context-factory.ts` — `AgentHandle.run` now accepts an optional
    `abortSignal` and combines it with the runtime's `runSignal`. New
    `ctx.replyText(text)` writes a complete runs + texts + textDeltas
    sequence so synthetic replies render in the chat. New goal-related
    methods exposed on `HandlerContext`.
  - `horton.ts` — `tryHandleSlashCommand` intercepts `/goal *` before
    the LLM; `/goal set` enqueues a one-shot kickoff so the agent starts
    immediately; `assistantHandler` wires the budget-enforcing
    `onStepEnd`, aborts on overflow, and posts the explanation reply.
  - `agents-server-ui` — new `GoalBanner` component above the timeline
    (objective + budget bar + status badge). `MessageInput` aborts the
    active run when a state-changing `/goal` command is submitted.
    `EntityTimeline` / `EntityContextDrawer` handle the new `goal`
    manifest kind.

- 8bc630a: Add generic externally-writable custom collections for agent
entity state: collections opt in via `externallyWritable`, writes go
through an authenticated schema-validated endpoint that stamps the
principal into a read-only `_principal` column, and
`createEntityTimelineQuery` can project them into the timeline via
`customSources`. Comments are reimplemented as one such collection,
gated per agent type through a reserved `comments/v1` contract that the
UI keys its comment affordances on. External writes are restricted to a
per-collection operations allowlist (insert-only by default), and
comments are insert-only.
- 6fc36d8: Embedder customization hooks for the built-in agents:
- `BuiltinAgentHandlerOptions.dockerSandbox` ({ image, allowFloatingTag,
env, extraMounts }) threads into the built-in `docker` sandbox profile.
These are embedder/operator-trust inputs: `extraMounts` is subject to
the runtime's docker-socket guard and `env` is passed verbatim into the
container.
- `AgentHandlerResult.modelCatalog` exposes the resolved model catalog
so embedders can register sibling agent types with the same model
resolution.
- New exports: `resolveBuiltinModelConfig`, and types
`BuiltinModelCatalog`, `BuiltinAgentModelConfig`,
`BuiltinDockerSandboxOptions`, `BuiltinDockerSandboxMount`.

- c48c1a8: Stream model reasoning / extended-thinking content into the
UI. While
  the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
  reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
  now shows the live reasoning text faded above the answer, with the
  existing `Thinking` shimmer heading and an elapsed-time ticker. Once
  the reasoning settles it collapses to `▸ Thought for 12s` — click to
  expand. Multiple reasoning rows per run are rendered independently in
  order, so tool-using turns show each step's reasoning separately.

  Implementation:
  - **Schema** — `reasoning` row gains `run_id`, `encrypted` (Anthropic
    redacted-thinking opaque payload, must round-trip back to the model
    verbatim), and `summary_title` (extracted at write time for
    providers that emit a bolded heading). New `reasoningDeltas`
    collection mirrors `textDeltas` for streamed content.
  - **Bridge** — `OutboundBridge` gains `onReasoningStart` /
    `onReasoningDelta` / `onReasoningEnd`, parallel to the text path.
  - **Adapter** — `pi-adapter.ts` routes pi-ai's `thinking_start` /
    `thinking_delta` / `thinking_end` events to the bridge, parses the
    `**Title**\n\n<body>` heading (OpenAI Responses only) once at
    `thinking_end` so the UI doesn't re-parse on every render.
  - **Timeline** — `EntityTimelineRunRow` gains a live
    `reasoning: Collection<EntityTimelineReasoningItem>` with content
    built from a delta-join, mirroring `EntityTimelineTextItem`.
  - **UI** — New `<ReasoningSection>` component renders above the
    answer in `AgentResponseLive`. Live shows faded markdown via
    `Streamdown` with `ThinkingIndicator` heading + summary title +
    elapsed-time ticker. Settled collapses to `Thought for Ns` with
    click-to-expand. Redacted Anthropic blocks render a single muted
    line — content is opaque, but the encrypted payload is still
    persisted server-side so the model gets it back next turn.

  Providers without reasoning emit nothing → no reasoning section
  rendered. Historical responses recorded before this PR have no
  closure cue, same as today.

  Anthropic extended thinking is now always-on for reasoning-capable
  models: `reasoningEffort: auto` maps to the minimal budget
  (1024 tokens), matching the OpenAI branch where `auto` already
  defaulted to `minimal`. Explicit `low`/`medium`/`high` scale the
  budget as before.

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## @electric-ax/agents-server@0.5.0

### Patch Changes

- 8bc630a: Add generic externally-writable custom collections for agent
entity state: collections opt in via `externallyWritable`, writes go
through an authenticated schema-validated endpoint that stamps the
principal into a read-only `_principal` column, and
`createEntityTimelineQuery` can project them into the timeline via
`customSources`. Comments are reimplemented as one such collection,
gated per agent type through a reserved `comments/v1` contract that the
UI keys its comment affordances on. External writes are restricted to a
per-collection operations allowlist (insert-only by default), and
comments are insert-only.
- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## electric-ax@0.2.18

### Patch Changes

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [6fc36d8]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
  - @electric-ax/agents@0.4.18
## @electric-ax/agents-server-ui@0.5.0

### Minor Changes

- c48c1a8: Stream model reasoning / extended-thinking content into the
UI. While
  the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
  reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
  now shows the live reasoning text faded above the answer, with the
  existing `Thinking` shimmer heading and an elapsed-time ticker. Once
  the reasoning settles it collapses to `▸ Thought for 12s` — click to
  expand. Multiple reasoning rows per run are rendered independently in
  order, so tool-using turns show each step's reasoning separately.

  Implementation:
  - **Schema** — `reasoning` row gains `run_id`, `encrypted` (Anthropic
    redacted-thinking opaque payload, must round-trip back to the model
    verbatim), and `summary_title` (extracted at write time for
    providers that emit a bolded heading). New `reasoningDeltas`
    collection mirrors `textDeltas` for streamed content.
  - **Bridge** — `OutboundBridge` gains `onReasoningStart` /
    `onReasoningDelta` / `onReasoningEnd`, parallel to the text path.
  - **Adapter** — `pi-adapter.ts` routes pi-ai's `thinking_start` /
    `thinking_delta` / `thinking_end` events to the bridge, parses the
    `**Title**\n\n<body>` heading (OpenAI Responses only) once at
    `thinking_end` so the UI doesn't re-parse on every render.
  - **Timeline** — `EntityTimelineRunRow` gains a live
    `reasoning: Collection<EntityTimelineReasoningItem>` with content
    built from a delta-join, mirroring `EntityTimelineTextItem`.
  - **UI** — New `<ReasoningSection>` component renders above the
    answer in `AgentResponseLive`. Live shows faded markdown via
    `Streamdown` with `ThinkingIndicator` heading + summary title +
    elapsed-time ticker. Settled collapses to `Thought for Ns` with
    click-to-expand. Redacted Anthropic blocks render a single muted
    line — content is opaque, but the encrypted payload is still
    persisted server-side so the model gets it back next turn.

  Providers without reasoning emit nothing → no reasoning section
  rendered. Historical responses recorded before this PR have no
  closure cue, same as today.

  Anthropic extended thinking is now always-on for reasoning-capable
  models: `reasoningEffort: auto` maps to the minimal budget
  (1024 tokens), matching the OpenAI branch where `auto` already
  defaulted to `minimal`. Explicit `low`/`medium`/`high` scale the
  budget as before.

### Patch Changes

- 708c946: Add `/goal` slash command to Horton sessions. Lets the user
set an
  objective with an optional token budget; the agent works autonomously
  toward the goal and stops when it calls `mark_goal_complete` or when
  the run exceeds the budget.

  ```text
  /goal set "ship feature X" --tokens 50k   # default 50k tokens
  /goal set "explore" --unlimited           # opt out of the cap
  /goal show                                 # current state
  /goal complete                             # mark done manually
  /goal clear                                # remove the goal
  ```

  ## Behaviour
  - **One goal per session**, persisted as a `kind: 'goal'` entry on the
    `manifests` collection — resumes automatically across desktop
    restarts.
  - **Mid-run token enforcement**: an `onStepEnd` hook on the outbound
    bridge surfaces per-step token counts; Horton accumulates them and
    aborts the active `ctx.agent.run()` via an `AbortController` once
    `tokensUsed >= tokenBudget`. The cap counts **new input (fresh +
    cache-write tokens) + output** per step — prompt-cache reads (which
    re-count the whole conversation on every warm step) are excluded, so
    the budget tracks new work rather than context size.
  - **Live progress**: the goal banner ticks up after each step. The
    manifest update is written via `writeEvent` directly (not the
    wake-session's staged manifest transaction, which only commits at
    end-of-wake — too late for a long-running run).
  - **`mark_goal_complete` tool**: registered on Horton's tool list.
    Flips status to `complete`, surfaces in the chat as an ordinary
    agent reply via the new `ctx.replyText` helper.
  - **State-changing `/goal` commands interrupt the active run** —
    typing `/goal complete`, `/goal clear`, or `/goal set` while a run
    is in flight signals SIGINT alongside sending the message, so the
    prior run aborts instead of finishing the old work first. `/goal
show` is read-only and does not interrupt.
  - **Budget-limited stop message**: when the cap is hit mid-run, the
    agent posts a synthetic reply explaining what happened and
    suggesting a larger budget to resume.

  ## Plumbing
  - `entity-schema.ts` — new `ManifestGoalEntryValue` (objective,
    status, tokenBudget, tokensUsed, createdAt, updatedAt) added to the
    manifest discriminated union.
  - `goal-api.ts` (new) — `setGoal` / `clearGoal` / `getGoal` /
    `markGoalComplete` / `updateGoalUsage`. All goal mutations share a
    single ordered write channel (direct `writeEvent` upserts, live for
    the UI) plus an in-wake read-your-writes cache, so a mutation firing
    mid-run can never snapshot — and replay — a stale `tokensUsed` over
    a fresher one. `updateGoalUsage` additionally never decreases the
    counter.
  - `goal-command.ts` (new) — `/goal` parser (`--tokens N|50k|1.2m|
unlimited`, `--unlimited` flag, subcommand aliases `done`/`status`)
    and dispatcher.
  - `tools/goal-tools.ts` (new) — `createMarkGoalCompleteTool` exposes
    the completion signal to the LLM.
  - `outbound-bridge.ts` — new optional `OutboundBridgeHooks.onStepEnd`
    callback, threaded through `pi-adapter` and the `AgentConfig` passed
    to `useAgent`.
  - `context-factory.ts` — `AgentHandle.run` now accepts an optional
    `abortSignal` and combines it with the runtime's `runSignal`. New
    `ctx.replyText(text)` writes a complete runs + texts + textDeltas
    sequence so synthetic replies render in the chat. New goal-related
    methods exposed on `HandlerContext`.
  - `horton.ts` — `tryHandleSlashCommand` intercepts `/goal *` before
    the LLM; `/goal set` enqueues a one-shot kickoff so the agent starts
    immediately; `assistantHandler` wires the budget-enforcing
    `onStepEnd`, aborts on overflow, and posts the explanation reply.
  - `agents-server-ui` — new `GoalBanner` component above the timeline
    (objective + budget bar + status badge). `MessageInput` aborts the
    active run when a state-changing `/goal` command is submitted.
    `EntityTimeline` / `EntityContextDrawer` handle the new `goal`
    manifest kind.

- 0b26edf: Bring session sharing to mobile (desktop `ShareEntityDialog`
parity, mobile-first UX):
- **Share session screen.** A modal route opened from the session menu's
new **Share** entry. It exposes a link pill (abbreviated session web URL
— one tap opens the native OS share sheet, which includes Copy), a
"People with access" list with a pinned Owner row, a Google-Drive-style
"General access" section for the workspace-wide _All users_ grant, and a
search-first "Add people" section. Roles (View / Chat / Manage, same
permission sets and glyphs as desktop) commit per row through a
bottom-sheet picker with a destructive _Remove access_ action — no
deferred Grant/Update button. The grant list comes from the
manage-protected REST `GET /grants` endpoint (the synced
effective-permissions shape is scoped to the current principal, so it
can't list other people's access); non-managers still get the link
actions and see a manage-required message below.
- **Copy session id.** The session menu's status header and the
long-press row sheet now render the id with a tap-to-copy affordance
(copy→check icon swap, mirroring the desktop entity header), via a new
`expo-clipboard` dependency.
- **Session web links.** `sessionWebUrl()` builds
`{serverUrl}/__agent_ui/#/entity/{id}` directly — targeting the web UI
path rather than the server root, whose absolute-path redirect would
drop a Cloud `/t/<service-id>/v1` tenant prefix.

The desktop dialog's `userDisplay()`/`initials()` helpers move into
`agents-server-ui`'s `lib/userDisplay.ts` so mobile deep-imports them
instead of duplicating. Grant-diffing, removal, and access-model
grouping logic is ported into a pure, unit-tested `entityGrants` module.
No server API changes.

- 8bc630a: Add generic externally-writable custom collections for agent
entity state: collections opt in via `externallyWritable`, writes go
through an authenticated schema-validated endpoint that stamps the
principal into a read-only `_principal` column, and
`createEntityTimelineQuery` can project them into the timeline via
`customSources`. Comments are reimplemented as one such collection,
gated per agent type through a reserved `comments/v1` contract that the
UI keys its comment affordances on. External writes are restricted to a
per-collection operations allowlist (insert-only by default), and
comments are insert-only.
- 8b1d39f: Hide the per-response token-usage label when the combined
input + output
count falls below a threshold (`SHOW_USAGE_THRESHOLD`, currently 1000).
Tiny tool-only steps and one-line replies no longer clutter the meta row
with noise like `47 ↑ 12 ↓`; the threshold lives in a single constant so
  it's easy to tune.
- c1f3aac: Show only uncached input tokens in the per-response token
usage label.

  The input side previously summed `input + cacheRead + cacheWrite`, so
  on warm-cache turns the meta row re-counted the entire conversation on
  every step and ballooned into a cumulative number that said nothing
  about the work the response actually did. The adapter now surfaces the
  uncached side only — fresh prompt tokens plus cache writes, with
  prompt-cache reads excluded. (`cacheWrite` is counted because
  cache-enabled providers report newly appended prompt tokens there,
  with `input` collapsing to ~0.)

  Steps recorded before this change keep their stored cache-inclusive
  totals — both step fields are optional and the display just sums
  what's persisted, so no migration is needed.

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## @electric-ax/example-agents-chat-starter@0.1.9

### Patch Changes

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## @electric-ax/example-agents-walkthrough@0.1.6

### Patch Changes

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## @electric-ax/example-deep-survey@0.1.25

### Patch Changes

- Updated dependencies [708c946]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-runtime@0.4.0
## @electric-ax/agents-desktop@0.1.18

### Patch Changes

- c48c1a8: Stream model reasoning / extended-thinking content into the
UI. While
  the model is "thinking" (Anthropic extended thinking, DeepSeek-R1
  reasoning, Moonshot K2, OpenAI Responses summaries) the agent response
  now shows the live reasoning text faded above the answer, with the
  existing `Thinking` shimmer heading and an elapsed-time ticker. Once
  the reasoning settles it collapses to `▸ Thought for 12s` — click to
  expand. Multiple reasoning rows per run are rendered independently in
  order, so tool-using turns show each step's reasoning separately.

  Implementation:
  - **Schema** — `reasoning` row gains `run_id`, `encrypted` (Anthropic
    redacted-thinking opaque payload, must round-trip back to the model
    verbatim), and `summary_title` (extracted at write time for
    providers that emit a bolded heading). New `reasoningDeltas`
    collection mirrors `textDeltas` for streamed content.
  - **Bridge** — `OutboundBridge` gains `onReasoningStart` /
    `onReasoningDelta` / `onReasoningEnd`, parallel to the text path.
  - **Adapter** — `pi-adapter.ts` routes pi-ai's `thinking_start` /
    `thinking_delta` / `thinking_end` events to the bridge, parses the
    `**Title**\n\n<body>` heading (OpenAI Responses only) once at
    `thinking_end` so the UI doesn't re-parse on every render.
  - **Timeline** — `EntityTimelineRunRow` gains a live
    `reasoning: Collection<EntityTimelineReasoningItem>` with content
    built from a delta-join, mirroring `EntityTimelineTextItem`.
  - **UI** — New `<ReasoningSection>` component renders above the
    answer in `AgentResponseLive`. Live shows faded markdown via
    `Streamdown` with `ThinkingIndicator` heading + summary title +
    elapsed-time ticker. Settled collapses to `Thought for Ns` with
    click-to-expand. Redacted Anthropic blocks render a single muted
    line — content is opaque, but the encrypted payload is still
    persisted server-side so the model gets it back next turn.

  Providers without reasoning emit nothing → no reasoning section
  rendered. Historical responses recorded before this PR have no
  closure cue, same as today.

  Anthropic extended thinking is now always-on for reasoning-capable
  models: `reasoningEffort: auto` maps to the minimal budget
  (1024 tokens), matching the OpenAI branch where `auto` already
  defaulted to `minimal`. Explicit `low`/`medium`/`high` scale the
  budget as before.
## @electric-ax/agents-mobile@0.0.16

### Patch Changes

- 0b26edf: Bring session sharing to mobile (desktop `ShareEntityDialog`
parity, mobile-first UX):
- **Share session screen.** A modal route opened from the session menu's
new **Share** entry. It exposes a link pill (abbreviated session web URL
— one tap opens the native OS share sheet, which includes Copy), a
"People with access" list with a pinned Owner row, a Google-Drive-style
"General access" section for the workspace-wide _All users_ grant, and a
search-first "Add people" section. Roles (View / Chat / Manage, same
permission sets and glyphs as desktop) commit per row through a
bottom-sheet picker with a destructive _Remove access_ action — no
deferred Grant/Update button. The grant list comes from the
manage-protected REST `GET /grants` endpoint (the synced
effective-permissions shape is scoped to the current principal, so it
can't list other people's access); non-managers still get the link
actions and see a manage-required message below.
- **Copy session id.** The session menu's status header and the
long-press row sheet now render the id with a tap-to-copy affordance
(copy→check icon swap, mirroring the desktop entity header), via a new
`expo-clipboard` dependency.
- **Session web links.** `sessionWebUrl()` builds
`{serverUrl}/__agent_ui/#/entity/{id}` directly — targeting the web UI
path rather than the server root, whose absolute-path redirect would
drop a Cloud `/t/<service-id>/v1` tenant prefix.

The desktop dialog's `userDisplay()`/`initials()` helpers move into
`agents-server-ui`'s `lib/userDisplay.ts` so mobile deep-imports them
instead of duplicating. Grant-diffing, removal, and access-model
grouping logic is ported into a pure, unit-tested `entityGrants` module.
No server API changes.

- Updated dependencies [708c946]
- Updated dependencies [0b26edf]
- Updated dependencies [8bc630a]
- Updated dependencies [c48c1a8]
- Updated dependencies [8b1d39f]
- Updated dependencies [c1f3aac]
  - @electric-ax/agents-server-ui@0.5.0
  - @electric-ax/agents-runtime@0.4.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant