@maximem/synap-js-sdk 0.5.12 → 0.5.13
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/index.cjs +55 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/index.js +45 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -408,22 +408,40 @@ function isOutcomeUnknown(error) {
|
|
|
408
408
|
if (error instanceof _chunkUXNVTP4Dcjs.ConflictError) return false;
|
|
409
409
|
if (error instanceof _chunkUXNVTP4Dcjs.InsufficientCreditsError) return false;
|
|
410
410
|
if (error instanceof _chunkUXNVTP4Dcjs.ContextNotFoundError) return false;
|
|
411
|
-
if (error instanceof _chunkUXNVTP4Dcjs.NetworkTimeoutError) return true;
|
|
412
411
|
if (isConnectionRefusal(error)) return false;
|
|
412
|
+
if (error instanceof _chunkUXNVTP4Dcjs.NetworkTimeoutError) return true;
|
|
413
413
|
return true;
|
|
414
414
|
}
|
|
415
|
+
var CONNECTION_REFUSAL_CODES = /* @__PURE__ */ new Set([
|
|
416
|
+
"ECONNREFUSED",
|
|
417
|
+
"ENOTFOUND",
|
|
418
|
+
"EAI_AGAIN",
|
|
419
|
+
"ECONNRESET",
|
|
420
|
+
"EHOSTUNREACH"
|
|
421
|
+
]);
|
|
415
422
|
function isConnectionRefusal(error) {
|
|
416
|
-
|
|
417
|
-
|
|
423
|
+
let cur = error;
|
|
424
|
+
for (let depth = 0; depth < 4 && cur !== null && typeof cur === "object"; depth += 1) {
|
|
425
|
+
const code = cur.code;
|
|
426
|
+
if (typeof code === "string" && CONNECTION_REFUSAL_CODES.has(code)) return true;
|
|
427
|
+
cur = cur.cause;
|
|
428
|
+
}
|
|
429
|
+
return false;
|
|
418
430
|
}
|
|
419
431
|
function toTransportError(error, correlationId) {
|
|
420
432
|
if (error instanceof _chunkUXNVTP4Dcjs.SynapError) return error;
|
|
421
|
-
const name = _optionalChain([error, 'optionalAccess',
|
|
433
|
+
const name = _optionalChain([error, 'optionalAccess', _10 => _10.name]);
|
|
422
434
|
if (name === "AbortError" || name === "TimeoutError") {
|
|
423
435
|
return new (0, _chunkUXNVTP4Dcjs.NetworkTimeoutError)("Request timed out", { correlationId, cause: error });
|
|
424
436
|
}
|
|
437
|
+
if (isConnectionRefusal(error)) {
|
|
438
|
+
return new (0, _chunkUXNVTP4Dcjs.NetworkTimeoutError)(
|
|
439
|
+
`Connection failed: ${_nullishCoalesce(_optionalChain([error, 'optionalAccess', _11 => _11.message]), () => ( String(error)))}`,
|
|
440
|
+
{ correlationId, cause: error }
|
|
441
|
+
);
|
|
442
|
+
}
|
|
425
443
|
return new (0, _chunkUXNVTP4Dcjs.ServiceUnavailableError)(
|
|
426
|
-
`Network request failed: ${_nullishCoalesce(_optionalChain([error, 'optionalAccess',
|
|
444
|
+
`Network request failed: ${_nullishCoalesce(_optionalChain([error, 'optionalAccess', _12 => _12.message]), () => ( String(error)))}`,
|
|
427
445
|
{ correlationId, cause: error }
|
|
428
446
|
);
|
|
429
447
|
}
|
|
@@ -504,11 +522,11 @@ function stringOrNull(v) {
|
|
|
504
522
|
}
|
|
505
523
|
function withTimeout(ms, external) {
|
|
506
524
|
const controller = new AbortController();
|
|
507
|
-
const onExternalAbort = () => controller.abort(_optionalChain([external, 'optionalAccess',
|
|
525
|
+
const onExternalAbort = () => controller.abort(_optionalChain([external, 'optionalAccess', _13 => _13.reason]));
|
|
508
526
|
const timer = setTimeout(() => {
|
|
509
527
|
controller.abort(new (0, _chunkUXNVTP4Dcjs.NetworkTimeoutError)(`Timed out after ${ms}ms`));
|
|
510
528
|
}, ms);
|
|
511
|
-
_optionalChain([timer, 'access',
|
|
529
|
+
_optionalChain([timer, 'access', _14 => _14.unref, 'optionalCall', _15 => _15()]);
|
|
512
530
|
if (external) {
|
|
513
531
|
if (external.aborted) onExternalAbort();
|
|
514
532
|
else external.addEventListener("abort", onExternalAbort, { once: true });
|
|
@@ -517,7 +535,7 @@ function withTimeout(ms, external) {
|
|
|
517
535
|
signal: controller.signal,
|
|
518
536
|
dispose() {
|
|
519
537
|
clearTimeout(timer);
|
|
520
|
-
_optionalChain([external, 'optionalAccess',
|
|
538
|
+
_optionalChain([external, 'optionalAccess', _16 => _16.removeEventListener, 'call', _17 => _17("abort", onExternalAbort)]);
|
|
521
539
|
}
|
|
522
540
|
};
|
|
523
541
|
}
|
|
@@ -525,14 +543,14 @@ function sleep(ms, signal) {
|
|
|
525
543
|
if (ms <= 0) return Promise.resolve();
|
|
526
544
|
return new Promise((resolve, reject) => {
|
|
527
545
|
const timer = setTimeout(() => {
|
|
528
|
-
_optionalChain([signal, 'optionalAccess',
|
|
546
|
+
_optionalChain([signal, 'optionalAccess', _18 => _18.removeEventListener, 'call', _19 => _19("abort", onAbort)]);
|
|
529
547
|
resolve();
|
|
530
548
|
}, ms);
|
|
531
549
|
function onAbort() {
|
|
532
550
|
clearTimeout(timer);
|
|
533
|
-
reject(_nullishCoalesce(_optionalChain([signal, 'optionalAccess',
|
|
551
|
+
reject(_nullishCoalesce(_optionalChain([signal, 'optionalAccess', _20 => _20.reason]), () => ( new Error("Aborted"))));
|
|
534
552
|
}
|
|
535
|
-
_optionalChain([signal, 'optionalAccess',
|
|
553
|
+
_optionalChain([signal, 'optionalAccess', _21 => _21.addEventListener, 'call', _22 => _22("abort", onAbort, { once: true })]);
|
|
536
554
|
});
|
|
537
555
|
}
|
|
538
556
|
|
|
@@ -745,7 +763,7 @@ function retrievalOptionsOf(options) {
|
|
|
745
763
|
}
|
|
746
764
|
async function fetchContext(transport, scope, options = {}, hooks = {}) {
|
|
747
765
|
const startedAt = Date.now();
|
|
748
|
-
await _optionalChain([transport, 'access',
|
|
766
|
+
await _optionalChain([transport, 'access', _23 => _23.ready, 'optionalCall', _24 => _24()]);
|
|
749
767
|
await transport.checkCustomerId(
|
|
750
768
|
opt(options, "customer_id", "customerId"),
|
|
751
769
|
`${scope}.context.fetch`
|
|
@@ -755,11 +773,16 @@ async function fetchContext(transport, scope, options = {}, hooks = {}) {
|
|
|
755
773
|
const { contextMode } = scopeOptionsOf(scope, options);
|
|
756
774
|
const summaryMode = scope === "user" && contextMode === "conversation-summary";
|
|
757
775
|
const finish = (response2) => {
|
|
758
|
-
_optionalChain([hooks, 'access',
|
|
776
|
+
_optionalChain([hooks, 'access', _25 => _25.onResponse, 'optionalCall', _26 => _26(scope, options, response2)]);
|
|
759
777
|
return response2;
|
|
760
778
|
};
|
|
779
|
+
const conversationId = opt(options, "conversation_id", "conversationId");
|
|
780
|
+
const skipServerSt = conversationId ? _optionalChain([hooks, 'access', _27 => _27.skipServerShortTerm, 'optionalCall', _28 => _28(conversationId)]) === true : false;
|
|
761
781
|
const network = async () => {
|
|
762
|
-
const { endpoint, body } = buildFetchRequest(
|
|
782
|
+
const { endpoint, body } = buildFetchRequest(
|
|
783
|
+
scope,
|
|
784
|
+
skipServerSt ? { ...options, include_conversation_context: false } : options
|
|
785
|
+
);
|
|
763
786
|
const result = await transport.request(endpoint, { body });
|
|
764
787
|
return applyResponseShape(_nullishCoalesce(_optionalChain([result, 'optionalAccess', _29 => _29["context"]]), () => ( {})), responseShape);
|
|
765
788
|
};
|
|
@@ -1420,7 +1443,7 @@ function storedBatchRows(bodies, result) {
|
|
|
1420
1443
|
function createConversationNamespace(transport, subscribers = new CompactionSubscribers(), onWrite = () => {
|
|
1421
1444
|
}, onTurn = () => {
|
|
1422
1445
|
}, onFetched = () => {
|
|
1423
|
-
}, localShortTerm = { prompt: () => null, compacted: () => null }, agentModel = () => ({})) {
|
|
1446
|
+
}, localShortTerm = { prompt: () => null, compacted: () => null }, agentModel = () => ({}), fetchHooks = {}) {
|
|
1424
1447
|
const writesInFlight = /* @__PURE__ */ new Map();
|
|
1425
1448
|
const withTurnModel = (body, options) => {
|
|
1426
1449
|
const metadata = withAgentModel(
|
|
@@ -1527,7 +1550,7 @@ function createConversationNamespace(transport, subscribers = new CompactionSubs
|
|
|
1527
1550
|
async fetch(options = {}) {
|
|
1528
1551
|
const id = _nullishCoalesce(options.conversation_id, () => ( options.conversationId));
|
|
1529
1552
|
validateConversationId(id);
|
|
1530
|
-
const response = await fetchContext(transport, "conversation", options);
|
|
1553
|
+
const response = await fetchContext(transport, "conversation", options, fetchHooks);
|
|
1531
1554
|
onFetched(
|
|
1532
1555
|
response,
|
|
1533
1556
|
id,
|
|
@@ -1976,7 +1999,7 @@ function createInstanceNamespace(credentials, cache, onTurn, agentModel = () =>
|
|
|
1976
1999
|
}
|
|
1977
2000
|
|
|
1978
2001
|
// src/version.ts
|
|
1979
|
-
var SDK_VERSION = "0.5.
|
|
2002
|
+
var SDK_VERSION = "0.5.13";
|
|
1980
2003
|
|
|
1981
2004
|
// src/registry.ts
|
|
1982
2005
|
var instances = /* @__PURE__ */ new Map();
|
|
@@ -3799,6 +3822,14 @@ var SynapClient = (_class4 = class _SynapClient {
|
|
|
3799
3822
|
// user, customer and client fetches (the conversation fetch does its own
|
|
3800
3823
|
// through `onFetched`). Until 0.5.12 only the conversation fetch had it,
|
|
3801
3824
|
// so the same usage gave the model different context in JS.
|
|
3825
|
+
// Python's `_should_skip_server_st`: when this process already holds the
|
|
3826
|
+
// conversation's compaction and every turn after it, the server is told
|
|
3827
|
+
// not to assemble them again.
|
|
3828
|
+
skipServerShortTerm: (conversationId) => {
|
|
3829
|
+
if (!this.#isStAuthoritative()) return false;
|
|
3830
|
+
const entry = this.#shortTerm.get(conversationId);
|
|
3831
|
+
return entry !== null && entry.compactionId !== null && isComplete(entry);
|
|
3832
|
+
},
|
|
3802
3833
|
onResponse: (scope, options2, response) => {
|
|
3803
3834
|
if (scope === "conversation") return;
|
|
3804
3835
|
const o2 = options2;
|
|
@@ -3862,7 +3893,12 @@ var SynapClient = (_class4 = class _SynapClient {
|
|
|
3862
3893
|
reseed: (conversationId, response) => this.#reseedShortTerm(conversationId, response),
|
|
3863
3894
|
historyExcerpts: (conversationId, response, query) => this.#withHistoryExcerpts(conversationId, response, query)
|
|
3864
3895
|
},
|
|
3865
|
-
() => this.#agentModel
|
|
3896
|
+
() => this.#agentModel,
|
|
3897
|
+
// The same hooks as the other three scopes: the anticipation cache first,
|
|
3898
|
+
// as Python's conversation fetch does, and the audit events. Until 0.5.13
|
|
3899
|
+
// the conversation fetch was built without them, so every JS conversation
|
|
3900
|
+
// fetch was a billed round trip, including ones the stream had answered.
|
|
3901
|
+
this.#fetchHooks
|
|
3866
3902
|
);
|
|
3867
3903
|
this.memories = createMemoriesInterface(this.#transport, ({ userId, customerId }) => {
|
|
3868
3904
|
for (const id of /* @__PURE__ */ new Set([userId, customerId])) {
|
|
@@ -4476,7 +4512,7 @@ function resolveBaseUrl(options) {
|
|
|
4476
4512
|
function resolveCredentials(options) {
|
|
4477
4513
|
const apiKey = _nullishCoalesce(options.apiKey, () => ( _chunkZKOJDUN4cjs.getEnv.call(void 0, "SYNAP_API_KEY")));
|
|
4478
4514
|
if (!apiKey) {
|
|
4479
|
-
throw new (0, _chunkUXNVTP4Dcjs.
|
|
4515
|
+
throw new (0, _chunkUXNVTP4Dcjs.AuthenticationError)(
|
|
4480
4516
|
"No Synap API key found. Set SYNAP_API_KEY in your environment, or pass apiKey to the SynapClient constructor."
|
|
4481
4517
|
);
|
|
4482
4518
|
}
|