@vibedev-si/dsh-vibedev 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +155 -0
- package/THIRD-PARTY-NOTICES.txt +566 -0
- package/client/client.js +1368 -0
- package/cordis.patch.yml +5 -0
- package/icon.svg +7 -0
- package/lib/account/index.d.ts +118 -0
- package/lib/anthropic-messages-KOS0z8Fy.js +13472 -0
- package/lib/auth/credentials.d.ts +47 -0
- package/lib/auth/login.d.ts +154 -0
- package/lib/gateway/assets.d.ts +61 -0
- package/lib/gateway/catalog.d.ts +126 -0
- package/lib/gateway/errors.d.ts +76 -0
- package/lib/gateway/http.d.ts +94 -0
- package/lib/index.d.ts +105 -0
- package/lib/index.js +7301 -0
- package/lib/llm/adapter.d.ts +129 -0
- package/lib/llm/catalog.d.ts +75 -0
- package/lib/llm/context.d.ts +54 -0
- package/lib/llm/index.d.ts +69 -0
- package/lib/llm/limits.d.ts +19 -0
- package/lib/llm/models.d.ts +67 -0
- package/lib/llm/replay.d.ts +66 -0
- package/lib/llm/stream.d.ts +46 -0
- package/lib/media/chat.d.ts +49 -0
- package/lib/media/sources.d.ts +46 -0
- package/lib/models-CAcLevEN.js +1045 -0
- package/lib/node-Cujw_a4_.js +2403 -0
- package/lib/node-vkDR3GtK.js +25 -0
- package/lib/openai-completions-DqTCiqpS.js +983 -0
- package/lib/openai-prompt-cache-kzRZVokq.js +9567 -0
- package/lib/openai-responses-DygWnsye.js +832 -0
- package/lib/pricing.d.ts +49 -0
- package/lib/runtime.d.ts +150 -0
- package/lib/search/provider.d.ts +86 -0
- package/lib/service.d.ts +99 -0
- package/lib/tasks/remote.d.ts +47 -0
- package/lib/tasks/store.d.ts +132 -0
- package/lib/tasks/tracker.d.ts +127 -0
- package/lib/tools/account.d.ts +21 -0
- package/lib/tools/audio.d.ts +13 -0
- package/lib/tools/common.d.ts +77 -0
- package/lib/tools/image.d.ts +50 -0
- package/lib/tools/models.d.ts +13 -0
- package/lib/tools/tasks.d.ts +13 -0
- package/lib/tools/transcribe.d.ts +19 -0
- package/lib/tools/video.d.ts +48 -0
- package/lib/transform-messages-Csvf2ItW.js +1023 -0
- package/lib/util/files.d.ts +80 -0
- package/lib/video/plan.d.ts +96 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +127 -0
package/lib/pricing.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Price estimates from the catalog's `media_pricing` (selling prices with the
|
|
3
|
+
* account multiplier applied). The gateway estimates the same way at admission:
|
|
4
|
+
* per-second video prices times billed seconds, where billed seconds are the
|
|
5
|
+
* output length plus the summed reference video length, rounded up once.
|
|
6
|
+
* Estimates are for the user's information; the gateway's receipt is the charge.
|
|
7
|
+
* @module dsh-vibedev/pricing
|
|
8
|
+
*/
|
|
9
|
+
import type { MediaModel } from './gateway/catalog.js';
|
|
10
|
+
/** One estimate. */
|
|
11
|
+
export interface Estimate {
|
|
12
|
+
readonly amountCny: number;
|
|
13
|
+
/** How it was reached, such as `¥0.99/s × 5 s`. */
|
|
14
|
+
readonly basis: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Format an amount in yuan.
|
|
18
|
+
* @param amount - the amount.
|
|
19
|
+
* @returns `¥4.95`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function yuan(amount: number): string;
|
|
22
|
+
/**
|
|
23
|
+
* A one-line price for listings: `¥0.10 per image`, `¥0.99/s (720p)`.
|
|
24
|
+
* @param model - the model.
|
|
25
|
+
* @returns the price, or undefined when the catalog gives none.
|
|
26
|
+
*/
|
|
27
|
+
export declare function describePrice(model: MediaModel): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Estimate an image request.
|
|
30
|
+
* @param model - the image model.
|
|
31
|
+
* @param count - images requested.
|
|
32
|
+
* @returns the estimate, or undefined without a price.
|
|
33
|
+
*/
|
|
34
|
+
export declare function estimateImages(model: MediaModel, count: number): Estimate | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Estimate a video request.
|
|
37
|
+
* @param model - the video model.
|
|
38
|
+
* @param duration - the requested length in seconds, when given.
|
|
39
|
+
* @param resolution - the requested resolution, when given.
|
|
40
|
+
* @param referenceMs - the summed length of the reference videos.
|
|
41
|
+
* @returns the estimate, or undefined without a price.
|
|
42
|
+
*/
|
|
43
|
+
export declare function estimateVideo(model: MediaModel, duration: number | undefined, resolution: string | undefined, referenceMs?: number): Estimate | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Estimate a music or podcast request.
|
|
46
|
+
* @param model - the audio model.
|
|
47
|
+
* @returns the estimate, or undefined without a price.
|
|
48
|
+
*/
|
|
49
|
+
export declare function estimateAudio(model: MediaModel): Estimate | undefined;
|
package/lib/runtime.d.ts
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What every media tool shares: the gateway client, the model catalog (cached
|
|
3
|
+
* briefly), model choice, the workspace output folders, input loading
|
|
4
|
+
* (workspace paths, links, data URLs and `chat:` attachments) and the optional
|
|
5
|
+
* spending confirmation.
|
|
6
|
+
* @module dsh-vibedev/runtime
|
|
7
|
+
*/
|
|
8
|
+
import type { AttachmentStore } from '@deepseek-ai/dsh-attachment';
|
|
9
|
+
import type { FileSystem } from '@deepseek-ai/dsh-fs';
|
|
10
|
+
import type { JobRegistry } from '@deepseek-ai/dsh-jobs';
|
|
11
|
+
import type { ToolRunContext } from '@deepseek-ai/dsh-tools';
|
|
12
|
+
import type { ApprovalService } from '@deepseek-ai/dsh-user-approval';
|
|
13
|
+
import type { MediaKind, MediaModel } from './gateway/catalog.js';
|
|
14
|
+
import type { GatewayHttp } from './gateway/http.js';
|
|
15
|
+
import type { MediaLibrary } from './gateway/assets.js';
|
|
16
|
+
import type { ChatMediaKind } from './media/chat.js';
|
|
17
|
+
import type { LoadedMedia } from './media/sources.js';
|
|
18
|
+
import type { TaskStore } from './tasks/store.js';
|
|
19
|
+
import type { TaskTracker } from './tasks/tracker.js';
|
|
20
|
+
/** The model a setting can pin per kind of output. */
|
|
21
|
+
export type ModelSlot = 'image' | 'video' | 'music' | 'podcast' | 'transcription';
|
|
22
|
+
/** Live settings (the plugin's volatile config). */
|
|
23
|
+
export interface MediaSettings {
|
|
24
|
+
/** Output folder, relative to the workspace (or absolute). */
|
|
25
|
+
readonly outputDir: () => string;
|
|
26
|
+
readonly confirmSpending: () => boolean;
|
|
27
|
+
/** A pinned model id, or `''` to let the agent choose. */
|
|
28
|
+
readonly defaultModel: (slot: ModelSlot) => string;
|
|
29
|
+
}
|
|
30
|
+
/** Construction options. Optional services are read when used, since they can come and go. */
|
|
31
|
+
export interface RuntimeOptions {
|
|
32
|
+
readonly http: GatewayHttp;
|
|
33
|
+
readonly library: MediaLibrary;
|
|
34
|
+
readonly tracker: TaskTracker;
|
|
35
|
+
readonly store: TaskStore;
|
|
36
|
+
readonly settings: MediaSettings;
|
|
37
|
+
readonly stateDir: string;
|
|
38
|
+
readonly fs?: () => FileSystem | undefined;
|
|
39
|
+
readonly attachments?: () => AttachmentStore | undefined;
|
|
40
|
+
readonly approval?: () => ApprovalService | undefined;
|
|
41
|
+
readonly jobs?: () => JobRegistry | undefined;
|
|
42
|
+
readonly now?: () => number;
|
|
43
|
+
readonly log?: (message: string) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Who a media request runs for: an agent's tool call (a {@link ToolRunContext}
|
|
47
|
+
* fits as it is), or a host caller such as the film workbench, which names the
|
|
48
|
+
* workspace itself and shows the cost in its own interface first.
|
|
49
|
+
*/
|
|
50
|
+
export interface MediaCall {
|
|
51
|
+
readonly signal: AbortSignal;
|
|
52
|
+
readonly callId?: ToolRunContext['callId'];
|
|
53
|
+
readonly agent?: ToolRunContext['agent'];
|
|
54
|
+
/** The workspace, for callers without an agent session. */
|
|
55
|
+
readonly cwd?: string;
|
|
56
|
+
/** The caller already showed the cost and the user chose to go ahead. */
|
|
57
|
+
readonly confirmed?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Shared state and helpers of the media tools. */
|
|
60
|
+
export declare class MediaRuntime {
|
|
61
|
+
readonly options: RuntimeOptions;
|
|
62
|
+
private catalog;
|
|
63
|
+
private fetching;
|
|
64
|
+
private generation;
|
|
65
|
+
readonly now: () => number;
|
|
66
|
+
/**
|
|
67
|
+
* @param options - gateway client, stores, settings and host services.
|
|
68
|
+
*/
|
|
69
|
+
constructor(options: RuntimeOptions);
|
|
70
|
+
get http(): GatewayHttp;
|
|
71
|
+
get library(): MediaLibrary;
|
|
72
|
+
get tracker(): TaskTracker;
|
|
73
|
+
get store(): TaskStore;
|
|
74
|
+
get settings(): MediaSettings;
|
|
75
|
+
/**
|
|
76
|
+
* The media models this account can use. Cached for two minutes; a failed
|
|
77
|
+
* refresh falls back to the last list for up to an hour.
|
|
78
|
+
* @param signal - cancels the request.
|
|
79
|
+
* @returns the models, in catalog order.
|
|
80
|
+
*/
|
|
81
|
+
models(signal?: AbortSignal): Promise<MediaModel[]>;
|
|
82
|
+
/** Forget what belonged to the previous account (catalog and uploaded assets), as after a sign-in change. */
|
|
83
|
+
accountChanged(): void;
|
|
84
|
+
/** Forget the cached catalog. */
|
|
85
|
+
invalidateCatalog(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Choose the model for a request: the one asked for, else the pinned one,
|
|
88
|
+
* else the first in catalog order that `accept` takes (or simply the first).
|
|
89
|
+
* @param kind - the kind of output.
|
|
90
|
+
* @param slot - the settings slot.
|
|
91
|
+
* @param requested - the model the agent asked for, if any.
|
|
92
|
+
* @param accept - whether a model can serve this request.
|
|
93
|
+
* @param signal - cancels the catalog request.
|
|
94
|
+
* @returns the model.
|
|
95
|
+
*/
|
|
96
|
+
pickModel(kind: MediaKind, slot: ModelSlot, requested: string | undefined, accept?: (model: MediaModel) => boolean, signal?: AbortSignal): Promise<MediaModel>;
|
|
97
|
+
/**
|
|
98
|
+
* The workspace of the calling session.
|
|
99
|
+
* @param call - the tool call or host call.
|
|
100
|
+
* @returns its absolute working directory, when it has one.
|
|
101
|
+
*/
|
|
102
|
+
workspace(call: MediaCall): string | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* The absolute folder outputs of one kind are saved in: `<workspace>/<outputDir>/<sub>`.
|
|
105
|
+
* Without a workspace, the plugin state directory is used.
|
|
106
|
+
* @param call - the tool call or host call.
|
|
107
|
+
* @param sub - `images`, `videos`, `audio` or `transcripts`.
|
|
108
|
+
* @returns the folder (created on first write).
|
|
109
|
+
*/
|
|
110
|
+
outputFolder(call: MediaCall, sub: string): string;
|
|
111
|
+
/**
|
|
112
|
+
* A file-name stem: the requested name, else a timestamp plus the start of the prompt.
|
|
113
|
+
* @param filename - the agent's requested name, without extension.
|
|
114
|
+
* @param prompt - the prompt.
|
|
115
|
+
* @returns the stem.
|
|
116
|
+
*/
|
|
117
|
+
stem(filename: string | undefined, prompt: string | undefined): string;
|
|
118
|
+
/**
|
|
119
|
+
* A path relative to the workspace when it is inside it, for messages.
|
|
120
|
+
* @param call - the tool call or host call.
|
|
121
|
+
* @param path - an absolute path.
|
|
122
|
+
* @returns the display path.
|
|
123
|
+
*/
|
|
124
|
+
display(call: MediaCall, path: string): string;
|
|
125
|
+
private reader;
|
|
126
|
+
/**
|
|
127
|
+
* Load one input: a `chat:` attachment, a data URL, a link, or a path in the workspace.
|
|
128
|
+
* @param call - the tool call or host call.
|
|
129
|
+
* @param source - what the agent passed.
|
|
130
|
+
* @param want - the kind the input needs.
|
|
131
|
+
* @param maxBytes - the largest accepted file.
|
|
132
|
+
* @returns the loaded media.
|
|
133
|
+
*/
|
|
134
|
+
load(call: MediaCall, source: string, want: ChatMediaKind, maxBytes: number): Promise<LoadedMedia>;
|
|
135
|
+
/**
|
|
136
|
+
* Ask the user before spending, when the setting asks for it.
|
|
137
|
+
* @param call - the tool call or host call.
|
|
138
|
+
* @param toolName - the tool asking.
|
|
139
|
+
* @param what - the request and its estimated price, in English and Chinese.
|
|
140
|
+
* @throws {@link MediaError} when the user declines or nobody can answer.
|
|
141
|
+
*/
|
|
142
|
+
confirmSpending(call: MediaCall, toolName: string, what: {
|
|
143
|
+
en: string;
|
|
144
|
+
zh: string;
|
|
145
|
+
}): Promise<void>;
|
|
146
|
+
/** The background-job registry, when the host has one. */
|
|
147
|
+
jobs(): JobRegistry | undefined;
|
|
148
|
+
/** Log through the host. */
|
|
149
|
+
log(message: string): void;
|
|
150
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `GatewaySearchProvider`: a `WebSearchProvider` backed by the VibeDev gateway's
|
|
3
|
+
* `POST /v1/vibedev/web-search`. The gateway returns titles, snippets and
|
|
4
|
+
* publication dates, not page bodies (`web_fetch` reads pages), plus instant
|
|
5
|
+
* answers, which become the result's `content`.
|
|
6
|
+
*
|
|
7
|
+
* The gateway asks clients to send searches one at a time and to wait as
|
|
8
|
+
* `Retry-After` says, so the provider queues searches (`web_search` runs one
|
|
9
|
+
* call's queries in parallel) and waits out short rate-limit and busy answers
|
|
10
|
+
* before giving up. A token the gateway rejects is reported back to where it
|
|
11
|
+
* came from, which renews it, and the search is retried once.
|
|
12
|
+
*
|
|
13
|
+
* Ported from the VibeDev app's own search package
|
|
14
|
+
* (`@vibedev/dsh-web-search-gateway`, provider.ts); here the credential is the
|
|
15
|
+
* plugin's (host account, its own sign-in, or a development key).
|
|
16
|
+
* @module dsh-vibedev/search/provider
|
|
17
|
+
*/
|
|
18
|
+
import type { WebSearchProvider, WebSearchRequest, WebSearchResult } from '@deepseek-ai/dsh-web';
|
|
19
|
+
import type { GatewayCredential } from '../gateway/http.js';
|
|
20
|
+
/** Stable id the provider registers under; a profile selects it as `web.searchProvider`. */
|
|
21
|
+
export declare const GATEWAY_SEARCH_PROVIDER_ID = "vibedev-gateway";
|
|
22
|
+
/** What the provider needs from its plugin, plus test seams. */
|
|
23
|
+
export interface GatewaySearchOptions {
|
|
24
|
+
/** Absolute URL of the gateway's web-search endpoint. */
|
|
25
|
+
readonly endpoint: string;
|
|
26
|
+
/** The credential for the next request; undefined while nobody is signed in and no key is set. */
|
|
27
|
+
readonly resolveCredential: () => Promise<GatewayCredential | undefined>;
|
|
28
|
+
/** Report a credential the gateway rejected, so its source renews it. */
|
|
29
|
+
readonly rejectCredential?: (credential: GatewayCredential) => Promise<void>;
|
|
30
|
+
/** `User-Agent` sent with every request. */
|
|
31
|
+
readonly userAgent: string;
|
|
32
|
+
/** Deadline for one HTTP request. */
|
|
33
|
+
readonly requestTimeoutMs: number;
|
|
34
|
+
/** Retries after a rate-limited or busy answer. */
|
|
35
|
+
readonly maxRetries: number;
|
|
36
|
+
/** Longest `Retry-After` waited out; a longer one fails the search at once. */
|
|
37
|
+
readonly maxRetryWaitMs: number;
|
|
38
|
+
/** HTTP client; defaults to the global `fetch`. */
|
|
39
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
40
|
+
/** Delay used for `Retry-After`; defaults to a timer that the search's signal cancels. */
|
|
41
|
+
readonly sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Milliseconds a `Retry-After` header asks for: delta seconds or an HTTP date.
|
|
45
|
+
* @param header - the header value, or null when absent.
|
|
46
|
+
* @param now - the current epoch milliseconds, for an HTTP date.
|
|
47
|
+
* @returns the wait, or undefined when the header is absent or unreadable.
|
|
48
|
+
*/
|
|
49
|
+
export declare function searchRetryAfterMs(header: string | null, now?: number): number | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* The request body: the query and, when bounded, the result count within the gateway's limits.
|
|
52
|
+
* Any other field makes the gateway answer 400.
|
|
53
|
+
* @param request - the seam request.
|
|
54
|
+
* @returns the JSON body.
|
|
55
|
+
*/
|
|
56
|
+
export declare function requestBody(request: WebSearchRequest): string;
|
|
57
|
+
/**
|
|
58
|
+
* Map a gateway search answer to the seam's result. Entries without a usable URL are dropped;
|
|
59
|
+
* instant answers become `content`.
|
|
60
|
+
* @param payload - the parsed response body.
|
|
61
|
+
* @returns the normalized result.
|
|
62
|
+
*/
|
|
63
|
+
export declare function mapSearchResponse(payload: unknown): WebSearchResult;
|
|
64
|
+
/** Web search through the VibeDev gateway. */
|
|
65
|
+
export declare class GatewaySearchProvider implements WebSearchProvider {
|
|
66
|
+
private readonly options;
|
|
67
|
+
readonly id = "vibedev-gateway";
|
|
68
|
+
private queue;
|
|
69
|
+
/**
|
|
70
|
+
* @param options - endpoint, credential plane, retry bounds, and test seams.
|
|
71
|
+
*/
|
|
72
|
+
constructor(options: GatewaySearchOptions);
|
|
73
|
+
/** Always usable: without a credential a search fails with a sign-in hint rather than an unselected provider. */
|
|
74
|
+
available(): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Run one search after the ones already queued.
|
|
77
|
+
* @param request - the query and optional result bound.
|
|
78
|
+
* @param signal - cancels the search, queued or running.
|
|
79
|
+
* @returns the normalized result.
|
|
80
|
+
*/
|
|
81
|
+
search(request: WebSearchRequest, signal?: AbortSignal): Promise<WebSearchResult>;
|
|
82
|
+
private searchNow;
|
|
83
|
+
private credential;
|
|
84
|
+
private post;
|
|
85
|
+
private json;
|
|
86
|
+
}
|
package/lib/service.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The media service other plugins call, registered as `vibedevMedia`: the
|
|
3
|
+
* film workbench's storyboard generates through it when someone presses a
|
|
4
|
+
* generate button. It takes the same paths as the agent tools — model
|
|
5
|
+
* choice, reference checks and uploads, idempotent submission, a background
|
|
6
|
+
* follower that saves the result — with the caller naming the workspace and
|
|
7
|
+
* where results go. The caller has already shown the price and the user chose
|
|
8
|
+
* to go ahead, so the spending confirmation setting does not ask again.
|
|
9
|
+
* @module dsh-vibedev/service
|
|
10
|
+
*/
|
|
11
|
+
import type { MediaModel } from './gateway/catalog.js';
|
|
12
|
+
import type { MediaRuntime } from './runtime.js';
|
|
13
|
+
import type { TaskRecord, TaskStatus } from './tasks/store.js';
|
|
14
|
+
import type { ImageRequest } from './tools/image.js';
|
|
15
|
+
import type { VideoRequest } from './tools/video.js';
|
|
16
|
+
/** Where a host request runs and where its results go. */
|
|
17
|
+
export interface HostTarget {
|
|
18
|
+
/** The workspace; relative input paths resolve against it. */
|
|
19
|
+
readonly cwd: string;
|
|
20
|
+
/** Absolute folder the results are saved in. */
|
|
21
|
+
readonly folder: string;
|
|
22
|
+
/** File-name stem of the results. */
|
|
23
|
+
readonly stem: string;
|
|
24
|
+
}
|
|
25
|
+
/** A video or audio task, as host callers see it. */
|
|
26
|
+
export interface MediaTaskView {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly kind: TaskRecord['kind'];
|
|
29
|
+
readonly model: string;
|
|
30
|
+
readonly status: TaskStatus;
|
|
31
|
+
readonly progress?: string;
|
|
32
|
+
readonly outputs?: readonly {
|
|
33
|
+
readonly path?: string;
|
|
34
|
+
readonly url?: string;
|
|
35
|
+
readonly durationSeconds?: number;
|
|
36
|
+
}[];
|
|
37
|
+
readonly error?: {
|
|
38
|
+
readonly code: string;
|
|
39
|
+
readonly message: string;
|
|
40
|
+
};
|
|
41
|
+
readonly estimatedCny?: string;
|
|
42
|
+
readonly chargedCny?: string;
|
|
43
|
+
readonly createdAt: number;
|
|
44
|
+
readonly updatedAt: number;
|
|
45
|
+
}
|
|
46
|
+
export declare class MediaHostService {
|
|
47
|
+
private readonly runtime;
|
|
48
|
+
readonly version: string;
|
|
49
|
+
constructor(runtime: MediaRuntime, version: string);
|
|
50
|
+
private call;
|
|
51
|
+
/**
|
|
52
|
+
* The media models this account can use (cached briefly).
|
|
53
|
+
* @param signal - cancels the request.
|
|
54
|
+
* @returns the models in catalog order.
|
|
55
|
+
*/
|
|
56
|
+
models(signal?: AbortSignal): Promise<readonly MediaModel[]>;
|
|
57
|
+
/**
|
|
58
|
+
* Generate images now and save them.
|
|
59
|
+
* @param request - what to generate.
|
|
60
|
+
* @param target - the workspace and where the files go.
|
|
61
|
+
* @param signal - cancels the request.
|
|
62
|
+
* @returns the model, the saved files, the estimate and a revised prompt.
|
|
63
|
+
*/
|
|
64
|
+
generateImages(request: ImageRequest, target: HostTarget, signal: AbortSignal): Promise<{
|
|
65
|
+
images: {
|
|
66
|
+
absolutePath: string;
|
|
67
|
+
mediaType: string;
|
|
68
|
+
bytes: number;
|
|
69
|
+
}[];
|
|
70
|
+
model: string;
|
|
71
|
+
estimatedCny?: string;
|
|
72
|
+
revisedPrompt?: string;
|
|
73
|
+
}>;
|
|
74
|
+
/**
|
|
75
|
+
* Submit a video. The plugin follows the task in the background and saves
|
|
76
|
+
* the video when it finishes; watch it with {@link task} and {@link onTask}.
|
|
77
|
+
* A submission the gateway did not confirm is resent in the background
|
|
78
|
+
* under the same key, so it is reported as a task still being submitted
|
|
79
|
+
* rather than as a failure.
|
|
80
|
+
* @param request - what to generate.
|
|
81
|
+
* @param target - the workspace and where the video goes.
|
|
82
|
+
* @param signal - cancels the preparation and the submission.
|
|
83
|
+
* @returns the task.
|
|
84
|
+
*/
|
|
85
|
+
startVideo(request: VideoRequest, target: HostTarget, signal: AbortSignal): Promise<MediaTaskView>;
|
|
86
|
+
/**
|
|
87
|
+
* A task's current state.
|
|
88
|
+
* @param id - the task id.
|
|
89
|
+
* @returns the task, or `undefined` when there is none.
|
|
90
|
+
*/
|
|
91
|
+
task(id: string): Promise<MediaTaskView | undefined>;
|
|
92
|
+
/**
|
|
93
|
+
* Hear about every change to one task.
|
|
94
|
+
* @param id - the task id.
|
|
95
|
+
* @param listener - called with the task after each change.
|
|
96
|
+
* @returns stops listening.
|
|
97
|
+
*/
|
|
98
|
+
onTask(id: string, listener: (task: MediaTaskView) => void): () => void;
|
|
99
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reading the gateway's asynchronous task objects: `POST /v1/videos` and
|
|
3
|
+
* `GET /v1/videos/{id}` (OpenAI video shape plus the gateway's `effective`
|
|
4
|
+
* receipt and `asset`), and `POST /v1/audio/generations` and
|
|
5
|
+
* `GET /v1/audio/generations/{id}` (`outputs[]`). Unknown statuses count as
|
|
6
|
+
* still running; only an explicit terminal status ends a task.
|
|
7
|
+
* @module dsh-vibedev/tasks/remote
|
|
8
|
+
*/
|
|
9
|
+
/** One produced file as the gateway describes it. */
|
|
10
|
+
export interface RemoteOutput {
|
|
11
|
+
/** Position in `outputs[]`, for `/content?index=N`. */
|
|
12
|
+
readonly index: number;
|
|
13
|
+
readonly url?: string;
|
|
14
|
+
readonly contentType?: string;
|
|
15
|
+
readonly title?: string;
|
|
16
|
+
readonly durationSeconds?: number;
|
|
17
|
+
}
|
|
18
|
+
/** A task's state. */
|
|
19
|
+
export interface RemoteTask {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly state: 'pending' | 'completed' | 'failed';
|
|
22
|
+
/** The gateway's own status word. */
|
|
23
|
+
readonly status: string;
|
|
24
|
+
/** Percent done, when the gateway reports it. */
|
|
25
|
+
readonly progress?: number;
|
|
26
|
+
readonly error?: {
|
|
27
|
+
readonly code: string;
|
|
28
|
+
readonly message: string;
|
|
29
|
+
};
|
|
30
|
+
/** Estimated price at submission (CNY, two decimals). */
|
|
31
|
+
readonly estimatedCny?: string;
|
|
32
|
+
/** Settled charge (CNY); absent until the gateway settles, which is not the same as free. */
|
|
33
|
+
readonly chargedCny?: string;
|
|
34
|
+
readonly outputs: readonly RemoteOutput[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Read a video task.
|
|
38
|
+
* @param body - the parsed answer.
|
|
39
|
+
* @returns the task, or undefined when the answer names no task id.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseVideoTask(body: unknown): RemoteTask | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Read a music or podcast task.
|
|
44
|
+
* @param body - the parsed answer.
|
|
45
|
+
* @returns the task, or undefined when the answer names no task id.
|
|
46
|
+
*/
|
|
47
|
+
export declare function parseAudioTask(body: unknown): RemoteTask | undefined;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The durable list of video and audio tasks, one file per task under
|
|
3
|
+
* `<state dir>/tasks/`, so harness processes sharing a home never overwrite
|
|
4
|
+
* each other's tasks. A task is recorded before it is submitted, under the id
|
|
5
|
+
* that doubles as its `Idempotency-Key`: a submission cut short is resent under
|
|
6
|
+
* the same key (the gateway returns the original task instead of creating a
|
|
7
|
+
* second one), and a task still running when the host restarts is followed to
|
|
8
|
+
* the end. A claim file names the process following a task, so two processes
|
|
9
|
+
* never poll and download the same one.
|
|
10
|
+
* @module dsh-vibedev/tasks/store
|
|
11
|
+
*/
|
|
12
|
+
/** What a task produces. */
|
|
13
|
+
export type TaskKind = 'video' | 'audio';
|
|
14
|
+
/**
|
|
15
|
+
* `submitting`: recorded, not yet confirmed by the gateway. `pending`: the
|
|
16
|
+
* gateway accepted it. `lost`: given up on (too old, or the gateway forgot it).
|
|
17
|
+
*/
|
|
18
|
+
export type TaskStatus = 'submitting' | 'pending' | 'completed' | 'failed' | 'lost';
|
|
19
|
+
/** One produced file. */
|
|
20
|
+
export interface TaskOutput {
|
|
21
|
+
/** Position in the gateway's outputs. */
|
|
22
|
+
readonly index?: number;
|
|
23
|
+
/** Where it was saved; absent when the download failed. */
|
|
24
|
+
readonly path?: string;
|
|
25
|
+
/** The gateway's link to the file (valid for about 30 days). */
|
|
26
|
+
readonly url?: string;
|
|
27
|
+
readonly contentType?: string;
|
|
28
|
+
readonly bytes?: number;
|
|
29
|
+
readonly title?: string;
|
|
30
|
+
readonly durationSeconds?: number;
|
|
31
|
+
}
|
|
32
|
+
/** One task. */
|
|
33
|
+
export interface TaskRecord {
|
|
34
|
+
/** Local id; also the `Idempotency-Key` of the submission. */
|
|
35
|
+
readonly id: string;
|
|
36
|
+
readonly kind: TaskKind;
|
|
37
|
+
readonly model: string;
|
|
38
|
+
/** A short description for listings (a prompt excerpt). */
|
|
39
|
+
readonly label: string;
|
|
40
|
+
readonly createdAt: number;
|
|
41
|
+
readonly updatedAt: number;
|
|
42
|
+
/** The session that asked for it. */
|
|
43
|
+
readonly owner?: string;
|
|
44
|
+
/** Absolute directory the outputs are saved in. */
|
|
45
|
+
readonly outputDir: string;
|
|
46
|
+
/** File-name stem for the outputs. */
|
|
47
|
+
readonly stem: string;
|
|
48
|
+
/** The submission, kept so an unconfirmed one can be resent unchanged. */
|
|
49
|
+
readonly endpoint: string;
|
|
50
|
+
readonly body: Readonly<Record<string, unknown>>;
|
|
51
|
+
readonly gatewayId?: string;
|
|
52
|
+
readonly status: TaskStatus;
|
|
53
|
+
readonly progress?: string;
|
|
54
|
+
/** Outputs saved so far; a finished task lists every output. */
|
|
55
|
+
readonly outputs?: readonly TaskOutput[];
|
|
56
|
+
readonly error?: {
|
|
57
|
+
readonly code: string;
|
|
58
|
+
readonly message: string;
|
|
59
|
+
};
|
|
60
|
+
readonly estimatedCny?: string;
|
|
61
|
+
readonly chargedCny?: string;
|
|
62
|
+
readonly finishedAt?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Whether a task has ended.
|
|
66
|
+
* @param record - the task.
|
|
67
|
+
* @returns true for completed, failed and lost tasks.
|
|
68
|
+
*/
|
|
69
|
+
export declare function isFinished(record: Pick<TaskRecord, 'status'>): boolean;
|
|
70
|
+
/** Task records under `<state dir>/tasks/`. */
|
|
71
|
+
export declare class TaskStore {
|
|
72
|
+
private readonly directory;
|
|
73
|
+
private readonly now;
|
|
74
|
+
private readonly chains;
|
|
75
|
+
/**
|
|
76
|
+
* @param directory - the plugin state directory.
|
|
77
|
+
* @param now - clock.
|
|
78
|
+
*/
|
|
79
|
+
constructor(directory: string, now?: () => number);
|
|
80
|
+
private get dir();
|
|
81
|
+
private file;
|
|
82
|
+
/** Run one change to a task after the previous change to it in this process. */
|
|
83
|
+
private serial;
|
|
84
|
+
/** All tasks, newest first, as they are on disk now (other processes' tasks included). */
|
|
85
|
+
list(): Promise<TaskRecord[]>;
|
|
86
|
+
/**
|
|
87
|
+
* One task.
|
|
88
|
+
* @param id - its local id.
|
|
89
|
+
* @returns the task, or undefined.
|
|
90
|
+
*/
|
|
91
|
+
get(id: string): Promise<TaskRecord | undefined>;
|
|
92
|
+
/**
|
|
93
|
+
* Record a new task.
|
|
94
|
+
* @param record - the task.
|
|
95
|
+
* @returns the stored task.
|
|
96
|
+
*/
|
|
97
|
+
add(record: TaskRecord): Promise<TaskRecord>;
|
|
98
|
+
/**
|
|
99
|
+
* Change a task.
|
|
100
|
+
* @param id - its local id.
|
|
101
|
+
* @param patch - the fields to replace.
|
|
102
|
+
* @returns the updated task, or undefined when it is unknown.
|
|
103
|
+
*/
|
|
104
|
+
update(id: string, patch: Partial<Omit<TaskRecord, 'id' | 'kind' | 'createdAt'>>): Promise<TaskRecord | undefined>;
|
|
105
|
+
/**
|
|
106
|
+
* Forget a task, such as a submission the gateway refused outright.
|
|
107
|
+
* @param id - its local id.
|
|
108
|
+
*/
|
|
109
|
+
remove(id: string): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Claim the right to follow a task: free, already ours, or held by a process
|
|
112
|
+
* that stopped renewing it for `staleMs`.
|
|
113
|
+
* @param id - the task.
|
|
114
|
+
* @param holder - this process's claim id.
|
|
115
|
+
* @param staleMs - how old an unrenewed claim may be before it is taken over.
|
|
116
|
+
* @returns whether this process now holds the claim.
|
|
117
|
+
*/
|
|
118
|
+
claim(id: string, holder: string, staleMs: number): Promise<boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* Keep a claim alive.
|
|
121
|
+
* @param id - the task.
|
|
122
|
+
* @param holder - this process's claim id.
|
|
123
|
+
*/
|
|
124
|
+
renewClaim(id: string, holder: string): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Give up a claim this process holds.
|
|
127
|
+
* @param id - the task.
|
|
128
|
+
* @param holder - this process's claim id.
|
|
129
|
+
*/
|
|
130
|
+
release(id: string, holder: string): Promise<void>;
|
|
131
|
+
private prune;
|
|
132
|
+
}
|