@vinaverse/client 0.1.0-alpha.11 → 0.1.0-alpha.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/README.md +3 -1
- package/dist/agent/index.cjs +187 -24
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +3 -3
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +3 -3
- package/dist/backend/index.cjs +3 -0
- package/dist/backend/index.cjs.map +1 -1
- package/dist/backend/index.d.cts +3 -3
- package/dist/backend/index.d.ts +3 -3
- package/dist/backend/index.js +6 -3
- package/dist/backend/index.js.map +1 -1
- package/dist/{chunk-46D3FSLU.js → chunk-5HKZB2CJ.js} +14 -6
- package/dist/chunk-5HKZB2CJ.js.map +1 -0
- package/dist/{chunk-GWLLUOFY.js → chunk-LAB2FPXF.js} +31 -8
- package/dist/chunk-LAB2FPXF.js.map +1 -0
- package/dist/{chunk-JI6HUXH3.js → chunk-WOMAGTI5.js} +149 -20
- package/dist/chunk-WOMAGTI5.js.map +1 -0
- package/dist/conversation/index.cjs +40 -9
- package/dist/conversation/index.cjs.map +1 -1
- package/dist/conversation/index.d.cts +4 -4
- package/dist/conversation/index.d.ts +4 -4
- package/dist/conversation/index.js +3 -3
- package/dist/history/index.cjs +7 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +10 -4
- package/dist/history/index.d.ts +10 -4
- package/dist/history/index.js +10 -5
- package/dist/history/index.js.map +1 -1
- package/dist/index.cjs +29 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{runtime-CNgz2_8G.d.ts → runtime-44JlV32O.d.ts} +92 -14
- package/dist/{runtime-6O0qIPmo.d.cts → runtime-DWiB-XHX.d.cts} +92 -14
- package/dist/{session-D0ijOQX3.d.ts → session-lPGrKdhf.d.cts} +5 -0
- package/dist/{session-D0ijOQX3.d.cts → session-lPGrKdhf.d.ts} +5 -0
- package/dist/{store-CGRSxVcL.d.ts → store-Cjw9YmXA.d.ts} +6 -1
- package/dist/{store-CxoHwd64.d.cts → store-D-an5vch.d.cts} +6 -1
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-46D3FSLU.js.map +0 -1
- package/dist/chunk-GWLLUOFY.js.map +0 -1
- package/dist/chunk-JI6HUXH3.js.map +0 -1
package/README.md
CHANGED
|
@@ -183,7 +183,9 @@ against the session it was given in; a reply restored from the device or a resum
|
|
|
183
183
|
`{ screen: 'other' }`, no entity); revisions only grow across a conversation's sessions (`placeRevision` on the
|
|
184
184
|
session request), a `context_conflict` (409, with `current_revision`) sends the newest place once more above it, only while the session
|
|
185
185
|
and the person are the same, then says `moved`,
|
|
186
|
-
and a telling lands only on the session it was told to.
|
|
186
|
+
and a telling lands only on the session it was told to. One update is in flight per conversation: a place told meanwhile
|
|
187
|
+
(`show` and `tell` in one move, rapid moves) waits, only the newest, and goes next; a refusal that is no conflict is said
|
|
188
|
+
through `onWarning` (`context_refused`) in development builds. `onEvent` also says `message_sent`, `reply_completed` and
|
|
187
189
|
`card_shown` (never the words), its `key` is a salted SHA-256 hash of the conversation's key (`hashKey`), never the person's id: stable per install
|
|
188
190
|
(the salt is kept at `<persistenceKey>:salt` in your storage, a new one after `erase()`), and
|
|
189
191
|
`session_opened` says where the chat was opened from (`entryPoint`: `launcher`, `ask`, `deep_link`, or your own).
|
package/dist/agent/index.cjs
CHANGED
|
@@ -19,7 +19,8 @@ var CARD_KINDS = {
|
|
|
19
19
|
question: true,
|
|
20
20
|
proposal: true,
|
|
21
21
|
next_step: true,
|
|
22
|
-
links: true
|
|
22
|
+
links: true,
|
|
23
|
+
anchor: true
|
|
23
24
|
};
|
|
24
25
|
function isKnownCard(card) {
|
|
25
26
|
return Object.hasOwn(CARD_KINDS, card.kind);
|
|
@@ -129,6 +130,11 @@ var RECONNECTABLE = /* @__PURE__ */ new Set(["server_restart"]);
|
|
|
129
130
|
var NEW_SESSION = /* @__PURE__ */ new Set(["idle", "expired", "limit_reached"]);
|
|
130
131
|
var str = (v) => typeof v === "string" ? v : void 0;
|
|
131
132
|
var ConversationEngine = class {
|
|
133
|
+
/** `now`: the clock a message is stamped by when the server gives no time. */
|
|
134
|
+
constructor(now = Date.now) {
|
|
135
|
+
this.now = now;
|
|
136
|
+
}
|
|
137
|
+
now;
|
|
132
138
|
sessionId = null;
|
|
133
139
|
conversationId = null;
|
|
134
140
|
connection = null;
|
|
@@ -317,7 +323,14 @@ var ConversationEngine = class {
|
|
|
317
323
|
case "message.staff": {
|
|
318
324
|
const id = str(event.message_id);
|
|
319
325
|
if (id !== void 0)
|
|
320
|
-
this.say(
|
|
326
|
+
this.say(
|
|
327
|
+
"staff",
|
|
328
|
+
str(event.text) ?? "",
|
|
329
|
+
`s:${id}`,
|
|
330
|
+
{},
|
|
331
|
+
void 0,
|
|
332
|
+
str(event.at)
|
|
333
|
+
);
|
|
321
334
|
return;
|
|
322
335
|
}
|
|
323
336
|
case "input.received": {
|
|
@@ -399,7 +412,9 @@ var ConversationEngine = class {
|
|
|
399
412
|
role,
|
|
400
413
|
str(item.text) ?? "",
|
|
401
414
|
transcriptKey(role, str(item.id), str(item.at)),
|
|
402
|
-
item.interrupted === true ? { partial: "interrupted" } : {}
|
|
415
|
+
item.interrupted === true ? { partial: "interrupted" } : {},
|
|
416
|
+
void 0,
|
|
417
|
+
str(item.at)
|
|
403
418
|
);
|
|
404
419
|
}
|
|
405
420
|
}
|
|
@@ -444,7 +459,8 @@ var ConversationEngine = class {
|
|
|
444
459
|
text2,
|
|
445
460
|
key,
|
|
446
461
|
partial ? { partial } : {},
|
|
447
|
-
at
|
|
462
|
+
at,
|
|
463
|
+
str(item.at)
|
|
448
464
|
);
|
|
449
465
|
else
|
|
450
466
|
this.messages = this.messages.map((m) => {
|
|
@@ -572,9 +588,16 @@ var ConversationEngine = class {
|
|
|
572
588
|
this.unqueue(id);
|
|
573
589
|
}
|
|
574
590
|
/** Adds a message once: a key already held (a frame seen twice) changes nothing. */
|
|
575
|
-
say(role, text2, key, extra = {}, seq) {
|
|
591
|
+
say(role, text2, key, extra = {}, seq, at) {
|
|
576
592
|
if (this.messages.some((m) => m.key === key)) return;
|
|
577
|
-
this.messages.push({
|
|
593
|
+
this.messages.push({
|
|
594
|
+
role,
|
|
595
|
+
text: text2,
|
|
596
|
+
key,
|
|
597
|
+
seq: seq ?? this.seq++,
|
|
598
|
+
...extra,
|
|
599
|
+
at: at || new Date(this.now()).toISOString()
|
|
600
|
+
});
|
|
578
601
|
}
|
|
579
602
|
/** The turn's streamed text, kept as the agent's message when the turn ends without its `message.completed`. */
|
|
580
603
|
cutOff(partial) {
|
|
@@ -1547,6 +1570,7 @@ function buildTimeline(input, previous) {
|
|
|
1547
1570
|
role: "person",
|
|
1548
1571
|
text: sent.text,
|
|
1549
1572
|
state: pending,
|
|
1573
|
+
at: sent.at,
|
|
1550
1574
|
...pending === "not_sent" ? {
|
|
1551
1575
|
rejection: rejection ?? {
|
|
1552
1576
|
code: state.refused[id] ?? "",
|
|
@@ -1598,7 +1622,8 @@ function messageItem(m) {
|
|
|
1598
1622
|
text: m.text,
|
|
1599
1623
|
state: m.received ? "delivered" : "sent",
|
|
1600
1624
|
...m.partial ? { partial: m.partial } : {},
|
|
1601
|
-
...m.refusal ? { refusal: true } : {}
|
|
1625
|
+
...m.refusal ? { refusal: true } : {},
|
|
1626
|
+
at: m.at
|
|
1602
1627
|
};
|
|
1603
1628
|
}
|
|
1604
1629
|
function equal(a, b) {
|
|
@@ -1632,7 +1657,9 @@ var OUTCOMES2 = /* @__PURE__ */ new Set([
|
|
|
1632
1657
|
]);
|
|
1633
1658
|
var ConversationStore = class {
|
|
1634
1659
|
options;
|
|
1635
|
-
engine = new ConversationEngine(
|
|
1660
|
+
engine = new ConversationEngine(
|
|
1661
|
+
() => this.options.clock?.now() ?? Date.now()
|
|
1662
|
+
);
|
|
1636
1663
|
session = null;
|
|
1637
1664
|
info = null;
|
|
1638
1665
|
getting = null;
|
|
@@ -1815,7 +1842,11 @@ var ConversationStore = class {
|
|
|
1815
1842
|
if ([...text2].length > MAX_TEXT)
|
|
1816
1843
|
throw new RangeError(`A message is at most ${MAX_TEXT} characters.`);
|
|
1817
1844
|
const id = (this.options.createId ?? randomId)();
|
|
1818
|
-
this.sent.set(id, {
|
|
1845
|
+
this.sent.set(id, {
|
|
1846
|
+
text: text2,
|
|
1847
|
+
order: lastOrder(this.engine.state()) + 0.5,
|
|
1848
|
+
at: new Date(this.options.clock?.now() ?? Date.now()).toISOString()
|
|
1849
|
+
});
|
|
1819
1850
|
this.tellActivity({ type: "message_sent", id });
|
|
1820
1851
|
if (!this.session) {
|
|
1821
1852
|
this.early.set(id, text2);
|
|
@@ -2456,6 +2487,65 @@ function shallowEqual(a, b) {
|
|
|
2456
2487
|
}
|
|
2457
2488
|
|
|
2458
2489
|
// src/agent/runtime.ts
|
|
2490
|
+
var ANCHOR_TYPES = /* @__PURE__ */ new Set([
|
|
2491
|
+
"booking",
|
|
2492
|
+
"rental",
|
|
2493
|
+
"professional",
|
|
2494
|
+
"workspace",
|
|
2495
|
+
"service",
|
|
2496
|
+
"class",
|
|
2497
|
+
"policy"
|
|
2498
|
+
]);
|
|
2499
|
+
function anchorRef(type, id) {
|
|
2500
|
+
return ANCHOR_TYPES.has(type) && /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/.test(id) ? { type, id } : null;
|
|
2501
|
+
}
|
|
2502
|
+
var JOINS = [
|
|
2503
|
+
768,
|
|
2504
|
+
879,
|
|
2505
|
+
6832,
|
|
2506
|
+
6911,
|
|
2507
|
+
7616,
|
|
2508
|
+
7679,
|
|
2509
|
+
8400,
|
|
2510
|
+
8447,
|
|
2511
|
+
65056,
|
|
2512
|
+
65071,
|
|
2513
|
+
8205,
|
|
2514
|
+
8205,
|
|
2515
|
+
65038,
|
|
2516
|
+
65039,
|
|
2517
|
+
127995,
|
|
2518
|
+
127999
|
|
2519
|
+
];
|
|
2520
|
+
var joins = (point) => {
|
|
2521
|
+
const c = point?.codePointAt(0) ?? -1;
|
|
2522
|
+
for (let i = 0; i < JOINS.length; i += 2)
|
|
2523
|
+
if (c >= JOINS[i] && c <= JOINS[i + 1]) return true;
|
|
2524
|
+
return false;
|
|
2525
|
+
};
|
|
2526
|
+
function entryLabel(label) {
|
|
2527
|
+
let out = "";
|
|
2528
|
+
let size = 0;
|
|
2529
|
+
const points = Array.from(label.trim());
|
|
2530
|
+
for (let i = 0; i < points.length; ) {
|
|
2531
|
+
let end = i + 1;
|
|
2532
|
+
while (end < points.length && (joins(points[end]) || points[end - 1] === "\u200D"))
|
|
2533
|
+
end++;
|
|
2534
|
+
if (size + end - i > 60) break;
|
|
2535
|
+
out += points.slice(i, end).join("");
|
|
2536
|
+
size += end - i;
|
|
2537
|
+
i = end;
|
|
2538
|
+
}
|
|
2539
|
+
return out || void 0;
|
|
2540
|
+
}
|
|
2541
|
+
function askAboutKey(key, place) {
|
|
2542
|
+
return { ...key, thread: `ask:${place.entity.type}:${place.entity.id}` };
|
|
2543
|
+
}
|
|
2544
|
+
function entryOf(entry) {
|
|
2545
|
+
if (!/^[a-z][a-z0-9_]{0,31}$/.test(entry.point)) return null;
|
|
2546
|
+
const label = entry.label === void 0 ? void 0 : entryLabel(entry.label);
|
|
2547
|
+
return label ? { point: entry.point, label } : { point: entry.point };
|
|
2548
|
+
}
|
|
2459
2549
|
var AgentRefusal = class extends Error {
|
|
2460
2550
|
constructor(kind, options = {}) {
|
|
2461
2551
|
super(
|
|
@@ -2590,6 +2680,7 @@ var samePlace = (a, b) => a?.screen === b?.screen && (a?.entity?.type ?? null) =
|
|
|
2590
2680
|
function usable(session, insecure) {
|
|
2591
2681
|
return typeof session.id === "string" && session.id !== "" && (insecure.realtime === true || /^wss:\/\//i.test(session.realtime_url ?? "")) && (insecure.turns === true || /^https:\/\//i.test(session.turns_url ?? "")) && Boolean(session.client_secret);
|
|
2592
2682
|
}
|
|
2683
|
+
var devBuild = () => globalThis.__DEV__ === true;
|
|
2593
2684
|
function warnInsecure(insecure, warn) {
|
|
2594
2685
|
if (!(insecure.realtime || insecure.turns)) return;
|
|
2595
2686
|
if (globalThis.__DEV__ === true) return;
|
|
@@ -2608,6 +2699,7 @@ function createAgentRuntime(options) {
|
|
|
2608
2699
|
};
|
|
2609
2700
|
const clock = options.clock ?? SYSTEM_CLOCK;
|
|
2610
2701
|
const keepAlive = options.keepAlive ?? "session";
|
|
2702
|
+
const graceMs = options.graceMs ?? 6e4;
|
|
2611
2703
|
const staleMs = options.statusStaleMs ?? 5 * 6e4;
|
|
2612
2704
|
const insecure = options.insecureAddresses ?? {};
|
|
2613
2705
|
warnInsecure(insecure, options.onWarning ?? ((m) => console.warn(m)));
|
|
@@ -2627,6 +2719,7 @@ function createAgentRuntime(options) {
|
|
|
2627
2719
|
changed();
|
|
2628
2720
|
};
|
|
2629
2721
|
let sessionName = null;
|
|
2722
|
+
const names = /* @__PURE__ */ new Map();
|
|
2630
2723
|
let generation = 0;
|
|
2631
2724
|
const keyOf = (key) => agentKey(key, options.agent ?? null);
|
|
2632
2725
|
const prefix = options.conversation?.persistenceKey ?? "vinaverse.agent";
|
|
@@ -2709,6 +2802,7 @@ function createAgentRuntime(options) {
|
|
|
2709
2802
|
if (!entry) return;
|
|
2710
2803
|
live.delete(k);
|
|
2711
2804
|
clearTimeout(entry.timer);
|
|
2805
|
+
clearTimeout(entry.grace);
|
|
2712
2806
|
entry.store.dispose();
|
|
2713
2807
|
emit({ type: "conversation_ended", key: k });
|
|
2714
2808
|
changed();
|
|
@@ -2734,7 +2828,9 @@ function createAgentRuntime(options) {
|
|
|
2734
2828
|
agent: options.agent ?? null,
|
|
2735
2829
|
place: entry.place,
|
|
2736
2830
|
placeRevision: ++entry.revision,
|
|
2737
|
-
entryPoint: entry.entryPoint
|
|
2831
|
+
entryPoint: entry.entryPoint,
|
|
2832
|
+
...options.sendAnchor && entry.anchor ? { anchor: entry.anchor } : {},
|
|
2833
|
+
...options.sendAnchor && entry.via ? { entry: entry.via } : {}
|
|
2738
2834
|
};
|
|
2739
2835
|
const { conversationId, openId, place: told } = asked;
|
|
2740
2836
|
let session;
|
|
@@ -2761,6 +2857,7 @@ function createAgentRuntime(options) {
|
|
|
2761
2857
|
const unsettled = reason === "unknown_open" ? String(field(error, "openId") ?? openId) : null;
|
|
2762
2858
|
update(entry, { failure, reason, code, openId: unsettled });
|
|
2763
2859
|
emit({ type: "session_failed", key: entry.key, failure, reason });
|
|
2860
|
+
if (entry.shown === 0) end(entry.key);
|
|
2764
2861
|
}
|
|
2765
2862
|
throw error;
|
|
2766
2863
|
}
|
|
@@ -2770,8 +2867,9 @@ function createAgentRuntime(options) {
|
|
|
2770
2867
|
if (session.conversation_id)
|
|
2771
2868
|
current.set(entry.key, session.conversation_id);
|
|
2772
2869
|
const name = session.agent?.display_name?.trim();
|
|
2773
|
-
if (name && name !== sessionName) {
|
|
2870
|
+
if (name && (name !== sessionName || names.get(key.mode) !== name)) {
|
|
2774
2871
|
sessionName = name;
|
|
2872
|
+
names.set(key.mode, name);
|
|
2775
2873
|
changed();
|
|
2776
2874
|
}
|
|
2777
2875
|
update(entry, {
|
|
@@ -2789,6 +2887,14 @@ function createAgentRuntime(options) {
|
|
|
2789
2887
|
sessionId: session.id,
|
|
2790
2888
|
...entry.entryPoint ? { from: entry.entryPoint } : {}
|
|
2791
2889
|
});
|
|
2890
|
+
if (entry.shown === 0) {
|
|
2891
|
+
if (entry.expiresAt === null || over(entry)) {
|
|
2892
|
+
end(entry.key);
|
|
2893
|
+
return session;
|
|
2894
|
+
}
|
|
2895
|
+
expireLater(entry);
|
|
2896
|
+
}
|
|
2897
|
+
if (!samePlace(told, entry.place)) tell(entry, {});
|
|
2792
2898
|
return session;
|
|
2793
2899
|
}
|
|
2794
2900
|
const kept = (k) => `${prefix}.${k}`;
|
|
@@ -2803,6 +2909,7 @@ function createAgentRuntime(options) {
|
|
|
2803
2909
|
live.clear();
|
|
2804
2910
|
current.clear();
|
|
2805
2911
|
sessionName = null;
|
|
2912
|
+
names.clear();
|
|
2806
2913
|
status = null;
|
|
2807
2914
|
reading = null;
|
|
2808
2915
|
statusState = NO_STATUS;
|
|
@@ -2908,18 +3015,31 @@ function createAgentRuntime(options) {
|
|
|
2908
3015
|
place: null,
|
|
2909
3016
|
told: null,
|
|
2910
3017
|
revision: 0,
|
|
3018
|
+
telling: false,
|
|
3019
|
+
queued: false,
|
|
2911
3020
|
entryPoint: null,
|
|
3021
|
+
anchor: null,
|
|
3022
|
+
via: null,
|
|
2912
3023
|
expiresAt: null,
|
|
2913
3024
|
shown: 0,
|
|
2914
3025
|
started: false,
|
|
2915
3026
|
suspended: false,
|
|
2916
3027
|
sentOnce: /* @__PURE__ */ new Set(),
|
|
2917
3028
|
timer: void 0,
|
|
3029
|
+
grace: void 0,
|
|
2918
3030
|
turns: /* @__PURE__ */ new Map(),
|
|
2919
3031
|
failedOpen: void 0
|
|
2920
3032
|
};
|
|
2921
3033
|
return entry;
|
|
2922
3034
|
}
|
|
3035
|
+
const suspend = (entry) => {
|
|
3036
|
+
clearTimeout(entry.grace);
|
|
3037
|
+
entry.grace = void 0;
|
|
3038
|
+
if (entry.shown > 0 || entry.suspended || live.get(entry.key) !== entry)
|
|
3039
|
+
return;
|
|
3040
|
+
entry.suspended = true;
|
|
3041
|
+
entry.store.setForeground(false);
|
|
3042
|
+
};
|
|
2923
3043
|
const over = (entry) => entry.expiresAt !== null && entry.expiresAt <= clock.now();
|
|
2924
3044
|
const expireLater = (entry) => {
|
|
2925
3045
|
clearTimeout(entry.timer);
|
|
@@ -2937,31 +3057,63 @@ function createAgentRuntime(options) {
|
|
|
2937
3057
|
const tell = (entry, at) => {
|
|
2938
3058
|
if (at.place !== void 0) entry.place = at.place;
|
|
2939
3059
|
if (at.entryPoint !== void 0) entry.entryPoint = at.entryPoint;
|
|
3060
|
+
if (at.anchor !== void 0)
|
|
3061
|
+
entry.anchor = at.anchor && anchorRef(at.anchor.type, at.anchor.id);
|
|
3062
|
+
if (at.entry !== void 0) entry.via = at.entry && entryOf(at.entry);
|
|
2940
3063
|
const sessionId = entry.state.sessionId;
|
|
2941
3064
|
const moved = sessionId !== null && !samePlace(entry.told, entry.place);
|
|
2942
3065
|
update(entry, { moved });
|
|
2943
3066
|
const updateContext = backend.updateContext?.bind(backend);
|
|
2944
3067
|
if (!moved || !updateContext || sessionId === null) return;
|
|
3068
|
+
if (entry.telling) {
|
|
3069
|
+
entry.queued = true;
|
|
3070
|
+
return;
|
|
3071
|
+
}
|
|
3072
|
+
entry.telling = true;
|
|
2945
3073
|
const asked = generation;
|
|
2946
3074
|
const current2 = () => asked === generation && live.get(entry.key) === entry && entry.state.sessionId === sessionId;
|
|
3075
|
+
const settle = () => {
|
|
3076
|
+
entry.telling = false;
|
|
3077
|
+
if (!entry.queued) return;
|
|
3078
|
+
entry.queued = false;
|
|
3079
|
+
if (asked === generation && live.get(entry.key) === entry)
|
|
3080
|
+
tell(entry, {});
|
|
3081
|
+
};
|
|
2947
3082
|
const send = (again) => {
|
|
2948
3083
|
const place = entry.place;
|
|
2949
3084
|
const revision = ++entry.revision;
|
|
2950
|
-
|
|
3085
|
+
let told;
|
|
3086
|
+
try {
|
|
3087
|
+
told = updateContext(sessionId, place ?? CLEARED, revision);
|
|
3088
|
+
} catch (error) {
|
|
3089
|
+
told = Promise.reject(error);
|
|
3090
|
+
}
|
|
3091
|
+
told.then(
|
|
2951
3092
|
() => {
|
|
2952
|
-
if (
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
3093
|
+
if (current2() && entry.revision === revision) {
|
|
3094
|
+
entry.told = place;
|
|
3095
|
+
update(entry, { moved: !samePlace(entry.told, entry.place) });
|
|
3096
|
+
emit({ type: "context_updated", key: entry.key, sessionId });
|
|
3097
|
+
}
|
|
3098
|
+
settle();
|
|
2956
3099
|
},
|
|
2957
3100
|
(error) => {
|
|
2958
3101
|
const theirs = field(error, "currentRevision");
|
|
2959
3102
|
const conflict = field(error, "outcome") === "context_conflict" || field(error, "reason") === "conflict";
|
|
2960
|
-
if (
|
|
3103
|
+
if (conflict && !again && current2() && entry.revision === revision) {
|
|
3104
|
+
if (typeof theirs === "number" && theirs >= entry.revision)
|
|
3105
|
+
entry.revision = theirs;
|
|
3106
|
+
send(true);
|
|
2961
3107
|
return;
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
3108
|
+
}
|
|
3109
|
+
if (!conflict && devBuild()) {
|
|
3110
|
+
const status2 = field(error, "status");
|
|
3111
|
+
warn(
|
|
3112
|
+
`@vinaverse/client/agent: updateContext was refused${typeof status2 === "number" ? ` (${status2})` : ""}: ${error instanceof Error ? error.message : String(error)}. The new place is offered as a question instead.`,
|
|
3113
|
+
{ code: "context_refused" }
|
|
3114
|
+
);
|
|
3115
|
+
}
|
|
3116
|
+
settle();
|
|
2965
3117
|
}
|
|
2966
3118
|
);
|
|
2967
3119
|
};
|
|
@@ -2980,6 +3132,8 @@ function createAgentRuntime(options) {
|
|
|
2980
3132
|
entry.shown++;
|
|
2981
3133
|
clearTimeout(entry.timer);
|
|
2982
3134
|
entry.timer = void 0;
|
|
3135
|
+
clearTimeout(entry.grace);
|
|
3136
|
+
entry.grace = void 0;
|
|
2983
3137
|
if (entry.suspended) {
|
|
2984
3138
|
entry.suspended = false;
|
|
2985
3139
|
entry.store.setForeground(true);
|
|
@@ -2995,12 +3149,15 @@ function createAgentRuntime(options) {
|
|
|
2995
3149
|
released = true;
|
|
2996
3150
|
entry.shown--;
|
|
2997
3151
|
if (entry.shown > 0 || live.get(entry.key) !== entry) return;
|
|
2998
|
-
|
|
3152
|
+
const status2 = entry.store.getSnapshot().status;
|
|
3153
|
+
const opening = status2 === "starting" && keepAlive !== "view";
|
|
3154
|
+
if (!opening && (keepAlive === "view" || NOT_KEPT.has(status2) || entry.expiresAt === null || over(entry))) {
|
|
2999
3155
|
end(entry.key);
|
|
3000
3156
|
return;
|
|
3001
3157
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3158
|
+
if (graceMs > 0)
|
|
3159
|
+
entry.grace = setTimeout(() => suspend(entry), graceMs);
|
|
3160
|
+
else suspend(entry);
|
|
3004
3161
|
expireLater(entry);
|
|
3005
3162
|
};
|
|
3006
3163
|
},
|
|
@@ -3070,6 +3227,9 @@ function createAgentRuntime(options) {
|
|
|
3070
3227
|
forget(key) {
|
|
3071
3228
|
forget(keyOf(key));
|
|
3072
3229
|
},
|
|
3230
|
+
background() {
|
|
3231
|
+
for (const entry of live.values()) if (entry.grace) suspend(entry);
|
|
3232
|
+
},
|
|
3073
3233
|
sweep() {
|
|
3074
3234
|
for (const entry of [...live.values()])
|
|
3075
3235
|
if (entry.shown === 0 && over(entry)) end(entry.key);
|
|
@@ -3128,7 +3288,7 @@ function createAgentRuntime(options) {
|
|
|
3128
3288
|
getStatusState: () => statusState,
|
|
3129
3289
|
backend,
|
|
3130
3290
|
epoch: () => generation,
|
|
3131
|
-
getName: () => sessionName ?? status?.value.displayName ?? null,
|
|
3291
|
+
getName: (mode) => (mode === void 0 ? sessionName : names.get(mode)) ?? status?.value.displayName ?? null,
|
|
3132
3292
|
subscribe(listener) {
|
|
3133
3293
|
listeners.add(listener);
|
|
3134
3294
|
return () => listeners.delete(listener);
|
|
@@ -3312,7 +3472,10 @@ async function retrying(run, policy, signal, onRetry) {
|
|
|
3312
3472
|
|
|
3313
3473
|
exports.AgentRefusal = AgentRefusal;
|
|
3314
3474
|
exports.agentKey = agentKey;
|
|
3475
|
+
exports.anchorRef = anchorRef;
|
|
3476
|
+
exports.askAboutKey = askAboutKey;
|
|
3315
3477
|
exports.createAgentRuntime = createAgentRuntime;
|
|
3478
|
+
exports.entryLabel = entryLabel;
|
|
3316
3479
|
exports.greetedKey = greetedKey;
|
|
3317
3480
|
exports.hashKey = hashKey;
|
|
3318
3481
|
exports.isRefusal = isRefusal;
|