pi-openai-toolkit 0.24.0 → 0.24.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/LICENSE +21 -21
- package/NOTICE +83 -83
- package/config.schema.json +264 -264
- package/docs/configuration.md +304 -304
- package/package.json +123 -123
- package/src/compact-client.ts +412 -412
- package/src/compaction-projection.ts +35 -35
- package/src/config/legacy.ts +469 -469
- package/src/config/migration.ts +115 -115
- package/src/config/notifications.ts +46 -42
- package/src/config/policy.ts +115 -115
- package/src/config/v2.ts +1128 -1128
- package/src/config.ts +320 -320
- package/src/debug.ts +238 -238
- package/src/deferred-tool-carryover.ts +282 -282
- package/src/details-store.ts +151 -151
- package/src/extension-runtime.ts +1095 -1095
- package/src/image-generation/extension.ts +189 -189
- package/src/image-generation/protocol.ts +579 -579
- package/src/image-generation/types.ts +300 -300
- package/src/native-fallback.ts +140 -140
- package/src/payload-rewrite.ts +515 -515
- package/src/pi-context-hook.ts +117 -117
- package/src/remote-v2-client.ts +811 -811
- package/src/request-context-cache.ts +155 -155
- package/src/responses-headers.ts +180 -180
- package/src/retired-remote-windows.ts +35 -35
- package/src/runtime.ts +875 -875
- package/src/serializer.ts +882 -882
- package/src/supported-environment.ts +27 -27
- package/src/types.ts +541 -541
- package/src/web-search/alpha-client.ts +876 -876
- package/src/web-search/extension.ts +530 -530
- package/src/web-search/payload.ts +299 -299
- package/src/web-search/prompt.ts +60 -60
- package/src/web-search/types.ts +166 -166
- package/tsconfig.check.json +50 -50
package/src/native-fallback.ts
CHANGED
|
@@ -1,140 +1,140 @@
|
|
|
1
|
-
import {
|
|
2
|
-
compact,
|
|
3
|
-
type CompactionResult,
|
|
4
|
-
type ExtensionContext,
|
|
5
|
-
type SessionBeforeCompactEvent,
|
|
6
|
-
} from "@earendil-works/pi-coding-agent";
|
|
7
|
-
import type { ProviderHeaders } from "@earendil-works/pi-ai";
|
|
8
|
-
import { mergeProviderHeaders } from "./provider-headers";
|
|
9
|
-
import { parseModelSpec } from "./runtime";
|
|
10
|
-
import type { CompactionConfig } from "./types";
|
|
11
|
-
|
|
12
|
-
export { parseModelSpec } from "./runtime";
|
|
13
|
-
|
|
14
|
-
export type NativeFallbackFailureReason =
|
|
15
|
-
| "disabled"
|
|
16
|
-
| "no-model-configured"
|
|
17
|
-
| "invalid-model-spec"
|
|
18
|
-
| "model-not-found"
|
|
19
|
-
| "same-as-current-model"
|
|
20
|
-
| "auth-failed"
|
|
21
|
-
| "aborted"
|
|
22
|
-
| "empty-summary"
|
|
23
|
-
| "compact-failed";
|
|
24
|
-
|
|
25
|
-
export type NativeFallbackResult =
|
|
26
|
-
| {
|
|
27
|
-
ok: true;
|
|
28
|
-
result: CompactionResult;
|
|
29
|
-
model: { provider: string; id: string };
|
|
30
|
-
}
|
|
31
|
-
| {
|
|
32
|
-
ok: false;
|
|
33
|
-
reason: NativeFallbackFailureReason;
|
|
34
|
-
modelSpec?: string;
|
|
35
|
-
errorMessage?: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/** pi's exported native compact(); injectable for tests. */
|
|
39
|
-
export type NativeCompactFn = typeof compact;
|
|
40
|
-
|
|
41
|
-
type ResolvedAuth =
|
|
42
|
-
| { ok: true; apiKey?: string; headers?: ProviderHeaders; baseUrl?: string; env?: Record<string, string> }
|
|
43
|
-
| { ok: false; error: string };
|
|
44
|
-
|
|
45
|
-
function isAbortError(error: unknown): boolean {
|
|
46
|
-
return (
|
|
47
|
-
(error instanceof DOMException && error.name === "AbortError") ||
|
|
48
|
-
(error instanceof Error && (error.name === "AbortError" || error.name === "ABORT_ERR"))
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function toErrorMessage(error: unknown): string {
|
|
53
|
-
return error instanceof Error ? error.message : String(error);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Run pi's native compaction method with a caller-resolved summary model.
|
|
58
|
-
*
|
|
59
|
-
* The two compaction chains stay separate: the caller passes `remoteCompactModel` only when a
|
|
60
|
-
* remote v2 request was actually attempted and failed, and `nativeFallback.model` only when the
|
|
61
|
-
* active model cannot use remote v2 at all. This function never inspects `remoteCompactModel`
|
|
62
|
-
* itself, so a model that cannot compact remotely can never inherit the remote producer.
|
|
63
|
-
*
|
|
64
|
-
* Unset or same-current-model defaults stay with Pi. This helper does not
|
|
65
|
-
* select a session model or take ownership of Pi's scheduler.
|
|
66
|
-
*/
|
|
67
|
-
export async function runNativeFallbackCompaction(args: {
|
|
68
|
-
ctx: ExtensionContext;
|
|
69
|
-
event: SessionBeforeCompactEvent;
|
|
70
|
-
config: CompactionConfig;
|
|
71
|
-
/** Model spec supplied by the caller for this specific fallback reason. */
|
|
72
|
-
modelSpec?: string;
|
|
73
|
-
compactFn?: NativeCompactFn;
|
|
74
|
-
/** Reject results if the originating session/branch/selection changed. */
|
|
75
|
-
isCurrent?: () => boolean;
|
|
76
|
-
}): Promise<NativeFallbackResult> {
|
|
77
|
-
const { ctx, event, config } = args;
|
|
78
|
-
const compactFn = args.compactFn ?? compact;
|
|
79
|
-
const nativeFallback = config.nativeFallback;
|
|
80
|
-
const isCurrent = () => !event.signal.aborted && (args.isCurrent?.() ?? true);
|
|
81
|
-
if (!isCurrent()) return { ok: false, reason: "aborted" };
|
|
82
|
-
|
|
83
|
-
if (!nativeFallback.enabled) return { ok: false, reason: "disabled" };
|
|
84
|
-
const spec = args.modelSpec?.trim() ?? "";
|
|
85
|
-
if (!spec) return { ok: false, reason: "no-model-configured" };
|
|
86
|
-
const parsed = parseModelSpec(spec);
|
|
87
|
-
if (!parsed) return { ok: false, reason: "invalid-model-spec", modelSpec: spec };
|
|
88
|
-
const model = ctx.modelRegistry.find(parsed.provider, parsed.modelId);
|
|
89
|
-
if (!model) return { ok: false, reason: "model-not-found", modelSpec: spec };
|
|
90
|
-
if (ctx.model && ctx.model.provider === model.provider && ctx.model.id === model.id) {
|
|
91
|
-
return { ok: false, reason: "same-as-current-model", modelSpec: spec };
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Pi owns prompt construction, tool-result truncation and split-turn requests.
|
|
95
|
-
// A chars/4 estimate is not target-model token accounting and must not veto
|
|
96
|
-
// the user's summary model. Surface actual provider failures to the caller.
|
|
97
|
-
|
|
98
|
-
let auth: ResolvedAuth;
|
|
99
|
-
try {
|
|
100
|
-
auth = (await ctx.modelRegistry.getApiKeyAndHeaders(model)) as ResolvedAuth;
|
|
101
|
-
} catch (error) {
|
|
102
|
-
return { ok: false, reason: "auth-failed", modelSpec: spec, errorMessage: toErrorMessage(error) };
|
|
103
|
-
}
|
|
104
|
-
if (!auth.ok) {
|
|
105
|
-
return { ok: false, reason: "auth-failed", modelSpec: spec, errorMessage: auth.error };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!isCurrent()) return { ok: false, reason: "aborted", modelSpec: spec };
|
|
109
|
-
try {
|
|
110
|
-
const result = await compactFn(
|
|
111
|
-
event.preparation,
|
|
112
|
-
auth.baseUrl ? { ...model, baseUrl: auth.baseUrl } : model,
|
|
113
|
-
auth.apiKey,
|
|
114
|
-
mergeProviderHeaders(auth.headers),
|
|
115
|
-
event.customInstructions,
|
|
116
|
-
event.signal,
|
|
117
|
-
nativeFallback.thinkingLevel,
|
|
118
|
-
undefined,
|
|
119
|
-
auth.env,
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
if (!isCurrent()) {
|
|
123
|
-
return { ok: false, reason: "aborted", modelSpec: spec };
|
|
124
|
-
}
|
|
125
|
-
if (!result.summary || result.summary.trim().length === 0) {
|
|
126
|
-
return { ok: false, reason: "empty-summary", modelSpec: spec };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
ok: true,
|
|
131
|
-
result,
|
|
132
|
-
model: { provider: model.provider, id: model.id },
|
|
133
|
-
};
|
|
134
|
-
} catch (error) {
|
|
135
|
-
if (event.signal.aborted || isAbortError(error)) {
|
|
136
|
-
return { ok: false, reason: "aborted", modelSpec: spec };
|
|
137
|
-
}
|
|
138
|
-
return { ok: false, reason: "compact-failed", modelSpec: spec, errorMessage: toErrorMessage(error) };
|
|
139
|
-
}
|
|
140
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
compact,
|
|
3
|
+
type CompactionResult,
|
|
4
|
+
type ExtensionContext,
|
|
5
|
+
type SessionBeforeCompactEvent,
|
|
6
|
+
} from "@earendil-works/pi-coding-agent";
|
|
7
|
+
import type { ProviderHeaders } from "@earendil-works/pi-ai";
|
|
8
|
+
import { mergeProviderHeaders } from "./provider-headers";
|
|
9
|
+
import { parseModelSpec } from "./runtime";
|
|
10
|
+
import type { CompactionConfig } from "./types";
|
|
11
|
+
|
|
12
|
+
export { parseModelSpec } from "./runtime";
|
|
13
|
+
|
|
14
|
+
export type NativeFallbackFailureReason =
|
|
15
|
+
| "disabled"
|
|
16
|
+
| "no-model-configured"
|
|
17
|
+
| "invalid-model-spec"
|
|
18
|
+
| "model-not-found"
|
|
19
|
+
| "same-as-current-model"
|
|
20
|
+
| "auth-failed"
|
|
21
|
+
| "aborted"
|
|
22
|
+
| "empty-summary"
|
|
23
|
+
| "compact-failed";
|
|
24
|
+
|
|
25
|
+
export type NativeFallbackResult =
|
|
26
|
+
| {
|
|
27
|
+
ok: true;
|
|
28
|
+
result: CompactionResult;
|
|
29
|
+
model: { provider: string; id: string };
|
|
30
|
+
}
|
|
31
|
+
| {
|
|
32
|
+
ok: false;
|
|
33
|
+
reason: NativeFallbackFailureReason;
|
|
34
|
+
modelSpec?: string;
|
|
35
|
+
errorMessage?: string;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/** pi's exported native compact(); injectable for tests. */
|
|
39
|
+
export type NativeCompactFn = typeof compact;
|
|
40
|
+
|
|
41
|
+
type ResolvedAuth =
|
|
42
|
+
| { ok: true; apiKey?: string; headers?: ProviderHeaders; baseUrl?: string; env?: Record<string, string> }
|
|
43
|
+
| { ok: false; error: string };
|
|
44
|
+
|
|
45
|
+
function isAbortError(error: unknown): boolean {
|
|
46
|
+
return (
|
|
47
|
+
(error instanceof DOMException && error.name === "AbortError") ||
|
|
48
|
+
(error instanceof Error && (error.name === "AbortError" || error.name === "ABORT_ERR"))
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function toErrorMessage(error: unknown): string {
|
|
53
|
+
return error instanceof Error ? error.message : String(error);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Run pi's native compaction method with a caller-resolved summary model.
|
|
58
|
+
*
|
|
59
|
+
* The two compaction chains stay separate: the caller passes `remoteCompactModel` only when a
|
|
60
|
+
* remote v2 request was actually attempted and failed, and `nativeFallback.model` only when the
|
|
61
|
+
* active model cannot use remote v2 at all. This function never inspects `remoteCompactModel`
|
|
62
|
+
* itself, so a model that cannot compact remotely can never inherit the remote producer.
|
|
63
|
+
*
|
|
64
|
+
* Unset or same-current-model defaults stay with Pi. This helper does not
|
|
65
|
+
* select a session model or take ownership of Pi's scheduler.
|
|
66
|
+
*/
|
|
67
|
+
export async function runNativeFallbackCompaction(args: {
|
|
68
|
+
ctx: ExtensionContext;
|
|
69
|
+
event: SessionBeforeCompactEvent;
|
|
70
|
+
config: CompactionConfig;
|
|
71
|
+
/** Model spec supplied by the caller for this specific fallback reason. */
|
|
72
|
+
modelSpec?: string;
|
|
73
|
+
compactFn?: NativeCompactFn;
|
|
74
|
+
/** Reject results if the originating session/branch/selection changed. */
|
|
75
|
+
isCurrent?: () => boolean;
|
|
76
|
+
}): Promise<NativeFallbackResult> {
|
|
77
|
+
const { ctx, event, config } = args;
|
|
78
|
+
const compactFn = args.compactFn ?? compact;
|
|
79
|
+
const nativeFallback = config.nativeFallback;
|
|
80
|
+
const isCurrent = () => !event.signal.aborted && (args.isCurrent?.() ?? true);
|
|
81
|
+
if (!isCurrent()) return { ok: false, reason: "aborted" };
|
|
82
|
+
|
|
83
|
+
if (!nativeFallback.enabled) return { ok: false, reason: "disabled" };
|
|
84
|
+
const spec = args.modelSpec?.trim() ?? "";
|
|
85
|
+
if (!spec) return { ok: false, reason: "no-model-configured" };
|
|
86
|
+
const parsed = parseModelSpec(spec);
|
|
87
|
+
if (!parsed) return { ok: false, reason: "invalid-model-spec", modelSpec: spec };
|
|
88
|
+
const model = ctx.modelRegistry.find(parsed.provider, parsed.modelId);
|
|
89
|
+
if (!model) return { ok: false, reason: "model-not-found", modelSpec: spec };
|
|
90
|
+
if (ctx.model && ctx.model.provider === model.provider && ctx.model.id === model.id) {
|
|
91
|
+
return { ok: false, reason: "same-as-current-model", modelSpec: spec };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Pi owns prompt construction, tool-result truncation and split-turn requests.
|
|
95
|
+
// A chars/4 estimate is not target-model token accounting and must not veto
|
|
96
|
+
// the user's summary model. Surface actual provider failures to the caller.
|
|
97
|
+
|
|
98
|
+
let auth: ResolvedAuth;
|
|
99
|
+
try {
|
|
100
|
+
auth = (await ctx.modelRegistry.getApiKeyAndHeaders(model)) as ResolvedAuth;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return { ok: false, reason: "auth-failed", modelSpec: spec, errorMessage: toErrorMessage(error) };
|
|
103
|
+
}
|
|
104
|
+
if (!auth.ok) {
|
|
105
|
+
return { ok: false, reason: "auth-failed", modelSpec: spec, errorMessage: auth.error };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (!isCurrent()) return { ok: false, reason: "aborted", modelSpec: spec };
|
|
109
|
+
try {
|
|
110
|
+
const result = await compactFn(
|
|
111
|
+
event.preparation,
|
|
112
|
+
auth.baseUrl ? { ...model, baseUrl: auth.baseUrl } : model,
|
|
113
|
+
auth.apiKey,
|
|
114
|
+
mergeProviderHeaders(auth.headers),
|
|
115
|
+
event.customInstructions,
|
|
116
|
+
event.signal,
|
|
117
|
+
nativeFallback.thinkingLevel,
|
|
118
|
+
undefined,
|
|
119
|
+
auth.env,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (!isCurrent()) {
|
|
123
|
+
return { ok: false, reason: "aborted", modelSpec: spec };
|
|
124
|
+
}
|
|
125
|
+
if (!result.summary || result.summary.trim().length === 0) {
|
|
126
|
+
return { ok: false, reason: "empty-summary", modelSpec: spec };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
ok: true,
|
|
131
|
+
result,
|
|
132
|
+
model: { provider: model.provider, id: model.id },
|
|
133
|
+
};
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (event.signal.aborted || isAbortError(error)) {
|
|
136
|
+
return { ok: false, reason: "aborted", modelSpec: spec };
|
|
137
|
+
}
|
|
138
|
+
return { ok: false, reason: "compact-failed", modelSpec: spec, errorMessage: toErrorMessage(error) };
|
|
139
|
+
}
|
|
140
|
+
}
|