@stackfactor/agent-utils 1.4.1 → 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.
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.reportUsageWhileRunning = exports.reportUsage = exports.recordUsage = exports.UsageLedger = exports.USAGE_REPORT_INTERVAL_MS = exports.USAGE_UNITS = void 0;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const client_api_1 = require("@stackfactor/client-api");
9
+ const logger_js_1 = __importDefault(require("./logger.js"));
10
+ const runtimeContext_js_1 = require("./runtimeContext.js");
11
+ /**
12
+ * What an agent used, and how the platform gets to know.
13
+ *
14
+ * An agent says WHAT it used — a model, a unit, an amount — and the platform
15
+ * says what that costs, who is charged and what it was for. Everything that
16
+ * calls a model through this package counts what the call used into the
17
+ * request's {@link UsageLedger}; {@link serve} and {@link runOnce} report the
18
+ * ledger to the platform while the work runs and when it ends, whether it
19
+ * ended well or not. An agent does nothing for this to happen.
20
+ *
21
+ * An agent that calls a provider itself — its own SDK, an HTTP request —
22
+ * counts what that used with {@link recordUsage}.
23
+ */
24
+ /** What usage is counted in; the units the platform has rates for. */
25
+ exports.USAGE_UNITS = [
26
+ "inputTokens",
27
+ "outputTokens",
28
+ "imageInputTokens",
29
+ "imageOutputTokens",
30
+ "characters",
31
+ "seconds",
32
+ "credits",
33
+ ];
34
+ /** Entries one report may carry (the platform's limit). */
35
+ const REPORT_ENTRIES_MAX = 100;
36
+ /** How often a report is tried before it is given up on, and the first wait between tries. */
37
+ const REPORT_ATTEMPTS = 3;
38
+ const REPORT_RETRY_BASE_MS = 500;
39
+ /** How often work that is still running reports what it used so far. */
40
+ exports.USAGE_REPORT_INTERVAL_MS = 60_000;
41
+ const keyOf = (model, unit) => `${model}\n${unit}`;
42
+ /**
43
+ * What one request used and has not reported yet, summed by model and unit.
44
+ */
45
+ class UsageLedger {
46
+ pending = new Map();
47
+ /** Adds to what is pending. Anything that is not a positive amount of a known unit is ignored. */
48
+ add(model, unit, amount) {
49
+ if (typeof model !== "string" ||
50
+ model.trim().length === 0 ||
51
+ !exports.USAGE_UNITS.includes(unit) ||
52
+ typeof amount !== "number" ||
53
+ !Number.isFinite(amount) ||
54
+ amount <= 0) {
55
+ return;
56
+ }
57
+ const name = model.trim();
58
+ const key = keyOf(name, unit);
59
+ const entry = this.pending.get(key);
60
+ if (entry)
61
+ entry.amount += amount;
62
+ else
63
+ this.pending.set(key, { model: name, unit, amount });
64
+ }
65
+ /** What is pending, which then no longer is. */
66
+ take() {
67
+ const entries = [...this.pending.values()];
68
+ this.pending = new Map();
69
+ return entries;
70
+ }
71
+ /** True when there is nothing to report. */
72
+ get isEmpty() {
73
+ return this.pending.size === 0;
74
+ }
75
+ }
76
+ exports.UsageLedger = UsageLedger;
77
+ /**
78
+ * Counts what the running request used. For an agent that calls a provider
79
+ * itself; what is called through `langChain` is counted already. Outside a
80
+ * request there is nothing to count into, and nothing happens.
81
+ * @param model - The model's id, as its provider names it
82
+ * @param unit - What the amount is counted in
83
+ * @param amount - How much
84
+ */
85
+ const recordUsage = (model, unit, amount) => {
86
+ (0, runtimeContext_js_1.getContext)()?.usage?.add(model, unit, amount);
87
+ };
88
+ exports.recordUsage = recordUsage;
89
+ const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
90
+ const defaultReport = (usage, reportId, token) => client_api_1.integration.reportRunUsage(usage, reportId, token);
91
+ /**
92
+ * Sends one report, again when it fails, under the same name every time: the
93
+ * platform charges a report it has seen only once.
94
+ */
95
+ const send = async (entries, token, report, retryBaseMs) => {
96
+ const reportId = (0, node_crypto_1.randomUUID)();
97
+ for (let attempt = 1;; attempt++) {
98
+ try {
99
+ await report(entries, reportId, token);
100
+ return;
101
+ }
102
+ catch (error) {
103
+ if (attempt >= REPORT_ATTEMPTS)
104
+ throw error;
105
+ await delay(retryBaseMs * 2 ** (attempt - 1));
106
+ }
107
+ }
108
+ };
109
+ /**
110
+ * Reports what the request used and has not reported yet. Never throws, and
111
+ * never changes what the work answers: the work happened, and a platform that
112
+ * cannot be told what it used right now is told by the next report, or not at
113
+ * all — which is logged as an error, with what was used.
114
+ *
115
+ * @param context - The request whose ledger is reported
116
+ * @param options - `report` sends a report (default: the platform's route);
117
+ * `last` says no other report follows, so what cannot be sent is given up on
118
+ * rather than kept for the next one
119
+ */
120
+ const reportUsage = async (context, options = {}) => {
121
+ const ledger = context?.usage;
122
+ if (!ledger || ledger.isEmpty)
123
+ return;
124
+ const token = context.request?.authToken ?? context.request?.authorization;
125
+ const entries = ledger.take();
126
+ if (!token) {
127
+ logger_js_1.default.log(null, logger_js_1.default.levels.error, `usage was not reported, the request carries no token: ${JSON.stringify(entries)}`);
128
+ return;
129
+ }
130
+ for (let start = 0; start < entries.length; start += REPORT_ENTRIES_MAX) {
131
+ const chunk = entries.slice(start, start + REPORT_ENTRIES_MAX);
132
+ try {
133
+ await send(chunk, token, options.report ?? defaultReport, options.retryBaseMs ?? REPORT_RETRY_BASE_MS);
134
+ }
135
+ catch (error) {
136
+ if (options.last) {
137
+ logger_js_1.default.log(null, logger_js_1.default.levels.error, `usage could not be reported (${error?.message ?? error}): ${JSON.stringify(chunk)}`);
138
+ }
139
+ else {
140
+ for (const entry of chunk)
141
+ ledger.add(entry.model, entry.unit, entry.amount);
142
+ logger_js_1.default.log(null, logger_js_1.default.levels.warn, `usage could not be reported, it is kept for the next report: ${error?.message ?? error}`);
143
+ }
144
+ }
145
+ }
146
+ };
147
+ exports.reportUsage = reportUsage;
148
+ /**
149
+ * Reports what the request used so far every {@link USAGE_REPORT_INTERVAL_MS}
150
+ * while the work runs, so work that dies has reported most of what it used.
151
+ * @returns Stops it
152
+ */
153
+ const reportUsageWhileRunning = (context, options = {}) => {
154
+ const timer = setInterval(() => {
155
+ void (0, exports.reportUsage)(context, { report: options.report, retryBaseMs: options.retryBaseMs });
156
+ }, options.intervalMs ?? exports.USAGE_REPORT_INTERVAL_MS);
157
+ timer.unref?.();
158
+ return () => clearInterval(timer);
159
+ };
160
+ exports.reportUsageWhileRunning = reportUsageWhileRunning;
@@ -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/esm/index.js CHANGED
@@ -2,14 +2,16 @@ 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 { langChain };
11
12
  export { logger };
12
- export { serve };
13
+ export { serve, runOnce, isRunOnceExecution, EXECUTION_ENV };
13
14
  export { callAgent };
14
15
  export { checkAgent };
15
16
  export { runtimeContext };
17
+ export { recordUsage, 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;
@@ -23,27 +35,31 @@ export type UsageTracker = {
23
35
  /**
24
36
  * Instantiates and returns the appropriate LangChain chat model based on the model
25
37
  * name prefix. `claude-` maps to `ChatAnthropic`, `gemini-` maps to
26
- * `ChatGoogleGenerativeAI`, and `gpt-` maps to `ChatOpenAI`. DeepSeek (`deepseek-`),
27
- * Kimi/Moonshot (`kimi-`, `moonshot-`), and GLM/Zhipu (`glm-`) models are routed
28
- * through `ChatOpenAI` against each provider's OpenAI-compatible endpoint. When a Zod
38
+ * `ChatGoogleGenerativeAI`, and `gpt-` maps to `ChatOpenAI`. When a Zod
29
39
  * `schema` is provided, native structured output is configured per provider: OpenAI
30
40
  * via `response_format` with `json_schema`, Anthropic via `output_config.format`, and
31
41
  * Gemini via JSON mode (`json: true`) plus `responseSchema`. In every case the model
32
42
  * emits JSON as the message text, so the caller's parse/validate pipeline is unchanged.
33
- * The schema is ignored for the OpenAI-compatible providers (DeepSeek/Kimi/GLM), which
34
- * have no native structured-output support here. Throws a `BAD_REQUEST` error for
35
- * unrecognised model names.
43
+ * Throws a `BAD_REQUEST` error for unrecognised model names.
44
+ *
45
+ * Output token limits are not caller-configurable. Anthropic requires
46
+ * `max_tokens` on every request and @langchain/anthropic defaults it to 4096,
47
+ * so the Claude branch pins it explicitly; OpenAI and Gemini are sent no limit
48
+ * and fall back to each provider's own default, which is that model's maximum.
36
49
  * @param modelName - The model identifier, e.g. `"gpt-4o"`, `"claude-3-5-sonnet"`,
37
- * `"gemini-1.5-pro"`, `"deepseek-chat"`, `"kimi-k2-0905-preview"`, `"glm-4.6"`
50
+ * `"gemini-1.5-pro"`
38
51
  * @param config - Configuration object containing API keys (`openAIAPIKey`,
39
- * `anthropicAPIKey`, `googleAPIKey`, `deepSeekAPIKey`, `kimiAPIKey`, `glmAPIKey`),
40
- * optional `maxTokens`, and optional `temperature`
52
+ * `anthropicAPIKey`, `googleAPIKey`) and optional `temperature`
41
53
  * @param schema - Optional Zod schema used to configure native structured JSON output
42
- * for GPT / Claude / Gemini models; ignored for OpenAI-compatible providers
43
54
  * @returns A configured LangChain chat model (or bound runnable) instance
44
55
  */
45
56
  export declare const getLLMModel: (modelName: string, config: any, schema?: any) => any;
46
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;
47
63
  checkIfAIProviderConfigured: (config: any) => void;
48
64
  createAgent: (name: string, modelName: string, systemPrompt: string, tools: any[], responseFormat: any, config: any, usageTracker?: UsageTracker | null) => any;
49
65
  runAgent: (agent: any, prompt: string, config: any, onProgress?: Function | null, usageTracker?: UsageTracker | null) => Promise<any>;
@@ -51,7 +67,10 @@ declare const _default: {
51
67
  runPromptWithModelForImageGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
52
68
  runPromptWithModelForVideoGeneration: (modelName: string, config: any, prompt: string, options?: any, usageTracker?: UsageTracker | null) => Promise<any>;
53
69
  throwErrorIfNotSuccessful: (response: any) => string;
54
- 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;
55
74
  validateModel: (selectedModel: string, supportedModels: string[]) => string;
56
75
  };
57
76
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"langChain.d.ts","sourceRoot":"","sources":["../../src/langChain.ts"],"names":[],"mappings":"AA4GA;;;;;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;AAmrBF;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,eAAO,MAAM,WAAW,GACtB,WAAW,MAAM,EACjB,QAAQ,GAAG,EACX,SAAQ,GAAU,KACjB,GAoHF,CAAC;;0CAj0B2C,GAAG,KAAG,IAAI;wBAo1B/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;+CAh0B9C,YAAY,GAAG,IAAI,GAAG,SAAS,aAC7B,MAAM,kBACD,MAAM,UACd,GAAG,KACV,IAAI;mCAg1BU,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"}