doover-js 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apis/messages-api.d.ts +27 -5
- package/dist/apis/messages-api.js +13 -3
- package/dist/esm/apis/messages-api.d.ts +27 -5
- package/dist/esm/apis/messages-api.js +13 -3
- package/dist/esm/package.json +1 -1
- package/dist/esm/react/index.d.ts +1 -1
- package/dist/esm/react/index.js +1 -1
- package/dist/esm/react/useMultiAgentChannelMessages.d.ts +21 -1
- package/dist/esm/react/useMultiAgentChannelMessages.js +51 -4
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/useMultiAgentChannelMessages.d.ts +21 -1
- package/dist/react/useMultiAgentChannelMessages.js +52 -4
- package/package.json +1 -1
|
@@ -20,10 +20,32 @@ export interface ListMessagesParams {
|
|
|
20
20
|
* index 0.
|
|
21
21
|
*/
|
|
22
22
|
order?: "asc" | "desc";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `getTimeseries` options. The endpoint always returns `{ results, count,
|
|
26
|
+
* next }`: while `next` is set there's more, and passing it back as `before`
|
|
27
|
+
* continues newest → oldest.
|
|
28
|
+
*/
|
|
29
|
+
export interface TimeseriesParams {
|
|
30
|
+
/** Exclusive upper bound, and the paging cursor (a response's `next`). */
|
|
31
|
+
before?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Lower bound. A missing bound is filled a week from the other, so unlike
|
|
34
|
+
* `listMessages`, `after` on its own doesn't page forward: it reads the
|
|
35
|
+
* newest `limit` points in the week after it.
|
|
36
|
+
*/
|
|
37
|
+
after?: string;
|
|
38
|
+
/** Points per page; the server sends 50 without it and allows 1500. */
|
|
39
|
+
limit?: number;
|
|
40
|
+
field_name?: string[];
|
|
41
|
+
/**
|
|
42
|
+
* `"desc"` (default) keeps the server's newest-first order; `"asc"`
|
|
43
|
+
* reverses each page client-side so the oldest point is at index 0.
|
|
44
|
+
*/
|
|
45
|
+
order?: "asc" | "desc";
|
|
23
46
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* back as `before` to page through results.
|
|
47
|
+
* @deprecated No effect, and no longer sent: the endpoint has no such
|
|
48
|
+
* parameter and always returns `next`.
|
|
27
49
|
*/
|
|
28
50
|
paginate?: boolean;
|
|
29
51
|
}
|
|
@@ -52,11 +74,11 @@ export declare class MessagesApi {
|
|
|
52
74
|
channelName: string;
|
|
53
75
|
}, body: MessageBody): Promise<MessageStructure>;
|
|
54
76
|
private _postMessage;
|
|
55
|
-
getTimeseries(agentId: string, channelName: string, params:
|
|
77
|
+
getTimeseries(agentId: string, channelName: string, params: TimeseriesParams): Promise<DataSeries>;
|
|
56
78
|
getTimeseries(identifier: {
|
|
57
79
|
agentId: string;
|
|
58
80
|
channelName: string;
|
|
59
|
-
}, params:
|
|
81
|
+
}, params: TimeseriesParams): Promise<DataSeries>;
|
|
60
82
|
private _getTimeseries;
|
|
61
83
|
getMessage(agentId: string, channelName: string, messageId: string): Promise<MessageStructure>;
|
|
62
84
|
getMessage(identifier: {
|
|
@@ -66,9 +66,19 @@ class MessagesApi {
|
|
|
66
66
|
const { agentId, channelName, options } = (0, _args_js_1.resolveChannelArgs)(args);
|
|
67
67
|
return this._getTimeseries(agentId, channelName, options);
|
|
68
68
|
}
|
|
69
|
-
_getTimeseries(agentId, channelName, params) {
|
|
70
|
-
const { order:
|
|
71
|
-
|
|
69
|
+
async _getTimeseries(agentId, channelName, params) {
|
|
70
|
+
const { order, paginate: _paginate, ...query } = params;
|
|
71
|
+
const series = await this.rest.get(`/agents/${agentId}/channels/${channelName}/messages/timeseries`, query);
|
|
72
|
+
// Older servers sent `next` as a JSON number; keep the declared string
|
|
73
|
+
// type (the digits past 2^53 were already rounded in parsing).
|
|
74
|
+
const next = series.next;
|
|
75
|
+
return {
|
|
76
|
+
...series,
|
|
77
|
+
...(typeof next === "number" ? { next: String(next) } : {}),
|
|
78
|
+
results: order === "asc" && series.results
|
|
79
|
+
? [...series.results].reverse()
|
|
80
|
+
: series.results,
|
|
81
|
+
};
|
|
72
82
|
}
|
|
73
83
|
async getMessage(...args) {
|
|
74
84
|
if (typeof args[0] === "string") {
|
|
@@ -20,10 +20,32 @@ export interface ListMessagesParams {
|
|
|
20
20
|
* index 0.
|
|
21
21
|
*/
|
|
22
22
|
order?: "asc" | "desc";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* `getTimeseries` options. The endpoint always returns `{ results, count,
|
|
26
|
+
* next }`: while `next` is set there's more, and passing it back as `before`
|
|
27
|
+
* continues newest → oldest.
|
|
28
|
+
*/
|
|
29
|
+
export interface TimeseriesParams {
|
|
30
|
+
/** Exclusive upper bound, and the paging cursor (a response's `next`). */
|
|
31
|
+
before?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Lower bound. A missing bound is filled a week from the other, so unlike
|
|
34
|
+
* `listMessages`, `after` on its own doesn't page forward: it reads the
|
|
35
|
+
* newest `limit` points in the week after it.
|
|
36
|
+
*/
|
|
37
|
+
after?: string;
|
|
38
|
+
/** Points per page; the server sends 50 without it and allows 1500. */
|
|
39
|
+
limit?: number;
|
|
40
|
+
field_name?: string[];
|
|
41
|
+
/**
|
|
42
|
+
* `"desc"` (default) keeps the server's newest-first order; `"asc"`
|
|
43
|
+
* reverses each page client-side so the oldest point is at index 0.
|
|
44
|
+
*/
|
|
45
|
+
order?: "asc" | "desc";
|
|
23
46
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* back as `before` to page through results.
|
|
47
|
+
* @deprecated No effect, and no longer sent: the endpoint has no such
|
|
48
|
+
* parameter and always returns `next`.
|
|
27
49
|
*/
|
|
28
50
|
paginate?: boolean;
|
|
29
51
|
}
|
|
@@ -52,11 +74,11 @@ export declare class MessagesApi {
|
|
|
52
74
|
channelName: string;
|
|
53
75
|
}, body: MessageBody): Promise<MessageStructure>;
|
|
54
76
|
private _postMessage;
|
|
55
|
-
getTimeseries(agentId: string, channelName: string, params:
|
|
77
|
+
getTimeseries(agentId: string, channelName: string, params: TimeseriesParams): Promise<DataSeries>;
|
|
56
78
|
getTimeseries(identifier: {
|
|
57
79
|
agentId: string;
|
|
58
80
|
channelName: string;
|
|
59
|
-
}, params:
|
|
81
|
+
}, params: TimeseriesParams): Promise<DataSeries>;
|
|
60
82
|
private _getTimeseries;
|
|
61
83
|
getMessage(agentId: string, channelName: string, messageId: string): Promise<MessageStructure>;
|
|
62
84
|
getMessage(identifier: {
|
|
@@ -63,9 +63,19 @@ export class MessagesApi {
|
|
|
63
63
|
const { agentId, channelName, options } = resolveChannelArgs(args);
|
|
64
64
|
return this._getTimeseries(agentId, channelName, options);
|
|
65
65
|
}
|
|
66
|
-
_getTimeseries(agentId, channelName, params) {
|
|
67
|
-
const { order:
|
|
68
|
-
|
|
66
|
+
async _getTimeseries(agentId, channelName, params) {
|
|
67
|
+
const { order, paginate: _paginate, ...query } = params;
|
|
68
|
+
const series = await this.rest.get(`/agents/${agentId}/channels/${channelName}/messages/timeseries`, query);
|
|
69
|
+
// Older servers sent `next` as a JSON number; keep the declared string
|
|
70
|
+
// type (the digits past 2^53 were already rounded in parsing).
|
|
71
|
+
const next = series.next;
|
|
72
|
+
return {
|
|
73
|
+
...series,
|
|
74
|
+
...(typeof next === "number" ? { next: String(next) } : {}),
|
|
75
|
+
results: order === "asc" && series.results
|
|
76
|
+
? [...series.results].reverse()
|
|
77
|
+
: series.results,
|
|
78
|
+
};
|
|
69
79
|
}
|
|
70
80
|
async getMessage(...args) {
|
|
71
81
|
if (typeof args[0] === "string") {
|
package/dist/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"doover-js","version":"0.
|
|
1
|
+
{"name":"doover-js","version":"0.14.0","type":"module","sideEffects":false}
|
|
@@ -28,7 +28,7 @@ export { useSendRpc } from "./useSendRpc.js";
|
|
|
28
28
|
export type { RpcCommandId, RpcStatusEvent, SendRpcVariables, UseSendRpcOptions, UseSendRpcResult, } from "./useSendRpc.js";
|
|
29
29
|
export { useMultiAgentAggregates, multiAgentAggregatesQueryKey, } from "./useMultiAgentAggregates.js";
|
|
30
30
|
export type { UseMultiAgentAggregatesOptions, UseMultiAgentAggregatesResult, } from "./useMultiAgentAggregates.js";
|
|
31
|
-
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, } from "./useMultiAgentChannelMessages.js";
|
|
31
|
+
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, MULTI_AGENT_MAX_WINDOW_MS, } from "./useMultiAgentChannelMessages.js";
|
|
32
32
|
export type { UseMultiAgentChannelMessagesOptions, UseMultiAgentChannelMessagesResult, } from "./useMultiAgentChannelMessages.js";
|
|
33
33
|
export { useDeviceMap } from "./useDeviceMap.js";
|
|
34
34
|
export type { DeviceMapEntry, UseDeviceMapOptions, UseDeviceMapResult, } from "./useDeviceMap.js";
|
package/dist/esm/react/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export { useChannelMessage, channelMessageQueryKey, } from "./useChannelMessage.
|
|
|
14
14
|
export { useInvocationLogs, invocationLogsQueryKey, } from "./useInvocationLogs.js";
|
|
15
15
|
export { useSendRpc } from "./useSendRpc.js";
|
|
16
16
|
export { useMultiAgentAggregates, multiAgentAggregatesQueryKey, } from "./useMultiAgentAggregates.js";
|
|
17
|
-
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, } from "./useMultiAgentChannelMessages.js";
|
|
17
|
+
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, MULTI_AGENT_MAX_WINDOW_MS, } from "./useMultiAgentChannelMessages.js";
|
|
18
18
|
export { useDeviceMap } from "./useDeviceMap.js";
|
|
19
19
|
export { useTurnCredentials } from "./useTurnCredentials.js";
|
|
20
20
|
export { useAgentTokenState, useSetAgentTokenPolicy, useSetAgentAuthLock, useRevokeAgentTokens, useSetRevocationFloor, useCreateAdhocToken, useCreateDeviceToken, agentTokenStateQueryKey, } from "./useAgentTokenState.js";
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type InfiniteData, type UseInfiniteQueryResult } from "@tanstack/react-query";
|
|
2
2
|
import type { MessageStructure } from "../types/common.js";
|
|
3
|
+
/**
|
|
4
|
+
* Widest `before - after` span one multi-agent request may cover. The server
|
|
5
|
+
* caps it at 7 days (it walks each agent's history a day at a time); the
|
|
6
|
+
* minute's margin keeps each request clear of the cap. Longer ranges are
|
|
7
|
+
* read as a series of these, newest first.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MULTI_AGENT_MAX_WINDOW_MS: number;
|
|
3
10
|
export declare function multiAgentChannelMessagesQueryKey(channelName: string, agentIds: string[], sources?: string[], scope?: {
|
|
4
11
|
after?: string;
|
|
5
12
|
fields?: readonly string[];
|
|
@@ -25,7 +32,12 @@ export interface UseMultiAgentChannelMessagesOptions {
|
|
|
25
32
|
* of these top-level field names. Forwarded as `field_name`.
|
|
26
33
|
*/
|
|
27
34
|
fields?: string[];
|
|
28
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Optional first-page `before` cursor (snowflake id). With `after`, it
|
|
37
|
+
* bounds a time range, which may be wider than the server's 7-day cap:
|
|
38
|
+
* the range is then read a window at a time, each further window arriving
|
|
39
|
+
* as more pages (see `after`).
|
|
40
|
+
*/
|
|
29
41
|
initialBefore?: string;
|
|
30
42
|
/**
|
|
31
43
|
* Keep paging older automatically until `hasNextPage` is false. Each page
|
|
@@ -48,6 +60,14 @@ export interface UseMultiAgentChannelMessagesOptions {
|
|
|
48
60
|
* mirrors `useChannelMessages`'s `after`. Use this to fetch a bounded
|
|
49
61
|
* time window (e.g. last 24h) across many agents without filtering
|
|
50
62
|
* on the client.
|
|
63
|
+
*
|
|
64
|
+
* With `initialBefore` more than `MULTI_AGENT_MAX_WINDOW_MS` before it, the
|
|
65
|
+
* range is split into windows the server accepts, read newest first:
|
|
66
|
+
* `fetchNextPage` finishes one window's per-agent cursors, then moves on
|
|
67
|
+
* to the next window, and `hasNextPage` stays true until the whole range
|
|
68
|
+
* is read. A quiet window can come back empty, so fetch on until you have
|
|
69
|
+
* what you need (or set `autoPaginate`, raising `maxPages` for a long
|
|
70
|
+
* range: a year is 53 windows).
|
|
51
71
|
*/
|
|
52
72
|
after?: string;
|
|
53
73
|
/**
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo } from "react";
|
|
2
2
|
import { useInfiniteQuery, useQueryClient, } from "@tanstack/react-query";
|
|
3
3
|
import { useDooverClient } from "./context.js";
|
|
4
|
+
/**
|
|
5
|
+
* Widest `before - after` span one multi-agent request may cover. The server
|
|
6
|
+
* caps it at 7 days (it walks each agent's history a day at a time); the
|
|
7
|
+
* minute's margin keeps each request clear of the cap. Longer ranges are
|
|
8
|
+
* read as a series of these, newest first.
|
|
9
|
+
*/
|
|
10
|
+
export const MULTI_AGENT_MAX_WINDOW_MS = 7 * 24 * 60 * 60 * 1000 - 60000;
|
|
11
|
+
/** The window above as a snowflake-id delta (ids carry ms in bits 22+). */
|
|
12
|
+
const MAX_WINDOW_ID_SPAN = BigInt(MULTI_AGENT_MAX_WINDOW_MS) << 22n;
|
|
4
13
|
export function multiAgentChannelMessagesQueryKey(channelName, agentIds, sources, scope) {
|
|
5
14
|
const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
|
|
6
15
|
const base = [
|
|
@@ -26,6 +35,31 @@ export function multiAgentChannelMessagesQueryKey(channelName, agentIds, sources
|
|
|
26
35
|
? [...base, scopeKey]
|
|
27
36
|
: base;
|
|
28
37
|
}
|
|
38
|
+
/** The window ending at `before`, reaching back no further than `after`. */
|
|
39
|
+
function windowEndingAt(before, after) {
|
|
40
|
+
const start = BigInt(before) - MAX_WINDOW_ID_SPAN;
|
|
41
|
+
const floor = BigInt(after);
|
|
42
|
+
return {
|
|
43
|
+
windowBefore: before,
|
|
44
|
+
windowAfter: (start > floor ? start : floor).toString(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Within a windowed range: carry on inside the current window, or once it's
|
|
49
|
+
* drained, step back to the window before it until the range's `after`.
|
|
50
|
+
*/
|
|
51
|
+
function nextWindowedPageParam(lastPage, lastParam, after) {
|
|
52
|
+
const { windowBefore, windowAfter } = lastParam;
|
|
53
|
+
if (windowBefore === undefined || windowAfter === undefined) {
|
|
54
|
+
return nextPageParam(lastPage);
|
|
55
|
+
}
|
|
56
|
+
const within = nextPageParam(lastPage);
|
|
57
|
+
if (within)
|
|
58
|
+
return { ...within, windowBefore, windowAfter };
|
|
59
|
+
if (BigInt(windowAfter) <= BigInt(after))
|
|
60
|
+
return undefined;
|
|
61
|
+
return windowEndingAt(windowAfter, after);
|
|
62
|
+
}
|
|
29
63
|
function nextPageParam(lastPage) {
|
|
30
64
|
if (!lastPage)
|
|
31
65
|
return undefined;
|
|
@@ -107,23 +141,36 @@ export function useMultiAgentChannelMessages(channelName, agentIds, options) {
|
|
|
107
141
|
};
|
|
108
142
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
109
143
|
}, [client, channelName, liveUpdates, agentIds.join(",")]);
|
|
144
|
+
// A range wider than the server accepts in one request is read a window
|
|
145
|
+
// at a time; narrower ones (and open-ended reads) are one window as ever.
|
|
146
|
+
const windowed = after !== undefined &&
|
|
147
|
+
initialBefore !== undefined &&
|
|
148
|
+
BigInt(initialBefore) - BigInt(after) > MAX_WINDOW_ID_SPAN;
|
|
110
149
|
const query = useInfiniteQuery({
|
|
111
150
|
queryKey: key,
|
|
112
151
|
enabled: agentIds.length > 0,
|
|
113
152
|
staleTime: Infinity,
|
|
114
|
-
initialPageParam: (
|
|
115
|
-
|
|
153
|
+
initialPageParam: (windowed
|
|
154
|
+
? windowEndingAt(initialBefore, after)
|
|
155
|
+
: initialBefore
|
|
156
|
+
? { before: initialBefore }
|
|
157
|
+
: {}),
|
|
158
|
+
getNextPageParam: (lastPage, _allPages, lastParam) => windowed
|
|
159
|
+
? nextWindowedPageParam(lastPage, lastParam, after)
|
|
160
|
+
: nextPageParam(lastPage),
|
|
116
161
|
queryFn: async ({ pageParam }) => {
|
|
162
|
+
const before = pageParam.before ?? pageParam.windowBefore;
|
|
163
|
+
const lowerBound = pageParam.windowAfter ?? after;
|
|
117
164
|
const params = {
|
|
118
165
|
agent_id: pageParam.agentIds ?? agentIds,
|
|
119
|
-
...(
|
|
166
|
+
...(before ? { before } : {}),
|
|
120
167
|
...(pageParam.agentBefore ? { agent_before: pageParam.agentBefore } : {}),
|
|
121
168
|
...(limit !== undefined ? { limit } : {}),
|
|
122
169
|
...(agentMessageLimit !== undefined
|
|
123
170
|
? { agent_message_limit: agentMessageLimit }
|
|
124
171
|
: {}),
|
|
125
172
|
...(fields && fields.length > 0 ? { field_name: fields } : {}),
|
|
126
|
-
...(
|
|
173
|
+
...(lowerBound !== undefined ? { after: lowerBound } : {}),
|
|
127
174
|
};
|
|
128
175
|
// Pass `{ sources }` as a trailing bag only when set — cast through
|
|
129
176
|
// `never` since the TypeScript overloads don't declare it.
|
package/dist/react/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export { useSendRpc } from "./useSendRpc.js";
|
|
|
28
28
|
export type { RpcCommandId, RpcStatusEvent, SendRpcVariables, UseSendRpcOptions, UseSendRpcResult, } from "./useSendRpc.js";
|
|
29
29
|
export { useMultiAgentAggregates, multiAgentAggregatesQueryKey, } from "./useMultiAgentAggregates.js";
|
|
30
30
|
export type { UseMultiAgentAggregatesOptions, UseMultiAgentAggregatesResult, } from "./useMultiAgentAggregates.js";
|
|
31
|
-
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, } from "./useMultiAgentChannelMessages.js";
|
|
31
|
+
export { useMultiAgentChannelMessages, multiAgentChannelMessagesQueryKey, MULTI_AGENT_MAX_WINDOW_MS, } from "./useMultiAgentChannelMessages.js";
|
|
32
32
|
export type { UseMultiAgentChannelMessagesOptions, UseMultiAgentChannelMessagesResult, } from "./useMultiAgentChannelMessages.js";
|
|
33
33
|
export { useDeviceMap } from "./useDeviceMap.js";
|
|
34
34
|
export type { DeviceMapEntry, UseDeviceMapOptions, UseDeviceMapResult, } from "./useDeviceMap.js";
|
package/dist/react/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useServiceReachability = exports.resetSharedQueryClient = exports.getSharedQueryClient = exports.agentTokenStateQueryKey = exports.useCreateDeviceToken = exports.useCreateAdhocToken = exports.useSetRevocationFloor = exports.useRevokeAgentTokens = exports.useSetAgentAuthLock = exports.useSetAgentTokenPolicy = exports.useAgentTokenState = exports.useTurnCredentials = exports.useDeviceMap = exports.multiAgentChannelMessagesQueryKey = exports.useMultiAgentChannelMessages = exports.multiAgentAggregatesQueryKey = exports.useMultiAgentAggregates = exports.useSendRpc = exports.invocationLogsQueryKey = exports.useInvocationLogs = exports.channelMessageQueryKey = exports.useChannelMessage = exports.channelMessagesQueryKey = exports.useChannelMessages = exports.useUpdateMessage = exports.useUpdateAggregate = exports.useSendMessage = exports.useAgentChannel = exports.channelAggregateQueryKey = exports.useChannelAggregate = exports.useChannelSubscription = exports.agentConnectionsQueryKey = exports.useAgentConnections = exports.useConnectionState = exports.hasOfflineStatus = exports.useOfflineStatus = exports.useClientStatus = exports.useDooverClient = exports.DooverProvider = void 0;
|
|
3
|
+
exports.useServiceReachability = exports.resetSharedQueryClient = exports.getSharedQueryClient = exports.agentTokenStateQueryKey = exports.useCreateDeviceToken = exports.useCreateAdhocToken = exports.useSetRevocationFloor = exports.useRevokeAgentTokens = exports.useSetAgentAuthLock = exports.useSetAgentTokenPolicy = exports.useAgentTokenState = exports.useTurnCredentials = exports.useDeviceMap = exports.MULTI_AGENT_MAX_WINDOW_MS = exports.multiAgentChannelMessagesQueryKey = exports.useMultiAgentChannelMessages = exports.multiAgentAggregatesQueryKey = exports.useMultiAgentAggregates = exports.useSendRpc = exports.invocationLogsQueryKey = exports.useInvocationLogs = exports.channelMessageQueryKey = exports.useChannelMessage = exports.channelMessagesQueryKey = exports.useChannelMessages = exports.useUpdateMessage = exports.useUpdateAggregate = exports.useSendMessage = exports.useAgentChannel = exports.channelAggregateQueryKey = exports.useChannelAggregate = exports.useChannelSubscription = exports.agentConnectionsQueryKey = exports.useAgentConnections = exports.useConnectionState = exports.hasOfflineStatus = exports.useOfflineStatus = exports.useClientStatus = exports.useDooverClient = exports.DooverProvider = void 0;
|
|
4
4
|
var context_js_1 = require("./context.js");
|
|
5
5
|
Object.defineProperty(exports, "DooverProvider", { enumerable: true, get: function () { return context_js_1.DooverProvider; } });
|
|
6
6
|
Object.defineProperty(exports, "useDooverClient", { enumerable: true, get: function () { return context_js_1.useDooverClient; } });
|
|
@@ -44,6 +44,7 @@ Object.defineProperty(exports, "multiAgentAggregatesQueryKey", { enumerable: tru
|
|
|
44
44
|
var useMultiAgentChannelMessages_js_1 = require("./useMultiAgentChannelMessages.js");
|
|
45
45
|
Object.defineProperty(exports, "useMultiAgentChannelMessages", { enumerable: true, get: function () { return useMultiAgentChannelMessages_js_1.useMultiAgentChannelMessages; } });
|
|
46
46
|
Object.defineProperty(exports, "multiAgentChannelMessagesQueryKey", { enumerable: true, get: function () { return useMultiAgentChannelMessages_js_1.multiAgentChannelMessagesQueryKey; } });
|
|
47
|
+
Object.defineProperty(exports, "MULTI_AGENT_MAX_WINDOW_MS", { enumerable: true, get: function () { return useMultiAgentChannelMessages_js_1.MULTI_AGENT_MAX_WINDOW_MS; } });
|
|
47
48
|
var useDeviceMap_js_1 = require("./useDeviceMap.js");
|
|
48
49
|
Object.defineProperty(exports, "useDeviceMap", { enumerable: true, get: function () { return useDeviceMap_js_1.useDeviceMap; } });
|
|
49
50
|
var useTurnCredentials_js_1 = require("./useTurnCredentials.js");
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { type InfiniteData, type UseInfiniteQueryResult } from "@tanstack/react-query";
|
|
2
2
|
import type { MessageStructure } from "../types/common.js";
|
|
3
|
+
/**
|
|
4
|
+
* Widest `before - after` span one multi-agent request may cover. The server
|
|
5
|
+
* caps it at 7 days (it walks each agent's history a day at a time); the
|
|
6
|
+
* minute's margin keeps each request clear of the cap. Longer ranges are
|
|
7
|
+
* read as a series of these, newest first.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MULTI_AGENT_MAX_WINDOW_MS: number;
|
|
3
10
|
export declare function multiAgentChannelMessagesQueryKey(channelName: string, agentIds: string[], sources?: string[], scope?: {
|
|
4
11
|
after?: string;
|
|
5
12
|
fields?: readonly string[];
|
|
@@ -25,7 +32,12 @@ export interface UseMultiAgentChannelMessagesOptions {
|
|
|
25
32
|
* of these top-level field names. Forwarded as `field_name`.
|
|
26
33
|
*/
|
|
27
34
|
fields?: string[];
|
|
28
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Optional first-page `before` cursor (snowflake id). With `after`, it
|
|
37
|
+
* bounds a time range, which may be wider than the server's 7-day cap:
|
|
38
|
+
* the range is then read a window at a time, each further window arriving
|
|
39
|
+
* as more pages (see `after`).
|
|
40
|
+
*/
|
|
29
41
|
initialBefore?: string;
|
|
30
42
|
/**
|
|
31
43
|
* Keep paging older automatically until `hasNextPage` is false. Each page
|
|
@@ -48,6 +60,14 @@ export interface UseMultiAgentChannelMessagesOptions {
|
|
|
48
60
|
* mirrors `useChannelMessages`'s `after`. Use this to fetch a bounded
|
|
49
61
|
* time window (e.g. last 24h) across many agents without filtering
|
|
50
62
|
* on the client.
|
|
63
|
+
*
|
|
64
|
+
* With `initialBefore` more than `MULTI_AGENT_MAX_WINDOW_MS` before it, the
|
|
65
|
+
* range is split into windows the server accepts, read newest first:
|
|
66
|
+
* `fetchNextPage` finishes one window's per-agent cursors, then moves on
|
|
67
|
+
* to the next window, and `hasNextPage` stays true until the whole range
|
|
68
|
+
* is read. A quiet window can come back empty, so fetch on until you have
|
|
69
|
+
* what you need (or set `autoPaginate`, raising `maxPages` for a long
|
|
70
|
+
* range: a year is 53 windows).
|
|
51
71
|
*/
|
|
52
72
|
after?: string;
|
|
53
73
|
/**
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MULTI_AGENT_MAX_WINDOW_MS = void 0;
|
|
3
4
|
exports.multiAgentChannelMessagesQueryKey = multiAgentChannelMessagesQueryKey;
|
|
4
5
|
exports.useMultiAgentChannelMessages = useMultiAgentChannelMessages;
|
|
5
6
|
const react_1 = require("react");
|
|
6
7
|
const react_query_1 = require("@tanstack/react-query");
|
|
7
8
|
const context_js_1 = require("./context.js");
|
|
9
|
+
/**
|
|
10
|
+
* Widest `before - after` span one multi-agent request may cover. The server
|
|
11
|
+
* caps it at 7 days (it walks each agent's history a day at a time); the
|
|
12
|
+
* minute's margin keeps each request clear of the cap. Longer ranges are
|
|
13
|
+
* read as a series of these, newest first.
|
|
14
|
+
*/
|
|
15
|
+
exports.MULTI_AGENT_MAX_WINDOW_MS = 7 * 24 * 60 * 60 * 1000 - 60000;
|
|
16
|
+
/** The window above as a snowflake-id delta (ids carry ms in bits 22+). */
|
|
17
|
+
const MAX_WINDOW_ID_SPAN = BigInt(exports.MULTI_AGENT_MAX_WINDOW_MS) << 22n;
|
|
8
18
|
function multiAgentChannelMessagesQueryKey(channelName, agentIds, sources, scope) {
|
|
9
19
|
const sourceDim = sources && sources.length ? [...sources].sort().join(",") : "*";
|
|
10
20
|
const base = [
|
|
@@ -30,6 +40,31 @@ function multiAgentChannelMessagesQueryKey(channelName, agentIds, sources, scope
|
|
|
30
40
|
? [...base, scopeKey]
|
|
31
41
|
: base;
|
|
32
42
|
}
|
|
43
|
+
/** The window ending at `before`, reaching back no further than `after`. */
|
|
44
|
+
function windowEndingAt(before, after) {
|
|
45
|
+
const start = BigInt(before) - MAX_WINDOW_ID_SPAN;
|
|
46
|
+
const floor = BigInt(after);
|
|
47
|
+
return {
|
|
48
|
+
windowBefore: before,
|
|
49
|
+
windowAfter: (start > floor ? start : floor).toString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Within a windowed range: carry on inside the current window, or once it's
|
|
54
|
+
* drained, step back to the window before it until the range's `after`.
|
|
55
|
+
*/
|
|
56
|
+
function nextWindowedPageParam(lastPage, lastParam, after) {
|
|
57
|
+
const { windowBefore, windowAfter } = lastParam;
|
|
58
|
+
if (windowBefore === undefined || windowAfter === undefined) {
|
|
59
|
+
return nextPageParam(lastPage);
|
|
60
|
+
}
|
|
61
|
+
const within = nextPageParam(lastPage);
|
|
62
|
+
if (within)
|
|
63
|
+
return { ...within, windowBefore, windowAfter };
|
|
64
|
+
if (BigInt(windowAfter) <= BigInt(after))
|
|
65
|
+
return undefined;
|
|
66
|
+
return windowEndingAt(windowAfter, after);
|
|
67
|
+
}
|
|
33
68
|
function nextPageParam(lastPage) {
|
|
34
69
|
if (!lastPage)
|
|
35
70
|
return undefined;
|
|
@@ -111,23 +146,36 @@ function useMultiAgentChannelMessages(channelName, agentIds, options) {
|
|
|
111
146
|
};
|
|
112
147
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
113
148
|
}, [client, channelName, liveUpdates, agentIds.join(",")]);
|
|
149
|
+
// A range wider than the server accepts in one request is read a window
|
|
150
|
+
// at a time; narrower ones (and open-ended reads) are one window as ever.
|
|
151
|
+
const windowed = after !== undefined &&
|
|
152
|
+
initialBefore !== undefined &&
|
|
153
|
+
BigInt(initialBefore) - BigInt(after) > MAX_WINDOW_ID_SPAN;
|
|
114
154
|
const query = (0, react_query_1.useInfiniteQuery)({
|
|
115
155
|
queryKey: key,
|
|
116
156
|
enabled: agentIds.length > 0,
|
|
117
157
|
staleTime: Infinity,
|
|
118
|
-
initialPageParam: (
|
|
119
|
-
|
|
158
|
+
initialPageParam: (windowed
|
|
159
|
+
? windowEndingAt(initialBefore, after)
|
|
160
|
+
: initialBefore
|
|
161
|
+
? { before: initialBefore }
|
|
162
|
+
: {}),
|
|
163
|
+
getNextPageParam: (lastPage, _allPages, lastParam) => windowed
|
|
164
|
+
? nextWindowedPageParam(lastPage, lastParam, after)
|
|
165
|
+
: nextPageParam(lastPage),
|
|
120
166
|
queryFn: async ({ pageParam }) => {
|
|
167
|
+
const before = pageParam.before ?? pageParam.windowBefore;
|
|
168
|
+
const lowerBound = pageParam.windowAfter ?? after;
|
|
121
169
|
const params = {
|
|
122
170
|
agent_id: pageParam.agentIds ?? agentIds,
|
|
123
|
-
...(
|
|
171
|
+
...(before ? { before } : {}),
|
|
124
172
|
...(pageParam.agentBefore ? { agent_before: pageParam.agentBefore } : {}),
|
|
125
173
|
...(limit !== undefined ? { limit } : {}),
|
|
126
174
|
...(agentMessageLimit !== undefined
|
|
127
175
|
? { agent_message_limit: agentMessageLimit }
|
|
128
176
|
: {}),
|
|
129
177
|
...(fields && fields.length > 0 ? { field_name: fields } : {}),
|
|
130
|
-
...(
|
|
178
|
+
...(lowerBound !== undefined ? { after: lowerBound } : {}),
|
|
131
179
|
};
|
|
132
180
|
// Pass `{ sources }` as a trailing bag only when set — cast through
|
|
133
181
|
// `never` since the TypeScript overloads don't declare it.
|