@jsonstudio/llms 0.6.1643 → 0.6.1739

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.
Files changed (96) hide show
  1. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.d.ts +10 -0
  2. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +121 -0
  3. package/dist/conversion/compat/actions/iflow-kimi-cli-defaults.d.ts +10 -0
  4. package/dist/conversion/compat/actions/iflow-kimi-cli-defaults.js +80 -0
  5. package/dist/conversion/compat/actions/iflow-kimi-history-media-placeholder.d.ts +7 -0
  6. package/dist/conversion/compat/actions/iflow-kimi-history-media-placeholder.js +161 -0
  7. package/dist/conversion/compat/actions/iflow-kimi-thinking-reasoning-fill.d.ts +12 -0
  8. package/dist/conversion/compat/actions/iflow-kimi-thinking-reasoning-fill.js +67 -0
  9. package/dist/conversion/compat/actions/iflow-response-body-unwrap.d.ts +9 -0
  10. package/dist/conversion/compat/actions/iflow-response-body-unwrap.js +140 -0
  11. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.d.ts +10 -0
  12. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +59 -0
  13. package/dist/conversion/compat/actions/lmstudio-responses-input-stringify.d.ts +14 -0
  14. package/dist/conversion/compat/actions/lmstudio-responses-input-stringify.js +125 -0
  15. package/dist/conversion/compat/actions/normalize-tool-call-ids.d.ts +11 -0
  16. package/dist/conversion/compat/actions/normalize-tool-call-ids.js +140 -0
  17. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.d.ts +2 -0
  18. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +152 -0
  19. package/dist/conversion/compat/antigravity-session-signature.d.ts +1 -1
  20. package/dist/conversion/compat/antigravity-session-signature.js +5 -4
  21. package/dist/conversion/compat/profiles/chat-iflow.json +6 -0
  22. package/dist/conversion/compat/profiles/chat-lmstudio.json +7 -1
  23. package/dist/conversion/hub/operation-table/operation-table-runner.js +1 -1
  24. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +19 -2
  25. package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +101 -5
  26. package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.d.ts +2 -0
  27. package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.js +63 -0
  28. package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +18 -0
  29. package/dist/conversion/hub/pipeline/hub-pipeline.js +1 -1
  30. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +8 -5
  31. package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +5 -1
  32. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +113 -0
  33. package/dist/conversion/hub/pipeline/target-utils.js +3 -0
  34. package/dist/conversion/hub/response/provider-response.js +27 -1
  35. package/dist/conversion/responses/responses-openai-bridge.js +32 -6
  36. package/dist/conversion/shared/anthropic-message-utils.js +20 -5
  37. package/dist/conversion/shared/bridge-id-utils.d.ts +2 -0
  38. package/dist/conversion/shared/bridge-id-utils.js +52 -15
  39. package/dist/conversion/shared/responses-conversation-store.js +40 -5
  40. package/dist/conversion/shared/responses-output-builder.js +23 -7
  41. package/dist/conversion/shared/responses-tool-utils.d.ts +1 -0
  42. package/dist/conversion/shared/responses-tool-utils.js +30 -13
  43. package/dist/conversion/shared/text-markup-normalizer.d.ts +1 -0
  44. package/dist/conversion/shared/text-markup-normalizer.js +269 -1
  45. package/dist/router/virtual-router/bootstrap.js +31 -7
  46. package/dist/router/virtual-router/classifier.js +1 -1
  47. package/dist/router/virtual-router/engine/antigravity/alias-lease.d.ts +33 -0
  48. package/dist/router/virtual-router/engine/antigravity/alias-lease.js +247 -0
  49. package/dist/router/virtual-router/engine/health/index.d.ts +23 -0
  50. package/dist/router/virtual-router/engine/health/index.js +720 -0
  51. package/dist/router/virtual-router/engine/provider-key/parse.d.ts +6 -0
  52. package/dist/router/virtual-router/engine/provider-key/parse.js +43 -0
  53. package/dist/router/virtual-router/engine/routing-pools/index.d.ts +13 -0
  54. package/dist/router/virtual-router/engine/routing-pools/index.js +225 -0
  55. package/dist/router/virtual-router/engine/routing-state/keys.d.ts +3 -0
  56. package/dist/router/virtual-router/engine/routing-state/keys.js +30 -0
  57. package/dist/router/virtual-router/engine/routing-state/metadata.d.ts +6 -0
  58. package/dist/router/virtual-router/engine/routing-state/metadata.js +132 -0
  59. package/dist/router/virtual-router/engine/routing-state/store.d.ts +11 -0
  60. package/dist/router/virtual-router/engine/routing-state/store.js +107 -0
  61. package/dist/router/virtual-router/engine-health.d.ts +1 -23
  62. package/dist/router/virtual-router/engine-health.js +1 -720
  63. package/dist/router/virtual-router/engine-selection/route-utils.js +57 -0
  64. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +8 -48
  65. package/dist/router/virtual-router/engine-selection/tier-selection.js +34 -17
  66. package/dist/router/virtual-router/engine-selection.d.ts +1 -13
  67. package/dist/router/virtual-router/engine-selection.js +1 -225
  68. package/dist/router/virtual-router/engine.d.ts +2 -23
  69. package/dist/router/virtual-router/engine.js +130 -603
  70. package/dist/router/virtual-router/message-utils.js +15 -5
  71. package/dist/servertool/engine.js +4 -4
  72. package/dist/servertool/handlers/followup-request-builder.js +46 -0
  73. package/dist/servertool/handlers/gemini-empty-reply-continue.js +48 -47
  74. package/dist/servertool/handlers/stop-message-auto.js +64 -7
  75. package/dist/servertool/handlers/vision.js +10 -0
  76. package/dist/servertool/types.d.ts +3 -0
  77. package/dist/sse/sse-to-json/builders/response-builder.js +6 -0
  78. package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +32 -2
  79. package/dist/sse/sse-to-json/parsers/sse-parser.js +34 -0
  80. package/dist/sse/sse-to-json/responses-sse-to-json-converter.d.ts +1 -0
  81. package/dist/sse/sse-to-json/responses-sse-to-json-converter.js +33 -1
  82. package/dist/tools/apply-patch/args-normalizer/default-actions.d.ts +2 -0
  83. package/dist/tools/apply-patch/args-normalizer/default-actions.js +12 -0
  84. package/dist/tools/apply-patch/args-normalizer/extract-patch.d.ts +2 -0
  85. package/dist/tools/apply-patch/args-normalizer/extract-patch.js +15 -0
  86. package/dist/tools/apply-patch/args-normalizer/index.d.ts +2 -0
  87. package/dist/tools/apply-patch/args-normalizer/index.js +164 -0
  88. package/dist/tools/apply-patch/args-normalizer/structured-builders.d.ts +7 -0
  89. package/dist/tools/apply-patch/args-normalizer/structured-builders.js +85 -0
  90. package/dist/tools/apply-patch/args-normalizer/types.d.ts +54 -0
  91. package/dist/tools/apply-patch/args-normalizer/types.js +1 -0
  92. package/dist/tools/apply-patch/patch-text/looks-like-patch.js +1 -0
  93. package/dist/tools/apply-patch/patch-text/normalize.js +104 -5
  94. package/dist/tools/apply-patch/structured/coercion.js +28 -4
  95. package/dist/tools/apply-patch/validator.js +7 -146
  96. package/package.json +1 -1
@@ -23,7 +23,7 @@ export class RoutingClassifier {
23
23
  const evaluationMap = {
24
24
  vision: {
25
25
  triggered: features.hasImageAttachment,
26
- reason: 'vision:image-detected'
26
+ reason: 'vision:media-detected'
27
27
  },
28
28
  thinking: {
29
29
  triggered: thinkingFromUser || thinkingFromRead,
@@ -0,0 +1,33 @@
1
+ import type { RouterMetadataInput, VirtualRouterConfig } from '../../types.js';
2
+ import type { ProviderRegistry } from '../../provider-registry.js';
3
+ export type AntigravityAliasLeaseStore = Map<string, {
4
+ sessionKey: string;
5
+ lastSeenAt: number;
6
+ }>;
7
+ export type AntigravitySessionAliasStore = Map<string, string>;
8
+ export type AntigravityLeasePersistenceState = {
9
+ loadedOnce: boolean;
10
+ loadedMtimeMs: number | null;
11
+ flushTimer: ReturnType<typeof setTimeout> | null;
12
+ };
13
+ export declare function resolveAntigravityAliasReuseCooldownMs(config: VirtualRouterConfig): number;
14
+ export declare function hydrateAntigravityAliasLeaseStoreIfNeeded(options: {
15
+ force?: boolean;
16
+ leaseStore: AntigravityAliasLeaseStore;
17
+ persistence: AntigravityLeasePersistenceState;
18
+ aliasReuseCooldownMs: number;
19
+ }): void;
20
+ export declare function recordAntigravitySessionLease(options: {
21
+ metadata: RouterMetadataInput;
22
+ providerKey: string;
23
+ sessionKey: string | undefined;
24
+ providerRegistry: ProviderRegistry;
25
+ leaseStore: AntigravityAliasLeaseStore;
26
+ sessionAliasStore: AntigravitySessionAliasStore;
27
+ persistence: AntigravityLeasePersistenceState;
28
+ aliasReuseCooldownMs: number;
29
+ commitSessionBinding: boolean;
30
+ debug?: {
31
+ log?: (...args: any[]) => void;
32
+ };
33
+ }): void;
@@ -0,0 +1,247 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ export function resolveAntigravityAliasReuseCooldownMs(config) {
5
+ const cfg = config.loadBalancing?.aliasSelection?.sessionLeaseCooldownMs;
6
+ if (typeof cfg === 'number' && Number.isFinite(cfg)) {
7
+ return Math.max(0, Math.floor(cfg));
8
+ }
9
+ return 5 * 60_000;
10
+ }
11
+ function resolveAntigravityLeaseScope(providerRegistry, providerKey) {
12
+ try {
13
+ const profile = providerRegistry.get(providerKey);
14
+ const modelId = typeof profile?.modelId === 'string' ? profile.modelId.trim().toLowerCase() : '';
15
+ if (modelId.startsWith('gemini-')) {
16
+ return 'gemini';
17
+ }
18
+ return null;
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ function buildScopedSessionKey(sessionKey) {
25
+ return `${sessionKey}::gemini`;
26
+ }
27
+ function buildAntigravityLeaseRuntimeKey(runtimeKey) {
28
+ return `${runtimeKey}::gemini`;
29
+ }
30
+ function extractRuntimeKey(providerKey) {
31
+ const value = typeof providerKey === 'string' ? providerKey.trim() : '';
32
+ if (!value)
33
+ return null;
34
+ const firstDot = value.indexOf('.');
35
+ if (firstDot <= 0 || firstDot === value.length - 1)
36
+ return null;
37
+ const secondDot = value.indexOf('.', firstDot + 1);
38
+ if (secondDot <= firstDot + 1)
39
+ return null;
40
+ const providerId = value.slice(0, firstDot);
41
+ const alias = value.slice(firstDot + 1, secondDot);
42
+ if (!providerId || !alias)
43
+ return null;
44
+ return `${providerId}.${alias}`;
45
+ }
46
+ function resolveAntigravityAliasLeasePersistPath() {
47
+ try {
48
+ const enabledRaw = process.env.ROUTECODEX_ANTIGRAVITY_ALIAS_LEASE_PERSIST;
49
+ const enabled = typeof enabledRaw === 'string' &&
50
+ ['1', 'true', 'yes', 'on'].includes(enabledRaw.trim().toLowerCase());
51
+ if (!enabled) {
52
+ return null;
53
+ }
54
+ const home = os.homedir();
55
+ if (!home)
56
+ return null;
57
+ return path.join(home, '.routecodex', 'state', 'antigravity-alias-leases.json');
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ export function hydrateAntigravityAliasLeaseStoreIfNeeded(options) {
64
+ const filePath = resolveAntigravityAliasLeasePersistPath();
65
+ if (!filePath) {
66
+ return;
67
+ }
68
+ const force = options.force === true;
69
+ let stat = null;
70
+ try {
71
+ stat = fs.statSync(filePath);
72
+ }
73
+ catch {
74
+ options.persistence.loadedOnce = true;
75
+ options.persistence.loadedMtimeMs = null;
76
+ return;
77
+ }
78
+ const mtimeMs = typeof stat.mtimeMs === 'number' && Number.isFinite(stat.mtimeMs) ? stat.mtimeMs : stat.mtime.getTime();
79
+ if (!force && options.persistence.loadedOnce && options.persistence.loadedMtimeMs === mtimeMs) {
80
+ return;
81
+ }
82
+ let parsed;
83
+ try {
84
+ parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
85
+ }
86
+ catch {
87
+ options.persistence.loadedOnce = true;
88
+ options.persistence.loadedMtimeMs = mtimeMs;
89
+ return;
90
+ }
91
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
92
+ options.persistence.loadedOnce = true;
93
+ options.persistence.loadedMtimeMs = mtimeMs;
94
+ return;
95
+ }
96
+ const leasesRaw = parsed.leases;
97
+ if (!leasesRaw || typeof leasesRaw !== 'object' || Array.isArray(leasesRaw)) {
98
+ options.persistence.loadedOnce = true;
99
+ options.persistence.loadedMtimeMs = mtimeMs;
100
+ return;
101
+ }
102
+ const now = Date.now();
103
+ const cooldownMs = options.aliasReuseCooldownMs;
104
+ const nextLeaseStore = new Map();
105
+ for (const [runtimeKeyRaw, entryRaw] of Object.entries(leasesRaw)) {
106
+ const runtimeKeyBase = typeof runtimeKeyRaw === 'string' ? runtimeKeyRaw.trim() : '';
107
+ if (!runtimeKeyBase || !runtimeKeyBase.startsWith('antigravity.'))
108
+ continue;
109
+ if (!entryRaw || typeof entryRaw !== 'object' || Array.isArray(entryRaw))
110
+ continue;
111
+ const rawSessionKey = typeof entryRaw.sessionKey === 'string' ? String(entryRaw.sessionKey).trim() : '';
112
+ const lastSeenAt = typeof entryRaw.lastSeenAt === 'number' && Number.isFinite(entryRaw.lastSeenAt)
113
+ ? Math.floor(entryRaw.lastSeenAt)
114
+ : 0;
115
+ if (!rawSessionKey || !lastSeenAt)
116
+ continue;
117
+ if (cooldownMs > 0 && now - lastSeenAt >= cooldownMs)
118
+ continue;
119
+ // Backwards compatible: legacy lease keys were unscoped ("antigravity.<alias>").
120
+ // Policy: only keep Gemini-scoped leases. Drop any non-gemini scoped entries.
121
+ const hasExplicitScope = runtimeKeyBase.includes('::');
122
+ if (hasExplicitScope && !runtimeKeyBase.endsWith('::gemini'))
123
+ continue;
124
+ const runtimeKey = hasExplicitScope ? runtimeKeyBase : buildAntigravityLeaseRuntimeKey(runtimeKeyBase);
125
+ if (rawSessionKey.includes('::') && !rawSessionKey.endsWith('::gemini'))
126
+ continue;
127
+ const sessionKey = rawSessionKey.includes('::') ? rawSessionKey : buildScopedSessionKey(rawSessionKey);
128
+ nextLeaseStore.set(runtimeKey, { sessionKey, lastSeenAt });
129
+ }
130
+ options.leaseStore.clear();
131
+ for (const [key, val] of nextLeaseStore.entries()) {
132
+ options.leaseStore.set(key, val);
133
+ }
134
+ options.persistence.loadedOnce = true;
135
+ options.persistence.loadedMtimeMs = mtimeMs;
136
+ }
137
+ function flushAntigravityAliasLeaseStoreSync(options) {
138
+ const filePath = resolveAntigravityAliasLeasePersistPath();
139
+ if (!filePath) {
140
+ return;
141
+ }
142
+ try {
143
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
144
+ }
145
+ catch {
146
+ // ignore
147
+ }
148
+ const now = Date.now();
149
+ const cooldownMs = options.aliasReuseCooldownMs;
150
+ const leases = {};
151
+ for (const [runtimeKey, entry] of options.leaseStore.entries()) {
152
+ if (!runtimeKey || !entry)
153
+ continue;
154
+ if (cooldownMs > 0 && now - entry.lastSeenAt >= cooldownMs)
155
+ continue;
156
+ if (!entry.sessionKey || !entry.lastSeenAt)
157
+ continue;
158
+ leases[runtimeKey] = { sessionKey: entry.sessionKey, lastSeenAt: entry.lastSeenAt };
159
+ }
160
+ try {
161
+ const tmpPath = `${filePath}.tmp.${process.pid}.${now}`;
162
+ fs.writeFileSync(tmpPath, JSON.stringify({ version: 1, updatedAt: now, leases }, null, 2), 'utf8');
163
+ fs.renameSync(tmpPath, filePath);
164
+ try {
165
+ const stat = fs.statSync(filePath);
166
+ const mtimeMs = typeof stat.mtimeMs === 'number' && Number.isFinite(stat.mtimeMs) ? stat.mtimeMs : stat.mtime.getTime();
167
+ options.persistence.loadedOnce = true;
168
+ options.persistence.loadedMtimeMs = mtimeMs;
169
+ }
170
+ catch {
171
+ // ignore
172
+ }
173
+ }
174
+ catch {
175
+ // best-effort persistence: must not affect routing
176
+ }
177
+ }
178
+ function scheduleAntigravityAliasLeaseStoreFlush(options) {
179
+ if (options.persistence.flushTimer) {
180
+ return;
181
+ }
182
+ options.persistence.flushTimer = setTimeout(() => {
183
+ options.persistence.flushTimer = null;
184
+ flushAntigravityAliasLeaseStoreSync(options);
185
+ }, 250);
186
+ options.persistence.flushTimer.unref?.();
187
+ }
188
+ export function recordAntigravitySessionLease(options) {
189
+ // Per-request runtime override: allow callers (e.g. servertool followups) to disable
190
+ // Antigravity gemini session binding/lease without changing global config.
191
+ try {
192
+ const rt = options.metadata?.__rt;
193
+ if (rt && typeof rt === 'object' && !Array.isArray(rt)) {
194
+ const disable = rt.disableAntigravitySessionBinding;
195
+ const mode = rt.antigravitySessionBinding;
196
+ if (disable === true || mode === false) {
197
+ return;
198
+ }
199
+ if (typeof mode === 'string' && ['0', 'false', 'off', 'disabled', 'none'].includes(mode.trim().toLowerCase())) {
200
+ return;
201
+ }
202
+ }
203
+ }
204
+ catch {
205
+ // ignore metadata parse errors
206
+ }
207
+ const sessionKey = options.sessionKey;
208
+ if (!sessionKey) {
209
+ return;
210
+ }
211
+ const runtimeKeyBase = extractRuntimeKey(options.providerKey);
212
+ if (!runtimeKeyBase || !runtimeKeyBase.startsWith('antigravity.')) {
213
+ return;
214
+ }
215
+ // Policy: antigravity alias leasing/binding applies only to Gemini models.
216
+ const scope = resolveAntigravityLeaseScope(options.providerRegistry, options.providerKey);
217
+ if (scope !== 'gemini') {
218
+ return;
219
+ }
220
+ const scopedSessionKey = buildScopedSessionKey(sessionKey);
221
+ const runtimeKey = buildAntigravityLeaseRuntimeKey(runtimeKeyBase);
222
+ const now = Date.now();
223
+ const cooldownMs = options.aliasReuseCooldownMs;
224
+ const existing = options.leaseStore.get(runtimeKey);
225
+ // Do not steal a lease from another active session. This prevents a "forced fallback" route
226
+ // (e.g. default route bypass) from evicting the original session and causing churn.
227
+ if (existing && existing.sessionKey !== scopedSessionKey && cooldownMs > 0 && now - existing.lastSeenAt < cooldownMs) {
228
+ return;
229
+ }
230
+ options.leaseStore.set(runtimeKey, { sessionKey: scopedSessionKey, lastSeenAt: now });
231
+ scheduleAntigravityAliasLeaseStoreFlush(options);
232
+ if (!options.commitSessionBinding) {
233
+ return;
234
+ }
235
+ // Bind sessionKey → alias runtimeKey so subsequent routing will prefer this alias.
236
+ options.sessionAliasStore.set(scopedSessionKey, runtimeKeyBase);
237
+ try {
238
+ options.debug?.log?.('[virtual-router][antigravity-session-binding] commit', {
239
+ sessionKey: scopedSessionKey,
240
+ runtimeKey: runtimeKeyBase,
241
+ prev: existing?.sessionKey ?? null
242
+ });
243
+ }
244
+ catch {
245
+ // ignore
246
+ }
247
+ }
@@ -0,0 +1,23 @@
1
+ import { ProviderHealthManager } from '../../health-manager.js';
2
+ import { ProviderRegistry } from '../../provider-registry.js';
3
+ import type { ProviderErrorEvent, ProviderFailureEvent, ProviderHealthConfig } from '../../types.js';
4
+ type DebugLike = {
5
+ log?: (...args: unknown[]) => void;
6
+ } | Console | undefined;
7
+ export declare function resetRateLimitBackoffForProvider(providerKey: string): void;
8
+ export declare function applyAntigravityRiskPolicyImpl(event: ProviderErrorEvent, providerRegistry: ProviderRegistry, healthManager: ProviderHealthManager, markProviderCooldown: (providerKey: string, cooldownMs: number | undefined) => void, debug?: DebugLike): void;
9
+ export declare function handleProviderFailureImpl(event: ProviderFailureEvent, healthManager: ProviderHealthManager, healthConfig: Required<ProviderHealthConfig>, markProviderCooldown: (providerKey: string, cooldownMs: number | undefined) => void): void;
10
+ export declare function mapProviderErrorImpl(event: ProviderErrorEvent, healthConfig: Required<ProviderHealthConfig>): ProviderFailureEvent | null;
11
+ export declare function applySeriesCooldownImpl(event: ProviderErrorEvent, providerRegistry: ProviderRegistry, healthManager: ProviderHealthManager, markProviderCooldown: (providerKey: string, cooldownMs: number | undefined) => void, debug?: DebugLike): void;
12
+ /**
13
+ * 处理来自 Host 侧的配额恢复事件:
14
+ * - 清除指定 providerKey 在健康管理器中的熔断/冷却状态;
15
+ * - 清理对应的速率退避计数;
16
+ * - 调用调用方提供的 clearProviderCooldown 回调移除显式 cooldown TTL。
17
+ *
18
+ * 返回值表示是否已处理(true=已处理且后续应跳过常规错误映射逻辑)。
19
+ */
20
+ export declare function applyQuotaRecoveryImpl(event: ProviderErrorEvent, healthManager: ProviderHealthManager, clearProviderCooldown: (providerKey: string) => void, debug?: DebugLike): boolean;
21
+ export declare function applyQuotaDepletedImpl(event: ProviderErrorEvent, healthManager: ProviderHealthManager, markProviderCooldown: (providerKey: string, cooldownMs: number | undefined) => void, debug?: DebugLike): boolean;
22
+ export declare function deriveReason(code: string, stage: string, statusCode?: number): string;
23
+ export {};