pi-openai-toolkit 0.20.7 → 0.21.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/LICENSE +21 -21
- package/NOTICE +83 -83
- package/README.md +8 -26
- package/README.zh.md +8 -26
- package/config.schema.json +278 -366
- package/docs/configuration.md +294 -310
- package/docs/internals.md +166 -175
- package/package.json +3 -13
- package/src/compact-client.ts +412 -389
- package/src/compaction-errors.ts +96 -0
- package/src/compaction-projection.ts +35 -35
- package/src/config/legacy.ts +519 -717
- package/src/config/migration.ts +103 -100
- package/src/config/notifications.ts +36 -28
- package/src/config/policy.ts +10 -18
- package/src/config/v2.ts +1167 -1380
- package/src/config.ts +310 -319
- package/src/context-management/codex-provider.ts +270 -270
- package/src/context-management/history-notes.ts +357 -357
- package/src/context-management/manual-compact.ts +0 -11
- package/src/context-management/tools.ts +371 -371
- package/src/context-management/types.ts +168 -168
- package/src/context-management/window-manager.ts +801 -801
- package/src/debug.ts +238 -237
- package/src/deferred-tool-carryover.ts +282 -282
- package/src/details-store.ts +151 -151
- package/src/extension-runtime.ts +1662 -1623
- 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 +4 -132
- package/src/payload-rewrite.ts +515 -518
- package/src/pi-context-hook.ts +117 -117
- package/src/remote-v2-client.ts +811 -814
- package/src/request-context-cache.ts +155 -155
- package/src/responses-headers.ts +180 -180
- package/src/runtime.ts +865 -832
- package/src/serializer.ts +882 -882
- package/src/supported-environment.ts +27 -27
- package/src/types.ts +565 -648
- 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 -54
- package/src/auto-mode/classifier.ts +0 -161
- package/src/auto-mode/extension.ts +0 -691
- package/src/auto-mode/model-selection-guard.ts +0 -52
- package/src/auto-mode/policy.ts +0 -146
- package/src/auto-mode/prompt.ts +0 -279
- package/src/auto-mode/reviewer.ts +0 -325
- package/src/auto-mode/tool-review-tui.ts +0 -211
- package/src/auto-mode/transcript.ts +0 -135
- package/src/auto-mode/types.ts +0 -137
|
@@ -1,189 +1,189 @@
|
|
|
1
|
-
import { StringEnum, Type, type Static } from "@earendil-works/pi-ai";
|
|
2
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { loadToolkitConfig, resolveToolkitConfig } from "../config";
|
|
4
|
-
import { notifyConfigIssues } from "../config/notifications";
|
|
5
|
-
import { registerPhysicalModelObserver } from "../runtime";
|
|
6
|
-
import { executeImageGeneration } from "./service";
|
|
7
|
-
import { isImageGenerationEnabledForModel } from "./eligibility";
|
|
8
|
-
import { renderImageGenerationResult } from "./render";
|
|
9
|
-
import {
|
|
10
|
-
IMAGE_GENERATION_QUALITIES,
|
|
11
|
-
IMAGE_GENERATION_SIZES,
|
|
12
|
-
IMAGE_GENERATION_TOOL_NAME,
|
|
13
|
-
MAX_IMAGE_BATCH_SIZE,
|
|
14
|
-
MAX_IMAGE_MODEL_ID_CHARS,
|
|
15
|
-
MAX_IMAGE_PATH_CHARS,
|
|
16
|
-
MAX_IMAGE_PROMPT_CHARS,
|
|
17
|
-
MAX_REFERENCE_IMAGE_COUNT,
|
|
18
|
-
ImageGenerationError,
|
|
19
|
-
sanitizeImageDiagnostic,
|
|
20
|
-
type ImageGenerationToolDetails,
|
|
21
|
-
} from "./types";
|
|
22
|
-
|
|
23
|
-
const registeredApis = new WeakSet<object>();
|
|
24
|
-
|
|
25
|
-
const GenerateImageParameters = Type.Object(
|
|
26
|
-
{
|
|
27
|
-
prompt: Type.String({
|
|
28
|
-
minLength: 1,
|
|
29
|
-
maxLength: MAX_IMAGE_PROMPT_CHARS,
|
|
30
|
-
description: "Image generation or edit prompt. Preserve the user's requested subject and constraints.",
|
|
31
|
-
}),
|
|
32
|
-
referenceImagePaths: Type.Optional(
|
|
33
|
-
Type.Union(
|
|
34
|
-
[
|
|
35
|
-
Type.Null(),
|
|
36
|
-
Type.Array(Type.String({ minLength: 1, maxLength: MAX_IMAGE_PATH_CHARS }), {
|
|
37
|
-
minItems: 1,
|
|
38
|
-
maxItems: MAX_REFERENCE_IMAGE_COUNT,
|
|
39
|
-
}),
|
|
40
|
-
],
|
|
41
|
-
{
|
|
42
|
-
description:
|
|
43
|
-
"Use null when the user did not explicitly identify reference images; otherwise provide one to five user-identified local image paths.",
|
|
44
|
-
},
|
|
45
|
-
),
|
|
46
|
-
),
|
|
47
|
-
outputPath: Type.Optional(
|
|
48
|
-
Type.Union(
|
|
49
|
-
[
|
|
50
|
-
Type.Null(),
|
|
51
|
-
Type.String({
|
|
52
|
-
minLength: 1,
|
|
53
|
-
maxLength: MAX_IMAGE_PATH_CHARS,
|
|
54
|
-
}),
|
|
55
|
-
],
|
|
56
|
-
{
|
|
57
|
-
description:
|
|
58
|
-
"Use null when the user did not explicitly request a destination; otherwise provide an explicit .png, .jpg, .jpeg, or .webp file path matching the provider output format.",
|
|
59
|
-
},
|
|
60
|
-
),
|
|
61
|
-
),
|
|
62
|
-
size: Type.Optional(
|
|
63
|
-
StringEnum(IMAGE_GENERATION_SIZES, {
|
|
64
|
-
description: "Requested raster-image dimensions, or auto.",
|
|
65
|
-
}),
|
|
66
|
-
),
|
|
67
|
-
quality: Type.Optional(
|
|
68
|
-
StringEnum(IMAGE_GENERATION_QUALITIES, {
|
|
69
|
-
description: "Requested image quality, or auto.",
|
|
70
|
-
}),
|
|
71
|
-
),
|
|
72
|
-
model: Type.Optional(
|
|
73
|
-
Type.Union(
|
|
74
|
-
[
|
|
75
|
-
Type.Null(),
|
|
76
|
-
Type.String({
|
|
77
|
-
minLength: 1,
|
|
78
|
-
maxLength: MAX_IMAGE_MODEL_ID_CHARS,
|
|
79
|
-
}),
|
|
80
|
-
],
|
|
81
|
-
{
|
|
82
|
-
description:
|
|
83
|
-
"Use null to accept the default image model, configured by imageGeneration.defaultModel; otherwise provide another model id exactly as it appears in that configured list.",
|
|
84
|
-
},
|
|
85
|
-
),
|
|
86
|
-
),
|
|
87
|
-
batchSize: Type.Optional(
|
|
88
|
-
Type.Union(
|
|
89
|
-
[
|
|
90
|
-
Type.Null(),
|
|
91
|
-
Type.Integer({ minimum: 1, maximum: MAX_IMAGE_BATCH_SIZE }),
|
|
92
|
-
],
|
|
93
|
-
{
|
|
94
|
-
description:
|
|
95
|
-
"Run this many independent image requests concurrently (1-10). Batch requests use generated artifacts and cannot set outputPath.",
|
|
96
|
-
},
|
|
97
|
-
),
|
|
98
|
-
),
|
|
99
|
-
},
|
|
100
|
-
{ additionalProperties: false },
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
type GenerateImageToolParams = Static<typeof GenerateImageParameters>;
|
|
104
|
-
|
|
105
|
-
function syncImageGenerationTool(
|
|
106
|
-
pi: ExtensionAPI,
|
|
107
|
-
model: Parameters<typeof isImageGenerationEnabledForModel>[0],
|
|
108
|
-
config: Parameters<typeof isImageGenerationEnabledForModel>[1],
|
|
109
|
-
): void {
|
|
110
|
-
const eligible = isImageGenerationEnabledForModel(model, config);
|
|
111
|
-
const activeTools = pi.getActiveTools();
|
|
112
|
-
const active = activeTools.includes(IMAGE_GENERATION_TOOL_NAME);
|
|
113
|
-
if (eligible && !active) {
|
|
114
|
-
pi.setActiveTools([...activeTools, IMAGE_GENERATION_TOOL_NAME]);
|
|
115
|
-
} else if (!eligible && active) {
|
|
116
|
-
pi.setActiveTools(activeTools.filter((name) => name !== IMAGE_GENERATION_TOOL_NAME));
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export function registerImageGenerationExtension(
|
|
121
|
-
pi: ExtensionAPI,
|
|
122
|
-
loadConfig: typeof loadToolkitConfig = loadToolkitConfig,
|
|
123
|
-
executeImage: typeof executeImageGeneration = executeImageGeneration,
|
|
124
|
-
): void {
|
|
125
|
-
if (registeredApis.has(pi)) return;
|
|
126
|
-
registeredApis.add(pi);
|
|
127
|
-
registerPhysicalModelObserver(pi);
|
|
128
|
-
|
|
129
|
-
pi.registerTool<typeof GenerateImageParameters, ImageGenerationToolDetails, Record<string, never>>({
|
|
130
|
-
name: IMAGE_GENERATION_TOOL_NAME,
|
|
131
|
-
label: "OpenAI Generate Image",
|
|
132
|
-
description:
|
|
133
|
-
"Generate raster images, or edit from one to five user-approved local reference images, through an independent Images API request using a configured image model. PNG, JPEG, and WebP responses are validated and saved in their actual format. This is a paid provider operation; batchSize runs independent requests concurrently.",
|
|
134
|
-
promptSnippet: "Generate or edit raster images through an independent Images API request and a configured imageGeneration.allowedModels entry.",
|
|
135
|
-
promptGuidelines: [
|
|
136
|
-
"Use openai_generate_image when the user explicitly asks to create, draw, render, or edit a raster image and the active model speaks a Responses API.",
|
|
137
|
-
"Do not call openai_generate_image speculatively: it consumes the user's provider or gateway image quota.",
|
|
138
|
-
"Keep the image prompt faithful to the user's requested subject and constraints; do not invent unrequested style details.",
|
|
139
|
-
"Set referenceImagePaths to null unless the user explicitly identified local files; never invent paths or placeholder strings, and remember upload requires user approval.",
|
|
140
|
-
"Set outputPath to null unless the user explicitly asks for a destination; never invent a destination or placeholder string, and otherwise use the default Pi agent artifact.",
|
|
141
|
-
"Set model to null unless the user named an image model configured in imageGeneration.allowedModels; never invent or guess a model id, and remember an unlisted model fails before the paid request.",
|
|
142
|
-
"Use batchSize only when the user asks for multiple variants; each batch item is an independent paid request, and batchSize cannot be combined with outputPath.",
|
|
143
|
-
"Do not substitute Python, browser automation, shell scripts, or unrelated image tools for an eligible image request.",
|
|
144
|
-
],
|
|
145
|
-
parameters: GenerateImageParameters,
|
|
146
|
-
executionMode: "sequential",
|
|
147
|
-
async execute(toolCallId, params: GenerateImageToolParams, signal, _onUpdate, ctx) {
|
|
148
|
-
try {
|
|
149
|
-
const result = await executeImage({
|
|
150
|
-
params,
|
|
151
|
-
toolCallId,
|
|
152
|
-
signal,
|
|
153
|
-
ctx,
|
|
154
|
-
});
|
|
155
|
-
return {
|
|
156
|
-
content: [{ type: "text", text: result.text }],
|
|
157
|
-
details: result.details,
|
|
158
|
-
};
|
|
159
|
-
} catch (error) {
|
|
160
|
-
if (error instanceof ImageGenerationError) {
|
|
161
|
-
throw new Error(error.message);
|
|
162
|
-
}
|
|
163
|
-
throw new Error(
|
|
164
|
-
sanitizeImageDiagnostic(error instanceof Error ? error.message : error, "Image generation failed."),
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
renderResult: renderImageGenerationResult,
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
const synchronize = (ctx: Parameters<typeof executeImageGeneration>[0]["ctx"], model = ctx.model) => {
|
|
172
|
-
const resolved = resolveToolkitConfig(loadConfig(), model);
|
|
173
|
-
notifyConfigIssues(ctx, resolved);
|
|
174
|
-
const valid = !resolved.invalidFeatures.some((feature) => feature === "imageGeneration" || feature === "compatibility");
|
|
175
|
-
syncImageGenerationTool(pi, model, { ...resolved.config.imageGeneration, enabled: valid && resolved.policy.imageGeneration.enabled });
|
|
176
|
-
};
|
|
177
|
-
pi.on("session_start", (_event, ctx) => synchronize(ctx));
|
|
178
|
-
pi.on("model_select", (event, ctx) => synchronize(ctx, event.model));
|
|
179
|
-
pi.on("before_agent_start", (_event, ctx) => synchronize(ctx));
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export default function imageGenerationExtension(pi: ExtensionAPI): void {
|
|
183
|
-
registerImageGenerationExtension(pi);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export const _extensionTest = {
|
|
187
|
-
GenerateImageParameters,
|
|
188
|
-
syncImageGenerationTool,
|
|
189
|
-
};
|
|
1
|
+
import { StringEnum, Type, type Static } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { loadToolkitConfig, resolveToolkitConfig } from "../config";
|
|
4
|
+
import { notifyConfigIssues } from "../config/notifications";
|
|
5
|
+
import { registerPhysicalModelObserver } from "../runtime";
|
|
6
|
+
import { executeImageGeneration } from "./service";
|
|
7
|
+
import { isImageGenerationEnabledForModel } from "./eligibility";
|
|
8
|
+
import { renderImageGenerationResult } from "./render";
|
|
9
|
+
import {
|
|
10
|
+
IMAGE_GENERATION_QUALITIES,
|
|
11
|
+
IMAGE_GENERATION_SIZES,
|
|
12
|
+
IMAGE_GENERATION_TOOL_NAME,
|
|
13
|
+
MAX_IMAGE_BATCH_SIZE,
|
|
14
|
+
MAX_IMAGE_MODEL_ID_CHARS,
|
|
15
|
+
MAX_IMAGE_PATH_CHARS,
|
|
16
|
+
MAX_IMAGE_PROMPT_CHARS,
|
|
17
|
+
MAX_REFERENCE_IMAGE_COUNT,
|
|
18
|
+
ImageGenerationError,
|
|
19
|
+
sanitizeImageDiagnostic,
|
|
20
|
+
type ImageGenerationToolDetails,
|
|
21
|
+
} from "./types";
|
|
22
|
+
|
|
23
|
+
const registeredApis = new WeakSet<object>();
|
|
24
|
+
|
|
25
|
+
const GenerateImageParameters = Type.Object(
|
|
26
|
+
{
|
|
27
|
+
prompt: Type.String({
|
|
28
|
+
minLength: 1,
|
|
29
|
+
maxLength: MAX_IMAGE_PROMPT_CHARS,
|
|
30
|
+
description: "Image generation or edit prompt. Preserve the user's requested subject and constraints.",
|
|
31
|
+
}),
|
|
32
|
+
referenceImagePaths: Type.Optional(
|
|
33
|
+
Type.Union(
|
|
34
|
+
[
|
|
35
|
+
Type.Null(),
|
|
36
|
+
Type.Array(Type.String({ minLength: 1, maxLength: MAX_IMAGE_PATH_CHARS }), {
|
|
37
|
+
minItems: 1,
|
|
38
|
+
maxItems: MAX_REFERENCE_IMAGE_COUNT,
|
|
39
|
+
}),
|
|
40
|
+
],
|
|
41
|
+
{
|
|
42
|
+
description:
|
|
43
|
+
"Use null when the user did not explicitly identify reference images; otherwise provide one to five user-identified local image paths.",
|
|
44
|
+
},
|
|
45
|
+
),
|
|
46
|
+
),
|
|
47
|
+
outputPath: Type.Optional(
|
|
48
|
+
Type.Union(
|
|
49
|
+
[
|
|
50
|
+
Type.Null(),
|
|
51
|
+
Type.String({
|
|
52
|
+
minLength: 1,
|
|
53
|
+
maxLength: MAX_IMAGE_PATH_CHARS,
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
{
|
|
57
|
+
description:
|
|
58
|
+
"Use null when the user did not explicitly request a destination; otherwise provide an explicit .png, .jpg, .jpeg, or .webp file path matching the provider output format.",
|
|
59
|
+
},
|
|
60
|
+
),
|
|
61
|
+
),
|
|
62
|
+
size: Type.Optional(
|
|
63
|
+
StringEnum(IMAGE_GENERATION_SIZES, {
|
|
64
|
+
description: "Requested raster-image dimensions, or auto.",
|
|
65
|
+
}),
|
|
66
|
+
),
|
|
67
|
+
quality: Type.Optional(
|
|
68
|
+
StringEnum(IMAGE_GENERATION_QUALITIES, {
|
|
69
|
+
description: "Requested image quality, or auto.",
|
|
70
|
+
}),
|
|
71
|
+
),
|
|
72
|
+
model: Type.Optional(
|
|
73
|
+
Type.Union(
|
|
74
|
+
[
|
|
75
|
+
Type.Null(),
|
|
76
|
+
Type.String({
|
|
77
|
+
minLength: 1,
|
|
78
|
+
maxLength: MAX_IMAGE_MODEL_ID_CHARS,
|
|
79
|
+
}),
|
|
80
|
+
],
|
|
81
|
+
{
|
|
82
|
+
description:
|
|
83
|
+
"Use null to accept the default image model, configured by imageGeneration.defaultModel; otherwise provide another model id exactly as it appears in that configured list.",
|
|
84
|
+
},
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
batchSize: Type.Optional(
|
|
88
|
+
Type.Union(
|
|
89
|
+
[
|
|
90
|
+
Type.Null(),
|
|
91
|
+
Type.Integer({ minimum: 1, maximum: MAX_IMAGE_BATCH_SIZE }),
|
|
92
|
+
],
|
|
93
|
+
{
|
|
94
|
+
description:
|
|
95
|
+
"Run this many independent image requests concurrently (1-10). Batch requests use generated artifacts and cannot set outputPath.",
|
|
96
|
+
},
|
|
97
|
+
),
|
|
98
|
+
),
|
|
99
|
+
},
|
|
100
|
+
{ additionalProperties: false },
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
type GenerateImageToolParams = Static<typeof GenerateImageParameters>;
|
|
104
|
+
|
|
105
|
+
function syncImageGenerationTool(
|
|
106
|
+
pi: ExtensionAPI,
|
|
107
|
+
model: Parameters<typeof isImageGenerationEnabledForModel>[0],
|
|
108
|
+
config: Parameters<typeof isImageGenerationEnabledForModel>[1],
|
|
109
|
+
): void {
|
|
110
|
+
const eligible = isImageGenerationEnabledForModel(model, config);
|
|
111
|
+
const activeTools = pi.getActiveTools();
|
|
112
|
+
const active = activeTools.includes(IMAGE_GENERATION_TOOL_NAME);
|
|
113
|
+
if (eligible && !active) {
|
|
114
|
+
pi.setActiveTools([...activeTools, IMAGE_GENERATION_TOOL_NAME]);
|
|
115
|
+
} else if (!eligible && active) {
|
|
116
|
+
pi.setActiveTools(activeTools.filter((name) => name !== IMAGE_GENERATION_TOOL_NAME));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function registerImageGenerationExtension(
|
|
121
|
+
pi: ExtensionAPI,
|
|
122
|
+
loadConfig: typeof loadToolkitConfig = loadToolkitConfig,
|
|
123
|
+
executeImage: typeof executeImageGeneration = executeImageGeneration,
|
|
124
|
+
): void {
|
|
125
|
+
if (registeredApis.has(pi)) return;
|
|
126
|
+
registeredApis.add(pi);
|
|
127
|
+
registerPhysicalModelObserver(pi);
|
|
128
|
+
|
|
129
|
+
pi.registerTool<typeof GenerateImageParameters, ImageGenerationToolDetails, Record<string, never>>({
|
|
130
|
+
name: IMAGE_GENERATION_TOOL_NAME,
|
|
131
|
+
label: "OpenAI Generate Image",
|
|
132
|
+
description:
|
|
133
|
+
"Generate raster images, or edit from one to five user-approved local reference images, through an independent Images API request using a configured image model. PNG, JPEG, and WebP responses are validated and saved in their actual format. This is a paid provider operation; batchSize runs independent requests concurrently.",
|
|
134
|
+
promptSnippet: "Generate or edit raster images through an independent Images API request and a configured imageGeneration.allowedModels entry.",
|
|
135
|
+
promptGuidelines: [
|
|
136
|
+
"Use openai_generate_image when the user explicitly asks to create, draw, render, or edit a raster image and the active model speaks a Responses API.",
|
|
137
|
+
"Do not call openai_generate_image speculatively: it consumes the user's provider or gateway image quota.",
|
|
138
|
+
"Keep the image prompt faithful to the user's requested subject and constraints; do not invent unrequested style details.",
|
|
139
|
+
"Set referenceImagePaths to null unless the user explicitly identified local files; never invent paths or placeholder strings, and remember upload requires user approval.",
|
|
140
|
+
"Set outputPath to null unless the user explicitly asks for a destination; never invent a destination or placeholder string, and otherwise use the default Pi agent artifact.",
|
|
141
|
+
"Set model to null unless the user named an image model configured in imageGeneration.allowedModels; never invent or guess a model id, and remember an unlisted model fails before the paid request.",
|
|
142
|
+
"Use batchSize only when the user asks for multiple variants; each batch item is an independent paid request, and batchSize cannot be combined with outputPath.",
|
|
143
|
+
"Do not substitute Python, browser automation, shell scripts, or unrelated image tools for an eligible image request.",
|
|
144
|
+
],
|
|
145
|
+
parameters: GenerateImageParameters,
|
|
146
|
+
executionMode: "sequential",
|
|
147
|
+
async execute(toolCallId, params: GenerateImageToolParams, signal, _onUpdate, ctx) {
|
|
148
|
+
try {
|
|
149
|
+
const result = await executeImage({
|
|
150
|
+
params,
|
|
151
|
+
toolCallId,
|
|
152
|
+
signal,
|
|
153
|
+
ctx,
|
|
154
|
+
});
|
|
155
|
+
return {
|
|
156
|
+
content: [{ type: "text", text: result.text }],
|
|
157
|
+
details: result.details,
|
|
158
|
+
};
|
|
159
|
+
} catch (error) {
|
|
160
|
+
if (error instanceof ImageGenerationError) {
|
|
161
|
+
throw new Error(error.message);
|
|
162
|
+
}
|
|
163
|
+
throw new Error(
|
|
164
|
+
sanitizeImageDiagnostic(error instanceof Error ? error.message : error, "Image generation failed."),
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
renderResult: renderImageGenerationResult,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const synchronize = (ctx: Parameters<typeof executeImageGeneration>[0]["ctx"], model = ctx.model) => {
|
|
172
|
+
const resolved = resolveToolkitConfig(loadConfig(), model);
|
|
173
|
+
notifyConfigIssues(ctx, resolved);
|
|
174
|
+
const valid = !resolved.invalidFeatures.some((feature) => feature === "imageGeneration" || feature === "compatibility");
|
|
175
|
+
syncImageGenerationTool(pi, model, { ...resolved.config.imageGeneration, enabled: valid && resolved.policy.imageGeneration.enabled });
|
|
176
|
+
};
|
|
177
|
+
pi.on("session_start", (_event, ctx) => synchronize(ctx));
|
|
178
|
+
pi.on("model_select", (event, ctx) => synchronize(ctx, event.model));
|
|
179
|
+
pi.on("before_agent_start", (_event, ctx) => synchronize(ctx));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export default function imageGenerationExtension(pi: ExtensionAPI): void {
|
|
183
|
+
registerImageGenerationExtension(pi);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export const _extensionTest = {
|
|
187
|
+
GenerateImageParameters,
|
|
188
|
+
syncImageGenerationTool,
|
|
189
|
+
};
|