@ai-matrx/chat 0.4.20 → 0.4.22
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/CHANGELOG.md +21 -0
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.d.ts +7 -0
- package/dist/agents/components/inputs/smart-input/InboxQueueStrip.js +61 -6
- package/dist/agents/components/memory/hooks/useAgentMemories.d.ts +6 -6
- package/dist/agents/components/messages-display/user/AgentUserMessage.js +5 -2
- package/dist/agents/redux/execution-system/inbox/inbox.selectors.d.ts +3 -1
- package/dist/agents/redux/execution-system/inbox/inbox.selectors.js +3 -0
- package/dist/agents/redux/execution-system/inbox/inbox.slice.d.ts +19 -1
- package/dist/agents/redux/execution-system/inbox/inbox.slice.js +36 -1
- package/dist/agents/redux/execution-system/thunks/process-stream.js +2 -2
- package/dist/agents/redux/tools/tools.selectors.d.ts +84 -84
- package/dist/agents/redux/tools/tools.thunks.d.ts +14 -14
- package/dist/host/db-types.d.ts +3 -51998
- package/dist/ui/mandates-storage/mandateStorage.d.ts +276 -276
- package/dist/ui/mandates-storage/shortcutStorage.d.ts +970 -970
- package/dist/utils/client-lazy.d.ts +1 -16
- package/dist/utils/client-lazy.js +1 -22
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
+
## 0.4.22
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/chat/v0.4.21..npm/chat/v0.4.22 -- apps/shared/chat`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.4.21 — Queued lines show their wait and their delivery
|
|
10
|
+
|
|
11
|
+
- The waiting-messages strip shows how long each queued line has waited (a live 1 s timer), and
|
|
12
|
+
when the agent takes a line it flashes "Delivered · waited 12s" for 1.6 s before clearing.
|
|
13
|
+
New slice actions `deliverInboxItem` / `clearDeliveredInboxItem` and selector
|
|
14
|
+
`selectDeliveredInboxItems`; delivery still leaves the queue exactly like a removal, so
|
|
15
|
+
`selectInboxItemStatus` reads `null` on delivery as before. Ported from the browser extension.
|
|
16
|
+
|
|
17
|
+
## 0.4.21
|
|
18
|
+
|
|
19
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
20
|
+
`git diff npm/chat/v0.4.20..npm/chat/v0.4.21 -- apps/shared/chat`).
|
|
21
|
+
No source changes intended and no consumer action required.
|
|
22
|
+
|
|
3
23
|
## 0.4.20 — The credential capture card moves into the package
|
|
4
24
|
|
|
5
25
|
- New `@ai-matrx/chat/agents/ui-first-tools/ui/CredentialCaptureCard`: the one card for an agent
|
|
@@ -1616,3 +1636,4 @@ First release. Phases 0 and 1 of
|
|
|
1616
1636
|
declared in the export map, so importing one fails honestly instead of resolving to a
|
|
1617
1637
|
half-built screen. `./native` is reserved for the first real React Native consumer (C25).
|
|
1618
1638
|
|
|
1639
|
+
|
|
@@ -20,6 +20,13 @@ import React from "react";
|
|
|
20
20
|
interface InboxQueueStripProps {
|
|
21
21
|
conversationId: string;
|
|
22
22
|
}
|
|
23
|
+
/** How long a delivered line keeps its "Delivered" moment before it clears (ms). */
|
|
24
|
+
export declare const DELIVERED_LINGER_MS = 1600;
|
|
25
|
+
/**
|
|
26
|
+
* How long a line has waited — kit's `compact` elapsed voice, floored to whole
|
|
27
|
+
* seconds and rounded DOWN so the 1 s ticker never shows time that has not passed.
|
|
28
|
+
*/
|
|
29
|
+
export declare function waitedLabel(fromIso: string, toMs: number): string;
|
|
23
30
|
/**
|
|
24
31
|
* Delivered collab notes are prefixed "[Collaboration note] Agent '<name>' …"
|
|
25
32
|
* server-side; the queued text carries the same prefix. Pull the agent name
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import React, { useState } from "react";
|
|
3
|
+
import React, { useEffect, useState } from "react";
|
|
4
|
+
import { formatDurationSeconds } from "@ai-matrx/kit/format";
|
|
4
5
|
import {
|
|
5
6
|
ArrowUp,
|
|
7
|
+
Check,
|
|
6
8
|
CircleHelp,
|
|
7
9
|
Clock,
|
|
8
10
|
Handshake,
|
|
@@ -19,7 +21,10 @@ import {
|
|
|
19
21
|
TooltipContent,
|
|
20
22
|
TooltipTrigger
|
|
21
23
|
} from "@ai-matrx/design-system";
|
|
22
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
selectDeliveredInboxItems,
|
|
26
|
+
selectInboxItems
|
|
27
|
+
} from "../../../redux/execution-system/inbox/inbox.selectors.js";
|
|
23
28
|
import { TERMINAL_RUNTIME_STATUSES } from "../../../runtime-reconnect/types.js";
|
|
24
29
|
import { selectIsExecuting } from "../../../redux/execution-system/selectors/aggregate.selectors.js";
|
|
25
30
|
import {
|
|
@@ -29,11 +34,27 @@ import {
|
|
|
29
34
|
editInboxItem
|
|
30
35
|
} from "../../../redux/execution-system/inbox/inbox.thunks.js";
|
|
31
36
|
import {
|
|
37
|
+
clearDeliveredInboxItem,
|
|
32
38
|
removeInboxItem
|
|
33
39
|
} from "../../../redux/execution-system/inbox/inbox.slice.js";
|
|
34
40
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
35
41
|
import { useConversationAbilities } from "../../../redux/execution-system/host-conversations/conversation-abilities.js";
|
|
36
42
|
const queueActionClassName = "h-11 w-11 min-h-11 min-w-11 shrink-0 rounded p-0 text-muted-foreground hover:bg-muted hover:text-foreground lg:h-8 lg:w-8 lg:min-h-8 lg:min-w-8";
|
|
43
|
+
const DELIVERED_LINGER_MS = 1600;
|
|
44
|
+
function waitedLabel(fromIso, toMs) {
|
|
45
|
+
const seconds = Math.max(0, Math.floor((toMs - Date.parse(fromIso)) / 1e3));
|
|
46
|
+
return formatDurationSeconds(seconds, { style: "compact", round: "down" });
|
|
47
|
+
}
|
|
48
|
+
function useSecondTicker(active) {
|
|
49
|
+
const [now, setNow] = useState(() => Date.now());
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!active) return;
|
|
52
|
+
setNow(Date.now());
|
|
53
|
+
const id = setInterval(() => setNow(Date.now()), 1e3);
|
|
54
|
+
return () => clearInterval(id);
|
|
55
|
+
}, [active]);
|
|
56
|
+
return now;
|
|
57
|
+
}
|
|
37
58
|
function statusLabel(item, running) {
|
|
38
59
|
if (item.status === "failed") return item.error ?? "Failed to send";
|
|
39
60
|
if (item.status === "sending") return "Sending\u2026";
|
|
@@ -71,7 +92,22 @@ function InboxQueueStripBody({ conversationId }) {
|
|
|
71
92
|
/* @__PURE__ */ new Set()
|
|
72
93
|
);
|
|
73
94
|
const visible = items.filter((i) => i.isVisibleToUser || isCollabNoteItem(i));
|
|
74
|
-
|
|
95
|
+
const delivered = useAppSelector(selectDeliveredInboxItems(conversationId));
|
|
96
|
+
const hasWaiting = visible.some(
|
|
97
|
+
(i) => (i.status === "pending" || i.status === "sending") && !isCollabNoteItem(i)
|
|
98
|
+
);
|
|
99
|
+
const now = useSecondTicker(hasWaiting);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (delivered.length === 0) return;
|
|
102
|
+
const timers = delivered.map(
|
|
103
|
+
(d) => setTimeout(
|
|
104
|
+
() => dispatch(clearDeliveredInboxItem({ conversationId, injectionId: d.injectionId })),
|
|
105
|
+
Math.max(0, DELIVERED_LINGER_MS - (Date.now() - Date.parse(d.deliveredAt)))
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
return () => timers.forEach(clearTimeout);
|
|
109
|
+
}, [delivered, conversationId, dispatch]);
|
|
110
|
+
if (visible.length === 0 && delivered.length === 0) return null;
|
|
75
111
|
const isDeparting = (item) => !isCollabNoteItem(item) && (item.mode === "steer" || promotingIds.has(item.injectionId));
|
|
76
112
|
const departing = visible.filter(isDeparting);
|
|
77
113
|
const waiting = visible.filter((item) => !isDeparting(item));
|
|
@@ -142,13 +178,16 @@ function InboxQueueStripBody({ conversationId }) {
|
|
|
142
178
|
)
|
|
143
179
|
] }),
|
|
144
180
|
/* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
145
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */
|
|
181
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
146
182
|
"span",
|
|
147
183
|
{
|
|
148
184
|
tabIndex: 0,
|
|
149
185
|
role: "status",
|
|
150
186
|
className: `block truncate rounded-sm text-[11px] leading-4 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring lg:cursor-help ${failed ? "text-destructive" : "text-muted-foreground"}`,
|
|
151
|
-
children:
|
|
187
|
+
children: [
|
|
188
|
+
promoting ? "Sending\u2026" : statusLabel(item, running),
|
|
189
|
+
(item.status === "pending" || item.status === "sending") && !collabNote ? ` \xB7 ${waitedLabel(item.queuedAt, now)}` : null
|
|
190
|
+
]
|
|
152
191
|
}
|
|
153
192
|
) }),
|
|
154
193
|
/* @__PURE__ */ jsx(TooltipContent, { side: "top", className: "max-w-[20rem]", children: statusHelp })
|
|
@@ -262,6 +301,20 @@ function InboxQueueStripBody({ conversationId }) {
|
|
|
262
301
|
)
|
|
263
302
|
] }, item.injectionId);
|
|
264
303
|
}),
|
|
304
|
+
delivered.map((d) => /* @__PURE__ */ jsxs(
|
|
305
|
+
"div",
|
|
306
|
+
{
|
|
307
|
+
"data-inbox-delivered": "",
|
|
308
|
+
role: "status",
|
|
309
|
+
className: "flex min-w-0 items-center gap-2 rounded-lg border border-emerald-500/30 bg-emerald-500/[0.08] px-3 py-2 text-xs motion-safe:animate-out motion-safe:fade-out motion-safe:delay-1000 motion-safe:duration-500",
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 shrink-0 text-emerald-600 dark:text-emerald-400" }),
|
|
312
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-foreground", children: d.text }),
|
|
313
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: `Delivered \xB7 waited ${waitedLabel(d.queuedAt, Date.parse(d.deliveredAt))}` })
|
|
314
|
+
]
|
|
315
|
+
},
|
|
316
|
+
`delivered-${d.injectionId}`
|
|
317
|
+
)),
|
|
265
318
|
/* @__PURE__ */ jsx(
|
|
266
319
|
TextInputDialog,
|
|
267
320
|
{
|
|
@@ -296,6 +349,8 @@ function InboxQueueStripBody({ conversationId }) {
|
|
|
296
349
|
] });
|
|
297
350
|
}
|
|
298
351
|
export {
|
|
352
|
+
DELIVERED_LINGER_MS,
|
|
299
353
|
InboxQueueStrip,
|
|
300
|
-
parseCollabNoteAgent
|
|
354
|
+
parseCollabNoteAgent,
|
|
355
|
+
waitedLabel
|
|
301
356
|
};
|
|
@@ -19,7 +19,7 @@ export declare function useAgentMemories(): {
|
|
|
19
19
|
content: string;
|
|
20
20
|
created_at: string;
|
|
21
21
|
created_by: string | null;
|
|
22
|
-
custom_fields: import("
|
|
22
|
+
custom_fields: import("@ai-matrx/data/types").Json;
|
|
23
23
|
deleted_at: string | null;
|
|
24
24
|
expires_at: string | null;
|
|
25
25
|
id: string;
|
|
@@ -27,14 +27,14 @@ export declare function useAgentMemories(): {
|
|
|
27
27
|
key: string;
|
|
28
28
|
last_accessed_at: string | null;
|
|
29
29
|
memory_type: string;
|
|
30
|
-
metadata: import("
|
|
30
|
+
metadata: import("@ai-matrx/data/types").Json;
|
|
31
31
|
organization_id: string;
|
|
32
32
|
scope: string;
|
|
33
33
|
scope_id: string | null;
|
|
34
34
|
updated_at: string;
|
|
35
35
|
updated_by: string | null;
|
|
36
36
|
version: number;
|
|
37
|
-
visibility: import("
|
|
37
|
+
visibility: import("@ai-matrx/data/types").Database["platform"]["Enums"]["visibility"];
|
|
38
38
|
}[];
|
|
39
39
|
totalCount: number;
|
|
40
40
|
sortMode: MemorySortMode;
|
|
@@ -49,7 +49,7 @@ export declare function useAgentMemories(): {
|
|
|
49
49
|
content: string;
|
|
50
50
|
created_at: string;
|
|
51
51
|
created_by: string | null;
|
|
52
|
-
custom_fields: import("
|
|
52
|
+
custom_fields: import("@ai-matrx/data/types").Json;
|
|
53
53
|
deleted_at: string | null;
|
|
54
54
|
expires_at: string | null;
|
|
55
55
|
id: string;
|
|
@@ -57,14 +57,14 @@ export declare function useAgentMemories(): {
|
|
|
57
57
|
key: string;
|
|
58
58
|
last_accessed_at: string | null;
|
|
59
59
|
memory_type: string;
|
|
60
|
-
metadata: import("
|
|
60
|
+
metadata: import("@ai-matrx/data/types").Json;
|
|
61
61
|
organization_id: string;
|
|
62
62
|
scope: string;
|
|
63
63
|
scope_id: string | null;
|
|
64
64
|
updated_at: string;
|
|
65
65
|
updated_by: string | null;
|
|
66
66
|
version: number;
|
|
67
|
-
visibility: import("
|
|
67
|
+
visibility: import("@ai-matrx/data/types").Database["platform"]["Enums"]["visibility"];
|
|
68
68
|
} | null;
|
|
69
69
|
saving: boolean;
|
|
70
70
|
deletingId: string | null;
|
|
@@ -262,7 +262,7 @@ function AgentUserMessage({
|
|
|
262
262
|
}
|
|
263
263
|
);
|
|
264
264
|
}
|
|
265
|
-
const containerMargin = compact ? "" : "ml-12";
|
|
265
|
+
const containerMargin = compact || compactUserMessage ? "" : "ml-12";
|
|
266
266
|
return /* @__PURE__ */ jsxs(
|
|
267
267
|
"div",
|
|
268
268
|
{
|
|
@@ -287,7 +287,10 @@ function AgentUserMessage({
|
|
|
287
287
|
/* @__PURE__ */ jsx(
|
|
288
288
|
"div",
|
|
289
289
|
{
|
|
290
|
-
className: compactUserMessage ?
|
|
290
|
+
className: compactUserMessage ? (
|
|
291
|
+
// Tight: no inset from the left, and the markdown paragraph's own margins dropped.
|
|
292
|
+
"bg-muted rounded-md px-3 py-2 [&_.math-content-wrapper]:my-0 [&_p:last-child]:mb-0"
|
|
293
|
+
) : "bg-muted border border-border rounded-lg px-2 py-2",
|
|
291
294
|
"data-user-message-style": compactUserMessage ? "compact" : "card",
|
|
292
295
|
children: /* @__PURE__ */ jsxs("div", { className: "relative min-w-0", children: [
|
|
293
296
|
/* @__PURE__ */ jsxs(
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
* conversationInbox selectors — queued-while-running message cards.
|
|
3
3
|
*/
|
|
4
4
|
import type { ChatRootState } from "../../../../store/root-state.js";
|
|
5
|
-
import type { ConversationInboxItem } from "./inbox.slice.js";
|
|
5
|
+
import type { ConversationInboxItem, DeliveredInboxItem } from "./inbox.slice.js";
|
|
6
|
+
/** Lines the agent just took, still showing their "Delivered" moment. Stable empty reference. */
|
|
7
|
+
export declare const selectDeliveredInboxItems: (conversationId: string) => (state: ChatRootState) => DeliveredInboxItem[];
|
|
6
8
|
/** All queued items for a conversation, FIFO. Stable empty reference. */
|
|
7
9
|
export declare const selectInboxItems: (conversationId: string) => (state: ChatRootState) => ConversationInboxItem[];
|
|
8
10
|
/** Count of items still waiting (sending + pending). Primitive — no memo needed. */
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const EMPTY_ITEMS = [];
|
|
2
|
+
const EMPTY_DELIVERED = [];
|
|
3
|
+
const selectDeliveredInboxItems = (conversationId) => (state) => state.conversationInbox?.deliveredByConversationId?.[conversationId] ?? EMPTY_DELIVERED;
|
|
2
4
|
const selectInboxItems = (conversationId) => (state) => state.conversationInbox?.byConversationId[conversationId] ?? EMPTY_ITEMS;
|
|
3
5
|
const selectInboxWaitingCount = (conversationId) => (state) => {
|
|
4
6
|
const items = state.conversationInbox?.byConversationId[conversationId];
|
|
@@ -17,6 +19,7 @@ function isStrandablePersonLine(item) {
|
|
|
17
19
|
}
|
|
18
20
|
export {
|
|
19
21
|
isStrandablePersonLine,
|
|
22
|
+
selectDeliveredInboxItems,
|
|
20
23
|
selectInboxItemStatus,
|
|
21
24
|
selectInboxItems,
|
|
22
25
|
selectInboxWaitingCount
|
|
@@ -49,9 +49,20 @@ export interface ConversationInboxItem {
|
|
|
49
49
|
*/
|
|
50
50
|
source?: string | null;
|
|
51
51
|
}
|
|
52
|
+
/** A queued line the agent just took — shown as "Delivered" for a moment, then cleared. */
|
|
53
|
+
export interface DeliveredInboxItem {
|
|
54
|
+
injectionId: string;
|
|
55
|
+
text: string;
|
|
56
|
+
mode: InboxItemMode;
|
|
57
|
+
queuedAt: string;
|
|
58
|
+
/** ISO timestamp — when `injection_consumed` named it. */
|
|
59
|
+
deliveredAt: string;
|
|
60
|
+
}
|
|
52
61
|
export interface ConversationInboxState {
|
|
53
62
|
/** FIFO per conversation — order mirrors server `enqueued_seq`. */
|
|
54
63
|
byConversationId: Record<string, ConversationInboxItem[]>;
|
|
64
|
+
/** Items the stream just delivered, per conversation (the strip clears each after a beat). */
|
|
65
|
+
deliveredByConversationId?: Record<string, DeliveredInboxItem[]>;
|
|
55
66
|
}
|
|
56
67
|
export declare const addInboxItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<ConversationInboxItem, "conversationInbox/addInboxItem">, confirmInboxItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
57
68
|
conversationId: string;
|
|
@@ -68,7 +79,14 @@ export declare const addInboxItem: import("@reduxjs/toolkit").ActionCreatorWithP
|
|
|
68
79
|
}, "conversationInbox/setInboxItemText">, removeInboxItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
69
80
|
conversationId: string;
|
|
70
81
|
injectionId: string;
|
|
71
|
-
}, "conversationInbox/removeInboxItem">,
|
|
82
|
+
}, "conversationInbox/removeInboxItem">, deliverInboxItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
83
|
+
conversationId: string;
|
|
84
|
+
injectionId: string;
|
|
85
|
+
deliveredAt?: string;
|
|
86
|
+
}, "conversationInbox/deliverInboxItem">, clearDeliveredInboxItem: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
87
|
+
conversationId: string;
|
|
88
|
+
injectionId: string;
|
|
89
|
+
}, "conversationInbox/clearDeliveredInboxItem">, hydrateInboxItems: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
72
90
|
conversationId: string;
|
|
73
91
|
items: ConversationInboxItem[];
|
|
74
92
|
}, "conversationInbox/hydrateInboxItems">;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createSlice } from "@reduxjs/toolkit";
|
|
2
2
|
import { destroyInstance } from "../conversations/conversations.slice.js";
|
|
3
3
|
const initialState = {
|
|
4
|
-
byConversationId: {}
|
|
4
|
+
byConversationId: {},
|
|
5
|
+
deliveredByConversationId: {}
|
|
5
6
|
};
|
|
6
7
|
function bucket(state, conversationId) {
|
|
7
8
|
if (!state.byConversationId[conversationId]) {
|
|
@@ -64,6 +65,35 @@ const conversationInboxSlice = createSlice({
|
|
|
64
65
|
(i) => i.injectionId !== injectionId
|
|
65
66
|
);
|
|
66
67
|
},
|
|
68
|
+
/**
|
|
69
|
+
* The stream delivered an item (`injection_consumed`): it leaves the queue
|
|
70
|
+
* exactly like `removeInboxItem` (so `selectInboxItemStatus` reads null — the
|
|
71
|
+
* delivery ack), and a visible person line is remembered as just delivered.
|
|
72
|
+
*/
|
|
73
|
+
deliverInboxItem(state, action) {
|
|
74
|
+
const { conversationId, injectionId } = action.payload;
|
|
75
|
+
const items = state.byConversationId[conversationId];
|
|
76
|
+
const item = items?.find((i) => i.injectionId === injectionId);
|
|
77
|
+
if (!items || !item) return;
|
|
78
|
+
state.byConversationId[conversationId] = items.filter((i) => i.injectionId !== injectionId);
|
|
79
|
+
if (!item.isVisibleToUser || item.source === "agent_collab") return;
|
|
80
|
+
const delivered = state.deliveredByConversationId ??= {};
|
|
81
|
+
(delivered[conversationId] ??= []).push({
|
|
82
|
+
injectionId,
|
|
83
|
+
text: item.text,
|
|
84
|
+
mode: item.mode,
|
|
85
|
+
queuedAt: item.queuedAt,
|
|
86
|
+
deliveredAt: action.payload.deliveredAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
/** The "Delivered" moment is over — drop it. */
|
|
90
|
+
clearDeliveredInboxItem(state, action) {
|
|
91
|
+
const list = state.deliveredByConversationId?.[action.payload.conversationId];
|
|
92
|
+
if (!list) return;
|
|
93
|
+
state.deliveredByConversationId[action.payload.conversationId] = list.filter(
|
|
94
|
+
(i) => i.injectionId !== action.payload.injectionId
|
|
95
|
+
);
|
|
96
|
+
},
|
|
67
97
|
/**
|
|
68
98
|
* Replace the pending set from a server list (`GET …/inbox?status=pending`)
|
|
69
99
|
* — reopen-mid-run rehydration. Local `sending`/`failed` items are kept
|
|
@@ -80,6 +110,7 @@ const conversationInboxSlice = createSlice({
|
|
|
80
110
|
extraReducers: (builder) => {
|
|
81
111
|
builder.addCase(destroyInstance, (state, action) => {
|
|
82
112
|
delete state.byConversationId[action.payload];
|
|
113
|
+
delete state.deliveredByConversationId?.[action.payload];
|
|
83
114
|
});
|
|
84
115
|
}
|
|
85
116
|
});
|
|
@@ -89,13 +120,17 @@ const {
|
|
|
89
120
|
failInboxItem,
|
|
90
121
|
setInboxItemText,
|
|
91
122
|
removeInboxItem,
|
|
123
|
+
deliverInboxItem,
|
|
124
|
+
clearDeliveredInboxItem,
|
|
92
125
|
hydrateInboxItems
|
|
93
126
|
} = conversationInboxSlice.actions;
|
|
94
127
|
var inbox_slice_default = conversationInboxSlice.reducer;
|
|
95
128
|
export {
|
|
96
129
|
addInboxItem,
|
|
130
|
+
clearDeliveredInboxItem,
|
|
97
131
|
confirmInboxItem,
|
|
98
132
|
inbox_slice_default as default,
|
|
133
|
+
deliverInboxItem,
|
|
99
134
|
failInboxItem,
|
|
100
135
|
hydrateInboxItems,
|
|
101
136
|
removeInboxItem,
|
|
@@ -132,7 +132,7 @@ import {
|
|
|
132
132
|
hasDisplayableMessageContent,
|
|
133
133
|
refetchSingleMessage
|
|
134
134
|
} from "../message-crud/refetch-single-message.thunk.js";
|
|
135
|
-
import {
|
|
135
|
+
import { deliverInboxItem } from "../inbox/inbox.slice.js";
|
|
136
136
|
import {
|
|
137
137
|
selectConversationMessages,
|
|
138
138
|
selectMessageCount,
|
|
@@ -2034,7 +2034,7 @@ async function processStream({
|
|
|
2034
2034
|
}
|
|
2035
2035
|
for (const item of event.data.items ?? []) {
|
|
2036
2036
|
dispatch(
|
|
2037
|
-
|
|
2037
|
+
deliverInboxItem({
|
|
2038
2038
|
conversationId,
|
|
2039
2039
|
injectionId: item.injection_id
|
|
2040
2040
|
})
|