@ai-matrx/chat 0.4.12 → 0.4.15
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 +44 -0
- package/dist/agents/components/shared/AgentModeController.d.ts +1 -1
- package/dist/agents/components/shared/AgentModeController.js +4 -0
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +1 -1
- package/dist/agents/redux/execution-system/active-requests/active-requests.slice.d.ts +2 -0
- package/dist/agents/redux/execution-system/active-requests/active-requests.slice.js +7 -0
- package/dist/agents/redux/execution-system/conversations/conversation-persistence.js +2 -4
- package/dist/agents/redux/execution-system/instance-context/instance-context.slice.js +1 -1
- package/dist/agents/redux/execution-system/thunks/dispatch-matrx-extend-tool.thunk.js +3 -1
- package/dist/agents/redux/execution-system/thunks/process-stream.js +26 -23
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +1 -1
- package/dist/agents/runtime-reconnect/api.d.ts +6 -25
- package/dist/agents/runtime-reconnect/api.js +7 -13
- package/dist/agents/runtime-reconnect/reconnect-server-operation.thunk.js +167 -159
- package/dist/agents/runtime-reconnect/types.d.ts +2 -0
- package/dist/agents/services/mcp-connections.service.d.ts +12 -0
- package/dist/agents/services/mcp-connections.service.js +4 -7
- package/dist/agents/types/request.types.d.ts +6 -0
- package/dist/agents/utils/json-extraction.js +2 -2
- package/dist/cx-chat/utils/settings-diff.js +1 -21
- package/dist/host/configure.js +15 -5
- package/dist/host/contract.d.ts +43 -2
- package/dist/host/db-types.d.ts +112 -0
- package/dist/host/db.js +6 -0
- package/dist/host/defaults/diagnostics.d.ts +5 -0
- package/dist/host/defaults/diagnostics.js +1 -2
- package/dist/host/defaults/identity.d.ts +26 -0
- package/dist/host/defaults/identity.js +133 -1
- package/dist/host/identity.d.ts +19 -2
- package/dist/host/identity.js +18 -10
- package/dist/host/session-retry.js +2 -2
- package/dist/host/ui-slots.js +27 -20
- package/dist/surfaces/services/bind-agent-to-surface.service.js +2 -4
- package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
- package/dist/ui/mandates-storage/mandateStorage.d.ts +60 -0
- package/dist/ui/mandates-storage/shortcutStorage.d.ts +15 -0
- package/dist/utils/deep-equal.d.ts +5 -0
- package/dist/utils/deep-equal.js +24 -0
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
+
## 0.4.15
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/chat/v0.4.14..npm/chat/v0.4.15 -- apps/shared/chat`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
9
|
+
## 0.4.14 — token-only hosts, on-device tools, and a bundle budget (W0(b), W0(c), W0(e))
|
|
10
|
+
|
|
11
|
+
- **Token-only database clients** (supabase-js `accessToken` option — matrx-local's custodian
|
|
12
|
+
client, where `db.auth` throws): new host field `accessToken: () => Promise<string | null>`; the
|
|
13
|
+
default identity reads the person from that token (admin level through `db`). A token-only `db`
|
|
14
|
+
with no function is signed out and settled, announced once with the remedy. The resolver no
|
|
15
|
+
longer touches `db.auth` on such a client.
|
|
16
|
+
- **One session door:** every package session read goes through the identity port
|
|
17
|
+
(`readSessionToken`, `hasBrowserSession`, `hostSessionSource` in `host/identity`); guard test
|
|
18
|
+
`host/__tests__/session-reads-go-through-the-identity-port.test.ts` fails on a direct auth-js call.
|
|
19
|
+
- **`deviceTools` host port** (`ChatDeviceToolsPort`): a host that IS the device (chat inside Matrx
|
|
20
|
+
Extend, a desktop app) executes delegated device tools; the package keeps the lifecycle, the
|
|
21
|
+
durable result submit and the resume. Absent: unchanged web route through the extension bridge.
|
|
22
|
+
- **Side-panel bundle budget:** `pnpm check:side-panel-bundle` builds the bare Vite canary and fails
|
|
23
|
+
when the first chat screen or the whole output (gzip) passes `side-panel-bundle-budget.json`
|
|
24
|
+
(measured on 0.4.9: 2435 kB / 8197 kB — a ratchet, lower it when it shrinks).
|
|
25
|
+
|
|
26
|
+
Consumer action: none for session (auth-js) hosts. A token-only host passes `accessToken` (the same
|
|
27
|
+
function its Supabase client got). A device host passes `deviceTools`.
|
|
28
|
+
|
|
29
|
+
## 0.4.14 — reconnect rides the shared follow core
|
|
30
|
+
|
|
31
|
+
- Reconnect (`reconnectServerOperation`) now identifies, rejoins, follows and settles through
|
|
32
|
+
`followServerJob` (@ai-matrx/agents 0.57.0); `processStream` dedupes replay through the shared
|
|
33
|
+
`createStreamReplayCursor` (a high-water mark per `stream_id`, persisted on `ActiveRequest` as
|
|
34
|
+
`transportSeqByStream`). The chat-only follower (`followOperationStream`) is deleted. Fixes
|
|
35
|
+
replayed segment A rendering twice after a live A then B.
|
|
36
|
+
|
|
37
|
+
Consumer action: none.
|
|
38
|
+
|
|
39
|
+
## 0.4.13 — markdown-source helpers from their one home
|
|
40
|
+
|
|
41
|
+
- `StreamingJsonTracker`, `extractAllJson`, `extractFirstJson`, `findAllFencedBlocks` are read from
|
|
42
|
+
`@ai-matrx/content-ir/json-extract`, and `stripThinkingStreaming` from `@ai-matrx/content-ir/source`
|
|
43
|
+
(kit 0.36.0 no longer carries them).
|
|
44
|
+
|
|
45
|
+
Consumer action: none.
|
|
46
|
+
|
|
3
47
|
## Unreleased
|
|
4
48
|
|
|
5
49
|
- Chat's own message surfaces import `ui/markdown-stream/MarkdownStream` by its default export, so a host test that mocks that module (default only) replaces it everywhere, as it did when it was a slot.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Eye } from "lucide-react";
|
|
2
|
-
export type AgentPageMode = "view" | "edit" | "run" | "shortcuts" | "apps" | "surfaces" | "hindsight" | "versions" | "widgets";
|
|
2
|
+
export type AgentPageMode = "view" | "edit" | "run" | "shortcuts" | "apps" | "surfaces" | "hindsight" | "runs" | "versions" | "widgets";
|
|
3
3
|
export type ModeOption = AgentPageMode | "new";
|
|
4
4
|
export declare const MODES: {
|
|
5
5
|
id: ModeOption;
|
|
@@ -3,6 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState, useTransition } from "react";
|
|
4
4
|
import { useRouter, usePathname, Link } from "../../../host/navigation.js";
|
|
5
5
|
import {
|
|
6
|
+
Activity,
|
|
6
7
|
AppWindow,
|
|
7
8
|
Eye,
|
|
8
9
|
History,
|
|
@@ -40,6 +41,7 @@ const MODES = [
|
|
|
40
41
|
{ id: "apps", label: "Apps", icon: AppWindow },
|
|
41
42
|
{ id: "surfaces", label: "Surfaces", icon: Layers },
|
|
42
43
|
{ id: "hindsight", label: "Review", icon: Telescope },
|
|
44
|
+
{ id: "runs", label: "Runs", icon: Activity },
|
|
43
45
|
{ id: "versions", label: "Versions", icon: History },
|
|
44
46
|
{ id: "widgets", label: "Widgets", icon: LayoutGrid },
|
|
45
47
|
{ id: "new", label: "New", icon: Plus }
|
|
@@ -54,6 +56,7 @@ function getAgentModeHref(mode, agentId, basePath) {
|
|
|
54
56
|
apps: `${basePath}/${agentId}/apps`,
|
|
55
57
|
surfaces: `${basePath}/${agentId}/surfaces`,
|
|
56
58
|
hindsight: `${basePath}/${agentId}/hindsight`,
|
|
59
|
+
runs: `${basePath}/${agentId}/runs`,
|
|
57
60
|
versions: `${basePath}/${agentId}/latest`,
|
|
58
61
|
widgets: `${basePath}/${agentId}/widgets`
|
|
59
62
|
};
|
|
@@ -67,6 +70,7 @@ function deriveAgentMode(pathname, agentId, basePath) {
|
|
|
67
70
|
if (pathname.startsWith(`${base}/apps`)) return "apps";
|
|
68
71
|
if (pathname.startsWith(`${base}/surfaces`)) return "surfaces";
|
|
69
72
|
if (pathname.startsWith(`${base}/hindsight`)) return "hindsight";
|
|
73
|
+
if (pathname.startsWith(`${base}/runs`)) return "runs";
|
|
70
74
|
if (pathname.startsWith(`${base}/widgets`)) return "widgets";
|
|
71
75
|
const versionPattern = new RegExp(
|
|
72
76
|
`^${basePath.replace(/\//g, "\\/")}\\/[^/]+\\/v\\/\\d+$`
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
insertCitationMarkers
|
|
18
18
|
} from "../messages/message-citations.js";
|
|
19
19
|
import { soleFence } from "@ai-matrx/content-ir/source";
|
|
20
|
-
import { stripThinkingStreaming } from "@ai-matrx/
|
|
20
|
+
import { stripThinkingStreaming } from "@ai-matrx/content-ir/source";
|
|
21
21
|
const EMPTY_REQUEST_IDS = [];
|
|
22
22
|
const EMPTY_ACTIVE_REQUESTS = [];
|
|
23
23
|
const selectRequest = (requestId) => (state) => state.activeRequests.byRequestId[requestId];
|
|
@@ -66,6 +66,8 @@ export declare const createRequest: import("@reduxjs/toolkit").ActionCreatorWith
|
|
|
66
66
|
requestId: string;
|
|
67
67
|
streamSeq: number;
|
|
68
68
|
streamId?: string | null;
|
|
69
|
+
/** The cursor's per-segment high-water marks (replay dedup survives A→B). */
|
|
70
|
+
marks?: Record<string, number>;
|
|
69
71
|
}, "activeRequests/recordTransportSeq">, setRequestStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
70
72
|
requestId: string;
|
|
71
73
|
status: RequestStatus;
|
|
@@ -269,6 +269,13 @@ const activeRequestsSlice = createSlice({
|
|
|
269
269
|
recordTransportSeq(state, action) {
|
|
270
270
|
const request = state.byRequestId[action.payload.requestId];
|
|
271
271
|
if (!request) return;
|
|
272
|
+
if (action.payload.marks) {
|
|
273
|
+
const merged = { ...request.transportSeqByStream ?? {} };
|
|
274
|
+
for (const [id, seq] of Object.entries(action.payload.marks)) {
|
|
275
|
+
merged[id] = Math.max(merged[id] ?? 0, seq);
|
|
276
|
+
}
|
|
277
|
+
request.transportSeqByStream = merged;
|
|
278
|
+
}
|
|
272
279
|
const streamId = action.payload.streamId ?? null;
|
|
273
280
|
if (streamId && streamId !== request.transportStreamId) {
|
|
274
281
|
request.transportStreamId = streamId;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { supabase } from "../../../../host/db.js";
|
|
2
|
+
import { hasBrowserSession } from "../../../../host/identity.js";
|
|
2
3
|
async function waitForConversationPersisted(conversationId, {
|
|
3
4
|
signal,
|
|
4
5
|
timeoutMs = 18e4,
|
|
5
6
|
intervalMs = 250,
|
|
6
7
|
maxIntervalMs = 1500
|
|
7
8
|
} = {}) {
|
|
8
|
-
|
|
9
|
-
data: { session }
|
|
10
|
-
} = await supabase.auth.getSession();
|
|
11
|
-
if (!session) {
|
|
9
|
+
if (!await hasBrowserSession()) {
|
|
12
10
|
console.info(
|
|
13
11
|
`[conversation-persistence] Guest session \u2014 skipping persistence poll for ${conversationId} (URL stays on /new; server persists under the guest's anonymous user).`
|
|
14
12
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createSlice } from "@reduxjs/toolkit";
|
|
2
|
-
import isEqual from "
|
|
2
|
+
import { deepEqual as isEqual } from "../../../../utils/deep-equal.js";
|
|
3
3
|
import { destroyInstance } from "../conversations/conversations.slice.js";
|
|
4
4
|
import { createInstanceFull } from "../create-instance-full.js";
|
|
5
5
|
import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
|
|
@@ -2,13 +2,15 @@ import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
|
2
2
|
import { submitToolResult } from "../../../api/submit-tool-results.js";
|
|
3
3
|
import { upsertToolLifecycle } from "../active-requests/active-requests.slice.js";
|
|
4
4
|
import { invokeMatrxExtendTool } from "../../../../host/server/extension-bridge.js";
|
|
5
|
+
import { getChatHost, isChatHostConfigured } from "../../../../host/configure.js";
|
|
5
6
|
import { extractErrorMessage } from "@ai-matrx/data/net";
|
|
6
7
|
const dispatchMatrxExtendTool = createAsyncThunk(
|
|
7
8
|
"matrxExtendTools/dispatch",
|
|
8
9
|
async ({ conversationId, requestId, callId, toolName, args }, { dispatch }) => {
|
|
9
10
|
const startedAt = performance.now();
|
|
10
11
|
try {
|
|
11
|
-
const
|
|
12
|
+
const deviceTools = isChatHostConfigured() ? getChatHost().deviceTools : null;
|
|
13
|
+
const invocation = deviceTools ? await deviceTools.invoke(toolName, args, { conversationId, callId }) : await invokeMatrxExtendTool(toolName, args);
|
|
12
14
|
if (!invocation.handled) {
|
|
13
15
|
const message = invocation.reason === "matrx_extend_unavailable" ? `'${toolName}' runs inside the Matrx Extend browser extension, and no Matrx Extend is installed or reachable in this browser right now. Nothing ran and nothing was changed. Tell the user plainly, and ask them to install or enable Matrx Extend and reload this page \u2014 or take a route that does not need the extension.` : `Matrx Extend is installed here, but it does not own a tool named '${toolName}', so nothing ran and nothing was changed. Do not retry the same name: use a tool that is actually offered this turn, or tell the user this capability is not available on this browser.`;
|
|
14
16
|
dispatch(
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "../../../../host/usage-gate.js";
|
|
7
7
|
import { parseNdjsonStream } from "../../../../host/server/stream-parser.js";
|
|
8
8
|
import {
|
|
9
|
+
createStreamReplayCursor,
|
|
9
10
|
isStreamTransportLost,
|
|
10
11
|
readStreamCursor,
|
|
11
12
|
StreamTransportError
|
|
@@ -114,7 +115,7 @@ import {
|
|
|
114
115
|
} from "../instance-context/sync-canvas-item-context.thunk.js";
|
|
115
116
|
import { docKindForContextKey } from "../../../utils/workingDocumentContext.js";
|
|
116
117
|
import { isCanvasItemContextKey } from "../../../utils/canvasItemContext.js";
|
|
117
|
-
import { StreamingJsonTracker } from "@ai-matrx/
|
|
118
|
+
import { StreamingJsonTracker } from "@ai-matrx/content-ir/json-extract";
|
|
118
119
|
import { StreamBlockAccumulator } from "../utils/stream-block-accumulator.js";
|
|
119
120
|
import { deriveAnswerDataText } from "../active-requests/active-requests.selectors.js";
|
|
120
121
|
import { captureError } from "../../../../host/diagnostics.js";
|
|
@@ -143,7 +144,6 @@ import { getCapabilitiesForConversation } from "../../../runtime/get-model-capab
|
|
|
143
144
|
import { toast } from "../../../../host/notify.js";
|
|
144
145
|
import { isDirectiveApplyEvent } from "@ai-matrx/agents/envelope";
|
|
145
146
|
import { proposeDirective } from "../../proposed-directives/proposedDirectivesSlice.js";
|
|
146
|
-
const readTransportCursor = readStreamCursor;
|
|
147
147
|
function renderBlockToContentType(type) {
|
|
148
148
|
if (type === "image" || type === "image_output") return "image";
|
|
149
149
|
if (type === "audio_output") return "audio";
|
|
@@ -395,7 +395,8 @@ async function processStream({
|
|
|
395
395
|
recordTransportSeq({
|
|
396
396
|
requestId,
|
|
397
397
|
streamSeq: cursor.streamSeq,
|
|
398
|
-
streamId: cursor.streamId
|
|
398
|
+
streamId: cursor.streamId,
|
|
399
|
+
marks: cursor.marks
|
|
399
400
|
})
|
|
400
401
|
);
|
|
401
402
|
}
|
|
@@ -455,8 +456,22 @@ async function processStream({
|
|
|
455
456
|
dispatch(setRequestStatus({ requestId, status: "error", error }));
|
|
456
457
|
dispatch(setInstanceStatus({ conversationId, status: "error" }));
|
|
457
458
|
};
|
|
458
|
-
|
|
459
|
-
|
|
459
|
+
const seededRequest = getState().activeRequests.byRequestId[requestId];
|
|
460
|
+
const transportCursor = createStreamReplayCursor({
|
|
461
|
+
seed: {
|
|
462
|
+
streamId: seededRequest?.transportStreamId ?? null,
|
|
463
|
+
lastSeq: seededRequest?.lastTransportSeq ?? 0,
|
|
464
|
+
marks: seededRequest?.transportSeqByStream ?? {}
|
|
465
|
+
},
|
|
466
|
+
// New emitter segment: retain prior rendered content, but make the next
|
|
467
|
+
// client block begin after it. This mirrors a fresh local resume request
|
|
468
|
+
// without blanking the retained viewer.
|
|
469
|
+
onSegmentChange: () => {
|
|
470
|
+
blockAccumulator.rewindToBlockCount(
|
|
471
|
+
getState().activeRequests.byRequestId[requestId]?.renderBlockOrder.length ?? 0
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
});
|
|
460
475
|
let retainedEntry;
|
|
461
476
|
const consume = async (nextResponse, nextAbortController, nextOnEvent) => {
|
|
462
477
|
if (retainedEntry.busy) {
|
|
@@ -480,25 +495,13 @@ async function processStream({
|
|
|
480
495
|
let sawTerminalEvent = false;
|
|
481
496
|
try {
|
|
482
497
|
for await (const event of events) {
|
|
483
|
-
const
|
|
484
|
-
if (
|
|
485
|
-
|
|
486
|
-
if (segmentChanged) {
|
|
487
|
-
blockAccumulator.rewindToBlockCount(
|
|
488
|
-
getState().activeRequests.byRequestId[requestId]?.renderBlockOrder.length ?? 0
|
|
489
|
-
);
|
|
490
|
-
lastTransportSeq = 0;
|
|
491
|
-
}
|
|
492
|
-
if (transportCursor.streamId !== null) {
|
|
493
|
-
transportStreamId = transportCursor.streamId;
|
|
494
|
-
}
|
|
495
|
-
if (transportCursor.streamSeq <= lastTransportSeq) {
|
|
496
|
-
continue;
|
|
497
|
-
}
|
|
498
|
-
lastTransportSeq = transportCursor.streamSeq;
|
|
498
|
+
const stamp = readStreamCursor(event);
|
|
499
|
+
if (stamp !== null) {
|
|
500
|
+
if (!transportCursor.admit(event)) continue;
|
|
499
501
|
pendingTransportCursor = {
|
|
500
|
-
streamSeq:
|
|
501
|
-
streamId:
|
|
502
|
+
streamSeq: stamp.streamSeq,
|
|
503
|
+
streamId: stamp.streamId,
|
|
504
|
+
marks: transportCursor.marks
|
|
502
505
|
};
|
|
503
506
|
scheduleBatchEvent();
|
|
504
507
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractAllJson, extractFirstJson } from "@ai-matrx/
|
|
1
|
+
import { extractAllJson, extractFirstJson } from "@ai-matrx/content-ir/json-extract";
|
|
2
2
|
import { extractErrorMessage } from "@ai-matrx/data/net";
|
|
3
3
|
import { destroyInstanceIfAllowed } from "../conversations/conversations.thunks.js";
|
|
4
4
|
import { captureError } from "../../../../host/diagnostics.js";
|
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
* follower may retry for minutes across a deploy drain by design), and no
|
|
19
19
|
* org header (org rides the conversation body only, like `runAiStream`).
|
|
20
20
|
*/
|
|
21
|
+
import { type FollowServerJobOptions, type ServerJobOutcome } from "@ai-matrx/agents/matrx";
|
|
21
22
|
import type { ResolvedBackend } from "../redux/execution-system/thunks/resolve-base-url.js";
|
|
22
|
-
import type {
|
|
23
|
+
import type { RuntimeOperationsByLinkResponse } from "./types.js";
|
|
23
24
|
/**
|
|
24
25
|
* `GET /runtime/operations/by-link/conversation/{conversationId}` — the
|
|
25
26
|
* identify step. Returns `null` when the surface is absent or the caller owns
|
|
@@ -27,29 +28,9 @@ import type { RuntimeExecutionStatus, RuntimeOperationEvent, RuntimeOperationsBy
|
|
|
27
28
|
* shape by design); throws on other failures.
|
|
28
29
|
*/
|
|
29
30
|
export declare function fetchOperationsByLink(backend: ResolvedBackend, conversationId: string, signal?: AbortSignal): Promise<RuntimeOperationsByLinkResponse | null>;
|
|
30
|
-
export interface FollowOperationResult {
|
|
31
|
-
/** True when the server sent the terminal `end` frame. */
|
|
32
|
-
ended: boolean;
|
|
33
|
-
/** The root status carried on the `end` frame (when `ended`). */
|
|
34
|
-
status: RuntimeExecutionStatus | null;
|
|
35
|
-
}
|
|
36
|
-
export interface FollowOperationOptions {
|
|
37
|
-
backend: ResolvedBackend;
|
|
38
|
-
executionId: string;
|
|
39
|
-
/** Resume cursor — the operation view's `last_event_seq` (0 = from start). */
|
|
40
|
-
lastEventSeq: number;
|
|
41
|
-
/** Caller teardown — aborting resolves the promise with `ended: false`. */
|
|
42
|
-
signal: AbortSignal;
|
|
43
|
-
/** Fired per durable spine event (lifecycle transitions + notes). */
|
|
44
|
-
onEvent: (event: RuntimeOperationEvent, seq: number | null) => void;
|
|
45
|
-
}
|
|
46
31
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* (
|
|
50
|
-
* `end` frame (the operation settled); `{ended: false}` when the caller
|
|
51
|
-
* aborted or every reconnect attempt failed. A WAITING_INPUT park keeps the
|
|
52
|
-
* stream open by design — a resume re-attaches to the same execution and its
|
|
53
|
-
* events continue arriving here on the same cursor.
|
|
32
|
+
* Identify → rejoin → follow → settle for one conversation, on the shared
|
|
33
|
+
* `followServerJob` core over this backend's channel. Chat supplies only its
|
|
34
|
+
* wiring (the Redux rejoin consumer, banner callbacks, `loadConversation`).
|
|
54
35
|
*/
|
|
55
|
-
export declare function
|
|
36
|
+
export declare function followConversationServerJob(backend: ResolvedBackend, conversationId: string, options: Omit<FollowServerJobOptions, "target">): Promise<ServerJobOutcome>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMatrxTransport,
|
|
3
|
-
|
|
3
|
+
followServerJob,
|
|
4
4
|
getRuntimeOperationsByLink
|
|
5
5
|
} from "@ai-matrx/agents/matrx";
|
|
6
6
|
function transportFor(backend) {
|
|
@@ -21,19 +21,13 @@ async function fetchOperationsByLink(backend, conversationId, signal) {
|
|
|
21
21
|
{ limit: 5, ...signal ? { signal } : {} }
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
lastEventSeq: opts.lastEventSeq,
|
|
30
|
-
signal: opts.signal,
|
|
31
|
-
onEvent: (event, seq) => opts.onEvent(event, seq)
|
|
32
|
-
}
|
|
33
|
-
);
|
|
34
|
-
return { ended: result.ended, status: result.status };
|
|
24
|
+
function followConversationServerJob(backend, conversationId, options) {
|
|
25
|
+
return followServerJob(transportFor(backend), {
|
|
26
|
+
...options,
|
|
27
|
+
target: { linkKind: "conversation", linkId: conversationId }
|
|
28
|
+
});
|
|
35
29
|
}
|
|
36
30
|
export {
|
|
37
31
|
fetchOperationsByLink,
|
|
38
|
-
|
|
32
|
+
followConversationServerJob
|
|
39
33
|
};
|