@glbgpt/cli 0.1.0-test.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/README.md +111 -0
- package/dist/src/auth/authClient.d.ts +32 -0
- package/dist/src/auth/authClient.js +88 -0
- package/dist/src/auth/authClient.js.map +1 -0
- package/dist/src/auth/credentialStore.d.ts +22 -0
- package/dist/src/auth/credentialStore.js +51 -0
- package/dist/src/auth/credentialStore.js.map +1 -0
- package/dist/src/auth/loginFlow.d.ts +30 -0
- package/dist/src/auth/loginFlow.js +43 -0
- package/dist/src/auth/loginFlow.js.map +1 -0
- package/dist/src/auth/loopbackServer.d.ts +41 -0
- package/dist/src/auth/loopbackServer.js +141 -0
- package/dist/src/auth/loopbackServer.js.map +1 -0
- package/dist/src/auth/token.d.ts +8 -0
- package/dist/src/auth/token.js +15 -0
- package/dist/src/auth/token.js.map +1 -0
- package/dist/src/commands/accountCommand.d.ts +2 -0
- package/dist/src/commands/accountCommand.js +56 -0
- package/dist/src/commands/accountCommand.js.map +1 -0
- package/dist/src/commands/configCommand.d.ts +4 -0
- package/dist/src/commands/configCommand.js +53 -0
- package/dist/src/commands/configCommand.js.map +1 -0
- package/dist/src/commands/execCommand.d.ts +32 -0
- package/dist/src/commands/execCommand.js +122 -0
- package/dist/src/commands/execCommand.js.map +1 -0
- package/dist/src/commands/loginCommand.d.ts +11 -0
- package/dist/src/commands/loginCommand.js +96 -0
- package/dist/src/commands/loginCommand.js.map +1 -0
- package/dist/src/commands/mediaCommand.d.ts +41 -0
- package/dist/src/commands/mediaCommand.js +277 -0
- package/dist/src/commands/mediaCommand.js.map +1 -0
- package/dist/src/config/configFile.d.ts +30 -0
- package/dist/src/config/configFile.js +54 -0
- package/dist/src/config/configFile.js.map +1 -0
- package/dist/src/config/env.d.ts +6 -0
- package/dist/src/config/env.js +24 -0
- package/dist/src/config/env.js.map +1 -0
- package/dist/src/config/paths.d.ts +6 -0
- package/dist/src/config/paths.js +16 -0
- package/dist/src/config/paths.js.map +1 -0
- package/dist/src/core/catalog.d.ts +49 -0
- package/dist/src/core/catalog.js +96 -0
- package/dist/src/core/catalog.js.map +1 -0
- package/dist/src/core/httpChatBackend.d.ts +31 -0
- package/dist/src/core/httpChatBackend.js +134 -0
- package/dist/src/core/httpChatBackend.js.map +1 -0
- package/dist/src/core/id.d.ts +2 -0
- package/dist/src/core/id.js +5 -0
- package/dist/src/core/id.js.map +1 -0
- package/dist/src/core/runChat.d.ts +28 -0
- package/dist/src/core/runChat.js +49 -0
- package/dist/src/core/runChat.js.map +1 -0
- package/dist/src/core/session.d.ts +44 -0
- package/dist/src/core/session.js +70 -0
- package/dist/src/core/session.js.map +1 -0
- package/dist/src/core/sessionStore.d.ts +39 -0
- package/dist/src/core/sessionStore.js +106 -0
- package/dist/src/core/sessionStore.js.map +1 -0
- package/dist/src/core/toolRegistry.d.ts +19 -0
- package/dist/src/core/toolRegistry.js +53 -0
- package/dist/src/core/toolRegistry.js.map +1 -0
- package/dist/src/core/tools/generateImage.d.ts +10 -0
- package/dist/src/core/tools/generateImage.js +34 -0
- package/dist/src/core/tools/generateImage.js.map +1 -0
- package/dist/src/core/turnLoop.d.ts +31 -0
- package/dist/src/core/turnLoop.js +155 -0
- package/dist/src/core/turnLoop.js.map +1 -0
- package/dist/src/core/types.d.ts +137 -0
- package/dist/src/core/types.js +9 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/exec/input.d.ts +35 -0
- package/dist/src/exec/input.js +85 -0
- package/dist/src/exec/input.js.map +1 -0
- package/dist/src/exec/output.d.ts +39 -0
- package/dist/src/exec/output.js +84 -0
- package/dist/src/exec/output.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +253 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcp/server.d.ts +38 -0
- package/dist/src/mcp/server.js +99 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/media/aiApiClient.d.ts +53 -0
- package/dist/src/media/aiApiClient.js +97 -0
- package/dist/src/media/aiApiClient.js.map +1 -0
- package/dist/src/media/errors.d.ts +7 -0
- package/dist/src/media/errors.js +70 -0
- package/dist/src/media/errors.js.map +1 -0
- package/dist/src/media/executor.d.ts +50 -0
- package/dist/src/media/executor.js +55 -0
- package/dist/src/media/executor.js.map +1 -0
- package/dist/src/media/generateImageTool.d.ts +19 -0
- package/dist/src/media/generateImageTool.js +120 -0
- package/dist/src/media/generateImageTool.js.map +1 -0
- package/dist/src/media/manifest.d.ts +23 -0
- package/dist/src/media/manifest.js +558 -0
- package/dist/src/media/manifest.js.map +1 -0
- package/dist/src/media/resolution.d.ts +13 -0
- package/dist/src/media/resolution.js +42 -0
- package/dist/src/media/resolution.js.map +1 -0
- package/dist/src/media/taskLedger.d.ts +17 -0
- package/dist/src/media/taskLedger.js +44 -0
- package/dist/src/media/taskLedger.js.map +1 -0
- package/dist/src/media/taskManager.d.ts +52 -0
- package/dist/src/media/taskManager.js +130 -0
- package/dist/src/media/taskManager.js.map +1 -0
- package/dist/src/media/types.d.ts +80 -0
- package/dist/src/media/types.js +15 -0
- package/dist/src/media/types.js.map +1 -0
- package/dist/src/tui/App.d.ts +34 -0
- package/dist/src/tui/App.js +540 -0
- package/dist/src/tui/App.js.map +1 -0
- package/dist/src/tui/MultilineInput.d.ts +36 -0
- package/dist/src/tui/MultilineInput.js +221 -0
- package/dist/src/tui/MultilineInput.js.map +1 -0
- package/dist/src/tui/atPopup.d.ts +21 -0
- package/dist/src/tui/atPopup.js +55 -0
- package/dist/src/tui/atPopup.js.map +1 -0
- package/dist/src/tui/attachments.d.ts +24 -0
- package/dist/src/tui/attachments.js +91 -0
- package/dist/src/tui/attachments.js.map +1 -0
- package/dist/src/tui/branding.d.ts +22 -0
- package/dist/src/tui/branding.js +119 -0
- package/dist/src/tui/branding.js.map +1 -0
- package/dist/src/tui/chatController.d.ts +188 -0
- package/dist/src/tui/chatController.js +614 -0
- package/dist/src/tui/chatController.js.map +1 -0
- package/dist/src/tui/commands.d.ts +13 -0
- package/dist/src/tui/commands.js +22 -0
- package/dist/src/tui/commands.js.map +1 -0
- package/dist/src/tui/confirmationBridge.d.ts +23 -0
- package/dist/src/tui/confirmationBridge.js +47 -0
- package/dist/src/tui/confirmationBridge.js.map +1 -0
- package/dist/src/tui/inputHistory.d.ts +7 -0
- package/dist/src/tui/inputHistory.js +64 -0
- package/dist/src/tui/inputHistory.js.map +1 -0
- package/dist/src/tui/markdown.d.ts +1 -0
- package/dist/src/tui/markdown.js +143 -0
- package/dist/src/tui/markdown.js.map +1 -0
- package/dist/src/tui/models.d.ts +30 -0
- package/dist/src/tui/models.js +54 -0
- package/dist/src/tui/models.js.map +1 -0
- package/dist/src/tui/run.d.ts +29 -0
- package/dist/src/tui/run.js +212 -0
- package/dist/src/tui/run.js.map +1 -0
- package/dist/src/tui/slashMedia.d.ts +36 -0
- package/dist/src/tui/slashMedia.js +86 -0
- package/dist/src/tui/slashMedia.js.map +1 -0
- package/dist/src/tui/visualLines.d.ts +38 -0
- package/dist/src/tui/visualLines.js +110 -0
- package/dist/src/tui/visualLines.js.map +1 -0
- package/dist/src/util/clipboardImage.d.ts +6 -0
- package/dist/src/util/clipboardImage.js +69 -0
- package/dist/src/util/clipboardImage.js.map +1 -0
- package/dist/src/util/hyperlink.d.ts +10 -0
- package/dist/src/util/hyperlink.js +33 -0
- package/dist/src/util/hyperlink.js.map +1 -0
- package/dist/src/util/imageRef.d.ts +15 -0
- package/dist/src/util/imageRef.js +46 -0
- package/dist/src/util/imageRef.js.map +1 -0
- package/dist/src/util/inlineImage.d.ts +13 -0
- package/dist/src/util/inlineImage.js +56 -0
- package/dist/src/util/inlineImage.js.map +1 -0
- package/dist/src/util/openBrowser.d.ts +5 -0
- package/dist/src/util/openBrowser.js +23 -0
- package/dist/src/util/openBrowser.js.map +1 -0
- package/dist/src/util/retry.d.ts +43 -0
- package/dist/src/util/retry.js +116 -0
- package/dist/src/util/retry.js.map +1 -0
- package/dist/src/version.d.ts +6 -0
- package/dist/src/version.js +16 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/media/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,MAAM,MAAM,GAAG,mCAAmC,CAAC;AAEnD,uDAAuD;AACvD,MAAM,UAAU,uBAAuB,CAAC,GAAyB;IAC/D,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,IAAI;YACP,OAAO,gCAAgC,MAAM,EAAE,CAAC;QAClD,KAAK,IAAI;YACP,OAAO,+EAA+E,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9G,KAAK,IAAI;YACP,OAAO,8CAA8C,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,KAAK,IAAI;YACP,OAAO,wDAAwD,CAAC;QAClE,KAAK,IAAI;YACP,OAAO,+DAA+D,CAAC;QACzE;YACE,OAAO,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,sCAAsC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,mBAAmB,CAAC,UAAqC;IACvE,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,oBAAoB;YACvB,OAAO,gCAAgC,MAAM,EAAE,CAAC;QAClD,KAAK,uBAAuB;YAC1B,OAAO,8CAA8C,CAAC;QACxD;YACE,OAAO,qDAAqD,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;IACxG,CAAC;AACH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,mBAAmB,CAAC,SAAyB,EAAE,YAA4B;IACzF,MAAM,IAAI,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEvC,IAAI,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,OAAO,+FAA+F,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACtH,CAAC;IACD,IAAI,mCAAmC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,gCAAgC,MAAM,EAAE,CAAC;IAClD,CAAC;IACD,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,OAAO,yFAAyF,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAChH,CAAC;IACD,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,uEAAuE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,sEAAsE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7F,CAAC;IACD,+EAA+E;IAC/E,OAAO,GAAG,IAAI,oBAAoB,CAAC;AACrC,CAAC;AAED,6EAA6E;AAC7E,SAAS,MAAM,CAAC,GAAmB;IACjC,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC;IACzB,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,OAAO,KAAK,OAAO,GAAG,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AiApiClient } from './aiApiClient.js';
|
|
2
|
+
import { MediaGenParams, ModelSpec, ParamValidationError } from './types.js';
|
|
3
|
+
/** Info shown to the user/agent before spending. */
|
|
4
|
+
export interface ConfirmInfo {
|
|
5
|
+
model: string;
|
|
6
|
+
displayName: string;
|
|
7
|
+
/** Media kind — lets the TUI offer "edit" by prefilling the matching slash command. */
|
|
8
|
+
type: 'image' | 'video';
|
|
9
|
+
params: MediaGenParams;
|
|
10
|
+
credits: number;
|
|
11
|
+
}
|
|
12
|
+
/** Authorization gate (contract §10): TUI block, auto-approve for top-level command, budget for exec. */
|
|
13
|
+
export interface Confirmer {
|
|
14
|
+
confirm(info: ConfirmInfo): Promise<boolean>;
|
|
15
|
+
}
|
|
16
|
+
export type ExecuteOutcome = {
|
|
17
|
+
status: 'submitted';
|
|
18
|
+
taskId: string;
|
|
19
|
+
model: string;
|
|
20
|
+
credits: number;
|
|
21
|
+
params: MediaGenParams;
|
|
22
|
+
} | {
|
|
23
|
+
status: 'cancelled';
|
|
24
|
+
} | {
|
|
25
|
+
status: 'not_sellable';
|
|
26
|
+
reasonCode: string | null;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Shared generation pipeline: validate → estimate → confirm → upload local images → submit.
|
|
30
|
+
*
|
|
31
|
+
* Returns the taskId immediately; polling/download is the TaskManager's job. The Confirmer is
|
|
32
|
+
* injected so the same executor serves the in-chat tool, the top-level command, and exec.
|
|
33
|
+
*/
|
|
34
|
+
export declare class GenerationExecutor {
|
|
35
|
+
private readonly client;
|
|
36
|
+
private readonly confirmer;
|
|
37
|
+
constructor(client: AiApiClient, confirmer: Confirmer);
|
|
38
|
+
/** Validate params and get a price, without confirming or submitting (for `--estimate`). */
|
|
39
|
+
estimate(modelId: string, rawParams: MediaGenParams): Promise<{
|
|
40
|
+
spec: ModelSpec;
|
|
41
|
+
params: MediaGenParams;
|
|
42
|
+
sellable: boolean;
|
|
43
|
+
credits: number;
|
|
44
|
+
reasonCode: string | null;
|
|
45
|
+
}>;
|
|
46
|
+
execute(modelId: string, rawParams: MediaGenParams): Promise<ExecuteOutcome>;
|
|
47
|
+
/** Replace local file paths in `images` with uploaded URLs (http/https pass through). */
|
|
48
|
+
private uploadLocalImages;
|
|
49
|
+
}
|
|
50
|
+
export { ParamValidationError };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { resolveModel, validateAndNormalize } from './manifest.js';
|
|
2
|
+
import { ParamValidationError } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Shared generation pipeline: validate → estimate → confirm → upload local images → submit.
|
|
5
|
+
*
|
|
6
|
+
* Returns the taskId immediately; polling/download is the TaskManager's job. The Confirmer is
|
|
7
|
+
* injected so the same executor serves the in-chat tool, the top-level command, and exec.
|
|
8
|
+
*/
|
|
9
|
+
export class GenerationExecutor {
|
|
10
|
+
client;
|
|
11
|
+
confirmer;
|
|
12
|
+
constructor(client, confirmer) {
|
|
13
|
+
this.client = client;
|
|
14
|
+
this.confirmer = confirmer;
|
|
15
|
+
}
|
|
16
|
+
/** Validate params and get a price, without confirming or submitting (for `--estimate`). */
|
|
17
|
+
async estimate(modelId, rawParams) {
|
|
18
|
+
const spec = resolveModel(modelId);
|
|
19
|
+
const params = validateAndNormalize(spec, rawParams);
|
|
20
|
+
const estimateId = spec.estimateModelFor?.(params) ?? spec.estimateModel;
|
|
21
|
+
const est = await this.client.estimatePrice(estimateId, spec.buildEstimateParams(params));
|
|
22
|
+
return { spec, params, sellable: est.sellable, credits: est.credits, reasonCode: est.reasonCode };
|
|
23
|
+
}
|
|
24
|
+
async execute(modelId, rawParams) {
|
|
25
|
+
const { spec, params, sellable, credits, reasonCode } = await this.estimate(modelId, rawParams);
|
|
26
|
+
if (!sellable) {
|
|
27
|
+
return { status: 'not_sellable', reasonCode };
|
|
28
|
+
}
|
|
29
|
+
const approved = await this.confirmer.confirm({
|
|
30
|
+
model: spec.id,
|
|
31
|
+
displayName: spec.displayName,
|
|
32
|
+
type: spec.type,
|
|
33
|
+
params,
|
|
34
|
+
credits,
|
|
35
|
+
});
|
|
36
|
+
if (!approved) {
|
|
37
|
+
return { status: 'cancelled' };
|
|
38
|
+
}
|
|
39
|
+
const uploaded = await this.uploadLocalImages(spec, params);
|
|
40
|
+
const taskId = await this.client.submit(spec.submitPath, spec.buildBody(uploaded));
|
|
41
|
+
return { status: 'submitted', taskId, model: spec.id, credits, params: uploaded };
|
|
42
|
+
}
|
|
43
|
+
/** Replace local file paths in `images` with uploaded URLs (http/https pass through). */
|
|
44
|
+
async uploadLocalImages(spec, params) {
|
|
45
|
+
if (!params.images || params.images.length === 0)
|
|
46
|
+
return params;
|
|
47
|
+
const resolved = await Promise.all(params.images.map((img) => (isUrl(img) ? Promise.resolve(img) : this.client.uploadImage(spec.agentId, img))));
|
|
48
|
+
return { ...params, images: resolved };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function isUrl(s) {
|
|
52
|
+
return /^https?:\/\//i.test(s);
|
|
53
|
+
}
|
|
54
|
+
export { ParamValidationError };
|
|
55
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/media/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ClientTool } from '../core/types.js';
|
|
2
|
+
import type { GenerationExecutor } from './executor.js';
|
|
3
|
+
import type { TaskManager } from './taskManager.js';
|
|
4
|
+
import type { TaskLedger } from './taskLedger.js';
|
|
5
|
+
export interface MediaToolDeps {
|
|
6
|
+
executor: GenerationExecutor;
|
|
7
|
+
taskManager: TaskManager;
|
|
8
|
+
ledger: TaskLedger;
|
|
9
|
+
}
|
|
10
|
+
/** Back-compat alias. */
|
|
11
|
+
export type GenerateImageToolDeps = MediaToolDeps;
|
|
12
|
+
/**
|
|
13
|
+
* The real in-chat media tools (contract §4): estimate → confirm (via the executor's Confirmer) →
|
|
14
|
+
* submit, then return the task id to the model immediately. The TaskManager polls and downloads in
|
|
15
|
+
* the background; the result appears in the conversation when ready. Never throws — failures come
|
|
16
|
+
* back as a tool result so the model can react.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createGenerateImageTool(deps: MediaToolDeps): ClientTool;
|
|
19
|
+
export declare function createGenerateVideoTool(deps: MediaToolDeps): ClientTool;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { DEFAULT_IMAGE_MODEL, DEFAULT_VIDEO_MODEL, IMAGE_MODELS, VIDEO_MODELS, findModel } from './manifest.js';
|
|
2
|
+
import { PaymentRequiredError } from './aiApiClient.js';
|
|
3
|
+
import { describePaymentRequired, describeNotSellable } from './errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* The real in-chat media tools (contract §4): estimate → confirm (via the executor's Confirmer) →
|
|
6
|
+
* submit, then return the task id to the model immediately. The TaskManager polls and downloads in
|
|
7
|
+
* the background; the result appears in the conversation when ready. Never throws — failures come
|
|
8
|
+
* back as a tool result so the model can react.
|
|
9
|
+
*/
|
|
10
|
+
export function createGenerateImageTool(deps) {
|
|
11
|
+
return buildTool('image', deps);
|
|
12
|
+
}
|
|
13
|
+
export function createGenerateVideoTool(deps) {
|
|
14
|
+
return buildTool('video', deps);
|
|
15
|
+
}
|
|
16
|
+
function buildTool(kind, deps) {
|
|
17
|
+
const isVideo = kind === 'video';
|
|
18
|
+
const modelIds = (isVideo ? VIDEO_MODELS : IMAGE_MODELS).map((m) => m.id);
|
|
19
|
+
const defaultModel = isVideo ? DEFAULT_VIDEO_MODEL : DEFAULT_IMAGE_MODEL;
|
|
20
|
+
const noun = isVideo ? 'video' : 'image';
|
|
21
|
+
const properties = {
|
|
22
|
+
prompt: { type: 'string', description: 'What to generate' },
|
|
23
|
+
model: { type: 'string', enum: modelIds, description: `${noun} model (default ${defaultModel})` },
|
|
24
|
+
aspect_ratio: { type: 'string', description: 'e.g. 1:1, 16:9, 9:16' },
|
|
25
|
+
resolution: { type: 'string', description: isVideo ? 'e.g. 480p, 720p, 1080p' : 'e.g. 1K, 2K, 4K' },
|
|
26
|
+
seed: { type: 'integer', description: 'Random seed (if supported)' },
|
|
27
|
+
negative_prompt: { type: 'string', description: 'Content to avoid (if supported)' },
|
|
28
|
+
};
|
|
29
|
+
if (isVideo) {
|
|
30
|
+
properties.duration = { type: 'integer', description: 'Video length in seconds' };
|
|
31
|
+
properties.generate_audio = { type: 'boolean', description: 'Generate a soundtrack (if supported)' };
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
properties.count = { type: 'integer', description: 'Number of images (if supported)' };
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: isVideo ? 'generate_video' : 'generate_image',
|
|
38
|
+
description: `Generate ${isVideo ? 'a video' : 'an image'} from a text prompt. Returns a task id immediately; ` +
|
|
39
|
+
`the ${noun} runs in the background and appears in the conversation when ready (do not wait for it). ` +
|
|
40
|
+
`After calling, tell the user generation has STARTED — never claim the ${noun} is already done.`,
|
|
41
|
+
parameters: { type: 'object', properties, required: ['prompt'] },
|
|
42
|
+
async execute(args) {
|
|
43
|
+
const prompt = typeof args.prompt === 'string' ? args.prompt : '';
|
|
44
|
+
if (!prompt.trim())
|
|
45
|
+
return { error: 'prompt is required' };
|
|
46
|
+
const modelId = typeof args.model === 'string' && args.model ? args.model : defaultModel;
|
|
47
|
+
const params = {
|
|
48
|
+
prompt,
|
|
49
|
+
aspectRatio: str(args.aspect_ratio),
|
|
50
|
+
resolution: str(args.resolution),
|
|
51
|
+
};
|
|
52
|
+
if (typeof args.seed === 'number')
|
|
53
|
+
params.seed = args.seed;
|
|
54
|
+
if (typeof args.negative_prompt === 'string' && args.negative_prompt)
|
|
55
|
+
params.negativePrompt = args.negative_prompt;
|
|
56
|
+
if (!isVideo && typeof args.count === 'number')
|
|
57
|
+
params.n = args.count;
|
|
58
|
+
const warnings = [];
|
|
59
|
+
if (isVideo) {
|
|
60
|
+
if (typeof args.duration === 'number')
|
|
61
|
+
params.duration = args.duration;
|
|
62
|
+
if (typeof args.generate_audio === 'boolean') {
|
|
63
|
+
// Models often guess generate_audio:true on their own. On a model without audio
|
|
64
|
+
// support, hard-rejecting just burns a failed round-trip — drop the flag and tell
|
|
65
|
+
// the model instead. (The top-level --audio flag is explicit user intent and still
|
|
66
|
+
// validates strictly in the manifest.)
|
|
67
|
+
const spec = findModel(modelId);
|
|
68
|
+
if (args.generate_audio && spec && !spec.support.supportsAudio) {
|
|
69
|
+
warnings.push(`${modelId} does not support audio; generating without a soundtrack.`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
params.generateAudio = args.generate_audio;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const outcome = await deps.executor.execute(modelId, params);
|
|
78
|
+
if (outcome.status === 'cancelled') {
|
|
79
|
+
return {
|
|
80
|
+
cancelled: true,
|
|
81
|
+
note: 'The user declined this generation (they may adjust the parameters and retry).',
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (outcome.status === 'not_sellable') {
|
|
85
|
+
return { error: describeNotSellable(outcome.reasonCode) };
|
|
86
|
+
}
|
|
87
|
+
// submitted — record and kick off background polling; do NOT await.
|
|
88
|
+
void deps.ledger
|
|
89
|
+
.append({ taskId: outcome.taskId, model: outcome.model, prompt, createdAt: Date.now() })
|
|
90
|
+
.catch(() => { });
|
|
91
|
+
void deps.taskManager.register(outcome.taskId, { model: outcome.model, prompt }).catch(() => { });
|
|
92
|
+
return {
|
|
93
|
+
task_id: outcome.taskId,
|
|
94
|
+
status: 'submitted',
|
|
95
|
+
model: outcome.model,
|
|
96
|
+
estimated_credits: outcome.credits,
|
|
97
|
+
...(warnings.length ? { warnings } : {}),
|
|
98
|
+
note: `The ${noun} is STILL GENERATING in the background (typically 1-3 minutes) — it is NOT ` +
|
|
99
|
+
`finished. Briefly tell the user generation has started and the result will appear in ` +
|
|
100
|
+
`the conversation automatically, then end your response. Do NOT say it is already ` +
|
|
101
|
+
`generated/created/done, and never describe or predict what the ${noun} looks like — ` +
|
|
102
|
+
`you have not seen it.`,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
return {
|
|
107
|
+
error: err instanceof PaymentRequiredError
|
|
108
|
+
? describePaymentRequired(err)
|
|
109
|
+
: err instanceof Error
|
|
110
|
+
? err.message
|
|
111
|
+
: String(err),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function str(v) {
|
|
118
|
+
return typeof v === 'string' && v ? v : undefined;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=generateImageTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateImageTool.js","sourceRoot":"","sources":["../../../src/media/generateImageTool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { MediaGenParams, ModelSpec } from './types.js';
|
|
2
|
+
export declare const IMAGE_MODELS: ModelSpec[];
|
|
3
|
+
export declare const VIDEO_MODELS: ModelSpec[];
|
|
4
|
+
export declare const ALL_MODELS: ModelSpec[];
|
|
5
|
+
export declare const DEFAULT_IMAGE_MODEL = "nano-banana-2";
|
|
6
|
+
export declare const DEFAULT_VIDEO_MODEL = "grok-imagine-video";
|
|
7
|
+
/** Apply the server's disabled-model overlay (unknown ids are fine — future models). */
|
|
8
|
+
export declare function applyMediaDisabled(ids: string[]): void;
|
|
9
|
+
/** True when the server has pulled this model (hidden from lists, refused on use). */
|
|
10
|
+
export declare function isModelDisabled(id: string): boolean;
|
|
11
|
+
/** Test hook: clear the overlay. */
|
|
12
|
+
export declare function resetMediaDisabled(): void;
|
|
13
|
+
/** Models currently available for use/listing (built-in minus the server overlay). */
|
|
14
|
+
export declare function availableModels(): ModelSpec[];
|
|
15
|
+
/** Look up a model spec by CLI id. */
|
|
16
|
+
export declare function findModel(id: string): ModelSpec | undefined;
|
|
17
|
+
/** Resolve a model id, erroring with close candidates on a typo (no silent fuzzy match). */
|
|
18
|
+
export declare function resolveModel(id: string): ModelSpec;
|
|
19
|
+
/**
|
|
20
|
+
* Validate raw user params against a model's declared support and return normalized params.
|
|
21
|
+
* Throws ParamValidationError with allowed values on an unsupported choice (no silent clamp).
|
|
22
|
+
*/
|
|
23
|
+
export declare function validateAndNormalize(spec: ModelSpec, raw: MediaGenParams): MediaGenParams;
|