Commit Graph
158 Commits
Author SHA1 Message Date
can1357 2155b8e020 perf: replaced WeakMap caches with symbol-keyed properties
- Migrated per-object caches (chat/tool starts, model fingerprints, validation contexts, provider indexes, render IDs) from WeakMap to Symbol-keyed properties on the objects themselves.
- Rewrote SSE debug tee as a single-pass inline parser, eliminating the body.tee() + readSseEvents re-parse pipeline.
- Refactored MockModel from a factory function + external WeakMap state into a self-contained class.
- Added FIFO memoization caches for heuristic candidate expansion and namespace suffix lookups.
2026-05-17 03:47:45 +02:00
can1357 39f34ada70 feat: added pure-JS sanitizeText
- Migrated sanitizeText from pi-natives to pi-utils as a pure-JS implementation, removing the native dependency across all call sites.
2026-05-16 20:12:26 +02:00
can1357 32453aaff0 feat(agent): added AgentTelemetry across compaction and branch-summary
- Added optional AgentTelemetry to summary, handoff, branch-summary, and compact option types.
- Replaced one-shot `completeSimple` usage with `instrumentedCompleteSimple` across compaction, summary, and branch-summary calls and passed `oneshotKind`.
- Added `PiGenAIAttr.OneshotKind`, `InstrumentedChatSpanOptions`, and response-header forwarding in telemetry span lifecycle.
- Added `resolveTelemetry` propagation in coding-agent session and inspect-image paths to pass request-scoped telemetry.
- Added compaction telemetry test harness and span assertions for success, no-telemetry, and error cases.
2026-05-16 18:03:07 +02:00
can1357 feb6c74c84 feat(agent): implemented header-based gateway detection in agent telemetry
- Added MockResponse metadata fields and invoked onResponse pre-stream with lowercased headers, status fallback, and requestId.
- Wrapped request onResponse in agent-loop, captured response headers, and forwarded them with baseUrl to finish/fail span handling.
- Added detectGatewayFromHeaders export and pi.gen_ai.gateway.* span attributes via header-based gateway detection.
- Extended telemetry event/span payloads with responseHeaders and validated detection-priority and onResponse forwarding in tests.
2026-05-15 23:46:23 +02:00
can1357 8b1364d4c2 feat(coding-agent): implemented one-shot generateHandoff in coding-agent
- Replaced event-driven handoff with one-shot `generateHandoff(...)` via `completeSimple`.
- Added cancellable `/handoff` command handling with a loader and Escape-to-abort flow.
- Removed legacy `compaction/handoff.ts` exports and added `generateHandoff(messages, model, apiKey, options)`.
- Fixed pre-cancelled handoff behavior to return `Handoff cancelled` and propagate abort signals.
- Updated handoff tests/mocks to assert `generateHandoff` invocation details and `AgentSession.handoff()` options.
2026-05-15 18:49:53 +02:00
can1357 e1aaf78874 refactor(compaction): moved compaction APIs to @oh-my-pi/pi-agent-core
- Relocated compaction, branch-summarization, pruning, and utils from coding-agent to packages/agent/src/compaction.
- Moved OpenAI remote compaction helpers from packages/ai to the new compaction module.
- Added handoff.ts with extractHandoffDocument, createHandoffContext, and renderHandoffPrompt helpers.
- Exposed new entries.ts with standalone SessionEntry types so coding-agent no longer owns them.
2026-05-15 18:31:12 +02:00
can1357 3c6d2346ad fix(agent): corrected run telemetry counters, cached input tokens, and span hook safety
- Skipped tool double-count: runTool's interrupt early-return no longer records the skipped tool inline; the post-batch tail sweep now handles accounting once per record so a single queued steering cancellation no longer logs N+1 skips.
- Aborted/errored assistant messages with embedded tool calls now record a collector orphan with status 'aborted' or 'error', so coverage.toolsInvoked and tools counters reflect them.
- run-collector chat record now stores inputTokens = input + cacheRead + cacheWrite, matching ChatUsageEvent and the public AgentRunSummary contract.
- onSpanStart and onSpanEnd hook invocations are wrapped in safeOnSpanStart/safeOnSpanEnd; thrown user callbacks surface via onTelemetryWarning (on_span_start_failed / on_span_end_failed) instead of leaking through finishChatSpan/finishExecuteToolSpan/finishInvokeAgentSpan/recordHandoff.
- summarizeTelemetryValue gained a depth+ancestor guard for arrays (matching the existing object recursion guard); cycles return '[Circular]' and over-depth returns the bounded {kind:'array',length} sentinel.
2026-05-15 17:48:02 +02:00
can1357 2867e1f4e3 feat(deps): added pi.zod exports and removed TypeBox package exports
- Added canonical `pi.zod` schema API exports and removed TypeBox package exports/imports.
- Migrated Tool schema typing from TypeBox to shared `TSchema`/Zod flow with legacy TypeBox compatibility.
- Updated AI provider adapters and MCP/agent builders to convert tool params through `toolWireSchema()`.
- Reworked schema validation from AJV to Zod-safe parsing with `fromTypeBox`, `toolWireSchema`, and meta schema checks.
2026-05-15 14:46:54 +02:00
can1357 80103f383d feat(agent): added OpenAI/PiGenAI OTEL constants and run summaries
- Swapped deprecated telemetry keys for OpenAIAttr/PiGenAIAttr constants, including tool intent keys.
- Normalized provider names via mapProviderNameToOtel and emitted OTEL pi.gen_ai fields on chat/request/response spans.
- Revised usage and aggregate telemetry to include cache-token totals plus failed and skipped step counts in run summaries.
- Updated OTEL and run-summary tests to use z.object schemas and renamed GenAI/PiGenAI attribute assertions.
2026-05-15 14:46:54 +02:00
can1357 7cb7c8313d feat(agent): added onChatUsage hook for chat usage telemetry
- Added `onChatUsage` telemetry configuration and `ChatUsageEvent` payload so each chat step with usage now emits a usage event without requiring a cost estimator.
- Updated chat span completion paths to await async chat usage emission, and emitted `on_chat_usage_failed` warnings when callbacks or hooks reject.
- Awaited `finishChatSpan` in assistant-stream completion and abort flows so telemetry callbacks run before returning from chat completion.
2026-05-15 14:46:54 +02:00
can1357 d1412eac98 feat(agent): added generic telemetry extension hooks
- Added resolveAttributes, normalizeProvider, normalizeAgentName, onCostDelta, onTelemetryWarning, and contentSerializer hooks to AgentTelemetryConfig.
- Added "summary" capture mode emitting bounded dashboard-friendly span attributes without full payloads.
- Added recordManualChatTelemetry for instrumenting non-loop model calls.
- Introduced TelemetryAttributeContext as a base for TelemetryHookContext.
2026-05-15 14:46:54 +02:00
can1357 716b6c8234 feat(agent): added run-end tracking to emit telemetry.onRunEnd only once
- Added `runEnded`/`markRunEnded()` tracking and only fired `telemetry.onRunEnd` once per run.
- Added `agent_end` telemetry support for per-run `telemetry`/`coverage` and `agentLoopDetailed()` with `detailed()`.
- Added `aggregateAgentRunSummaries`/`aggregateAgentRunCoverage` and mapped `execute_tool` outcomes to `blocked` and `skipped`.
- Updated `finishInvokeAgentSpan` to derive failure `error.type`/status text from run status and exception state.
- Added run-summary test helpers covering `agent_end`, aggregation, and `onRunEnd` warning/compatibility scenarios.
2026-05-15 14:46:54 +02:00
can1357 14cc9d6bdc feat(agent): added run-collector exports and agent loop detailed spans
- Added `run-collector` exports, `agentLoopDetailed`, and `agentLoopContinueDetailed` APIs.
- Expanded `agent_end` event payloads with optional `telemetry` and `coverage` fields.
- Added `AgentRunCollector` span tracking with typed chat/tool records and summary/coverage builders.
- Fixed telemetry totals to include interrupted, skipped, and failed tool/chat paths via `failChatSpan` and skip recording.
2026-05-15 14:46:54 +02:00
can1357 e4e2389f83 refactor(agent): converted GenAI telemetry attributes to a const enum
- Replaced `GenAIAttr` with an `export const enum` in telemetry while preserving all GenAI attribute constants.
- Updated the OTEL stream test fixture to emit an `error` event with an `error` payload instead of a `done` event.
- Added runSubprocess telemetry propagation tests for inheriting parent telemetry and handling missing parent telemetry.
2026-05-15 14:46:54 +02:00
can1357 4679789cf1 feat(agent): added OTEL spans for agent invoke/chat/tool flows
- Added opt-in telemetry configuration to Agent and session APIs, including Agent#setTelemetry mutator.
- Implemented OpenTelemetry spans for invoke_agent, chat, execute_tool, and handoff paths with metadata and step tracking.
- Added a telemetry helper module, OpenTelemetry request/usage types, and dependency wiring with no-op behavior when tracer SDK is absent.
- Added OTEL end-to-end tests and fixed coding-agent OutputSink realignment and artifact-link newline output issues.
2026-05-15 14:46:53 +02:00
Aaron Z 1942a8607b fix(agent): calculate costs in proxy stream path
The proxy server returns accurate raw token counts but omits pre-calculated
costs. Each direct provider normally calls calculateCost internally, but the
proxy path bypasses that entirely — leaving cost fields at their initialized
zero values.

Import calculateCost from @oh-my-pi/pi-ai/models and invoke it after assigning
usage in both "done" and "error" cases within processProxyEvent.
2026-05-15 17:07:33 +08:00
can1357 cf1e75cdc6 fix(agent): added type guard and array validation for LLM message handling
- Strengthened `defaultConvertToLlm` filtering with a `Message` type predicate.
- Added an `Array.isArray` guard before checking `partial.content` length for assistant partial messages.
2026-05-15 09:40:07 +02:00
can1357 c29fe28dbb feat(agent): add beforeToolCall and afterToolCall hooks
Mirrors the pi-mono API surface so apps can preflight tool execution
(block or mutate validated args) and post-process tool results
(override content/details/isError) without wrapping tools.

- `AgentLoopConfig.beforeToolCall` runs after argument validation. Return
  `{ block: true, reason }` to short-circuit with a tool-error result.
  Mutations to `context.args` are forwarded to `tool.execute` without
  revalidation, matching pi-mono semantics.
- `AgentLoopConfig.afterToolCall` runs after execution and before
  `tool_execution_end` / tool-result message emission. Returned fields
  override the executed result; omitted fields fall through. Hook
  exceptions surface as tool errors and do not abort the batch.
- `Agent` exposes both hooks as public, reassignable fields so extension
  reloads can swap implementations mid-session.

Compatibility: fully additive. Both hooks default to undefined and the
loop behaves identically when neither is set. The internal
`executeToolCalls` signature was collapsed to `(context, message,
signal, stream, config)` -- it is not exported, so this is not a public
API change. Pi-mono's `terminate` field on `AfterToolCallResult` is
omitted because our `AgentToolResult` has no batch-level early-stop
contract.
2026-05-15 09:16:44 +02:00
can1357 f1f6516056 refactor: reorganized exports and removed obsolete helper branches
- Removed export leakage by demoting many helper and const symbols to module-local scope.
- Renamed underscore-prefixed internals and cache fields, then updated related references and `satisfies never` checks.
- Deleted obsolete logic branches and helpers, including harmony-stream interruption flow and unused benchmark runtime helpers.
- Updated Biome config and manifests by broadening lint coverage and removing an unused `@napi-rs/cli` dev dependency.
- Adjusted tests and utilities to use renamed test helpers and remove redundant private test-only helpers/locals.
2026-05-14 04:36:19 +02:00
can1357 c562f4dc2a fix(coding-agent/eval): hardened eval parser against stray non-marker lines
- Updated parseEvalInput to verify begin-cell markers before dereferencing regex matches.
- Skipped stray non-marker lines between and after cells, preserving valid cells when model output is noisy.
- Added eval parse regression tests for stray content and trailing chatter, and kept abort-line handling explicit.
2026-05-12 09:41:06 +02:00
can1357 4623e7d3ea fix(coding-agent): marked streaming edit aggregates as errors when per-path edits fail
- Stored a failure counter during single-path edit execution and set isError on aggregate results when any entry edit failed.
- Set streaming-edit handling to always evaluate auto-generated-file checks, but only primed the file cache when edit.streamingAbort was enabled.
2026-05-12 04:44:38 +02:00
can1357 8b92ec937e feat: gpt-5 harmony errata fixes
- Replaced `===== ... =====` eval cell headers with `*** Begin ` / `*** End ` markers; legacy format remains renderable in HTML exports.
- Replaced hashline patch grammar with `*** Begin Patch` / `*** End Patch` envelope; old inputs without the envelope are still accepted.
- Extracted `sniffEvalLanguage` into a shared `sniff.ts` module reused by the parser and tool.
- Added `docs/ERRATA-GPT5-HARMONY.md` and `scripts/session-stats/harmony_backtest.py` documenting and backtesting the GPT-5 Harmony-header leak defect.
2026-05-10 19:52:44 +02:00
can1357 9f386dd6e5 feat(ai,coding-agent): raw SSE diagnostics + steady-state idle watchdog
Adds an opt-in onSseEvent callback across HTTP-streaming providers (Anthropic, OpenAI Responses/Completions, Azure OpenAI Responses, OpenAI Codex SSE, Google Gemini CLI, GitLab Duo, Kimi, Synthetic) so callers can inspect raw SSE frames without altering parsed output. Provider fetch wrapping only tees response bodies when an observer is wired; standalone packages/ai consumers without onSseEvent are not penalized.

Adds streamIdleTimeoutMs (env: PI_STREAM_IDLE_TIMEOUT_MS, with PI_OPENAI_STREAM_IDLE_TIMEOUT_MS as a backward-compatible alias). Anthropic now enforces a steady-state idle watchdog (default 120s) in addition to the first-event watchdog. OpenAI Responses, Azure Responses, and Codex (SSE + WebSocket) gain a semantic-progress predicate so response.in_progress-style keepalives no longer keep stalled tool calls alive forever.

Adds a coding-agent debug-panel raw SSE viewer backed by a per-session bounded buffer (1000 records / 512KB) that AgentSession populates unconditionally so users can post-hoc inspect a stuck stream from the TUI.
2026-05-10 04:53:41 +02:00
Miroslav Drbal fc70a45c46 fix(ai): stable metadata.user_id per session for Anthropic OAuth
Anthropic counts sessions by metadata.user_id. Without this fix, OMP
generated fresh random entropy on every API request, inflating the
session count and preventing backend attribution to the authenticated
account.

Changes:

packages/ai:
- resolveAnthropicMetadataUserId() now accepts JSON-format user_id
  matching real Claude Code's getAPIMetadata shape
  ({ session_id, account_uuid, ... }). Previously only the legacy
  cloaking format was accepted on OAuth, causing stable caller-supplied
  values to be silently discarded.
- AnthropicOAuthFlow.exchangeToken() and refreshAnthropicToken() now
  populate OAuthCredentials.{accountId, email} from the token response
  account block, removing the need for a separate /api/oauth/profile
  round-trip.
- AuthStorage.getOAuthAccountId(provider, sessionId) returns the OAuth
  accountId for the session-sticky credential, used to build
  account_uuid in metadata.user_id. Guards against misattribution for
  API-key, runtime-override, env-key, and fallback-resolver paths that
  do not record a session credential.

packages/agent:
- Agent.metadataForProvider(provider) resolves request metadata for
  the given provider via the installed resolver, or returns the static
  metadata value. The plain metadata getter now returns only the static
  value; provider-aware resolution is explicit.
- Agent.setMetadataResolver(fn) installs a (provider: string) resolver
  evaluated per LLM request in agent-loop, after getApiKey records the
  session-sticky credential, so account_uuid reflects the credential
  actually used.
- AgentLoopConfig.metadataResolver is called with config.model.provider
  after getApiKey, overriding the static metadata field.

packages/coding-agent:
- AgentSession.#syncAgentSessionId installs a metadata resolver that
  builds { user_id: JSON.stringify({ session_id, account_uuid? }) },
  matching the Anthropic session attribution format. account_uuid is
  only included for provider="anthropic" to avoid leaking the OAuth
  identity to third-party Anthropic-format-compatible providers.
- sessionId getter prefers providerSessionId when supplied via
  AgentSessionConfig so all API paths (getApiKey, direct calls,
  metadata resolver) share the same provider-facing session ID.
- prepareSimpleStreamOptions stamps session metadata on direct calls
  (runEphemeralTurn, compaction, branch summary, title generation) so
  they share the same session bucket as Agent.prompt requests.
- generateBranchSummary and generateSessionTitle accept a
  (provider: string) metadata resolver evaluated after their own
  getApiKey call for correct credential attribution.
2026-05-09 09:48:10 +02:00
can1357 9e8ad8148f feat: added hideThinkingSummary across stream, agent, session payloads
- Added hideThinkingSummary options across stream, agent, and session payload paths.
- Routed Coding-Agent hideThinkingBlock toggles to agent hideThinkingSummary during session updates.
- Updated OpenAI, Azure OpenAI, and Codex requests to omit reasoning.summary when hide/ summary is null.
- Reworked system-prompt preparation with per-step timeouts, fallback defaults, and step-level warnings.
2026-05-07 23:23:08 +02:00
can1357 1a2869444e fix(agent): coerced malformed tool results before downstream agent processing
- Added a boundary normalizer that validated tool output shape and replaced malformed responses with a fallback text-only result.
- Updated tool execution to coerce both streaming partial updates and final tool results through that normalizer.
- Set the tool call error state when a malformed result was detected by the coercer.
2026-05-07 04:36:40 +02:00
can1357 9672139228 feat: added shared readSseEvents utility for Anthropic SSE parsing
- Added `readSseEvents` and `ServerSentEvent` exports in utils for reusable SSE stream parsing.
- Replaced Anthropic's local SSE parser with shared `readSseEvents(response.body, signal)` decoding.
- Updated abort handling in agent stream loop to race an `ABORTED` sentinel with `responseIterator.next()`.
- Expanded stream tests for `readSseEvents` parsing of CRLF, comments, split UTF-8 chunks, and trailing events.
2026-05-07 00:08:06 +02:00
can1357 2f871b6d23 feat(coding-agent): added loadMode and summary to AgentTool discovery
- Added optional `loadMode` and `summary` fields to `AgentTool` and related type declarations.
- Added `loadMode` and `summary` metadata to built-in tool classes for discoverable/essential behavior.
- Replaced `BUILTIN_TOOL_METADATA` with per-tool fields in discovery code paths.
- Updated `search_tool_bm25` and discovery indexing to use each tool's `summary` text.
- Updated discovery tests to validate tool `loadMode` and summary completeness.
2026-05-06 19:14:39 +02:00
can1357 8c323666be feat: added ordered systemPrompt arrays and normalized context prompts
- Converted systemPrompt APIs and state types to ordered `string[]` across agent, AI, and coding-agent surfaces.
- Added `normalizeSystemPrompts` and applied it to context normalization before building provider request payloads.
- Updated AI providers to emit separate normalized prompt blocks/messages instead of a single merged system prompt.
- Removed dedicated `projectPrompt` state and remapped that context into system-context buckets in session, dump, and token accounting.
- Aligned tests and changelogs to pass and assert `systemPrompt` as arrays with ordered prompt semantics.
2026-05-04 15:20:26 +02:00
can1357 a60e492fba feat(agent): enabled dynamic reasoning override per model call
- Added an optional `getReasoning` callback to `AgentLoopConfig` to resolve reasoning effort dynamically for each LLM call.
- Updated the agent loop to resolve reasoning via `getReasoning` and use it in place of static `reasoning` when provided.
- Added a test confirming a run re-reads the thinking level between consecutive model calls when it changes mid-run.
2026-05-03 07:39:52 +02:00
Miroslav Drbal af7849f3ae fix(agent): handle unhandled rejection when getApiKey or runLoop throws
agentLoop/agentLoopContinue IIFEs were fire-and-forget: any error thrown
inside runLoop (e.g. missing API key via getApiKey callback) became an
unhandled rejection and left the EventStream permanently hung, so the
for-await consumer in Agent#runLoop never resumed its catch block.

- Add EventStream.fail(err): rejects all waiting consumers, stores the
  error so queue-draining consumers throw after the queue empties, and
  rejects finalResultPromise (guarded by a no-op .catch() to prevent a
  secondary unhandled rejection when nobody awaits result()).
- Wrap runLoop calls in both agentLoop and agentLoopContinue IIFEs with
  try/catch that routes errors into stream.fail(err), letting the
  existing Agent#runLoop catch block convert them to error assistant
  messages.
2026-05-02 10:41:09 +02:00
can1357 b51ca3f7ee fix(ai): corrected AI abort precedence and provider stream normalization
- Fixed abort-source handling so caller aborts always win and local reasons only attach to matching request signals.
- Fixed agent-loop streaming to race event reads against abort signals and emit an aborted assistant message.
- Fixed Anthropic request construction to honor thinkingEnabled=false and omit temperature/top_p/top_k for Opus non-thinking.
- Fixed OpenAI Codex request handling by normalizing response URLs, decoding non-string websocket frames, and cleaning handshake headers.
- Added regression tests for abort precedence, Anthropic alignment cases, and Codex stream/header normalization.
- Documented the cancellation and provider behavior fixes in package changelogs.
2026-05-02 01:06:53 +02:00
HabibPro1999andcan1357 0dc4aa36fd feat(ai): expose provider response metadata 2026-04-30 03:52:52 +02:00
can1357 37a8203f94 refactor(coding-agent): standardized tool intent handling via unified intent option
- Replaced `AgentTool` `nointent` and `deriveIntent` with a unified `intent` option that supports `omit`, `optional`, `require`, or a callback function.
- Updated agent tool schema injection and execution paths to inject `_i` as required/optional/omitted and to derive intent through the new `intent` callback.
- Aligned atom-edit tests with the updated default sed behavior (`g` now off by default and explicit `g: true` for global replacement).
2026-04-26 14:54:53 +02:00
can1357 18085ac704 feat(coding-agent): added optional tool intent derivation and opt-out support
- Added `nointent` and `deriveIntent` to `AgentTool`, and made intent-schema injection honor `PI_NO_INTENT` plus per-tool opt-outs.
- Updated tool execution and streaming UI handling to derive a fallback intent when `_i` is absent, without aborting on derivation failures.
- Marked several coding tools as `nointent` and added `deriveIntent` callbacks where needed, then relaxed prompt language to indicate intent is present on most tools.
2026-04-26 14:22:26 +02:00
can1357 2a3edbc39a fix(agent): switched intent field to _i and stripped intent from args
- Changed the intent marker from "i" to "_i" in the agent loop path.
- Updated intent extraction to always destructure out the intent key and return stripped arguments even when intent is not a string.
2026-04-26 04:09:05 +02:00
can1357 d0a3791ea6 fix(agent): changed intent tracing marker from _i to i
- Updated the agent loop intent marker constant to use `i` instead of `_i` for tracing fields.
- Updated intent tracing documentation to describe a generic string marker field and cleanup behavior.
- Adjusted related Anthropic and coding-agent tests to match the renamed intent field via shared `INTENT_FIELD` usage.
2026-04-26 03:58:56 +02:00
Hans Josephsenandcan1357 2a367bf043 feat(coding-agent/edit): add codex apply_patch as a new edit mode
Slots a new "apply_patch" variant alongside the existing edit modes
(replace, patch, hashline, chunk, vim). The mode accepts a single input
string containing a Codex *** Begin Patch / *** End Patch envelope,
parses it with a new lenient parser (heredoc-tolerant), and fans each
file-op out to the existing executePatchSingle so LSP writethrough,
plan-mode guards, fs-cache invalidation and diagnostics are shared
with the patch mode.

Exposes both tool shapes from the spec: the JSON function-tool variant
(§1.2, {input: string}) and the OpenAI custom-tool / Lark-grammar
"freeform" variant (§1.1, raw patch string). The edit tool advertises
a Lark grammar via customFormat and a wire name via customWireName;
openai-responses emits it as a grammar-constrained custom tool when a
model opts in with applyPatchToolType: "freeform" in models.json.
custom_tool_call / custom_tool_call_output are plumbed end-to-end
through the shared responses code (emission, streaming, history
replay), and the agent-loop dispatcher matches tool calls by either
name or customWireName so returned calls route correctly.

Also threads preview/diff rendering for apply_patch through the TUI
(tool-execution + edit renderer) so streaming patches show per-file
diffs like the other edit modes.

Default edit mode is unchanged (hashline); opt in via edit.mode or
PI_EDIT_VARIANT=apply_patch.
2026-04-24 00:15:17 +02:00
can1357 b4887e37b7 fix: address PR regression follow-ups 2026-04-13 00:48:13 +02:00
djdembeck ce225ddf83 fix: sanitize tool execution events and streamline handling
- agent-loop: sanitize text content in tool_execution result/partialResult
- ai/cursor: fix ANSI escape handling, add incomplete escape detection
- coding-agent/cursor: fix per-delta sanitization with tracked state
- print-mode: flush stderr before exit to prevent data loss
- add unit tests for bash execution clamp display line
2026-04-10 14:51:27 -05:00
djdembeck 82c502b9eb fix: sanitize tool result content in agent-loop
- Add sanitizeText import

- Sanitize text content before creating ToolResultMessage

- Prevents terminal escape sequences from leaking through
2026-04-10 13:54:03 -05:00
can1357 757bdca7a1 feat: added assistant message event interception for streaming edit abort control
- Added `onAssistantMessageEvent` callback to Agent API for inspecting and aborting assistant streaming events.
- Added `setAssistantMessageEventInterceptor()` method to dynamically update assistant message event handlers.
- Converted `checkAutoGeneratedFileContent()` from async to synchronous for improved streaming edit abort detection performance.
- Implemented LRU caching in auto-generated file detection with early path-based checks to prevent unnecessary edits.
- Refactored streaming edit pre-caching to use assistant message event interception for real-time abort capability.
- Extracted `peekFile()` utility for efficient file prefix reading with pooled buffer reuse strategy.
2026-04-08 14:51:15 +02:00
can1357 7fb18faf4c fix(coding-agent): backported pi-mono changes (1feccfed..b21b42d0)
packages/ai:
- feat: expose provider responseId on AssistantMessage
- feat: lazy-load provider modules for faster startup
- fix: hash foreign Responses API tool call IDs exceeding 64-char limit
- fix: ignore null chunks in openai-completions streams
- fix: keep image tool results inline for Gemini 3+ and Antigravity
- fix: correct Bedrock Claude 4.6 context window to 200k
- fix: support prompt caching for Bedrock application inference profiles
- fix: add OpenRouter reasoning payload format
- fix: ignore placeholder Vertex API keys
- fix: skip AJV validation in restricted runtimes
- fix: Anthropic OAuth client injection and responseId extraction
- fix: Codex incomplete/failed response status handling

packages/agent:
- fix: defer steering until after tool execution completes

packages/tui:
- feat: namespaced keybinding IDs with KeybindingsManager conflict detection
- feat: configurable select list column sizing (#2154 by @markusylisiurunen)
- fix: stream truncateToWidth for large strings
- fix: skip Termux height redraws
- fix: stop evicting unrelated default keybindings
- fix: resolve raw backspace ambiguity on Windows Terminal
- fix: clear stale scrollback on session switch (#2155 by @Perlence)
- fix: remove trailing markdown block spacing (#2152 by @markusylisiurunen)

packages/coding-agent:
- feat: add resizable share sidebar (#2435 by @dmmulroy)
- feat: emit OSC 133 command-executed marker
- feat: reload custom themes from disk watcher
- feat: add --fork session flag
- feat: file mutation queue for serialized writes
- feat: initial message consolidation utility
- fix: keybindings migrated to namespaced IDs
- fix: resolve waitForRetry() race when auto-retry produces tool calls
- fix: handle slash-delimited /model refs
- fix: refresh active model after provider updates
- fix: extended transient error patterns for retry
2026-03-22 18:28:40 +01:00
can1357 620d1c4513 feat(agent): added prompt() overload and MCP type guard for safer session handling
- Added overload for `prompt()` method accepting string input with optional options parameter.
- Added type guard `supportsMCPToolDiscoveryExecution()` with `MCPDiscoveryExecutionSession` type predicate for safer session type narrowing.
- Added default parameter value to `refreshToolChoiceForActiveTools()` for improved robustness.
2026-03-16 13:50:30 +01:00
94ad651d17 feat: add MCP tool discovery search (#352)
* Add MCP tool discovery search and live refresh

* Fix MCP discovery review feedback

* Address remaining MCP discovery review comments

* feat: compact MCP discovery search results

* fix: align MCP discovery search contract

* feat: add MCP server tool counts to discovery hints

* fix(agent): corrected stale toolChoice validation against active tools

- Fixed stale forced toolChoice passed to provider after mid-turn tool refresh by validating against active tools.
- Added refreshToolChoiceForActiveTools() to filter invalid tool choices when available tools change.
- Changed getToolChoice config to use computed function instead of static property for dynamic validation.
- Fixed MCP tool selection tracking in coding-agent to distinguish between discovery-enabled and non-discovery sessions.
- Updated search_tool_bm25 to filter already-selected tools before applying limit parameter.

---------

Co-authored-by: can1357 <me@can.ac>
2026-03-16 13:43:43 +01:00
can1357 1962938fa5 feat: added payload interception and signature metadata for provider requests
- Added `onPayload` callback option to intercept and transform provider request payloads before transmission across agent and AI packages.
- Added structured text signature metadata with phase information to OpenAI and Azure OpenAI providers for enhanced response tracking.
- Added `before_provider_request` extension event to coding-agent for chaining payload transformations across multiple handlers.
- Improved error messages in `response.failed` events with detailed error codes, messages, and incomplete reasons from provider responses.
2026-03-10 07:38:13 +01:00
can1357 8e3e0ebf9e feat: introduced Effort enum and ThinkingConfig for model-aware reasoning
- Introduced Effort enum and ThinkingConfig metadata for per-model reasoning capabilities with min/max effort levels.
- Migrated thinking level API from string-based ThinkingLevel to structured Effort enum across agent and AI packages.
- Added model-thinking module with effort mapping, policy application, and semantic versioning utilities for provider-specific thinking modes.
- Removed supportsXhigh() function and replaced effort clamping with model-aware validation using ThinkingConfig metadata.
- Expanded models.json with thinking configuration objects for 50+ models including Claude, Gemini, and OpenAI variants.
- Added Python analysis scripts for edit tool usage patterns and tool invocation stream processing.
2026-03-06 12:35:01 +01:00
can1357 b696842570 feat: added serviceTier option and providerPayload field to OpenAI providers
- Added serviceTier option to OpenAI providers for controlling processing priority and cost across agent, completions, responses, and codex APIs.
- Added providerPayload field to messages for transport-native history reconstruction in OpenAI Responses and Codex APIs.
- Added /fast slash command and serviceTier setting to coding-agent for toggling OpenAI priority mode with fast mode indicator.
- Added remote compaction support with encrypted reasoning preservation for OpenAI models in coding-agent.
- Removed usage caching layer across all providers and refactored UsageFetchContext to eliminate cache and now dependencies.
- Fixed OpenAI Codex streaming service_tier inclusion, provider retry logic with exponential backoff, and email-based credential deduplication.
2026-03-06 12:34:57 +01:00
can1357 e1897ce013 refactor: migrated thinking configuration to centralized pi-ai module
- Extracted thinking module with ThinkingEffort, ThinkingLevel, and ThinkingMode types to centralize reasoning configuration across packages.
- Migrated ThinkingLevel type from pi-agent-core to pi-ai package with new validation functions parseThinkingLevel() and getAvailableThinkingLevel().
- Consolidated thinking level constants and descriptions into reusable exports (ALL_THINKING_LEVELS, THINKING_MODE_DESCRIPTIONS) for consistent UI display.
- Removed local thinking-effort-label utility and replaced formatThinkingEffortLabel() with centralized formatThinking() function from pi-ai.
- Refactored thinking mode handling to distinguish ThinkingSelector (user-facing with 'off' option) from ThinkingEffort (provider-level).
2026-03-05 00:03:40 +01:00
can1357 8c89b5c38d refactor(agent): extracted tool result emission into dedicated function
- Extracted tool result emission logic into dedicated emitToolResult function to eliminate duplication.
- Consolidated tool execution result handling to emit results immediately after execution rather than deferring to post-processing loop.
- Simplified post-execution loop by delegating result emission to emitToolResult and removing redundant message construction.
2026-03-01 06:04:29 +01:00