@shivaedev/agent-pi 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/dist/adapters/deliver.d.ts +5 -2
- package/dist/adapters/deliver.d.ts.map +1 -1
- package/dist/adapters/deliver.js +13 -7
- package/dist/adapters/deliver.js.map +1 -1
- package/dist/adapters/mapping.d.ts +1 -1
- package/dist/adapters/mapping.d.ts.map +1 -1
- package/dist/adapters/mapping.js +30 -24
- package/dist/adapters/mapping.js.map +1 -1
- package/dist/adapters/openSession.d.ts.map +1 -1
- package/dist/adapters/openSession.js +7 -2
- package/dist/adapters/openSession.js.map +1 -1
- package/package.json +5 -5
- package/src/adapters/deliver.ts +19 -11
- package/src/adapters/mapping.ts +30 -24
- package/src/adapters/openSession.ts +13 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0 - 2026-11-04
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Acknowledge Pi's accepted prompt dispositions, complete handled initial prompts without waiting for a run, and preserve active runs when input is handled or queued.
|
|
8
|
+
- Treat prompt rejection before a disposition as refusal and resolution without a disposition as uncertain acceptance.
|
|
9
|
+
- Report aborted settlements as interrupted while preserving final assistant failures.
|
|
10
|
+
|
|
11
|
+
### Breaking
|
|
12
|
+
|
|
13
|
+
- Require Pi's coding-agent SDK 1.4.0. Consumers must upgrade their `@earendil-works/pi-coding-agent` peer dependency before using this adapter release. Terminal execution events now arrive at `agent_settled`; consumers reading raw `agent_end` events must wait for settlement to determine the run outcome.
|
|
14
|
+
|
|
3
15
|
## 0.3.1 - 2026-11-04
|
|
4
16
|
|
|
5
17
|
### Changed
|
package/README.md
CHANGED
|
@@ -30,11 +30,11 @@ const work = Effect.gen(function* () {
|
|
|
30
30
|
|
|
31
31
|
### Acceptance, events and recovery
|
|
32
32
|
|
|
33
|
-
A receipt acknowledges Pi's
|
|
33
|
+
A receipt acknowledges Pi's `started`, `queued` or `handled` disposition, independently of its prompt promise. A handled initial prompt completes without a run; handled or queued input leaves an active run open. A prompt promise rejected before any disposition becomes `Rejected`, matching Pi's own RPC refusal signal. Resolution without a disposition becomes `UnknownAcceptance` with the submitted operation ID. Reconciliation returns remembered acceptance or refusal evidence within this backend instance; unknown IDs remain uncertain because Pi has no operation-ID lookup. An operation ID cannot be submitted twice to the same backend instance.
|
|
34
34
|
|
|
35
35
|
The version-one session reference contains the native session-file path. Save `receipt.session`, close its prior run scope, then pass it with a new start request to `agent.sessions.resume`; the adapter opens that file through `SessionManager.open`, preserving its native history. An unavailable file fails with `BackendUnavailable` before submission rather than silently creating replacement history. An unsupported reference version fails with `ProtocolFailure`. References do not contain application agent identities.
|
|
36
36
|
|
|
37
|
-
`events(receipt)` is a live, single-consumer stream buffered from subscription until the run scope closes. It includes the session-file reference, acknowledgement, execution state, settled user and assistant messages, thinking, tool calls and results, turn token deltas and separate provider USD cost deltas. Raw payloads preserve the complete provider event. Unmapped events, including retry and compaction notifications, remain `raw` events. An `agent_end`
|
|
37
|
+
`events(receipt)` is a live, single-consumer stream buffered from subscription until the run scope closes. It includes the session-file reference, acknowledgement, execution state, settled user and assistant messages, thinking, tool calls and results, turn token deltas and separate provider USD cost deltas. Raw payloads preserve the complete provider event. Unmapped events, including retry and compaction notifications, remain `raw` events. An `agent_end` stays raw while the run remains open. At `agent_settled`, final assistant stop reasons distinguish completed, failed and interrupted runs, and `aborted` always reports interruption.
|
|
38
38
|
|
|
39
39
|
`inspect` reads execution evidence from the live session; after its scope closes it returns missing evidence. This is not a persisted run monitor or a transcript reader. Interruption calls Pi's abort; the scope finalizer unsubscribes, aborts and disposes even if abort fails.
|
|
40
40
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { AgentSession, PromptOptions } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
|
-
|
|
3
|
+
import type { BackendFailure } from "@shivaedev/agent/failures.ts";
|
|
4
|
+
type PromptDisposition = Parameters<NonNullable<PromptOptions["preflightResult"]>>[0];
|
|
5
|
+
export declare function deliver(session: AgentSession, text: string, delivery: "followUp" | "steer"): Effect.Effect<PromptDisposition, BackendFailure>;
|
|
6
|
+
export {};
|
|
4
7
|
//# sourceMappingURL=deliver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/adapters/deliver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"deliver.d.ts","sourceRoot":"","sources":["../../src/adapters/deliver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAGnE,KAAK,iBAAiB,GAAG,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtF,wBAAgB,OAAO,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAwB7I"}
|
package/dist/adapters/deliver.js
CHANGED
|
@@ -2,18 +2,24 @@ import { Effect } from "effect";
|
|
|
2
2
|
import { protocolFailure, rejected } from "#adapters/failure.ts";
|
|
3
3
|
export function deliver(session, text, delivery) {
|
|
4
4
|
return Effect.callback((resume) => {
|
|
5
|
-
let
|
|
5
|
+
let accepted = false;
|
|
6
6
|
session
|
|
7
7
|
.prompt(text, {
|
|
8
|
-
preflightResult: (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
resume(Effect.void);
|
|
12
|
-
}
|
|
8
|
+
preflightResult: (disposition) => {
|
|
9
|
+
accepted = true;
|
|
10
|
+
resume(Effect.succeed(disposition));
|
|
13
11
|
},
|
|
14
12
|
streamingBehavior: delivery,
|
|
15
13
|
})
|
|
16
|
-
.then(() =>
|
|
14
|
+
.then(() => {
|
|
15
|
+
if (!accepted) {
|
|
16
|
+
resume(Effect.fail(protocolFailure("Pi prompt resolved without acceptance evidence")));
|
|
17
|
+
}
|
|
18
|
+
}, (error) => {
|
|
19
|
+
if (!accepted) {
|
|
20
|
+
resume(Effect.fail(rejected(error)));
|
|
21
|
+
}
|
|
22
|
+
});
|
|
17
23
|
});
|
|
18
24
|
}
|
|
19
25
|
//# sourceMappingURL=deliver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliver.js","sourceRoot":"","sources":["../../src/adapters/deliver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"deliver.js","sourceRoot":"","sources":["../../src/adapters/deliver.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIjE,MAAM,UAAU,OAAO,CAAC,OAAqB,EAAE,IAAY,EAAE,QAA8B;IAC1F,OAAO,MAAM,CAAC,QAAQ,CAAoC,CAAC,MAAM,EAAE,EAAE;QACpE,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,OAAO;aACL,MAAM,CAAC,IAAI,EAAE;YACb,eAAe,EAAE,CAAC,WAAW,EAAE,EAAE;gBAChC,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;YACrC,CAAC;YACD,iBAAiB,EAAE,QAAQ;SAC3B,CAAC;aACD,IAAI,CACJ,GAAG,EAAE;YACJ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,gDAAgD,CAAC,CAAC,CAAC,CAAC;YACxF,CAAC;QACF,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;YAClB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACtC,CAAC;QACF,CAAC,CACD,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -5,5 +5,5 @@ export declare function rawOf(kind: string, payload: unknown): {
|
|
|
5
5
|
payload: string;
|
|
6
6
|
source: string;
|
|
7
7
|
};
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function makeEventMapper(): (event: AgentSessionEvent) => RunEvent[];
|
|
9
9
|
//# sourceMappingURL=mapping.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../src/adapters/mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAG3D,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;;;EAEnD;AAKD,wBAAgB,
|
|
1
|
+
{"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../src/adapters/mapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAG3D,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;;;;EAEnD;AAKD,wBAAgB,eAAe,YAEf,iBAAiB,KAAG,QAAQ,EAAE,CA+B7C"}
|
package/dist/adapters/mapping.js
CHANGED
|
@@ -4,33 +4,39 @@ export function rawOf(kind, payload) {
|
|
|
4
4
|
return { kind, payload: JSON.stringify(payload), source: "pi" };
|
|
5
5
|
}
|
|
6
6
|
const decodeOutput = Schema.decodeUnknownOption(Schema.Struct({ content: Schema.Array(Schema.Struct({ text: Schema.optional(Schema.String), type: Schema.String })) }));
|
|
7
|
-
export function
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
export function makeEventMapper() {
|
|
8
|
+
let ending = "completed";
|
|
9
|
+
return (event) => {
|
|
10
|
+
const raw = rawOf(event.type, event);
|
|
11
|
+
switch (event.type) {
|
|
12
|
+
case "agent_start":
|
|
13
|
+
ending = "completed";
|
|
14
|
+
return [{ raw, state: "running", type: "execution" }];
|
|
15
|
+
case "agent_end": {
|
|
16
|
+
if (event.willRetry) {
|
|
17
|
+
return [{ raw, type: "raw" }];
|
|
18
|
+
}
|
|
19
|
+
const assistant = event.messages.filter((message) => message.role === "assistant").at(-1);
|
|
20
|
+
ending = endState(assistant?.stopReason);
|
|
14
21
|
return [{ raw, type: "raw" }];
|
|
15
22
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
23
|
+
case "agent_settled":
|
|
24
|
+
return [{ raw, state: event.aborted ? "interrupted" : ending, type: "execution" }];
|
|
25
|
+
case "message_end":
|
|
26
|
+
return messageEvents(event.message, raw);
|
|
27
|
+
case "tool_execution_start":
|
|
28
|
+
return [{ input: JSON.stringify(event.args), name: event.toolName, raw, toolId: event.toolCallId, type: "tool.started" }];
|
|
29
|
+
case "tool_execution_end": {
|
|
30
|
+
const output = Option.match(decodeOutput(event.result), {
|
|
31
|
+
onNone: () => "",
|
|
32
|
+
onSome: ({ content }) => content.flatMap((part) => (part.type === "text" && part.text !== undefined ? [part.text] : [])).join("\n"),
|
|
33
|
+
});
|
|
34
|
+
return [{ ok: !event.isError, output, raw, toolId: event.toolCallId, type: "tool.completed" }];
|
|
35
|
+
}
|
|
36
|
+
default:
|
|
37
|
+
return [{ raw, type: "raw" }];
|
|
30
38
|
}
|
|
31
|
-
|
|
32
|
-
return [{ raw, type: "raw" }];
|
|
33
|
-
}
|
|
39
|
+
};
|
|
34
40
|
}
|
|
35
41
|
function endState(reason) {
|
|
36
42
|
if (reason === "aborted") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.js","sourceRoot":"","sources":["../../src/adapters/mapping.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,UAAU,KAAK,CAAC,IAAY,EAAE,OAAgB;IACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC;AACD,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,CAC9C,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,CACtH,CAAC;AAEF,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"mapping.js","sourceRoot":"","sources":["../../src/adapters/mapping.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openSession.d.ts","sourceRoot":"","sources":["../../src/adapters/openSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAO3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"openSession.d.ts","sourceRoot":"","sources":["../../src/adapters/openSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAO3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAkCP,MAAM,YAAY,UAAU,GAAG,OAAO;;;;;;;;;;;;;6IAarD,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, Queue, Stream } from "effect";
|
|
2
2
|
import { deliver } from "#adapters/deliver.ts";
|
|
3
3
|
import { unavailable } from "#adapters/failure.ts";
|
|
4
|
-
import {
|
|
4
|
+
import { makeEventMapper, rawOf } from "#adapters/mapping.ts";
|
|
5
5
|
import { openRuntime } from "#adapters/runtime.ts";
|
|
6
6
|
export const openSession = Effect.fnUntraced(function* (options, request, resume) {
|
|
7
7
|
const { session, sessionFile } = yield* openRuntime(options, request, resume);
|
|
@@ -13,6 +13,7 @@ export const openSession = Effect.fnUntraced(function* (options, request, resume
|
|
|
13
13
|
}
|
|
14
14
|
Queue.offerUnsafe(output, event);
|
|
15
15
|
}
|
|
16
|
+
const toAgentEvents = makeEventMapper();
|
|
16
17
|
const unsubscribe = session.subscribe((event) => {
|
|
17
18
|
for (const mapped of toAgentEvents(event)) {
|
|
18
19
|
emit(mapped);
|
|
@@ -34,7 +35,11 @@ export const openSession = Effect.fnUntraced(function* (options, request, resume
|
|
|
34
35
|
events: Stream.fromQueue(output),
|
|
35
36
|
inspect: Effect.sync(() => observation),
|
|
36
37
|
interrupt: Effect.tryPromise({ catch: unavailable, try: () => session.abort() }),
|
|
37
|
-
prompt: (text, delivery) => deliver(session, text, delivery)
|
|
38
|
+
prompt: (text, delivery) => deliver(session, text, delivery).pipe(Effect.tap((disposition) => Effect.sync(() => {
|
|
39
|
+
if (disposition === "handled" && observation.type === "known" && observation.state === "accepted") {
|
|
40
|
+
emit({ state: "completed", type: "execution" });
|
|
41
|
+
}
|
|
42
|
+
})), Effect.asVoid),
|
|
38
43
|
receipt,
|
|
39
44
|
};
|
|
40
45
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openSession.js","sourceRoot":"","sources":["../../src/adapters/openSession.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG3D,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"openSession.js","sourceRoot":"","sources":["../../src/adapters/openSession.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/agent-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Pi integration for Effect applications",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/agent-pi#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -43,17 +43,17 @@
|
|
|
43
43
|
"@shivaedev/agent": "0.3.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@earendil-works/pi-coding-agent": "
|
|
46
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
47
47
|
"@effect/vitest": "4.0.7",
|
|
48
|
-
"@shivaedev/quality": "0.
|
|
49
|
-
"@shivaedev/test-story": "0.39.
|
|
48
|
+
"@shivaedev/quality": "0.62.1",
|
|
49
|
+
"@shivaedev/test-story": "0.39.2",
|
|
50
50
|
"@types/node": "24.19.2",
|
|
51
51
|
"effect": "4.0.7",
|
|
52
52
|
"typescript": "7.0.2",
|
|
53
53
|
"vitest": "5.0.5"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@earendil-works/pi-coding-agent": "
|
|
56
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
57
57
|
"effect": "4.0.7"
|
|
58
58
|
},
|
|
59
59
|
"peerDependenciesMeta": {
|
package/src/adapters/deliver.ts
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
import type { AgentSession } from "@earendil-works/pi-coding-agent";
|
|
1
|
+
import type { AgentSession, PromptOptions } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Effect } from "effect";
|
|
3
3
|
import type { BackendFailure } from "@shivaedev/agent/failures.ts";
|
|
4
4
|
import { protocolFailure, rejected } from "#adapters/failure.ts";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
type PromptDisposition = Parameters<NonNullable<PromptOptions["preflightResult"]>>[0];
|
|
7
|
+
|
|
8
|
+
export function deliver(session: AgentSession, text: string, delivery: "followUp" | "steer"): Effect.Effect<PromptDisposition, BackendFailure> {
|
|
9
|
+
return Effect.callback<PromptDisposition, BackendFailure>((resume) => {
|
|
10
|
+
let accepted = false;
|
|
9
11
|
session
|
|
10
12
|
.prompt(text, {
|
|
11
|
-
preflightResult: (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
resume(Effect.void);
|
|
15
|
-
}
|
|
13
|
+
preflightResult: (disposition) => {
|
|
14
|
+
accepted = true;
|
|
15
|
+
resume(Effect.succeed(disposition));
|
|
16
16
|
},
|
|
17
17
|
streamingBehavior: delivery,
|
|
18
18
|
})
|
|
19
19
|
.then(
|
|
20
|
-
() =>
|
|
21
|
-
|
|
20
|
+
() => {
|
|
21
|
+
if (!accepted) {
|
|
22
|
+
resume(Effect.fail(protocolFailure("Pi prompt resolved without acceptance evidence")));
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
(error: unknown) => {
|
|
26
|
+
if (!accepted) {
|
|
27
|
+
resume(Effect.fail(rejected(error)));
|
|
28
|
+
}
|
|
29
|
+
},
|
|
22
30
|
);
|
|
23
31
|
});
|
|
24
32
|
}
|
package/src/adapters/mapping.ts
CHANGED
|
@@ -10,33 +10,39 @@ const decodeOutput = Schema.decodeUnknownOption(
|
|
|
10
10
|
Schema.Struct({ content: Schema.Array(Schema.Struct({ text: Schema.optional(Schema.String), type: Schema.String })) }),
|
|
11
11
|
);
|
|
12
12
|
|
|
13
|
-
export function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
export function makeEventMapper() {
|
|
14
|
+
let ending: "completed" | "failed" | "interrupted" = "completed";
|
|
15
|
+
return (event: AgentSessionEvent): RunEvent[] => {
|
|
16
|
+
const raw = rawOf(event.type, event);
|
|
17
|
+
switch (event.type) {
|
|
18
|
+
case "agent_start":
|
|
19
|
+
ending = "completed";
|
|
20
|
+
return [{ raw, state: "running", type: "execution" }];
|
|
21
|
+
case "agent_end": {
|
|
22
|
+
if (event.willRetry) {
|
|
23
|
+
return [{ raw, type: "raw" }];
|
|
24
|
+
}
|
|
25
|
+
const assistant = event.messages.filter((message) => message.role === "assistant").at(-1);
|
|
26
|
+
ending = endState(assistant?.stopReason);
|
|
20
27
|
return [{ raw, type: "raw" }];
|
|
21
28
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
29
|
+
case "agent_settled":
|
|
30
|
+
return [{ raw, state: event.aborted ? "interrupted" : ending, type: "execution" }];
|
|
31
|
+
case "message_end":
|
|
32
|
+
return messageEvents(event.message, raw);
|
|
33
|
+
case "tool_execution_start":
|
|
34
|
+
return [{ input: JSON.stringify(event.args), name: event.toolName, raw, toolId: event.toolCallId, type: "tool.started" }];
|
|
35
|
+
case "tool_execution_end": {
|
|
36
|
+
const output = Option.match(decodeOutput(event.result), {
|
|
37
|
+
onNone: () => "",
|
|
38
|
+
onSome: ({ content }) => content.flatMap((part) => (part.type === "text" && part.text !== undefined ? [part.text] : [])).join("\n"),
|
|
39
|
+
});
|
|
40
|
+
return [{ ok: !event.isError, output, raw, toolId: event.toolCallId, type: "tool.completed" }];
|
|
41
|
+
}
|
|
42
|
+
default:
|
|
43
|
+
return [{ raw, type: "raw" }];
|
|
36
44
|
}
|
|
37
|
-
|
|
38
|
-
return [{ raw, type: "raw" }];
|
|
39
|
-
}
|
|
45
|
+
};
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
function endState(reason: string | undefined) {
|
|
@@ -3,7 +3,7 @@ import type { RunEvent } from "@shivaedev/agent/events.ts";
|
|
|
3
3
|
import type { Observation, Receipt, StartRequest } from "@shivaedev/agent/run.ts";
|
|
4
4
|
import { deliver } from "#adapters/deliver.ts";
|
|
5
5
|
import { unavailable } from "#adapters/failure.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { makeEventMapper, rawOf } from "#adapters/mapping.ts";
|
|
7
7
|
import { openRuntime } from "#adapters/runtime.ts";
|
|
8
8
|
import type { PiOptions } from "#PiOptions.ts";
|
|
9
9
|
|
|
@@ -17,6 +17,7 @@ export const openSession = Effect.fnUntraced(function* (options: PiOptions, requ
|
|
|
17
17
|
}
|
|
18
18
|
Queue.offerUnsafe(output, event);
|
|
19
19
|
}
|
|
20
|
+
const toAgentEvents = makeEventMapper();
|
|
20
21
|
const unsubscribe = session.subscribe((event) => {
|
|
21
22
|
for (const mapped of toAgentEvents(event)) {
|
|
22
23
|
emit(mapped);
|
|
@@ -40,7 +41,17 @@ export const openSession = Effect.fnUntraced(function* (options: PiOptions, requ
|
|
|
40
41
|
events: Stream.fromQueue(output),
|
|
41
42
|
inspect: Effect.sync(() => observation),
|
|
42
43
|
interrupt: Effect.tryPromise({ catch: unavailable, try: () => session.abort() }),
|
|
43
|
-
prompt: (text: string, delivery: "followUp" | "steer") =>
|
|
44
|
+
prompt: (text: string, delivery: "followUp" | "steer") =>
|
|
45
|
+
deliver(session, text, delivery).pipe(
|
|
46
|
+
Effect.tap((disposition) =>
|
|
47
|
+
Effect.sync(() => {
|
|
48
|
+
if (disposition === "handled" && observation.type === "known" && observation.state === "accepted") {
|
|
49
|
+
emit({ state: "completed", type: "execution" });
|
|
50
|
+
}
|
|
51
|
+
}),
|
|
52
|
+
),
|
|
53
|
+
Effect.asVoid,
|
|
54
|
+
),
|
|
44
55
|
receipt,
|
|
45
56
|
};
|
|
46
57
|
});
|