Commit Graph
637 Commits
Author SHA1 Message Date
can1357 19c0afcc0d feat: implemented external thinking flags and transport reasoning controls
- Added the `--external-thinking` CLI flag alongside model capability checks to gate external thinking tool availability.
- Updated Anthropic and Google transports to honor `forceReasoningOff` for native thinking-off controls.
- Renamed the `thoughts` property and parameter to `notes` across think fixtures, tools, and tests.
- Updated system prompt instructions and test suites to verify transport-specific thinking and tool activation.
2026-08-12 02:23:17 +02:00
can1357 10fd42289c feat: introduced external thinking support and private scratchpad think tool
- Added support for external thinking and forced reasoning disablement across AI provider options and request transformers.
- Implemented the private scratchpad think tool along with its renderer, system prompt rules, and schema configuration.
- Updated agent session management and SDK tools to support dynamic runtime activation of the think tool via the externalThinking setting.
- Added comprehensive unit tests covering reasoning fallbacks, tool activation, and rendering behavior.
2026-08-11 20:39:57 +02:00
Duncan Ogilvie 4d5ebd23f9 fix(mcp): replace deferred tool placeholders 2026-08-10 02:17:31 +02:00
Duncan Ogilvie 158a70ad54 fix(extensions): preserve MCP ownership on refresh 2026-08-10 02:09:23 +02:00
Duncan Ogilvie 77916b6c99 fix(extensions): restore activation rollback context 2026-08-10 01:54:36 +02:00
Duncan Ogilvie d1f73de44c fix(extensions): serialize registry mutations 2026-08-10 01:17:23 +02:00
Duncan Ogilvie 36ed07378c fix(extensions): bound detached tool activation 2026-08-10 01:04:02 +02:00
Duncan Ogilvie 4d0c346f87 fix(extensions): abort timed-out tool activations 2026-08-10 00:54:42 +02:00
Duncan Ogilvie 0abb4a9529 fix(extensions): preserve late tool invariants 2026-08-09 23:51:39 +02:00
Duncan Ogilvie 033c7a725e fix(extensions): preserve restricted tool isolation 2026-08-09 23:39:55 +02:00
Duncan Ogilvie 05f17fa76f fix(extensions): make lifecycle registration atomic 2026-08-09 22:07:46 +02:00
Duncan Ogilvie fe1a615463 fix(extensions): reconcile lifecycle replacements 2026-08-09 21:44:45 +02:00
Duncan Ogilvie f544ddc6f6 fix(extensions): settle failed lifecycle registrations 2026-08-09 21:19:31 +02:00
Duncan Ogilvie 0fd55c3dce fix(extensions): type late MCP deduplication 2026-08-09 16:08:03 +02:00
Duncan Ogilvie 07c7fe0938 fix(extensions): stabilize late MCP collisions 2026-08-09 14:39:32 +02:00
Duncan Ogilvie 1592ca7a1d fix(extensions): preserve late tool activation 2026-08-09 14:13:57 +02:00
Duncan Ogilvie 19b428b757 fix(extensions): register lifecycle tools 2026-08-09 13:44:39 +02:00
can1357 68dece477f Merge PR #7772: fix(session): handle subscription-cap retry exhaustion (@roboomp) 2026-08-07 13:37:54 +02:00
can1357 35ab3ece48 refactor(secrets): extracted buildSecretObfuscator from sdk session setup
Moved the obfuscator assembly (secrets.yml + env entries + built-in
credential patterns, placeholder-key minting rules, redaction-only
fallback) from createAgentSessionScoped into the secrets module so other
entrypoints can build the same obfuscator.
2026-08-07 05:59:58 +02:00
roboomp f6c5a43a1f fix(session): handled subscription-cap retry exhaustion
- Classified subscription and plan rate caps as credential-rotatable usage limits while preserving transient per-minute throttles.

- Applied reason-specific backoff to transient rate limits and collapsed exhausted retry attempts behind one budget-labeled terminal error.

- Covered classification, delay selection, persisted transcript aggregation, and retry event propagation.

Fixes #7767
2026-08-06 01:31:22 +00:00
Brent db97103c32 fix(coding-agent): complete usage-aware fallback integration 2026-08-03 16:34:35 +00:00
Christian Stewart 302148523f fix(hub): wake owners when supervised processes exit
Publish terminal daemon completions to the session that started the
process so idle agents can resume without polling hub status.

Persist every unacknowledged generation with a stable completion ID and
immutable snapshot. Replay the collection after reconnect or broker
recovery, and clear each event only after the owning client acknowledges
it.

Signed-off-by: Christian Stewart <christian@aperture.us>
2026-08-03 01:31:39 -07:00
can1357 a58584ff3c feat: implemented shared serialization utilities and standardized inventories
- Added shared Python call and literal serialization utilities with multiline verbatim support.
- Standardized tool inventories to format as an OpenAI-Harmony functions namespace using TypeScript declarations.
- Updated tool normalization and rendering functions to accept options objects and default to Python-syntax examples.
- Refactored Gemini dialect rendering to leverage shared serialization functions directly.
2026-08-03 05:06:49 +02:00
can1357 cc2265f681 feat: use simple form replace when replace is the edit mode 2026-08-03 01:00:51 +02:00
can1357 10625d2e9a Merge PR #7376: feat(coding-agent): add OpenAI service tier override (@paralin)
# Conflicts:
#	packages/coding-agent/src/commands/launch.ts
2026-08-02 21:22:41 +02:00
can1357 160bdd05c3 fix(agent): keep session scout notices live 2026-08-02 20:52:57 +02:00
can1357 3de8c3a476 Merge PR #7344: fix(agent): stop leaking scout into prompts when it is disabled (@szavadsky)
# Conflicts:
#	packages/coding-agent/src/prompts/system/system-prompt.md
2026-08-02 20:52:56 +02:00
can1357 92b50faacc feat(coding-agent/lsp): implemented lsp multiplexer server and shared daemon lifecycle
- Added an LSP multiplexer server, protocol definitions, and daemon lifecycle management to route traffic across sessions.
- Introduced `lsp.shared` settings configuration and SDK session creation support for shared language servers.
- Migrated shared daemon ensure helpers into a central launch module with updated import references.
- Added comprehensive unit tests and fake LSP server fixtures covering muxing, sharing, caching, and restarts.
2026-08-02 18:15:22 +02:00
Christian Stewart 9d69db481a feat(coding-agent): add OpenAI service tier override
The OpenAI service tier could only be chosen through the `tier.openai`
setting, or for a resumed session through whatever tier that session
recorded. Wanting flex or priority for a single run meant editing
settings and putting them back afterwards, while `bench` already took a
`--service-tier` flag that the session CLI did not offer.

Add `--service-tier` to the root command. The flag wins over the
configured setting and over a resumed session's recorded tier, leaves
the Anthropic and Google entries untouched, and records the resulting
map so a later resume keeps it. `none` removes the OpenAI entry, which
omits `service_tier` from the request.

Signed-off-by: Christian Stewart <christian@aperture.us>
2026-08-02 05:07:33 -07:00
Slava Zavadsky 9885ee34fc fix(agent): stop leaking scout into prompts when it is disabled
Hard-coded 'scout' references reached the model even when the scout
agent was disabled via task.disabledAgents or absent from the session
spawn list. Gate every such reference on scout actually being spawnable:
the task tool description, the delegation gates, the plan-mode and
workflowz notices, the glob/grep/ast-grep guidance, and the task
specialization advisory. Prompt shape is otherwise unchanged; only
erroneous references to the unavailable subagent are dropped.

Closes #7313
2026-08-01 23:50:33 -04:00
can1357 03e54555f9 Merge PR #7065: fix(xdg): fix files and folder for xdg-maintained (@Parsifa1) 2026-08-01 20:39:29 +02:00
can1357 386385f18b fix(coding-agent): skipped xd:// mounting when write tool is not granted
- Prevent xdev state allocation and tool mounting in sessions lacking a write tool.
- Expose discoverable tools top-level instead of auto-granting write transports.
2026-08-01 20:39:08 +02:00
can1357 cc884eea9b Merge PR #7252: fix(coding-agent): keep hub-killed subagent from resurrecting as parked (@roboomp) 2026-08-01 20:14:40 +02:00
can1357 237aa46faf fix(coding-agent): refreshed repo context after cwd changes 2026-08-01 20:13:38 +02:00
can1357 93a9f0d991 Merge PR #7262: fix(coding-agent): refresh context files on plugin reload (@roboomp) 2026-08-01 20:13:38 +02:00
Sunil Srivatsa f22c0edbfa fix(coding-agent): scope SDK extension packages 2026-08-01 13:50:53 -04:00
Sunil Srivatsa 8a7edb3f3d fix(coding-agent): preserve explicit extensions in isolation 2026-08-01 12:32:19 -04:00
roboomp 55115f4bfd fix(coding-agent): refresh advisor context prompt on reload
Rebuilt advisor runtimes with the rediscovered context files so advisor turns stop evaluating against stale AGENTS.md instructions after /reload-plugins.

Fixes #7258
2026-08-01 11:46:55 +00:00
roboomp 08c80f7da0 fix(coding-agent): scope context rediscovery to session settings
Threaded the session's disabledExtensions into context-file rediscovery so a concurrently-created session's global settings cannot toggle another session's context entries.

Fixes #7258
2026-08-01 11:36:34 +00:00
roboomp 2b268b4d2c fix(coding-agent): refreshed context files on plugin reload
Rediscovered context files from the active session cwd whenever plugin prompt sources refresh, while preserving explicitly preloaded SDK context.

Covered edited and disabled context files in the current system prompt.

Fixes #7258
2026-08-01 11:27:03 +00:00
roboomp 57732e9dcd fix(coding-agent): detach hard-aborted refs so ensureLive can't route into a dead session
Preserving aborted refs on dispose exposed a latent invariant break: the
executor's hard-abort path (finalizeSubagentLifecycle) set status `aborted`
and disposed the session without detaching it. With the ref now retained, it
kept a dangling pointer to the disposed session, and ensureLive returns any
non-null ref.session before its revivability check — so hub focus / transcript
chat could route into a dead session.

- finalizeSubagentLifecycle: detach the session before disposing on the
  terminal hard-abort path, upholding the AgentRef invariant (session === null
  when aborted).
- release(tombstone): detach before dispose too (capture the live session
  first), same invariant.
- unregisterUnlessParked: preserve `aborted` refs only when already detached;
  an aborted ref still holding a live session is a bug and is unregistered
  rather than kept reachable.
- Regression test now asserts ensureLive rejects a tombstoned id as terminal.

Fixes #7250
2026-08-01 09:42:41 +00:00
roboomp d350dd8f84 fix(coding-agent): preserve aborted tombstone across live-session dispose
A live-session hub kill did not stick: release(tombstone) awaited the
wrapped session dispose first, and createAgentSession's unregisterUnlessParked
removed any non-parked ref, so the subsequent detach/setStatus no-oped and the
ref was gone — leaving the reopen resurrection for idle/running agents.

- release(tombstone) now marks the ref `aborted` BEFORE disposing, so the
  dispose guard preserves it; the session is detached afterward.
- unregisterUnlessParked now also spares terminal `aborted` refs (matching
  the documented "hard-killed, terminal" retention and finalizeSubagentLifecycle).
- Regression test now uses a session stub that mirrors the real wrapped
  dispose (unregister unless parked/aborted), so it fails if the tombstone is
  set after dispose.

Fixes #7250
2026-08-01 09:34:43 +00:00
Parsifa1 ea437745a3 fix(xdg): move secret-placeholder.key, marketplaces.json, and run/ out of config root
These four paths bypassed DirResolver's XDG-aware rootSubdir/agentSubdir
hooks, resolving directly against getConfigRootDir()/getAgentDir() and
ignoring XDG state/data layout. Add XDG-aware path helpers in dirs.ts
and route all four through them:

- secret-placeholder.key → $XDG_STATE_HOME/omp/ (state, agent flattened)
- marketplaces.json      → $XDG_DATA_HOME/omp/  (data)
- run/daemons/<hash>/    → $XDG_STATE_HOME/omp/run/ (state)
- run/provider-inflight/ → $XDG_STATE_HOME/omp/run/ (state)

omp config init-xdg migrates secret-placeholder.key and marketplaces.json
from their legacy locations; run/ is ephemeral and rebuilds on restart.
2026-08-01 06:40:48 +00:00
can1357 f76ce86966 Merge PR #6840: feat(extensions): add ctx.invokeTool for native built-in delegation (@psyrendust) 2026-07-31 20:17:32 +02:00
can1357 ccc9b900cf fix(eval): forked subagent kernel resets away from shared sessions
- Subagents inherit the parent's eval session id, so a child's
  reset: true destroyed the co-owned kernel and every sibling's
  interpreter state mid-session.
- resolveOwnerScopedSessionKey now routes a reset from a non-exclusive
  owner onto a deterministic per-owner fork key: the requester gets a
  fresh private kernel, co-owners keep the shared one, and the fork
  stays sticky for that owner until its teardown reaps it.
- Applied across Python, JavaScript, Ruby, and Julia executors; JS
  contexts gained an owner registry plus disposeVmContextsByOwner,
  wired into EvalRunner.disposeKernels and SDK session teardown.
- Covered by pure key-resolution contracts and an end-to-end JS test:
  co-owner reset forks, shared state survives, fork is sticky, and
  per-owner dispose reaps only the fork.
2026-07-31 20:13:23 +02:00
can1357 371a2349aa Merge PR #7067: fix(secrets): exact-match edits failing on files with credential-shaped tokens (@iacore) 2026-07-31 19:27:35 +02:00
iacore fcf6d65140 fix(coding-agent): resolve the secret placeholder key lazily for builtin credential entries
Appending builtinCredentialSecretEntries() unconditionally made every
secrets.enabled session carry a regex obfuscate entry, so
secretEntriesNeedPlaceholderKey was always true and startup always
created secret-placeholder.key — nullifying the replace-only/no-secret
key-avoidance path and failing headless runs on an unwritable config
root for a feature they never use.

Only configured entries now force startup key creation. The built-in
credential pattern matches dynamically, so SecretObfuscator accepts a
key provider resolved once on the first actual credential match, via
the new getSecretPlaceholderKeySync (never throws: degrades to a
process-ephemeral key with a warning when the key file is unwritable).

Also moves both CHANGELOG entries from the released 17.1.7 sections to
[Unreleased].
2026-07-31 13:38:09 +08:00
Larry Gordon a50bcd5fed fix(extensions): wire invokeTool to the extension path as same-tool delegation
Addresses PR review. The initial version put invokeTool on AgentToolContext
via ToolContextStore, but the extension execute path (RegisteredToolAdapter)
builds its own ExtensionContext and never saw it, so the documented
registerTool wrapper use case did not work. It also allowed arbitrary
cross-tool targets (bypassing the target's approval policy), used a
session-global recursion counter that tripped on concurrent independent
delegations, and missed discoverable built-ins that xdev partitioning moves
out of the tool array.

Rework:
- Move invokeTool onto ExtensionContext, and bind it in RegisteredToolAdapter
  to the tool's own name, so a re-registered built-in actually receives it.
- Make delegation same-tool only: invokeTool takes just (params, options) and
  runs the native built-in of the caller's own name. It cannot reach an
  arbitrary target, so it cannot escalate past the approval already granted
  for the call, and the native call is not re-gated.
- Track recursion depth per call chain (threaded through invokeNativeTool and
  createContext) instead of session-global state, so concurrent delegations
  do not interfere.
- Seed the native resolver from the xdev registry when present (it retains
  discoverable built-ins like browser), else the built-in registry.

Replaces the ToolContextStore-level unit test with an end-to-end test that
registers a built-in wrapper through the extension/session path and asserts
the native tool runs the wrapper's delegated input.
2026-07-30 10:35:12 -07:00
Larry Gordon 6acf957dd8 feat(extensions): add ctx.invokeTool for native built-in delegation
A tool's execute context now carries invokeTool(name, params, options?),
which runs the native built-in of `name` and returns its result. A tool
that re-registers a built-in (e.g. wrapping write to add logging or a
policy check) can delegate to the original instead of reimplementing it.

The native implementation is captured before extension re-registration
replaces the registry entry and before the ExtensionToolWrapper pass, so
invokeTool reaches the unwrapped native execute: it does not recurse into
the caller's own wrapper, and it inherits the caller's already-granted
approval rather than re-running the gate. Delegation depth is guarded
against accidental self-recursion, and it resolves to undefined when no
native tool of that name exists.

Wired through ToolContextStore with a lazy native-tool resolver, so it is
coding-agent-only (no agent-loop change) and sees the fully-assembled
built-in set at call time.
2026-07-30 10:35:09 -07:00
iacore 54008bce99 fix(secrets): round-tripped unconfigured credential-shaped tokens through reversible obfuscation
With secrets.enabled (Hide Secrets), a credential-shaped token not present
in secrets.yml or the environment fell through to pi-ai's irreversible
[*_token_redacted] rewrite in transform-messages. The model echoed that
placeholder into edit-tool old_text, which could never match the real
bytes on disk, breaking exact-match edits of any file containing such a
token.

Route the same token shapes (SENSITIVE_TOKEN_RE, now exported from
pi-ai) through the SecretObfuscator as a built-in obfuscate-mode regex
entry: the provider sees reversible keyed placeholders, and
deobfuscateToolArguments restores the real bytes before tool execution.
Hide Secrets' contract is unchanged — credential bytes still never
reach the provider; pi-ai's redaction stays as the backstop for hosts
without an obfuscator.

Fixes #6968
2026-07-30 15:14:00 +08:00