@ai-matrx/chat 0.7.6 → 0.7.8
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 +29 -0
- package/dist/agents/api/fetch-pending-calls.js +4 -3
- package/dist/agents/api/submit-tool-results.js +3 -6
- package/dist/agents/components/chat/begin-fresh-chat.js +2 -2
- package/dist/agents/components/inputs/smart-input/InputActionButtons.d.ts +2 -2
- package/dist/agents/components/inputs/smart-input/InputActionButtons.js +3 -1
- package/dist/agents/components/inputs/smart-input/SmartAgentInputStacked.js +8 -3
- package/dist/agents/components/inputs/smart-input/composer/ComposerSplash.js +2 -3
- package/dist/agents/components/inputs/smart-input/composer/useComposerMode.js +4 -2
- package/dist/agents/components/live-run/LiveRunDisplay.d.ts +7 -1
- package/dist/agents/components/live-run/LiveRunDisplay.js +3 -1
- package/dist/agents/components/messages-display/assistant/AssistantMessageFooter.js +4 -2
- package/dist/agents/components/shared/transcript-layout.d.ts +9 -8
- package/dist/agents/components/shared/transcript-layout.js +2 -2
- package/dist/agents/redux/agent-definition/agent-cache-bust-request.js +7 -7
- package/dist/agents/redux/execution-system/context-rules/receipt-check.js +2 -2
- package/dist/agents/redux/execution-system/inbox/inbox.thunks.d.ts +2 -2
- package/dist/agents/redux/execution-system/inbox/inbox.thunks.js +7 -15
- package/dist/agents/redux/execution-system/observational-memory/fetch-memory-cost.thunk.d.ts +1 -1
- package/dist/agents/redux/execution-system/observational-memory/fetch-memory-cost.thunk.js +7 -4
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +1 -114
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.js +28 -43
- package/dist/agents/redux/execution-system/thunks/call-conversation-api.d.ts +44 -0
- package/dist/agents/redux/execution-system/thunks/call-conversation-api.js +78 -0
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.d.ts +41 -0
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.js +66 -0
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.d.ts +20 -0
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +9 -2
- package/dist/agents/redux/execution-system/thunks/launch-agent-execution.thunk.js +4 -6
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.d.ts +1 -5
- package/dist/agents/redux/execution-system/thunks/notify-and-play-dispatcher.js +2 -1
- package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +7 -17
- package/dist/agents/redux/execution-system/thunks/settle-after-stop.thunk.js +2 -2
- package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +3 -3
- package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +8 -2
- package/dist/agents/redux/execution-system/utils/continuation-body.js +3 -3
- package/dist/agents/redux/execution-system/utils/required-organization.d.ts +18 -0
- package/dist/agents/redux/execution-system/utils/required-organization.js +14 -10
- package/dist/agents/services/mcp-connections.service.js +5 -8
- package/dist/agents/ui-first-tools/dispatcher/dispatch-ui-first-tool.thunk.js +2 -1
- package/dist/host/defaults/files-host.js +11 -1
- package/dist/host/defaults/server-api.d.ts +1 -15
- package/dist/host/defaults/server-api.js +0 -21
- package/dist/host/defaults/server.d.ts +2 -1
- package/dist/host/defaults/server.js +8 -6
- package/dist/host/request-headers.d.ts +26 -0
- package/dist/host/request-headers.js +17 -0
- package/dist/host/server/call-api.d.ts +0 -13
- package/dist/host/server/call-api.js +0 -2
- package/dist/host/server/matrx-transport.d.ts +0 -1
- package/dist/host/server/matrx-transport.js +0 -2
- package/dist/store/root-state.d.ts +4 -21
- package/dist/surfaces/hooks/useSurfaceConfig.js +2 -1
- package/dist/surfaces/manifests/agent-builder.manifest.d.ts +8 -0
- package/dist/surfaces/manifests/agent-builder.manifest.js +62 -2
- package/dist/surfaces/runtime/surface-feedback.js +2 -2
- package/dist/ui/mandates-storage/mandateStorage.d.ts +36 -0
- package/dist/ui/mandates-storage/shortcutStorage.d.ts +9 -0
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +22 -0
- package/dist/ui/markdown-stream/MarkdownStreamImpl.js +3 -3
- package/dist/ui/markdown-stream/StreamTextFallback.d.ts +6 -0
- package/dist/ui/markdown-stream/StreamTextFallback.js +23 -0
- package/dist/ui/markdown-stream/merge-thinking-across-hidden.d.ts +19 -0
- package/dist/ui/markdown-stream/merge-thinking-across-hidden.js +21 -0
- package/package.json +16 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
+
## 0.7.8
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/chat/v0.7.7..npm/chat/v0.7.8 -- apps/shared/chat`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.7.7
|
|
10
|
+
### Unreleased
|
|
11
|
+
|
|
12
|
+
- **`continueAgentJson`** (`agents/redux/execution-system/thunks/continue-agent-json`): the NEXT turn of a
|
|
13
|
+
conversation whose first turn ran headlessly, waited on like the first (`adoptHeadlessAgentJson`). A turn is
|
|
14
|
+
the person's words (`userInput`) or a turn the HOST writes (`hostTurn` — sent as `host_turn`, never
|
|
15
|
+
`user_input`); per-turn structured content rides `context` (`null` removes a key). A conversation not in the
|
|
16
|
+
tab yet is read first. `executeInstance` takes `hostTurn` (continuations only; the empty-turn rule lets it
|
|
17
|
+
through). Lane F6b: the Applet builder's build, fix rounds, changes and replies are one conversation. Test:
|
|
18
|
+
`a-host-turn-continues-the-conversation.test.ts`. **Consumer action:** none.
|
|
19
|
+
- `MarkdownStream`'s stand-in (shown while the app's lazy rich-content host loads, and after a render error)
|
|
20
|
+
reads the request's own answer text when no `content` was passed, and says "Loading…" while it has none —
|
|
21
|
+
it used to print "No content available" over a finished answer, so an Applet run read "Done — No content
|
|
22
|
+
available" on a slow network (lane F8, live Applet audit 2026-10-09). `StreamTextFallback`. Test:
|
|
23
|
+
`the-fallback-never-hides-a-finished-answer.test.tsx` (red on the old stand-in). **Consumer action:** none.
|
|
24
|
+
- Where machine frames are hidden (an Expert, an Applet visitor), thinking runs separated only by settled
|
|
25
|
+
tool calls render as ONE thinking block — live slots and reloaded segments alike
|
|
26
|
+
(`mergeThinkingAcrossHidden`). A research run used to stack ~40 identical "Thought process" rows above the
|
|
27
|
+
answer (live Applet audit, 2026-10-09). Test: `merge-thinking-across-hidden.test.ts`.
|
|
28
|
+
- `LiveRunDisplay` takes `errorText`: the host's own sentence for a failed run, shown instead of the
|
|
29
|
+
request's (an Applet shows visitors a plain sentence; the server's words stay in the error inspector).
|
|
30
|
+
**Consumer action:** none required; Applet hosts pass it.
|
|
31
|
+
|
|
3
32
|
## 0.7.6
|
|
4
33
|
### Unreleased
|
|
5
34
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { callApi } from "../../host/server/call-api.js";
|
|
2
|
+
import { callConversationApi } from "../redux/execution-system/thunks/call-conversation-api.js";
|
|
2
3
|
const inFlightConversationReads = /* @__PURE__ */ new Map();
|
|
3
4
|
function readConversationPendingCalls(conversationId, dispatch) {
|
|
4
5
|
const joined = inFlightConversationReads.get(conversationId);
|
|
5
6
|
if (joined) return joined;
|
|
6
7
|
const tracked = dispatch(
|
|
7
|
-
|
|
8
|
+
// THE CONVERSATION DOOR: the turn's own server, credential and organization.
|
|
9
|
+
callConversationApi(conversationId, {
|
|
8
10
|
path: "/ai/conversation/{conversation_id}/pending_calls",
|
|
9
|
-
method: "GET"
|
|
10
|
-
pathParams: { conversation_id: conversationId }
|
|
11
|
+
method: "GET"
|
|
11
12
|
})
|
|
12
13
|
).finally(() => {
|
|
13
14
|
if (inFlightConversationReads.get(conversationId) === tracked) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { selectHostConversation } from "../redux/execution-system/host-conversations/host-conversations.selectors.js";
|
|
2
2
|
import { answerHostAsk } from "../redux/execution-system/host-conversations/host-conversation.thunks.js";
|
|
3
|
-
import {
|
|
3
|
+
import { callConversationApi } from "../redux/execution-system/thunks/call-conversation-api.js";
|
|
4
4
|
import { toast } from "../../host/notify.js";
|
|
5
5
|
import { formatDurationMs } from "@ai-matrx/kit/format";
|
|
6
6
|
import { setInstanceStatus } from "../redux/execution-system/conversations/conversations.slice.js";
|
|
@@ -92,17 +92,14 @@ function isRetryableError(err) {
|
|
|
92
92
|
function postToolResults(conversationId, results) {
|
|
93
93
|
return async (dispatch, getState) => {
|
|
94
94
|
const callIds = results.map((r) => r.call_id).join(", ");
|
|
95
|
-
const conversationOrganizationId = getState().conversations?.byConversationId?.[conversationId]?.organizationId ?? void 0;
|
|
96
95
|
let lastError = null;
|
|
97
96
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
98
97
|
try {
|
|
99
98
|
const result = await dispatch(
|
|
100
|
-
|
|
99
|
+
callConversationApi(conversationId, {
|
|
101
100
|
path: "/ai/conversations/{conversation_id}/tool_results",
|
|
102
101
|
method: "POST",
|
|
103
|
-
|
|
104
|
-
body: { results },
|
|
105
|
-
scopeOverrides: conversationOrganizationId ? { organization_id: conversationOrganizationId } : void 0
|
|
102
|
+
body: { results }
|
|
106
103
|
})
|
|
107
104
|
);
|
|
108
105
|
if (result.error) {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
stageDraftHandoff
|
|
9
9
|
} from "../../redux/chat/chat-route.slice.js";
|
|
10
10
|
import { DEFAULT_NEW_CHAT_MANDATE_KEY } from "./chat-quick-actions.config.js";
|
|
11
|
+
import { selectIsAuthenticated } from "../../../host/identity.js";
|
|
11
12
|
function parseChatPath(pathname) {
|
|
12
13
|
const agentMatch = pathname.match(/^\/chat\/a\/([^/]+)/);
|
|
13
14
|
if (agentMatch) {
|
|
@@ -116,8 +117,7 @@ async function beginFreshChat({
|
|
|
116
117
|
}) {
|
|
117
118
|
const state = getState();
|
|
118
119
|
let defaultAgentId = null;
|
|
119
|
-
|
|
120
|
-
if (auth && auth.id !== null && !auth.isAnonymous) {
|
|
120
|
+
if (selectIsAuthenticated(state)) {
|
|
121
121
|
try {
|
|
122
122
|
defaultAgentId = await resolveDefaultAgentBounded();
|
|
123
123
|
} catch (error) {
|
|
@@ -58,9 +58,9 @@ interface InputActionButtonsProps {
|
|
|
58
58
|
* audio) live in the + menu; Output and Effort in the agent pill's menu.
|
|
59
59
|
*/
|
|
60
60
|
folded?: boolean;
|
|
61
|
-
/**
|
|
61
|
+
/** Scope · values: after + · mic (· live audio) in Compact's row, after + in the card's own bar. */
|
|
62
62
|
leading?: React.ReactNode;
|
|
63
|
-
/** Compact's row
|
|
63
|
+
/** Agent · output · effort: the right end of Compact's row, or just left of the mic in the card's own bar. */
|
|
64
64
|
trailing?: React.ReactNode;
|
|
65
65
|
/**
|
|
66
66
|
* Which part this instance draws. Compact mounts two: `"send"` (↵, inside
|
|
@@ -202,9 +202,11 @@ function InputActionButtons({
|
|
|
202
202
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
203
203
|
plusMenu,
|
|
204
204
|
database ? /* @__PURE__ */ jsx(DesktopPresenceIndicator, { conversationId }) : null,
|
|
205
|
-
variablesToggle
|
|
205
|
+
variablesToggle,
|
|
206
|
+
composer.leading
|
|
206
207
|
] }),
|
|
207
208
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
209
|
+
composer.trailing,
|
|
208
210
|
extraRightControls,
|
|
209
211
|
micGroup,
|
|
210
212
|
liveAudioButton,
|
|
@@ -20,7 +20,7 @@ import { Button } from "@ai-matrx/design-system";
|
|
|
20
20
|
import { cn } from "@ai-matrx/design-system";
|
|
21
21
|
import { composerShows } from "./composer/composer-mode-visibility.js";
|
|
22
22
|
import { ComposerChipsRow } from "./composer/ComposerChipsRow.js";
|
|
23
|
-
import {
|
|
23
|
+
import { ComposerPills, ComposerScopeCluster, ComposerValueGroupChip } from "./composer/ComposerMetaRow.js";
|
|
24
24
|
import { useComposerFold } from "./composer/useComposerFold.js";
|
|
25
25
|
import { useTouchOnlyDevice } from "../../../../ui/composer/useTouchOnlyDevice.js";
|
|
26
26
|
function SmartAgentInputStacked({
|
|
@@ -323,7 +323,12 @@ function SmartAgentInputStacked({
|
|
|
323
323
|
onVoiceBusyChange: setVoiceBusy,
|
|
324
324
|
extraRightControls,
|
|
325
325
|
onRequestInputExpand: () => setExpandRequestKey((key) => key + 1),
|
|
326
|
-
composer:
|
|
326
|
+
composer: {
|
|
327
|
+
...composerParts,
|
|
328
|
+
// The pills live in the card's own bar: no strip under the card (rule: existing bars).
|
|
329
|
+
leading: composer.meta === "none" ? void 0 : /* @__PURE__ */ jsx(ComposerScopeCluster, { conversationId, composer, folded }),
|
|
330
|
+
trailing: composer.meta === "none" ? void 0 : /* @__PURE__ */ jsx(ComposerPills, { conversationId, composer, menuSide, folded })
|
|
331
|
+
}
|
|
327
332
|
}
|
|
328
333
|
)
|
|
329
334
|
] })
|
|
@@ -344,7 +349,7 @@ function SmartAgentInputStacked({
|
|
|
344
349
|
trailing: composer.meta === "none" ? void 0 : /* @__PURE__ */ jsx(ComposerPills, { conversationId, composer, menuSide, folded })
|
|
345
350
|
}
|
|
346
351
|
}
|
|
347
|
-
) :
|
|
352
|
+
) : null
|
|
348
353
|
]
|
|
349
354
|
}
|
|
350
355
|
);
|
|
@@ -15,6 +15,7 @@ import { useSessionKnob } from "../../../../../host/prefs-react.js";
|
|
|
15
15
|
import { cn } from "@ai-matrx/design-system";
|
|
16
16
|
import { COMPOSER_KNOBS } from "./composer-mode-cookie.js";
|
|
17
17
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
18
|
+
import { selectOrganizationId } from "../../../../../host/org.js";
|
|
18
19
|
function timeOfDayGreeting(hour) {
|
|
19
20
|
if (hour < 5) return "Evening";
|
|
20
21
|
if (hour < 12) return "Morning";
|
|
@@ -69,9 +70,7 @@ function ComposerQuickActions({
|
|
|
69
70
|
className
|
|
70
71
|
}) {
|
|
71
72
|
const knob = useSessionKnob(COMPOSER_KNOBS.quickActions);
|
|
72
|
-
const organizationId = useAppSelector(
|
|
73
|
-
(state) => state.appContext?.organization_id ?? null
|
|
74
|
-
);
|
|
73
|
+
const organizationId = useAppSelector(selectOrganizationId);
|
|
75
74
|
const actions = parseQuickActions(knob);
|
|
76
75
|
const quickActionKeys = actions.map((a) => a.mandateKey);
|
|
77
76
|
const mandates = useMandateSet(quickActionKeys, {
|
|
@@ -13,13 +13,15 @@ import {
|
|
|
13
13
|
readComposerModeCookieClient,
|
|
14
14
|
writeComposerModeCookie
|
|
15
15
|
} from "./composer-mode-cookie.js";
|
|
16
|
+
import { selectUserId } from "../../../../../host/identity.js";
|
|
17
|
+
import { selectOrganizationId } from "../../../../../host/org.js";
|
|
16
18
|
let knobsAppliedThisTab = false;
|
|
17
19
|
let choseModeThisTab = false;
|
|
18
20
|
function useComposerMode(initialMode, { enabled = true } = {}) {
|
|
19
21
|
const dispatch = useAppDispatch();
|
|
20
22
|
const stored = useAppSelector(selectComposerMode);
|
|
21
|
-
const organizationId = useAppSelector(
|
|
22
|
-
const userId = useAppSelector(
|
|
23
|
+
const organizationId = useAppSelector(selectOrganizationId);
|
|
24
|
+
const userId = useAppSelector(selectUserId);
|
|
23
25
|
const knobOrganization = enabled ? organizationId : null;
|
|
24
26
|
const defaultModeKnob = useEffectiveKnob(knobOrganization, userId, COMPOSER_KNOBS.defaultMode);
|
|
25
27
|
const rememberKnob = useEffectiveKnob(knobOrganization, userId, COMPOSER_KNOBS.rememberLastMode);
|
|
@@ -25,6 +25,12 @@ export interface LiveRunDisplayProps {
|
|
|
25
25
|
* so a refused launch never reads as a run still on its way.
|
|
26
26
|
*/
|
|
27
27
|
failure?: string | null;
|
|
28
|
+
/**
|
|
29
|
+
* The host's own sentence for a failed run, shown INSTEAD of the request's. A host whose viewers did not
|
|
30
|
+
* build the agent (an Applet's visitors) shows a plain sentence; the server's words stay in the error
|
|
31
|
+
* inspector (Applet audit 2026-10-09).
|
|
32
|
+
*/
|
|
33
|
+
errorText?: string | null;
|
|
28
34
|
/** Renders a dismiss (X) affordance; caller tears the run down. */
|
|
29
35
|
onDismiss?: () => void;
|
|
30
36
|
className?: string;
|
|
@@ -42,4 +48,4 @@ export interface LiveRunDisplayProps {
|
|
|
42
48
|
*/
|
|
43
49
|
variant?: "card" | "bare";
|
|
44
50
|
}
|
|
45
|
-
export declare function LiveRunDisplay({ conversationId, requestId: requestIdProp, label, pending, failure, onDismiss, className, bodyClassName, variant, }: LiveRunDisplayProps): import("react").JSX.Element | null;
|
|
51
|
+
export declare function LiveRunDisplay({ conversationId, requestId: requestIdProp, label, pending, failure, errorText, onDismiss, className, bodyClassName, variant, }: LiveRunDisplayProps): import("react").JSX.Element | null;
|
|
@@ -21,6 +21,7 @@ function LiveRunDisplay({
|
|
|
21
21
|
label,
|
|
22
22
|
pending = false,
|
|
23
23
|
failure = null,
|
|
24
|
+
errorText = null,
|
|
24
25
|
onDismiss,
|
|
25
26
|
className,
|
|
26
27
|
bodyClassName,
|
|
@@ -32,7 +33,8 @@ function LiveRunDisplay({
|
|
|
32
33
|
pending && !failure
|
|
33
34
|
);
|
|
34
35
|
const { requestId, isActive, statusText, chunkCount } = status;
|
|
35
|
-
const
|
|
36
|
+
const rawError = status.errorMessage ?? (failure || null);
|
|
37
|
+
const errorMessage = rawError && errorText ? errorText : rawError;
|
|
36
38
|
const conversationMessages = useAppSelector(
|
|
37
39
|
conversationId ? selectConversationMessages(conversationId) : selectNoConversationMessages
|
|
38
40
|
);
|
|
@@ -165,7 +165,7 @@ function AssistantMessageFooter(props) {
|
|
|
165
165
|
isLatestAssistant
|
|
166
166
|
} = useAssistantMessageActions(props);
|
|
167
167
|
const answerActions = useTranscriptLayout().answerActions;
|
|
168
|
-
const isHoverOnly = answerActions === "hover" || density === "compact" && !isLatestAssistant;
|
|
168
|
+
const isHoverOnly = answerActions === "hover" || answerActions === "latest" && !isLatestAssistant || density === "compact" && !isLatestAssistant;
|
|
169
169
|
const rowRef = useRef(null);
|
|
170
170
|
useEffect(() => {
|
|
171
171
|
const row = rowRef.current;
|
|
@@ -183,7 +183,9 @@ function AssistantMessageFooter(props) {
|
|
|
183
183
|
{
|
|
184
184
|
className: cn(
|
|
185
185
|
"transition-opacity",
|
|
186
|
-
isHoverOnly &&
|
|
186
|
+
isHoverOnly && // Hidden by opacity, never display: the row keeps its height, so revealing it shifts
|
|
187
|
+
// nothing. A touch screen has no hover, so it is always visible there.
|
|
188
|
+
"opacity-0 group-hover/assistant-msg:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100"
|
|
187
189
|
),
|
|
188
190
|
children: [
|
|
189
191
|
/* @__PURE__ */ jsxs(
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* How a host lays the ONE conversation column out (HOST-OWNED-SOURCE-PLAN P28e look bar).
|
|
3
3
|
*
|
|
4
|
-
* Knobs, never forks:
|
|
5
|
-
*
|
|
4
|
+
* Knobs, never forks: a host that says nothing gets the default look (flat compact user turn,
|
|
5
|
+
* actions on hover). Matrx 2 (desktop) fills its pane, starts at the left edge and draws the
|
|
6
6
|
* person's turn as a compact block — the look its coding screen had before the column.
|
|
7
7
|
*
|
|
8
8
|
* - `width`: "reading" (the canonical `max-w-3xl` reading column) | "fill" (the host's pane).
|
|
9
9
|
* - `align`: "center" | "start" — where a reading-width column sits in a wider pane.
|
|
10
|
-
* - `userMessage`: "
|
|
11
|
-
* "
|
|
12
|
-
* - `answerActions`: "
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* - `userMessage`: "compact" (DEFAULT: a flat tight block; only a genuinely long message
|
|
11
|
+
* collapses) | "card" (the bordered card that collapses a long message behind a chevron).
|
|
12
|
+
* - `answerActions`: "hover" (DEFAULT: the action row is revealed on hover / keyboard focus, and
|
|
13
|
+
* always on touch — its height is reserved, so revealing it moves nothing; a finished answer ends
|
|
14
|
+
* on its last word) | "latest" (the latest answer's row is always visible, older ones on hover) |
|
|
15
|
+
* "shown" (every answer's row always visible).
|
|
15
16
|
*/
|
|
16
17
|
import { type ReactNode } from "react";
|
|
17
18
|
export interface TranscriptLayout {
|
|
18
19
|
width?: "reading" | "fill";
|
|
19
20
|
align?: "center" | "start";
|
|
20
21
|
userMessage?: "card" | "compact";
|
|
21
|
-
answerActions?: "shown" | "hover";
|
|
22
|
+
answerActions?: "shown" | "latest" | "hover";
|
|
22
23
|
}
|
|
23
24
|
export declare const DEFAULT_TRANSCRIPT_LAYOUT: Required<TranscriptLayout>;
|
|
24
25
|
export declare function resolveTranscriptLayout(layout?: TranscriptLayout): Required<TranscriptLayout>;
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
const DEFAULT_TRANSCRIPT_LAYOUT = {
|
|
7
7
|
width: "reading",
|
|
8
8
|
align: "center",
|
|
9
|
-
userMessage: "
|
|
10
|
-
answerActions: "
|
|
9
|
+
userMessage: "compact",
|
|
10
|
+
answerActions: "hover"
|
|
11
11
|
};
|
|
12
12
|
const TranscriptLayoutContext = createContext(DEFAULT_TRANSCRIPT_LAYOUT);
|
|
13
13
|
function resolveTranscriptLayout(layout) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { chatRequestHeaders } from "../../../host/request-headers.js";
|
|
2
2
|
import { selectResolvedBaseUrl } from "../../../host/server/api-config.js";
|
|
3
3
|
import { selectAccessToken, selectFingerprintId } from "../../../host/identity.js";
|
|
4
4
|
import { selectOrganizationId } from "../../../host/org.js";
|
|
@@ -17,7 +17,6 @@ function resolveAgentCacheBustBackend(state) {
|
|
|
17
17
|
const accessToken = selectAccessToken(state);
|
|
18
18
|
const fingerprintId = selectFingerprintId(state);
|
|
19
19
|
if (accessToken) {
|
|
20
|
-
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
21
20
|
const organizationId = selectOrganizationId(state);
|
|
22
21
|
if (!organizationId) {
|
|
23
22
|
console.warn(
|
|
@@ -27,13 +26,14 @@ function resolveAgentCacheBustBackend(state) {
|
|
|
27
26
|
}
|
|
28
27
|
return {
|
|
29
28
|
baseUrl: trimmedBase,
|
|
30
|
-
|
|
29
|
+
// THE ONE HEADER BUILDER (host/request-headers.ts).
|
|
30
|
+
headers: { ...headers, ...chatRequestHeaders({ accessToken, fingerprintId: null }, organizationId) }
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
return {
|
|
34
|
+
baseUrl: trimmedBase,
|
|
35
|
+
headers: { ...headers, ...chatRequestHeaders({ accessToken: null, fingerprintId }, null) }
|
|
36
|
+
};
|
|
37
37
|
}
|
|
38
38
|
async function postInvalidateAgentCache(baseUrl, agentId, headers, options) {
|
|
39
39
|
const response = await sendMatrxRequest(
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import { setContextReceipt } from "../instance-context/instance-context.slice.js";
|
|
6
6
|
import { captureError } from "../../../../host/diagnostics.js";
|
|
7
7
|
import { toast } from "../../../../host/notify.js";
|
|
8
|
+
import { selectIsAdmin } from "../../../../host/identity.js";
|
|
8
9
|
function toContextReceiptRow(row) {
|
|
9
10
|
const out = {
|
|
10
11
|
key: row.key,
|
|
@@ -101,8 +102,7 @@ function recordContextReceipt(dispatch, getState, args) {
|
|
|
101
102
|
requestId,
|
|
102
103
|
level: "high"
|
|
103
104
|
});
|
|
104
|
-
|
|
105
|
-
if (auth?.isAdmin && auth.adminLaneOpen) {
|
|
105
|
+
if (selectIsAdmin(getState())) {
|
|
106
106
|
console.error("[context-rules] receipt mismatch", { conversationId, requestId, mismatches, receipt });
|
|
107
107
|
toast.warning(`Context mismatch: ${summary}`.slice(0, 140));
|
|
108
108
|
}
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* anywhere else; bypassing the funnel forfeits the optimistic card +
|
|
11
11
|
* `injection_consumed` delivery handshake.
|
|
12
12
|
*
|
|
13
|
-
* All four calls ride `
|
|
14
|
-
*
|
|
13
|
+
* All four calls ride THE CONVERSATION DOOR (`callConversationApi`): the turn's own server,
|
|
14
|
+
* credential and organization, so a mid-run message can never go where the run is not.
|
|
15
15
|
*/
|
|
16
16
|
import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
|
|
17
17
|
import { type InboxItemKind, type InboxItemMode } from "./inbox.slice.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
2
|
-
import {
|
|
2
|
+
import { callConversationApi } from "../thunks/call-conversation-api.js";
|
|
3
3
|
import { toast } from "../../../../host/notify.js";
|
|
4
4
|
import {
|
|
5
5
|
addInboxItem,
|
|
@@ -55,10 +55,9 @@ const enqueueInboxMessage = createAsyncThunk(
|
|
|
55
55
|
})
|
|
56
56
|
);
|
|
57
57
|
const result = await dispatch(
|
|
58
|
-
|
|
58
|
+
callConversationApi(conversationId, {
|
|
59
59
|
path: "/ai/conversations/{conversation_id}/inbox",
|
|
60
60
|
method: "POST",
|
|
61
|
-
pathParams: { conversation_id: conversationId },
|
|
62
61
|
expectedErrorStatuses: [404],
|
|
63
62
|
body: {
|
|
64
63
|
kind,
|
|
@@ -116,13 +115,10 @@ const retractInboxItem = createAsyncThunk(
|
|
|
116
115
|
return "retracted";
|
|
117
116
|
}
|
|
118
117
|
const result = await dispatch(
|
|
119
|
-
|
|
118
|
+
callConversationApi(conversationId, {
|
|
120
119
|
path: "/ai/conversations/{conversation_id}/inbox/{injection_id}",
|
|
121
120
|
method: "DELETE",
|
|
122
|
-
pathParams: {
|
|
123
|
-
conversation_id: conversationId,
|
|
124
|
-
injection_id: injectionId
|
|
125
|
-
}
|
|
121
|
+
pathParams: { injection_id: injectionId }
|
|
126
122
|
})
|
|
127
123
|
);
|
|
128
124
|
if (result.error && result.error.status === 409) {
|
|
@@ -150,13 +146,10 @@ const editInboxItem = createAsyncThunk(
|
|
|
150
146
|
return;
|
|
151
147
|
}
|
|
152
148
|
const result = await dispatch(
|
|
153
|
-
|
|
149
|
+
callConversationApi(conversationId, {
|
|
154
150
|
path: "/ai/conversations/{conversation_id}/inbox/{injection_id}",
|
|
155
151
|
method: "PATCH",
|
|
156
|
-
pathParams: {
|
|
157
|
-
conversation_id: conversationId,
|
|
158
|
-
injection_id: injectionId
|
|
159
|
-
},
|
|
152
|
+
pathParams: { injection_id: injectionId },
|
|
160
153
|
body: { text }
|
|
161
154
|
})
|
|
162
155
|
);
|
|
@@ -178,10 +171,9 @@ const editInboxItem = createAsyncThunk(
|
|
|
178
171
|
);
|
|
179
172
|
const hydrateInbox = createAsyncThunk("conversationInbox/hydrate", async ({ conversationId }, { dispatch }) => {
|
|
180
173
|
const result = await dispatch(
|
|
181
|
-
|
|
174
|
+
callConversationApi(conversationId, {
|
|
182
175
|
path: "/ai/conversations/{conversation_id}/inbox",
|
|
183
176
|
method: "GET",
|
|
184
|
-
pathParams: { conversation_id: conversationId },
|
|
185
177
|
queryParams: { status: "pending" }
|
|
186
178
|
})
|
|
187
179
|
);
|
package/dist/agents/redux/execution-system/observational-memory/fetch-memory-cost.thunk.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* captures that as a typed error on the slice and never throws.
|
|
14
14
|
*/
|
|
15
15
|
import type { ChatRootState } from "../../../../store/root-state.js";
|
|
16
|
-
import {
|
|
16
|
+
import type { MemoryCostSummary } from "../../../../host/server/call-api.js";
|
|
17
17
|
interface FetchMemoryCostArgs {
|
|
18
18
|
conversationId: string;
|
|
19
19
|
signal?: AbortSignal;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
2
|
-
import {
|
|
3
|
-
callConversationMemoryCost
|
|
4
|
-
} from "../../../../host/server/call-api.js";
|
|
2
|
+
import { callConversationApi } from "../thunks/call-conversation-api.js";
|
|
5
3
|
import {
|
|
6
4
|
setCostFetchStatus,
|
|
7
5
|
setCostSummary
|
|
@@ -11,7 +9,12 @@ const fetchMemoryCost = createAsyncThunk(
|
|
|
11
9
|
async ({ conversationId, signal }, { dispatch, rejectWithValue }) => {
|
|
12
10
|
dispatch(setCostFetchStatus({ conversationId, status: "loading" }));
|
|
13
11
|
const result = await dispatch(
|
|
14
|
-
|
|
12
|
+
// THE CONVERSATION DOOR: the turn's own server, credential and organization.
|
|
13
|
+
callConversationApi(conversationId, {
|
|
14
|
+
path: "/ai/conversations/{conversation_id}/memory_cost",
|
|
15
|
+
method: "GET",
|
|
16
|
+
...signal ? { signal } : {}
|
|
17
|
+
})
|
|
15
18
|
);
|
|
16
19
|
if (result.error || !result.data) {
|
|
17
20
|
const message = result.error?.message ?? "Failed to fetch memory cost.";
|
|
@@ -362,120 +362,7 @@ export declare const selectIsInstanceReady: (conversationId: string) => ((state:
|
|
|
362
362
|
* Usage — stabilize selector identity with `useMemo`:
|
|
363
363
|
* `useMemo(() => makeSelectAssembledRequest(conversationId), [conversationId])`.
|
|
364
364
|
*/
|
|
365
|
-
export declare function makeSelectAssembledRequest(conversationId: string): (
|
|
366
|
-
voiceAgent: import("../../../../voice-agent/types.js").VoiceAgentState;
|
|
367
|
-
agentDefinition: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState;
|
|
368
|
-
conversationList: import("../../conversation-list/conversation-list.types.js").ConversationListState;
|
|
369
|
-
conversationHistory: import("../../conversation-history/types.js").ConversationHistoryState;
|
|
370
|
-
agentShortcut: import("../../agent-shortcuts/types.js").AgentShortcutSliceState;
|
|
371
|
-
agentShortcutCategory: import("../../agent-shortcut-categories/types.js").AgentShortcutCategorySliceState;
|
|
372
|
-
surfaceUserState: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice;
|
|
373
|
-
conversations: import("../conversations/conversations.slice.js").ConversationsState;
|
|
374
|
-
chatIncognito: import("../../chat/chat-incognito.slice.js").ChatIncognitoState;
|
|
375
|
-
chatRoute: import("../../chat/chat-route.slice.js").ChatRouteState;
|
|
376
|
-
instanceModelOverrides: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState;
|
|
377
|
-
instanceInputCapabilities: import("../instance-input-capabilities/instance-input-capabilities.slice.js").InstanceInputCapabilitiesState;
|
|
378
|
-
instanceVariableValues: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState;
|
|
379
|
-
instanceResources: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState;
|
|
380
|
-
instanceContext: import("../instance-context/instance-context.slice.js").InstanceContextState;
|
|
381
|
-
instanceWorkingDocument: import("../instance-working-document/instance-working-document.slice.js").InstanceWorkingDocumentSliceState;
|
|
382
|
-
instanceUserInput: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState;
|
|
383
|
-
instanceClientTools: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState;
|
|
384
|
-
pendingAsks: import("../../../ui-first-tools/redux/pending-asks.slice.js").PendingAsksState;
|
|
385
|
-
conversationInbox: import("../inbox/inbox.slice.js").ConversationInboxState;
|
|
386
|
-
agentLists: import("../../../ui-first-tools/redux/agent-lists.slice.js").AgentListsState;
|
|
387
|
-
instanceUIState: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice;
|
|
388
|
-
activeTools: import("../active-tools/active-tools.slice.js").ActiveToolsState;
|
|
389
|
-
activeRequests: import("../active-requests/active-requests.slice.js").ActiveRequestsState;
|
|
390
|
-
runSets: import("../run-sets/run-sets.slice.js").RunSetsState;
|
|
391
|
-
messages: import("../messages/messages.slice.js").MessagesState;
|
|
392
|
-
observability: import("../observability/observability.slice.js").ObservabilityState;
|
|
393
|
-
contextState: import("../context-state/context-state.slice.js").ContextStateSliceState;
|
|
394
|
-
observationalMemory: import("../observational-memory/observational-memory.slice.js").ObservationalMemoryState;
|
|
395
|
-
cacheBypass: import("../message-crud/cache-bypass.slice.js").CacheBypassState;
|
|
396
|
-
conversationFocus: import("../conversation-focus/conversation-focus.slice.js").ConversationFocusState;
|
|
397
|
-
surfaces: import("../../surfaces/surfaces.slice.js").SurfacesState;
|
|
398
|
-
surfacesCatalog: import("../../../../surfaces/redux/surfacesCatalogSlice.js").SurfacesCatalogSliceState;
|
|
399
|
-
agentSurfaceBindings: import("../../../../surfaces/redux/agentSurfaceBindingsSlice.js").AgentSurfaceBindingsSliceState;
|
|
400
|
-
surfaceConfig: import("../../../../surfaces/redux/surfaceConfigSlice.js").SurfaceConfigSliceState;
|
|
401
|
-
agentAssistantMarkdownDraft: import("../../agent-assistant-markdown-draft.slice.js").AgentAssistantMarkdownDraftState;
|
|
402
|
-
mcp: import("../../mcp/mcp.slice.js").McpSliceState;
|
|
403
|
-
proposedDirectives: import("../../proposed-directives/proposedDirectivesSlice.js").ProposedDirectivesState;
|
|
404
|
-
conversationAttachments: import("../../../connectors/attachments.slice.js").AttachmentsSliceState;
|
|
405
|
-
chatHost: import("../../../../store/chat-host.slice.js").ChatHostState;
|
|
406
|
-
hostConversations: import("../host-conversations/host-conversations.slice.js").HostConversationsState;
|
|
407
|
-
} & import("../../../../store/root-state.js").ChatHostReadSlices) => AssembledAgentStartRequest | null) & {
|
|
408
|
-
clearCache: () => void;
|
|
409
|
-
resultsCount: () => number;
|
|
410
|
-
resetResultsCount: () => void;
|
|
411
|
-
} & {
|
|
412
|
-
resultFunc: (resultFuncArgs_0: import("../conversations/conversations.slice.js").ConversationsState, resultFuncArgs_1: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, resultFuncArgs_2: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, resultFuncArgs_3: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, resultFuncArgs_4: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, resultFuncArgs_5: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, resultFuncArgs_6: import("../instance-context/instance-context.slice.js").InstanceContextState, resultFuncArgs_7: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, resultFuncArgs_8: {
|
|
413
|
-
organization_id?: string | null;
|
|
414
|
-
} | undefined, resultFuncArgs_9: import("../../../../store/chat-host.slice.js").ChatHostState, resultFuncArgs_10: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, resultFuncArgs_11: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, resultFuncArgs_12: import("../messages/messages.slice.js").MessagesState, resultFuncArgs_13: {
|
|
415
|
-
id: string | null;
|
|
416
|
-
email?: string | null;
|
|
417
|
-
isAnonymous?: boolean;
|
|
418
|
-
accessToken?: string | null;
|
|
419
|
-
isAdmin?: boolean;
|
|
420
|
-
adminLaneOpen?: boolean;
|
|
421
|
-
adminLevel?: string | null;
|
|
422
|
-
} | undefined, resultFuncArgs_14: {
|
|
423
|
-
fingerprintId?: string | null;
|
|
424
|
-
userMetadata?: {
|
|
425
|
-
fullName?: string | null;
|
|
426
|
-
name?: string | null;
|
|
427
|
-
preferredUsername?: string | null;
|
|
428
|
-
} | null;
|
|
429
|
-
} | undefined) => AssembledAgentStartRequest | null;
|
|
430
|
-
memoizedResultFunc: ((resultFuncArgs_0: import("../conversations/conversations.slice.js").ConversationsState, resultFuncArgs_1: import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, resultFuncArgs_2: import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, resultFuncArgs_3: import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, resultFuncArgs_4: import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, resultFuncArgs_5: import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, resultFuncArgs_6: import("../instance-context/instance-context.slice.js").InstanceContextState, resultFuncArgs_7: import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, resultFuncArgs_8: {
|
|
431
|
-
organization_id?: string | null;
|
|
432
|
-
} | undefined, resultFuncArgs_9: import("../../../../store/chat-host.slice.js").ChatHostState, resultFuncArgs_10: import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, resultFuncArgs_11: import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, resultFuncArgs_12: import("../messages/messages.slice.js").MessagesState, resultFuncArgs_13: {
|
|
433
|
-
id: string | null;
|
|
434
|
-
email?: string | null;
|
|
435
|
-
isAnonymous?: boolean;
|
|
436
|
-
accessToken?: string | null;
|
|
437
|
-
isAdmin?: boolean;
|
|
438
|
-
adminLaneOpen?: boolean;
|
|
439
|
-
adminLevel?: string | null;
|
|
440
|
-
} | undefined, resultFuncArgs_14: {
|
|
441
|
-
fingerprintId?: string | null;
|
|
442
|
-
userMetadata?: {
|
|
443
|
-
fullName?: string | null;
|
|
444
|
-
name?: string | null;
|
|
445
|
-
preferredUsername?: string | null;
|
|
446
|
-
} | null;
|
|
447
|
-
} | undefined) => AssembledAgentStartRequest | null) & {
|
|
448
|
-
clearCache: () => void;
|
|
449
|
-
resultsCount: () => number;
|
|
450
|
-
resetResultsCount: () => void;
|
|
451
|
-
};
|
|
452
|
-
lastResult: () => AssembledAgentStartRequest | null;
|
|
453
|
-
dependencies: [(s: ChatRootState) => import("../conversations/conversations.slice.js").ConversationsState, (s: ChatRootState) => import("../instance-ui-state/instance-ui-state.slice.js").InstanceUIStateSlice, (s: ChatRootState) => import("../instance-user-input/instance-user-input.slice.js").InstanceUserInputSliceState, (s: ChatRootState) => import("../instance-resources/instance-resources.slice.js").InstanceResourcesState, (s: ChatRootState) => import("../instance-variable-values/instance-variable-values.slice.js").InstanceVariableValuesState, (s: ChatRootState) => import("../instance-model-overrides/instance-model-overrides.slice.js").InstanceModelOverridesState, (s: ChatRootState) => import("../instance-context/instance-context.slice.js").InstanceContextState, (s: ChatRootState) => import("../instance-client-tools/instance-client-tools.slice.js").InstanceClientToolsState, (s: ChatRootState) => {
|
|
454
|
-
organization_id?: string | null;
|
|
455
|
-
} | undefined, (s: ChatRootState) => import("../../../../store/chat-host.slice.js").ChatHostState, (s: ChatRootState) => import("../../../types/agent-definition.types.js").AgentDefinitionSliceState, (s: ChatRootState) => import("../../../../surfaces/redux/userStateSlice.js").SurfaceUserStateSlice, (s: ChatRootState) => import("../messages/messages.slice.js").MessagesState, (s: ChatRootState) => {
|
|
456
|
-
id: string | null;
|
|
457
|
-
email?: string | null;
|
|
458
|
-
isAnonymous?: boolean;
|
|
459
|
-
accessToken?: string | null;
|
|
460
|
-
isAdmin?: boolean;
|
|
461
|
-
adminLaneOpen?: boolean;
|
|
462
|
-
adminLevel?: string | null;
|
|
463
|
-
} | undefined, (s: ChatRootState) => {
|
|
464
|
-
fingerprintId?: string | null;
|
|
465
|
-
userMetadata?: {
|
|
466
|
-
fullName?: string | null;
|
|
467
|
-
name?: string | null;
|
|
468
|
-
preferredUsername?: string | null;
|
|
469
|
-
} | null;
|
|
470
|
-
} | undefined];
|
|
471
|
-
recomputations: () => number;
|
|
472
|
-
resetRecomputations: () => void;
|
|
473
|
-
dependencyRecomputations: () => number;
|
|
474
|
-
resetDependencyRecomputations: () => void;
|
|
475
|
-
} & {
|
|
476
|
-
memoize: typeof import("reselect").weakMapMemoize;
|
|
477
|
-
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
478
|
-
};
|
|
365
|
+
export declare function makeSelectAssembledRequest(conversationId: string): (state: ChatRootState) => AssembledAgentStartRequest | null;
|
|
479
366
|
/** @deprecated Use {@link makeSelectAssembledRequest}; same underlying factory (alias). */
|
|
480
367
|
export declare const selectAssembledRequest: typeof makeSelectAssembledRequest;
|
|
481
368
|
/**
|