@code-yeongyu/senpi 2026.9.9-2 → 2026.9.9
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 +1 -22
- package/dist/core/agent-session.d.ts +1 -8
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +0 -33
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +1 -4
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
- package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +4 -47
- package/dist/core/extensions/builtin/imagegen/tool.d.ts +19 -10
- package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -1
- package/dist/core/extensions/builtin/imagegen/tool.js +45 -21
- package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +8 -17
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +0 -5
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/resource-loader.d.ts +0 -2
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +7 -11
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -13
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -5
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -21
- package/dist/core/tools/read.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +0 -4
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +0 -3
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/docs/skills.md +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +0 -12
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +6 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +33 -15
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +1 -31
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +1 -31
- package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/images.d.ts +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/images.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/images.js +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/images.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/core/extensions/builtin/compaction/resume-admission.d.ts +0 -7
- package/dist/core/extensions/builtin/compaction/resume-admission.d.ts.map +0 -1
- package/dist/core/extensions/builtin/compaction/resume-admission.js +0 -7
- package/dist/core/extensions/builtin/compaction/resume-admission.js.map +0 -1
- package/dist/core/extensions/builtin/imagegen/params.d.ts +0 -36
- package/dist/core/extensions/builtin/imagegen/params.d.ts.map +0 -1
- package/dist/core/extensions/builtin/imagegen/params.js +0 -55
- package/dist/core/extensions/builtin/imagegen/params.js.map +0 -1
- package/dist/core/extensions/builtin/imagegen/reference-images.d.ts +0 -11
- package/dist/core/extensions/builtin/imagegen/reference-images.d.ts.map +0 -1
- package/dist/core/extensions/builtin/imagegen/reference-images.js +0 -55
- package/dist/core/extensions/builtin/imagegen/reference-images.js.map +0 -1
- package/dist/core/tools/read-classifiers.d.ts +0 -17
- package/dist/core/tools/read-classifiers.d.ts.map +0 -1
- package/dist/core/tools/read-classifiers.js +0 -26
- package/dist/core/tools/read-classifiers.js.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts +0 -4
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js +0 -11
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts +0 -25
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts.map +0 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js +0 -58
- package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAkC,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnF,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EACN,KAAK,qBAAqB,EAM1B,MAAM,4BAA4B,CAAC;AAkBpC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,8BAA8B,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACtE,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE,CAAC;
|
|
1
|
+
{"version":3,"file":"session-stream.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAkC,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnF,OAAO,KAAK,EAAE,UAAU,EAAkB,MAAM,mBAAmB,CAAC;AAGpE,OAAO,EACN,KAAK,qBAAqB,EAM1B,MAAM,4BAA4B,CAAC;AAkBpC,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,eAAe,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACxC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,mBAAmB,CAAC;IACnC,gBAAgB,EAAE,8BAA8B,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IACtE,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACpE,CAAC;AA4IF,wBAAuB,uBAAuB,CAAC,KAAK,EAAE,0BAA0B,GAAG,cAAc,CAAC,UAAU,CAAC,CAW5G"}
|
|
@@ -19,9 +19,6 @@ const OBSERVED_KIND = {
|
|
|
19
19
|
flatten: "cold-seed",
|
|
20
20
|
bootstrap: "cold-seed",
|
|
21
21
|
};
|
|
22
|
-
function contextHasPriorAssistantMessage(context) {
|
|
23
|
-
return context.messages.some((message) => message.role === "assistant");
|
|
24
|
-
}
|
|
25
22
|
function entrySnapshot(entry, hashes) {
|
|
26
23
|
return {
|
|
27
24
|
sdkSessionId: entry.sdkSessionId,
|
|
@@ -56,7 +53,7 @@ async function createResidentAttempt(input, auth) {
|
|
|
56
53
|
crossAccountResumeSupported: auth.authLane !== "config-dir",
|
|
57
54
|
idleExpired: existing ? isIdleExpired(existing) : false,
|
|
58
55
|
});
|
|
59
|
-
const firstTurn = existing === undefined && getBinding(sessionId) === undefined &&
|
|
56
|
+
const firstTurn = existing === undefined && getBinding(sessionId) === undefined && hashes.length <= 1;
|
|
60
57
|
let observedReason = "reason" in decision ? decision.reason : decision.kind === "bootstrap" ? "registry_miss" : undefined;
|
|
61
58
|
let observedKind = OBSERVED_KIND[decision.kind];
|
|
62
59
|
let entry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Context, Model, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { type AuthenticatedAttemptInput, queryWithAuthLane } from \"./auth-lane.ts\";\nimport { buildPromptBlocks } from \"./prompt-bridge.ts\";\nimport { dedupeUltraworkBlocks, serializedPayloadBytes } from \"./prompt-directive-dedupe.ts\";\nimport type { SDKMessage, SDKUserMessage } from \"./sdk-boundary.ts\";\nimport { getSdkBoundary } from \"./sdk-boundary.ts\";\nimport { type ContinuityDecision, decideNativeContinuity } from \"./session-continuity.ts\";\nimport {\n\ttype ContinuityObservation,\n\tconsumePendingCloseCause,\n\temitContinuityObservation,\n\tobserveSessionSyncDecision,\n\tsanitizeTerminalFailure,\n\tstageContinuityDecision,\n} from \"./session-observability.ts\";\nimport { bindingFromEntry, getBinding, reattachSession } from \"./session-reattach.ts\";\nimport {\n\ttype ClaudeSdkOauthSessionEntry,\n\tcloseSession,\n\tgetOrCreateSession,\n\tgetSession,\n\tisIdleExpired,\n} from \"./session-registry.ts\";\nimport { admitRestoredBinding } from \"./session-restored-admission.ts\";\nimport {\n\tbuildDeltaPromptBlocks,\n\tconfigFingerprint,\n\tsentHashesForEntry,\n\tsentMessageHashes,\n\tsentMessages,\n} from \"./session-sync.ts\";\nimport { createSessionTurnAttempt } from \"./session-turn-attempt.ts\";\nimport type { ClaudeSdkOauthProviderSettings } from \"./settings.ts\";\n\nexport type ResidentSessionStreamInput = {\n\tmodel: Model<Api>;\n\tcontext: Context;\n\tstreamOptions: SimpleStreamOptions;\n\tproviderSettings: ClaudeSdkOauthProviderSettings;\n\tpinnedAccount?: string;\n\tbuildOptions: Parameters<typeof queryWithAuthLane>[0][\"buildOptions\"];\n\tcustomToolNameToSdk: ReadonlyMap<string, string>;\n\ttoolWatchNote?: string;\n\tonResumeFallback: (error: unknown) => void;\n\tonContinuityDecision?: (observation: ContinuityObservation) => void;\n};\n\nfunction userMessage(content: SDKUserMessage[\"message\"][\"content\"]): SDKUserMessage[\"message\"] {\n\treturn { role: \"user\", content } as SDKUserMessage[\"message\"];\n}\n\nconst OBSERVED_KIND: Record<ContinuityDecision[\"kind\"], \"incremental\" | \"resume\" | \"cold-seed\"> = {\n\tdelta: \"incremental\",\n\treattach: \"resume\",\n\tfork: \"resume\",\n\tflatten: \"cold-seed\",\n\tbootstrap: \"cold-seed\",\n};\n\nfunction contextHasPriorAssistantMessage(context: Context): boolean {\n\treturn context.messages.some((message) => message.role === \"assistant\");\n}\n\nfunction entrySnapshot(entry: ClaudeSdkOauthSessionEntry, hashes: readonly string[]) {\n\treturn {\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t\tsentCount: entry.sentCount,\n\t\tsentHashes: hashes.slice(0, entry.sentCount),\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(entry.sentCount) ?? null,\n\t\tassistantUuidByIndex: entry.assistantUuidByIndex,\n\t\tpendingForkReason: entry.pendingForkReason,\n\t\ttaintedReason: entry.taintedReason,\n\t};\n}\n\nasync function createResidentAttempt(\n\tinput: ResidentSessionStreamInput,\n\tauth: AuthenticatedAttemptInput,\n): Promise<ReturnType<typeof createSessionTurnAttempt>> {\n\tconst sessionId = input.streamOptions.sessionId!;\n\tconst messages = sentMessages(input.context);\n\tconst hashes = sentMessageHashes(messages);\n\tconst existing = getSession(sessionId);\n\tconst fingerprint = configFingerprint(auth.options, input.context, auth.authLane, auth.accountName);\n\tconst residentHashes = existing ? (sentHashesForEntry(existing) ?? hashes) : hashes;\n\tconst { binding, transcriptAvailable } = await admitRestoredBinding(sessionId, auth.options.cwd, auth.authLane);\n\tconst decision = decideNativeContinuity({\n\t\tentry: existing ? entrySnapshot(existing, residentHashes) : undefined,\n\t\tbinding,\n\t\tcurrentHashes: hashes,\n\t\taccountName: auth.accountName,\n\t\tmodelId: input.model.id,\n\t\tfingerprint,\n\t\ttranscriptAvailable,\n\t\tcrossAccountResumeSupported: auth.authLane !== \"config-dir\",\n\t\tidleExpired: existing ? isIdleExpired(existing) : false,\n\t});\n\tconst firstTurn =\n\t\texisting === undefined && getBinding(sessionId) === undefined && !contextHasPriorAssistantMessage(input.context);\n\tlet observedReason =\n\t\t\"reason\" in decision ? decision.reason : decision.kind === \"bootstrap\" ? \"registry_miss\" : undefined;\n\tlet observedKind: \"incremental\" | \"resume\" | \"cold-seed\" = OBSERVED_KIND[decision.kind];\n\tlet entry: ClaudeSdkOauthSessionEntry;\n\tlet from = 0;\n\tlet flatten = decision.kind === \"flatten\" || decision.kind === \"bootstrap\";\n\n\tif (decision.kind === \"delta\" && existing) {\n\t\tentry = existing;\n\t\tfrom = decision.from;\n\t} else if (decision.kind === \"reattach\" || decision.kind === \"fork\") {\n\t\tconst source = getBinding(sessionId) ?? (existing ? bindingFromEntry(existing, residentHashes) : undefined);\n\t\tconst binding = source\n\t\t\t? (({ sentPrefixHash: _persistedPrefix, ...rest }) => ({\n\t\t\t\t\t...rest,\n\t\t\t\t\tsentCount: decision.from,\n\t\t\t\t\tsentHashes: hashes.slice(0, decision.from),\n\t\t\t\t\tassistantUuidByIndex: (source.assistantUuidByIndex ?? []).filter(([index]) => index <= decision.from),\n\t\t\t\t\taccountName: auth.accountName,\n\t\t\t\t\tmodelId: input.model.id,\n\t\t\t\t\tsystemPromptHash: fingerprint.systemPromptHash,\n\t\t\t\t\ttoolsetHash: fingerprint.toolsetHash,\n\t\t\t\t\t...(decision.kind === \"fork\" ? { lastAssistantUuid: decision.atUuid } : {}),\n\t\t\t\t}))(source)\n\t\t\t: undefined;\n\t\ttry {\n\t\t\tif (!binding) throw new Error(\"Claude SDK OAuth continuity binding is unavailable\");\n\t\t\tentry = await reattachSession({\n\t\t\t\tbinding,\n\t\t\t\toptions: auth.options,\n\t\t\t\t...(decision.kind === \"fork\" ? { atUuid: decision.atUuid } : {}),\n\t\t\t\t...(input.streamOptions.signal ? { signal: input.streamOptions.signal } : {}),\n\t\t\t});\n\t\t\tfrom = decision.from;\n\t\t} catch (error) {\n\t\t\tif (input.streamOptions.signal?.aborted) throw error;\n\t\t\tinput.onResumeFallback(error);\n\t\t\tobservedKind = \"cold-seed\";\n\t\t\tobservedReason = \"resume_initialization_failed\";\n\t\t\tflatten = true;\n\t\t\tentry = getOrCreateSession({\n\t\t\t\tsenpiSessionId: sessionId,\n\t\t\t\taccountName: auth.accountName,\n\t\t\t\tmodelId: input.model.id,\n\t\t\t\t...fingerprint,\n\t\t\t\toptions: auth.options,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (existing) closeSession(sessionId, observedReason ?? \"registry_miss\");\n\t\tentry = getOrCreateSession({\n\t\t\tsenpiSessionId: sessionId,\n\t\t\taccountName: auth.accountName,\n\t\t\tmodelId: input.model.id,\n\t\t\t...fingerprint,\n\t\t\toptions: auth.options,\n\t\t});\n\t}\n\n\tconst flattenResult = flatten\n\t\t? dedupeUltraworkBlocks(buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote))\n\t\t: undefined;\n\tconst blocks = flattenResult\n\t\t? flattenResult.blocks\n\t\t: buildDeltaPromptBlocks(messages.slice(from), input.customToolNameToSdk);\n\tconst payloadBytes = flattenResult ? serializedPayloadBytes(flattenResult.blocks) : undefined;\n\tconst staged = stageContinuityDecision(\n\t\tobserveSessionSyncDecision({\n\t\t\tkind: observedKind,\n\t\t\treason: observedReason,\n\t\t\tdeltaMessages: flatten ? hashes.length : hashes.length - from,\n\t\t\tfirstTurn,\n\t\t\tsenpiSessionId: sessionId,\n\t\t\t...(payloadBytes !== undefined ? { payloadBytes } : {}),\n\t\t\t...(flattenResult?.collapsedDirectives !== undefined\n\t\t\t\t? { collapsedDirectives: flattenResult.collapsedDirectives }\n\t\t\t\t: {}),\n\t\t}),\n\t\tinput.onContinuityDecision,\n\t\t// The pending close cause is consumed only when the staged observation\n\t\t// actually emits (attempt retained) — a discarded attempt leaves the\n\t\t// cause pending for the next admission.\n\t\t() => consumePendingCloseCause(sessionId),\n\t);\n\treturn createSessionTurnAttempt(entry, userMessage(blocks), hashes, input.streamOptions.signal, staged);\n}\n\nexport async function* residentSessionMessages(input: ResidentSessionStreamInput): AsyncGenerator<SDKMessage> {\n\ttry {\n\t\tyield* residentAuthLaneMessages(input);\n\t} catch (error) {\n\t\t// Every attempt failed: the turn yields exactly one terminal observation.\n\t\temitContinuityObservation(\n\t\t\t{ kind: \"flatten\", reason: sanitizeTerminalFailure(error) },\n\t\t\tinput.onContinuityDecision,\n\t\t);\n\t\tthrow error;\n\t}\n}\n\nfunction residentAuthLaneMessages(input: ResidentSessionStreamInput): AsyncIterable<SDKMessage> {\n\treturn queryWithAuthLane({\n\t\tprompt: \"\",\n\t\tquery: getSdkBoundary().query,\n\t\tproviderSettings: input.providerSettings,\n\t\tenv: input.streamOptions.env,\n\t\tsignal: input.streamOptions.signal,\n\t\tsessionId: input.streamOptions.affinitySessionId ?? input.streamOptions.sessionId,\n\t\tpinnedAccount: input.pinnedAccount,\n\t\tbuildOptions: input.buildOptions,\n\t\tcreateAttempt: (auth) => createResidentAttempt(input, auth),\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"session-stream.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/session-stream.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Context, Model, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { type AuthenticatedAttemptInput, queryWithAuthLane } from \"./auth-lane.ts\";\nimport { buildPromptBlocks } from \"./prompt-bridge.ts\";\nimport { dedupeUltraworkBlocks, serializedPayloadBytes } from \"./prompt-directive-dedupe.ts\";\nimport type { SDKMessage, SDKUserMessage } from \"./sdk-boundary.ts\";\nimport { getSdkBoundary } from \"./sdk-boundary.ts\";\nimport { type ContinuityDecision, decideNativeContinuity } from \"./session-continuity.ts\";\nimport {\n\ttype ContinuityObservation,\n\tconsumePendingCloseCause,\n\temitContinuityObservation,\n\tobserveSessionSyncDecision,\n\tsanitizeTerminalFailure,\n\tstageContinuityDecision,\n} from \"./session-observability.ts\";\nimport { bindingFromEntry, getBinding, reattachSession } from \"./session-reattach.ts\";\nimport {\n\ttype ClaudeSdkOauthSessionEntry,\n\tcloseSession,\n\tgetOrCreateSession,\n\tgetSession,\n\tisIdleExpired,\n} from \"./session-registry.ts\";\nimport { admitRestoredBinding } from \"./session-restored-admission.ts\";\nimport {\n\tbuildDeltaPromptBlocks,\n\tconfigFingerprint,\n\tsentHashesForEntry,\n\tsentMessageHashes,\n\tsentMessages,\n} from \"./session-sync.ts\";\nimport { createSessionTurnAttempt } from \"./session-turn-attempt.ts\";\nimport type { ClaudeSdkOauthProviderSettings } from \"./settings.ts\";\n\nexport type ResidentSessionStreamInput = {\n\tmodel: Model<Api>;\n\tcontext: Context;\n\tstreamOptions: SimpleStreamOptions;\n\tproviderSettings: ClaudeSdkOauthProviderSettings;\n\tpinnedAccount?: string;\n\tbuildOptions: Parameters<typeof queryWithAuthLane>[0][\"buildOptions\"];\n\tcustomToolNameToSdk: ReadonlyMap<string, string>;\n\ttoolWatchNote?: string;\n\tonResumeFallback: (error: unknown) => void;\n\tonContinuityDecision?: (observation: ContinuityObservation) => void;\n};\n\nfunction userMessage(content: SDKUserMessage[\"message\"][\"content\"]): SDKUserMessage[\"message\"] {\n\treturn { role: \"user\", content } as SDKUserMessage[\"message\"];\n}\n\nconst OBSERVED_KIND: Record<ContinuityDecision[\"kind\"], \"incremental\" | \"resume\" | \"cold-seed\"> = {\n\tdelta: \"incremental\",\n\treattach: \"resume\",\n\tfork: \"resume\",\n\tflatten: \"cold-seed\",\n\tbootstrap: \"cold-seed\",\n};\n\nfunction entrySnapshot(entry: ClaudeSdkOauthSessionEntry, hashes: readonly string[]) {\n\treturn {\n\t\tsdkSessionId: entry.sdkSessionId,\n\t\taccountName: entry.accountName,\n\t\tmodelId: entry.modelId,\n\t\tsystemPromptHash: entry.systemPromptHash,\n\t\ttoolsetHash: entry.toolsetHash,\n\t\tsentCount: entry.sentCount,\n\t\tsentHashes: hashes.slice(0, entry.sentCount),\n\t\tlastAssistantUuid: entry.assistantUuidByIndex.get(entry.sentCount) ?? null,\n\t\tassistantUuidByIndex: entry.assistantUuidByIndex,\n\t\tpendingForkReason: entry.pendingForkReason,\n\t\ttaintedReason: entry.taintedReason,\n\t};\n}\n\nasync function createResidentAttempt(\n\tinput: ResidentSessionStreamInput,\n\tauth: AuthenticatedAttemptInput,\n): Promise<ReturnType<typeof createSessionTurnAttempt>> {\n\tconst sessionId = input.streamOptions.sessionId!;\n\tconst messages = sentMessages(input.context);\n\tconst hashes = sentMessageHashes(messages);\n\tconst existing = getSession(sessionId);\n\tconst fingerprint = configFingerprint(auth.options, input.context, auth.authLane, auth.accountName);\n\tconst residentHashes = existing ? (sentHashesForEntry(existing) ?? hashes) : hashes;\n\tconst { binding, transcriptAvailable } = await admitRestoredBinding(sessionId, auth.options.cwd, auth.authLane);\n\tconst decision = decideNativeContinuity({\n\t\tentry: existing ? entrySnapshot(existing, residentHashes) : undefined,\n\t\tbinding,\n\t\tcurrentHashes: hashes,\n\t\taccountName: auth.accountName,\n\t\tmodelId: input.model.id,\n\t\tfingerprint,\n\t\ttranscriptAvailable,\n\t\tcrossAccountResumeSupported: auth.authLane !== \"config-dir\",\n\t\tidleExpired: existing ? isIdleExpired(existing) : false,\n\t});\n\tconst firstTurn = existing === undefined && getBinding(sessionId) === undefined && hashes.length <= 1;\n\tlet observedReason =\n\t\t\"reason\" in decision ? decision.reason : decision.kind === \"bootstrap\" ? \"registry_miss\" : undefined;\n\tlet observedKind: \"incremental\" | \"resume\" | \"cold-seed\" = OBSERVED_KIND[decision.kind];\n\tlet entry: ClaudeSdkOauthSessionEntry;\n\tlet from = 0;\n\tlet flatten = decision.kind === \"flatten\" || decision.kind === \"bootstrap\";\n\n\tif (decision.kind === \"delta\" && existing) {\n\t\tentry = existing;\n\t\tfrom = decision.from;\n\t} else if (decision.kind === \"reattach\" || decision.kind === \"fork\") {\n\t\tconst source = getBinding(sessionId) ?? (existing ? bindingFromEntry(existing, residentHashes) : undefined);\n\t\tconst binding = source\n\t\t\t? (({ sentPrefixHash: _persistedPrefix, ...rest }) => ({\n\t\t\t\t\t...rest,\n\t\t\t\t\tsentCount: decision.from,\n\t\t\t\t\tsentHashes: hashes.slice(0, decision.from),\n\t\t\t\t\tassistantUuidByIndex: (source.assistantUuidByIndex ?? []).filter(([index]) => index <= decision.from),\n\t\t\t\t\taccountName: auth.accountName,\n\t\t\t\t\tmodelId: input.model.id,\n\t\t\t\t\tsystemPromptHash: fingerprint.systemPromptHash,\n\t\t\t\t\ttoolsetHash: fingerprint.toolsetHash,\n\t\t\t\t\t...(decision.kind === \"fork\" ? { lastAssistantUuid: decision.atUuid } : {}),\n\t\t\t\t}))(source)\n\t\t\t: undefined;\n\t\ttry {\n\t\t\tif (!binding) throw new Error(\"Claude SDK OAuth continuity binding is unavailable\");\n\t\t\tentry = await reattachSession({\n\t\t\t\tbinding,\n\t\t\t\toptions: auth.options,\n\t\t\t\t...(decision.kind === \"fork\" ? { atUuid: decision.atUuid } : {}),\n\t\t\t\t...(input.streamOptions.signal ? { signal: input.streamOptions.signal } : {}),\n\t\t\t});\n\t\t\tfrom = decision.from;\n\t\t} catch (error) {\n\t\t\tif (input.streamOptions.signal?.aborted) throw error;\n\t\t\tinput.onResumeFallback(error);\n\t\t\tobservedKind = \"cold-seed\";\n\t\t\tobservedReason = \"resume_initialization_failed\";\n\t\t\tflatten = true;\n\t\t\tentry = getOrCreateSession({\n\t\t\t\tsenpiSessionId: sessionId,\n\t\t\t\taccountName: auth.accountName,\n\t\t\t\tmodelId: input.model.id,\n\t\t\t\t...fingerprint,\n\t\t\t\toptions: auth.options,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (existing) closeSession(sessionId, observedReason ?? \"registry_miss\");\n\t\tentry = getOrCreateSession({\n\t\t\tsenpiSessionId: sessionId,\n\t\t\taccountName: auth.accountName,\n\t\t\tmodelId: input.model.id,\n\t\t\t...fingerprint,\n\t\t\toptions: auth.options,\n\t\t});\n\t}\n\n\tconst flattenResult = flatten\n\t\t? dedupeUltraworkBlocks(buildPromptBlocks(input.context, input.customToolNameToSdk, input.toolWatchNote))\n\t\t: undefined;\n\tconst blocks = flattenResult\n\t\t? flattenResult.blocks\n\t\t: buildDeltaPromptBlocks(messages.slice(from), input.customToolNameToSdk);\n\tconst payloadBytes = flattenResult ? serializedPayloadBytes(flattenResult.blocks) : undefined;\n\tconst staged = stageContinuityDecision(\n\t\tobserveSessionSyncDecision({\n\t\t\tkind: observedKind,\n\t\t\treason: observedReason,\n\t\t\tdeltaMessages: flatten ? hashes.length : hashes.length - from,\n\t\t\tfirstTurn,\n\t\t\tsenpiSessionId: sessionId,\n\t\t\t...(payloadBytes !== undefined ? { payloadBytes } : {}),\n\t\t\t...(flattenResult?.collapsedDirectives !== undefined\n\t\t\t\t? { collapsedDirectives: flattenResult.collapsedDirectives }\n\t\t\t\t: {}),\n\t\t}),\n\t\tinput.onContinuityDecision,\n\t\t// The pending close cause is consumed only when the staged observation\n\t\t// actually emits (attempt retained) — a discarded attempt leaves the\n\t\t// cause pending for the next admission.\n\t\t() => consumePendingCloseCause(sessionId),\n\t);\n\treturn createSessionTurnAttempt(entry, userMessage(blocks), hashes, input.streamOptions.signal, staged);\n}\n\nexport async function* residentSessionMessages(input: ResidentSessionStreamInput): AsyncGenerator<SDKMessage> {\n\ttry {\n\t\tyield* residentAuthLaneMessages(input);\n\t} catch (error) {\n\t\t// Every attempt failed: the turn yields exactly one terminal observation.\n\t\temitContinuityObservation(\n\t\t\t{ kind: \"flatten\", reason: sanitizeTerminalFailure(error) },\n\t\t\tinput.onContinuityDecision,\n\t\t);\n\t\tthrow error;\n\t}\n}\n\nfunction residentAuthLaneMessages(input: ResidentSessionStreamInput): AsyncIterable<SDKMessage> {\n\treturn queryWithAuthLane({\n\t\tprompt: \"\",\n\t\tquery: getSdkBoundary().query,\n\t\tproviderSettings: input.providerSettings,\n\t\tenv: input.streamOptions.env,\n\t\tsignal: input.streamOptions.signal,\n\t\tsessionId: input.streamOptions.affinitySessionId ?? input.streamOptions.sessionId,\n\t\tpinnedAccount: input.pinnedAccount,\n\t\tbuildOptions: input.buildOptions,\n\t\tcreateAttempt: (auth) => createResidentAttempt(input, auth),\n\t});\n}\n"]}
|
|
@@ -12,7 +12,7 @@ How to write image prompts that come back right the first time, and how to fix t
|
|
|
12
12
|
When image generation tooling is present in your tool set, pick the surface that actually exists right now:
|
|
13
13
|
|
|
14
14
|
- If a native `image_generation` server tool is available, use it. The provider runs generation server-side and returns the image in the response stream.
|
|
15
|
-
- Otherwise, call the `generate_image` tool. It sends your prompt
|
|
15
|
+
- Otherwise, call the `generate_image` tool. It sends your prompt to the configured OpenAI-compatible endpoint and saves the result to a file.
|
|
16
16
|
|
|
17
17
|
Check your current tool set before choosing. Skill visibility refreshes on reload, but tool state can change mid-session (model switch, credential change), so trust the tools you can see over what this page said at startup. If both surfaces ever appear, prefer the native server tool.
|
|
18
18
|
|
|
@@ -53,54 +53,11 @@ Both surfaces can return a `revised_prompt`: the prompt the model actually used
|
|
|
53
53
|
2. Fold the delta into your next prompt explicitly. If the rewrite dropped "overcast sky", put "overcast sky, no direct sunlight" back with more weight. If it added something you dislike, name the exclusion ("no lens flare").
|
|
54
54
|
3. Regenerate. Treat each round as a conversation with the rewriter, not a fresh roll of the dice.
|
|
55
55
|
|
|
56
|
-
##
|
|
56
|
+
## Editing and masks
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
- `gpt-image-2.5-flare`: fastest; choose it for everyday generation and quick iterations.
|
|
60
|
-
- `gpt-image-2`: legacy, previous-generation option.
|
|
58
|
+
v1 has no editing surface. The `generate_image` tool is text-only: it accepts a prompt and returns new images. There is no image input, no mask, no inpainting, no variation mode. The native `image_generation` server tool may perform provider-side edits on its own (action=auto), but no edit controls are exposed here.
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
`quality` accepts `low`, `medium`, `high`, `xhigh`, `max`, or `auto` (default). Start with `auto` or a lower tier while exploring, then increase quality for the final image. `xhigh` and `max` are available only on GPT Image 2.5 and incur higher latency and cost. Do not request them with `gpt-image-2`; the API rejects unsupported model/tier combinations.
|
|
65
|
-
|
|
66
|
-
## Image sizes
|
|
67
|
-
|
|
68
|
-
`size` defaults to `auto`. Choose a preset or an arbitrary `WIDTHxHEIGHT` for GPT Image 2 / 2.5. Custom dimensions must satisfy all of these constraints:
|
|
69
|
-
|
|
70
|
-
- Both width and height are divisible by 16.
|
|
71
|
-
- Aspect ratio is between 1:3 and 3:1, inclusive.
|
|
72
|
-
- Neither edge exceeds 3840 pixels.
|
|
73
|
-
- Total pixels are between 655,360 and 8,294,400, inclusive (the upper limit is 3840x2160 or 2160x3840, not 3840x3840).
|
|
74
|
-
|
|
75
|
-
| Size | Typical use |
|
|
76
|
-
| --- | --- |
|
|
77
|
-
| `auto` | Let the model choose |
|
|
78
|
-
| `1024x1024` | Square preset |
|
|
79
|
-
| `1536x1024` | Landscape preset |
|
|
80
|
-
| `1024x1536` | Portrait preset |
|
|
81
|
-
| `2048x2048` | Larger square |
|
|
82
|
-
| `2048x1152` | 16:9 landscape |
|
|
83
|
-
| `3840x2160` | Maximum-pixel 16:9 landscape |
|
|
84
|
-
| `2160x3840` | Maximum-pixel 9:16 portrait |
|
|
85
|
-
|
|
86
|
-
## Editing with reference images
|
|
87
|
-
|
|
88
|
-
Pass `reference_image_paths` to edit an existing image or use images as visual references. Supply 1-5 local PNG, JPEG, or WEBP files, each at most 50 MB. Paths may be absolute or relative to the current working directory. With references the tool sends an image-edit request; without them it generates from text.
|
|
89
|
-
|
|
90
|
-
Describe the desired END STATE in the prompt, not just a terse change instruction. State what must remain unchanged and what the finished image should contain. When passing multiple references, identify their roles in the same order as the paths.
|
|
91
|
-
|
|
92
|
-
```json
|
|
93
|
-
{
|
|
94
|
-
"prompt": "The same red fox from the reference, now wearing a knitted blue scarf, in an eye-level wildlife photograph. Preserve its face, fur markings, pose, and forest background. Soft overcast light, muted woodland colors, shallow depth of field; only the scarf is new.",
|
|
95
|
-
"model": "gpt-image-2.5-sunburst",
|
|
96
|
-
"reference_image_paths": ["art/fox.png"],
|
|
97
|
-
"quality": "high",
|
|
98
|
-
"size": "2048x1152",
|
|
99
|
-
"output_path": "art/fox-with-scarf.png"
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Read any returned `revised_prompt` after an edit, just as after generation. The client tool includes these in its result text and `details.revisedPrompts`. Compare the rewrite and saved image against the desired end state before another edit, and use a new `output_path` to preserve the source image.
|
|
60
|
+
Don't build workflows around editing. If the user asks to change an existing image, say that v1 generates from text only, then offer the closest text-only path: describe the desired end state as a full new prompt. Editing, masks, and image input are planned for a future version.
|
|
104
61
|
|
|
105
62
|
## Iteration workflow
|
|
106
63
|
|
|
@@ -1,13 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
export interface GenerateImageDetails {
|
|
3
|
+
paths: string[];
|
|
4
|
+
model: string;
|
|
5
|
+
source: string;
|
|
6
|
+
size: string;
|
|
7
|
+
quality: string;
|
|
8
|
+
requested: number;
|
|
9
|
+
generated: number;
|
|
10
|
+
revisedPrompts: string[];
|
|
11
|
+
error?: string;
|
|
12
|
+
reason?: "missing_config" | "provider_native_bypass" | "invalid_params" | "write_failed" | "provider_error";
|
|
13
|
+
}
|
|
3
14
|
export declare const GENERATE_IMAGE_TOOL_NAME = "generate_image";
|
|
4
|
-
export declare const generateImageTool: import("../../types.ts").ToolDefinition<
|
|
5
|
-
prompt:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
n: import("typebox").TOptional<import("typebox").TInteger>;
|
|
11
|
-
output_path: import("typebox").TOptional<import("typebox").TString>;
|
|
15
|
+
export declare const generateImageTool: import("../../types.ts").ToolDefinition<Type.TObject<{
|
|
16
|
+
prompt: Type.TString;
|
|
17
|
+
size: Type.TOptional<Type.TUnion<[Type.TLiteral<"auto">, Type.TLiteral<"1024x1024">, Type.TLiteral<"1024x1536">, Type.TLiteral<"1536x1024">]>>;
|
|
18
|
+
quality: Type.TOptional<Type.TUnion<[Type.TLiteral<"auto">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>>;
|
|
19
|
+
n: Type.TOptional<Type.TInteger>;
|
|
20
|
+
output_path: Type.TOptional<Type.TString>;
|
|
12
21
|
}>, GenerateImageDetails, any> & import("../../types.ts").ToolDefinition<any, any, any>;
|
|
13
22
|
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/tool.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/tool.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAyC/B,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,gBAAgB,GAAG,wBAAwB,GAAG,gBAAgB,GAAG,cAAc,GAAG,gBAAgB,CAAC;CAC5G;AAiFD,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,eAAO,MAAM,iBAAiB;;;;;;uFA4F5B,CAAC"}
|
|
@@ -1,13 +1,46 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
|
-
import { generateImages
|
|
4
|
+
import { generateImages } from "@earendil-works/pi-ai/compat";
|
|
5
|
+
import { Type } from "typebox";
|
|
5
6
|
import { defineTool } from "../../types.js";
|
|
6
7
|
import { resolveImageGenAuth } from "./auth.js";
|
|
7
|
-
import { DEFAULT_IMAGE_MODEL, failure, IMAGE_MODEL_NAMES, Params } from "./params.js";
|
|
8
8
|
import { displayPath, resolveTargets } from "./paths.js";
|
|
9
|
-
import { loadReferenceImages } from "./reference-images.js";
|
|
10
9
|
import { imageGenRegistryOverride, isNativeBypass, NATIVE_BYPASS_MESSAGE } from "./state.js";
|
|
10
|
+
const MODEL_ID = "gpt-image-2";
|
|
11
|
+
const Params = Type.Object({
|
|
12
|
+
prompt: Type.String({
|
|
13
|
+
minLength: 1,
|
|
14
|
+
maxLength: 32_000,
|
|
15
|
+
description: "Detailed description of the image to generate.",
|
|
16
|
+
}),
|
|
17
|
+
size: Type.Optional(Type.Union([Type.Literal("auto"), Type.Literal("1024x1024"), Type.Literal("1024x1536"), Type.Literal("1536x1024")], { default: "auto", description: "Output resolution. Defaults to auto." })),
|
|
18
|
+
quality: Type.Optional(Type.Union([Type.Literal("auto"), Type.Literal("low"), Type.Literal("medium"), Type.Literal("high")], {
|
|
19
|
+
default: "auto",
|
|
20
|
+
description: "Rendering quality. Defaults to auto.",
|
|
21
|
+
})),
|
|
22
|
+
n: Type.Optional(Type.Integer({ minimum: 1, maximum: 10, default: 1, description: "How many images to generate." })),
|
|
23
|
+
output_path: Type.Optional(Type.String({
|
|
24
|
+
minLength: 1,
|
|
25
|
+
description: "Where to write the image, relative to the working directory. Must end in .png. Defaults to generated-images/.",
|
|
26
|
+
})),
|
|
27
|
+
}, { additionalProperties: false });
|
|
28
|
+
/**
|
|
29
|
+
* Only the registry surface the credential resolver needs. The session passes its
|
|
30
|
+
* full ModelRegistry, which satisfies this structurally.
|
|
31
|
+
*/
|
|
32
|
+
function failure(message, reason, base) {
|
|
33
|
+
const details = {
|
|
34
|
+
...base,
|
|
35
|
+
paths: [],
|
|
36
|
+
model: MODEL_ID,
|
|
37
|
+
generated: 0,
|
|
38
|
+
revisedPrompts: [],
|
|
39
|
+
error: message,
|
|
40
|
+
reason,
|
|
41
|
+
};
|
|
42
|
+
return { content: [{ type: "text", text: message }], details };
|
|
43
|
+
}
|
|
11
44
|
function sourceLabel(auth) {
|
|
12
45
|
if (auth.kind === "none")
|
|
13
46
|
return "none";
|
|
@@ -15,14 +48,14 @@ function sourceLabel(auth) {
|
|
|
15
48
|
return "env:OPENAI_API_KEY";
|
|
16
49
|
return `${auth.provenance}:${auth.providerId ?? auth.kind}`;
|
|
17
50
|
}
|
|
18
|
-
function synthesizeModel(auth
|
|
51
|
+
function synthesizeModel(auth) {
|
|
19
52
|
const model = {
|
|
20
|
-
id,
|
|
21
|
-
name:
|
|
53
|
+
id: MODEL_ID,
|
|
54
|
+
name: "GPT Image 2",
|
|
22
55
|
api: "openai-images",
|
|
23
56
|
provider: auth.providerId ?? "openai",
|
|
24
57
|
baseUrl: auth.baseUrl,
|
|
25
|
-
input: ["text"
|
|
58
|
+
input: ["text"],
|
|
26
59
|
output: ["image"],
|
|
27
60
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
28
61
|
};
|
|
@@ -66,15 +99,14 @@ export const GENERATE_IMAGE_TOOL_NAME = "generate_image";
|
|
|
66
99
|
export const generateImageTool = defineTool({
|
|
67
100
|
name: GENERATE_IMAGE_TOOL_NAME,
|
|
68
101
|
label: "Generate Image",
|
|
69
|
-
description: "Generate
|
|
70
|
-
promptSnippet: "Generate
|
|
102
|
+
description: "Generate an image from a text prompt with gpt-image-2 and save it as a PNG file. Returns the saved file paths.",
|
|
103
|
+
promptSnippet: "Generate images from text prompts and save them as PNG files.",
|
|
71
104
|
parameters: Params,
|
|
72
105
|
async execute(toolCallId, params, signal, _onUpdate, ctx) {
|
|
73
106
|
const size = params.size ?? "auto";
|
|
74
107
|
const quality = params.quality ?? "auto";
|
|
75
108
|
const requested = params.n ?? 1;
|
|
76
|
-
const
|
|
77
|
-
const context = { model: modelId, size, quality, requested, source: "none" };
|
|
109
|
+
const context = { size, quality, requested, source: "none" };
|
|
78
110
|
const prompt = params.prompt.trim();
|
|
79
111
|
if (prompt.length === 0) {
|
|
80
112
|
return failure("Error: prompt must contain non-whitespace text.", "invalid_params", context);
|
|
@@ -87,14 +119,6 @@ export const generateImageTool = defineTool({
|
|
|
87
119
|
return failure(auth.reason, "missing_config", context);
|
|
88
120
|
}
|
|
89
121
|
const source = sourceLabel(auth);
|
|
90
|
-
const parsedSize = parseOpenAIImageSize(size);
|
|
91
|
-
if (!parsedSize.ok) {
|
|
92
|
-
return failure(`Error: ${parsedSize.error}`, "invalid_params", { ...context, source });
|
|
93
|
-
}
|
|
94
|
-
const references = await loadReferenceImages(ctx.cwd, params.reference_image_paths);
|
|
95
|
-
if (!references.ok) {
|
|
96
|
-
return failure(references.error, "invalid_params", { ...context, source });
|
|
97
|
-
}
|
|
98
122
|
const targets = resolveTargets(ctx.cwd, toolCallId, requested, params.output_path);
|
|
99
123
|
if (!targets.ok) {
|
|
100
124
|
return failure(targets.error, "invalid_params", { ...context, source });
|
|
@@ -104,7 +128,7 @@ export const generateImageTool = defineTool({
|
|
|
104
128
|
return failure(`Error: ${displayPath(ctx.cwd, target)} already exists. Choose another output_path.`, "invalid_params", { ...context, source });
|
|
105
129
|
}
|
|
106
130
|
}
|
|
107
|
-
const images = await generateImages(synthesizeModel(auth
|
|
131
|
+
const images = await generateImages(synthesizeModel(auth), { input: [{ type: "text", text: prompt }] }, {
|
|
108
132
|
...(auth.apiKey === undefined ? {} : { apiKey: auth.apiKey }),
|
|
109
133
|
...(auth.headers === undefined ? {} : { headers: auth.headers }),
|
|
110
134
|
...(signal === undefined ? {} : { signal }),
|
|
@@ -128,7 +152,7 @@ export const generateImageTool = defineTool({
|
|
|
128
152
|
const revisedPrompts = generated.flatMap((image) => (image.revisedPrompt ? [image.revisedPrompt] : []));
|
|
129
153
|
const details = {
|
|
130
154
|
paths: savedPaths,
|
|
131
|
-
model:
|
|
155
|
+
model: MODEL_ID,
|
|
132
156
|
source,
|
|
133
157
|
size,
|
|
134
158
|
quality,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { AssistantImages, ImagesModel } from \"@earendil-works/pi-ai/compat\";\nimport { generateImages, parseOpenAIImageSize } from \"@earendil-works/pi-ai/compat\";\nimport { defineTool, type ExtensionContext } from \"../../types.ts\";\nimport { type ImageGenAuthResolution, resolveImageGenAuth } from \"./auth.ts\";\nimport { DEFAULT_IMAGE_MODEL, failure, type GenerateImageDetails, IMAGE_MODEL_NAMES, Params } from \"./params.ts\";\nimport { displayPath, resolveTargets } from \"./paths.ts\";\nimport { loadReferenceImages } from \"./reference-images.ts\";\nimport { imageGenRegistryOverride, isNativeBypass, NATIVE_BYPASS_MESSAGE } from \"./state.ts\";\n\nexport type { GenerateImageDetails } from \"./params.ts\";\n\nfunction sourceLabel(auth: ImageGenAuthResolution): string {\n\tif (auth.kind === \"none\") return \"none\";\n\tif (auth.provenance === \"env\") return \"env:OPENAI_API_KEY\";\n\treturn `${auth.provenance}:${auth.providerId ?? auth.kind}`;\n}\n\nfunction synthesizeModel(\n\tauth: Extract<ImageGenAuthResolution, { kind: \"native-openai\" | \"gateway\" }>,\n\tid: keyof typeof IMAGE_MODEL_NAMES,\n) {\n\tconst model: ImagesModel<\"openai-images\"> = {\n\t\tid,\n\t\tname: IMAGE_MODEL_NAMES[id],\n\t\tapi: \"openai-images\",\n\t\tprovider: auth.providerId ?? \"openai\",\n\t\tbaseUrl: auth.baseUrl,\n\t\tinput: [\"text\", \"image\"],\n\t\toutput: [\"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n\treturn model;\n}\n\ninterface GeneratedImage {\n\tdata: string;\n\trevisedPrompt?: string;\n}\n\nfunction collectImages(images: AssistantImages): GeneratedImage[] {\n\tconst collected: GeneratedImage[] = [];\n\tlet pendingText: string | undefined;\n\tfor (const block of images.output) {\n\t\tif (block.type === \"text\") {\n\t\t\tconst text = block.text.trim();\n\t\t\tpendingText = text.length > 0 ? text : undefined;\n\t\t\tcontinue;\n\t\t}\n\t\tcollected.push({ data: block.data, ...(pendingText === undefined ? {} : { revisedPrompt: pendingText }) });\n\t\tpendingText = undefined;\n\t}\n\treturn collected;\n}\n\nasync function writeImages(paths: string[], images: GeneratedImage[]): Promise<string | undefined> {\n\tconst written: string[] = [];\n\tfor (const [index, image] of images.entries()) {\n\t\tconst target = paths[index];\n\t\tif (target === undefined) break;\n\t\ttry {\n\t\t\tawait mkdir(dirname(target), { recursive: true });\n\t\t\tawait writeFile(target, Buffer.from(image.data, \"base64\"), { flag: \"wx\" });\n\t\t\twritten.push(target);\n\t\t} catch (error) {\n\t\t\tfor (const path of written) await rm(path, { force: true }).catch(() => undefined);\n\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\treturn `Error: failed to write generated image to ${target}: ${reason}`;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport const GENERATE_IMAGE_TOOL_NAME = \"generate_image\";\n\nexport const generateImageTool = defineTool<typeof Params, GenerateImageDetails>({\n\tname: GENERATE_IMAGE_TOOL_NAME,\n\tlabel: \"Generate Image\",\n\tdescription:\n\t\t\"Generate or edit an image with OpenAI gpt-image-2.5 (Sunburst by default; Flare for speed) and save it as a PNG file. Pass reference_image_paths to edit or reference existing images. Returns the saved file paths.\",\n\tpromptSnippet: \"Generate or edit images from prompts and optional reference images, saving them as PNG files.\",\n\tparameters: Params,\n\tasync execute(toolCallId, params, signal, _onUpdate, ctx: ExtensionContext) {\n\t\tconst size = params.size ?? \"auto\";\n\t\tconst quality = params.quality ?? \"auto\";\n\t\tconst requested = params.n ?? 1;\n\t\tconst modelId = params.model ?? DEFAULT_IMAGE_MODEL;\n\t\tconst context = { model: modelId, size, quality, requested, source: \"none\" };\n\n\t\tconst prompt = params.prompt.trim();\n\t\tif (prompt.length === 0) {\n\t\t\treturn failure(\"Error: prompt must contain non-whitespace text.\", \"invalid_params\", context);\n\t\t}\n\t\tif (isNativeBypass()) {\n\t\t\treturn failure(NATIVE_BYPASS_MESSAGE, \"provider_native_bypass\", context);\n\t\t}\n\n\t\tconst auth = await resolveImageGenAuth({ modelRegistry: imageGenRegistryOverride() ?? ctx.modelRegistry });\n\t\tif (auth.kind === \"none\") {\n\t\t\treturn failure(auth.reason, \"missing_config\", context);\n\t\t}\n\t\tconst source = sourceLabel(auth);\n\t\tconst parsedSize = parseOpenAIImageSize(size);\n\t\tif (!parsedSize.ok) {\n\t\t\treturn failure(`Error: ${parsedSize.error}`, \"invalid_params\", { ...context, source });\n\t\t}\n\t\tconst references = await loadReferenceImages(ctx.cwd, params.reference_image_paths);\n\t\tif (!references.ok) {\n\t\t\treturn failure(references.error, \"invalid_params\", { ...context, source });\n\t\t}\n\t\tconst targets = resolveTargets(ctx.cwd, toolCallId, requested, params.output_path);\n\t\tif (!targets.ok) {\n\t\t\treturn failure(targets.error, \"invalid_params\", { ...context, source });\n\t\t}\n\t\tfor (const target of targets.paths) {\n\t\t\tif (existsSync(target)) {\n\t\t\t\treturn failure(\n\t\t\t\t\t`Error: ${displayPath(ctx.cwd, target)} already exists. Choose another output_path.`,\n\t\t\t\t\t\"invalid_params\",\n\t\t\t\t\t{ ...context, source },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst images = await generateImages(\n\t\t\tsynthesizeModel(auth, modelId),\n\t\t\t{ input: [{ type: \"text\", text: prompt }, ...references.images] },\n\t\t\t{\n\t\t\t\t...(auth.apiKey === undefined ? {} : { apiKey: auth.apiKey }),\n\t\t\t\t...(auth.headers === undefined ? {} : { headers: auth.headers }),\n\t\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t\t\tsize,\n\t\t\t\tquality,\n\t\t\t\tn: requested,\n\t\t\t},\n\t\t);\n\t\tif (images.stopReason !== \"stop\") {\n\t\t\tconst message = images.errorMessage ?? `Image generation ${images.stopReason}.`;\n\t\t\treturn failure(`Error: ${message}`, \"provider_error\", { ...context, source });\n\t\t}\n\n\t\tconst generated = collectImages(images);\n\t\tif (generated.length === 0) {\n\t\t\treturn failure(\"Error: the provider returned no images.\", \"provider_error\", { ...context, source });\n\t\t}\n\t\tconst writeError = await writeImages(targets.paths, generated);\n\t\tif (writeError !== undefined) {\n\t\t\treturn failure(writeError, \"write_failed\", { ...context, source });\n\t\t}\n\n\t\tconst savedPaths = targets.paths.slice(0, generated.length).map((target) => displayPath(ctx.cwd, target));\n\t\tconst revisedPrompts = generated.flatMap((image) => (image.revisedPrompt ? [image.revisedPrompt] : []));\n\t\tconst details: GenerateImageDetails = {\n\t\t\tpaths: savedPaths,\n\t\t\tmodel: modelId,\n\t\t\tsource,\n\t\t\tsize,\n\t\t\tquality,\n\t\t\trequested,\n\t\t\tgenerated: generated.length,\n\t\t\trevisedPrompts,\n\t\t};\n\t\tconst summary = [\n\t\t\t`Generated ${generated.length} image${generated.length === 1 ? \"\" : \"s\"}:`,\n\t\t\t...savedPaths.map((path) => `- ${path}`),\n\t\t\t...revisedPrompts.map((revised) => `Revised prompt: ${revised}`),\n\t\t].join(\"\\n\");\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{ type: \"text\" as const, text: summary },\n\t\t\t\t...generated.map((image) => ({ type: \"image\" as const, data: image.data, mimeType: \"image/png\" })),\n\t\t\t],\n\t\t\tdetails,\n\t\t\t...(images.usage === undefined ? {} : { usage: images.usage }),\n\t\t};\n\t},\n});\n"]}
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/imagegen/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { mkdir, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { AssistantImages, ImagesModel } from \"@earendil-works/pi-ai/compat\";\nimport { generateImages } from \"@earendil-works/pi-ai/compat\";\nimport { Type } from \"typebox\";\nimport { defineTool, type ExtensionContext } from \"../../types.ts\";\nimport { type ImageGenAuthResolution, resolveImageGenAuth } from \"./auth.ts\";\nimport { displayPath, resolveTargets } from \"./paths.ts\";\nimport { imageGenRegistryOverride, isNativeBypass, NATIVE_BYPASS_MESSAGE } from \"./state.ts\";\n\nconst MODEL_ID = \"gpt-image-2\";\n\nconst Params = Type.Object(\n\t{\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tmaxLength: 32_000,\n\t\t\tdescription: \"Detailed description of the image to generate.\",\n\t\t}),\n\t\tsize: Type.Optional(\n\t\t\tType.Union(\n\t\t\t\t[Type.Literal(\"auto\"), Type.Literal(\"1024x1024\"), Type.Literal(\"1024x1536\"), Type.Literal(\"1536x1024\")],\n\t\t\t\t{ default: \"auto\", description: \"Output resolution. Defaults to auto.\" },\n\t\t\t),\n\t\t),\n\t\tquality: Type.Optional(\n\t\t\tType.Union([Type.Literal(\"auto\"), Type.Literal(\"low\"), Type.Literal(\"medium\"), Type.Literal(\"high\")], {\n\t\t\t\tdefault: \"auto\",\n\t\t\t\tdescription: \"Rendering quality. Defaults to auto.\",\n\t\t\t}),\n\t\t),\n\t\tn: Type.Optional(\n\t\t\tType.Integer({ minimum: 1, maximum: 10, default: 1, description: \"How many images to generate.\" }),\n\t\t),\n\t\toutput_path: Type.Optional(\n\t\t\tType.String({\n\t\t\t\tminLength: 1,\n\t\t\t\tdescription:\n\t\t\t\t\t\"Where to write the image, relative to the working directory. Must end in .png. Defaults to generated-images/.\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\nexport interface GenerateImageDetails {\n\tpaths: string[];\n\tmodel: string;\n\tsource: string;\n\tsize: string;\n\tquality: string;\n\trequested: number;\n\tgenerated: number;\n\trevisedPrompts: string[];\n\terror?: string;\n\treason?: \"missing_config\" | \"provider_native_bypass\" | \"invalid_params\" | \"write_failed\" | \"provider_error\";\n}\n\n/**\n * Only the registry surface the credential resolver needs. The session passes its\n * full ModelRegistry, which satisfies this structurally.\n */\nfunction failure(\n\tmessage: string,\n\treason: NonNullable<GenerateImageDetails[\"reason\"]>,\n\tbase: Pick<GenerateImageDetails, \"size\" | \"quality\" | \"requested\" | \"source\">,\n) {\n\tconst details: GenerateImageDetails = {\n\t\t...base,\n\t\tpaths: [],\n\t\tmodel: MODEL_ID,\n\t\tgenerated: 0,\n\t\trevisedPrompts: [],\n\t\terror: message,\n\t\treason,\n\t};\n\treturn { content: [{ type: \"text\" as const, text: message }], details };\n}\n\nfunction sourceLabel(auth: ImageGenAuthResolution): string {\n\tif (auth.kind === \"none\") return \"none\";\n\tif (auth.provenance === \"env\") return \"env:OPENAI_API_KEY\";\n\treturn `${auth.provenance}:${auth.providerId ?? auth.kind}`;\n}\n\nfunction synthesizeModel(auth: Extract<ImageGenAuthResolution, { kind: \"native-openai\" | \"gateway\" }>) {\n\tconst model: ImagesModel<\"openai-images\"> = {\n\t\tid: MODEL_ID,\n\t\tname: \"GPT Image 2\",\n\t\tapi: \"openai-images\",\n\t\tprovider: auth.providerId ?? \"openai\",\n\t\tbaseUrl: auth.baseUrl,\n\t\tinput: [\"text\"],\n\t\toutput: [\"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n\treturn model;\n}\n\ninterface GeneratedImage {\n\tdata: string;\n\trevisedPrompt?: string;\n}\n\nfunction collectImages(images: AssistantImages): GeneratedImage[] {\n\tconst collected: GeneratedImage[] = [];\n\tlet pendingText: string | undefined;\n\tfor (const block of images.output) {\n\t\tif (block.type === \"text\") {\n\t\t\tconst text = block.text.trim();\n\t\t\tpendingText = text.length > 0 ? text : undefined;\n\t\t\tcontinue;\n\t\t}\n\t\tcollected.push({ data: block.data, ...(pendingText === undefined ? {} : { revisedPrompt: pendingText }) });\n\t\tpendingText = undefined;\n\t}\n\treturn collected;\n}\n\nasync function writeImages(paths: string[], images: GeneratedImage[]): Promise<string | undefined> {\n\tconst written: string[] = [];\n\tfor (const [index, image] of images.entries()) {\n\t\tconst target = paths[index];\n\t\tif (target === undefined) break;\n\t\ttry {\n\t\t\tawait mkdir(dirname(target), { recursive: true });\n\t\t\tawait writeFile(target, Buffer.from(image.data, \"base64\"), { flag: \"wx\" });\n\t\t\twritten.push(target);\n\t\t} catch (error) {\n\t\t\tfor (const path of written) await rm(path, { force: true }).catch(() => undefined);\n\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\treturn `Error: failed to write generated image to ${target}: ${reason}`;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport const GENERATE_IMAGE_TOOL_NAME = \"generate_image\";\n\nexport const generateImageTool = defineTool<typeof Params, GenerateImageDetails>({\n\tname: GENERATE_IMAGE_TOOL_NAME,\n\tlabel: \"Generate Image\",\n\tdescription:\n\t\t\"Generate an image from a text prompt with gpt-image-2 and save it as a PNG file. Returns the saved file paths.\",\n\tpromptSnippet: \"Generate images from text prompts and save them as PNG files.\",\n\tparameters: Params,\n\tasync execute(toolCallId, params, signal, _onUpdate, ctx: ExtensionContext) {\n\t\tconst size = params.size ?? \"auto\";\n\t\tconst quality = params.quality ?? \"auto\";\n\t\tconst requested = params.n ?? 1;\n\t\tconst context = { size, quality, requested, source: \"none\" };\n\n\t\tconst prompt = params.prompt.trim();\n\t\tif (prompt.length === 0) {\n\t\t\treturn failure(\"Error: prompt must contain non-whitespace text.\", \"invalid_params\", context);\n\t\t}\n\t\tif (isNativeBypass()) {\n\t\t\treturn failure(NATIVE_BYPASS_MESSAGE, \"provider_native_bypass\", context);\n\t\t}\n\n\t\tconst auth = await resolveImageGenAuth({ modelRegistry: imageGenRegistryOverride() ?? ctx.modelRegistry });\n\t\tif (auth.kind === \"none\") {\n\t\t\treturn failure(auth.reason, \"missing_config\", context);\n\t\t}\n\t\tconst source = sourceLabel(auth);\n\t\tconst targets = resolveTargets(ctx.cwd, toolCallId, requested, params.output_path);\n\t\tif (!targets.ok) {\n\t\t\treturn failure(targets.error, \"invalid_params\", { ...context, source });\n\t\t}\n\t\tfor (const target of targets.paths) {\n\t\t\tif (existsSync(target)) {\n\t\t\t\treturn failure(\n\t\t\t\t\t`Error: ${displayPath(ctx.cwd, target)} already exists. Choose another output_path.`,\n\t\t\t\t\t\"invalid_params\",\n\t\t\t\t\t{ ...context, source },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst images = await generateImages(\n\t\t\tsynthesizeModel(auth),\n\t\t\t{ input: [{ type: \"text\", text: prompt }] },\n\t\t\t{\n\t\t\t\t...(auth.apiKey === undefined ? {} : { apiKey: auth.apiKey }),\n\t\t\t\t...(auth.headers === undefined ? {} : { headers: auth.headers }),\n\t\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t\t\tsize,\n\t\t\t\tquality,\n\t\t\t\tn: requested,\n\t\t\t},\n\t\t);\n\t\tif (images.stopReason !== \"stop\") {\n\t\t\tconst message = images.errorMessage ?? `Image generation ${images.stopReason}.`;\n\t\t\treturn failure(`Error: ${message}`, \"provider_error\", { ...context, source });\n\t\t}\n\n\t\tconst generated = collectImages(images);\n\t\tif (generated.length === 0) {\n\t\t\treturn failure(\"Error: the provider returned no images.\", \"provider_error\", { ...context, source });\n\t\t}\n\t\tconst writeError = await writeImages(targets.paths, generated);\n\t\tif (writeError !== undefined) {\n\t\t\treturn failure(writeError, \"write_failed\", { ...context, source });\n\t\t}\n\n\t\tconst savedPaths = targets.paths.slice(0, generated.length).map((target) => displayPath(ctx.cwd, target));\n\t\tconst revisedPrompts = generated.flatMap((image) => (image.revisedPrompt ? [image.revisedPrompt] : []));\n\t\tconst details: GenerateImageDetails = {\n\t\t\tpaths: savedPaths,\n\t\t\tmodel: MODEL_ID,\n\t\t\tsource,\n\t\t\tsize,\n\t\t\tquality,\n\t\t\trequested,\n\t\t\tgenerated: generated.length,\n\t\t\trevisedPrompts,\n\t\t};\n\t\tconst summary = [\n\t\t\t`Generated ${generated.length} image${generated.length === 1 ? \"\" : \"s\"}:`,\n\t\t\t...savedPaths.map((path) => `- ${path}`),\n\t\t\t...revisedPrompts.map((revised) => `Revised prompt: ${revised}`),\n\t\t].join(\"\\n\");\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{ type: \"text\" as const, text: summary },\n\t\t\t\t...generated.map((image) => ({ type: \"image\" as const, data: image.data, mimeType: \"image/png\" })),\n\t\t\t],\n\t\t\tdetails,\n\t\t\t...(images.usage === undefined ? {} : { usage: images.usage }),\n\t\t};\n\t},\n});\n"]}
|
|
@@ -23,10 +23,9 @@ export declare function drainPendingProviderRegistrations(runtime: ExtensionRunt
|
|
|
23
23
|
/**
|
|
24
24
|
* Create an Extension from an inline factory function.
|
|
25
25
|
*/
|
|
26
|
-
export declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd: string, eventBus: EventBus, runtime: ExtensionRuntime, extensionPath?: string
|
|
26
|
+
export declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd: string, eventBus: EventBus, runtime: ExtensionRuntime, extensionPath?: string): Promise<Extension>;
|
|
27
27
|
export declare function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus, runtime?: ExtensionRuntime, options?: {
|
|
28
28
|
factoryResolver?: ExtensionFactoryResolver;
|
|
29
|
-
sharedHostEnabled?: boolean;
|
|
30
29
|
}): Promise<LoadExtensionsResult>;
|
|
31
30
|
export declare function loadExtensionsCached(paths: string[], cwd: string, eventBus?: EventBus, runtime?: ExtensionRuntime): Promise<LoadExtensionsResult>;
|
|
32
31
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"AACA;;;GAGG;AAyBH,OAAO,EAAkB,KAAK,QAAQ,EAAuD,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/loader.ts"],"names":[],"mappings":"AACA;;;GAGG;AAyBH,OAAO,EAAkB,KAAK,QAAQ,EAAuD,MAAM,iBAAiB,CAAC;AAOrH,OAAO,KAAK,EAEX,SAAS,EAET,gBAAgB,EAChB,gBAAgB,EAGhB,oBAAoB,EAGpB,2BAA2B,EAK3B,MAAM,YAAY,CAAC;AAmJpB,MAAM,MAAM,wBAAwB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,gBAAgB,GAAG,SAAS,CAAC;AAiBrH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAyBD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAsFzD;AAED;;;;;;;GAOG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,gBAAgB,GAAG,2BAA2B,EAAE,CAS1G;AA4bD;;GAEG;AACH,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,gBAAgB,EACzB,aAAa,SAAa,GACxB,OAAO,CAAC,SAAS,CAAC,CAGpB;AAsDD,wBAAsB,cAAc,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,gBAAgB,EAC1B,OAAO,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,wBAAwB,CAAA;CAAE,GACtD,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED,wBAAsB,oBAAoB,CACzC,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AA2FD;;GAEG;AACH,wBAAsB,yBAAyB,CAC9C,eAAe,EAAE,MAAM,EAAE,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAsB,EAChC,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,oBAAoB,CAAC,CA2C/B"}
|
|
@@ -29,7 +29,6 @@ import { execCommand } from "../exec.js";
|
|
|
29
29
|
import { readPiManifest } from "../pi-manifest.js";
|
|
30
30
|
import { createSyntheticSourceInfo } from "../source-info.js";
|
|
31
31
|
import { time } from "../timings.js";
|
|
32
|
-
import { registerReadClassifier } from "../tools/read-classifiers.js";
|
|
33
32
|
import { validateMcpServerDeclaration } from "./builtin/mcp/config-schema.js";
|
|
34
33
|
/** Modules available to extensions via virtualModules (for compiled binaries) */
|
|
35
34
|
const VIRTUAL_MODULES = {
|
|
@@ -268,7 +267,7 @@ export function drainPendingProviderRegistrations(runtime) {
|
|
|
268
267
|
* Registration methods write to the extension object.
|
|
269
268
|
* Action methods delegate to the shared runtime.
|
|
270
269
|
*/
|
|
271
|
-
function createExtensionAPI(extension, runtime, cwd, eventBus
|
|
270
|
+
function createExtensionAPI(extension, runtime, cwd, eventBus) {
|
|
272
271
|
const pendingFlagValues = new Map();
|
|
273
272
|
const pendingRuntimeChanges = [];
|
|
274
273
|
const loadingUnsubscribers = [];
|
|
@@ -292,7 +291,6 @@ function createExtensionAPI(extension, runtime, cwd, eventBus, sharedHostEnabled
|
|
|
292
291
|
};
|
|
293
292
|
const api = {
|
|
294
293
|
cwd,
|
|
295
|
-
sharedHostEnabled,
|
|
296
294
|
// Registration methods - write to extension
|
|
297
295
|
on(event, handler) {
|
|
298
296
|
assertActive();
|
|
@@ -375,13 +373,6 @@ function createExtensionAPI(extension, runtime, cwd, eventBus, sharedHostEnabled
|
|
|
375
373
|
extension.entryRenderers ??= new Map();
|
|
376
374
|
extension.entryRenderers.set(customType, renderer);
|
|
377
375
|
},
|
|
378
|
-
registerReadClassifier(classifier) {
|
|
379
|
-
assertActive();
|
|
380
|
-
const unregister = runtime.trackEventBusSubscription(registerReadClassifier(classifier));
|
|
381
|
-
if (state === "loading")
|
|
382
|
-
loadingUnsubscribers.push(unregister);
|
|
383
|
-
return unregister;
|
|
384
|
-
},
|
|
385
376
|
registerMcpServer(name, config) {
|
|
386
377
|
runtime.assertActive();
|
|
387
378
|
const error = validateMcpServerDeclaration(name, config);
|
|
@@ -615,9 +606,9 @@ function createExtension(extensionPath, resolvedPath, registrationCwd) {
|
|
|
615
606
|
registrationCwd,
|
|
616
607
|
};
|
|
617
608
|
}
|
|
618
|
-
async function initializeExtension(factory, extensionPath, resolvedPath, cwd, eventBus, runtime
|
|
609
|
+
async function initializeExtension(factory, extensionPath, resolvedPath, cwd, eventBus, runtime) {
|
|
619
610
|
const extension = createExtension(extensionPath, resolvedPath, cwd);
|
|
620
|
-
const load = createExtensionAPI(extension, runtime, cwd, eventBus
|
|
611
|
+
const load = createExtensionAPI(extension, runtime, cwd, eventBus);
|
|
621
612
|
try {
|
|
622
613
|
await factory(load.api);
|
|
623
614
|
load.commit();
|
|
@@ -629,7 +620,7 @@ async function initializeExtension(factory, extensionPath, resolvedPath, cwd, ev
|
|
|
629
620
|
time(`${extensionPath} factory`, "extensions");
|
|
630
621
|
return extension;
|
|
631
622
|
}
|
|
632
|
-
async function loadExtension(extensionPath, cwd, eventBus, runtime, getImporter, factoryResolver, cacheToken
|
|
623
|
+
async function loadExtension(extensionPath, cwd, eventBus, runtime, getImporter, factoryResolver, cacheToken) {
|
|
633
624
|
const resolvedPath = resolvePath(extensionPath, cwd, { normalizeUnicodeSpaces: true });
|
|
634
625
|
try {
|
|
635
626
|
const factory = factoryResolver?.(extensionPath, resolvedPath) ??
|
|
@@ -638,7 +629,7 @@ async function loadExtension(extensionPath, cwd, eventBus, runtime, getImporter,
|
|
|
638
629
|
if (!factory) {
|
|
639
630
|
return { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };
|
|
640
631
|
}
|
|
641
|
-
const extension = await initializeExtension(factory, extensionPath, resolvedPath, cwd, eventBus, runtime
|
|
632
|
+
const extension = await initializeExtension(factory, extensionPath, resolvedPath, cwd, eventBus, runtime);
|
|
642
633
|
return { extension, error: null };
|
|
643
634
|
}
|
|
644
635
|
catch (err) {
|
|
@@ -649,9 +640,9 @@ async function loadExtension(extensionPath, cwd, eventBus, runtime, getImporter,
|
|
|
649
640
|
/**
|
|
650
641
|
* Create an Extension from an inline factory function.
|
|
651
642
|
*/
|
|
652
|
-
export async function loadExtensionFromFactory(factory, cwd, eventBus, runtime, extensionPath = "<inline>"
|
|
643
|
+
export async function loadExtensionFromFactory(factory, cwd, eventBus, runtime, extensionPath = "<inline>") {
|
|
653
644
|
const resolvedCwd = resolvePath(cwd);
|
|
654
|
-
return initializeExtension(factory, extensionPath, extensionPath, resolvedCwd, eventBus, runtime
|
|
645
|
+
return initializeExtension(factory, extensionPath, extensionPath, resolvedCwd, eventBus, runtime);
|
|
655
646
|
}
|
|
656
647
|
/**
|
|
657
648
|
* Load extensions from paths.
|
|
@@ -669,7 +660,7 @@ async function loadExtensionsInternal(paths, cwd, eventBus, runtime, options, us
|
|
|
669
660
|
return importer;
|
|
670
661
|
};
|
|
671
662
|
for (const extPath of paths) {
|
|
672
|
-
const { extension, error } = await loadExtension(extPath, resolvedCwd, resolvedEventBus, resolvedRuntime, getImporter, options?.factoryResolver, cacheToken
|
|
663
|
+
const { extension, error } = await loadExtension(extPath, resolvedCwd, resolvedEventBus, resolvedRuntime, getImporter, options?.factoryResolver, cacheToken);
|
|
673
664
|
if (error) {
|
|
674
665
|
errors.push({ path: extPath, error });
|
|
675
666
|
continue;
|