@warlock.js/ai 4.5.0 → 4.6.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/CHANGELOG.md +14 -0
- package/cjs/index.cjs +20 -1
- package/cjs/{src-DFibP2FQ.cjs → src-Bmajk4Qg.cjs} +1 -1
- package/cjs/{src-C02yzsLs.cjs → src-OZyDYHxm.cjs} +2789 -691
- package/cjs/src-OZyDYHxm.cjs.map +1 -0
- package/esm/agent/agent-config.type.d.mts +29 -0
- package/esm/agent/agent-config.type.d.mts.map +1 -1
- package/esm/agent/agent.d.mts.map +1 -1
- package/esm/agent/agent.mjs +126 -7
- package/esm/agent/agent.mjs.map +1 -1
- package/esm/agent/signature.mjs +57 -0
- package/esm/agent/signature.mjs.map +1 -0
- package/esm/agent/snapshot.mjs +101 -0
- package/esm/agent/snapshot.mjs.map +1 -0
- package/esm/ai-openai/src/image.mjs +5 -0
- package/esm/ai-openai/src/index.mjs +3 -0
- package/esm/ai-openai/src/sdk.mjs +3 -0
- package/esm/ai-openai/src/speech.mjs +5 -0
- package/esm/ai-openai/src/transcription.mjs +6 -0
- package/esm/ai-openai/src/utils/index.mjs +1 -0
- package/esm/ai-openai/src/utils/to-openai-messages.mjs +3 -0
- package/esm/ai.d.mts +45 -0
- package/esm/ai.d.mts.map +1 -1
- package/esm/ai.mjs +37 -1
- package/esm/ai.mjs.map +1 -1
- package/esm/contracts/agent/agent-options.type.d.mts +22 -2
- package/esm/contracts/agent/agent-options.type.d.mts.map +1 -1
- package/esm/contracts/agent/agent-snapshot.type.d.mts +90 -0
- package/esm/contracts/agent/agent-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/agent/agent.contract.d.mts +29 -1
- package/esm/contracts/agent/agent.contract.d.mts.map +1 -1
- package/esm/contracts/agent/index.d.mts +2 -1
- package/esm/contracts/image-model.contract.d.mts +156 -0
- package/esm/contracts/image-model.contract.d.mts.map +1 -0
- package/esm/contracts/index.d.mts +8 -3
- package/esm/contracts/planner/index.d.mts +3 -2
- package/esm/contracts/planner/planner-config.type.d.mts +30 -0
- package/esm/contracts/planner/planner-config.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts +13 -1
- package/esm/contracts/planner/planner-execute-options.type.d.mts.map +1 -1
- package/esm/contracts/planner/planner-snapshot.type.d.mts +77 -0
- package/esm/contracts/planner/planner-snapshot.type.d.mts.map +1 -0
- package/esm/contracts/planner/planner.contract.d.mts +21 -1
- package/esm/contracts/planner/planner.contract.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.d.mts +1 -1
- package/esm/contracts/result/base-report.type.d.mts.map +1 -1
- package/esm/contracts/result/base-report.type.mjs.map +1 -1
- package/esm/contracts/sdk-adapter.contract.d.mts +37 -0
- package/esm/contracts/sdk-adapter.contract.d.mts.map +1 -1
- package/esm/contracts/speech-model.contract.d.mts +97 -0
- package/esm/contracts/speech-model.contract.d.mts.map +1 -0
- package/esm/contracts/transcription-model.contract.d.mts +101 -0
- package/esm/contracts/transcription-model.contract.d.mts.map +1 -0
- package/esm/errors/agent-drift-error.d.mts +32 -0
- package/esm/errors/agent-drift-error.d.mts.map +1 -0
- package/esm/errors/agent-drift-error.mjs +31 -0
- package/esm/errors/agent-drift-error.mjs.map +1 -0
- package/esm/errors/error-code.type.d.mts +1 -1
- package/esm/errors/index.d.mts +2 -0
- package/esm/errors/index.mjs +2 -0
- package/esm/errors/planner-drift-error.d.mts +34 -0
- package/esm/errors/planner-drift-error.d.mts.map +1 -0
- package/esm/errors/planner-drift-error.mjs +33 -0
- package/esm/errors/planner-drift-error.mjs.map +1 -0
- package/esm/image/image-cost.d.mts +32 -0
- package/esm/image/image-cost.d.mts.map +1 -0
- package/esm/image/image-cost.mjs +55 -0
- package/esm/image/image-cost.mjs.map +1 -0
- package/esm/image/image.d.mts +92 -0
- package/esm/image/image.d.mts.map +1 -0
- package/esm/image/image.mjs +113 -0
- package/esm/image/image.mjs.map +1 -0
- package/esm/image/index.mjs +4 -0
- package/esm/index.d.mts +26 -4
- package/esm/index.mjs +20 -1
- package/esm/mock/index.d.mts +3 -0
- package/esm/mock/index.mjs +3 -0
- package/esm/mock/mock-config.type.d.mts +22 -0
- package/esm/mock/mock-config.type.d.mts.map +1 -1
- package/esm/mock/mock-image-model.d.mts +41 -0
- package/esm/mock/mock-image-model.d.mts.map +1 -0
- package/esm/mock/mock-image-model.mjs +52 -0
- package/esm/mock/mock-image-model.mjs.map +1 -0
- package/esm/mock/mock-sdk.d.mts +7 -1
- package/esm/mock/mock-sdk.d.mts.map +1 -1
- package/esm/mock/mock-sdk.mjs +27 -0
- package/esm/mock/mock-sdk.mjs.map +1 -1
- package/esm/mock/mock-speech-model.d.mts +31 -0
- package/esm/mock/mock-speech-model.d.mts.map +1 -0
- package/esm/mock/mock-speech-model.mjs +39 -0
- package/esm/mock/mock-speech-model.mjs.map +1 -0
- package/esm/mock/mock-transcription-model.d.mts +32 -0
- package/esm/mock/mock-transcription-model.d.mts.map +1 -0
- package/esm/mock/mock-transcription-model.mjs +36 -0
- package/esm/mock/mock-transcription-model.mjs.map +1 -0
- package/esm/planner/planner-run.d.mts +8 -0
- package/esm/planner/planner-run.d.mts.map +1 -1
- package/esm/planner/planner-run.mjs +161 -6
- package/esm/planner/planner-run.mjs.map +1 -1
- package/esm/planner/planner.d.mts.map +1 -1
- package/esm/planner/planner.mjs +25 -1
- package/esm/planner/planner.mjs.map +1 -1
- package/esm/planner/snapshot.mjs +95 -0
- package/esm/planner/snapshot.mjs.map +1 -0
- package/esm/rag/index.d.mts +7 -0
- package/esm/rag/index.mjs +7 -0
- package/esm/rag/loaders/errors.d.mts +19 -0
- package/esm/rag/loaders/errors.d.mts.map +1 -0
- package/esm/rag/loaders/errors.mjs +25 -0
- package/esm/rag/loaders/errors.mjs.map +1 -0
- package/esm/rag/loaders/index.mjs +7 -0
- package/esm/rag/loaders/load-html.d.mts +26 -0
- package/esm/rag/loaders/load-html.d.mts.map +1 -0
- package/esm/rag/loaders/load-html.mjs +138 -0
- package/esm/rag/loaders/load-html.mjs.map +1 -0
- package/esm/rag/loaders/load-pdf.d.mts +38 -0
- package/esm/rag/loaders/load-pdf.d.mts.map +1 -0
- package/esm/rag/loaders/load-pdf.mjs +150 -0
- package/esm/rag/loaders/load-pdf.mjs.map +1 -0
- package/esm/rag/loaders/load-text.d.mts +47 -0
- package/esm/rag/loaders/load-text.d.mts.map +1 -0
- package/esm/rag/loaders/load-text.mjs +60 -0
- package/esm/rag/loaders/load-text.mjs.map +1 -0
- package/esm/rag/loaders/load-web.d.mts +42 -0
- package/esm/rag/loaders/load-web.d.mts.map +1 -0
- package/esm/rag/loaders/load-web.mjs +89 -0
- package/esm/rag/loaders/load-web.mjs.map +1 -0
- package/esm/rag/loaders/loader.type.d.mts +89 -0
- package/esm/rag/loaders/loader.type.d.mts.map +1 -0
- package/esm/rag/store/pg-vector-store.d.mts +139 -0
- package/esm/rag/store/pg-vector-store.d.mts.map +1 -0
- package/esm/rag/store/pg-vector-store.mjs +328 -0
- package/esm/rag/store/pg-vector-store.mjs.map +1 -0
- package/esm/speech/index.mjs +3 -0
- package/esm/speech/speech.d.mts +65 -0
- package/esm/speech/speech.d.mts.map +1 -0
- package/esm/speech/speech.mjs +123 -0
- package/esm/speech/speech.mjs.map +1 -0
- package/esm/supervisor/entries.mjs +2 -2
- package/esm/supervisor/entries.mjs.map +1 -1
- package/esm/transcribe/audio-input.d.mts +47 -0
- package/esm/transcribe/audio-input.d.mts.map +1 -0
- package/esm/transcribe/audio-input.mjs +84 -0
- package/esm/transcribe/audio-input.mjs.map +1 -0
- package/esm/transcribe/index.mjs +4 -0
- package/esm/transcribe/transcribe.d.mts +64 -0
- package/esm/transcribe/transcribe.d.mts.map +1 -0
- package/esm/transcribe/transcribe.mjs +128 -0
- package/esm/transcribe/transcribe.mjs.map +1 -0
- package/llms-full.txt +753 -0
- package/llms.txt +5 -0
- package/package.json +3 -3
- package/skills/README.md +4 -0
- package/skills/durable-agent-runs/SKILL.md +135 -0
- package/skills/generate-images/SKILL.md +138 -0
- package/skills/generate-speech/SKILL.md +139 -0
- package/skills/rag-loaders-and-stores/SKILL.md +164 -0
- package/skills/transcribe-audio/SKILL.md +157 -0
- package/cjs/src-C02yzsLs.cjs.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Usage } from "./result/usage.type.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/contracts/transcription-model.contract.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* USD pricing for a speech-to-text (transcription) model. STT providers
|
|
6
|
+
* meter one of two ways; this single shape covers both so the cost
|
|
7
|
+
* folds into the same `Usage.cost` rollup as text / image / speech:
|
|
8
|
+
*
|
|
9
|
+
* - **Per-minute** (OpenAI `whisper-1`): billed per minute of input
|
|
10
|
+
* audio. Set `perMinute` (USD per audio-minute).
|
|
11
|
+
* - **Token-metered** (OpenAI `gpt-4o-transcribe`): billed per
|
|
12
|
+
* input/output token. Set `input` / `output` (USD per 1M tokens).
|
|
13
|
+
*
|
|
14
|
+
* Per-minute wins when both are set. Nothing set → `Usage.cost` stays
|
|
15
|
+
* `undefined`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const pricing: TranscriptionModelPricing = { perMinute: 0.006 }; // whisper-1
|
|
19
|
+
*/
|
|
20
|
+
type TranscriptionModelPricing = {
|
|
21
|
+
/** USD per minute of input audio — per-minute-metered STT. */perMinute?: number; /** USD per 1M input (audio) tokens — token-metered STT. */
|
|
22
|
+
input?: number; /** USD per 1M output (text) tokens — token-metered STT. */
|
|
23
|
+
output?: number;
|
|
24
|
+
};
|
|
25
|
+
/** One timestamped segment of a transcription (when the provider returns segments). */
|
|
26
|
+
type TranscriptionSegment = {
|
|
27
|
+
text: string; /** Segment start time in seconds. */
|
|
28
|
+
start?: number; /** Segment end time in seconds. */
|
|
29
|
+
end?: number;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* The audio to transcribe — inlined base64 bytes with an explicit IANA
|
|
33
|
+
* media type, plus an optional filename (some providers infer the codec
|
|
34
|
+
* from the extension). Read a file to base64 before calling, or pass
|
|
35
|
+
* in-memory bytes; this keeps the verb provider-neutral and
|
|
36
|
+
* serializable (no `fs` coupling in core).
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* const audio: AudioInput = { base64: buf.toString("base64"), mediaType: "audio/mpeg", filename: "note.mp3" };
|
|
40
|
+
*/
|
|
41
|
+
type AudioInput = {
|
|
42
|
+
base64: string;
|
|
43
|
+
mediaType: string;
|
|
44
|
+
filename?: string;
|
|
45
|
+
};
|
|
46
|
+
/** Options for a single {@link TranscriptionModelContract.transcribe} request. */
|
|
47
|
+
type TranscribeOptions = {
|
|
48
|
+
/** BCP-47 language hint (e.g. `"en"`) — improves accuracy + latency. */language?: string; /** Optional priming prompt (spelling/style hints). */
|
|
49
|
+
prompt?: string; /** Provider response format override (e.g. `"verbose_json"` for segments + duration). */
|
|
50
|
+
format?: string; /** Cancellation handle wired into the provider request where supported. */
|
|
51
|
+
signal?: AbortSignal; /** Provider-specific escape hatch — forwarded verbatim. */
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Raw result of a {@link TranscriptionModelContract.transcribe} call —
|
|
56
|
+
* low-level (throws a typed `AIError` on failure). The never-throws
|
|
57
|
+
* envelope is added by the `ai.transcribe()` facade verb.
|
|
58
|
+
*/
|
|
59
|
+
type TranscriptionResponse = {
|
|
60
|
+
/** The full transcript text. */text: string; /** Timestamped segments when the provider returns them (verbose mode). */
|
|
61
|
+
segments?: TranscriptionSegment[]; /** Input audio duration in seconds — drives per-minute cost when present. */
|
|
62
|
+
durationSeconds?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Token usage when the provider meters per token (gpt-4o-transcribe);
|
|
65
|
+
* `{ input: 0, output: 0, total: 0 }` for per-minute-metered models,
|
|
66
|
+
* whose spend is priced from {@link durationSeconds}.
|
|
67
|
+
*/
|
|
68
|
+
usage: Usage;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Provider-neutral contract for a speech-to-text model — the inverse of
|
|
72
|
+
* {@link SpeechModelContract}. Produced by an adapter's optional
|
|
73
|
+
* `transcribe?(config)` factory and consumed by `ai.transcribe()`.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* const stt = openai.transcribe({ name: "whisper-1" });
|
|
77
|
+
* const { text } = await stt.transcribe({ base64, mediaType: "audio/mpeg" });
|
|
78
|
+
*/
|
|
79
|
+
interface TranscriptionModelContract {
|
|
80
|
+
/** Model identifier (e.g. `"whisper-1"`, `"gpt-4o-transcribe"`). */
|
|
81
|
+
readonly name: string;
|
|
82
|
+
/** Provider this model belongs to (e.g. `"openai"`). */
|
|
83
|
+
readonly provider: string;
|
|
84
|
+
/** Per-minute or per-token USD pricing; folded into `Usage.cost` by `ai.transcribe()`. */
|
|
85
|
+
readonly pricing?: TranscriptionModelPricing;
|
|
86
|
+
/** Transcribe audio to text. Throws a typed `AIError` on failure. */
|
|
87
|
+
transcribe(audio: AudioInput, options?: TranscribeOptions): Promise<TranscriptionResponse>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Configuration passed to an adapter's `transcribe()` factory. Mirrors
|
|
91
|
+
* {@link SpeechModelConfig}: `name` + an optional per-model `pricing`
|
|
92
|
+
* override, with provider-specific keys on the index signature.
|
|
93
|
+
*/
|
|
94
|
+
type TranscriptionModelConfig = {
|
|
95
|
+
name: string; /** Per-model USD pricing override; wins over the SDK-level registry. */
|
|
96
|
+
pricing?: TranscriptionModelPricing;
|
|
97
|
+
[key: string]: unknown;
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
export { AudioInput, TranscribeOptions, TranscriptionModelConfig, TranscriptionModelContract, TranscriptionModelPricing, TranscriptionResponse, TranscriptionSegment };
|
|
101
|
+
//# sourceMappingURL=transcription-model.contract.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcription-model.contract.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/contracts/transcription-model.contract.ts"],"mappings":";;;;;AAkBA;;;;;;;;AAMQ;AAIR;;;;;KAVY,yBAAA;EAeV,8DAbA,SAAA,WAaG;EAXH,KAAA,WAwBoB;EAtBpB,MAAA;AAAA;;KAIU,oBAAA;EACV,IAAA,UAoBQ;EAlBR,KAAA,WAsBU;EApBV,GAAA;AAAA;;;;;;;;;AA8BY;AAQd;KAzBY,UAAA;EACV,MAAA;EACA,SAAA;EACA,QAAA;AAAA;;KAIU,iBAAA;EA8BV,wEA5BA,QAAA,WA4BY;EA1BZ,MAAA,WAsCe;EApCf,MAAA;EAEA,MAAA,GAAS,WAAW,EA2CF;EAAA,CAzCjB,GAAA;AAAA;;;;;;KAQS,qBAAA;EA8BS,gCA5BnB,IAAA,UA+BkB;EA7BlB,QAAA,GAAW,oBAAA,IA6B6B;EA3BxC,eAAA;EA2B4D;;;AAA6B;AAQ3F;EA7BE,KAAA,EAAO,KAAK;AAAA;;;;;;;AAiCA;;;UArBG,0BAAA;;WAEN,IAAA;;WAEA,QAAA;;WAEA,OAAA,GAAU,yBAAA;;EAGnB,UAAA,CAAW,KAAA,EAAO,UAAA,EAAY,OAAA,GAAU,iBAAA,GAAoB,OAAA,CAAQ,qBAAA;AAAA;;;;;;KAQ1D,wBAAA;EACV,IAAA;EAEA,OAAA,GAAU,yBAAyB;EAAA,CAClC,GAAA;AAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ErrorCategory } from "./error-category.type.mjs";
|
|
2
|
+
import { AIErrorOptions } from "./ai-error.mjs";
|
|
3
|
+
import { AgentExecutionError } from "./agent-execution-error.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/errors/agent-drift-error.d.ts
|
|
6
|
+
type AgentDriftErrorOptions = AIErrorOptions & {
|
|
7
|
+
/** Signature recorded on the snapshot being resumed. */savedSignature: string; /** Signature computed from the current agent definition. */
|
|
8
|
+
currentSignature: string;
|
|
9
|
+
runId: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `agent.resume(runId)` loaded a durable snapshot whose structural
|
|
13
|
+
* fingerprint does not match the current agent definition (model +
|
|
14
|
+
* provider + sorted tool names + maxTrips + output presence + version).
|
|
15
|
+
* The resume is refused — no trip runs — and the user decides how to
|
|
16
|
+
* recover: discard the snapshot, migrate manually, or call
|
|
17
|
+
* `resume(runId, { force: true })` to bypass the check.
|
|
18
|
+
*
|
|
19
|
+
* Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,
|
|
20
|
+
* different primitive. Thrown (not returned on `result.error`) because a
|
|
21
|
+
* drifted resume never produces a valid run.
|
|
22
|
+
*/
|
|
23
|
+
declare class AgentDriftError extends AgentExecutionError {
|
|
24
|
+
static readonly defaultCategory: ErrorCategory;
|
|
25
|
+
readonly savedSignature: string;
|
|
26
|
+
readonly currentSignature: string;
|
|
27
|
+
readonly runId: string;
|
|
28
|
+
constructor(message: string, options: AgentDriftErrorOptions);
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { AgentDriftError, AgentDriftErrorOptions };
|
|
32
|
+
//# sourceMappingURL=agent-drift-error.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-drift-error.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/agent-drift-error.ts"],"mappings":";;;;;KAIY,sBAAA,GAAyB,cAAc;0DAEjD,cAAA,UAFgC;EAIhC,gBAAA;EACA,KAAA;AAAA;;;;;AAAK;AAeP;;;;;;;cAAa,eAAA,SAAwB,mBAAA;EAAA,gBACZ,eAAA,EAAiB,aAAA;EAAA,SAExB,cAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,sBAAA;AAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AgentExecutionError } from "./agent-execution-error.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/errors/agent-drift-error.ts
|
|
4
|
+
/**
|
|
5
|
+
* `agent.resume(runId)` loaded a durable snapshot whose structural
|
|
6
|
+
* fingerprint does not match the current agent definition (model +
|
|
7
|
+
* provider + sorted tool names + maxTrips + output presence + version).
|
|
8
|
+
* The resume is refused — no trip runs — and the user decides how to
|
|
9
|
+
* recover: discard the snapshot, migrate manually, or call
|
|
10
|
+
* `resume(runId, { force: true })` to bypass the check.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,
|
|
13
|
+
* different primitive. Thrown (not returned on `result.error`) because a
|
|
14
|
+
* drifted resume never produces a valid run.
|
|
15
|
+
*/
|
|
16
|
+
var AgentDriftError = class extends AgentExecutionError {
|
|
17
|
+
static {
|
|
18
|
+
this.defaultCategory = "drift";
|
|
19
|
+
}
|
|
20
|
+
constructor(message, options) {
|
|
21
|
+
super(message, options, "AGENT_DRIFT");
|
|
22
|
+
this.name = "AgentDriftError";
|
|
23
|
+
this.savedSignature = options.savedSignature;
|
|
24
|
+
this.currentSignature = options.currentSignature;
|
|
25
|
+
this.runId = options.runId;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { AgentDriftError };
|
|
31
|
+
//# sourceMappingURL=agent-drift-error.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-drift-error.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/agent-drift-error.ts"],"sourcesContent":["import type { AIErrorOptions } from \"./ai-error\";\nimport { AgentExecutionError } from \"./agent-execution-error\";\nimport type { ErrorCategory } from \"./error-category.type\";\n\nexport type AgentDriftErrorOptions = AIErrorOptions & {\n /** Signature recorded on the snapshot being resumed. */\n savedSignature: string;\n /** Signature computed from the current agent definition. */\n currentSignature: string;\n runId: string;\n};\n\n/**\n * `agent.resume(runId)` loaded a durable snapshot whose structural\n * fingerprint does not match the current agent definition (model +\n * provider + sorted tool names + maxTrips + output presence + version).\n * The resume is refused — no trip runs — and the user decides how to\n * recover: discard the snapshot, migrate manually, or call\n * `resume(runId, { force: true })` to bypass the check.\n *\n * Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,\n * different primitive. Thrown (not returned on `result.error`) because a\n * drifted resume never produces a valid run.\n */\nexport class AgentDriftError extends AgentExecutionError {\n public static readonly defaultCategory: ErrorCategory = \"drift\";\n\n public readonly savedSignature: string;\n public readonly currentSignature: string;\n public readonly runId: string;\n\n public constructor(message: string, options: AgentDriftErrorOptions) {\n super(message, options, \"AGENT_DRIFT\");\n this.name = \"AgentDriftError\";\n this.savedSignature = options.savedSignature;\n this.currentSignature = options.currentSignature;\n this.runId = options.runId;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,IAAa,kBAAb,cAAqC,oBAAoB;;yBACC;;CAMxD,AAAO,YAAY,SAAiB,SAAiC;EACnE,MAAM,SAAS,SAAS,aAAa;EACrC,KAAK,OAAO;EACZ,KAAK,iBAAiB,QAAQ;EAC9B,KAAK,mBAAmB,QAAQ;EAChC,KAAK,QAAQ,QAAQ;CACvB;AACF"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* return agent.execute(input);
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
|
-
type AIErrorCode = "AGENT_EXEC_FAILED" | "AGENT_CANCELLED" | "AGENT_MAX_TRIPS" | "SCHEMA_VALIDATION_FAILED" | "TOOL_EXEC_FAILED" | "PROVIDER_ERROR" | "PROVIDER_RATE_LIMIT" | "PROVIDER_QUOTA_EXCEEDED" | "PROVIDER_TIMEOUT" | "CONTEXT_LENGTH_EXCEEDED" | "CONTENT_FILTER" | "PROVIDER_INVALID_REQUEST" | "PROVIDER_AUTH" | "BUDGET_EXCEEDED" | "GUARDRAIL_VIOLATION" | "WORKFLOW_ERROR" | "STEP_FAILED" | "WORKFLOW_DRIFT" | "WORKFLOW_CANCELLED" | "WORKFLOW_MAX_STEPS" | "WORKFLOW_INVALID_GOTO" | "SUPERVISOR_FAILED" | "SUPERVISOR_MAX_ITERATIONS" | "SUPERVISOR_INVALID_ROUTE" | "SUPERVISOR_CANCELLED" | "SUPERVISOR_DRIFT" | "SUPERVISOR_INTENT_DESCRIPTION_REQUIRED" | "SUPERVISOR_INTENT_MIXED_DISPATCH" | "SUPERVISOR_INTENT_STREAM_AND_OUTPUT" | "SUPERVISOR_INTENT_STREAM_TO_REQUIRED" | "SUPERVISOR_INTENT_STREAM_ON_WORKFLOW" | "SUPERVISOR_DISPATCH_CYCLE" | "ORCHESTRATOR_FAILED" | "ORCHESTRATOR_DRIFT" | "ORCHESTRATOR_CONFIG" | "ORCHESTRATOR_CANCELLED" | "PLANNER_FAILED" | "PLANNER_PLAN_INVALID" | "PLANNER_CANCELLED" | "VCR_CASSETTE_MISS" | "OUTBOUND_POLICY_BLOCKED";
|
|
16
|
+
type AIErrorCode = "AGENT_EXEC_FAILED" | "AGENT_CANCELLED" | "AGENT_MAX_TRIPS" | "AGENT_DRIFT" | "SCHEMA_VALIDATION_FAILED" | "TOOL_EXEC_FAILED" | "PROVIDER_ERROR" | "PROVIDER_RATE_LIMIT" | "PROVIDER_QUOTA_EXCEEDED" | "PROVIDER_TIMEOUT" | "CONTEXT_LENGTH_EXCEEDED" | "CONTENT_FILTER" | "PROVIDER_INVALID_REQUEST" | "PROVIDER_AUTH" | "BUDGET_EXCEEDED" | "GUARDRAIL_VIOLATION" | "WORKFLOW_ERROR" | "STEP_FAILED" | "WORKFLOW_DRIFT" | "WORKFLOW_CANCELLED" | "WORKFLOW_MAX_STEPS" | "WORKFLOW_INVALID_GOTO" | "SUPERVISOR_FAILED" | "SUPERVISOR_MAX_ITERATIONS" | "SUPERVISOR_INVALID_ROUTE" | "SUPERVISOR_CANCELLED" | "SUPERVISOR_DRIFT" | "SUPERVISOR_INTENT_DESCRIPTION_REQUIRED" | "SUPERVISOR_INTENT_MIXED_DISPATCH" | "SUPERVISOR_INTENT_STREAM_AND_OUTPUT" | "SUPERVISOR_INTENT_STREAM_TO_REQUIRED" | "SUPERVISOR_INTENT_STREAM_ON_WORKFLOW" | "SUPERVISOR_DISPATCH_CYCLE" | "ORCHESTRATOR_FAILED" | "ORCHESTRATOR_DRIFT" | "ORCHESTRATOR_CONFIG" | "ORCHESTRATOR_CANCELLED" | "PLANNER_FAILED" | "PLANNER_PLAN_INVALID" | "PLANNER_CANCELLED" | "PLANNER_DRIFT" | "VCR_CASSETTE_MISS" | "OUTBOUND_POLICY_BLOCKED";
|
|
17
17
|
//#endregion
|
|
18
18
|
export { AIErrorCode };
|
|
19
19
|
//# sourceMappingURL=error-code.type.d.mts.map
|
package/esm/errors/index.d.mts
CHANGED
|
@@ -3,6 +3,7 @@ import { AIErrorCode } from "./error-code.type.mjs";
|
|
|
3
3
|
import { AIError, AIErrorOptions } from "./ai-error.mjs";
|
|
4
4
|
import { AgentExecutionError } from "./agent-execution-error.mjs";
|
|
5
5
|
import { AgentCancelledError, AgentCancelledErrorOptions } from "./agent-cancelled-error.mjs";
|
|
6
|
+
import { AgentDriftError, AgentDriftErrorOptions } from "./agent-drift-error.mjs";
|
|
6
7
|
import { AgentMaxTripsError, AgentMaxTripsErrorOptions } from "./agent-max-trips-error.mjs";
|
|
7
8
|
import { BudgetExceededError, BudgetExceededErrorOptions, BudgetUnit } from "./budget-exceeded-error.mjs";
|
|
8
9
|
import { ProviderError } from "./provider-error.mjs";
|
|
@@ -21,6 +22,7 @@ import { OrchestratorDriftError, OrchestratorDriftErrorOptions } from "./orchest
|
|
|
21
22
|
import { OutboundPolicyError } from "./outbound-policy-error.mjs";
|
|
22
23
|
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
23
24
|
import { PlannerCancelledError, PlannerCancelledErrorOptions } from "./planner-cancelled-error.mjs";
|
|
25
|
+
import { PlannerDriftError, PlannerDriftErrorOptions } from "./planner-drift-error.mjs";
|
|
24
26
|
import { PlannerPlanInvalidError } from "./planner-plan-invalid-error.mjs";
|
|
25
27
|
import { ProviderAuthError } from "./provider-auth-error.mjs";
|
|
26
28
|
import { ProviderRateLimitError, ProviderRateLimitErrorOptions } from "./provider-rate-limit-error.mjs";
|
package/esm/errors/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AIError } from "./ai-error.mjs";
|
|
2
2
|
import { AgentExecutionError } from "./agent-execution-error.mjs";
|
|
3
3
|
import { AgentCancelledError } from "./agent-cancelled-error.mjs";
|
|
4
|
+
import { AgentDriftError } from "./agent-drift-error.mjs";
|
|
4
5
|
import { AgentMaxTripsError } from "./agent-max-trips-error.mjs";
|
|
5
6
|
import { BudgetExceededError } from "./budget-exceeded-error.mjs";
|
|
6
7
|
import { ProviderError } from "./provider-error.mjs";
|
|
@@ -19,6 +20,7 @@ import { OrchestratorDriftError } from "./orchestrator-drift-error.mjs";
|
|
|
19
20
|
import { OutboundPolicyError } from "./outbound-policy-error.mjs";
|
|
20
21
|
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
21
22
|
import { PlannerCancelledError } from "./planner-cancelled-error.mjs";
|
|
23
|
+
import { PlannerDriftError } from "./planner-drift-error.mjs";
|
|
22
24
|
import { PlannerPlanInvalidError } from "./planner-plan-invalid-error.mjs";
|
|
23
25
|
import { ProviderAuthError } from "./provider-auth-error.mjs";
|
|
24
26
|
import { ProviderRateLimitError } from "./provider-rate-limit-error.mjs";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ErrorCategory } from "./error-category.type.mjs";
|
|
2
|
+
import { AIErrorOptions } from "./ai-error.mjs";
|
|
3
|
+
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/errors/planner-drift-error.d.ts
|
|
6
|
+
type PlannerDriftErrorOptions = AIErrorOptions & {
|
|
7
|
+
/** Signature recorded on the snapshot being resumed. */savedSignature: string; /** Signature computed from the current planner definition. */
|
|
8
|
+
currentSignature: string;
|
|
9
|
+
runId: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* `planner.resume(runId)` loaded a durable snapshot whose structural
|
|
13
|
+
* fingerprint does not match the current planner definition (name +
|
|
14
|
+
* ordered capability names). The resume is refused — no node runs — and
|
|
15
|
+
* the user decides how to recover: discard the snapshot, migrate
|
|
16
|
+
* manually, or call `resume(runId, { force: true })` to bypass the check.
|
|
17
|
+
*
|
|
18
|
+
* A mid-run re-plan is NOT drift — the plan changed, not the definition;
|
|
19
|
+
* the persisted `replanCount` honors the replan budget across a resume.
|
|
20
|
+
*
|
|
21
|
+
* Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,
|
|
22
|
+
* different primitive. Thrown (not returned on `result.error`) because a
|
|
23
|
+
* drifted resume never produces a valid run.
|
|
24
|
+
*/
|
|
25
|
+
declare class PlannerDriftError extends PlannerFailedError {
|
|
26
|
+
static readonly defaultCategory: ErrorCategory;
|
|
27
|
+
readonly savedSignature: string;
|
|
28
|
+
readonly currentSignature: string;
|
|
29
|
+
readonly runId: string;
|
|
30
|
+
constructor(message: string, options: PlannerDriftErrorOptions);
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { PlannerDriftError, PlannerDriftErrorOptions };
|
|
34
|
+
//# sourceMappingURL=planner-drift-error.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-drift-error.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/planner-drift-error.ts"],"mappings":";;;;;KAIY,wBAAA,GAA2B,cAAc;0DAEnD,cAAA,UAFkC;EAIlC,gBAAA;EACA,KAAA;AAAA;;;;;AAAK;AAiBP;;;;;;;;;cAAa,iBAAA,SAA0B,kBAAA;EAAA,gBACd,eAAA,EAAiB,aAAA;EAAA,SAExB,cAAA;EAAA,SACA,gBAAA;EAAA,SACA,KAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,wBAAA;AAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PlannerFailedError } from "./planner-failed-error.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/errors/planner-drift-error.ts
|
|
4
|
+
/**
|
|
5
|
+
* `planner.resume(runId)` loaded a durable snapshot whose structural
|
|
6
|
+
* fingerprint does not match the current planner definition (name +
|
|
7
|
+
* ordered capability names). The resume is refused — no node runs — and
|
|
8
|
+
* the user decides how to recover: discard the snapshot, migrate
|
|
9
|
+
* manually, or call `resume(runId, { force: true })` to bypass the check.
|
|
10
|
+
*
|
|
11
|
+
* A mid-run re-plan is NOT drift — the plan changed, not the definition;
|
|
12
|
+
* the persisted `replanCount` honors the replan budget across a resume.
|
|
13
|
+
*
|
|
14
|
+
* Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,
|
|
15
|
+
* different primitive. Thrown (not returned on `result.error`) because a
|
|
16
|
+
* drifted resume never produces a valid run.
|
|
17
|
+
*/
|
|
18
|
+
var PlannerDriftError = class extends PlannerFailedError {
|
|
19
|
+
static {
|
|
20
|
+
this.defaultCategory = "drift";
|
|
21
|
+
}
|
|
22
|
+
constructor(message, options) {
|
|
23
|
+
super(message, options, "PLANNER_DRIFT");
|
|
24
|
+
this.name = "PlannerDriftError";
|
|
25
|
+
this.savedSignature = options.savedSignature;
|
|
26
|
+
this.currentSignature = options.currentSignature;
|
|
27
|
+
this.runId = options.runId;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { PlannerDriftError };
|
|
33
|
+
//# sourceMappingURL=planner-drift-error.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-drift-error.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/errors/planner-drift-error.ts"],"sourcesContent":["import type { AIErrorOptions } from \"./ai-error\";\nimport type { ErrorCategory } from \"./error-category.type\";\nimport { PlannerFailedError } from \"./planner-failed-error\";\n\nexport type PlannerDriftErrorOptions = AIErrorOptions & {\n /** Signature recorded on the snapshot being resumed. */\n savedSignature: string;\n /** Signature computed from the current planner definition. */\n currentSignature: string;\n runId: string;\n};\n\n/**\n * `planner.resume(runId)` loaded a durable snapshot whose structural\n * fingerprint does not match the current planner definition (name +\n * ordered capability names). The resume is refused — no node runs — and\n * the user decides how to recover: discard the snapshot, migrate\n * manually, or call `resume(runId, { force: true })` to bypass the check.\n *\n * A mid-run re-plan is NOT drift — the plan changed, not the definition;\n * the persisted `replanCount` honors the replan budget across a resume.\n *\n * Mirrors `SupervisorDriftError` / `WorkflowDriftError` — same rationale,\n * different primitive. Thrown (not returned on `result.error`) because a\n * drifted resume never produces a valid run.\n */\nexport class PlannerDriftError extends PlannerFailedError {\n public static readonly defaultCategory: ErrorCategory = \"drift\";\n\n public readonly savedSignature: string;\n public readonly currentSignature: string;\n public readonly runId: string;\n\n public constructor(message: string, options: PlannerDriftErrorOptions) {\n super(message, options, \"PLANNER_DRIFT\");\n this.name = \"PlannerDriftError\";\n this.savedSignature = options.savedSignature;\n this.currentSignature = options.currentSignature;\n this.runId = options.runId;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAa,oBAAb,cAAuC,mBAAmB;;yBACA;;CAMxD,AAAO,YAAY,SAAiB,SAAmC;EACrE,MAAM,SAAS,SAAS,eAAe;EACvC,KAAK,OAAO;EACZ,KAAK,iBAAiB,QAAQ;EAC9B,KAAK,mBAAmB,QAAQ;EAChC,KAAK,QAAQ,QAAQ;CACvB;AACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ModelPricing } from "../contracts/result/model-pricing.type.mjs";
|
|
2
|
+
import { Usage } from "../contracts/result/usage.type.mjs";
|
|
3
|
+
import { ImageModelPricing } from "../contracts/image-model.contract.mjs";
|
|
4
|
+
|
|
5
|
+
//#region ../@warlock.js/ai/src/image/image-cost.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Price one image-generation `Usage` against an
|
|
8
|
+
* {@link ImageModelPricing}, returning a `ModelPricing`-shaped USD
|
|
9
|
+
* breakdown so image spend folds into the exact same `Usage.cost`
|
|
10
|
+
* rollup the text path uses (`accumulateCost` / `mergeUsage`). There is
|
|
11
|
+
* no separate image-cost field anywhere downstream — only this one
|
|
12
|
+
* function, which knows the two metering models:
|
|
13
|
+
*
|
|
14
|
+
* - **Per-image** (DALL·E, Imagen): `perImageBySize[size]` (when the
|
|
15
|
+
* request `size` matches a tier) else flat `perImage`, times the
|
|
16
|
+
* number of images returned, attributed to `cost.output` (the image
|
|
17
|
+
* IS the output). Token channels stay 0.
|
|
18
|
+
* - **Token** (gpt-image-1): delegates to the standard
|
|
19
|
+
* {@link computeCost} against the prompt/image token `Usage`.
|
|
20
|
+
*
|
|
21
|
+
* Per-image wins when both shapes are configured (a provider is one or
|
|
22
|
+
* the other). Returns `undefined` when no usable pricing is present —
|
|
23
|
+
* the framework treats that as "cost unknown", never a false zero.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* computeImageCost({ input: 0, output: 0, total: 0 }, 2, "1024x1024", { perImage: 0.04 });
|
|
27
|
+
* // → { input: 0, output: 0.08 }
|
|
28
|
+
*/
|
|
29
|
+
declare function computeImageCost(usage: Usage, imageCount: number, size: string | undefined, pricing: ImageModelPricing | undefined): ModelPricing | undefined;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { computeImageCost };
|
|
32
|
+
//# sourceMappingURL=image-cost.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-cost.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/image/image-cost.ts"],"mappings":";;;;;;;AA4BA;;;;;;;;;;;;;;;;AAKe;;;;;iBALC,gBAAA,CACd,KAAA,EAAO,KAAA,EACP,UAAA,UACA,IAAA,sBACA,OAAA,EAAS,iBAAA,eACR,YAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { computeCost } from "../utils/compute-cost.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../@warlock.js/ai/src/image/image-cost.ts
|
|
4
|
+
/**
|
|
5
|
+
* Price one image-generation `Usage` against an
|
|
6
|
+
* {@link ImageModelPricing}, returning a `ModelPricing`-shaped USD
|
|
7
|
+
* breakdown so image spend folds into the exact same `Usage.cost`
|
|
8
|
+
* rollup the text path uses (`accumulateCost` / `mergeUsage`). There is
|
|
9
|
+
* no separate image-cost field anywhere downstream — only this one
|
|
10
|
+
* function, which knows the two metering models:
|
|
11
|
+
*
|
|
12
|
+
* - **Per-image** (DALL·E, Imagen): `perImageBySize[size]` (when the
|
|
13
|
+
* request `size` matches a tier) else flat `perImage`, times the
|
|
14
|
+
* number of images returned, attributed to `cost.output` (the image
|
|
15
|
+
* IS the output). Token channels stay 0.
|
|
16
|
+
* - **Token** (gpt-image-1): delegates to the standard
|
|
17
|
+
* {@link computeCost} against the prompt/image token `Usage`.
|
|
18
|
+
*
|
|
19
|
+
* Per-image wins when both shapes are configured (a provider is one or
|
|
20
|
+
* the other). Returns `undefined` when no usable pricing is present —
|
|
21
|
+
* the framework treats that as "cost unknown", never a false zero.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* computeImageCost({ input: 0, output: 0, total: 0 }, 2, "1024x1024", { perImage: 0.04 });
|
|
25
|
+
* // → { input: 0, output: 0.08 }
|
|
26
|
+
*/
|
|
27
|
+
function computeImageCost(usage, imageCount, size, pricing) {
|
|
28
|
+
if (!pricing) return;
|
|
29
|
+
if (pricing.perImage !== void 0 || pricing.perImageBySize !== void 0) {
|
|
30
|
+
const perImage = resolvePerImageRate(size, pricing);
|
|
31
|
+
if (perImage === void 0) return;
|
|
32
|
+
return {
|
|
33
|
+
input: 0,
|
|
34
|
+
output: perImage * imageCount
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (pricing.input !== void 0 && pricing.output !== void 0) return computeCost(usage, {
|
|
38
|
+
input: pricing.input,
|
|
39
|
+
output: pricing.output
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Resolve the USD-per-image rate: a `perImageBySize` tier matching the
|
|
44
|
+
* requested `size` wins, otherwise the flat `perImage`. Returns
|
|
45
|
+
* `undefined` only when neither is set (the caller already gated on
|
|
46
|
+
* per-image metering being configured at all).
|
|
47
|
+
*/
|
|
48
|
+
function resolvePerImageRate(size, pricing) {
|
|
49
|
+
if (size !== void 0 && pricing.perImageBySize?.[size] !== void 0) return pricing.perImageBySize[size];
|
|
50
|
+
return pricing.perImage;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { computeImageCost };
|
|
55
|
+
//# sourceMappingURL=image-cost.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-cost.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/image/image-cost.ts"],"sourcesContent":["import type { ImageModelPricing } from \"../contracts/image-model.contract\";\nimport type { ModelPricing } from \"../contracts/result/model-pricing.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { computeCost } from \"../utils/compute-cost\";\n\n/**\n * Price one image-generation `Usage` against an\n * {@link ImageModelPricing}, returning a `ModelPricing`-shaped USD\n * breakdown so image spend folds into the exact same `Usage.cost`\n * rollup the text path uses (`accumulateCost` / `mergeUsage`). There is\n * no separate image-cost field anywhere downstream — only this one\n * function, which knows the two metering models:\n *\n * - **Per-image** (DALL·E, Imagen): `perImageBySize[size]` (when the\n * request `size` matches a tier) else flat `perImage`, times the\n * number of images returned, attributed to `cost.output` (the image\n * IS the output). Token channels stay 0.\n * - **Token** (gpt-image-1): delegates to the standard\n * {@link computeCost} against the prompt/image token `Usage`.\n *\n * Per-image wins when both shapes are configured (a provider is one or\n * the other). Returns `undefined` when no usable pricing is present —\n * the framework treats that as \"cost unknown\", never a false zero.\n *\n * @example\n * computeImageCost({ input: 0, output: 0, total: 0 }, 2, \"1024x1024\", { perImage: 0.04 });\n * // → { input: 0, output: 0.08 }\n */\nexport function computeImageCost(\n usage: Usage,\n imageCount: number,\n size: string | undefined,\n pricing: ImageModelPricing | undefined,\n): ModelPricing | undefined {\n if (!pricing) {\n return undefined;\n }\n\n const perImageMetered = pricing.perImage !== undefined || pricing.perImageBySize !== undefined;\n\n if (perImageMetered) {\n const perImage = resolvePerImageRate(size, pricing);\n\n if (perImage === undefined) {\n return undefined;\n }\n\n return { input: 0, output: perImage * imageCount };\n }\n\n if (pricing.input !== undefined && pricing.output !== undefined) {\n return computeCost(usage, { input: pricing.input, output: pricing.output });\n }\n\n return undefined;\n}\n\n/**\n * Resolve the USD-per-image rate: a `perImageBySize` tier matching the\n * requested `size` wins, otherwise the flat `perImage`. Returns\n * `undefined` only when neither is set (the caller already gated on\n * per-image metering being configured at all).\n */\nfunction resolvePerImageRate(\n size: string | undefined,\n pricing: ImageModelPricing,\n): number | undefined {\n if (size !== undefined && pricing.perImageBySize?.[size] !== undefined) {\n return pricing.perImageBySize[size];\n }\n\n return pricing.perImage;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,iBACd,OACA,YACA,MACA,SAC0B;CAC1B,IAAI,CAAC,SACH;CAKF,IAFwB,QAAQ,aAAa,UAAa,QAAQ,mBAAmB,QAEhE;EACnB,MAAM,WAAW,oBAAoB,MAAM,OAAO;EAElD,IAAI,aAAa,QACf;EAGF,OAAO;GAAE,OAAO;GAAG,QAAQ,WAAW;EAAW;CACnD;CAEA,IAAI,QAAQ,UAAU,UAAa,QAAQ,WAAW,QACpD,OAAO,YAAY,OAAO;EAAE,OAAO,QAAQ;EAAO,QAAQ,QAAQ;CAAO,CAAC;AAI9E;;;;;;;AAQA,SAAS,oBACP,MACA,SACoB;CACpB,IAAI,SAAS,UAAa,QAAQ,iBAAiB,UAAU,QAC3D,OAAO,QAAQ,eAAe;CAGhC,OAAO,QAAQ;AACjB"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { BaseReport } from "../contracts/result/base-report.type.mjs";
|
|
2
|
+
import { ExecuteResult } from "../contracts/result/execute-result.type.mjs";
|
|
3
|
+
import { FlowObserveOption } from "../observe/resolve-observers.mjs";
|
|
4
|
+
import { GeneratedImage, ImageModelContract } from "../contracts/image-model.contract.mjs";
|
|
5
|
+
|
|
6
|
+
//#region ../@warlock.js/ai/src/image/image.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Parameters for {@link image}. `model` comes from an adapter's
|
|
9
|
+
* `image()` factory (`openai.image({ name })` / `google.image({ name })`);
|
|
10
|
+
* the rest are provider-neutral generation knobs plus the standard
|
|
11
|
+
* observability seam every verb shares.
|
|
12
|
+
*/
|
|
13
|
+
type ImageParams = {
|
|
14
|
+
/** The image model to generate from (`sdk.image({ name })`). */model: ImageModelContract; /** Text description of the image(s) to generate. */
|
|
15
|
+
prompt: string; /** How many images to generate. Adapters clamp to the provider max. */
|
|
16
|
+
count?: number; /** Requested pixel size as `"WxH"` (e.g. `"1024x1024"`). */
|
|
17
|
+
size?: string; /** Quality tier (e.g. `"standard"` / `"hd"`). */
|
|
18
|
+
quality?: string; /** Aspect ratio (e.g. `"1:1"`, `"16:9"`) — ratio-based providers (Imagen). */
|
|
19
|
+
aspectRatio?: string; /** Concepts to steer away from (Imagen `negativePrompt`). */
|
|
20
|
+
negativePrompt?: string; /** Output container hint (`"png"` / `"jpeg"` / `"webp"`). */
|
|
21
|
+
format?: string; /** Cancellation handle, wired into the provider request where supported. */
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
/**
|
|
24
|
+
* Observability routing for this call — same `observe` seam as
|
|
25
|
+
* agents / workflows. `true` routes to the globally registered
|
|
26
|
+
* observers; an `Observer` object routes flow-locally; `false` opts
|
|
27
|
+
* out; omitted follows the global observe-all flag.
|
|
28
|
+
*/
|
|
29
|
+
observe?: FlowObserveOption; /** Groups this call into a session for flat cost/trace queries. */
|
|
30
|
+
sessionId?: string; /** Report node name (defaults to `"image"`). */
|
|
31
|
+
name?: string; /** Provider-specific options forwarded verbatim to the adapter. */
|
|
32
|
+
options?: Record<string, unknown>;
|
|
33
|
+
};
|
|
34
|
+
/** Success payload of an {@link image} run. */
|
|
35
|
+
type ImageData = {
|
|
36
|
+
/** The generated images, normalized to the discriminated shape. */images: GeneratedImage[];
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The report node an {@link image} run produces — a {@link BaseReport}
|
|
40
|
+
* (`type: "image"`) plus which model ran and how many images came back,
|
|
41
|
+
* so panoptic and any flat-row consumer attribute the cost/latency
|
|
42
|
+
* without special-casing.
|
|
43
|
+
*/
|
|
44
|
+
type ImageReport = BaseReport & {
|
|
45
|
+
type: "image"; /** Identity of the image model this run used. */
|
|
46
|
+
model: {
|
|
47
|
+
name: string;
|
|
48
|
+
provider: string;
|
|
49
|
+
}; /** Number of images returned (0 on failure). */
|
|
50
|
+
imageCount: number;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Result envelope of {@link image} — the same uniform
|
|
54
|
+
* `{ data, error, usage, report }` every executable returns, narrowed
|
|
55
|
+
* with the `"image"` discriminant.
|
|
56
|
+
*/
|
|
57
|
+
type ImageResult = ExecuteResult<ImageData> & {
|
|
58
|
+
type: "image";
|
|
59
|
+
report: ImageReport;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Generate one or more images from a text prompt — the image-output
|
|
63
|
+
* counterpart to `ai.agent`, and the first verb of the output-modality
|
|
64
|
+
* track (Theme I). Wraps an {@link ImageModelContract} (from
|
|
65
|
+
* `openai.image(...)` / `google.image(...)`) in the framework's uniform
|
|
66
|
+
* result contract:
|
|
67
|
+
*
|
|
68
|
+
* - **Never throws.** Provider failures (auth, rate-limit,
|
|
69
|
+
* content-filter, invalid request) surface as a typed `AIError` on
|
|
70
|
+
* `result.error`; `result.data` is then `undefined`.
|
|
71
|
+
* - **Cost-truth.** When the model carries pricing, `result.usage.cost`
|
|
72
|
+
* is filled in — per-token for gpt-image-1, per-image for
|
|
73
|
+
* DALL·E / Imagen — folding into the same `Usage.cost` rollup as text.
|
|
74
|
+
* - **Observable.** The completed {@link ImageReport} routes to any
|
|
75
|
+
* registered `Observer` (panoptic, OTel, …) via the shared `observe`
|
|
76
|
+
* seam, exactly like an agent run.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const openai = new OpenAISDK({ apiKey });
|
|
80
|
+
* const { data, error, usage } = await ai.image({
|
|
81
|
+
* model: openai.image({ name: "gpt-image-1" }),
|
|
82
|
+
* prompt: "an isometric office desk, soft studio lighting",
|
|
83
|
+
* size: "1024x1024",
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* if (error) console.warn(error.code);
|
|
87
|
+
* else for (const img of data.images) save(img); // { type: "base64" | "url", ... }
|
|
88
|
+
*/
|
|
89
|
+
declare function image(params: ImageParams): Promise<ImageResult>;
|
|
90
|
+
//#endregion
|
|
91
|
+
export { ImageData, ImageParams, ImageReport, ImageResult, image };
|
|
92
|
+
//# sourceMappingURL=image.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.d.mts","names":[],"sources":["../../../../../../../@warlock.js/ai/src/image/image.ts"],"mappings":";;;;;;;;AAsBA;;;;KAAY,WAAA;EAyBA,gEAvBV,KAAA,EAAO,kBAAA,EA6BS;EA3BhB,MAAA,UAFA;EAIA,KAAA,WAFA;EAIA,IAAA;EAEA,OAAA,WAEA;EAAA,WAAA,WAIA;EAFA,cAAA,WAIS;EAFT,MAAA,WASU;EAPV,MAAA,GAAS,WAAA;EAWT;;;;AAEgB;AAIlB;EAVE,OAAA,GAAU,iBAAA;EAEV,SAAA,WAUsB;EARtB,IAAA,WAiBqB;EAfrB,OAAA,GAAU,MAAA;AAAA;;KAIA,SAAA;EAcV,mEAZA,MAAA,EAAQ,cAAc;AAAA;;;AAcZ;AAQZ;;;KAbY,WAAA,GAAc,UAAU;EAClC,IAAA,WAcQ;EAZR,KAAA;IAAS,IAAA;IAAc,QAAA;EAAA,GAWvB;EATA,UAAA;AAAA;;AAUmB;AA+BrB;;;KAjCY,WAAA,GAAc,aAAA,CAAc,SAAA;EACtC,IAAA;EACA,MAAA,EAAQ,WAAA;AAAA;;;;;;;AA+B2D;;;;;;;;;;;;;;;;;;;;;;iBAA/C,KAAA,CAAM,MAAA,EAAQ,WAAA,GAAc,OAAA,CAAQ,WAAA"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { AIError } from "../errors/ai-error.mjs";
|
|
2
|
+
import { ProviderError } from "../errors/provider-error.mjs";
|
|
3
|
+
import { generateRunId } from "../utils/generate-run-id.mjs";
|
|
4
|
+
import { REPORT_SCHEMA_VERSION } from "../contracts/result/base-report.type.mjs";
|
|
5
|
+
import { stampReportLineage } from "../utils/stamp-report-lineage.mjs";
|
|
6
|
+
import { notifyObservers } from "../observe/resolve-observers.mjs";
|
|
7
|
+
import { computeImageCost } from "./image-cost.mjs";
|
|
8
|
+
|
|
9
|
+
//#region ../@warlock.js/ai/src/image/image.ts
|
|
10
|
+
/**
|
|
11
|
+
* Generate one or more images from a text prompt — the image-output
|
|
12
|
+
* counterpart to `ai.agent`, and the first verb of the output-modality
|
|
13
|
+
* track (Theme I). Wraps an {@link ImageModelContract} (from
|
|
14
|
+
* `openai.image(...)` / `google.image(...)`) in the framework's uniform
|
|
15
|
+
* result contract:
|
|
16
|
+
*
|
|
17
|
+
* - **Never throws.** Provider failures (auth, rate-limit,
|
|
18
|
+
* content-filter, invalid request) surface as a typed `AIError` on
|
|
19
|
+
* `result.error`; `result.data` is then `undefined`.
|
|
20
|
+
* - **Cost-truth.** When the model carries pricing, `result.usage.cost`
|
|
21
|
+
* is filled in — per-token for gpt-image-1, per-image for
|
|
22
|
+
* DALL·E / Imagen — folding into the same `Usage.cost` rollup as text.
|
|
23
|
+
* - **Observable.** The completed {@link ImageReport} routes to any
|
|
24
|
+
* registered `Observer` (panoptic, OTel, …) via the shared `observe`
|
|
25
|
+
* seam, exactly like an agent run.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const openai = new OpenAISDK({ apiKey });
|
|
29
|
+
* const { data, error, usage } = await ai.image({
|
|
30
|
+
* model: openai.image({ name: "gpt-image-1" }),
|
|
31
|
+
* prompt: "an isometric office desk, soft studio lighting",
|
|
32
|
+
* size: "1024x1024",
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* if (error) console.warn(error.code);
|
|
36
|
+
* else for (const img of data.images) save(img); // { type: "base64" | "url", ... }
|
|
37
|
+
*/
|
|
38
|
+
async function image(params) {
|
|
39
|
+
const { model, prompt } = params;
|
|
40
|
+
const runId = generateRunId("image");
|
|
41
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
42
|
+
const startPerf = performance.now();
|
|
43
|
+
const usage = {
|
|
44
|
+
input: 0,
|
|
45
|
+
output: 0,
|
|
46
|
+
total: 0
|
|
47
|
+
};
|
|
48
|
+
let data;
|
|
49
|
+
let error;
|
|
50
|
+
let status = "completed";
|
|
51
|
+
let imageCount = 0;
|
|
52
|
+
try {
|
|
53
|
+
const response = await model.generate(prompt, {
|
|
54
|
+
count: params.count,
|
|
55
|
+
size: params.size,
|
|
56
|
+
quality: params.quality,
|
|
57
|
+
aspectRatio: params.aspectRatio,
|
|
58
|
+
negativePrompt: params.negativePrompt,
|
|
59
|
+
format: params.format,
|
|
60
|
+
signal: params.signal,
|
|
61
|
+
...params.options
|
|
62
|
+
});
|
|
63
|
+
Object.assign(usage, response.usage);
|
|
64
|
+
if (usage.cost === void 0) {
|
|
65
|
+
const cost = computeImageCost(usage, response.images.length, params.size, model.pricing);
|
|
66
|
+
if (cost !== void 0) usage.cost = cost;
|
|
67
|
+
}
|
|
68
|
+
data = { images: response.images };
|
|
69
|
+
imageCount = response.images.length;
|
|
70
|
+
} catch (thrown) {
|
|
71
|
+
error = thrown instanceof AIError ? thrown : new ProviderError(toMessage(thrown), { cause: thrown });
|
|
72
|
+
status = params.signal?.aborted ? "cancelled" : "failed";
|
|
73
|
+
}
|
|
74
|
+
const report = {
|
|
75
|
+
runId,
|
|
76
|
+
rootRunId: runId,
|
|
77
|
+
name: params.name ?? "image",
|
|
78
|
+
type: "image",
|
|
79
|
+
status,
|
|
80
|
+
error,
|
|
81
|
+
startedAt,
|
|
82
|
+
endedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
83
|
+
duration: performance.now() - startPerf,
|
|
84
|
+
usage,
|
|
85
|
+
children: [],
|
|
86
|
+
model: {
|
|
87
|
+
name: model.name,
|
|
88
|
+
provider: model.provider
|
|
89
|
+
},
|
|
90
|
+
imageCount,
|
|
91
|
+
reportSchemaVersion: 1
|
|
92
|
+
};
|
|
93
|
+
stampReportLineage(report, {
|
|
94
|
+
rootRunId: runId,
|
|
95
|
+
sessionId: params.sessionId
|
|
96
|
+
});
|
|
97
|
+
await notifyObservers(params.observe, report);
|
|
98
|
+
return {
|
|
99
|
+
type: "image",
|
|
100
|
+
data,
|
|
101
|
+
error,
|
|
102
|
+
usage,
|
|
103
|
+
report
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** Best-effort message for a non-`AIError` thrown value. */
|
|
107
|
+
function toMessage(thrown) {
|
|
108
|
+
return thrown instanceof Error ? thrown.message : String(thrown);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//#endregion
|
|
112
|
+
export { image };
|
|
113
|
+
//# sourceMappingURL=image.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image.mjs","names":[],"sources":["../../../../../../../@warlock.js/ai/src/image/image.ts"],"sourcesContent":["import type {\n GeneratedImage,\n ImageModelContract,\n} from \"../contracts/image-model.contract\";\nimport type { BaseReport } from \"../contracts/result/base-report.type\";\nimport { REPORT_SCHEMA_VERSION } from \"../contracts/result/base-report.type\";\nimport type { ExecuteResult } from \"../contracts/result/execute-result.type\";\nimport type { Usage } from \"../contracts/result/usage.type\";\nimport { AIError } from \"../errors/ai-error\";\nimport { ProviderError } from \"../errors/provider-error\";\nimport type { FlowObserveOption } from \"../observe/resolve-observers\";\nimport { notifyObservers } from \"../observe/resolve-observers\";\nimport { generateRunId } from \"../utils/generate-run-id\";\nimport { stampReportLineage } from \"../utils/stamp-report-lineage\";\nimport { computeImageCost } from \"./image-cost\";\n\n/**\n * Parameters for {@link image}. `model` comes from an adapter's\n * `image()` factory (`openai.image({ name })` / `google.image({ name })`);\n * the rest are provider-neutral generation knobs plus the standard\n * observability seam every verb shares.\n */\nexport type ImageParams = {\n /** The image model to generate from (`sdk.image({ name })`). */\n model: ImageModelContract;\n /** Text description of the image(s) to generate. */\n prompt: string;\n /** How many images to generate. Adapters clamp to the provider max. */\n count?: number;\n /** Requested pixel size as `\"WxH\"` (e.g. `\"1024x1024\"`). */\n size?: string;\n /** Quality tier (e.g. `\"standard\"` / `\"hd\"`). */\n quality?: string;\n /** Aspect ratio (e.g. `\"1:1\"`, `\"16:9\"`) — ratio-based providers (Imagen). */\n aspectRatio?: string;\n /** Concepts to steer away from (Imagen `negativePrompt`). */\n negativePrompt?: string;\n /** Output container hint (`\"png\"` / `\"jpeg\"` / `\"webp\"`). */\n format?: string;\n /** Cancellation handle, wired into the provider request where supported. */\n signal?: AbortSignal;\n /**\n * Observability routing for this call — same `observe` seam as\n * agents / workflows. `true` routes to the globally registered\n * observers; an `Observer` object routes flow-locally; `false` opts\n * out; omitted follows the global observe-all flag.\n */\n observe?: FlowObserveOption;\n /** Groups this call into a session for flat cost/trace queries. */\n sessionId?: string;\n /** Report node name (defaults to `\"image\"`). */\n name?: string;\n /** Provider-specific options forwarded verbatim to the adapter. */\n options?: Record<string, unknown>;\n};\n\n/** Success payload of an {@link image} run. */\nexport type ImageData = {\n /** The generated images, normalized to the discriminated shape. */\n images: GeneratedImage[];\n};\n\n/**\n * The report node an {@link image} run produces — a {@link BaseReport}\n * (`type: \"image\"`) plus which model ran and how many images came back,\n * so panoptic and any flat-row consumer attribute the cost/latency\n * without special-casing.\n */\nexport type ImageReport = BaseReport & {\n type: \"image\";\n /** Identity of the image model this run used. */\n model: { name: string; provider: string };\n /** Number of images returned (0 on failure). */\n imageCount: number;\n};\n\n/**\n * Result envelope of {@link image} — the same uniform\n * `{ data, error, usage, report }` every executable returns, narrowed\n * with the `\"image\"` discriminant.\n */\nexport type ImageResult = ExecuteResult<ImageData> & {\n type: \"image\";\n report: ImageReport;\n};\n\n/**\n * Generate one or more images from a text prompt — the image-output\n * counterpart to `ai.agent`, and the first verb of the output-modality\n * track (Theme I). Wraps an {@link ImageModelContract} (from\n * `openai.image(...)` / `google.image(...)`) in the framework's uniform\n * result contract:\n *\n * - **Never throws.** Provider failures (auth, rate-limit,\n * content-filter, invalid request) surface as a typed `AIError` on\n * `result.error`; `result.data` is then `undefined`.\n * - **Cost-truth.** When the model carries pricing, `result.usage.cost`\n * is filled in — per-token for gpt-image-1, per-image for\n * DALL·E / Imagen — folding into the same `Usage.cost` rollup as text.\n * - **Observable.** The completed {@link ImageReport} routes to any\n * registered `Observer` (panoptic, OTel, …) via the shared `observe`\n * seam, exactly like an agent run.\n *\n * @example\n * const openai = new OpenAISDK({ apiKey });\n * const { data, error, usage } = await ai.image({\n * model: openai.image({ name: \"gpt-image-1\" }),\n * prompt: \"an isometric office desk, soft studio lighting\",\n * size: \"1024x1024\",\n * });\n *\n * if (error) console.warn(error.code);\n * else for (const img of data.images) save(img); // { type: \"base64\" | \"url\", ... }\n */\nexport async function image(params: ImageParams): Promise<ImageResult> {\n const { model, prompt } = params;\n\n const runId = generateRunId(\"image\");\n const startedAt = new Date().toISOString();\n const startPerf = performance.now();\n\n const usage: Usage = { input: 0, output: 0, total: 0 };\n let data: ImageData | undefined;\n let error: AIError | undefined;\n let status: ImageReport[\"status\"] = \"completed\";\n let imageCount = 0;\n\n try {\n const response = await model.generate(prompt, {\n count: params.count,\n size: params.size,\n quality: params.quality,\n aspectRatio: params.aspectRatio,\n negativePrompt: params.negativePrompt,\n format: params.format,\n signal: params.signal,\n ...params.options,\n });\n\n // Preserve every usage channel the adapter reported (cached /\n // reasoning / cache-write, and any adapter-supplied `cost`), mirroring\n // how the agent path routes provider usage. Then honor a pre-priced\n // response or compute image cost — `usage.cost ??= …` precedence, same\n // as the agent path.\n Object.assign(usage, response.usage);\n\n if (usage.cost === undefined) {\n const cost = computeImageCost(usage, response.images.length, params.size, model.pricing);\n if (cost !== undefined) {\n usage.cost = cost;\n }\n }\n\n data = { images: response.images };\n imageCount = response.images.length;\n } catch (thrown) {\n error = thrown instanceof AIError ? thrown : new ProviderError(toMessage(thrown), { cause: thrown });\n // A caller-aborted run is \"cancelled\", not \"failed\" — keep the typed\n // cause but distinguish the terminal status for dashboards/retry policy.\n status = params.signal?.aborted ? \"cancelled\" : \"failed\";\n }\n\n const report: ImageReport = {\n runId,\n rootRunId: runId,\n name: params.name ?? \"image\",\n type: \"image\",\n status,\n error,\n startedAt,\n endedAt: new Date().toISOString(),\n duration: performance.now() - startPerf,\n usage,\n children: [],\n model: { name: model.name, provider: model.provider },\n imageCount,\n reportSchemaVersion: REPORT_SCHEMA_VERSION,\n };\n\n stampReportLineage(report, { rootRunId: runId, sessionId: params.sessionId });\n\n await notifyObservers(params.observe, report);\n\n return { type: \"image\", data, error, usage, report };\n}\n\n/** Best-effort message for a non-`AIError` thrown value. */\nfunction toMessage(thrown: unknown): string {\n return thrown instanceof Error ? thrown.message : String(thrown);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkHA,eAAsB,MAAM,QAA2C;CACrE,MAAM,EAAE,OAAO,WAAW;CAE1B,MAAM,QAAQ,cAAc,OAAO;CACnC,MAAM,6BAAY,IAAI,KAAK,EAAC,CAAC,YAAY;CACzC,MAAM,YAAY,YAAY,IAAI;CAElC,MAAM,QAAe;EAAE,OAAO;EAAG,QAAQ;EAAG,OAAO;CAAE;CACrD,IAAI;CACJ,IAAI;CACJ,IAAI,SAAgC;CACpC,IAAI,aAAa;CAEjB,IAAI;EACF,MAAM,WAAW,MAAM,MAAM,SAAS,QAAQ;GAC5C,OAAO,OAAO;GACd,MAAM,OAAO;GACb,SAAS,OAAO;GAChB,aAAa,OAAO;GACpB,gBAAgB,OAAO;GACvB,QAAQ,OAAO;GACf,QAAQ,OAAO;GACf,GAAG,OAAO;EACZ,CAAC;EAOD,OAAO,OAAO,OAAO,SAAS,KAAK;EAEnC,IAAI,MAAM,SAAS,QAAW;GAC5B,MAAM,OAAO,iBAAiB,OAAO,SAAS,OAAO,QAAQ,OAAO,MAAM,MAAM,OAAO;GACvF,IAAI,SAAS,QACX,MAAM,OAAO;EAEjB;EAEA,OAAO,EAAE,QAAQ,SAAS,OAAO;EACjC,aAAa,SAAS,OAAO;CAC/B,SAAS,QAAQ;EACf,QAAQ,kBAAkB,UAAU,SAAS,IAAI,cAAc,UAAU,MAAM,GAAG,EAAE,OAAO,OAAO,CAAC;EAGnG,SAAS,OAAO,QAAQ,UAAU,cAAc;CAClD;CAEA,MAAM,SAAsB;EAC1B;EACA,WAAW;EACX,MAAM,OAAO,QAAQ;EACrB,MAAM;EACN;EACA;EACA;EACA,0BAAS,IAAI,KAAK,EAAC,CAAC,YAAY;EAChC,UAAU,YAAY,IAAI,IAAI;EAC9B;EACA,UAAU,CAAC;EACX,OAAO;GAAE,MAAM,MAAM;GAAM,UAAU,MAAM;EAAS;EACpD;EACA;CACF;CAEA,mBAAmB,QAAQ;EAAE,WAAW;EAAO,WAAW,OAAO;CAAU,CAAC;CAE5E,MAAM,gBAAgB,OAAO,SAAS,MAAM;CAE5C,OAAO;EAAE,MAAM;EAAS;EAAM;EAAO;EAAO;CAAO;AACrD;;AAGA,SAAS,UAAU,QAAyB;CAC1C,OAAO,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACjE"}
|