@maximem/synap-js-sdk 0.4.8 → 0.5.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/dist/anticipation-cache-LRE3TLK4.cjs.map +1 -1
- package/dist/{chunk-T5QQBJ6T.js → chunk-ASM2OIIG.js} +292 -7
- package/dist/chunk-ASM2OIIG.js.map +1 -0
- package/dist/{chunk-OCMM2Z5P.js → chunk-BWMPKLFG.js} +40 -2
- package/dist/chunk-BWMPKLFG.js.map +1 -0
- package/dist/{chunk-7CWBRHUO.cjs → chunk-IA2N5NUY.cjs} +302 -17
- package/dist/chunk-IA2N5NUY.cjs.map +1 -0
- package/dist/{chunk-2TVL5IPQ.cjs → chunk-T372OL3Q.cjs} +41 -3
- package/dist/chunk-T372OL3Q.cjs.map +1 -0
- package/dist/chunk-T6U5PVAD.cjs.map +1 -1
- package/dist/chunk-ZKOJDUN4.cjs.map +1 -1
- package/dist/env-55ULHNJZ.cjs.map +1 -1
- package/dist/errors-Bl3vY1eb.d.cts +382 -0
- package/dist/errors-Bl3vY1eb.d.ts +382 -0
- package/dist/grpc/index.cjs +7 -7
- package/dist/grpc/index.cjs.map +1 -1
- package/dist/grpc/index.d.cts +44 -4
- package/dist/grpc/index.d.ts +44 -4
- package/dist/grpc/index.js +5 -5
- package/dist/index.cjs +278 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -148
- package/dist/index.d.ts +97 -148
- package/dist/index.js +171 -54
- package/dist/index.js.map +1 -1
- package/dist/stream-client-6OWRYOA4.js +16 -0
- package/dist/stream-client-Y5JGSF2R.cjs +16 -0
- package/dist/stream-client-Y5JGSF2R.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/anticipation-cache-C1rUEpaW.d.cts +0 -211
- package/dist/anticipation-cache-C1rUEpaW.d.ts +0 -211
- package/dist/chunk-2TVL5IPQ.cjs.map +0 -1
- package/dist/chunk-7CWBRHUO.cjs.map +0 -1
- package/dist/chunk-OCMM2Z5P.js.map +0 -1
- package/dist/chunk-T5QQBJ6T.js.map +0 -1
- package/dist/stream-client-2C5KIOWP.js +0 -7
- package/dist/stream-client-GPU37E6F.cjs +0 -7
- package/dist/stream-client-GPU37E6F.cjs.map +0 -1
- /package/dist/{stream-client-2C5KIOWP.js.map → stream-client-6OWRYOA4.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/util/correlation.ts"],"sourcesContent":["/**\n * Synap SDK error taxonomy.\n *\n * Mirrors `maximem_synap/models/errors.py` 1:1, including the four\n * backward-compatibility aliases at the bottom. If you add an error to one\n * SDK, add it to the other in the same change.\n *\n * ## Why every error carries a `.code`\n *\n * This package ships dual ESM + CJS. A consumer whose dependency graph pulls\n * in both formats gets *two* copies of every class in this file, and then:\n *\n * try { ... } catch (e) { if (e instanceof SynapError) { ... } }\n *\n * silently evaluates to `false` against the copy from the other format. Error\n * handling stops working and nothing throws to tell you. `.code` is a plain\n * string, so it is immune. Prefer it at package boundaries:\n *\n * if (isSynapError(e) && e.code === 'rate_limit') { ... }\n *\n * `Symbol.hasInstance` is also wired up on the base class, so `instanceof`\n * works across realms too -- but `.code` is the documented contract.\n */\n\n/** Stable, format-independent discriminators. Never renumber or reuse. */\nexport type SynapErrorCode =\n | 'synap_error'\n | 'transient'\n | 'permanent'\n | 'network_timeout'\n | 'rate_limit'\n | 'insufficient_credits'\n | 'service_unavailable'\n | 'invalid_input'\n | 'invalid_instance_id'\n | 'invalid_conversation_id'\n | 'authentication'\n | 'context_not_found'\n | 'conflict'\n | 'transcript_conflict'\n | 'session_expired'\n | 'listening_already_active'\n | 'listening_not_active'\n | 'agent_unavailable';\n\nconst BRAND = Symbol.for('@maximem/synap-js-sdk.SynapError');\n\nexport interface SynapErrorOptions {\n correlationId?: string | null;\n cause?: unknown;\n}\n\nexport class SynapError extends Error {\n /**\n * The single declaration site for each subclass's code.\n *\n * It is `static` rather than a class field on purpose. Under\n * `useDefineForClassFields` (the default at our ES2022 target) a class field\n * is an *instance* property, so it is invisible from the constructor object.\n * `Symbol.hasInstance` below only has the constructor to work with, so a\n * field would leave it unable to tell `AuthenticationError` from\n * `RateLimitError` -- it would report every Synap error as an instance of\n * every other one.\n */\n static readonly errorCode: SynapErrorCode = 'synap_error';\n /** True for errors where a retry may succeed. Static for the same reason. */\n static readonly isTransient: boolean = false;\n\n /** Own, enumerable, so logs and JSON.stringify include it. */\n readonly code: SynapErrorCode;\n readonly correlationId: string | null;\n readonly transient: boolean;\n\n constructor(message: string, options: SynapErrorOptions = {}) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n const ctor = new.target as typeof SynapError;\n this.name = new.target.name;\n this.code = ctor.errorCode;\n this.transient = ctor.isTransient;\n this.correlationId = options.correlationId ?? null;\n Object.defineProperty(this, BRAND, { value: true, enumerable: false });\n // Without this, subclassing a built-in under a downlevel target breaks the\n // prototype chain and `instanceof` fails even within a single copy.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static override [Symbol.hasInstance](instance: unknown): boolean {\n if (instance === null || typeof instance !== 'object') return false;\n // Cross-realm / dual-format tolerant: identify by brand, then narrow by the\n // subclass's own code so `e instanceof RateLimitError` stays meaningful.\n if (!(BRAND in instance)) return false;\n const expected = (this as unknown as { errorCode?: SynapErrorCode }).errorCode;\n // Called on something that is not one of our classes: fall back to the brand.\n if (expected === undefined) return true;\n // Everything branded descends from the root.\n if (expected === 'synap_error') return true;\n const actual = (instance as { code?: string }).code;\n return actual === expected || descendsFrom(actual, expected);\n }\n}\n\n/** Type guard that works across ESM/CJS copies and realms. */\nexport function isSynapError(e: unknown): e is SynapError {\n return typeof e === 'object' && e !== null && BRAND in e;\n}\n\nexport class SynapTransientError extends SynapError {\n static override readonly errorCode: SynapErrorCode = 'transient';\n static override readonly isTransient: boolean = true;\n}\n\nexport class SynapPermanentError extends SynapError {\n static override readonly errorCode: SynapErrorCode = 'permanent';\n static override readonly isTransient: boolean = false;\n}\n\n// ─── Transient ────────────────────────────────────────────────────────────────\n\nexport class NetworkTimeoutError extends SynapTransientError {\n static override readonly errorCode: SynapErrorCode = 'network_timeout';\n}\n\n/**\n * Rate limit exceeded (HTTP 429, gRPC RESOURCE_EXHAUSTED).\n *\n * Also carries the two credit stops the server reports as 429, because both\n * recover with time or a plan change rather than with a retry of this request:\n * `reason: 'trial_limit_reached'` (the Trial cap is spent, see `upgradeUrl`)\n * and `reason: 'subscription_inactive'` (a paid plan whose subscription is past\n * due, unpaid or cancelled, see `manageUrl`). `reason` is null for an ordinary\n * rate limit and against a server too old to send one.\n */\nexport class RateLimitError extends SynapTransientError {\n static override readonly errorCode: SynapErrorCode = 'rate_limit';\n readonly retryAfterSeconds: number | null;\n /** Machine-readable cause, when the stop was a credit stop. */\n readonly reason: string | null;\n /** Where a Trial customer upgrades. Python calls this `upgrade_url`. */\n readonly upgradeUrl: string | null;\n /** Where billing is managed. Python calls this `manage_url`. */\n readonly manageUrl: string | null;\n\n constructor(\n message: string,\n options: SynapErrorOptions & {\n retryAfterSeconds?: number | null;\n reason?: string | null;\n upgradeUrl?: string | null;\n manageUrl?: string | null;\n } = {},\n ) {\n super(message, options);\n this.retryAfterSeconds = options.retryAfterSeconds ?? null;\n this.reason = options.reason ?? null;\n this.upgradeUrl = options.upgradeUrl ?? null;\n this.manageUrl = options.manageUrl ?? null;\n }\n}\n\nexport class ServiceUnavailableError extends SynapTransientError {\n static override readonly errorCode: SynapErrorCode = 'service_unavailable';\n}\n\nexport class AgentUnavailableError extends SynapTransientError {\n static override readonly errorCode: SynapErrorCode = 'agent_unavailable';\n constructor(message = 'Agent unavailable', options: SynapErrorOptions = {}) {\n super(message, options);\n }\n}\n\n// ─── Permanent ────────────────────────────────────────────────────────────────\n\n/**\n * The caller's credit wallet cannot cover this request.\n *\n * HTTP 402, and gRPC RESOURCE_EXHAUSTED with credit-related trailing metadata.\n * Permanent by design: retrying without topping up burns quota and never\n * succeeds. This is the error behind \"the agent forgot\" reports where retrieval\n * silently returns nothing.\n */\nexport class InsufficientCreditsError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'insufficient_credits';\n readonly balanceCredits: number | null;\n readonly requiredCredits: number | null;\n /** Where the balance can be viewed. Python calls this `recovery_url`. */\n readonly recoveryUrl: string | null;\n /** Where a redeem code can be entered. Python calls this `redeem_url`. */\n readonly redeemUrl: string | null;\n /**\n * Machine-readable cause. `'overages_disabled'` means the plan is paid and\n * the balance is spent, but the account has not allowed usage past zero, so\n * the work stops until someone allows overages or adds credits. Null when an\n * older server did not send one.\n */\n readonly reason: string | null;\n /** Where that setting and billing are managed. Python calls this `manage_url`. */\n readonly manageUrl: string | null;\n\n constructor(\n message: string,\n options: SynapErrorOptions & {\n balanceCredits?: number | null;\n requiredCredits?: number | null;\n recoveryUrl?: string | null;\n redeemUrl?: string | null;\n reason?: string | null;\n manageUrl?: string | null;\n } = {},\n ) {\n super(message, options);\n this.balanceCredits = options.balanceCredits ?? null;\n this.requiredCredits = options.requiredCredits ?? null;\n this.recoveryUrl = options.recoveryUrl ?? null;\n this.redeemUrl = options.redeemUrl ?? null;\n this.reason = options.reason ?? null;\n this.manageUrl = options.manageUrl ?? null;\n }\n}\n\nexport class InvalidInputError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'invalid_input';\n}\n\n/**\n * Raised by `validateInstanceId` before any network call, matching Python's\n * `utils/validators.py`. The message text is identical in both SDKs.\n */\nexport class InvalidInstanceIdError extends InvalidInputError {\n static override readonly errorCode: SynapErrorCode = 'invalid_instance_id';\n}\n\n/** See the note on InvalidInstanceIdError. Raised by `validateConversationId`. */\nexport class InvalidConversationIdError extends InvalidInputError {\n static override readonly errorCode: SynapErrorCode = 'invalid_conversation_id';\n}\n\nexport class AuthenticationError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'authentication';\n}\n\nexport class ContextNotFoundError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'context_not_found';\n}\n\nexport class ConflictError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'conflict';\n}\n\nexport class TranscriptConflictError extends ConflictError {\n static override readonly errorCode: SynapErrorCode = 'transcript_conflict';\n}\n\nexport class SessionExpiredError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'session_expired';\n}\n\nexport class ListeningAlreadyActiveError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'listening_already_active';\n}\n\nexport class ListeningNotActiveError extends SynapPermanentError {\n static override readonly errorCode: SynapErrorCode = 'listening_not_active';\n}\n\n// ─── Hierarchy metadata (drives the cross-copy instanceof above) ──────────────\n\nconst PARENT: Partial<Record<SynapErrorCode, SynapErrorCode>> = {\n transient: 'synap_error',\n permanent: 'synap_error',\n network_timeout: 'transient',\n rate_limit: 'transient',\n service_unavailable: 'transient',\n agent_unavailable: 'transient',\n insufficient_credits: 'permanent',\n invalid_input: 'permanent',\n invalid_instance_id: 'invalid_input',\n invalid_conversation_id: 'invalid_input',\n authentication: 'permanent',\n context_not_found: 'permanent',\n conflict: 'permanent',\n transcript_conflict: 'conflict',\n session_expired: 'permanent',\n listening_already_active: 'permanent',\n listening_not_active: 'permanent',\n};\n\nfunction descendsFrom(actual: string | undefined, expected: string): boolean {\n let cur = actual as SynapErrorCode | undefined;\n const seen = new Set<string>();\n while (cur && !seen.has(cur)) {\n seen.add(cur);\n if (cur === expected) return true;\n cur = PARENT[cur];\n }\n return false;\n}\n\n// ─── Backward-compatibility aliases (mirrors the tail of errors.py) ──────────\n// `ConnectionError` deliberately shadows the global in a module scope. Python\n// does the same thing; keeping the name means ported code reads identically.\n\nexport const SDKError = SynapError;\nexport const TransientError = SynapTransientError;\nexport const PermanentError = SynapPermanentError;\nexport const ConnectionError = NetworkTimeoutError;\n","/**\n * Correlation ID generation.\n *\n * `globalThis.crypto` is unflagged from Node 19 onward and this package\n * declares `engines.node >= 20`, so `randomUUID` is normally present. It is\n * still feature-detected rather than assumed, because `engines` is advisory:\n * npm warns and installs anyway, and the SDK also runs on Workers, Edge and\n * Bun, where the available crypto surface varies.\n *\n * Deliberately does NOT import `node:crypto`. That import is what breaks Edge\n * and Workers builds at bundle time, and a correlation ID is not a security\n * value, so there is nothing to gain from it.\n */\nexport function newCorrelationId(): string {\n const c = globalThis.crypto;\n if (typeof c?.randomUUID === 'function') return c.randomUUID();\n\n if (typeof c?.getRandomValues === 'function') {\n const b = c.getRandomValues(new Uint8Array(16));\n // RFC 4122 version (4) and variant bits. The `?? 0` guards satisfy\n // `noUncheckedIndexedAccess`; a 16-byte array always has these slots.\n b[6] = ((b[6] ?? 0) & 0x0f) | 0x40;\n b[8] = ((b[8] ?? 0) & 0x3f) | 0x80;\n const h = Array.from(b, (x) => x.toString(16).padStart(2, '0')).join('');\n return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;\n }\n\n // Last resort. Correlation IDs are for tracing only, never for security, so\n // Math.random is acceptable here and only here.\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {\n const r = (Math.random() * 16) | 0;\n return (ch === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n}\n"],"mappings":";AA6CA,IAAM,QAAQ,uBAAO,IAAI,kCAAkC;AAOpD,IAAM,aAAN,cAAyB,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYpC,OAAgB,YAA4B;AAAA;AAAA,EAE5C,OAAgB,cAAuB;AAAA;AAAA,EAG9B;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAAiB,UAA6B,CAAC,GAAG;AAC5D,UAAM,SAAS,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAS;AACjF,UAAM,OAAO;AACb,SAAK,OAAO,WAAW;AACvB,SAAK,OAAO,KAAK;AACjB,SAAK,YAAY,KAAK;AACtB,SAAK,gBAAgB,QAAQ,iBAAiB;AAC9C,WAAO,eAAe,MAAM,OAAO,EAAE,OAAO,MAAM,YAAY,MAAM,CAAC;AAGrE,WAAO,eAAe,MAAM,WAAW,SAAS;AAAA,EAClD;AAAA,EAEA,QAAiB,OAAO,WAAW,EAAE,UAA4B;AAC/D,QAAI,aAAa,QAAQ,OAAO,aAAa,SAAU,QAAO;AAG9D,QAAI,EAAE,SAAS,UAAW,QAAO;AACjC,UAAM,WAAY,KAAmD;AAErE,QAAI,aAAa,OAAW,QAAO;AAEnC,QAAI,aAAa,cAAe,QAAO;AACvC,UAAM,SAAU,SAA+B;AAC/C,WAAO,WAAW,YAAY,aAAa,QAAQ,QAAQ;AAAA,EAC7D;AACF;AAGO,SAAS,aAAa,GAA6B;AACxD,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,SAAS;AACzD;AAEO,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAClD,OAAyB,YAA4B;AAAA,EACrD,OAAyB,cAAuB;AAClD;AAEO,IAAM,sBAAN,cAAkC,WAAW;AAAA,EAClD,OAAyB,YAA4B;AAAA,EACrD,OAAyB,cAAuB;AAClD;AAIO,IAAM,sBAAN,cAAkC,oBAAoB;AAAA,EAC3D,OAAyB,YAA4B;AACvD;AAYO,IAAM,iBAAN,cAA6B,oBAAoB;AAAA,EACtD,OAAyB,YAA4B;AAAA,EAC5C;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,UAKI,CAAC,GACL;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,oBAAoB,QAAQ,qBAAqB;AACtD,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,YAAY,QAAQ,aAAa;AAAA,EACxC;AACF;AAEO,IAAM,0BAAN,cAAsC,oBAAoB;AAAA,EAC/D,OAAyB,YAA4B;AACvD;AAEO,IAAM,wBAAN,cAAoC,oBAAoB;AAAA,EAC7D,OAAyB,YAA4B;AAAA,EACrD,YAAY,UAAU,qBAAqB,UAA6B,CAAC,GAAG;AAC1E,UAAM,SAAS,OAAO;AAAA,EACxB;AACF;AAYO,IAAM,2BAAN,cAAuC,oBAAoB;AAAA,EAChE,OAAyB,YAA4B;AAAA,EAC5C;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA,EAEA;AAAA,EAET,YACE,SACA,UAOI,CAAC,GACL;AACA,UAAM,SAAS,OAAO;AACtB,SAAK,iBAAiB,QAAQ,kBAAkB;AAChD,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,cAAc,QAAQ,eAAe;AAC1C,SAAK,YAAY,QAAQ,aAAa;AACtC,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,YAAY,QAAQ,aAAa;AAAA,EACxC;AACF;AAEO,IAAM,oBAAN,cAAgC,oBAAoB;AAAA,EACzD,OAAyB,YAA4B;AACvD;AAMO,IAAM,yBAAN,cAAqC,kBAAkB;AAAA,EAC5D,OAAyB,YAA4B;AACvD;AAGO,IAAM,6BAAN,cAAyC,kBAAkB;AAAA,EAChE,OAAyB,YAA4B;AACvD;AAEO,IAAM,sBAAN,cAAkC,oBAAoB;AAAA,EAC3D,OAAyB,YAA4B;AACvD;AAEO,IAAM,uBAAN,cAAmC,oBAAoB;AAAA,EAC5D,OAAyB,YAA4B;AACvD;AAEO,IAAM,gBAAN,cAA4B,oBAAoB;AAAA,EACrD,OAAyB,YAA4B;AACvD;AAEO,IAAM,0BAAN,cAAsC,cAAc;AAAA,EACzD,OAAyB,YAA4B;AACvD;AAEO,IAAM,sBAAN,cAAkC,oBAAoB;AAAA,EAC3D,OAAyB,YAA4B;AACvD;AAEO,IAAM,8BAAN,cAA0C,oBAAoB;AAAA,EACnE,OAAyB,YAA4B;AACvD;AAEO,IAAM,0BAAN,cAAsC,oBAAoB;AAAA,EAC/D,OAAyB,YAA4B;AACvD;AAIA,IAAM,SAA0D;AAAA,EAC9D,WAAW;AAAA,EACX,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,0BAA0B;AAAA,EAC1B,sBAAsB;AACxB;AAEA,SAAS,aAAa,QAA4B,UAA2B;AAC3E,MAAI,MAAM;AACV,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,OAAO,CAAC,KAAK,IAAI,GAAG,GAAG;AAC5B,SAAK,IAAI,GAAG;AACZ,QAAI,QAAQ,SAAU,QAAO;AAC7B,UAAM,OAAO,GAAG;AAAA,EAClB;AACA,SAAO;AACT;AAMO,IAAM,WAAW;AACjB,IAAM,iBAAiB;AACvB,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;;;ACnSxB,SAAS,mBAA2B;AACzC,QAAM,IAAI,WAAW;AACrB,MAAI,OAAO,GAAG,eAAe,WAAY,QAAO,EAAE,WAAW;AAE7D,MAAI,OAAO,GAAG,oBAAoB,YAAY;AAC5C,UAAM,IAAI,EAAE,gBAAgB,IAAI,WAAW,EAAE,CAAC;AAG9C,MAAE,CAAC,KAAM,EAAE,CAAC,KAAK,KAAK,KAAQ;AAC9B,MAAE,CAAC,KAAM,EAAE,CAAC,KAAK,KAAK,KAAQ;AAC9B,UAAM,IAAI,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACvE,WAAO,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;AAAA,EAChG;AAIA,SAAO,uCAAuC,QAAQ,SAAS,CAAC,OAAO;AACrE,UAAM,IAAK,KAAK,OAAO,IAAI,KAAM;AACjC,YAAQ,OAAO,MAAM,IAAK,IAAI,IAAO,GAAK,SAAS,EAAE;AAAA,EACvD,CAAC;AACH;","names":[]}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
-
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkT372OL3Qcjs = require('./chunk-T372OL3Q.cjs');
|
|
6
|
+
|
|
7
|
+
// src/grpc/descriptor.ts
|
|
8
|
+
var PROTO_SHA = "c1d834043608ad4f";
|
|
3
9
|
var SYNAP_PROTO_DESCRIPTOR = {
|
|
4
10
|
"nested": {
|
|
5
11
|
"synap": {
|
|
@@ -202,6 +208,14 @@ var SYNAP_PROTO_DESCRIPTOR = {
|
|
|
202
208
|
"type": "string",
|
|
203
209
|
"id": 11
|
|
204
210
|
},
|
|
211
|
+
"tool_result_json": {
|
|
212
|
+
"type": "string",
|
|
213
|
+
"id": 15
|
|
214
|
+
},
|
|
215
|
+
"tool_call_id": {
|
|
216
|
+
"type": "string",
|
|
217
|
+
"id": 16
|
|
218
|
+
},
|
|
205
219
|
"search_queries": {
|
|
206
220
|
"rule": "repeated",
|
|
207
221
|
"type": "string",
|
|
@@ -216,6 +230,14 @@ var SYNAP_PROTO_DESCRIPTOR = {
|
|
|
216
230
|
"keyType": "string",
|
|
217
231
|
"type": "string",
|
|
218
232
|
"id": 14
|
|
233
|
+
},
|
|
234
|
+
"event_id": {
|
|
235
|
+
"type": "string",
|
|
236
|
+
"id": 17
|
|
237
|
+
},
|
|
238
|
+
"sent_at_ms": {
|
|
239
|
+
"type": "int64",
|
|
240
|
+
"id": 18
|
|
219
241
|
}
|
|
220
242
|
}
|
|
221
243
|
},
|
|
@@ -257,7 +279,8 @@ var SYNAP_PROTO_DESCRIPTOR = {
|
|
|
257
279
|
"oneof": [
|
|
258
280
|
"context_bundle",
|
|
259
281
|
"heartbeat_pong",
|
|
260
|
-
"signal"
|
|
282
|
+
"signal",
|
|
283
|
+
"event_ack"
|
|
261
284
|
]
|
|
262
285
|
}
|
|
263
286
|
},
|
|
@@ -273,6 +296,23 @@ var SYNAP_PROTO_DESCRIPTOR = {
|
|
|
273
296
|
"signal": {
|
|
274
297
|
"type": "StreamSignal",
|
|
275
298
|
"id": 3
|
|
299
|
+
},
|
|
300
|
+
"event_ack": {
|
|
301
|
+
"type": "EventAck",
|
|
302
|
+
"id": 4
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
"EventAck": {
|
|
307
|
+
"fields": {
|
|
308
|
+
"event_ids": {
|
|
309
|
+
"rule": "repeated",
|
|
310
|
+
"type": "string",
|
|
311
|
+
"id": 1
|
|
312
|
+
},
|
|
313
|
+
"timestamp_ms": {
|
|
314
|
+
"type": "int64",
|
|
315
|
+
"id": 2
|
|
276
316
|
}
|
|
277
317
|
}
|
|
278
318
|
},
|
|
@@ -624,7 +664,66 @@ var BACKOFF_MAX_MS = 3e4;
|
|
|
624
664
|
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
625
665
|
var HEARTBEAT_TIMEOUT_MS = 1e4;
|
|
626
666
|
var MAX_MISSED_HEARTBEATS = 3;
|
|
667
|
+
var SEND_QUEUE_MAX_DEPTH = 100;
|
|
668
|
+
var CLOSE_GRACE_MS = 2e3;
|
|
669
|
+
var SEND_QUEUE_MAX_AGE_MS = 5 * 60 * 1e3;
|
|
627
670
|
var MIN_TTL_SECONDS = 60;
|
|
671
|
+
var GRPC_RESOURCE_EXHAUSTED = 8;
|
|
672
|
+
var CREDIT_ABORT_DETAILS = "insufficient_credits";
|
|
673
|
+
var CREDIT_STOP_REASONS = /* @__PURE__ */ new Set([
|
|
674
|
+
"overages_disabled",
|
|
675
|
+
"trial_limit_reached",
|
|
676
|
+
"subscription_inactive"
|
|
677
|
+
]);
|
|
678
|
+
function metadataValue(metadata, key) {
|
|
679
|
+
if (metadata === null || typeof metadata !== "object") return null;
|
|
680
|
+
const getter = metadata.get;
|
|
681
|
+
const raw = typeof getter === "function" ? getter.call(metadata, key) : metadata[key];
|
|
682
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
683
|
+
if (value === void 0 || value === null) return null;
|
|
684
|
+
const text = typeof value === "string" ? value : String(value);
|
|
685
|
+
return text === "" ? null : text;
|
|
686
|
+
}
|
|
687
|
+
function numberOrNull(value) {
|
|
688
|
+
if (value === null) return null;
|
|
689
|
+
const parsed = Number(value);
|
|
690
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
691
|
+
}
|
|
692
|
+
function creditErrorFromRpc(error, correlationId = null) {
|
|
693
|
+
if (error === null || typeof error !== "object") return null;
|
|
694
|
+
if (error.code !== GRPC_RESOURCE_EXHAUSTED) return null;
|
|
695
|
+
const metadata = error.metadata;
|
|
696
|
+
const reason = metadataValue(metadata, "credit-reason");
|
|
697
|
+
if (reason === null || !CREDIT_STOP_REASONS.has(reason)) return null;
|
|
698
|
+
const rawDetails = error.details;
|
|
699
|
+
const details = typeof rawDetails === "string" && rawDetails !== "" ? rawDetails : CREDIT_ABORT_DETAILS;
|
|
700
|
+
const requestId = _nullishCoalesce(metadataValue(metadata, "request-id"), () => ( correlationId));
|
|
701
|
+
const manageUrl = metadataValue(metadata, "credit-manage-url");
|
|
702
|
+
if (reason === "overages_disabled") {
|
|
703
|
+
return new (0, _chunkT372OL3Qcjs.InsufficientCreditsError)(details, {
|
|
704
|
+
correlationId: requestId,
|
|
705
|
+
balanceCredits: numberOrNull(metadataValue(metadata, "credit-balance")),
|
|
706
|
+
requiredCredits: numberOrNull(metadataValue(metadata, "credit-minimum-required")),
|
|
707
|
+
recoveryUrl: metadataValue(metadata, "credit-recovery-url"),
|
|
708
|
+
redeemUrl: metadataValue(metadata, "credit-redeem-url"),
|
|
709
|
+
reason,
|
|
710
|
+
manageUrl
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
return new (0, _chunkT372OL3Qcjs.RateLimitError)(details, {
|
|
714
|
+
correlationId: requestId,
|
|
715
|
+
reason,
|
|
716
|
+
upgradeUrl: metadataValue(metadata, "credit-upgrade-url"),
|
|
717
|
+
manageUrl
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
function isCreditStop(error) {
|
|
721
|
+
if (!(error instanceof _chunkT372OL3Qcjs.InsufficientCreditsError) && !(error instanceof _chunkT372OL3Qcjs.RateLimitError)) {
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
const reason = error.reason;
|
|
725
|
+
return typeof reason === "string" && CREDIT_STOP_REASONS.has(reason);
|
|
726
|
+
}
|
|
628
727
|
var GrpcStreamClient = class {
|
|
629
728
|
|
|
630
729
|
|
|
@@ -636,6 +735,16 @@ var GrpcStreamClient = class {
|
|
|
636
735
|
#missedHeartbeats = 0;
|
|
637
736
|
#heartbeatTimer = null;
|
|
638
737
|
#shutdownRequested = false;
|
|
738
|
+
// Events that could not be written because there was no stream.
|
|
739
|
+
#sendQueue = [];
|
|
740
|
+
// Events written to a live stream that the server has not acknowledged. The
|
|
741
|
+
// queue above covers "the stream was down"; this covers the half that
|
|
742
|
+
// actually loses sessions — the write succeeded, the stream broke before the
|
|
743
|
+
// server processed it, and nobody knows.
|
|
744
|
+
#unacked = /* @__PURE__ */ new Map();
|
|
745
|
+
// Why the stream stopped, when it stopped for a reason the caller can act on
|
|
746
|
+
// (today: a credit refusal). Mirrors Python's `last_error`.
|
|
747
|
+
#lastError = null;
|
|
639
748
|
#grpc = null;
|
|
640
749
|
#ServiceStub = null;
|
|
641
750
|
#credentials;
|
|
@@ -659,21 +768,149 @@ var GrpcStreamClient = class {
|
|
|
659
768
|
get isConnected() {
|
|
660
769
|
return this.#state === "connected";
|
|
661
770
|
}
|
|
771
|
+
/**
|
|
772
|
+
* The error that ended the stream, if one did.
|
|
773
|
+
*
|
|
774
|
+
* Set when the server refused the stream for credits, so an `onDisconnect`
|
|
775
|
+
* handler can read the balance, the reason and the URL to fix it. Null for an
|
|
776
|
+
* ordinary disconnect.
|
|
777
|
+
*/
|
|
778
|
+
get lastError() {
|
|
779
|
+
return this.#lastError;
|
|
780
|
+
}
|
|
662
781
|
async connect() {
|
|
663
782
|
await this.#loadGrpc();
|
|
664
783
|
this.#shutdownRequested = false;
|
|
784
|
+
this.#lastError = null;
|
|
665
785
|
await this.#establish();
|
|
666
786
|
this.#startHeartbeat();
|
|
667
787
|
}
|
|
668
788
|
async disconnect() {
|
|
669
789
|
this.#shutdownRequested = true;
|
|
670
790
|
this.#stopHeartbeat();
|
|
671
|
-
this.#
|
|
791
|
+
this.#flushBeforeClose();
|
|
792
|
+
const call = this.#call;
|
|
793
|
+
if (call !== null) {
|
|
794
|
+
try {
|
|
795
|
+
call.end();
|
|
796
|
+
} catch (e) {
|
|
797
|
+
}
|
|
798
|
+
await new Promise((resolve) => {
|
|
799
|
+
let settled = false;
|
|
800
|
+
const done = () => {
|
|
801
|
+
if (!settled) {
|
|
802
|
+
settled = true;
|
|
803
|
+
resolve();
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
const timer = setTimeout(() => {
|
|
807
|
+
const left = this.undelivered();
|
|
808
|
+
if (left.unacknowledged > 0 || left.queued > 0) {
|
|
809
|
+
console.warn(
|
|
810
|
+
`[synap] closing with ${left.queued} queued and ${left.unacknowledged} unacknowledged event(s) the server did not confirm within ${CLOSE_GRACE_MS}ms`
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
done();
|
|
814
|
+
}, CLOSE_GRACE_MS);
|
|
815
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
816
|
+
call.on("end", () => {
|
|
817
|
+
clearTimeout(timer);
|
|
818
|
+
done();
|
|
819
|
+
});
|
|
820
|
+
call.on("status", () => {
|
|
821
|
+
clearTimeout(timer);
|
|
822
|
+
done();
|
|
823
|
+
});
|
|
824
|
+
call.on("error", () => {
|
|
825
|
+
clearTimeout(timer);
|
|
826
|
+
done();
|
|
827
|
+
});
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
this.#call = null;
|
|
672
831
|
this.#setState("closed");
|
|
673
832
|
}
|
|
674
|
-
/**
|
|
833
|
+
/**
|
|
834
|
+
* What this client could not get to the server.
|
|
835
|
+
*
|
|
836
|
+
* Every send path returns void, so a caller had no way to tell a delivered
|
|
837
|
+
* turn from a lost one. Mirrors Python's `undelivered()`.
|
|
838
|
+
*/
|
|
839
|
+
undelivered() {
|
|
840
|
+
return { queued: this.#sendQueue.length, unacknowledged: this.#unacked.size };
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Never fails the caller's turn, and no longer loses it either.
|
|
844
|
+
*
|
|
845
|
+
* A write that cannot go out is buffered and replayed on reconnect, and a
|
|
846
|
+
* write that does go out is held until the server acknowledges it. Before
|
|
847
|
+
* this, both cases ended at a silent `return`.
|
|
848
|
+
*/
|
|
675
849
|
sendConversationEvent(event) {
|
|
676
|
-
|
|
850
|
+
const stamped = {
|
|
851
|
+
...event,
|
|
852
|
+
event_id: event.event_id && event.event_id !== "" ? event.event_id : _chunkT372OL3Qcjs.newCorrelationId.call(void 0, ),
|
|
853
|
+
sent_at_ms: _nullishCoalesce(event.sent_at_ms, () => ( Date.now()))
|
|
854
|
+
};
|
|
855
|
+
if (!this.isConnected || this.#call === null) {
|
|
856
|
+
this.#enqueue(stamped);
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
this.#write({ conversation_event: { ...stamped } });
|
|
860
|
+
this.#trackUnacked(stamped);
|
|
861
|
+
}
|
|
862
|
+
#enqueue(event) {
|
|
863
|
+
this.#pruneQueue();
|
|
864
|
+
if (this.#sendQueue.length >= SEND_QUEUE_MAX_DEPTH) {
|
|
865
|
+
const evicted = this.#sendQueue.shift();
|
|
866
|
+
console.warn(
|
|
867
|
+
`[synap] send queue full (max=${SEND_QUEUE_MAX_DEPTH}); dropping oldest event (event_type=${_optionalChain([evicted, 'optionalAccess', _ => _.event, 'access', _2 => _2.event_type])})`
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
this.#sendQueue.push({ queuedAt: Date.now(), event });
|
|
871
|
+
}
|
|
872
|
+
#pruneQueue() {
|
|
873
|
+
const cutoff = Date.now() - SEND_QUEUE_MAX_AGE_MS;
|
|
874
|
+
while (this.#sendQueue.length > 0 && (_nullishCoalesce(_optionalChain([this, 'access', _3 => _3.#sendQueue, 'access', _4 => _4[0], 'optionalAccess', _5 => _5.queuedAt]), () => ( 0))) < cutoff) {
|
|
875
|
+
const expired = this.#sendQueue.shift();
|
|
876
|
+
console.warn(
|
|
877
|
+
`[synap] queued event expired (age>${SEND_QUEUE_MAX_AGE_MS}ms); dropping (event_type=${_optionalChain([expired, 'optionalAccess', _6 => _6.event, 'access', _7 => _7.event_type])})`
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
#trackUnacked(event) {
|
|
882
|
+
const id = event.event_id;
|
|
883
|
+
if (id === void 0 || id === "") return;
|
|
884
|
+
const cutoff = Date.now() - SEND_QUEUE_MAX_AGE_MS;
|
|
885
|
+
for (const [oldestId, held] of this.#unacked) {
|
|
886
|
+
if (held.queuedAt >= cutoff && this.#unacked.size < SEND_QUEUE_MAX_DEPTH) break;
|
|
887
|
+
this.#unacked.delete(oldestId);
|
|
888
|
+
console.warn(
|
|
889
|
+
`[synap] unacknowledged event dropped: the server never confirmed it (event_type=${held.event.event_type})`
|
|
890
|
+
);
|
|
891
|
+
}
|
|
892
|
+
this.#unacked.set(id, { queuedAt: Date.now(), event });
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Replay what the server never confirmed, then what never went out.
|
|
896
|
+
*
|
|
897
|
+
* That order is the order things happened in: an unacked event was written
|
|
898
|
+
* to the previous stream, so it is older than anything that piled up while
|
|
899
|
+
* there was no stream at all. Safe to repeat — every event carries the id it
|
|
900
|
+
* was first sent with and the server drops a second sighting of it.
|
|
901
|
+
*/
|
|
902
|
+
#replayBuffered() {
|
|
903
|
+
const unacked = [...this.#unacked.values()];
|
|
904
|
+
const queued = this.#sendQueue;
|
|
905
|
+
this.#sendQueue = [];
|
|
906
|
+
for (const held of [...unacked, ...queued]) {
|
|
907
|
+
this.#write({ conversation_event: { ...held.event } });
|
|
908
|
+
}
|
|
909
|
+
if (unacked.length > 0 || queued.length > 0) {
|
|
910
|
+
console.warn(
|
|
911
|
+
`[synap] replayed ${unacked.length} unacknowledged and ${queued.length} queued event(s) after reconnect`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
677
914
|
}
|
|
678
915
|
sendSessionControl(input) {
|
|
679
916
|
this.#write({ session_control: { ...input } });
|
|
@@ -684,11 +921,26 @@ var GrpcStreamClient = class {
|
|
|
684
921
|
sendContextAssembled(event) {
|
|
685
922
|
this.#write({ context_assembled: { ...event } });
|
|
686
923
|
}
|
|
924
|
+
#flushBeforeClose() {
|
|
925
|
+
if (!this.isConnected || this.#call === null) {
|
|
926
|
+
if (this.#sendQueue.length > 0 || this.#unacked.size > 0) {
|
|
927
|
+
console.warn(
|
|
928
|
+
`[synap] closing with ${this.#sendQueue.length} queued and ${this.#unacked.size} unacknowledged event(s) and no stream to send them on; they are lost`
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
const queued = this.#sendQueue;
|
|
934
|
+
this.#sendQueue = [];
|
|
935
|
+
for (const held of queued) {
|
|
936
|
+
this.#write({ conversation_event: { ...held.event } });
|
|
937
|
+
}
|
|
938
|
+
}
|
|
687
939
|
#write(msg) {
|
|
688
940
|
if (!this.isConnected || this.#call === null) return;
|
|
689
941
|
try {
|
|
690
942
|
this.#call.write(msg);
|
|
691
|
-
} catch (
|
|
943
|
+
} catch (e2) {
|
|
692
944
|
}
|
|
693
945
|
}
|
|
694
946
|
async #loadGrpc() {
|
|
@@ -741,6 +993,11 @@ var GrpcStreamClient = class {
|
|
|
741
993
|
const call = stub["Listen"](metadata);
|
|
742
994
|
call.on("data", (msg) => this.#handleMessage(msg));
|
|
743
995
|
call.on("error", (err) => {
|
|
996
|
+
const creditError = creditErrorFromRpc(err);
|
|
997
|
+
if (creditError !== null) {
|
|
998
|
+
this.#handleCreditStop(creditError);
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
744
1001
|
void this.#handleDisconnect(`error: ${String(err)}`);
|
|
745
1002
|
});
|
|
746
1003
|
call.on("end", () => {
|
|
@@ -750,8 +1007,14 @@ var GrpcStreamClient = class {
|
|
|
750
1007
|
this.#setState("connected");
|
|
751
1008
|
this.#reconnectAttempts = 0;
|
|
752
1009
|
this.#lastPongAt = Date.now();
|
|
1010
|
+
this.#replayBuffered();
|
|
753
1011
|
}
|
|
754
1012
|
#handleMessage(msg) {
|
|
1013
|
+
const ack = msg["event_ack"];
|
|
1014
|
+
if (ack) {
|
|
1015
|
+
for (const id of _nullishCoalesce(ack.event_ids, () => ( []))) this.#unacked.delete(id);
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
755
1018
|
if (msg["context_bundle"]) {
|
|
756
1019
|
this.#handleBundle(msg["context_bundle"]);
|
|
757
1020
|
return;
|
|
@@ -762,7 +1025,7 @@ var GrpcStreamClient = class {
|
|
|
762
1025
|
return;
|
|
763
1026
|
}
|
|
764
1027
|
const signal = msg["signal"];
|
|
765
|
-
if (_optionalChain([signal, 'optionalAccess',
|
|
1028
|
+
if (_optionalChain([signal, 'optionalAccess', _8 => _8.signal_type]) === "closing") {
|
|
766
1029
|
void this.#handleDisconnect("server_signal_closing");
|
|
767
1030
|
}
|
|
768
1031
|
}
|
|
@@ -771,14 +1034,14 @@ var GrpcStreamClient = class {
|
|
|
771
1034
|
const conversationId = String(_nullishCoalesce(bundle["anticipation_conversation_id"], () => ( "")));
|
|
772
1035
|
if (bundleType !== UNCACHEABLE_BUNDLE_TYPE) this.#store(bundle, bundleType, conversationId);
|
|
773
1036
|
if (bundleType === "compaction_update" && conversationId !== "") {
|
|
774
|
-
_optionalChain([this, 'access',
|
|
1037
|
+
_optionalChain([this, 'access', _9 => _9.#options, 'access', _10 => _10.onCompactionUpdate, 'optionalCall', _11 => _11(conversationId, bundle)]);
|
|
775
1038
|
}
|
|
776
|
-
_optionalChain([this, 'access',
|
|
1039
|
+
_optionalChain([this, 'access', _12 => _12.#options, 'access', _13 => _13.onContext, 'optionalCall', _14 => _14(bundle)]);
|
|
777
1040
|
}
|
|
778
1041
|
#store(bundle, bundleType, conversationId) {
|
|
779
1042
|
const itemsByType = {};
|
|
780
1043
|
for (const [type, list] of Object.entries(_nullishCoalesce(bundle["items_by_type"], () => ( {})))) {
|
|
781
|
-
const items = _optionalChain([list, 'optionalAccess',
|
|
1044
|
+
const items = _optionalChain([list, 'optionalAccess', _15 => _15.items]);
|
|
782
1045
|
itemsByType[type] = _nullishCoalesce(items, () => ( []));
|
|
783
1046
|
}
|
|
784
1047
|
const ttlHint = Number(_nullishCoalesce(bundle["ttl_hint_seconds"], () => ( 0)));
|
|
@@ -803,6 +1066,20 @@ var GrpcStreamClient = class {
|
|
|
803
1066
|
]
|
|
804
1067
|
});
|
|
805
1068
|
}
|
|
1069
|
+
/**
|
|
1070
|
+
* End the stream because the server refused it for credits.
|
|
1071
|
+
*
|
|
1072
|
+
* Reconnecting cannot clear a credit refusal, so the stream closes and the
|
|
1073
|
+
* typed error is kept on `lastError` for the application to read. Mirrors
|
|
1074
|
+
* Python's `_handle_credit_stop`.
|
|
1075
|
+
*/
|
|
1076
|
+
#handleCreditStop(error) {
|
|
1077
|
+
this.#lastError = error;
|
|
1078
|
+
this.#shutdownRequested = true;
|
|
1079
|
+
this.#stopHeartbeat();
|
|
1080
|
+
this.#closeCall();
|
|
1081
|
+
this.#setState("disconnected");
|
|
1082
|
+
}
|
|
806
1083
|
async #handleDisconnect(_reason) {
|
|
807
1084
|
if (this.#shutdownRequested) return;
|
|
808
1085
|
this.#closeCall();
|
|
@@ -820,7 +1097,11 @@ var GrpcStreamClient = class {
|
|
|
820
1097
|
if (this.#shutdownRequested) return;
|
|
821
1098
|
try {
|
|
822
1099
|
await this.#establish();
|
|
823
|
-
} catch (
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
if (isCreditStop(error)) {
|
|
1102
|
+
this.#handleCreditStop(error);
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
824
1105
|
void this.#handleDisconnect("reconnect_failed");
|
|
825
1106
|
}
|
|
826
1107
|
}
|
|
@@ -841,7 +1122,7 @@ var GrpcStreamClient = class {
|
|
|
841
1122
|
void this.#handleDisconnect("heartbeat_write_error");
|
|
842
1123
|
}
|
|
843
1124
|
}, HEARTBEAT_INTERVAL_MS);
|
|
844
|
-
_optionalChain([this, 'access',
|
|
1125
|
+
_optionalChain([this, 'access', _16 => _16.#heartbeatTimer, 'access', _17 => _17.unref, 'optionalCall', _18 => _18()]);
|
|
845
1126
|
}
|
|
846
1127
|
#stopHeartbeat() {
|
|
847
1128
|
if (this.#heartbeatTimer !== null) {
|
|
@@ -851,19 +1132,23 @@ var GrpcStreamClient = class {
|
|
|
851
1132
|
}
|
|
852
1133
|
#closeCall() {
|
|
853
1134
|
try {
|
|
854
|
-
_optionalChain([this, 'access',
|
|
1135
|
+
_optionalChain([this, 'access', _19 => _19.#call, 'optionalAccess', _20 => _20.end, 'call', _21 => _21()]);
|
|
855
1136
|
} catch (e4) {
|
|
856
1137
|
}
|
|
857
1138
|
this.#call = null;
|
|
858
1139
|
}
|
|
859
1140
|
#setState(state) {
|
|
860
1141
|
this.#state = state;
|
|
861
|
-
_optionalChain([this, 'access',
|
|
1142
|
+
_optionalChain([this, 'access', _22 => _22.#options, 'access', _23 => _23.onStateChange, 'optionalCall', _24 => _24(state)]);
|
|
862
1143
|
}
|
|
863
1144
|
};
|
|
864
1145
|
|
|
865
1146
|
|
|
866
1147
|
|
|
867
1148
|
|
|
868
|
-
|
|
869
|
-
|
|
1149
|
+
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
exports.PROTO_SHA = PROTO_SHA; exports.CREDIT_ABORT_DETAILS = CREDIT_ABORT_DETAILS; exports.CREDIT_STOP_REASONS = CREDIT_STOP_REASONS; exports.creditErrorFromRpc = creditErrorFromRpc; exports.isCreditStop = isCreditStop; exports.GrpcStreamClient = GrpcStreamClient;
|
|
1154
|
+
//# sourceMappingURL=chunk-IA2N5NUY.cjs.map
|