@estebanforge/pi-antigravity-bridge 1.6.1 → 1.6.2
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 +6 -0
- package/package.json +5 -5
- package/src/provider.ts +19 -11
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.6.2] - 2026-09-19
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Compatibility with host 0.86.0's normalized provider stream input.** Stream entry points now receive a branded `TranscriptContext` (`{ messages }` only): the `context.systemPrompt` / `context.tools` fields are gone, and only `normalizeContext()` produces the new type. G10 fresh-conversation delivery read `context.systemPrompt`, so every fresh agy conversation silently lost the system prompt block (operating instructions, AGENTS.md project context, tool-priority note); the prompt now comes from the transcript via `getCurrentSystemPrompt(context.messages)`. `emitToolUse` arguments are restricted to `Record<string, JsonValue>` per the tightened `ToolCall.arguments` contract (driver args arrive JSON-decoded off the wire, so the two call-site casts are sound). Test fixtures in `provider-{sysprompt,streaming,late-result,escalation}.test.ts` and the `scripts/test-provider.ts` smoke context wrap raw objects with `normalizeContext()`. Dev pins `@earendil-works/*` raised `^0.85.0` to `^0.86.0`; `tsc` clean, 360 tests green.
|
|
10
|
+
|
|
5
11
|
## [1.6.1] - 2026-09-18
|
|
6
12
|
|
|
7
13
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estebanforge/pi-antigravity-bridge",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Gemini provider for Pi on the Antigravity ACP server (official Google ACP) or the stream-json agy CLI. antigravity/* models in Pi's /model picker, no-patch MCP bridge: agy runs Pi's tools. ToS safe to use.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@earendil-works/pi-ai": "^0.
|
|
63
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
64
|
-
"@earendil-works/pi-server": "^0.
|
|
65
|
-
"@earendil-works/pi-tui": "^0.
|
|
62
|
+
"@earendil-works/pi-ai": "^0.86.0",
|
|
63
|
+
"@earendil-works/pi-coding-agent": "^0.86.0",
|
|
64
|
+
"@earendil-works/pi-server": "^0.86.0",
|
|
65
|
+
"@earendil-works/pi-tui": "^0.86.0",
|
|
66
66
|
"@types/node": "^22.0.0",
|
|
67
67
|
"tsx": "^4.19.0",
|
|
68
68
|
"typebox": "^1.1.38",
|
package/src/provider.ts
CHANGED
|
@@ -19,13 +19,15 @@
|
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
21
|
createAssistantMessageEventStream,
|
|
22
|
+
getCurrentSystemPrompt,
|
|
22
23
|
type AssistantMessage,
|
|
23
24
|
type AssistantMessageEventStream,
|
|
24
|
-
type
|
|
25
|
+
type JsonValue,
|
|
25
26
|
type Message,
|
|
26
27
|
type Model,
|
|
27
28
|
type SimpleStreamOptions,
|
|
28
29
|
type ThinkingLevel,
|
|
30
|
+
type TranscriptContext,
|
|
29
31
|
type Usage,
|
|
30
32
|
} from "@earendil-works/pi-ai";
|
|
31
33
|
import fs from "node:fs";
|
|
@@ -59,7 +61,7 @@ function zeroUsage(): Usage {
|
|
|
59
61
|
/** Extract the latest user message as a flat prompt string. agy maintains its
|
|
60
62
|
* own conversation history via --conversation, so we collapse pi's structured
|
|
61
63
|
* message to text. Returns null if the last message isn't a user message. */
|
|
62
|
-
function extractUserPrompt(context:
|
|
64
|
+
function extractUserPrompt(context: TranscriptContext): string | null {
|
|
63
65
|
const last = context.messages[context.messages.length - 1];
|
|
64
66
|
if (!last || last.role !== "user") return null;
|
|
65
67
|
const content = last.content;
|
|
@@ -75,7 +77,7 @@ function extractUserPrompt(context: Context): string | null {
|
|
|
75
77
|
/** Image blocks of the latest user message (pi-ai ImageContent: base64 data
|
|
76
78
|
* + mimeType). The ACP engine forwards them as typed content blocks; the
|
|
77
79
|
* stream-json CLI prompt is text-only, so its driver simply ignores these. */
|
|
78
|
-
function extractImages(context:
|
|
80
|
+
function extractImages(context: TranscriptContext): Array<{ data: string; mimeType: string }> {
|
|
79
81
|
const last = context.messages[context.messages.length - 1];
|
|
80
82
|
if (!last || last.role !== "user" || typeof last.content === "string") return [];
|
|
81
83
|
return last.content
|
|
@@ -100,7 +102,8 @@ const DIGEST_PREAMBLE =
|
|
|
100
102
|
|
|
101
103
|
// --- pi system prompt (G10) ----------------------------------------------------
|
|
102
104
|
//
|
|
103
|
-
// pi
|
|
105
|
+
// pi normalizes the system prompt into the transcript every turn (read via
|
|
106
|
+
// getCurrentSystemPrompt): its own operating instructions
|
|
104
107
|
// plus every AGENTS.md/CLAUDE.md it loaded (global agent dir first, then
|
|
105
108
|
// ancestors). The provider used to drop it, so agy models never saw the user's
|
|
106
109
|
// machine-level or project-level instructions. agy has no system-prompt flag
|
|
@@ -921,13 +924,14 @@ function nextRtId(kind: "nat" | "wrap"): string {
|
|
|
921
924
|
return `${kind}-${++RT_SEQ}`;
|
|
922
925
|
}
|
|
923
926
|
|
|
924
|
-
/** Emit a complete toolCall block and end the pi call with toolUse.
|
|
927
|
+
/** Emit a complete toolCall block and end the pi call with toolUse.
|
|
928
|
+
* pi 0.86 restricts ToolCall.arguments to JSON-compatible values. */
|
|
925
929
|
function emitToolUse(
|
|
926
930
|
stream: AssistantMessageEventStream,
|
|
927
931
|
blocks: BlockState,
|
|
928
932
|
id: string,
|
|
929
933
|
name: string,
|
|
930
|
-
args: Record<string,
|
|
934
|
+
args: Record<string, JsonValue>,
|
|
931
935
|
): void {
|
|
932
936
|
const partial = blocks.partial;
|
|
933
937
|
closeThinking(stream, blocks);
|
|
@@ -1050,7 +1054,7 @@ function acpEditFileArg(args: Record<string, unknown>): string | undefined {
|
|
|
1050
1054
|
emitToolUse(stream, blocks, id, mapped.tool, {
|
|
1051
1055
|
reasoning: `re-exec of agy ${activity.name} for display`,
|
|
1052
1056
|
...mapped.args,
|
|
1053
|
-
});
|
|
1057
|
+
} as Record<string, JsonValue>);
|
|
1054
1058
|
return "parked";
|
|
1055
1059
|
}
|
|
1056
1060
|
{
|
|
@@ -1067,7 +1071,9 @@ function acpEditFileArg(args: Record<string, unknown>): string | undefined {
|
|
|
1067
1071
|
case "bridge_call": {
|
|
1068
1072
|
// Park the pi call: real tool name + args, toolUse stopReason. pi
|
|
1069
1073
|
// executes; the toolResult returns on the next stream call.
|
|
1070
|
-
|
|
1074
|
+
// Driver args are JSON-decoded off the agy wire, so the JsonValue
|
|
1075
|
+
// cast is sound.
|
|
1076
|
+
emitToolUse(stream, blocks, activity.callId, activity.name, activity.args as Record<string, JsonValue>);
|
|
1071
1077
|
return "parked";
|
|
1072
1078
|
}
|
|
1073
1079
|
}
|
|
@@ -1077,7 +1083,7 @@ function acpEditFileArg(args: Record<string, unknown>): string | undefined {
|
|
|
1077
1083
|
async function runTurnDriver(
|
|
1078
1084
|
stream: AssistantMessageEventStream,
|
|
1079
1085
|
model: Model<Api>,
|
|
1080
|
-
context:
|
|
1086
|
+
context: TranscriptContext,
|
|
1081
1087
|
options: SimpleStreamOptions | undefined,
|
|
1082
1088
|
entries: AgyModelEntry[],
|
|
1083
1089
|
store: SessionStore,
|
|
@@ -1179,7 +1185,9 @@ async function runTurnDriver(
|
|
|
1179
1185
|
// Fresh conversation only: agy stores the block in its own history, so
|
|
1180
1186
|
// re-sending it every turn would bloat each prompt and bust the cache.
|
|
1181
1187
|
const sysPrompt =
|
|
1182
|
-
config.systemPrompt && !existing?.conversationId
|
|
1188
|
+
config.systemPrompt && !existing?.conversationId
|
|
1189
|
+
? getCurrentSystemPrompt(context.messages) || undefined
|
|
1190
|
+
: undefined;
|
|
1183
1191
|
const fullPrompt =
|
|
1184
1192
|
late.length > 0
|
|
1185
1193
|
? buildLateResultPrompt(late, prompt || undefined)
|
|
@@ -1258,7 +1266,7 @@ async function runTurnDriver(
|
|
|
1258
1266
|
* fallback). */
|
|
1259
1267
|
export function createStreamSimple(
|
|
1260
1268
|
deps: StreamSimpleDeps,
|
|
1261
|
-
): (model: Model<Api>, context:
|
|
1269
|
+
): (model: Model<Api>, context: TranscriptContext, options?: SimpleStreamOptions) => AssistantMessageEventStream {
|
|
1262
1270
|
const { entries, store, roundTrips } = deps;
|
|
1263
1271
|
|
|
1264
1272
|
return function streamSimple(model, context, options) {
|