pi-spark 0.27.0 → 0.28.1
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 +20 -0
- package/docs/background-model-calls-and-openai-codex-sessions.md +2 -0
- package/package.json +9 -9
- package/src/features/credits/providers/openai-codex.ts +1 -1
- package/src/features/presets/selector.ts +9 -7
- package/src/features/recap/idle.ts +2 -2
- package/src/features/recap/manager.ts +2 -2
- package/src/features/title/manager.ts +1 -1
- package/src/utils/model.ts +3 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.28.1](https://github.com/zlliang/pi-spark/compare/v0.28.0...v0.28.1) (2026-10-04)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* isolate background sessions for all providers, closes [#82](https://github.com/zlliang/pi-spark/issues/82) ([1ade72b](https://github.com/zlliang/pi-spark/commit/1ade72b71d2799ce3eeb0517f9ad0694f50e9d3a))
|
|
9
|
+
* **presets:** keep selector order and focus active preset ([b688b4d](https://github.com/zlliang/pi-spark/commit/b688b4dac32100e3c07e7d7d1dc84a8161d7f4b5))
|
|
10
|
+
* support Pi 1.0 ([c7bd177](https://github.com/zlliang/pi-spark/commit/c7bd1770e2d5134c6951be16a9c1fc5e5ab594fa))
|
|
11
|
+
|
|
12
|
+
## [0.28.0](https://github.com/zlliang/pi-spark/compare/v0.27.0...v0.28.0) (2026-09-22)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### ⚠ BREAKING CHANGES
|
|
16
|
+
|
|
17
|
+
* use Pi 0.87 context projections for recaps and titles
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
* use Pi 0.87 context projections for recaps and titles ([a822fa3](https://github.com/zlliang/pi-spark/commit/a822fa350f1146123d46a7dbf53d812947ff7b49))
|
|
22
|
+
|
|
3
23
|
## [0.27.0](https://github.com/zlliang/pi-spark/compare/v0.26.0...v0.27.0) (2026-09-20)
|
|
4
24
|
|
|
5
25
|
|
|
@@ -77,3 +77,5 @@ Use the [`measuring-model-cache`](../.agents/skills/measuring-model-cache/SKILL.
|
|
|
77
77
|
---
|
|
78
78
|
|
|
79
79
|
**Update Sep 19, 2026:** Background calls now use Pi 0.86's `ctx.modelRegistry.streamSimple(...).result()` to support extension-registered providers and resolve authentication automatically. Independent Codex UUIDv7 sessions and cleanup in `finally` remain unchanged.
|
|
80
|
+
|
|
81
|
+
**Update Oct 4, 2026:** OpenCode also requires a session ID, sent as the `x-opencode-session` header. Every background call now gets an independent UUIDv7 session ID, regardless of provider.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-spark",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Pi package that polishes your daily experience",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-coding-agent",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"zod": "^4.4.3"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@earendil-works/pi-agent-core": ">=0.
|
|
48
|
-
"@earendil-works/pi-ai": ">=0.
|
|
49
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
50
|
-
"@earendil-works/pi-tui": ">=0.
|
|
47
|
+
"@earendil-works/pi-agent-core": ">=1.0.0",
|
|
48
|
+
"@earendil-works/pi-ai": ">=1.0.0",
|
|
49
|
+
"@earendil-works/pi-coding-agent": ">=1.0.0",
|
|
50
|
+
"@earendil-works/pi-tui": ">=1.0.0",
|
|
51
51
|
"typebox": "*"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@earendil-works/pi-agent-core": ">=0.
|
|
55
|
-
"@earendil-works/pi-ai": ">=0.
|
|
56
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
57
|
-
"@earendil-works/pi-tui": ">=0.
|
|
54
|
+
"@earendil-works/pi-agent-core": ">=1.0.0",
|
|
55
|
+
"@earendil-works/pi-ai": ">=1.0.0",
|
|
56
|
+
"@earendil-works/pi-coding-agent": ">=1.0.0",
|
|
57
|
+
"@earendil-works/pi-tui": ">=1.0.0",
|
|
58
58
|
"@types/node": "*",
|
|
59
59
|
"typebox": "*",
|
|
60
60
|
"typescript": "^7.0.2"
|
|
@@ -12,13 +12,11 @@ export async function showPresetSelector(ctx: ExtensionContext, presetManager: P
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const selected = await ctx.ui.custom<string | null>((tui, theme, _keybindings, done) => {
|
|
15
|
-
const items = presetManager.keys
|
|
16
|
-
|
|
17
|
-
.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
description: presetManager.describe(key),
|
|
21
|
-
}));
|
|
15
|
+
const items = presetManager.keys.map((key) => ({
|
|
16
|
+
value: key,
|
|
17
|
+
label: presetManager.isActive(ctx, key) ? `${key} ${theme.fg("success", "✓")} ` : key,
|
|
18
|
+
description: presetManager.describe(key),
|
|
19
|
+
}));
|
|
22
20
|
|
|
23
21
|
const container = new Container();
|
|
24
22
|
container.addChild(new DynamicBorder((s: string) => theme.fg("border", s)));
|
|
@@ -34,6 +32,10 @@ export async function showPresetSelector(ctx: ExtensionContext, presetManager: P
|
|
|
34
32
|
scrollInfo: (text) => theme.fg("dim", text),
|
|
35
33
|
noMatch: (text) => theme.fg("warning", text),
|
|
36
34
|
});
|
|
35
|
+
|
|
36
|
+
const activeIndex = presetManager.keys.findIndex((key) => presetManager.isActive(ctx, key));
|
|
37
|
+
if (activeIndex > 0) selectList.setSelectedIndex(activeIndex);
|
|
38
|
+
|
|
37
39
|
selectList.onSelect = (item) => done(item.value);
|
|
38
40
|
selectList.onCancel = () => done(null);
|
|
39
41
|
box.addChild(selectList);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import parseDuration from "parse-duration";
|
|
2
2
|
import * as z from "zod";
|
|
3
|
-
import { convertToLlm
|
|
3
|
+
import { convertToLlm } from "@earendil-works/pi-coding-agent";
|
|
4
4
|
|
|
5
5
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
@@ -69,7 +69,7 @@ export class IdleListener {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
private check(ctx: ExtensionContext): void {
|
|
72
|
-
const canEnter = ctx.isIdle() && ctx.sessionManager.
|
|
72
|
+
const canEnter = ctx.isIdle() && convertToLlm(ctx.sessionManager.buildSessionProjection().messages).some((message) => message.role !== "system");
|
|
73
73
|
if (!canEnter) {
|
|
74
74
|
this.lastEditorText = undefined;
|
|
75
75
|
if (this.entered) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { convertToLlm, serializeConversation
|
|
1
|
+
import { convertToLlm, serializeConversation } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
3
|
import { clearRecapWidget, setRecapLoadingWidget, setRecapTextWidget } from "./widget";
|
|
4
4
|
import { sanitizeText } from "../../utils/format";
|
|
@@ -109,7 +109,7 @@ export class RecapManager {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
private buildPrompt(ctx: ExtensionContext): string {
|
|
112
|
-
const messages = ctx.sessionManager.
|
|
112
|
+
const messages = ctx.sessionManager.buildSessionProjection().messages;
|
|
113
113
|
const text = serializeConversation(convertToLlm(messages));
|
|
114
114
|
const conversation = text.length > MAX_CONVERSATION_CHARS ? text.slice(-MAX_CONVERSATION_CHARS) : text;
|
|
115
115
|
|
|
@@ -91,7 +91,7 @@ export class TitleManager {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
private buildPrompt(ctx: ExtensionContext): string {
|
|
94
|
-
const messages = ctx.sessionManager.
|
|
94
|
+
const messages = ctx.sessionManager.buildSessionProjection().messages;
|
|
95
95
|
const text = serializeConversation(convertToLlm(messages));
|
|
96
96
|
const conversation = text.length > MAX_CONVERSATION_CHARS ? text.slice(0, MAX_CONVERSATION_CHARS) : text;
|
|
97
97
|
|
package/src/utils/model.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { uuidv7 } from "@earendil-works/pi-
|
|
2
|
-
import { clampThinkingLevel, cleanupSessionResources } from "@earendil-works/pi-ai";
|
|
1
|
+
import { clampThinkingLevel, cleanupSessionResources, uuidv7 } from "@earendil-works/pi-ai";
|
|
3
2
|
|
|
4
3
|
import { formatModel } from "./format";
|
|
5
4
|
|
|
@@ -26,12 +25,11 @@ type ThinkingLevelSelection = {
|
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
|
-
* Completes a one-shot background request
|
|
28
|
+
* Completes a one-shot background request in an isolated session, so providers that route by
|
|
29
|
+
* session, such as OpenAI Codex and OpenCode, keep it apart from the main thread.
|
|
30
30
|
* See [the investigation](../../docs/background-model-calls-and-openai-codex-sessions.md).
|
|
31
31
|
*/
|
|
32
32
|
export async function completeBackground(ctx: ExtensionContext, model: Model<Api>, context: Context, options?: ModelsSimpleStreamOptions): Promise<AssistantMessage> {
|
|
33
|
-
if (model.api !== "openai-codex-responses") return ctx.modelRegistry.streamSimple(model, context, options).result();
|
|
34
|
-
|
|
35
33
|
const sessionId = uuidv7();
|
|
36
34
|
|
|
37
35
|
try {
|