Rewrite sessionNameGenerator.ts to consume a StreamFn-shaped dependency
(sourced from PiAgentSession.agent.streamFn, wired in leg B) instead of
ModelRegistry plus a dynamic @earendil-works/pi-ai/compat import.
streamFn resolves auth/headers/retry internally, so the explicit
modelRegistry.getApiKeyAndHeaders(model) call and apiKey/headers stream
options are no longer needed.
Deletes now-dead compat-loading machinery: getPiAiProviderRegistryModule,
loadPiAiProviderRegistryModule, importOptionalPiAiModule,
isModuleUnavailableError, hasGetApiProvider, PI_AI_COMPAT_MODULE,
ModuleImporter, SessionNameApiProvider, PiAiProviderRegistryModule, and
the module-level provider registry cache.
Updates the maybeGenerateSessionName call site in piSessionService.ts to
pass session.agent.streamFn instead of this.modelRegistry, and updates
both test files: sessionNameGenerator.test.ts gains coverage for the new
streamFn-driven generateShortSessionName signature (success and error
paths), and piSessionService.test.ts gains an end-to-end test proving a
first prompt generates a session name through the wired agent.streamFn
fake.
sessionNameGenerator.ts no longer imports @earendil-works/pi-ai/compat
or references getApiProvider anywhere.
Add a narrow `agent: { streamFn: StreamFn }` field to the PiAgentSession
interface, sourced structurally from the real AgentSession.agent (Agent,
from the stable @earendil-works/pi-agent-core package). This is the
resolved-auth/headers/retry "call this model" function pi's own
compaction/branch-summarization code uses internally, and will let
sessionNameGenerator.ts drop its dependency on the deprecated pi-ai
/compat provider registry in a follow-up leg.
No adapter object was needed: AgentSession's real .agent field already
structurally satisfies the new narrow shape, so defaultCreateAgentRuntime
needed no changes.
Adds a unit test proving the field is wired end-to-end via the injected
runtime creator. sessionNameGenerator.ts itself is untouched (leg C).
Coalesce session status/activity updates into one render per animation
frame instead of one per token, ignore prompt-editor status changes that
do not affect what it displays, and stop per-keystroke draft state from
re-rendering the surrounding template. This prevents streaming-driven
re-renders from interrupting in-progress touch gestures such as the iOS
long-press paste/edit callout.
The doctor "can find npm/pi" checks wrap the version command in a POSIX
subshell, `(cmd --version 2>&1 || true)`. Fish treats `( ... )` as command
substitution syntax and forbids it in command position, so every fish user saw
false-negative failures:
fish: command substitutions not allowed in command position
command -v npm && (npm --version 2>&1 || true)
Branch on the detected service shell and emit fish's `begin; ...; end`
grouping for fish, mirroring the existing fish-aware quoting in
serviceShellQuote. Bash and zsh keep the POSIX subshell.
Also guard the `main()` invocation with an ESM main-module check so the CLI
helpers can be imported by tests without side effects, and add a regression
test covering the bash, zsh, and fish command shapes.
Split subsession inspection into two tools: check_subsession gives a quick
glance (status + latest assistant output), while read_subsession reads through
a child's transcript with role/content filters, full-content substring search
(including tool-call args), optional per-value maxChars truncation that flags
clipped parts, includeToolArgs, and pagination.
Filtering and search run on full untruncated content; truncation is an explicit,
caller-owned final projection (no default) so a narrow read never silently hides
a match. Empty page-windows are distinguished from zero-match results.