@stackfactor/agent-utils 1.4.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ When `expectsJsonResponse` is `true` (the default), JSON escape instructions are
49
49
  | `schema` | `ZodSchema \| null` | `null` | Zod schema for response validation |
50
50
  | `agentName` | `string` | `"StackFactor"` | Display name for the agent (agentic mode) |
51
51
  | `tools` | `any[]` | `[]` | LangChain tools available to the agent (agentic mode) |
52
- | `usageTracker` | `UsageTracker \| null` | `null` | Optional accumulator updated on every successful LLM call with `cost` (USD) and per-model token counts. |
52
+ | `usageTracker` | `UsageTracker \| null` | `null` | Optional counter, for the agent's own use, of what each model used. The platform does not read it (see [Usage](#usage)). |
53
53
 
54
54
  **Returns:** JSON string (when `expectsJsonResponse` is `true`) or raw content string.
55
55
 
@@ -70,7 +70,7 @@ const result = await langChain.runPromptWithModel(
70
70
  );
71
71
  // usageTracker is now:
72
72
  // {
73
- // cost: 0.00123,
73
+ // cost: 0, // always: the platform prices what was used
74
74
  // tokens: {
75
75
  // "gpt-4o_inputTokens": 412,
76
76
  // "gpt-4o_outputTokens": 87,
@@ -255,6 +255,83 @@ Shared constants used across the package.
255
255
 
256
256
  ---
257
257
 
258
+ ## `platform`
259
+
260
+ Calls an integration makes back to StackFactor on its own behalf.
261
+
262
+ ### `platform.getTenantSettings(token)`
263
+
264
+ For **scheduled runs** (`event === 510`). A scheduled run starts once for the whole platform and
265
+ carries **no identity**: `request.authToken` is absent and `session` is `null`. The integration
266
+ brings its own: create a service account and an API token in the admin tenant, store the token as
267
+ a secret constant of the integration, and pass it here. The answer is this integration's settings
268
+ in every organization that has it enabled — an organization that switched it off is not listed.
269
+
270
+ ```js
271
+ const { platform } = require("@stackfactor/agent-utils");
272
+
273
+ // params.data.schedule → { name, cron, timezone, scheduledTime }
274
+ const tenants = await platform.getTenantSettings(config.STACKFACTOR_API_TOKEN);
275
+ for (const { tenant, settings } of tenants) {
276
+ // settings: the tenant-level fields this integration declares, secrets included.
277
+ // To act INSIDE the tenant, declare a secret field for the tenant's own API key
278
+ // and use settings.<thatField> for those calls.
279
+ }
280
+ ```
281
+
282
+ Which integration is asking is never yours to say: the platform puts a signed run ticket in the
283
+ run's envelope (`request.runTicket`) and the helper sends it back with your token. You never touch
284
+ it, and it cannot be used to read another integration's settings.
285
+
286
+ ## The run lifecycle (job executions)
287
+
288
+ An agent subscribed to a platform event with `runAs: job` is started as one Cloud Run job
289
+ execution per event. The runtime reports that run to the platform on the handler's behalf, and
290
+ the handler neither does nor knows any of it:
291
+
292
+ | When | What happens | Why it matters to you |
293
+ |---|---|---|
294
+ | Before the handler | **Claim.** Of however many executions the platform may start for one run — a retried task, a redelivered message — exactly one wins. | An execution that **loses** the claim exits **0** without running the handler: the work is somebody else's, and exiting 1 would have Cloud Run retry it forever. Write handlers as if they run once; they do. |
295
+ | While it runs | **Heartbeat**, every 30s. | A run that stops beating is treated as abandoned and swept. A handler that blocks the event loop for minutes will look dead — do long work in awaited chunks. |
296
+ | After the handler | **Settle**, `COMPLETED` with whatever the handler returned, or `FAILED` with the error. | The run's record carries your return value as its outcome, so return something small and descriptive. Settling also **revokes the execution's token**, so do not hold it past your handler. |
297
+
298
+ Which run is being reported is never the execution's to assert: the platform signs a run ticket
299
+ into the envelope (`request.runTicket`) and the runtime presents it. A run whose envelope carries
300
+ no ticket is not claimed or settled — nothing names it.
301
+
302
+ A settle the platform refuses (`settled: false` — the run was already swept) or that fails
303
+ outright does **not** change the execution's outcome: the work either happened or it did not.
304
+
305
+ ## Usage
306
+
307
+ What an agent used reaches the platform one way: the usage report. What a handler returns is its content and nothing else. A handler that returns `[data, usage]` sends that pair to the caller as the content.
308
+
309
+ Every model call made through `langChain` and every Tavily call is counted for the request it ran in. `serve` and `runOnce` report what was counted once a minute while the handler runs, once more when it ends, and also when it throws. The agent prices nothing: it reports a model, a unit and an amount, and the platform applies its own rates and charges the tenant's AI credits.
310
+
311
+ An agent that calls a provider without `langChain` counts the call itself:
312
+
313
+ ```typescript
314
+ import { recordUsage } from "@stackfactor/agent-utils";
315
+
316
+ const response = await anthropic.messages.create({ model, messages });
317
+ recordUsage(model, "inputTokens", response.usage.input_tokens);
318
+ recordUsage(model, "outputTokens", response.usage.output_tokens);
319
+ ```
320
+
321
+ | Unit | Counts |
322
+ | ------------------- | ------------------------------- |
323
+ | `inputTokens` | Text tokens sent to a model |
324
+ | `outputTokens` | Text tokens a model answered |
325
+ | `imageInputTokens` | Image tokens sent to a model |
326
+ | `imageOutputTokens` | Image tokens a model generated |
327
+ | `characters` | Characters turned into speech |
328
+ | `seconds` | Seconds of generated video |
329
+ | `credits` | Credits of a metered service |
330
+
331
+ `recordUsage` counts nothing outside a request, and nothing for an amount that is not a positive number. A report that fails is sent again twice under the same id, so it is charged once; one that still fails is logged and the run goes on.
332
+
333
+ ---
334
+
258
335
  ## Web Search (Tavily)
259
336
 
260
337
  Set `config.tavily` to give an agent the Tavily web tools. These run **client-side**: the model emits a tool call, this library performs the HTTP request, and the result is appended to the conversation. Only an agent loop can execute them, so **`config.agentic` must be `true`** — enabling `tavily` without it throws `BAD_REQUEST` rather than handing the model tools whose calls nothing answers.
@@ -285,7 +362,6 @@ const result = await langChain.runPromptWithModel(
285
362
  anthropicAPIKey: "sk-ant-...",
286
363
  tavilyAPIKey: "tvly-...",
287
364
  agentic: true, // required
288
- "tavily-credit-costs": 0.008, // USD per credit
289
365
  tavily: {
290
366
  tools: ["search", "extract", "map"],
291
367
  includeDomains: ["sc.gov", "sc.edu"],
@@ -296,7 +372,6 @@ const result = await langChain.runPromptWithModel(
296
372
  null, 0, 100, false, null, "StackFactor", [], usageTracker,
297
373
  );
298
374
  // usageTracker.tokens.tavilyCredits === 4
299
- // usageTracker.cost includes 4 * 0.008
300
375
  // usageTracker.webSearchSources === [{ url: "https://...", title: "..." }, ...]
301
376
  ```
302
377
 
@@ -339,7 +414,7 @@ A model that cannot tell it received half a regulation will reason over the half
339
414
  **Notes**
340
415
 
341
416
  - Works with every supported provider.
342
- - Credits come from each response's own `usage` block rather than an estimate, and are accumulated on `usageTracker.tokens.tavilyCredits`, costed from the `tavily-credit-costs` constant (USD per credit; falls back to Tavily's list price of `0.008`).
417
+ - Credits come from each response's own `usage` block rather than an estimate. They are reported to the platform as `credits` of the model `tavily` (see [Usage](#usage)) and counted on `usageTracker.tokens.tavilyCredits`.
343
418
  - URLs are collected on `usageTracker.webSearchSources`, deduplicated across the whole run — Tavily's terms require citing the original sources when its content is shown to end users.
344
419
  - Per-URL failures are surfaced in the tool result instead of being dropped, so a fetch failure is not mistaken for an absence of content.
345
420
  - Tool calls honour the caller's abort signal, so a cancelled run stops paying for in-flight crawls.
@@ -384,7 +459,7 @@ The `config` object accepted by LangChain methods supports the following keys:
384
459
  | `tavilyAPIKey` | `string` | Tavily API key; required when `tavily` is set |
385
460
  | `tavily` | `boolean \| TavilyConfig` | Enable the Tavily web tools; requires `agentic: true` (see [Web Search (Tavily)](#web-search-tavily)) |
386
461
 
387
- Per-model cost constants are read from the same object using flat keys: `<model>-input-token-costs`, `<model>-output-token-costs`, `<model>-image-input-token-costs`, `<model>-image-output-token-costs`, and `<model>-character-costs` (all USD per million). Tavily is billed separately via `tavily-credit-costs` (USD per credit).
462
+ The object carries no prices. The `<model>-…-costs` and `tavily-credit-costs` constants are no longer read: the platform prices what an agent used (see [Usage](#usage)).
388
463
 
389
464
  ---
390
465
 
@@ -2,9 +2,10 @@ import constants from "./const.js";
2
2
  import errorHandling, { AppError } from "./errorHandling.js";
3
3
  import langChain from "./langChain.js";
4
4
  import logger from "./logger.js";
5
- import { serve } from "./serve.js";
5
+ import { serve, runOnce, isRunOnceExecution, EXECUTION_ENV } from "./serve.js";
6
6
  import { callAgent, checkAgent } from "./client.js";
7
7
  import * as runtimeContext from "./runtimeContext.js";
8
+ import { recordUsage, USAGE_UNITS } from "./usage.js";
8
9
  export { constants };
9
10
  export { errorHandling, AppError };
10
11
  export type { ParsedError } from "./errorHandling.js";
@@ -12,9 +13,11 @@ export { langChain };
12
13
  export type { UsageTracker } from "./langChain.js";
13
14
  export type { TavilyConfig, TavilyToolName } from "./tavily.js";
14
15
  export { logger };
15
- export { serve };
16
+ export { serve, runOnce, isRunOnceExecution, EXECUTION_ENV };
16
17
  export { callAgent };
17
18
  export { checkAgent };
18
19
  export type { AgentExecuteRequest, CallAgentOptions, CheckAgentOptions, AgentHealth, } from "./client.js";
19
20
  export { runtimeContext };
21
+ export { recordUsage, USAGE_UNITS };
22
+ export type { UsageEntry, UsageUnit } from "./usage.js";
20
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AAEnC,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EAAE,KAAK,EAAE,CAAC;AAEjB,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,aAAa,EAAE,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;AAEnC,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,GACZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAEpC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.runtimeContext = exports.checkAgent = exports.callAgent = exports.serve = exports.logger = exports.langChain = exports.AppError = exports.errorHandling = exports.constants = void 0;
39
+ exports.USAGE_UNITS = exports.recordUsage = exports.runtimeContext = exports.checkAgent = exports.callAgent = exports.EXECUTION_ENV = exports.isRunOnceExecution = exports.runOnce = exports.serve = exports.logger = exports.langChain = exports.AppError = exports.errorHandling = exports.constants = void 0;
40
40
  const const_js_1 = __importDefault(require("./const.js"));
41
41
  exports.constants = const_js_1.default;
42
42
  const errorHandling_js_1 = __importStar(require("./errorHandling.js"));
@@ -48,8 +48,14 @@ const logger_js_1 = __importDefault(require("./logger.js"));
48
48
  exports.logger = logger_js_1.default;
49
49
  const serve_js_1 = require("./serve.js");
50
50
  Object.defineProperty(exports, "serve", { enumerable: true, get: function () { return serve_js_1.serve; } });
51
+ Object.defineProperty(exports, "runOnce", { enumerable: true, get: function () { return serve_js_1.runOnce; } });
52
+ Object.defineProperty(exports, "isRunOnceExecution", { enumerable: true, get: function () { return serve_js_1.isRunOnceExecution; } });
53
+ Object.defineProperty(exports, "EXECUTION_ENV", { enumerable: true, get: function () { return serve_js_1.EXECUTION_ENV; } });
51
54
  const client_js_1 = require("./client.js");
52
55
  Object.defineProperty(exports, "callAgent", { enumerable: true, get: function () { return client_js_1.callAgent; } });
53
56
  Object.defineProperty(exports, "checkAgent", { enumerable: true, get: function () { return client_js_1.checkAgent; } });
54
57
  const runtimeContext = __importStar(require("./runtimeContext.js"));
55
58
  exports.runtimeContext = runtimeContext;
59
+ const usage_js_1 = require("./usage.js");
60
+ Object.defineProperty(exports, "recordUsage", { enumerable: true, get: function () { return usage_js_1.recordUsage; } });
61
+ Object.defineProperty(exports, "USAGE_UNITS", { enumerable: true, get: function () { return usage_js_1.USAGE_UNITS; } });
@@ -1,8 +1,20 @@
1
+ type TokenUsage = {
2
+ input_tokens: number;
3
+ output_tokens: number;
4
+ total_tokens: number;
5
+ };
1
6
  /**
2
- * Accumulated usage and cost for a single agent run. Callers initialize an
7
+ * What a run used, by model, for the agent's own use: callers initialize an
3
8
  * empty object (`{}`) and pass it through `runPromptWithModel`; helpers
4
- * populate `cost` (USD total across all models) and per-model
5
- * `<model>_inputTokens` / `<model>_outputTokens` counters under `tokens`.
9
+ * populate per-model counters under `tokens` (`<model>_inputTokens`,
10
+ * `<model>_outputTokens`, ...).
11
+ *
12
+ * It is not how the platform learns what was used, and not what that costs:
13
+ * every call made through this module is counted into the request's usage
14
+ * ledger, with or without a tracker, and reported to the platform, which
15
+ * prices it (see `usage.ts`). `cost` stays 0 for that reason. A handler
16
+ * answers its data alone: a tracker it returned would reach the caller as
17
+ * part of the content.
6
18
  */
7
19
  export type UsageTracker = {
8
20
  cost: number;
@@ -43,6 +55,11 @@ export type UsageTracker = {
43
55
  */
44
56
  export declare const getLLMModel: (modelName: string, config: any, schema?: any) => any;
45
57
  declare const _default: {
58
+ canRetryValidation: (expectsJsonResponse: boolean, schema: any) => boolean;
59
+ isRetryableJsonFailure: (error: any) => boolean;
60
+ buildAgenticRetryPrompt: (userPrompt: string, rawContent: any, error: any) => string;
61
+ parseAgenticJsonResponse: (rawContent: any, schema: any) => string;
62
+ supportsNativeSchema: (modelName: string) => boolean;
46
63
  checkIfAIProviderConfigured: (config: any) => void;
47
64
  createAgent: (name: string, modelName: string, systemPrompt: string, tools: any[], responseFormat: any, config: any, usageTracker?: UsageTracker | null) => any;
48
65
  runAgent: (agent: any, prompt: string, config: any, onProgress?: Function | null, usageTracker?: UsageTracker | null) => Promise<any>;
@@ -50,7 +67,10 @@ declare const _default: {
50
67
  runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
51
68
  runPromptWithModelForVideoGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
52
69
  throwErrorIfNotSuccessful: (response: any) => string;
53
- updateUsageTrackerForCharacters: (tracker: UsageTracker | null | undefined, modelName: string, characterCount: number, config: any) => void;
70
+ updateImageUsageTracker: (tracker: UsageTracker | null | undefined, modelName: string, response: any, _config: any, provider: "openai" | "google") => void;
71
+ updateUsageTracker: (tracker: UsageTracker | null | undefined, modelName: string, usage: TokenUsage | null, _config?: any) => void;
72
+ updateUsageTrackerForCharacters: (tracker: UsageTracker | null | undefined, modelName: string, characterCount: number, _config?: any) => void;
73
+ updateVideoUsageTracker: (tracker: UsageTracker | null | undefined, modelName: string, seconds: number, _config?: any) => void;
54
74
  validateModel: (selectedModel: string, supportedModels: string[]) => string;
55
75
  };
56
76
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA6GA;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD,CAAC;AA0lBF;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,eAAO,MAAM,WAAW,GACtB,WAAW,MAAM,EACjB,QAAQ,GAAG,EACX,SAAQ,GAAU,KACjB,GAwHF,CAAC;;0CA3uB2C,GAAG,KAAG,IAAI;wBA8vB/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,iBACG,YAAY,GAAG,IAAI,KAChC,GAAG;sBAoCG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCAkYF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDA2tBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAmTF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CA7zC8B,GAAG,KAAG,MAAM;+CA1uB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCA0vBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AAg2CT,wBAUE"}
1
+ {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AAoGA,KAAK,UAAU,GAAG;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IAKtB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACvC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD,CAAC;AAmiBF;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,eAAO,MAAM,WAAW,GACtB,WAAW,MAAM,EACjB,QAAQ,GAAG,EACX,SAAQ,GAAU,KACjB,GAwHF,CAAC;;8CA4Z+C,OAAO,UAAU,GAAG,KAAG,OAAO;oCAWxC,GAAG,KAAG,OAAO;0CAgBtC,MAAM,cACN,GAAG,SACR,GAAG,KACT,MAAM;2CA0CqC,GAAG,UAAU,GAAG,KAAG,MAAM;sCAvvC9B,MAAM,KAAG,OAAO;0CA+FZ,GAAG,KAAG,IAAI;wBAusB/C,MAAM,aACD,MAAM,gBACH,MAAM,SACb,GAAG,EAAE,kBACI,GAAG,UACX,GAAG,iBACG,YAAY,GAAG,IAAI,KAChC,GAAG;sBAoCG,GAAG,UACF,MAAM,UACN,GAAG,eACC,QAAQ,GAAG,IAAI,iBACb,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;oCA6fF,MAAM,UACT,GAAG,UACH,GAAG,oBACO,GAAG,eACT,MAAM,eACN,MAAM,wBACG,OAAO,WACpB,GAAG,cACA,MAAM,UACV,GAAG,EAAE,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDA0sBF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;sDAmTF,MAAM,UACT,GAAG,UACH,MAAM,YACL,GAAG,iBACE,YAAY,GAAG,IAAI,KAChC,OAAO,CAAC,GAAG,CAAC;0CAv6C8B,GAAG,KAAG,MAAM;uCA3wB9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,YACP,GAAG,WACJ,GAAG,YACF,QAAQ,GAAG,QAAQ,KAC5B,IAAI;kCA5CI,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,SACV,UAAU,GAAG,IAAI,YACd,GAAG,KACZ,IAAI;+CA0FI,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,YACZ,GAAG,KACZ,IAAI;uCAoBI,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,WACR,MAAM,YACL,GAAG,KACZ,IAAI;mCA4sBU,MAAM,mBACJ,MAAM,EAAE,KACxB,MAAM;;AA08CT,wBAkBE"}