mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-06 18:39:47 +00:00
* feat(pi): auto-title Pi sessions via bundled hapi_change_title extension Pi sessions never got automatic titles: HAPI set PI_RPC_EMIT_TITLE=1 but Pi does not implement it, and unlike the Claude/Codex/OpenCode launchers the Pi bridge neither registers a change_title tool nor injects a title instruction. This materializes a bundled Pi extension at launch and passes it via --extension, giving Pi sessions the same titling flow: - hapi_change_title tool (namespaced to avoid collisions with user extensions, mirroring the OpenCode launcher naming) - first-turn system-prompt instruction matching the Claude/Codex wording - title lands via ctx.ui.setTitle(), which the existing extension UI bridge already syncs into session metadata Removes the dead PI_RPC_EMIT_TITLE env var. Requires pi >= 0.35.0 (when --extension landed, 2026-01). Closes #1669 by giving sessions titles from the session model itself, with zero extra title-provider calls. * fix(pi): publish title extension atomically and keep retitle rule Review findings from the HAPI PR bot: - [Major] Publish the generated extension atomically. All Pi sessions of a HAPI version share the same versioned path and Pi treats extension-load errors as fatal, so a plain writeFile could break a concurrent launch with a half-written file. The extension is now written to a unique temp file and moved into place with rename; if rename loses a race against another launcher that already published the file, the existing copy is kept and the temp file is cleaned up. - [Minor] Inject the title instruction on every before_agent_start instead of stopping after the first title, preserving the objective-change retitle rule from the persistent Claude/Codex instruction. Adds a concurrent-materialization test and a handler test that executes the title tool and asserts a later turn still carries the instruction. * test(pi): fix handler return type in title extension test * fix(pi): keep bundled title extension compatible with older Pi releases Follow-up review finding: the embedded extension assumed three behaviors that only exist in recent Pi releases, while HAPI has no Pi minimum-version floor, so accepted older installations either failed to load the extension or reached the tool without setting a title: - import TypeBox via '@sinclair/typebox', the specifier both the legacy extension loaders and the current one (which aliases it to the bundled 'typebox') resolve; - normalize the execute() context positionally: current Pi passes (toolCallId, params, signal, onUpdate, ctx), legacy releases passed (toolCallId, params, onUpdate, ctx, signal); - call ctx.ui.setTitle() directly instead of gating on ctx.hasUI, which older RPC releases report as false even though setTitle emits the extension UI event (this extension only runs under HAPI's RPC bridge). Tests now exercise both call orders, including hasUI: false. --------- Co-authored-by: HongChenGG <HongChenGG@users.noreply.github.com>