@assistant-ui/eve 0.0.18 → 0.0.20
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/LICENSE +1 -1
- package/dist/convertEveMessages.d.ts +31 -33
- package/dist/convertEveMessages.d.ts.map +1 -1
- package/dist/deriveCreatedAt.d.ts +5 -7
- package/dist/deriveCreatedAt.d.ts.map +1 -1
- package/dist/deriveCreatedAt.js +1 -0
- package/dist/deriveCreatedAt.js.map +1 -1
- package/dist/eveCloudSessions.d.ts +9 -0
- package/dist/eveCloudSessions.d.ts.map +1 -0
- package/dist/eveCloudSessions.js +51 -0
- package/dist/eveCloudSessions.js.map +1 -0
- package/dist/eveExtras.d.ts +1 -3
- package/dist/eveExtras.d.ts.map +1 -1
- package/dist/hooks.d.ts +5 -3
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/sdkIdentity.d.ts +3 -0
- package/dist/sdkIdentity.d.ts.map +1 -0
- package/dist/sdkIdentity.js +9 -0
- package/dist/sdkIdentity.js.map +1 -0
- package/dist/useEveAgentRuntime.d.ts +17 -12
- package/dist/useEveAgentRuntime.d.ts.map +1 -1
- package/dist/useEveAgentRuntime.js +104 -21
- package/dist/useEveAgentRuntime.js.map +1 -1
- package/package.json +9 -5
- package/src/deriveCreatedAt.test.ts +22 -0
- package/src/deriveCreatedAt.ts +5 -0
- package/src/eveCloudSessions.test.ts +78 -0
- package/src/eveCloudSessions.ts +59 -0
- package/src/hooks.ts +4 -0
- package/src/index.ts +1 -1
- package/src/sdkIdentity.ts +9 -0
- package/src/useEveAgentRuntime.cloud.test.tsx +558 -0
- package/src/useEveAgentRuntime.eveResume.test.tsx +102 -2
- package/src/useEveAgentRuntime.fast-refresh.test.tsx +342 -0
- package/src/useEveAgentRuntime.ts +203 -45
package/LICENSE
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { AppendMessage, RespondToToolApprovalOptions, ThreadMessage } from "@assistant-ui/core";
|
|
2
|
-
import { EveAuthorizationOutcome, EveAuthorizationPart, EveMessage, EveMessageData, EveMessageInputRequest } from "eve/react";
|
|
3
|
-
import { InputResponse } from "eve/client";
|
|
4
|
-
//#region src/convertEveMessages.d.ts
|
|
1
|
+
import { type AppendMessage, type RespondToToolApprovalOptions, type ThreadMessage } from "@assistant-ui/core";
|
|
2
|
+
import type { EveAuthorizationOutcome, EveAuthorizationPart, EveMessage, EveMessageData, EveMessageInputRequest } from "eve/react";
|
|
3
|
+
import type { InputResponse } from "eve/client";
|
|
5
4
|
export type ConvertEveMessagesOptions = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Marks the last assistant message as running while Eve is submitting or
|
|
7
|
+
* streaming. When omitted, a message carrying Eve's `"streaming"` marker is
|
|
8
|
+
* treated as running; pass `false` to settle interrupted messages to a
|
|
9
|
+
* terminal status.
|
|
10
|
+
*/
|
|
11
|
+
readonly isRunning?: boolean | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* The Eve session error, mapped onto the assistant message it interrupted.
|
|
14
|
+
*/
|
|
15
|
+
readonly error?: unknown;
|
|
16
|
+
readonly getCreatedAt?: ((message: EveMessage) => Date) | undefined;
|
|
18
17
|
};
|
|
19
18
|
/**
|
|
20
19
|
* Payload of the `authorization` data part the Eve runtime emits for a
|
|
@@ -28,16 +27,16 @@ export type ConvertEveMessagesOptions = {
|
|
|
28
27
|
* re-identify a challenge among several.
|
|
29
28
|
*/
|
|
30
29
|
export type EveAuthorizationData = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
readonly state: EveAuthorizationPart["state"];
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly displayName?: string;
|
|
33
|
+
readonly description?: string;
|
|
34
|
+
readonly url?: string;
|
|
35
|
+
readonly userCode?: string;
|
|
36
|
+
readonly instructions?: string;
|
|
37
|
+
readonly expiresAt?: string;
|
|
38
|
+
readonly outcome?: EveAuthorizationOutcome;
|
|
39
|
+
readonly reason?: string;
|
|
41
40
|
};
|
|
42
41
|
/**
|
|
43
42
|
* Converts a single Eve message into an assistant-ui thread message.
|
|
@@ -53,13 +52,13 @@ export declare const convertEveMessages: (data: EveMessageData, options?: Conver
|
|
|
53
52
|
* assignability to the send call site, checked against the installed version.
|
|
54
53
|
*/
|
|
55
54
|
export type EveMessageContent = string | ({
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
readonly type: "text";
|
|
56
|
+
readonly text: string;
|
|
58
57
|
} | {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
readonly type: "file";
|
|
59
|
+
readonly data: string;
|
|
60
|
+
readonly mediaType: string;
|
|
61
|
+
readonly filename?: string;
|
|
63
62
|
})[];
|
|
64
63
|
/**
|
|
65
64
|
* Converts an assistant-ui append message into the message payload accepted by
|
|
@@ -97,5 +96,4 @@ export declare const findEveInputRequest: (data: EveMessageData, approvalId: str
|
|
|
97
96
|
* a guess about one.
|
|
98
97
|
*/
|
|
99
98
|
export declare const toEveInputResponse: (response: RespondToToolApprovalOptions, inputRequest?: EveMessageInputRequest) => InputResponse;
|
|
100
|
-
//#endregion
|
|
101
99
|
//# sourceMappingURL=convertEveMessages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertEveMessages.d.ts","
|
|
1
|
+
{"version":3,"file":"convertEveMessages.d.ts","sourceRoot":"","sources":["../src/convertEveMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAOlB,KAAK,4BAA4B,EAEjC,KAAK,aAAa,EAMnB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,KAAK,EACV,uBAAuB,EACvB,oBAAoB,EAEpB,UAAU,EACV,cAAc,EACd,sBAAsB,EAEvB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqBhD,MAAM,MAAM,yBAAyB,GAAG;IACtC;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACzC;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACrE,CAAC;AA8OF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,KAAK,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAyIF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,UAAU,EACnB,OAAO,MAAM,EACb,UAAU,SAAS,UAAU,EAAE,EAC/B,UAAS,yBAA8B,KACtC,aAkCF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,cAAc,EACpB,UAAS,yBAA8B,KACtC,aAAa,EAGb,CAAC;AAEJ;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,CACI;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B,CACJ,EAAE,CAAC;AAER;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,SAAS,aAAa,KACrB,iBAiEF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,MAAM,cAAc,EACpB,YAAY,MAAM,KACjB,sBAAsB,GAAG,SAS3B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kBAAkB,GAC7B,UAAU,4BAA4B,EACtC,eAAe,sBAAsB,KACpC,aAyDF,CAAC"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { MessageStreamEvent } from "eve/client";
|
|
2
|
-
//#region src/deriveCreatedAt.d.ts
|
|
1
|
+
import type { MessageStreamEvent } from "eve/client";
|
|
3
2
|
export type TurnTimestamps = {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
readonly user?: Date;
|
|
4
|
+
readonly assistant?: Date;
|
|
6
5
|
};
|
|
7
6
|
export type TurnTimestampCache = {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
lastEvents: readonly MessageStreamEvent[];
|
|
8
|
+
timestamps: ReadonlyMap<string, TurnTimestamps>;
|
|
10
9
|
};
|
|
11
10
|
export declare const createTurnTimestampCache: () => TurnTimestampCache;
|
|
12
11
|
/**
|
|
@@ -18,5 +17,4 @@ export declare const createTurnTimestampCache: () => TurnTimestampCache;
|
|
|
18
17
|
* makes the render-phase cache writes safe when React discards a render.
|
|
19
18
|
*/
|
|
20
19
|
export declare const collectTurnTimestamps: (events: readonly MessageStreamEvent[], cache: TurnTimestampCache) => ReadonlyMap<string, TurnTimestamps>;
|
|
21
|
-
//#endregion
|
|
22
20
|
//# sourceMappingURL=deriveCreatedAt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveCreatedAt.d.ts","
|
|
1
|
+
{"version":3,"file":"deriveCreatedAt.d.ts","sourceRoot":"","sources":["../src/deriveCreatedAt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC1C,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACjD,CAAC;AAgCF,eAAO,MAAM,wBAAwB,QAAO,kBAG1C,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,kBAAkB,EAAE,EACrC,OAAO,kBAAkB,KACxB,WAAW,CAAC,MAAM,EAAE,cAAc,CA0CpC,CAAC"}
|
package/dist/deriveCreatedAt.js
CHANGED
|
@@ -50,6 +50,7 @@ const collectTurnTimestamps = (events, cache) => {
|
|
|
50
50
|
}
|
|
51
51
|
for (let i = resumesScan ? scanned.length : 0; i < events.length; i++) {
|
|
52
52
|
const event = events[i];
|
|
53
|
+
if (!Object.prototype.hasOwnProperty.call(ROLE_BY_EVENT_TYPE, event.type)) continue;
|
|
53
54
|
const role = ROLE_BY_EVENT_TYPE[event.type];
|
|
54
55
|
if (role === void 0) continue;
|
|
55
56
|
const data = event.data;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deriveCreatedAt.js","names":[],"sources":["../src/deriveCreatedAt.ts"],"sourcesContent":["import type { MessageStreamEvent } from \"eve/client\";\n\nexport type TurnTimestamps = {\n readonly user?: Date;\n readonly assistant?: Date;\n};\n\nexport type TurnTimestampCache = {\n lastEvents: readonly MessageStreamEvent[];\n timestamps: ReadonlyMap<string, TurnTimestamps>;\n};\n\n/**\n * The reducer cases eve projects into a message: `message.received` creates\n * `${turnId}:user`, and every assistant entry reaches `updateAssistantMessage`,\n * which creates `${turnId}:assistant` for a turn that has none. It enumerates\n * that reducer across the `>=0.32.0` peer range rather than stating a rule\n * about turn ids, because `turn.started` and the compaction events carry one\n * before the model runs. An event eve adds to the creating set later is absent\n * here and falls back to the wall clock instead of stamping a wrong time.\n */\nconst ROLE_BY_EVENT_TYPE: Partial<\n Record<MessageStreamEvent[\"type\"], keyof TurnTimestamps>\n> = {\n \"message.received\": \"user\",\n \"step.started\": \"assistant\",\n \"reasoning.appended\": \"assistant\",\n \"reasoning.completed\": \"assistant\",\n \"action.input.appended\": \"assistant\",\n \"actions.requested\": \"assistant\",\n \"input.requested\": \"assistant\",\n \"action.result\": \"assistant\",\n \"action.partial\": \"assistant\",\n \"authorization.required\": \"assistant\",\n \"authorization.completed\": \"assistant\",\n \"message.appended\": \"assistant\",\n \"message.completed\": \"assistant\",\n \"result.completed\": \"assistant\",\n \"turn.completed\": \"assistant\",\n \"turn.cancelled\": \"assistant\",\n};\n\nexport const createTurnTimestampCache = (): TurnTimestampCache => ({\n lastEvents: [],\n timestamps: new Map(),\n});\n\n/**\n * Eve appends to its log (`[...events, event]`), so a snapshot that keeps the\n * previous scan's last element by identity shares the whole prefix and the\n * scan resumes there. Any other snapshot is re-derived into a fresh map: turn\n * ids are per-session sequence numbers that recur after `reset()`, so entries\n * must not outlive the log that produced them. Re-derivation is also what\n * makes the render-phase cache writes safe when React discards a render.\n */\nexport const collectTurnTimestamps = (\n events: readonly MessageStreamEvent[],\n cache: TurnTimestampCache,\n): ReadonlyMap<string, TurnTimestamps> => {\n if (events === cache.lastEvents) return cache.timestamps;\n\n const scanned = cache.lastEvents;\n const resumesScan =\n scanned.length === 0 ||\n events[scanned.length - 1] === scanned[scanned.length - 1];\n\n let timestamps = cache.timestamps;\n let draft: Map<string, TurnTimestamps> | undefined;\n if (!resumesScan) {\n draft = new Map();\n timestamps = draft;\n }\n for (let i = resumesScan ? scanned.length : 0; i < events.length; i++) {\n const event = events[i]!;\n const role = ROLE_BY_EVENT_TYPE[event.type];\n if (role === undefined) continue;\n const data: unknown = (event as { readonly data?: unknown }).data;\n if (typeof data !== \"object\" || data === null) continue;\n const turnId = (data as { readonly turnId?: unknown }).turnId;\n if (typeof turnId !== \"string\") continue;\n const known = timestamps.get(turnId);\n if (known?.[role] !== undefined) continue;\n const at: unknown = (event as { readonly meta?: { readonly at?: unknown } })\n .meta?.at;\n if (typeof at !== \"string\") continue;\n const date = new Date(at);\n if (Number.isNaN(date.getTime())) continue;\n draft ??= new Map(timestamps);\n draft.set(turnId, { ...known, [role]: date });\n timestamps = draft;\n }\n\n cache.lastEvents = events;\n cache.timestamps = timestamps;\n return timestamps;\n};\n"],"mappings":";;;;;;;;;;AAqBA,MAAM,qBAEF;CACF,oBAAoB;CACpB,gBAAgB;CAChB,sBAAsB;CACtB,uBAAuB;CACvB,yBAAyB;CACzB,qBAAqB;CACrB,mBAAmB;CACnB,iBAAiB;CACjB,kBAAkB;CAClB,0BAA0B;CAC1B,2BAA2B;CAC3B,oBAAoB;CACpB,qBAAqB;CACrB,oBAAoB;CACpB,kBAAkB;CAClB,kBAAkB;AACpB;AAEA,MAAa,kCAAsD;CACjE,YAAY,CAAC;CACb,4BAAY,IAAI,IAAI;AACtB;;;;;;;;;AAUA,MAAa,yBACX,QACA,UACwC;CACxC,IAAI,WAAW,MAAM,YAAY,OAAO,MAAM;CAE9C,MAAM,UAAU,MAAM;CACtB,MAAM,cACJ,QAAQ,WAAW,KACnB,OAAO,QAAQ,SAAS,OAAO,QAAQ,QAAQ,SAAS;CAE1D,IAAI,aAAa,MAAM;CACvB,IAAI;CACJ,IAAI,CAAC,aAAa;EAChB,wBAAQ,IAAI,IAAI;EAChB,aAAa;CACf;CACA,KAAK,IAAI,IAAI,cAAc,QAAQ,SAAS,GAAG,IAAI,OAAO,QAAQ,KAAK;EACrE,MAAM,QAAQ,OAAO;
|
|
1
|
+
{"version":3,"file":"deriveCreatedAt.js","names":[],"sources":["../src/deriveCreatedAt.ts"],"sourcesContent":["import type { MessageStreamEvent } from \"eve/client\";\n\nexport type TurnTimestamps = {\n readonly user?: Date;\n readonly assistant?: Date;\n};\n\nexport type TurnTimestampCache = {\n lastEvents: readonly MessageStreamEvent[];\n timestamps: ReadonlyMap<string, TurnTimestamps>;\n};\n\n/**\n * The reducer cases eve projects into a message: `message.received` creates\n * `${turnId}:user`, and every assistant entry reaches `updateAssistantMessage`,\n * which creates `${turnId}:assistant` for a turn that has none. It enumerates\n * that reducer across the `>=0.32.0` peer range rather than stating a rule\n * about turn ids, because `turn.started` and the compaction events carry one\n * before the model runs. An event eve adds to the creating set later is absent\n * here and falls back to the wall clock instead of stamping a wrong time.\n */\nconst ROLE_BY_EVENT_TYPE: Partial<\n Record<MessageStreamEvent[\"type\"], keyof TurnTimestamps>\n> = {\n \"message.received\": \"user\",\n \"step.started\": \"assistant\",\n \"reasoning.appended\": \"assistant\",\n \"reasoning.completed\": \"assistant\",\n \"action.input.appended\": \"assistant\",\n \"actions.requested\": \"assistant\",\n \"input.requested\": \"assistant\",\n \"action.result\": \"assistant\",\n \"action.partial\": \"assistant\",\n \"authorization.required\": \"assistant\",\n \"authorization.completed\": \"assistant\",\n \"message.appended\": \"assistant\",\n \"message.completed\": \"assistant\",\n \"result.completed\": \"assistant\",\n \"turn.completed\": \"assistant\",\n \"turn.cancelled\": \"assistant\",\n};\n\nexport const createTurnTimestampCache = (): TurnTimestampCache => ({\n lastEvents: [],\n timestamps: new Map(),\n});\n\n/**\n * Eve appends to its log (`[...events, event]`), so a snapshot that keeps the\n * previous scan's last element by identity shares the whole prefix and the\n * scan resumes there. Any other snapshot is re-derived into a fresh map: turn\n * ids are per-session sequence numbers that recur after `reset()`, so entries\n * must not outlive the log that produced them. Re-derivation is also what\n * makes the render-phase cache writes safe when React discards a render.\n */\nexport const collectTurnTimestamps = (\n events: readonly MessageStreamEvent[],\n cache: TurnTimestampCache,\n): ReadonlyMap<string, TurnTimestamps> => {\n if (events === cache.lastEvents) return cache.timestamps;\n\n const scanned = cache.lastEvents;\n const resumesScan =\n scanned.length === 0 ||\n events[scanned.length - 1] === scanned[scanned.length - 1];\n\n let timestamps = cache.timestamps;\n let draft: Map<string, TurnTimestamps> | undefined;\n if (!resumesScan) {\n draft = new Map();\n timestamps = draft;\n }\n for (let i = resumesScan ? scanned.length : 0; i < events.length; i++) {\n const event = events[i]!;\n // `type` arrives off the wire, so an inherited member such as\n // `__proto__` would resolve here instead of missing, and be used as a\n // timestamp key. Only the table's own entries count.\n if (!Object.prototype.hasOwnProperty.call(ROLE_BY_EVENT_TYPE, event.type))\n continue;\n const role = ROLE_BY_EVENT_TYPE[event.type];\n if (role === undefined) continue;\n const data: unknown = (event as { readonly data?: unknown }).data;\n if (typeof data !== \"object\" || data === null) continue;\n const turnId = (data as { readonly turnId?: unknown }).turnId;\n if (typeof turnId !== \"string\") continue;\n const known = timestamps.get(turnId);\n if (known?.[role] !== undefined) continue;\n const at: unknown = (event as { readonly meta?: { readonly at?: unknown } })\n .meta?.at;\n if (typeof at !== \"string\") continue;\n const date = new Date(at);\n if (Number.isNaN(date.getTime())) continue;\n draft ??= new Map(timestamps);\n draft.set(turnId, { ...known, [role]: date });\n timestamps = draft;\n }\n\n cache.lastEvents = events;\n cache.timestamps = timestamps;\n return timestamps;\n};\n"],"mappings":";;;;;;;;;;AAqBA,MAAM,qBAEF;CACF,oBAAoB;CACpB,gBAAgB;CAChB,sBAAsB;CACtB,uBAAuB;CACvB,yBAAyB;CACzB,qBAAqB;CACrB,mBAAmB;CACnB,iBAAiB;CACjB,kBAAkB;CAClB,0BAA0B;CAC1B,2BAA2B;CAC3B,oBAAoB;CACpB,qBAAqB;CACrB,oBAAoB;CACpB,kBAAkB;CAClB,kBAAkB;AACpB;AAEA,MAAa,kCAAsD;CACjE,YAAY,CAAC;CACb,4BAAY,IAAI,IAAI;AACtB;;;;;;;;;AAUA,MAAa,yBACX,QACA,UACwC;CACxC,IAAI,WAAW,MAAM,YAAY,OAAO,MAAM;CAE9C,MAAM,UAAU,MAAM;CACtB,MAAM,cACJ,QAAQ,WAAW,KACnB,OAAO,QAAQ,SAAS,OAAO,QAAQ,QAAQ,SAAS;CAE1D,IAAI,aAAa,MAAM;CACvB,IAAI;CACJ,IAAI,CAAC,aAAa;EAChB,wBAAQ,IAAI,IAAI;EAChB,aAAa;CACf;CACA,KAAK,IAAI,IAAI,cAAc,QAAQ,SAAS,GAAG,IAAI,OAAO,QAAQ,KAAK;EACrE,MAAM,QAAQ,OAAO;EAIrB,IAAI,CAAC,OAAO,UAAU,eAAe,KAAK,oBAAoB,MAAM,IAAI,GACtE;EACF,MAAM,OAAO,mBAAmB,MAAM;EACtC,IAAI,SAAS,KAAA,GAAW;EACxB,MAAM,OAAiB,MAAsC;EAC7D,IAAI,OAAO,SAAS,YAAY,SAAS,MAAM;EAC/C,MAAM,SAAU,KAAuC;EACvD,IAAI,OAAO,WAAW,UAAU;EAChC,MAAM,QAAQ,WAAW,IAAI,MAAM;EACnC,IAAI,QAAQ,UAAU,KAAA,GAAW;EACjC,MAAM,KAAe,MAClB,MAAM;EACT,IAAI,OAAO,OAAO,UAAU;EAC5B,MAAM,OAAO,IAAI,KAAK,EAAE;EACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,GAAG;EAClC,UAAU,IAAI,IAAI,UAAU;EAC5B,MAAM,IAAI,QAAQ;GAAE,GAAG;IAAQ,OAAO;EAAK,CAAC;EAC5C,aAAa;CACf;CAEA,MAAM,aAAa;CACnB,MAAM,aAAa;CACnB,OAAO;AACT"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Lets the cloud thread list wait for the eve session a new thread's first turn creates, because eve assigns a session id only once that turn is accepted while a cloud thread takes its external id when it is created. */
|
|
2
|
+
export declare const createEveCloudSessions: () => {
|
|
3
|
+
wait: (threadId: string) => Promise<string>;
|
|
4
|
+
resolve: (threadId: string, sessionId: string) => void;
|
|
5
|
+
reject: (threadId: string, error: Error) => void;
|
|
6
|
+
release: (threadId: string) => void;
|
|
7
|
+
};
|
|
8
|
+
export type EveCloudSessions = ReturnType<typeof createEveCloudSessions>;
|
|
9
|
+
//# sourceMappingURL=eveCloudSessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eveCloudSessions.d.ts","sourceRoot":"","sources":["../src/eveCloudSessions.ts"],"names":[],"mappings":"AAmBA,6NAA6N;AAC7N,eAAO,MAAM,sBAAsB;qBAad,MAAM;wBACH,MAAM,aAAa,MAAM;uBAM1B,MAAM,SAAS,KAAK;wBAMnB,MAAM;CAU7B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//#region src/eveCloudSessions.ts
|
|
2
|
+
const createPendingSession = () => {
|
|
3
|
+
let resolve;
|
|
4
|
+
let reject;
|
|
5
|
+
const promise = new Promise((onResolve, onReject) => {
|
|
6
|
+
resolve = onResolve;
|
|
7
|
+
reject = onReject;
|
|
8
|
+
});
|
|
9
|
+
promise.catch(() => {});
|
|
10
|
+
return {
|
|
11
|
+
promise,
|
|
12
|
+
resolve,
|
|
13
|
+
reject
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
/** Lets the cloud thread list wait for the eve session a new thread's first turn creates, because eve assigns a session id only once that turn is accepted while a cloud thread takes its external id when it is created. */
|
|
17
|
+
const createEveCloudSessions = () => {
|
|
18
|
+
const pending = /* @__PURE__ */ new Map();
|
|
19
|
+
const get = (threadId) => {
|
|
20
|
+
let session = pending.get(threadId);
|
|
21
|
+
if (!session) {
|
|
22
|
+
session = createPendingSession();
|
|
23
|
+
pending.set(threadId, session);
|
|
24
|
+
}
|
|
25
|
+
return session;
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
wait: (threadId) => get(threadId).promise,
|
|
29
|
+
resolve: (threadId, sessionId) => {
|
|
30
|
+
const session = get(threadId);
|
|
31
|
+
if (session.sessionId !== void 0) return;
|
|
32
|
+
session.sessionId = sessionId;
|
|
33
|
+
session.resolve(sessionId);
|
|
34
|
+
},
|
|
35
|
+
reject: (threadId, error) => {
|
|
36
|
+
const session = pending.get(threadId);
|
|
37
|
+
if (!session || session.sessionId !== void 0) return;
|
|
38
|
+
pending.delete(threadId);
|
|
39
|
+
session.reject(error);
|
|
40
|
+
},
|
|
41
|
+
release: (threadId) => {
|
|
42
|
+
const session = pending.get(threadId);
|
|
43
|
+
pending.delete(threadId);
|
|
44
|
+
session?.reject(/* @__PURE__ */ new Error("The thread's eve runtime unmounted before its first turn created a session."));
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { createEveCloudSessions };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=eveCloudSessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eveCloudSessions.js","names":[],"sources":["../src/eveCloudSessions.ts"],"sourcesContent":["type PendingSession = {\n readonly promise: Promise<string>;\n readonly resolve: (sessionId: string) => void;\n readonly reject: (error: unknown) => void;\n sessionId?: string;\n};\n\nconst createPendingSession = (): PendingSession => {\n let resolve!: (sessionId: string) => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<string>((onResolve, onReject) => {\n resolve = onResolve;\n reject = onReject;\n });\n // A thread can fail its first turn before the thread list asks for its session.\n promise.catch(() => {});\n return { promise, resolve, reject };\n};\n\n/** Lets the cloud thread list wait for the eve session a new thread's first turn creates, because eve assigns a session id only once that turn is accepted while a cloud thread takes its external id when it is created. */\nexport const createEveCloudSessions = () => {\n const pending = new Map<string, PendingSession>();\n\n const get = (threadId: string) => {\n let session = pending.get(threadId);\n if (!session) {\n session = createPendingSession();\n pending.set(threadId, session);\n }\n return session;\n };\n\n return {\n wait: (threadId: string) => get(threadId).promise,\n resolve: (threadId: string, sessionId: string) => {\n const session = get(threadId);\n if (session.sessionId !== undefined) return;\n session.sessionId = sessionId;\n session.resolve(sessionId);\n },\n reject: (threadId: string, error: Error) => {\n const session = pending.get(threadId);\n if (!session || session.sessionId !== undefined) return;\n pending.delete(threadId);\n session.reject(error);\n },\n release: (threadId: string) => {\n const session = pending.get(threadId);\n pending.delete(threadId);\n session?.reject(\n new Error(\n \"The thread's eve runtime unmounted before its first turn created a session.\",\n ),\n );\n },\n };\n};\n\nexport type EveCloudSessions = ReturnType<typeof createEveCloudSessions>;\n"],"mappings":";AAOA,MAAM,6BAA6C;CACjD,IAAI;CACJ,IAAI;CACJ,MAAM,UAAU,IAAI,SAAiB,WAAW,aAAa;EAC3D,UAAU;EACV,SAAS;CACX,CAAC;CAED,QAAQ,YAAY,CAAC,CAAC;CACtB,OAAO;EAAE;EAAS;EAAS;CAAO;AACpC;;AAGA,MAAa,+BAA+B;CAC1C,MAAM,0BAAU,IAAI,IAA4B;CAEhD,MAAM,OAAO,aAAqB;EAChC,IAAI,UAAU,QAAQ,IAAI,QAAQ;EAClC,IAAI,CAAC,SAAS;GACZ,UAAU,qBAAqB;GAC/B,QAAQ,IAAI,UAAU,OAAO;EAC/B;EACA,OAAO;CACT;CAEA,OAAO;EACL,OAAO,aAAqB,IAAI,QAAQ,CAAC,CAAC;EAC1C,UAAU,UAAkB,cAAsB;GAChD,MAAM,UAAU,IAAI,QAAQ;GAC5B,IAAI,QAAQ,cAAc,KAAA,GAAW;GACrC,QAAQ,YAAY;GACpB,QAAQ,QAAQ,SAAS;EAC3B;EACA,SAAS,UAAkB,UAAiB;GAC1C,MAAM,UAAU,QAAQ,IAAI,QAAQ;GACpC,IAAI,CAAC,WAAW,QAAQ,cAAc,KAAA,GAAW;GACjD,QAAQ,OAAO,QAAQ;GACvB,QAAQ,OAAO,KAAK;EACtB;EACA,UAAU,aAAqB;GAC7B,MAAM,UAAU,QAAQ,IAAI,QAAQ;GACpC,QAAQ,OAAO,QAAQ;GACvB,SAAS,uBACP,IAAI,MACF,6EACF,CACF;EACF;CACF;AACF"}
|
package/dist/eveExtras.d.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { EveMessageData, UseEveAgentHelpers } from "eve/react";
|
|
2
|
-
//#region src/eveExtras.d.ts
|
|
1
|
+
import type { EveMessageData, UseEveAgentHelpers } from "eve/react";
|
|
3
2
|
export type EveRuntimeExtras = Pick<UseEveAgentHelpers<EveMessageData>, "error" | "events" | "session" | "reset">;
|
|
4
3
|
export declare const eveExtras: import("@assistant-ui/core/react").RuntimeExtras<EveRuntimeExtras>;
|
|
5
|
-
//#endregion
|
|
6
4
|
//# sourceMappingURL=eveExtras.d.ts.map
|
package/dist/eveExtras.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eveExtras.d.ts","
|
|
1
|
+
{"version":3,"file":"eveExtras.d.ts","sourceRoot":"","sources":["../src/eveExtras.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,kBAAkB,CAAC,cAAc,CAAC,EAClC,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CACzC,CAAC;AAEF,eAAO,MAAM,SAAS,oEACuC,CAAC"}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { EveRuntimeExtras } from "./eveExtras.js";
|
|
2
|
-
//#region src/hooks.d.ts
|
|
1
|
+
import type { EveRuntimeExtras } from "./eveExtras.js";
|
|
3
2
|
/** Read the last Eve session error from the runtime extras. */
|
|
4
3
|
export declare const useEveError: () => Error | undefined;
|
|
5
4
|
/**
|
|
6
5
|
* Read the current Eve session cursor from the runtime extras. Persist it to
|
|
7
6
|
* resume the session later via `initialSession`. `undefined` when no session
|
|
8
7
|
* exists yet or outside an Eve runtime.
|
|
8
|
+
*
|
|
9
|
+
* With `cloud`, each cloud thread already keeps its session, so there is nothing to persist.
|
|
9
10
|
*/
|
|
10
11
|
export declare const useEveSession: () => EveRuntimeExtras["session"] | undefined;
|
|
11
12
|
/**
|
|
@@ -18,7 +19,8 @@ export declare const useEveEvents: () => EveRuntimeExtras["events"];
|
|
|
18
19
|
* recreates the owned session, and clears events and projected data. Pending
|
|
19
20
|
* staged messages and tool execution state are discarded. Safe to render
|
|
20
21
|
* outside an Eve runtime; invoking the returned function there throws.
|
|
22
|
+
*
|
|
23
|
+
* With `cloud`, it starts a new thread instead, leaving the current thread and its session in the list.
|
|
21
24
|
*/
|
|
22
25
|
export declare const useEveReset: () => () => void;
|
|
23
|
-
//#endregion
|
|
24
26
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAoB;AAIpD,+DAA+D;AAC/D,eAAO,MAAM,WAAW,yBAAiD,CAAC;AAE1E;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,QAAO,gBAAgB,CAAC,SAAS,CAAC,GAAG,SACnB,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,gBAAgB,CAAC,QAAQ,CACX,CAAC;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,kBAGvB,CAAC"}
|
package/dist/hooks.js
CHANGED
|
@@ -9,6 +9,8 @@ const useEveError = () => eveExtras.use((e) => e.error, void 0);
|
|
|
9
9
|
* Read the current Eve session cursor from the runtime extras. Persist it to
|
|
10
10
|
* resume the session later via `initialSession`. `undefined` when no session
|
|
11
11
|
* exists yet or outside an Eve runtime.
|
|
12
|
+
*
|
|
13
|
+
* With `cloud`, each cloud thread already keeps its session, so there is nothing to persist.
|
|
12
14
|
*/
|
|
13
15
|
const useEveSession = () => eveExtras.use((e) => e.session, void 0);
|
|
14
16
|
/**
|
|
@@ -21,6 +23,8 @@ const useEveEvents = () => eveExtras.use((e) => e.events, EMPTY_EVENTS);
|
|
|
21
23
|
* recreates the owned session, and clears events and projected data. Pending
|
|
22
24
|
* staged messages and tool execution state are discarded. Safe to render
|
|
23
25
|
* outside an Eve runtime; invoking the returned function there throws.
|
|
26
|
+
*
|
|
27
|
+
* With `cloud`, it starts a new thread instead, leaving the current thread and its session in the list.
|
|
24
28
|
*/
|
|
25
29
|
const useEveReset = () => {
|
|
26
30
|
const aui = useAui();
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useAui } from \"@assistant-ui/store\";\nimport { eveExtras } from \"./eveExtras\";\nimport type { EveRuntimeExtras } from \"./eveExtras\";\n\nconst EMPTY_EVENTS: EveRuntimeExtras[\"events\"] = Object.freeze([]);\n\n/** Read the last Eve session error from the runtime extras. */\nexport const useEveError = () => eveExtras.use((e) => e.error, undefined);\n\n/**\n * Read the current Eve session cursor from the runtime extras. Persist it to\n * resume the session later via `initialSession`. `undefined` when no session\n * exists yet or outside an Eve runtime.\n */\nexport const useEveSession = (): EveRuntimeExtras[\"session\"] | undefined =>\n eveExtras.use((e) => e.session, undefined);\n\n/**\n * Read the authoritative Eve server event stream from the runtime extras.\n * Defaults to an empty array outside an Eve runtime.\n */\nexport const useEveEvents = (): EveRuntimeExtras[\"events\"] =>\n eveExtras.use((e) => e.events, EMPTY_EVENTS);\n\n/**\n * Returns a function that resets the Eve session: aborts any in-flight turn,\n * recreates the owned session, and clears events and projected data. Pending\n * staged messages and tool execution state are discarded. Safe to render\n * outside an Eve runtime; invoking the returned function there throws.\n */\nexport const useEveReset = () => {\n const aui = useAui();\n return () => eveExtras.get(aui).reset();\n};\n"],"mappings":";;;;AAMA,MAAM,eAA2C,OAAO,OAAO,CAAC,CAAC;;AAGjE,MAAa,oBAAoB,UAAU,KAAK,MAAM,EAAE,OAAO,KAAA,CAAS
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useAui } from \"@assistant-ui/store\";\nimport { eveExtras } from \"./eveExtras\";\nimport type { EveRuntimeExtras } from \"./eveExtras\";\n\nconst EMPTY_EVENTS: EveRuntimeExtras[\"events\"] = Object.freeze([]);\n\n/** Read the last Eve session error from the runtime extras. */\nexport const useEveError = () => eveExtras.use((e) => e.error, undefined);\n\n/**\n * Read the current Eve session cursor from the runtime extras. Persist it to\n * resume the session later via `initialSession`. `undefined` when no session\n * exists yet or outside an Eve runtime.\n *\n * With `cloud`, each cloud thread already keeps its session, so there is nothing to persist.\n */\nexport const useEveSession = (): EveRuntimeExtras[\"session\"] | undefined =>\n eveExtras.use((e) => e.session, undefined);\n\n/**\n * Read the authoritative Eve server event stream from the runtime extras.\n * Defaults to an empty array outside an Eve runtime.\n */\nexport const useEveEvents = (): EveRuntimeExtras[\"events\"] =>\n eveExtras.use((e) => e.events, EMPTY_EVENTS);\n\n/**\n * Returns a function that resets the Eve session: aborts any in-flight turn,\n * recreates the owned session, and clears events and projected data. Pending\n * staged messages and tool execution state are discarded. Safe to render\n * outside an Eve runtime; invoking the returned function there throws.\n *\n * With `cloud`, it starts a new thread instead, leaving the current thread and its session in the list.\n */\nexport const useEveReset = () => {\n const aui = useAui();\n return () => eveExtras.get(aui).reset();\n};\n"],"mappings":";;;;AAMA,MAAM,eAA2C,OAAO,OAAO,CAAC,CAAC;;AAGjE,MAAa,oBAAoB,UAAU,KAAK,MAAM,EAAE,OAAO,KAAA,CAAS;;;;;;;;AASxE,MAAa,sBACX,UAAU,KAAK,MAAM,EAAE,SAAS,KAAA,CAAS;;;;;AAM3C,MAAa,qBACX,UAAU,KAAK,MAAM,EAAE,QAAQ,YAAY;;;;;;;;;AAU7C,MAAa,oBAAoB;CAC/B,MAAM,MAAM,OAAO;CACnB,aAAa,UAAU,IAAI,GAAG,CAAC,CAAC,MAAM;AACxC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
/// <reference types="@assistant-ui/core/react" />
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export {
|
|
1
|
+
/// <reference types="@assistant-ui/core/react" preserve="true" />
|
|
2
|
+
export { convertEveMessage, convertEveMessages, getEveMessageContent, toEveInputResponse, } from "./convertEveMessages.js";
|
|
3
|
+
export type { ConvertEveMessagesOptions, EveAuthorizationData, EveMessageContent, } from "./convertEveMessages.js";
|
|
4
|
+
export { useEveAgentRuntime } from "./useEveAgentRuntime.js";
|
|
5
|
+
export type { UseEveAgentRuntimeOptions } from "./useEveAgentRuntime.js";
|
|
6
|
+
export { useEveError, useEveEvents, useEveReset, useEveSession } from "./hooks.js";
|
|
7
|
+
export type { EveRuntimeExtras } from "./eveExtras.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,gCAA6B;AAC9B,YAAY,EACV,yBAAyB,EACzB,oBAAoB,EACpB,iBAAiB,GAClB,gCAA6B;AAC9B,OAAO,EAAE,kBAAkB,EAAE,gCAA6B;AAC1D,YAAY,EAAE,yBAAyB,EAAE,gCAA6B;AACtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,mBAAgB;AAChF,YAAY,EAAE,gBAAgB,EAAE,uBAAoB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdkIdentity.d.ts","sourceRoot":"","sources":["../src/sdkIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,eAAO,MAAM,OAAO,EAAE,WAMrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdkIdentity.js","names":[],"sources":["../src/sdkIdentity.ts"],"sourcesContent":["import type { SdkIdentity } from \"assistant-cloud\";\n\nexport const EVE_SDK: SdkIdentity = {\n name: \"@assistant-ui/eve\",\n version:\n typeof __AUI_PACKAGE_VERSION__ === \"string\"\n ? __AUI_PACKAGE_VERSION__\n : \"0.0.0\",\n};\n"],"mappings":";AAEA,MAAa,UAAuB;CAClC,MAAM;CACN,SAAA;AAIF"}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import { AttachmentAdapter, DictationAdapter, ExternalStoreSharedOptions, FeedbackAdapter, RealtimeVoiceAdapter, SpeechSynthesisAdapter } from "@assistant-ui/core";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readonly
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { type AttachmentAdapter, type DictationAdapter, type ExternalStoreSharedOptions, type FeedbackAdapter, type RealtimeVoiceAdapter, type SpeechSynthesisAdapter } from "@assistant-ui/core";
|
|
2
|
+
import type { AssistantCloud } from "assistant-cloud";
|
|
3
|
+
import { type EveMessageData, type UseEveAgentOptions } from "eve/react";
|
|
4
|
+
type EveAgentOptions = Omit<UseEveAgentOptions<EveMessageData>, "reducer">;
|
|
5
|
+
export type UseEveAgentRuntimeOptions = EveAgentOptions & ExternalStoreSharedOptions & {
|
|
6
|
+
readonly adapters?: {
|
|
7
|
+
readonly attachments?: AttachmentAdapter | undefined;
|
|
8
|
+
readonly speech?: SpeechSynthesisAdapter | undefined;
|
|
9
|
+
readonly dictation?: DictationAdapter | undefined;
|
|
10
|
+
readonly voice?: RealtimeVoiceAdapter | undefined;
|
|
11
|
+
readonly feedback?: FeedbackAdapter | undefined;
|
|
12
|
+
} | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Backs the thread list with Assistant Cloud. Each cloud thread keeps one Eve session as its external id, saved once the thread's first turn creates the session, and opening a thread resumes it, so `session`, `initialSession`, `initialEvents`, and `resume` are not used. Pass it from the first render: adding or removing it later throws, so remount the runtime, for example with a `key`, to switch.
|
|
15
|
+
*/
|
|
16
|
+
readonly cloud?: AssistantCloud | undefined;
|
|
12
17
|
};
|
|
13
18
|
/**
|
|
14
19
|
* Connects Eve's `useEveAgent` hook to assistant-ui's runtime contract.
|
|
@@ -18,5 +23,5 @@ export type UseEveAgentRuntimeOptions = Omit<UseEveAgentOptions<EveMessageData>,
|
|
|
18
23
|
* tool approval UI.
|
|
19
24
|
*/
|
|
20
25
|
export declare const useEveAgentRuntime: (options?: UseEveAgentRuntimeOptions) => import("@assistant-ui/core").AssistantRuntime;
|
|
21
|
-
|
|
26
|
+
export {};
|
|
22
27
|
//# sourceMappingURL=useEveAgentRuntime.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEveAgentRuntime.d.ts","
|
|
1
|
+
{"version":3,"file":"useEveAgentRuntime.d.ts","sourceRoot":"","sources":["../src/useEveAgentRuntime.ts"],"names":[],"mappings":"AAUA,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,0BAA0B,EAC/B,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAG5B,MAAM,oBAAoB,CAAC;AAS5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EAExB,MAAM,WAAW,CAAC;AAkGnB,KAAK,eAAe,GAAG,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,SAAS,CAAC,CAAC;AAE3E,MAAM,MAAM,yBAAyB,GAAG,eAAe,GACrD,0BAA0B,GAAG;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EACd;QACE,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;QACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,sBAAsB,GAAG,SAAS,CAAC;QACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;QAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;QAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;KACjD,GACD,SAAS,CAAC;IACd;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC7C,CAAC;AAmfJ;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAS,yBAA8B,kDAazE,CAAC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { convertEveMessages, findEveInputRequest, getEveMessageContent, toEveInputResponse } from "./convertEveMessages.js";
|
|
3
3
|
import { collectTurnTimestamps, createTurnTimestampCache } from "./deriveCreatedAt.js";
|
|
4
|
+
import { createEveCloudSessions } from "./eveCloudSessions.js";
|
|
4
5
|
import { eveExtras } from "./eveExtras.js";
|
|
6
|
+
import { EVE_SDK } from "./sdkIdentity.js";
|
|
5
7
|
import { MessageNotSentError, fromThreadMessageLike, generateId, pickExternalStoreSharedOptions } from "@assistant-ui/core";
|
|
6
|
-
import { useExternalStoreRuntime, useRuntimeAdapters } from "@assistant-ui/core/react";
|
|
8
|
+
import { useCloudThreadListAdapter, useExternalStoreRuntime, useRemoteThreadListRuntime, useRuntimeAdapters } from "@assistant-ui/core/react";
|
|
9
|
+
import { useAui } from "@assistant-ui/store";
|
|
7
10
|
import { useCallback, useEffect, useInsertionEffect, useMemo, useRef, useState } from "react";
|
|
11
|
+
import { useReplaySafeEffect } from "@assistant-ui/store/internal";
|
|
8
12
|
import { useEveAgent } from "eve/react";
|
|
9
13
|
//#region src/useEveAgentRuntime.ts
|
|
10
14
|
const USER_STAGED_STATUS = {
|
|
@@ -35,27 +39,49 @@ const hasRunConfig = (runConfig) => runConfig?.custom !== void 0 && Object.keys(
|
|
|
35
39
|
* prompt and to every eve-side handler.
|
|
36
40
|
*/
|
|
37
41
|
const toEveSendOptions = (runConfig) => hasRunConfig(runConfig) ? { clientContext: runConfig.custom } : void 0;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
const withCloudThreadSession = ({ initialEvents: _initialEvents, initialSession: _initialSession, resume: _resume, session: _session, ...options }, sessionId) => sessionId === void 0 ? options : {
|
|
43
|
+
...options,
|
|
44
|
+
initialSession: {
|
|
45
|
+
sessionId,
|
|
46
|
+
streamIndex: 0
|
|
47
|
+
},
|
|
48
|
+
resume: true
|
|
49
|
+
};
|
|
50
|
+
const useEveThreadRuntime = (options, cloudSessions) => {
|
|
51
|
+
const { adapters, cloud: _cloud, isDisabled: _isDisabled, isSendDisabled: _isSendDisabled, suggestions: _suggestions, unstable_capabilities: _unstable_capabilities, ...agentOptions } = options;
|
|
52
|
+
const aui = useAui();
|
|
53
|
+
const [cloudThread] = useState(() => {
|
|
54
|
+
if (!cloudSessions) return void 0;
|
|
55
|
+
const { id, status, externalId } = aui.threadListItem.getState();
|
|
56
|
+
return {
|
|
57
|
+
sessions: cloudSessions,
|
|
58
|
+
id,
|
|
59
|
+
isNew: status === "new",
|
|
60
|
+
sessionId: externalId
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
const [resumesOnMount] = useState(() => cloudThread ? cloudThread.sessionId !== void 0 : agentOptions.resume === true);
|
|
64
|
+
const isSessionless = cloudThread !== void 0 && !cloudThread.isNew && cloudThread.sessionId === void 0;
|
|
47
65
|
const { onError, onEvent, onFinish, onSessionChange } = agentOptions;
|
|
48
66
|
const lastFinishStatusRef = useRef(null);
|
|
49
67
|
const agent = useEveAgent({
|
|
50
|
-
...agentOptions,
|
|
68
|
+
...cloudThread ? withCloudThreadSession(agentOptions, cloudThread.sessionId) : agentOptions,
|
|
51
69
|
...onError ? { onError: (error) => invokeEveLifecycleCallback("onError", onError, error) } : {},
|
|
52
70
|
...onEvent ? { onEvent: (event) => invokeEveLifecycleCallback("onEvent", onEvent, event) } : {},
|
|
53
71
|
onFinish: (snapshot) => {
|
|
54
72
|
lastFinishStatusRef.current = snapshot.status;
|
|
55
73
|
invokeEveLifecycleCallback("onFinish", onFinish, snapshot);
|
|
56
74
|
},
|
|
57
|
-
...onSessionChange ? { onSessionChange: (session) =>
|
|
75
|
+
...onSessionChange || cloudThread?.isNew ? { onSessionChange: (session) => {
|
|
76
|
+
if (cloudThread?.isNew && session === void 0) cloudThread.sessions.reject(cloudThread.id, /* @__PURE__ */ new Error("The eve turn ended before it created a session."));
|
|
77
|
+
else if (cloudThread?.isNew && session !== void 0) {
|
|
78
|
+
cloudThread.sessions.resolve(cloudThread.id, session.sessionId);
|
|
79
|
+
if (aui.threadListItem.getState().status === "new") aui.threadListItem.initialize().catch(() => {});
|
|
80
|
+
}
|
|
81
|
+
invokeEveLifecycleCallback("onSessionChange", onSessionChange, session);
|
|
82
|
+
} } : {}
|
|
58
83
|
});
|
|
84
|
+
if (cloudThread && !("resume" in agent)) throw new Error("useEveAgentRuntime needs eve 0.44.1 or later for `cloud`, because opening a cloud thread resumes its session.");
|
|
59
85
|
const runtimeAdapters = useRuntimeAdapters();
|
|
60
86
|
const [toolStatuses, setToolStatuses] = useState({});
|
|
61
87
|
const [stagedMessages, setStagedMessages] = useState(null);
|
|
@@ -102,7 +128,7 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
102
128
|
const resetEpochRef = useRef(0);
|
|
103
129
|
const isMountedRef = useRef(true);
|
|
104
130
|
const runtimeRef = useRef(null);
|
|
105
|
-
const enqueueSend = (dispatch, epochRef = sendEpochRef) => {
|
|
131
|
+
const enqueueSend = useCallback((dispatch, epochRef = sendEpochRef) => {
|
|
106
132
|
const epoch = epochRef.current;
|
|
107
133
|
const next = sendChainRef.current.then(() => {
|
|
108
134
|
if (!isMountedRef.current) throw sendAbandonedError;
|
|
@@ -111,14 +137,35 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
111
137
|
});
|
|
112
138
|
sendChainRef.current = next.catch(() => {});
|
|
113
139
|
return next;
|
|
114
|
-
};
|
|
140
|
+
}, []);
|
|
115
141
|
useEffect(() => {
|
|
116
142
|
isMountedRef.current = true;
|
|
117
143
|
return () => {
|
|
118
144
|
isMountedRef.current = false;
|
|
119
|
-
sendEpochRef.current += 1;
|
|
120
145
|
};
|
|
121
146
|
}, []);
|
|
147
|
+
useReplaySafeEffect(() => () => {
|
|
148
|
+
sendEpochRef.current += 1;
|
|
149
|
+
}, []);
|
|
150
|
+
const enqueueResume = useCallback(() => enqueueSend(async () => {
|
|
151
|
+
const live = agentRef.current;
|
|
152
|
+
if (live.session === void 0 || !("resume" in live)) return;
|
|
153
|
+
await live.resume();
|
|
154
|
+
}, resetEpochRef), [enqueueSend]);
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (!resumesOnMount) return;
|
|
157
|
+
let active = true;
|
|
158
|
+
queueMicrotask(() => {
|
|
159
|
+
if (active) enqueueResume().catch(() => {});
|
|
160
|
+
});
|
|
161
|
+
return () => {
|
|
162
|
+
active = false;
|
|
163
|
+
};
|
|
164
|
+
}, [enqueueResume, resumesOnMount]);
|
|
165
|
+
useReplaySafeEffect(() => {
|
|
166
|
+
if (!cloudThread?.isNew) return;
|
|
167
|
+
return () => cloudThread.sessions.release(cloudThread.id);
|
|
168
|
+
}, [cloudThread]);
|
|
122
169
|
useEffect(() => {
|
|
123
170
|
if (stagedInputsRef.current.size === 0) return;
|
|
124
171
|
const baseIds = new Set(convertedMessages.map((message) => message.id));
|
|
@@ -149,6 +196,10 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
149
196
|
setStagedMessages(nextMessages);
|
|
150
197
|
};
|
|
151
198
|
const reset = useCallback(() => {
|
|
199
|
+
if (cloudThread) {
|
|
200
|
+
aui.threads.switchToNewThread();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
152
203
|
runtimeRef.current?.thread.unstable_notifySessionReset();
|
|
153
204
|
sendEpochRef.current += 1;
|
|
154
205
|
resetEpochRef.current += 1;
|
|
@@ -157,7 +208,11 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
157
208
|
stagedInputsRef.current.clear();
|
|
158
209
|
setToolStatuses({});
|
|
159
210
|
agent.reset();
|
|
160
|
-
}, [
|
|
211
|
+
}, [
|
|
212
|
+
agent,
|
|
213
|
+
aui,
|
|
214
|
+
cloudThread
|
|
215
|
+
]);
|
|
161
216
|
const extras = useMemo(() => eveExtras.provide({
|
|
162
217
|
error: agent.error,
|
|
163
218
|
events: agent.events,
|
|
@@ -173,6 +228,7 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
173
228
|
...pickExternalStoreSharedOptions(options),
|
|
174
229
|
messages,
|
|
175
230
|
isRunning: providerIsRunning,
|
|
231
|
+
isLoading: agent.status === "resuming",
|
|
176
232
|
extras,
|
|
177
233
|
unstable_enableToolInvocations: true,
|
|
178
234
|
setToolStatuses,
|
|
@@ -184,7 +240,9 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
184
240
|
feedback: adapters?.feedback
|
|
185
241
|
},
|
|
186
242
|
onNew: async (message) => {
|
|
243
|
+
if (isSessionless) throw new MessageNotSentError("This thread has no eve session to send to.");
|
|
187
244
|
if (!(message.startRun ?? message.role === "user")) {
|
|
245
|
+
if (cloudThread?.isNew) cloudThread.sessions.reject(cloudThread.id, /* @__PURE__ */ new Error("The thread's first message was staged without a run."));
|
|
188
246
|
stageUserMessage(message);
|
|
189
247
|
return;
|
|
190
248
|
}
|
|
@@ -227,11 +285,7 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
227
285
|
if ("cancel" in controls) await controls.cancel();
|
|
228
286
|
else controls.stop();
|
|
229
287
|
},
|
|
230
|
-
..."resume" in agent ? { onRefetchThread: () =>
|
|
231
|
-
const live = agentRef.current;
|
|
232
|
-
if (live.session === void 0) return;
|
|
233
|
-
await live.resume();
|
|
234
|
-
}, resetEpochRef).catch((error) => {
|
|
288
|
+
..."resume" in agent ? { onRefetchThread: () => enqueueResume().catch((error) => {
|
|
235
289
|
if (isDroppedSend(error)) return;
|
|
236
290
|
throw error;
|
|
237
291
|
}) } : {},
|
|
@@ -245,6 +299,35 @@ const useEveAgentRuntime = (options = {}) => {
|
|
|
245
299
|
runtimeRef.current = runtime;
|
|
246
300
|
return runtime;
|
|
247
301
|
};
|
|
302
|
+
const useEveCloudRuntime = (cloud, options) => {
|
|
303
|
+
const [sessions] = useState(createEveCloudSessions);
|
|
304
|
+
const adapter = useCloudThreadListAdapter({
|
|
305
|
+
cloud,
|
|
306
|
+
sdk: EVE_SDK,
|
|
307
|
+
upsert: true,
|
|
308
|
+
create: async (threadId) => ({ externalId: await sessions.wait(threadId) })
|
|
309
|
+
});
|
|
310
|
+
return useRemoteThreadListRuntime({
|
|
311
|
+
adapter,
|
|
312
|
+
allowNesting: true,
|
|
313
|
+
runtimeHook: function RuntimeHook() {
|
|
314
|
+
return useEveThreadRuntime(options, sessions);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* Connects Eve's `useEveAgent` hook to assistant-ui's runtime contract.
|
|
320
|
+
*
|
|
321
|
+
* The runtime renders Eve messages, forwards new user messages to the Eve
|
|
322
|
+
* session, supports cancellation, and maps Eve input requests to assistant-ui
|
|
323
|
+
* tool approval UI.
|
|
324
|
+
*/
|
|
325
|
+
const useEveAgentRuntime = (options = {}) => {
|
|
326
|
+
const [hasCloud] = useState(options.cloud !== void 0);
|
|
327
|
+
if (options.cloud !== void 0 !== hasCloud) throw new Error("useEveAgentRuntime cannot add or remove `cloud` after it mounts; remount it, for example with a `key`, to switch.");
|
|
328
|
+
if (!options.cloud) return useEveThreadRuntime(options, void 0);
|
|
329
|
+
return useEveCloudRuntime(options.cloud, options);
|
|
330
|
+
};
|
|
248
331
|
//#endregion
|
|
249
332
|
export { useEveAgentRuntime };
|
|
250
333
|
|