Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
7e509a0
feat(chat): Add durable agent continuation queue
dcramer Jun 1, 2026
748fc05
fix(chat): Preserve Slack mailbox completion state
dcramer Jun 2, 2026
bbacfed
fix(chat): Harden durable continuation recovery
dcramer Jun 2, 2026
4b4b4d0
fix(chat): Requeue runnable conversation work
dcramer Jun 2, 2026
2a94501
fix(slack): Ack App Home publish failures
dcramer Jun 2, 2026
607d525
fix(slack): Align restored thread route context
dcramer Jun 2, 2026
7254b29
build: Repair rebased lockfile
dcramer Jun 2, 2026
405f5f1
fix(slack): Ack events before durable handoff
dcramer Jun 2, 2026
24c0932
fix(chat): Report lost Slack worker leases
dcramer Jun 2, 2026
37171a7
fix(slack): Pass event waitUntil promises
dcramer Jun 2, 2026
f867069
fix(slack): Preserve bot mentions and disconnect refreshes
dcramer Jun 2, 2026
13fbdcc
fix(slack): Steer rapid queued messages during active turns
dcramer Jun 2, 2026
1d0ac17
fix(slack): Strip normalized bot mentions in worker turns
dcramer Jun 2, 2026
b2fc2eb
test(slack): Split conversation work component coverage
dcramer Jun 2, 2026
502ebd1
test(slack): Share conversation work fixtures
dcramer Jun 2, 2026
e78f16e
fix(slack): Preserve user mentions after bot token
dcramer Jun 2, 2026
44ec1ba
fix(slack): Preserve form workspace context
dcramer Jun 2, 2026
eb283e7
test(slack): Cover durable edited mentions
dcramer Jun 2, 2026
d93ae98
fix(runtime): Report effective turn timeout
dcramer Jun 2, 2026
ee69291
fix(runtime): Preserve steered assistant text
dcramer Jun 2, 2026
dafb26c
fix(runtime): Keep failed steering pending
dcramer Jun 2, 2026
a691cf7
fix(runtime): Honor continuation safety gates
dcramer Jun 2, 2026
11702aa
fix(runtime): Separate cooperative yield resumes
dcramer Jun 2, 2026
7da2079
fix(runtime): Recover continuation work after stale leases
dcramer Jun 2, 2026
228eb3b
fix(runtime): Preserve invalid idle continuations
dcramer Jun 2, 2026
6972421
fix(runtime): Terminalize stale continuations
dcramer Jun 2, 2026
fe903f4
fix(runtime): Keep resumed follow-ups pending
dcramer Jun 2, 2026
efbce20
fix(mcp): Recover missing resumed tool calls
dcramer Jun 2, 2026
1c65e36
fix(runtime): Keep unhanded Slack work pending
dcramer Jun 2, 2026
4172cbe
fix(runtime): Resume turns before pending Slack mail
dcramer Jun 3, 2026
95e7a71
fix(queue): Authenticate conversation callbacks
dcramer Jun 3, 2026
cbdf43b
fix(runtime): Preserve continuation failure status
dcramer Jun 3, 2026
981f417
fix(runtime): Ignore replied duplicates before resume
dcramer Jun 3, 2026
715119d
fix(queue): Nudge failed conversation work
dcramer Jun 3, 2026
7ee7ca7
fix(runtime): Preserve steered yield snapshots
dcramer Jun 3, 2026
81d97f3
fix(runtime): Preserve parked continuations
dcramer Jun 3, 2026
9ecf3ed
fix(slack): Harden durable turn continuation
dcramer Jun 3, 2026
a60fc6e
fix(slack): Track turn processing reactions
dcramer Jun 3, 2026
7e43a52
fix(runtime): Fail closed on missing input checkpoints
dcramer Jun 3, 2026
5f05e09
fix(queue): Preserve recoverable work ownership
dcramer Jun 3, 2026
02ee629
fix(runtime): Fail terminal timeout resumes closed
dcramer Jun 3, 2026
07c54c4
fix(queue): Avoid duplicate inbound wake nudges
dcramer Jun 3, 2026
674e97b
fix(ci): Remove stale heartbeat imports
dcramer Jun 3, 2026
91b0e39
fix(runtime): Commit rescheduled Slack inputs
dcramer Jun 3, 2026
1541a53
fix(queue): Requeue lost lease work
dcramer Jun 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 37 additions & 32 deletions .agents/skills/pi-agent-integration/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,58 @@
---
name: pi-agent-integration
description: Integrate `@mariozechner/pi-agent-core` as the agent abstraction inside another library or runtime. Use when implementing or refactoring Pi Agent wrappers, streaming bridges, `convertToLlm`/`transformContext`, queueing via `steer`/`followUp`, `continue()` semantics, or timeout/abort/session behavior.
description: Integrate the latest `@earendil-works/pi-agent-core` APIs into an app, library, runtime, or agent harness. Use for Pi `Agent`, `AgentHarness`, streaming bridges, tool execution hooks, `convertToLlm`/`transformContext`, queueing via `steer`/`followUp`, `continue()` semantics, `streamFn`/`streamProxy`, timeout/abort, session, skill, or compaction behavior.
---

Implement Pi-agent consumers with stable streaming, correct queue semantics, and minimal wrapper surface area.
Implement Pi-agent consumers against the latest published Pi API with stable streaming, correct queue semantics, and minimal wrapper surface area.

## Step 1: Classify the request

Pick the path before editing:

| Request type | Read first |
| --- | --- |
| Wiring or updating agent wrapper APIs/options | `references/api-surface.md` |
| Adding behavior in a consumer library (chat, orchestration, tools) | `references/common-use-cases.md` |
| Debugging broken streaming/tool/continue behavior | `references/troubleshooting-workarounds.md` |
| Request type | Read first |
| --------------------------------------------------------------------------------- | ------------------------------------------- |
| Wiring or updating `Agent`, loop, provider, stream, or tool APIs | `references/api-surface.md` |
| Adding Pi behavior in a consuming app, library, or runtime | `references/common-use-cases.md` |
| Using Pi's built-in harness, sessions, skills, resources, or compaction | `references/harness.md` |
| Debugging broken streaming, tools, queues, continuation, proxy, or abort behavior | `references/troubleshooting-workarounds.md` |

If the task spans multiple categories, load only the relevant files above.
If a task spans multiple categories, load only the relevant references above. Keep guidance Pi-specific unless the user explicitly asks about a consuming product.

## Step 2: Apply integration guardrails

1. Treat `Agent` as the execution engine and keep wrapper abstractions thin.
2. Stream user-visible text only from `message_update` + `assistantMessageEvent.type === "text_delta"`.
3. Bridge deltas into `AsyncIterable<string>` and pass that iterable to downstream streaming surfaces.
4. Preserve message boundaries when streaming multi-message assistant output (insert separators intentionally, then normalize).
5. Never call `prompt()` or `continue()` while the agent is running; use `steer()`/`followUp()` for mid-run input.
6. Keep `convertToLlm` and `transformContext` explicit, deterministic, and easy to test.
7. Keep tool calls/results as internal execution artifacts unless product UX explicitly requires otherwise.
1. Treat npm `latest` for `@earendil-works/pi-agent-core` as the source of truth before relying on a contract.
2. Use `Agent` when event handling must be awaited as part of run settlement; use low-level `agentLoop` only when an observational event stream is enough.
3. Stream user-visible text only from `message_update` where `assistantMessageEvent.type === "text_delta"`.
4. Preserve assistant message boundaries deliberately when forwarding multi-message output.
5. Do not call `prompt()` or `continue()` while an agent is active; queue mid-run input with `steer()` or `followUp()`.
6. Treat normal `continue()` as a resume from a non-empty `user` or `toolResult` tail. An `assistant` tail can only drain queued steering/follow-up messages, otherwise it throws.
7. Keep `streamFn`, `convertToLlm`, `transformContext`, `getApiKey`, queue providers, and loop hooks no-throw for expected request/runtime failures; return safe values or encode failures in protocol events.
8. Keep tool calls, tool progress, tool results, thinking deltas, and provider payloads internal unless the product UX explicitly exposes them.
9. Prefer Pi's built-in harness when sessions, skills, prompt templates, resources, filesystem/shell environment, compaction, or tree navigation are required.

## Step 3: Implement with minimal surface

1. Prefer constructor options over custom wrapper state machines (`streamFn`, `getApiKey`, `sessionId`, `thinkingBudgets`, `maxRetryDelayMs`).
2. Use `transformContext` for pruning/injection and `convertToLlm` for message-role conversion/filtering.
3. Keep queue mode explicit (`steeringMode`, `followUpMode`) when concurrency/order matters.
4. For server-proxied model access, use `streamFn` with `streamProxy`-style behavior instead of bespoke provider logic in consumers.
5. Keep failure behavior explicit: timeout/abort paths should set observable diagnostics and terminate streaming cleanly.
1. Prefer Pi options over custom wrapper state machines: `streamFn`, `getApiKey`, `sessionId`, `thinkingBudgets`, `transport`, `maxRetryDelayMs`, `onPayload`, `onResponse`, `beforeToolCall`, `afterToolCall`, `prepareNextTurn`, `toolExecution`, `steeringMode`, and `followUpMode`.
2. Mutate `Agent` state through `agent.state` properties and `reset()`; do not invent setter wrappers unless the consumer API needs them.
3. Use `transformContext` for message-level pruning/injection and `convertToLlm` for provider-compatible role conversion/filtering.
4. Keep queue modes explicit (`"one-at-a-time"` or `"all"`) when ordering or batching matters.
5. For server-proxied model access, use `streamFn` with `streamProxy`-style behavior instead of provider logic scattered through consumers.
6. For tool policy, use `toolExecution`, per-tool `executionMode`, `beforeToolCall`, `afterToolCall`, thrown tool errors, and `terminate` before adding a custom tool runner.
7. Keep timeout/abort paths observable and make sure streams/iterables settle cleanly.

## Step 4: Verify behavior

1. Verify event-to-stream bridge emits only text deltas and always closes the iterable.
2. Verify `prompt()`/`continue()` race handling (throws while streaming; queue path works via `steer`/`followUp`).
3. Verify `continue()` preconditions: non-empty context and valid last-message role semantics.
4. Verify custom message types survive agent state while `convertToLlm` emits only LLM-compatible roles.
5. Verify tool execution and turn lifecycle events remain internal unless explicitly exposed.
6. Verify newline joining/normalization parity between streamed and finalized outputs.
1. Verify the event-to-stream bridge emits only text deltas, preserves intended boundaries, and closes on success, error, and abort.
2. Verify `prompt()`/`continue()` race handling and queued `steer()`/`followUp()` behavior.
3. Verify `continue()` preconditions for empty history, `user` tail, `toolResult` tail, and `assistant` tail with and without queued messages.
4. Verify custom message types remain in agent state while `convertToLlm` emits only provider-compatible messages.
5. Verify `streamFn` encodes expected provider failures instead of throwing/rejecting.
6. Verify tool execution ordering under default parallel mode, sequential overrides, hook blocking/patching, progress updates, and `terminate` behavior.
7. Verify `Agent.subscribe()` listener settlement and `waitForIdle()` behavior when listeners perform async work.
8. Verify `AgentHarness` session, resource, hook, compaction, and abort behavior when the harness path is used.

## Step 5: Migration and version checks

1. Check for queue API migrations (`queueMessage` -> `steer`/`followUp`) before editing old wrappers.
2. Check renamed hooks/options (`messageTransformer` -> `convertToLlm`, `preprocessor` -> `transformContext`).
3. Check default/available options in current package version before adding compatibility shims.
4. Favor hard cutovers unless backward compatibility is explicitly requested.
## Step 5: Version discipline

1. Target the latest published Pi package only.
2. Re-check the latest package metadata and declarations before material API updates.
3. Do not add backward-compatibility shims or old package-name guidance unless the user explicitly asks for a migration.
Loading
Loading