@maximem/synap-js-sdk 0.4.7 → 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 +14 -0
- package/dist/anticipation-cache-LRE3TLK4.cjs.map +1 -0
- package/dist/anticipation-cache-WLU4NMD5.js +14 -0
- package/dist/{chunk-ZU6ZC4SU.js → chunk-ASM2OIIG.js} +305 -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-3JSE64GW.cjs → chunk-IA2N5NUY.cjs} +315 -17
- package/dist/chunk-IA2N5NUY.cjs.map +1 -0
- package/dist/{chunk-6LDUDKHS.js → chunk-ODVOQOSO.js} +124 -8
- package/dist/chunk-ODVOQOSO.js.map +1 -0
- package/dist/{chunk-2TVL5IPQ.cjs → chunk-T372OL3Q.cjs} +41 -3
- package/dist/chunk-T372OL3Q.cjs.map +1 -0
- package/dist/{chunk-RB57I2IQ.cjs → chunk-T6U5PVAD.cjs} +125 -9
- package/dist/chunk-T6U5PVAD.cjs.map +1 -0
- 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 +8 -8
- 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 +6 -6
- package/dist/index.cjs +301 -173
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +102 -146
- package/dist/index.d.ts +102 -146
- package/dist/index.js +192 -64
- 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 +6 -1
- package/dist/anticipation-cache-ARYEEKMU.cjs +0 -10
- package/dist/anticipation-cache-ARYEEKMU.cjs.map +0 -1
- package/dist/anticipation-cache-BMVF5sXb.d.cts +0 -190
- package/dist/anticipation-cache-BMVF5sXb.d.ts +0 -190
- package/dist/anticipation-cache-H7HEVWQC.js +0 -10
- package/dist/chunk-2TVL5IPQ.cjs.map +0 -1
- package/dist/chunk-3JSE64GW.cjs.map +0 -1
- package/dist/chunk-6LDUDKHS.js.map +0 -1
- package/dist/chunk-OCMM2Z5P.js.map +0 -1
- package/dist/chunk-RB57I2IQ.cjs.map +0 -1
- package/dist/chunk-ZU6ZC4SU.js.map +0 -1
- package/dist/stream-client-6V4FGKZ3.js +0 -7
- package/dist/stream-client-PRTOH62B.cjs +0 -7
- package/dist/stream-client-PRTOH62B.cjs.map +0 -1
- /package/dist/{anticipation-cache-H7HEVWQC.js.map → anticipation-cache-WLU4NMD5.js.map} +0 -0
- /package/dist/{stream-client-6V4FGKZ3.js.map → stream-client-6OWRYOA4.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ANY_SCOPE,
|
|
3
|
+
AnticipationCache,
|
|
4
|
+
BM25,
|
|
5
|
+
CONTRACT,
|
|
6
|
+
THRESHOLDS,
|
|
7
|
+
isRecallQuery,
|
|
8
|
+
rungKey,
|
|
9
|
+
stem,
|
|
10
|
+
tokenize
|
|
11
|
+
} from "./chunk-ODVOQOSO.js";
|
|
12
|
+
import {
|
|
13
|
+
getEnv
|
|
14
|
+
} from "./chunk-QBCVMPGK.js";
|
|
1
15
|
import {
|
|
2
16
|
AgentUnavailableError,
|
|
3
17
|
AuthenticationError,
|
|
@@ -21,38 +35,9 @@ import {
|
|
|
21
35
|
SynapTransientError,
|
|
22
36
|
TranscriptConflictError,
|
|
23
37
|
TransientError,
|
|
24
|
-
isSynapError
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ANY_SCOPE,
|
|
28
|
-
AnticipationCache,
|
|
29
|
-
BM25,
|
|
30
|
-
CONTRACT,
|
|
31
|
-
THRESHOLDS,
|
|
32
|
-
isRecallQuery,
|
|
33
|
-
stem,
|
|
34
|
-
tokenize
|
|
35
|
-
} from "./chunk-6LDUDKHS.js";
|
|
36
|
-
import {
|
|
37
|
-
getEnv
|
|
38
|
-
} from "./chunk-QBCVMPGK.js";
|
|
39
|
-
|
|
40
|
-
// src/util/correlation.ts
|
|
41
|
-
function newCorrelationId() {
|
|
42
|
-
const c = globalThis.crypto;
|
|
43
|
-
if (typeof c?.randomUUID === "function") return c.randomUUID();
|
|
44
|
-
if (typeof c?.getRandomValues === "function") {
|
|
45
|
-
const b = c.getRandomValues(new Uint8Array(16));
|
|
46
|
-
b[6] = (b[6] ?? 0) & 15 | 64;
|
|
47
|
-
b[8] = (b[8] ?? 0) & 63 | 128;
|
|
48
|
-
const h = Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
49
|
-
return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20)}`;
|
|
50
|
-
}
|
|
51
|
-
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (ch) => {
|
|
52
|
-
const r = Math.random() * 16 | 0;
|
|
53
|
-
return (ch === "x" ? r : r & 3 | 8).toString(16);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
38
|
+
isSynapError,
|
|
39
|
+
newCorrelationId
|
|
40
|
+
} from "./chunk-BWMPKLFG.js";
|
|
56
41
|
|
|
57
42
|
// src/transport/endpoints.ts
|
|
58
43
|
var ENDPOINTS = {
|
|
@@ -422,6 +407,16 @@ function toTransportError(error, correlationId) {
|
|
|
422
407
|
{ correlationId, cause: error }
|
|
423
408
|
);
|
|
424
409
|
}
|
|
410
|
+
var CREDIT_ERRORS = /* @__PURE__ */ new Set(["insufficient_credits", "trial_limit_reached"]);
|
|
411
|
+
function creditPayload(parsed, detailObject) {
|
|
412
|
+
return detailObject ?? parsed;
|
|
413
|
+
}
|
|
414
|
+
function creditReason(payload) {
|
|
415
|
+
const reason = stringOrNull(payload["reason"]);
|
|
416
|
+
if (reason !== null) return reason;
|
|
417
|
+
const error = stringOrNull(payload["error"]);
|
|
418
|
+
return error !== null && CREDIT_ERRORS.has(error) ? error : null;
|
|
419
|
+
}
|
|
425
420
|
async function toHttpError(response, correlationId) {
|
|
426
421
|
const body = await response.text().catch(() => "");
|
|
427
422
|
let parsed = {};
|
|
@@ -443,14 +438,18 @@ async function toHttpError(response, correlationId) {
|
|
|
443
438
|
return new AuthenticationError(message, opts);
|
|
444
439
|
case 404:
|
|
445
440
|
return new ContextNotFoundError(message, opts);
|
|
446
|
-
case 402:
|
|
441
|
+
case 402: {
|
|
442
|
+
const credit = creditPayload(parsed, detailObject);
|
|
447
443
|
return new InsufficientCreditsError(message, {
|
|
448
444
|
...opts,
|
|
449
|
-
balanceCredits: numberOrNull(
|
|
450
|
-
requiredCredits: numberOrNull(
|
|
451
|
-
recoveryUrl: stringOrNull(
|
|
452
|
-
redeemUrl: stringOrNull(
|
|
445
|
+
balanceCredits: numberOrNull(credit["balance_credits"]),
|
|
446
|
+
requiredCredits: numberOrNull(credit["minimum_required_credits"]) ?? numberOrNull(credit["required_credits"]),
|
|
447
|
+
recoveryUrl: stringOrNull(credit["recovery_url"]),
|
|
448
|
+
redeemUrl: stringOrNull(credit["redeem_url"]),
|
|
449
|
+
reason: creditReason(credit),
|
|
450
|
+
manageUrl: stringOrNull(credit["manage_url"])
|
|
453
451
|
});
|
|
452
|
+
}
|
|
454
453
|
case 409:
|
|
455
454
|
if (detailObject !== null && detailObject["code"] === "transcript_conflict") {
|
|
456
455
|
return new TranscriptConflictError(message, opts);
|
|
@@ -459,9 +458,13 @@ async function toHttpError(response, correlationId) {
|
|
|
459
458
|
case 429: {
|
|
460
459
|
const header = response.headers.get("retry-after");
|
|
461
460
|
const retryAfter = header !== null && header.trim() !== "" ? Number(header) : null;
|
|
461
|
+
const credit = creditPayload(parsed, detailObject);
|
|
462
462
|
return new RateLimitError(message, {
|
|
463
463
|
...opts,
|
|
464
|
-
retryAfterSeconds: retryAfter !== null && Number.isFinite(retryAfter) ? retryAfter : null
|
|
464
|
+
retryAfterSeconds: retryAfter !== null && Number.isFinite(retryAfter) ? retryAfter : null,
|
|
465
|
+
reason: creditReason(credit),
|
|
466
|
+
upgradeUrl: stringOrNull(credit["upgrade_url"]),
|
|
467
|
+
manageUrl: stringOrNull(credit["manage_url"])
|
|
465
468
|
});
|
|
466
469
|
}
|
|
467
470
|
case 503:
|
|
@@ -1046,6 +1049,8 @@ function buildRecordMessageBody(options) {
|
|
|
1046
1049
|
};
|
|
1047
1050
|
const sessionId = either2(o2, "session_id", "sessionId");
|
|
1048
1051
|
if (sessionId !== void 0) body["session_id"] = sessionId;
|
|
1052
|
+
const scopePath = either2(o2, "scope_path", "scopePath");
|
|
1053
|
+
if (scopePath !== void 0) body["scope"] = scopePath;
|
|
1049
1054
|
return body;
|
|
1050
1055
|
}
|
|
1051
1056
|
function buildIngestTranscriptBody(options) {
|
|
@@ -1072,6 +1077,8 @@ function buildIngestTranscriptBody(options) {
|
|
|
1072
1077
|
if (options.metadata !== void 0) body["metadata"] = options.metadata;
|
|
1073
1078
|
if (startedAt !== void 0) body["started_at"] = startedAt;
|
|
1074
1079
|
if (endedAt !== void 0) body["ended_at"] = endedAt;
|
|
1080
|
+
const scopePath = either2(o2, "scope_path", "scopePath");
|
|
1081
|
+
if (scopePath !== void 0) body["scope"] = scopePath;
|
|
1075
1082
|
return body;
|
|
1076
1083
|
}
|
|
1077
1084
|
function buildCompactBody(options) {
|
|
@@ -1205,7 +1212,8 @@ function createConversationNamespace(transport, subscribers = new CompactionSubs
|
|
|
1205
1212
|
onFetched(
|
|
1206
1213
|
response,
|
|
1207
1214
|
id,
|
|
1208
|
-
options.user_id ?? options.userId
|
|
1215
|
+
options.user_id ?? options.userId,
|
|
1216
|
+
options.scope_path ?? options.scopePath
|
|
1209
1217
|
);
|
|
1210
1218
|
return response;
|
|
1211
1219
|
},
|
|
@@ -1370,8 +1378,24 @@ function thinkingMetadata(options) {
|
|
|
1370
1378
|
}
|
|
1371
1379
|
return md;
|
|
1372
1380
|
}
|
|
1381
|
+
var KNOWN_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
1382
|
+
"user_message",
|
|
1383
|
+
"assistant_message",
|
|
1384
|
+
"tool_call",
|
|
1385
|
+
"tool_result",
|
|
1386
|
+
"agent_thinking",
|
|
1387
|
+
"context_request",
|
|
1388
|
+
"context_fetch",
|
|
1389
|
+
"session_start",
|
|
1390
|
+
"session_end"
|
|
1391
|
+
]);
|
|
1392
|
+
function toolResultJson(result) {
|
|
1393
|
+
if (result === void 0 || result === null) return "";
|
|
1394
|
+
return typeof result === "string" ? result : JSON.stringify(result);
|
|
1395
|
+
}
|
|
1373
1396
|
function createInstanceNamespace(credentials, cache, onTurn) {
|
|
1374
1397
|
let client = null;
|
|
1398
|
+
const openSessions = /* @__PURE__ */ new Map();
|
|
1375
1399
|
let dispatchCompaction = null;
|
|
1376
1400
|
let applyCompaction = null;
|
|
1377
1401
|
const internals = {
|
|
@@ -1395,16 +1419,33 @@ function createInstanceNamespace(credentials, cache, onTurn) {
|
|
|
1395
1419
|
return client !== null && client.isConnected;
|
|
1396
1420
|
}
|
|
1397
1421
|
};
|
|
1422
|
+
function ensureSession(conversationId, userId, customerId) {
|
|
1423
|
+
if (!conversationId || !userId || client === null) return;
|
|
1424
|
+
if (openSessions.has(conversationId)) return;
|
|
1425
|
+
const sessionId = newCorrelationId();
|
|
1426
|
+
try {
|
|
1427
|
+
client.sendSessionControl({
|
|
1428
|
+
action: "start",
|
|
1429
|
+
session_id: sessionId,
|
|
1430
|
+
conversation_id: conversationId,
|
|
1431
|
+
...userId ? { user_id: userId } : {},
|
|
1432
|
+
...customerId ? { customer_id: customerId } : {}
|
|
1433
|
+
});
|
|
1434
|
+
openSessions.set(conversationId, sessionId);
|
|
1435
|
+
} catch {
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1398
1438
|
const namespace = {
|
|
1399
1439
|
async listen(options = {}) {
|
|
1400
1440
|
if (client !== null) {
|
|
1401
1441
|
throw new ListeningAlreadyActiveError("Listening is already active on this instance");
|
|
1402
1442
|
}
|
|
1403
|
-
const { GrpcStreamClient } = await import("./stream-client-
|
|
1443
|
+
const { GrpcStreamClient } = await import("./stream-client-6OWRYOA4.js");
|
|
1404
1444
|
const onContext = options.on_context ?? options.onContext;
|
|
1405
1445
|
const onDisconnect = options.on_disconnect ?? options.onDisconnect;
|
|
1406
1446
|
const onReconnect = options.on_reconnect ?? options.onReconnect;
|
|
1407
1447
|
let reconnectAttempts = 0;
|
|
1448
|
+
let stream = null;
|
|
1408
1449
|
const created = new GrpcStreamClient(credentials(), cache, {
|
|
1409
1450
|
host: options.host ?? getEnv("SYNAP_GRPC_HOST") ?? DEFAULT_GRPC_HOST,
|
|
1410
1451
|
port: options.port ?? envPort() ?? DEFAULT_GRPC_PORT,
|
|
@@ -1414,14 +1455,18 @@ function createInstanceNamespace(credentials, cache, onTurn) {
|
|
|
1414
1455
|
internals.onCompactionUpdate(conversationId, bundle);
|
|
1415
1456
|
},
|
|
1416
1457
|
onStateChange: (state) => {
|
|
1458
|
+
if (state !== "connected") openSessions.clear();
|
|
1417
1459
|
if (state === "reconnecting") {
|
|
1418
1460
|
reconnectAttempts += 1;
|
|
1419
1461
|
onReconnect?.(reconnectAttempts);
|
|
1420
1462
|
} else if (state === "disconnected") {
|
|
1421
|
-
|
|
1463
|
+
const stopped = stream?.lastError ?? null;
|
|
1464
|
+
const reason = stopped === null ? "stream disconnected" : `credit_stop:${stopped.reason ?? "unknown"}`;
|
|
1465
|
+
onDisconnect?.(reason);
|
|
1422
1466
|
}
|
|
1423
1467
|
}
|
|
1424
1468
|
});
|
|
1469
|
+
stream = created;
|
|
1425
1470
|
try {
|
|
1426
1471
|
await created.connect();
|
|
1427
1472
|
} catch (error) {
|
|
@@ -1435,29 +1480,58 @@ function createInstanceNamespace(credentials, cache, onTurn) {
|
|
|
1435
1480
|
},
|
|
1436
1481
|
async stop_listening() {
|
|
1437
1482
|
if (client === null) return;
|
|
1483
|
+
for (const conversationId of [...openSessions.keys()]) {
|
|
1484
|
+
await namespace.end_session(conversationId);
|
|
1485
|
+
}
|
|
1438
1486
|
const active = client;
|
|
1439
1487
|
client = null;
|
|
1440
1488
|
await active.disconnect();
|
|
1441
1489
|
},
|
|
1490
|
+
async end_session(conversationId) {
|
|
1491
|
+
const sessionId = openSessions.get(conversationId);
|
|
1492
|
+
if (sessionId === void 0 || client === null) return;
|
|
1493
|
+
openSessions.delete(conversationId);
|
|
1494
|
+
try {
|
|
1495
|
+
client.sendSessionControl({
|
|
1496
|
+
action: "end",
|
|
1497
|
+
session_id: sessionId,
|
|
1498
|
+
conversation_id: conversationId
|
|
1499
|
+
});
|
|
1500
|
+
} catch {
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1442
1503
|
async send_message(options) {
|
|
1443
1504
|
if (client === null) throw new ListeningNotActiveError("Listening is not active");
|
|
1444
1505
|
if (options.content === void 0) {
|
|
1445
1506
|
throw new ListeningNotActiveError("content is required");
|
|
1446
1507
|
}
|
|
1508
|
+
const eventType = options.event_type ?? options.eventType ?? "user_message";
|
|
1509
|
+
if (!KNOWN_EVENT_TYPES.has(eventType)) {
|
|
1510
|
+
throw new SynapError(
|
|
1511
|
+
`unknown event_type '${eventType}'. Expected one of: ` + [...KNOWN_EVENT_TYPES].sort().join(", ")
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1447
1514
|
const conversationId = options.conversation_id ?? options.conversationId ?? "";
|
|
1448
|
-
|
|
1515
|
+
ensureSession(
|
|
1449
1516
|
conversationId,
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1517
|
+
options.user_id ?? options.userId ?? "",
|
|
1518
|
+
options.customer_id ?? options.customerId ?? ""
|
|
1519
|
+
);
|
|
1520
|
+
if (eventType === "user_message" || eventType === "assistant_message") {
|
|
1521
|
+
onTurn?.({
|
|
1522
|
+
conversationId,
|
|
1523
|
+
role: options.role ?? "user",
|
|
1524
|
+
content: options.content
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1453
1527
|
client.sendConversationEvent({
|
|
1454
|
-
event_type:
|
|
1528
|
+
event_type: eventType,
|
|
1455
1529
|
content: options.content,
|
|
1456
1530
|
role: options.role ?? "user",
|
|
1457
1531
|
conversation_id: options.conversation_id ?? options.conversationId ?? "",
|
|
1458
1532
|
user_id: options.user_id ?? options.userId ?? "",
|
|
1459
1533
|
customer_id: options.customer_id ?? options.customerId ?? "",
|
|
1460
|
-
session_id: options.session_id ?? options.sessionId ?? "",
|
|
1534
|
+
session_id: options.session_id ?? options.sessionId ?? openSessions.get(conversationId) ?? "",
|
|
1461
1535
|
metadata: options.metadata ?? {},
|
|
1462
1536
|
timestamp_ms: Date.now(),
|
|
1463
1537
|
tool_name: options.tool_name ?? options.toolName ?? "",
|
|
@@ -1466,17 +1540,61 @@ function createInstanceNamespace(credentials, cache, onTurn) {
|
|
|
1466
1540
|
const a = options.tool_args ?? options.toolArgs;
|
|
1467
1541
|
return a === void 0 ? "" : JSON.stringify(a);
|
|
1468
1542
|
})(),
|
|
1543
|
+
tool_result_json: toolResultJson(options.tool_result ?? options.toolResult),
|
|
1544
|
+
tool_call_id: options.tool_call_id ?? options.toolCallId ?? "",
|
|
1469
1545
|
search_queries: options.search_queries ?? options.searchQueries ?? [],
|
|
1470
1546
|
context_types: options.context_types ?? options.contextTypes ?? []
|
|
1471
1547
|
});
|
|
1472
1548
|
},
|
|
1549
|
+
async record_tool_call(options) {
|
|
1550
|
+
await namespace.send_message({
|
|
1551
|
+
content: "",
|
|
1552
|
+
role: "assistant",
|
|
1553
|
+
event_type: "tool_call",
|
|
1554
|
+
tool_name: options.tool_name ?? options.toolName ?? "",
|
|
1555
|
+
...options.tool_args ?? options.toolArgs ? { tool_args: options.tool_args ?? options.toolArgs } : {},
|
|
1556
|
+
tool_call_id: options.tool_call_id ?? options.toolCallId ?? "",
|
|
1557
|
+
conversation_id: options.conversation_id ?? options.conversationId ?? "",
|
|
1558
|
+
user_id: options.user_id ?? options.userId ?? "",
|
|
1559
|
+
customer_id: options.customer_id ?? options.customerId ?? "",
|
|
1560
|
+
session_id: options.session_id ?? options.sessionId ?? "",
|
|
1561
|
+
metadata: options.metadata ?? {}
|
|
1562
|
+
});
|
|
1563
|
+
},
|
|
1564
|
+
async record_tool_result(options) {
|
|
1565
|
+
await namespace.send_message({
|
|
1566
|
+
content: "",
|
|
1567
|
+
role: "tool",
|
|
1568
|
+
event_type: "tool_result",
|
|
1569
|
+
tool_result: options.result,
|
|
1570
|
+
tool_name: options.tool_name ?? options.toolName ?? "",
|
|
1571
|
+
tool_call_id: options.tool_call_id ?? options.toolCallId ?? "",
|
|
1572
|
+
conversation_id: options.conversation_id ?? options.conversationId ?? "",
|
|
1573
|
+
user_id: options.user_id ?? options.userId ?? "",
|
|
1574
|
+
customer_id: options.customer_id ?? options.customerId ?? "",
|
|
1575
|
+
session_id: options.session_id ?? options.sessionId ?? "",
|
|
1576
|
+
metadata: options.metadata ?? {}
|
|
1577
|
+
});
|
|
1578
|
+
},
|
|
1473
1579
|
async record_thinking(options) {
|
|
1474
1580
|
if (client === null) throw new ListeningNotActiveError("Listening is not active");
|
|
1581
|
+
const conversationId = options.conversation_id ?? options.conversationId ?? "";
|
|
1582
|
+
ensureSession(
|
|
1583
|
+
conversationId,
|
|
1584
|
+
options.user_id ?? options.userId ?? "",
|
|
1585
|
+
options.customer_id ?? options.customerId ?? ""
|
|
1586
|
+
);
|
|
1475
1587
|
client.sendConversationEvent({
|
|
1476
1588
|
// Python emits reasoning as an `agent_thinking` conversation event.
|
|
1477
1589
|
event_type: "agent_thinking",
|
|
1478
1590
|
content: options.content,
|
|
1479
|
-
role
|
|
1591
|
+
// Deliberately no role. A thought is not the assistant's reply, and
|
|
1592
|
+
// this went out as 'assistant' from the day it shipped: the server
|
|
1593
|
+
// checked role before event_type, so every reasoning step any client
|
|
1594
|
+
// sent was filed as the final answer and the reasoning path never ran.
|
|
1595
|
+
// Sending no role is correct against both the fixed server and one that
|
|
1596
|
+
// has not been updated yet.
|
|
1597
|
+
role: "",
|
|
1480
1598
|
conversation_id: options.conversation_id ?? options.conversationId ?? "",
|
|
1481
1599
|
user_id: options.user_id ?? options.userId ?? "",
|
|
1482
1600
|
customer_id: options.customer_id ?? options.customerId ?? "",
|
|
@@ -1494,7 +1612,7 @@ function createInstanceNamespace(credentials, cache, onTurn) {
|
|
|
1494
1612
|
}
|
|
1495
1613
|
|
|
1496
1614
|
// src/version.ts
|
|
1497
|
-
var SDK_VERSION = "
|
|
1615
|
+
var SDK_VERSION = "0.5.1";
|
|
1498
1616
|
|
|
1499
1617
|
// src/registry.ts
|
|
1500
1618
|
var instances = /* @__PURE__ */ new Map();
|
|
@@ -1683,7 +1801,7 @@ function budgetRecentTurns(turns) {
|
|
|
1683
1801
|
return windowed;
|
|
1684
1802
|
}
|
|
1685
1803
|
function overlayLocalRecentTurns(response, store, conversationId, configured) {
|
|
1686
|
-
if (conversationId === void 0 || conversationId === "") return;
|
|
1804
|
+
if (conversationId === void 0 || conversationId === null || conversationId === "") return;
|
|
1687
1805
|
try {
|
|
1688
1806
|
const entry = store.get(conversationId);
|
|
1689
1807
|
if (entry === null) return;
|
|
@@ -1944,16 +2062,16 @@ function mergeUserSummary(response, bundle) {
|
|
|
1944
2062
|
|
|
1945
2063
|
// src/context/anticipated.ts
|
|
1946
2064
|
function scopeLookupParams(scope, params) {
|
|
1947
|
-
const { searchQuery, entityId, customerId, clientId, conversationId } = params;
|
|
2065
|
+
const { searchQuery, entityId, customerId, clientId, conversationId, scopeRung } = params;
|
|
1948
2066
|
switch (scope) {
|
|
1949
2067
|
case "conversation":
|
|
1950
|
-
return { searchQuery, entityId, customerId, clientId, conversationId };
|
|
2068
|
+
return { searchQuery, entityId, customerId, clientId, conversationId, scopeRung };
|
|
1951
2069
|
case "user":
|
|
1952
|
-
return { searchQuery, entityId, customerId, clientId };
|
|
2070
|
+
return { searchQuery, entityId, customerId, clientId, scopeRung };
|
|
1953
2071
|
case "customer":
|
|
1954
|
-
return { searchQuery, entityId: null, customerId, clientId };
|
|
2072
|
+
return { searchQuery, entityId: null, customerId, clientId, scopeRung };
|
|
1955
2073
|
case "client":
|
|
1956
|
-
return { searchQuery, entityId: null, customerId: null, clientId };
|
|
2074
|
+
return { searchQuery, entityId: null, customerId: null, clientId, scopeRung };
|
|
1957
2075
|
}
|
|
1958
2076
|
}
|
|
1959
2077
|
function buildAnticipationResponse(hit) {
|
|
@@ -1988,6 +2106,7 @@ function tryServeFromCache(cache, scope, params, maxItems) {
|
|
|
1988
2106
|
customerId: scoped.customerId ?? null,
|
|
1989
2107
|
clientId: scoped.clientId ?? null,
|
|
1990
2108
|
conversationId: scoped.conversationId ?? null,
|
|
2109
|
+
scopeRung: scoped.scopeRung ?? null,
|
|
1991
2110
|
maxItems
|
|
1992
2111
|
});
|
|
1993
2112
|
if (hit === null) return { response: null, hit: null };
|
|
@@ -2500,7 +2619,15 @@ var SynapClient = class {
|
|
|
2500
2619
|
entityId: o2["user_id"] ?? o2["userId"],
|
|
2501
2620
|
customerId: o2["customer_id"] ?? o2["customerId"],
|
|
2502
2621
|
clientId: this.#transport.currentCredentials().clientId || null,
|
|
2503
|
-
conversationId: o2["conversation_id"] ?? o2["conversationId"]
|
|
2622
|
+
conversationId: o2["conversation_id"] ?? o2["conversationId"],
|
|
2623
|
+
// The rung this read is addressed to, in the same words the server
|
|
2624
|
+
// stamped on the bundles it pushed. Without it the cache matched
|
|
2625
|
+
// on entity and conversation alone, so a bundle prefetched for one
|
|
2626
|
+
// rung answered a caller standing at another, entirely inside this
|
|
2627
|
+
// process and invisible to every server log.
|
|
2628
|
+
scopeRung: rungKey(
|
|
2629
|
+
o2["scope_path"] ?? o2["scopePath"]
|
|
2630
|
+
)
|
|
2504
2631
|
},
|
|
2505
2632
|
Number(o2["max_results"] ?? o2["maxResults"] ?? 10)
|
|
2506
2633
|
);
|
|
@@ -2545,9 +2672,9 @@ var SynapClient = class {
|
|
|
2545
2672
|
({ conversationId, role, content, timestamp }) => {
|
|
2546
2673
|
this.#shortTerm.appendTurn(conversationId, role, content, timestamp);
|
|
2547
2674
|
},
|
|
2548
|
-
(response, conversationId, userId) => {
|
|
2675
|
+
(response, conversationId, userId, scopePath) => {
|
|
2549
2676
|
overlayLocalRecentTurns(response, this.#shortTerm, conversationId, this.#stVerbatimOverlay);
|
|
2550
|
-
this.#injectUserSummary(response, conversationId, userId);
|
|
2677
|
+
this.#injectUserSummary(response, conversationId, userId, rungKey(scopePath));
|
|
2551
2678
|
},
|
|
2552
2679
|
{
|
|
2553
2680
|
prompt: (conversationId, style) => this.#localPrompt(conversationId, style),
|
|
@@ -2770,7 +2897,8 @@ var SynapClient = class {
|
|
|
2770
2897
|
};
|
|
2771
2898
|
const labels = [];
|
|
2772
2899
|
const tasks = [];
|
|
2773
|
-
|
|
2900
|
+
const present = (v) => v !== void 0 && v !== null && v !== "";
|
|
2901
|
+
if (present(conversationId) && wants("conversation")) {
|
|
2774
2902
|
labels.push("conversation");
|
|
2775
2903
|
tasks.push(this.conversation.context.fetch({
|
|
2776
2904
|
conversation_id: conversationId,
|
|
@@ -2779,7 +2907,7 @@ var SynapClient = class {
|
|
|
2779
2907
|
customer_id: customerId
|
|
2780
2908
|
}));
|
|
2781
2909
|
}
|
|
2782
|
-
if (userId
|
|
2910
|
+
if (present(userId) && wants("user")) {
|
|
2783
2911
|
labels.push("user");
|
|
2784
2912
|
tasks.push(this.user.context.fetch({
|
|
2785
2913
|
user_id: userId,
|
|
@@ -2791,7 +2919,7 @@ var SynapClient = class {
|
|
|
2791
2919
|
last_n_conversations: lastNConversations
|
|
2792
2920
|
}));
|
|
2793
2921
|
}
|
|
2794
|
-
if (customerId
|
|
2922
|
+
if (present(customerId) && wants("customer")) {
|
|
2795
2923
|
labels.push("customer");
|
|
2796
2924
|
tasks.push(this.customer.context.fetch({
|
|
2797
2925
|
customer_id: customerId,
|
|
@@ -2825,7 +2953,7 @@ var SynapClient = class {
|
|
|
2825
2953
|
for (const [, response] of successful) {
|
|
2826
2954
|
overlayLocalRecentTurns(response, this.#shortTerm, conversationId, this.#stVerbatimOverlay);
|
|
2827
2955
|
}
|
|
2828
|
-
if (includeConversationContext && conversationId
|
|
2956
|
+
if (includeConversationContext && present(conversationId)) {
|
|
2829
2957
|
try {
|
|
2830
2958
|
merged.conversation_context = await this.conversation.context.get_context_for_prompt({
|
|
2831
2959
|
conversation_id: conversationId
|
|
@@ -2912,11 +3040,11 @@ var SynapClient = class {
|
|
|
2912
3040
|
* cannot be scoped, and an unscoped lookup is how user A's summary ends up in
|
|
2913
3041
|
* user B's response.
|
|
2914
3042
|
*/
|
|
2915
|
-
#injectUserSummary(response, conversationId, userId) {
|
|
3043
|
+
#injectUserSummary(response, conversationId, userId, scopeRung) {
|
|
2916
3044
|
this.#turns.increment(conversationId);
|
|
2917
3045
|
if (userId === void 0 || userId === "") return;
|
|
2918
3046
|
if (!this.#turns.shouldInject(conversationId)) return;
|
|
2919
|
-
const summary = this.#anticipationCache.lookupUserSummary(userId);
|
|
3047
|
+
const summary = this.#anticipationCache.lookupUserSummary(userId, scopeRung);
|
|
2920
3048
|
if (summary === null) return;
|
|
2921
3049
|
mergeUserSummary(response, summary);
|
|
2922
3050
|
}
|