@estebanforge/pi-antigravity-bridge 1.3.2 → 1.3.3
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/README.md +3 -1
- package/docs/PI-BRIDGE-GAPS.md +7 -1
- package/extensions/index.ts +17 -2
- package/package.json +1 -1
- package/src/config.ts +17 -0
- package/src/provider.ts +42 -1
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.3.3] - 2026-09-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- pi system prompt injection (G10): pi's composed system prompt - operating instructions plus the global agent-dir `AGENTS.md` and ancestor `AGENTS.md`/`CLAUDE.md` files - is prepended as a delimited block to the first prompt of each NEW agy conversation. agy has no system-prompt flag, so the prompt text is the only delivery path; the block is sent once per conversation and stays byte-identical afterwards, so agy's server-side prompt cache keeps hitting (unlike the per-turn G1 digest, which stays off by default for that reason). On by default (`config.systemPrompt`, `AGY_SYSTEM_PROMPT`, `/agy system-prompt on|off`); existing conversations keep the version they started with.
|
|
10
|
+
|
|
5
11
|
## [1.3.2] - 2026-09-01
|
|
6
12
|
|
|
7
13
|
### Removed
|
package/README.md
CHANGED
|
@@ -91,8 +91,9 @@ If `agy models` fails at load (binary missing, auth not done, network stall), a
|
|
|
91
91
|
| --- | --- | --- |
|
|
92
92
|
| `bridgeTools` | `none` (bridge off), `mcp` (pi-mcp-adapter tools), `all` (every non-builtin tool, incl. other `Ask*` delegations) | `mcp` |
|
|
93
93
|
| `digest` | `off` (stable prompts; agy's prompt cache hits) or `on` (inject a delta of pi-side context - compaction summaries, other-provider turns - into each agy prompt; the delta changes every turn, so agy re-bills the full context). Enable for mixed-provider sessions where agy must see pi-side context | `off` |
|
|
94
|
+
| `systemPrompt` | `on` (prepend pi's system prompt - operating instructions plus the global agent-dir `AGENTS.md` and ancestor `AGENTS.md`/`CLAUDE.md` - to the first prompt of each new agy conversation) or `off` (agy-native behavior) | `on` |
|
|
94
95
|
|
|
95
|
-
Env overrides: `AGY_BRIDGE_TOOLS`, `AGY_DIGEST`.
|
|
96
|
+
Env overrides: `AGY_BRIDGE_TOOLS`, `AGY_DIGEST`, `AGY_SYSTEM_PROMPT`. Env wins over the file, so while `AGY_DIGEST` or `AGY_SYSTEM_PROMPT` is set, the matching `/agy digest` or `/agy system-prompt` toggle persists a value that never takes effect.
|
|
96
97
|
|
|
97
98
|
### The /agy command
|
|
98
99
|
|
|
@@ -108,6 +109,7 @@ Env overrides: `AGY_BRIDGE_TOOLS`, `AGY_DIGEST`.
|
|
|
108
109
|
/agy model flash|pro|gemini default model alias for the AskAntigravity tool
|
|
109
110
|
/agy thinking low|medium|high default thinking tier for the AskAntigravity tool
|
|
110
111
|
/agy digest on|off inject pi-side context into agy prompts (default off; see table above)
|
|
112
|
+
/agy system-prompt on|off send pi's system prompt + AGENTS.md to new agy conversations (default on)
|
|
111
113
|
/agy patch-cleanup restore the original pi files if an older version patched them
|
|
112
114
|
/agy clear drop all session bindings (force fresh conversations)
|
|
113
115
|
```
|
package/docs/PI-BRIDGE-GAPS.md
CHANGED
|
@@ -27,7 +27,13 @@ credentials, so a secret never crosses the bridge, and a long call renders in
|
|
|
27
27
|
pi's native UI while it runs. agy's file edits surface as git-sourced diffs in
|
|
28
28
|
pi's thinking stream. A delta digest of pi-side context (compaction summaries,
|
|
29
29
|
other-provider turns) is available but OFF by default (`/agy digest on`): the
|
|
30
|
-
digest changes every turn and defeats agy's server-side prompt cache.
|
|
30
|
+
digest changes every turn and defeats agy's server-side prompt cache. The
|
|
31
|
+
reverse direction is on by default (`/agy system-prompt off` to disable):
|
|
32
|
+
pi's composed system prompt - its operating instructions plus the global
|
|
33
|
+
agent-dir `AGENTS.md` and ancestor `AGENTS.md`/`CLAUDE.md` files - is
|
|
34
|
+
prepended as a delimited block to the first prompt of each new agy
|
|
35
|
+
conversation, once, so the prompt cache keeps hitting (G10 in
|
|
36
|
+
`CHANGELOG.md`).
|
|
31
37
|
|
|
32
38
|
## Open gaps
|
|
33
39
|
|
package/extensions/index.ts
CHANGED
|
@@ -302,8 +302,9 @@ function statusText(ctx: AgyCommandCtx): string {
|
|
|
302
302
|
` config: ${CONFIG_PATH}`,
|
|
303
303
|
` bridge tools: ${config.bridgeTools}`,
|
|
304
304
|
` digest: ${config.digest ? "on" : "off"}`,
|
|
305
|
+
` system prompt: ${config.systemPrompt ? "on" : "off"}`,
|
|
305
306
|
"",
|
|
306
|
-
"Subcommands: /agy mode plan|accept-edits, /agy permissions on|off, /agy model flash|pro|gemini, /agy thinking low|medium|high, /agy clear",
|
|
307
|
+
"Subcommands: /agy mode plan|accept-edits, /agy permissions on|off, /agy model flash|pro|gemini, /agy thinking low|medium|high, /agy digest on|off, /agy system-prompt on|off, /agy clear",
|
|
307
308
|
].join("\n");
|
|
308
309
|
}
|
|
309
310
|
|
|
@@ -311,7 +312,7 @@ function statusText(ctx: AgyCommandCtx): string {
|
|
|
311
312
|
function registerAgyCommand(pi: ExtensionAPI, ctx: AgyCommandCtx): void {
|
|
312
313
|
pi.registerCommand("agy", {
|
|
313
314
|
description:
|
|
314
|
-
"Antigravity provider: status, doctor, mode picker, clear sessions. Usage: /agy [status|doctor|mode [plan|accept-edits]|digest on|off|patch-cleanup|clear]",
|
|
315
|
+
"Antigravity provider: status, doctor, mode picker, clear sessions. Usage: /agy [status|doctor|mode [plan|accept-edits]|digest on|off|system-prompt on|off|patch-cleanup|clear]",
|
|
315
316
|
handler: async (args, cmdCtx: ExtensionCommandContext) => {
|
|
316
317
|
const ui = cmdCtx.ui;
|
|
317
318
|
const mode = cmdCtx.mode;
|
|
@@ -406,6 +407,20 @@ function registerAgyCommand(pi: ExtensionAPI, ctx: AgyCommandCtx): void {
|
|
|
406
407
|
}
|
|
407
408
|
return;
|
|
408
409
|
}
|
|
410
|
+
if (sub === "system-prompt") {
|
|
411
|
+
if (val === "on" || val === "off") {
|
|
412
|
+
const next = saveConfig({ systemPrompt: val === "on" });
|
|
413
|
+
ui?.notify(
|
|
414
|
+
next.systemPrompt
|
|
415
|
+
? "system-prompt on. pi's system prompt (incl. global and project AGENTS.md) is prepended to the first prompt of each new agy conversation. Existing conversations keep the version they started with."
|
|
416
|
+
: "system-prompt off. agy runs on its own system prompt; pi instructions and AGENTS.md files are not sent.",
|
|
417
|
+
"info",
|
|
418
|
+
);
|
|
419
|
+
} else {
|
|
420
|
+
ui?.notify(`system-prompt: ${loadConfig().systemPrompt ? "on" : "off"}\nusage: /agy system-prompt on|off`, "info");
|
|
421
|
+
}
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
409
424
|
|
|
410
425
|
if (sub === "thinking") {
|
|
411
426
|
if (val === "low" || val === "medium" || val === "high") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estebanforge/pi-antigravity-bridge",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "Streaming Gemini provider for pi, built on the agy CLI. Registers antigravity/* models in pi's /model picker; drives agy through its stream-json protocol (persistent process, tool round-trips, live usage).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
package/src/config.ts
CHANGED
|
@@ -60,6 +60,16 @@ export interface AgyConfig {
|
|
|
60
60
|
* sessions gain nothing: agy already keeps its own history, and bridge
|
|
61
61
|
* round-trips deliver tool results through the bridge, not the digest. */
|
|
62
62
|
digest: boolean;
|
|
63
|
+
/** Prepend pi's composed system prompt (pi tool guidance + the global
|
|
64
|
+
* agent-dir AGENTS.md and ancestor AGENTS.md/CLAUDE.md) to the FIRST
|
|
65
|
+
* prompt of each fresh agy conversation.
|
|
66
|
+
*
|
|
67
|
+
* Default ON: agy keeps its own history, so the prefix is sent once per
|
|
68
|
+
* conversation and stays byte-identical afterwards - agy's server-side
|
|
69
|
+
* prompt cache keeps hitting. This is why it is safe here while the G1
|
|
70
|
+
* digest (per-turn) is not. Turn off for agy-native behavior (agy's own
|
|
71
|
+
* system prompt only). */
|
|
72
|
+
systemPrompt: boolean;
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
const DEFAULTS: AgyConfig = {
|
|
@@ -69,6 +79,7 @@ const DEFAULTS: AgyConfig = {
|
|
|
69
79
|
defaultThinking: "medium",
|
|
70
80
|
bridgeTools: "mcp",
|
|
71
81
|
digest: false,
|
|
82
|
+
systemPrompt: true,
|
|
72
83
|
};
|
|
73
84
|
|
|
74
85
|
/** Load config merged over defaults. Env vars override the file when set. */
|
|
@@ -121,6 +132,11 @@ export function loadConfig(configPath: string = CONFIG_PATH): AgyConfig {
|
|
|
121
132
|
? ["1", "true", "on"].includes(process.env.AGY_DIGEST.toLowerCase())
|
|
122
133
|
: file.digest ?? false;
|
|
123
134
|
|
|
135
|
+
const envSys = process.env.AGY_SYSTEM_PROMPT;
|
|
136
|
+
const systemPrompt = envSys !== undefined
|
|
137
|
+
? ["1", "true", "on"].includes(envSys.toLowerCase())
|
|
138
|
+
: file.systemPrompt ?? DEFAULTS.systemPrompt;
|
|
139
|
+
|
|
124
140
|
return {
|
|
125
141
|
mode,
|
|
126
142
|
skipPermissions,
|
|
@@ -128,6 +144,7 @@ export function loadConfig(configPath: string = CONFIG_PATH): AgyConfig {
|
|
|
128
144
|
defaultThinking,
|
|
129
145
|
bridgeTools,
|
|
130
146
|
digest,
|
|
147
|
+
systemPrompt,
|
|
131
148
|
patchCleanupNotified: file.patchCleanupNotified === true,
|
|
132
149
|
};
|
|
133
150
|
}
|
package/src/provider.ts
CHANGED
|
@@ -84,6 +84,43 @@ const COMPACTION_MARKER = "compacted into the following summary";
|
|
|
84
84
|
const DIGEST_PREAMBLE =
|
|
85
85
|
"[The following is context from the broader pi session that this Antigravity turn was not directly spawned for: compaction summaries and turns handled by other providers or pi's own tools. Your own prior turns are already in your conversation history. Use this for continuity only.]";
|
|
86
86
|
|
|
87
|
+
// --- pi system prompt (G10) ----------------------------------------------------
|
|
88
|
+
//
|
|
89
|
+
// pi composes context.systemPrompt every turn: its own operating instructions
|
|
90
|
+
// plus every AGENTS.md/CLAUDE.md it loaded (global agent dir first, then
|
|
91
|
+
// ancestors). The provider used to drop it, so agy models never saw the user's
|
|
92
|
+
// machine-level or project-level instructions. agy has no system-prompt flag
|
|
93
|
+
// (verified against `agy --help`), so the only delivery path is the prompt
|
|
94
|
+
// text. We prepend it as a delimited block on the FIRST prompt of a fresh
|
|
95
|
+
// conversation only: agy keeps its own history, the block stays byte-identical
|
|
96
|
+
// afterwards, and agy's server-side prompt cache keeps hitting.
|
|
97
|
+
|
|
98
|
+
export const SYSTEM_PROMPT_PREAMBLE =
|
|
99
|
+
"[The following is the system prompt of the pi session that spawned this conversation: operating instructions plus project context (AGENTS.md files). Apply it for this whole conversation. Tool guidance may reference pi-side tools; use your own tools or the pi tool bridge for those actions.]";
|
|
100
|
+
|
|
101
|
+
export const SYSTEM_PROMPT_END = "[END SYSTEM PROMPT]";
|
|
102
|
+
|
|
103
|
+
/** Assemble the full agy prompt: system prompt block, pi-side digest, user
|
|
104
|
+
* prompt. Empty parts are dropped. Pure; exported for unit testing.
|
|
105
|
+
* Pass systemPrompt only on a fresh conversation (see runTurnDriver). */
|
|
106
|
+
export function buildFullPrompt(
|
|
107
|
+
systemPrompt: string | undefined,
|
|
108
|
+
digest: string,
|
|
109
|
+
prompt: string,
|
|
110
|
+
): string {
|
|
111
|
+
const parts: string[] = [];
|
|
112
|
+
if (systemPrompt) {
|
|
113
|
+
parts.push(`${SYSTEM_PROMPT_PREAMBLE}\n\n${systemPrompt}\n\n${SYSTEM_PROMPT_END}`);
|
|
114
|
+
}
|
|
115
|
+
if (digest) {
|
|
116
|
+
parts.push(`${DIGEST_PREAMBLE}\n\n${digest}`);
|
|
117
|
+
}
|
|
118
|
+
if (prompt) {
|
|
119
|
+
parts.push(prompt);
|
|
120
|
+
}
|
|
121
|
+
return parts.join("\n\n---\n\n");
|
|
122
|
+
}
|
|
123
|
+
|
|
87
124
|
/** Flatten any message content shape (string or content-block array) to text.
|
|
88
125
|
* Drops images, thinking, and tool-call blocks. */
|
|
89
126
|
function blocksToText(content: unknown): string {
|
|
@@ -623,7 +660,11 @@ async function runTurnDriver(
|
|
|
623
660
|
const effort = entry?.efforts?.length ? toAgyEffort(options?.reasoning, entry.efforts) : undefined;
|
|
624
661
|
const watermark = existing?.lastMessageCount ?? 0;
|
|
625
662
|
const digest = config.digest ? buildContextDigest(context.messages, watermark) : "";
|
|
626
|
-
|
|
663
|
+
// Fresh conversation only: agy stores the block in its own history, so
|
|
664
|
+
// re-sending it every turn would bloat each prompt and bust the cache.
|
|
665
|
+
const sysPrompt =
|
|
666
|
+
config.systemPrompt && !existing?.conversationId ? context.systemPrompt : undefined;
|
|
667
|
+
const fullPrompt = buildFullPrompt(sysPrompt, digest, prompt);
|
|
627
668
|
try {
|
|
628
669
|
handle = await deps.driver.run({
|
|
629
670
|
cwd,
|