@lunora/react 1.0.0-alpha.246 → 1.0.0-alpha.248
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/README.md +1 -1
- package/dist/index.d.mts +81 -12
- package/dist/index.d.ts +81 -12
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{useAgent-HdZlRJPr.mjs → useAgent-CO523Dot.mjs} +1 -1
- package/dist/packem_shared/useAgentChat-51qFVjQW.mjs +2 -0
- package/dist/packem_shared/useAgentToolEvents-YQl2HgR6.mjs +2 -0
- package/dist/packem_shared/useMutation-29nXea_s.mjs +2 -0
- package/dist/packem_shared/useVoiceAgent-ixfjauAR.mjs +2 -0
- package/package.json +4 -4
- package/dist/packem_shared/useAgentChat-mUYiftK-.mjs +0 -2
- package/dist/packem_shared/useAgentToolEvents-Dpc8Oce8.mjs +0 -2
- package/dist/packem_shared/useMutation-Bz9uwvGf.mjs +0 -2
- package/dist/packem_shared/useVoiceAgent-DAh27XxD.mjs +0 -2
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ function MessageList({ room }: { room: string }) {
|
|
|
97
97
|
| Hook | Returns | Notes |
|
|
98
98
|
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
99
99
|
| `useQuery(fn, args, options?)` | `T \| undefined` | Live query; shares one WS subscription across consumers of the same key. |
|
|
100
|
-
| `useMutation(fn)` | `{ mutate, pending, data, error, reset, withOptimisticUpdate }` | Per-call `optimistic` / `optimisticUpdate` options pass through to the client.
|
|
100
|
+
| `useMutation(fn)` | `{ mutate, pending, data, error, reset, withOptimisticUpdate }` | Per-call `optimistic` / `optimisticUpdate` options pass through to the client; `onlineOnly` refuses rather than queues. |
|
|
101
101
|
| `useSubscription(fn, args, options?)` | `{ data, error }` | No initial fetch — only server-pushed values. |
|
|
102
102
|
| `usePaginatedQuery(fn, args, { initialNumItems, onError? })` | `{ results, status, isLoading, loadMore, error }` | Cursor-paginated feed that stays consistent under live edits. A failed tail page is dropped so `loadMore` can retry it. |
|
|
103
103
|
| `useInfiniteQuery(fn, args, { initialNumItems, onError? })` | `{ pages, status, hasNextPage, fetchNextPage, error, … }` | Page-array variant of the same paginator. |
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, SubscriptionError, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutatorHandle, Preloaded } from '@lunora/client';
|
|
2
|
+
import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, SubscriptionError, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, OnlineOnlyOption, MutatorHandle, Preloaded } from '@lunora/client';
|
|
3
3
|
export { type ArgsOf, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type SubscriptionError, type SubscriptionErrorCallback, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
|
|
4
4
|
import { QueryClient } from '@tanstack/react-query';
|
|
5
5
|
export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-CdgGQ9s4.mjs";
|
|
@@ -81,6 +81,12 @@ interface UseQueryOptions {
|
|
|
81
81
|
shardKey?: string;
|
|
82
82
|
}
|
|
83
83
|
interface UseMutationCallOptions<TCurrent = unknown, TValue = unknown, TArgs = unknown> {
|
|
84
|
+
/**
|
|
85
|
+
* Refuse rather than queue this write when the connection is down; see
|
|
86
|
+
* `MutationCallOptions.onlineOnly`. For a function with a `v.sensitive` argument
|
|
87
|
+
* the hook narrows this to `true`, since such a write is always online-only.
|
|
88
|
+
*/
|
|
89
|
+
onlineOnly?: boolean;
|
|
84
90
|
/**
|
|
85
91
|
* Single-query shortcut forwarded to `client.mutation`: the transform is
|
|
86
92
|
* layered onto the subscription registered under **this write's own**
|
|
@@ -486,8 +492,8 @@ interface AgentChatMessage {
|
|
|
486
492
|
optimistic?: boolean;
|
|
487
493
|
role: "assistant" | "system" | "tool" | "user";
|
|
488
494
|
seq: number;
|
|
489
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
490
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
495
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
496
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
491
497
|
toolCallId?: string;
|
|
492
498
|
toolCalls?: ReadonlyArray<{
|
|
493
499
|
id: string;
|
|
@@ -541,7 +547,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
541
547
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
542
548
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
543
549
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
544
|
-
decision: "approve" | "reject";
|
|
550
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
545
551
|
instanceId: string;
|
|
546
552
|
note?: string;
|
|
547
553
|
threadKey: string;
|
|
@@ -549,10 +555,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
549
555
|
}, {
|
|
550
556
|
resolved: boolean;
|
|
551
557
|
}>;
|
|
558
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
559
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
560
|
+
secret: string;
|
|
561
|
+
threadKey: string;
|
|
562
|
+
toolCallId: string;
|
|
563
|
+
}, {
|
|
564
|
+
resolved: boolean;
|
|
565
|
+
}>;
|
|
566
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
567
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
568
|
+
threadKey: string;
|
|
569
|
+
toolCallId: string;
|
|
570
|
+
}, {
|
|
571
|
+
resolved: boolean;
|
|
572
|
+
}>;
|
|
552
573
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
553
574
|
type AgentThreadReference = FunctionReference<"query", {
|
|
554
575
|
key: string;
|
|
555
576
|
}, Record<string, unknown> | undefined>;
|
|
577
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
578
|
+
interface AgentApprovalGrant {
|
|
579
|
+
createdAt: number;
|
|
580
|
+
toolName: string;
|
|
581
|
+
}
|
|
582
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
583
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
584
|
+
key: string;
|
|
585
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
586
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
587
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
588
|
+
threadKey: string;
|
|
589
|
+
toolName: string;
|
|
590
|
+
}, {
|
|
591
|
+
revoked: boolean;
|
|
592
|
+
}>;
|
|
556
593
|
/**
|
|
557
594
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
558
595
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -567,8 +604,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
567
604
|
*/
|
|
568
605
|
interface UseAgentChatApi {
|
|
569
606
|
agents: {
|
|
607
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
608
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
570
609
|
agentMessages: AgentMessagesReference$1;
|
|
571
610
|
agentResolveApproval: AgentApprovalReference;
|
|
611
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
612
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
572
613
|
agentThread: AgentThreadReference;
|
|
573
614
|
};
|
|
574
615
|
}
|
|
@@ -585,7 +626,7 @@ interface UseAgentChatOptions {
|
|
|
585
626
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
586
627
|
limit?: number;
|
|
587
628
|
/**
|
|
588
|
-
* Called when the live history or
|
|
629
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
589
630
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
590
631
|
* such a failure is invisible and `messages` / `status` freeze at their last
|
|
591
632
|
* value.
|
|
@@ -609,29 +650,47 @@ interface UseAgentChatOptions {
|
|
|
609
650
|
threadKey: string;
|
|
610
651
|
}
|
|
611
652
|
interface UseAgentChatResult {
|
|
653
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
654
|
+
approvalGrants: ReadonlyArray<AgentApprovalGrant>;
|
|
612
655
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
613
656
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
657
|
+
/**
|
|
658
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
659
|
+
* later calls to it run without pausing. Undo with {@link UseAgentChatResult.revokeGrant}.
|
|
660
|
+
*/
|
|
661
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
614
662
|
/**
|
|
615
663
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
616
664
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
617
665
|
*/
|
|
618
666
|
cancel: () => Promise<void>;
|
|
619
|
-
/**
|
|
667
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
668
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
669
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
620
670
|
error: Error | undefined;
|
|
621
671
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
622
672
|
messages: ReadonlyArray<AgentChatMessage>;
|
|
623
673
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
624
674
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
675
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
676
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
625
677
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
626
678
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
627
679
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
628
680
|
status: AgentThreadStatus | undefined;
|
|
629
681
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
630
682
|
streamingText: string;
|
|
683
|
+
/**
|
|
684
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
685
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
686
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The hook keeps no copy; a
|
|
687
|
+
* failure rethrows the original error.
|
|
688
|
+
*/
|
|
689
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
631
690
|
}
|
|
632
691
|
/**
|
|
633
692
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
634
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey`.
|
|
693
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey`.
|
|
635
694
|
*
|
|
636
695
|
* It composes the existing primitives rather than adding transport:
|
|
637
696
|
* `useSubscription(api.agents.agentMessages)` for durable history,
|
|
@@ -724,7 +783,7 @@ interface UseAgentToolEventsOptions {
|
|
|
724
783
|
* Optional live event stream — the same app stream function `useAgentChat`
|
|
725
784
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
726
785
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
727
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
786
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
728
787
|
*/
|
|
729
788
|
stream?: AgentLiveStreamReference;
|
|
730
789
|
/** The thread whose tool activity to observe. */
|
|
@@ -732,7 +791,7 @@ interface UseAgentToolEventsOptions {
|
|
|
732
791
|
}
|
|
733
792
|
/**
|
|
734
793
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
735
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
794
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
736
795
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
737
796
|
* stream and has no `seq`. Discriminate on `type`.
|
|
738
797
|
*/
|
|
@@ -758,6 +817,11 @@ type AgentToolEvent = {
|
|
|
758
817
|
toolCallId?: string;
|
|
759
818
|
toolName?: string;
|
|
760
819
|
type: "awaiting-approval";
|
|
820
|
+
} | {
|
|
821
|
+
seq: number;
|
|
822
|
+
toolCallId?: string;
|
|
823
|
+
toolName?: string;
|
|
824
|
+
type: "awaiting-secret";
|
|
761
825
|
};
|
|
762
826
|
interface UseAgentToolEventsResult {
|
|
763
827
|
/**
|
|
@@ -980,7 +1044,7 @@ interface UseLiveTopicResult<Payload = unknown> {
|
|
|
980
1044
|
* its initial values there.
|
|
981
1045
|
*/
|
|
982
1046
|
declare function useLiveTopic<Payload>(topic: LiveTopicRef<Payload>, options?: UseLiveTopicOptions<Payload>): UseLiveTopicResult<Payload>;
|
|
983
|
-
type CallOptions<F extends FunctionReference> = UseMutationCallOptions<unknown, unknown, ArgsOf<F>>;
|
|
1047
|
+
type CallOptions<F extends FunctionReference> = OnlineOnlyOption<F> & UseMutationCallOptions<unknown, unknown, ArgsOf<F>>;
|
|
984
1048
|
interface MutationHook<F extends FunctionReference> {
|
|
985
1049
|
/** The latest invocation's resolved value, or `undefined` before the first success. */
|
|
986
1050
|
data: ReturnOf<F> | undefined;
|
|
@@ -1029,7 +1093,12 @@ interface MutationHook<F extends FunctionReference> {
|
|
|
1029
1093
|
* which queues it (the offline queue or a durable outbox) and paints the
|
|
1030
1094
|
* optimistic update. A write it cannot queue (before the shard's first connect,
|
|
1031
1095
|
* or with no WebSocket) waits until the browser is online again, then sends.
|
|
1032
|
-
* TanStack never retries; the queue owns replays.
|
|
1096
|
+
* TanStack never retries; the queue owns replays. An online-only write (`onlineOnly:
|
|
1097
|
+
* true`, or any call to a function with a `v.sensitive` argument) is not held for a
|
|
1098
|
+
* later send: it reaches `client.mutation` at once and rejects with
|
|
1099
|
+
* `OFFLINE_NOT_QUEUED` if the network is down. Such a call also leaves TanStack's
|
|
1100
|
+
* mutation cache, and with it the call's arguments, as soon as nothing observes it
|
|
1101
|
+
* (the hook still holds the latest call while mounted).
|
|
1033
1102
|
*/
|
|
1034
1103
|
declare const useMutation: <F extends FunctionReference>(function_: F) => MutationHook<F>;
|
|
1035
1104
|
interface MutatorHook<TArgs> {
|
|
@@ -1456,4 +1525,4 @@ interface UseVoiceAgentResult {
|
|
|
1456
1525
|
* `createSocket`) so the hook is drivable outside a browser.
|
|
1457
1526
|
*/
|
|
1458
1527
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1459
|
-
export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseLiveTopicOptions, type UseLiveTopicResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseSignUpInvitationsOptions, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLiveTopic, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useSignUpInvitations, useStream, useSubscription, useSuspenseQuery, useVoiceAgent };
|
|
1528
|
+
export { type ActionHook, type AdminAuthListResult, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseLiveTopicOptions, type UseLiveTopicResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseSignUpInvitationsOptions, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLiveTopic, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useSignUpInvitations, useStream, useSubscription, useSuspenseQuery, useVoiceAgent };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
|
-
import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, SubscriptionError, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutatorHandle, Preloaded } from '@lunora/client';
|
|
2
|
+
import { LunoraClient, OptimisticUpdate, User, SubscriptionErrorCallback, SubscriptionError, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, AuthImpersonation, AuthSession, AuthUser, ClientQueryRef, ConnectionStatus, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, OnlineOnlyOption, MutatorHandle, Preloaded } from '@lunora/client';
|
|
3
3
|
export { type ArgsOf, type AuthImpersonation, type AuthPage, type AuthSession, type AuthUser, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type SubscriptionError, type SubscriptionErrorCallback, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
|
|
4
4
|
import { QueryClient } from '@tanstack/react-query';
|
|
5
5
|
export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-CdgGQ9s4.js";
|
|
@@ -81,6 +81,12 @@ interface UseQueryOptions {
|
|
|
81
81
|
shardKey?: string;
|
|
82
82
|
}
|
|
83
83
|
interface UseMutationCallOptions<TCurrent = unknown, TValue = unknown, TArgs = unknown> {
|
|
84
|
+
/**
|
|
85
|
+
* Refuse rather than queue this write when the connection is down; see
|
|
86
|
+
* `MutationCallOptions.onlineOnly`. For a function with a `v.sensitive` argument
|
|
87
|
+
* the hook narrows this to `true`, since such a write is always online-only.
|
|
88
|
+
*/
|
|
89
|
+
onlineOnly?: boolean;
|
|
84
90
|
/**
|
|
85
91
|
* Single-query shortcut forwarded to `client.mutation`: the transform is
|
|
86
92
|
* layered onto the subscription registered under **this write's own**
|
|
@@ -486,8 +492,8 @@ interface AgentChatMessage {
|
|
|
486
492
|
optimistic?: boolean;
|
|
487
493
|
role: "assistant" | "system" | "tool" | "user";
|
|
488
494
|
seq: number;
|
|
489
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
490
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
495
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
496
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
491
497
|
toolCallId?: string;
|
|
492
498
|
toolCalls?: ReadonlyArray<{
|
|
493
499
|
id: string;
|
|
@@ -541,7 +547,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
541
547
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
542
548
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
543
549
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
544
|
-
decision: "approve" | "reject";
|
|
550
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
545
551
|
instanceId: string;
|
|
546
552
|
note?: string;
|
|
547
553
|
threadKey: string;
|
|
@@ -549,10 +555,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
549
555
|
}, {
|
|
550
556
|
resolved: boolean;
|
|
551
557
|
}>;
|
|
558
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
559
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
560
|
+
secret: string;
|
|
561
|
+
threadKey: string;
|
|
562
|
+
toolCallId: string;
|
|
563
|
+
}, {
|
|
564
|
+
resolved: boolean;
|
|
565
|
+
}>;
|
|
566
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
567
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
568
|
+
threadKey: string;
|
|
569
|
+
toolCallId: string;
|
|
570
|
+
}, {
|
|
571
|
+
resolved: boolean;
|
|
572
|
+
}>;
|
|
552
573
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
553
574
|
type AgentThreadReference = FunctionReference<"query", {
|
|
554
575
|
key: string;
|
|
555
576
|
}, Record<string, unknown> | undefined>;
|
|
577
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
578
|
+
interface AgentApprovalGrant {
|
|
579
|
+
createdAt: number;
|
|
580
|
+
toolName: string;
|
|
581
|
+
}
|
|
582
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
583
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
584
|
+
key: string;
|
|
585
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
586
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
587
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
588
|
+
threadKey: string;
|
|
589
|
+
toolName: string;
|
|
590
|
+
}, {
|
|
591
|
+
revoked: boolean;
|
|
592
|
+
}>;
|
|
556
593
|
/**
|
|
557
594
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
558
595
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -567,8 +604,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
567
604
|
*/
|
|
568
605
|
interface UseAgentChatApi {
|
|
569
606
|
agents: {
|
|
607
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
608
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
570
609
|
agentMessages: AgentMessagesReference$1;
|
|
571
610
|
agentResolveApproval: AgentApprovalReference;
|
|
611
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
612
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
572
613
|
agentThread: AgentThreadReference;
|
|
573
614
|
};
|
|
574
615
|
}
|
|
@@ -585,7 +626,7 @@ interface UseAgentChatOptions {
|
|
|
585
626
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
586
627
|
limit?: number;
|
|
587
628
|
/**
|
|
588
|
-
* Called when the live history or
|
|
629
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
589
630
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
590
631
|
* such a failure is invisible and `messages` / `status` freeze at their last
|
|
591
632
|
* value.
|
|
@@ -609,29 +650,47 @@ interface UseAgentChatOptions {
|
|
|
609
650
|
threadKey: string;
|
|
610
651
|
}
|
|
611
652
|
interface UseAgentChatResult {
|
|
653
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
654
|
+
approvalGrants: ReadonlyArray<AgentApprovalGrant>;
|
|
612
655
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
613
656
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
657
|
+
/**
|
|
658
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
659
|
+
* later calls to it run without pausing. Undo with {@link UseAgentChatResult.revokeGrant}.
|
|
660
|
+
*/
|
|
661
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
614
662
|
/**
|
|
615
663
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
616
664
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
617
665
|
*/
|
|
618
666
|
cancel: () => Promise<void>;
|
|
619
|
-
/**
|
|
667
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
668
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
669
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
620
670
|
error: Error | undefined;
|
|
621
671
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
622
672
|
messages: ReadonlyArray<AgentChatMessage>;
|
|
623
673
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
624
674
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
675
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
676
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
625
677
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
626
678
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
627
679
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
628
680
|
status: AgentThreadStatus | undefined;
|
|
629
681
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
630
682
|
streamingText: string;
|
|
683
|
+
/**
|
|
684
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
685
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
686
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The hook keeps no copy; a
|
|
687
|
+
* failure rethrows the original error.
|
|
688
|
+
*/
|
|
689
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
631
690
|
}
|
|
632
691
|
/**
|
|
633
692
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
634
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey`.
|
|
693
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey`.
|
|
635
694
|
*
|
|
636
695
|
* It composes the existing primitives rather than adding transport:
|
|
637
696
|
* `useSubscription(api.agents.agentMessages)` for durable history,
|
|
@@ -724,7 +783,7 @@ interface UseAgentToolEventsOptions {
|
|
|
724
783
|
* Optional live event stream — the same app stream function `useAgentChat`
|
|
725
784
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
726
785
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
727
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
786
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
728
787
|
*/
|
|
729
788
|
stream?: AgentLiveStreamReference;
|
|
730
789
|
/** The thread whose tool activity to observe. */
|
|
@@ -732,7 +791,7 @@ interface UseAgentToolEventsOptions {
|
|
|
732
791
|
}
|
|
733
792
|
/**
|
|
734
793
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
735
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
794
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
736
795
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
737
796
|
* stream and has no `seq`. Discriminate on `type`.
|
|
738
797
|
*/
|
|
@@ -758,6 +817,11 @@ type AgentToolEvent = {
|
|
|
758
817
|
toolCallId?: string;
|
|
759
818
|
toolName?: string;
|
|
760
819
|
type: "awaiting-approval";
|
|
820
|
+
} | {
|
|
821
|
+
seq: number;
|
|
822
|
+
toolCallId?: string;
|
|
823
|
+
toolName?: string;
|
|
824
|
+
type: "awaiting-secret";
|
|
761
825
|
};
|
|
762
826
|
interface UseAgentToolEventsResult {
|
|
763
827
|
/**
|
|
@@ -980,7 +1044,7 @@ interface UseLiveTopicResult<Payload = unknown> {
|
|
|
980
1044
|
* its initial values there.
|
|
981
1045
|
*/
|
|
982
1046
|
declare function useLiveTopic<Payload>(topic: LiveTopicRef<Payload>, options?: UseLiveTopicOptions<Payload>): UseLiveTopicResult<Payload>;
|
|
983
|
-
type CallOptions<F extends FunctionReference> = UseMutationCallOptions<unknown, unknown, ArgsOf<F>>;
|
|
1047
|
+
type CallOptions<F extends FunctionReference> = OnlineOnlyOption<F> & UseMutationCallOptions<unknown, unknown, ArgsOf<F>>;
|
|
984
1048
|
interface MutationHook<F extends FunctionReference> {
|
|
985
1049
|
/** The latest invocation's resolved value, or `undefined` before the first success. */
|
|
986
1050
|
data: ReturnOf<F> | undefined;
|
|
@@ -1029,7 +1093,12 @@ interface MutationHook<F extends FunctionReference> {
|
|
|
1029
1093
|
* which queues it (the offline queue or a durable outbox) and paints the
|
|
1030
1094
|
* optimistic update. A write it cannot queue (before the shard's first connect,
|
|
1031
1095
|
* or with no WebSocket) waits until the browser is online again, then sends.
|
|
1032
|
-
* TanStack never retries; the queue owns replays.
|
|
1096
|
+
* TanStack never retries; the queue owns replays. An online-only write (`onlineOnly:
|
|
1097
|
+
* true`, or any call to a function with a `v.sensitive` argument) is not held for a
|
|
1098
|
+
* later send: it reaches `client.mutation` at once and rejects with
|
|
1099
|
+
* `OFFLINE_NOT_QUEUED` if the network is down. Such a call also leaves TanStack's
|
|
1100
|
+
* mutation cache, and with it the call's arguments, as soon as nothing observes it
|
|
1101
|
+
* (the hook still holds the latest call while mounted).
|
|
1033
1102
|
*/
|
|
1034
1103
|
declare const useMutation: <F extends FunctionReference>(function_: F) => MutationHook<F>;
|
|
1035
1104
|
interface MutatorHook<TArgs> {
|
|
@@ -1456,4 +1525,4 @@ interface UseVoiceAgentResult {
|
|
|
1456
1525
|
* `createSocket`) so the hook is drivable outside a browser.
|
|
1457
1526
|
*/
|
|
1458
1527
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1459
|
-
export { type ActionHook, type AdminAuthListResult, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseLiveTopicOptions, type UseLiveTopicResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseSignUpInvitationsOptions, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLiveTopic, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useSignUpInvitations, useStream, useSubscription, useSuspenseQuery, useVoiceAgent };
|
|
1528
|
+
export { type ActionHook, type AdminAuthListResult, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseAuthSessionsOptions, type UseAuthUsersOptions, type UseHttpStreamOptions, type UseHttpStreamResult, type UseImpersonateResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseLiveTopicOptions, type UseLiveTopicResult, type UseMutationCallOptions, type UseOrganizationsOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseSignUpInvitationsOptions, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthSessions, useAuthState, useAuthUsers, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useImpersonate, useInfiniteQuery, useLiveTopic, useLunora, useMutation, useMutator, useOrganizations, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useSignUpInvitations, useStream, useSubscription, useSuspenseQuery, useVoiceAgent };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{AuthLoading as o,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-024-XH0I.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-CqN1F2FM.mjs";import{L as f,u as n}from"./packem_shared/lunora-provider-_WqSuvf9.mjs";import{lunoraQueryOptions as m}from"./packem_shared/lunoraQueryOptions-IJB_aFzi.mjs";import{useAction as x}from"./packem_shared/useAction-jJl4KPEw.mjs";import{useAuthSessions as g,useAuthUsers as A,useImpersonate as c,useOrganizations as h,useSignUpInvitations as U}from"./packem_shared/useAuthSessions-jJWdw8Zw.mjs";import{useAgent as S}from"./packem_shared/useAgent-
|
|
2
|
+
import{AuthLoading as o,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-024-XH0I.mjs";import{useAuthState as a}from"./packem_shared/useAuthState-CqN1F2FM.mjs";import{L as f,u as n}from"./packem_shared/lunora-provider-_WqSuvf9.mjs";import{lunoraQueryOptions as m}from"./packem_shared/lunoraQueryOptions-IJB_aFzi.mjs";import{useAction as x}from"./packem_shared/useAction-jJl4KPEw.mjs";import{useAuthSessions as g,useAuthUsers as A,useImpersonate as c,useOrganizations as h,useSignUpInvitations as U}from"./packem_shared/useAuthSessions-jJWdw8Zw.mjs";import{useAgent as S}from"./packem_shared/useAgent-CO523Dot.mjs";import{useAgentChat as E}from"./packem_shared/useAgentChat-51qFVjQW.mjs";import{useAgentState as L}from"./packem_shared/useAgentState-CwsVpvmD.mjs";import{useAgentToolEvents as R}from"./packem_shared/useAgentToolEvents-YQl2HgR6.mjs";import{default as F}from"./packem_shared/useAuth-CpGKVRsv.mjs";import{default as M}from"./packem_shared/useClientQuery-DUEUAqPh.mjs";import{default as b}from"./packem_shared/useConnectionStatus-Dtx_OWez.mjs";import{useFlag as O,useFlags as k}from"./packem_shared/useFlag-A7XPHExt.mjs";import{useHttpStream as V}from"./packem_shared/useHttpStream-CzryjxVH.mjs";import{default as q}from"./packem_shared/useInfiniteQuery-D_AG59dX.mjs";import{useLiveTopic as B}from"./packem_shared/useLiveTopic-UYAE2s4R.mjs";import{useMutation as G}from"./packem_shared/useMutation-29nXea_s.mjs";import{useMutator as K}from"./packem_shared/useMutator-BtUd-xEA.mjs";import{usePaginatedQuery as W}from"./packem_shared/usePaginatedQuery-DhQAsxgX.mjs";import{hydratePreloaded as Y,default as Z}from"./packem_shared/hydratePreloaded-qs8nspKB.mjs";import{usePresence as $}from"./packem_shared/usePresence-X5Ax04Cf.mjs";import{default as re}from"./packem_shared/useQuery-Cek_oF7t.mjs";import{useRateLimit as te}from"./packem_shared/useRateLimit-Cckxi8m9.mjs";import{useStream as se}from"./packem_shared/useStream-D8GB__4j.mjs";import{default as pe}from"./packem_shared/useSubscription-D9QkGhO3.mjs";import{default as ne}from"./packem_shared/useSuspenseQuery-CZTk7Kch.mjs";import{useVoiceAgent as me}from"./packem_shared/useVoiceAgent-ixfjauAR.mjs";import{createClientQuery as xe,getErrorCode as le,getRetryAfterMs as ge,isConflictError as Ae,isForbiddenError as ce,isRateLimitedError as he,isUnauthorizedError as Ue}from"@lunora/client";import{RestrictionError as Se,UploadControl as Ce,UploadError as Ee}from"@visulima/storage-client";import{useChunkedRestUpload as Le,useFileInput as Pe,useMultipartUpload as Re,usePasteUpload as ve,useTusUpload as Fe,useUpload as Ie}from"@visulima/storage-client/react";export{o as AuthLoading,t as Authenticated,f as LunoraProvider,Se as RestrictionError,u as Unauthenticated,Ce as UploadControl,Ee as UploadError,xe as createClientQuery,le as getErrorCode,ge as getRetryAfterMs,Y as hydratePreloaded,Ae as isConflictError,ce as isForbiddenError,he as isRateLimitedError,Ue as isUnauthorizedError,m as lunoraQueryOptions,x as useAction,S as useAgent,E as useAgentChat,L as useAgentState,R as useAgentToolEvents,F as useAuth,g as useAuthSessions,a as useAuthState,A as useAuthUsers,Le as useChunkedRestUpload,M as useClientQuery,b as useConnectionStatus,Pe as useFileInput,O as useFlag,k as useFlags,V as useHttpStream,c as useImpersonate,q as useInfiniteQuery,B as useLiveTopic,n as useLunora,Re as useMultipartUpload,G as useMutation,K as useMutator,h as useOrganizations,W as usePaginatedQuery,ve as usePasteUpload,Z as usePreloadedQuery,$ as usePresence,re as useQuery,te as useRateLimit,U as useSignUpInvitations,se as useStream,pe as useSubscription,ne as useSuspenseQuery,Fe as useTusUpload,Ie as useUpload,me as useVoiceAgent};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import{c as N}from"react/compiler-runtime";import{useMutation as R}from"./useMutation-
|
|
2
|
+
import{c as N}from"react/compiler-runtime";import{useMutation as R}from"./useMutation-29nXea_s.mjs";import O from"./useSubscription-D9QkGhO3.mjs";const b={__lunoraRef:""},F=_=>{const t=N(20),{api:A,cancel:a,onError:d,run:I,runArgs:f,threadKey:e}=_,s=R(I),T=R(a??b);let c;t[0]!==e?(c={key:e},t[0]=e,t[1]=c):c=t[1];let r;t[2]!==d?(r={onError:d},t[2]=d,t[3]=r):r=t[3];const{data:v,error:p}=O(A.agents.agentThread,c,r),n=v,g=n?.status,o=n?.instanceId,{mutate:m}=s,{mutate:M}=T;let i;t[4]!==f||t[5]!==m||t[6]!==e?(i=async(w,E)=>{await m({input:w,threadKey:e,...f,...E})},t[4]=f,t[5]=m,t[6]=e,t[7]=i):i=t[7];const h=i;let u;t[8]!==M||t[9]!==a||t[10]!==o||t[11]!==e?(u=async()=>{a===void 0||o===void 0||await M({instanceId:o,threadKey:e})},t[8]=M,t[9]=a,t[10]=o,t[11]=e,t[12]=u):u=t[12];const y=u;let l;return t[13]!==y||t[14]!==p||t[15]!==h||t[16]!==s.pending||t[17]!==g||t[18]!==n?(l={cancel:y,error:p,pending:s.pending,run:h,status:g,thread:n},t[13]=y,t[14]=p,t[15]=h,t[16]=s.pending,t[17]=g,t[18]=n,t[19]=l):l=t[19],l};export{F as useAgent};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{reconcileOptimistic as M,maxSeq as R}from"@lunora/client";import{useState as nt,useRef as k}from"react";import{u as rt}from"./lunora-provider-_WqSuvf9.mjs";import{useMutation as s}from"./useMutation-29nXea_s.mjs";import{useStream as at}from"./useStream-D8GB__4j.mjs";import d from"./useSubscription-D9QkGhO3.mjs";const ot={__lunoraRef:""},st={__lunoraRef:""},ct=[],it=[],kt=A=>{const{api:r,cancel:m,limit:g,onError:i,send:E,sendArgs:_,stream:v,threadKey:e}=A,T=g===void 0?{key:e}:{key:e,limit:g},{data:w,error:x}=d(r.agents.agentMessages,T,{onError:i}),{data:G,error:I}=d(r.agents.agentThread,{key:e},{onError:i}),{data:O,error:b}=d(r.agents.agentApprovalGrants,{key:e},{onError:i}),C=v===void 0?"skip":{key:e},{chunks:D}=at(v??st,C),j=s(E),q=s(m??ot),F=s(r.agents.agentResolveApproval),N=s(r.agents.agentRevokeApprovalGrant),K=s(r.agents.agentDeclineSecret),P=rt(),[Y,u]=nt([]),h=k(0),f=k(e);f.current!==e&&(f.current=e,u([]));const y=G,L=y?.status,c=y?.instanceId,a=w??ct,S=M(Y,a),U=R(a),$=S.length===0?a:[...a,...S.map((t,n)=>({content:t.content,optimistic:!0,role:"user",seq:U+1+n}))],z=a.filter(t=>t.role==="assistant").length,B=D.filter(t=>t.kind!=="progress"&&t.threadKey===e&&t.turn>=z).map(t=>t.text).join(""),{mutate:H}=j,{mutate:J}=q,{mutate:Q}=F,{mutate:V}=N,{mutate:W}=K,X=async(t,n)=>{const o=h.current;h.current+=1;const Z=R(a);u(p=>[...M(p,a),{content:t,id:o,maxDurableSeqAtSend:Z}]);try{await H({input:t,threadKey:e,..._,...n})}catch(p){throw u(tt=>tt.filter(et=>et.id!==o)),p}},l=async(t,n,o)=>{if(c===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await Q({decision:t,instanceId:c,threadKey:e,toolCallId:n,...o===void 0?{}:{note:o}})};return{approvalGrants:O??it,approve:(t,n)=>l("approve",t,n),approveForThread:(t,n)=>l("approve_for_thread",t,n),cancel:async()=>{m===void 0||c===void 0||await J({instanceId:c,threadKey:e})},declineSecret:async t=>{await W({threadKey:e,toolCallId:t})},error:x??I??b,messages:$,reject:(t,n)=>l("reject",t,n),revokeGrant:async t=>{await V({threadKey:e,toolName:t})},send:X,status:L,streamingText:B,supplySecret:async(t,n)=>{await P.mutation(r.agents.agentSupplySecret,{secret:n,threadKey:e,toolCallId:t},{onlineOnly:!0})}}};export{kt as useAgentChat};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{c as C}from"react/compiler-runtime";import{useStream as y}from"./useStream-D8GB__4j.mjs";import _ from"./useSubscription-D9QkGhO3.mjs";const I={__lunoraRef:""},N=[],S={awaiting_approval:"awaiting-approval",awaiting_secret:"awaiting-secret"},k=o=>{const t=o.status===void 0?void 0:S[o.status];if(t!==void 0)return{seq:o.seq,type:t,...o.toolCallId===void 0?{}:{toolCallId:o.toolCallId},...o.toolName===void 0?{}:{toolName:o.toolName}}},q=o=>{if(o.role==="assistant"&&o.toolCalls)return o.toolCalls.map(r=>({input:r.input,seq:o.seq,toolCallId:r.id,toolName:r.name,type:"call"}));if(o.role!=="tool")return;const t=k(o);return t!==void 0?[t]:[{output:o.content,seq:o.seq,type:"result",...o.status==="approved"||o.status==="rejected"?{status:o.status}:{},...o.toolCallId===void 0?{}:{toolCallId:o.toolCallId},...o.toolName===void 0?{}:{toolName:o.toolName}}]},m=o=>{const t=C(12),{api:r,limit:n,stream:i,threadKey:l}=o;let a;t[0]!==n||t[1]!==l?(a=n===void 0?{key:l}:{key:l,limit:n},t[0]=n,t[1]=l,t[2]=a):a=t[2];const v=a,{data:f}=_(r.agents.agentMessages,v);let s;t[3]!==i||t[4]!==l?(s=i===void 0?"skip":{key:l},t[3]=i,t[4]=l,t[5]=s):s=t[5];const E=s,{chunks:p}=y(i??I,E),c=f??N;let e;if(t[6]!==p||t[7]!==c||t[8]!==l){e=c.flatMap(A);for(const d of p)d.kind==="progress"&&d.threadKey===l&&e.push({data:d.data,toolCallId:d.toolCallId,type:"progress"});t[6]=p,t[7]=c,t[8]=l,t[9]=e}else e=t[9];let u;return t[10]!==e?(u={events:e},t[10]=e,t[11]=u):u=t[11],u};function A(o){return q(o)??[]}export{m as useAgentToolEvents};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{useQueryClient as k,useMutation as v,onlineManager as g}from"@tanstack/react-query";import{useRef as A,useState as P,useCallback as O}from"react";import{u as Q}from"./lunora-provider-_WqSuvf9.mjs";const R=async()=>new Promise(n=>{if(g.isOnline()){n();return}const r=g.subscribe(u=>{u&&(r(),n())})}),x=n=>{const r=Q(),u=k(),a=n.sensitive===!0,c=A(0),[l,p]=P(!1),b=v({mutationFn:async({args:e,options:t})=>(!(a||t?.onlineOnly===!0)&&!r.canQueueOffline(t?.shardKey)&&await R(),r.mutation(n,e,t)),networkMode:"always",...a?{gcTime:0}:{},retry:0,onMutate:()=>{c.current+=1,p(!0)},onSettled:(e,t,o)=>{if(c.current-=1,p(c.current>0),a||o.options?.onlineOnly===!0){const i=u.getMutationCache();for(const h of i.findAll({predicate:C=>C.state.variables===o}))i.remove(h)}}}),{data:m,error:d,isError:f,mutateAsync:s,reset:y}=b,w=O((e,t)=>s({args:e,options:t}),[s]),M=O(e=>({data:m,error:d,isError:f,mutate:(o,i)=>s({args:o,options:{optimisticUpdate:e,...i}}),pending:l,reset:y,withOptimisticUpdate:M}),[s,m,d,f,l,y]);return{data:m,error:d,isError:f,mutate:w,pending:l,reset:y,withOptimisticUpdate:M}};export{x as useMutation};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import{useState as T,useRef as W,useCallback as y,useEffect as G}from"react";import{u as X}from"./lunora-provider-_WqSuvf9.mjs";const N="/_lunora/ws",j="/_lunora/voice/",z=4001,O=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,Q=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},Y=(e,r)=>{if(r===void 0||r==="")return O(e);if(r.endsWith(N))return r.slice(0,-N.length);try{return new URL(r).origin}catch{return O(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,c=new URLSearchParams({threadKey:e.threadKey});return`${s}${j}${encodeURIComponent(e.agent)}?${c.toString()}`},ee=(e,r)=>{if(r?.code===z)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},te=(e,r,s)=>{const c=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==c&&s(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},ne=16e3,re=e=>{if(e.length===0)return 0;let r=0;for(const s of e)r+=s*s;return Math.sqrt(r/e.length)},se=(e,r)=>{const s=r/ne,c=s>1?Math.floor(e.length/s):e.length,d=new ArrayBuffer(c*2),l=new DataView(d);for(let u=0;u<c;u+=1){const g=e[Math.floor(u*s)]??0,p=Math.max(-1,Math.min(1,g));l.setInt16(u*2,p<0?p*32768:p*32767,!0)}return new Uint8Array(d)},oe=async e=>{const r=globalThis,s=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),c=r.AudioContext??r.webkitAudioContext;if(!s||!c)throw new Error("useVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const d=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new c,u=l.createMediaStreamSource(d),g=l.createScriptProcessor(4096,1,1);let p=!1,w=!1,a=0,h=0;return g.onaudioprocess=o=>{const f=o.inputBuffer.getChannelData(0),m=p?0:re(f);if(e.onLevel(m),p)return;if(e.onAudio(se(f,l.sampleRate)),e.isTurnActive()){h=m>=e.interruptThreshold?h+1:0,h>=e.interruptChunks&&(h=0,e.onInterrupt());return}h=0;const x=f.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,a=0;return}w&&(a+=x,a>=e.silenceDurationMs&&(w=!1,a=0,e.onSilence()))},u.connect(g),g.connect(l.destination),{setMuted:o=>{p=o},stop:()=>{g.disconnect(),u.disconnect();for(const o of d.getTracks())o.stop();l.close()}}},ie=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("useVoiceAgent: audio playback requires AudioContext (no browser audio available)");const s=new r,c=new Set;let d=0,l=Promise.resolve(),u=0;const g=async(a,h)=>{if(h!==u)return;let o;try{o=await s.decodeAudioData(a.buffer)}catch{return}if(h!==u)return;const f=s.createBufferSource();f.buffer=o,f.connect(s.destination);const m=Math.max(s.currentTime,d);f.start(m),d=m+o.duration,c.add(f),f.onended=()=>{c.delete(f)}},p=a=>{const h=Uint8Array.from(a),o=u;l=l.then(()=>g(h,o))},w=()=>{u+=1;for(const a of c)try{a.stop()}catch{}c.clear(),d=s.currentTime};return{enqueue:p,interrupt:w,stop:()=>{w(),s.close()}}},P=1,ce=.01,ae=1200,ue=.15,le=3,he=e=>{const{createMicrophone:r=oe,createSpeaker:s=ie,createSocket:c,interruptChunks:d=le,interruptThreshold:l=ue,silenceDurationMs:u=ae,silenceThreshold:g=ce,threadKey:p,voice:w}=e,a=X(),[h,o]=T("idle"),[f,m]=T(!1),[x,M]=T(""),[H,v]=T(""),[$,R]=T(0),[I,U]=T(!1),[B,E]=T(void 0),i=W(void 0),_=W(!1),C=y(n=>{const t=i.current?.socket;return t?.readyState===P?(t.send(JSON.stringify(n)),!0):!1},[]),A=y(()=>{const n=i.current;if(i.current=void 0,n){n.unwatchIdentity?.(),n.microphone?.stop(),n.speaker?.stop(),n.socket.onmessage=null,n.socket.onerror=null,n.socket.onclose=null;try{n.socket.close()}catch{}}_.current=!1,m(!1),o("idle"),R(0)},[]),L=y(n=>{const t=i.current;switch(n.type){case"assistant_delta":{t&&(t.speaking=!0),o("speaking"),v(F=>F+n.text);break}case"assistant_discarded":{t&&(t.suppressAudio=!0),t?.speaker?.interrupt(),v("");break}case"assistant_done":{t&&(t.awaitingTurn=!1,t.speaking=!1),v(n.text),o("listening");break}case"error":{t&&(t.awaitingTurn=!1,t.speaking=!1),E(new Error(n.message)),o("listening");break}case"interrupted":{t&&(t.awaitingTurn=!1,t.speaking=!1,t.suppressAudio=!1),t?.speaker?.interrupt(),o("listening");break}case"ready":{t&&(t.audioFormat=n.audioFormat,t.suppressAudio=!1),m(!0),o("listening");break}case"user_transcript":{t&&(t.suppressAudio=!1),M(n.text),v(""),o("thinking");break}}},[]),D=y(n=>{const t=i.current;!t||t.suppressAudio||(t.speaker??=s({audioFormat:t.audioFormat}),t.speaking=!0,o("speaking"),t.speaker.enqueue(n))},[s]),q=y(async()=>{if(i.current||_.current)return;_.current=!0,E(void 0),M(""),v("");let n;try{const t=Z({agent:Q(w.__lunoraRef),httpUrl:a.url,threadKey:p,wsUrl:a.wsUrl}),S=(c??(k=>{const b=a.getWebSocketImpl();if(!b)throw new Error("useVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new b(k)}))(t);S.binaryType="arraybuffer",n={audioFormat:"mp3",microphone:void 0,socket:S,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},i.current=n,n.unwatchIdentity=te(a,"useVoiceAgent",k=>{i.current===n&&(E(k),A())}),S.onmessage=k=>{if(typeof k.data=="string"){try{L(JSON.parse(k.data))}catch{}return}D(new Uint8Array(k.data))},S.onerror=()=>{E(new Error("useVoiceAgent: voice socket error"))},S.onclose=k=>{if(i.current!==n)return;const b=ee("useVoiceAgent",k);b&&E(b),A()};const V=await r({interruptChunks:d,interruptThreshold:l,isTurnActive:()=>(i.current?.speaking??!1)||(i.current?.awaitingTurn??!1),onAudio:k=>{S.readyState===P&&S.send(k)},onInterrupt:()=>{C({type:"interrupt"}),i.current?.speaker?.interrupt(),i.current&&(i.current.awaitingTurn=!1,i.current.speaking=!1,i.current.suppressAudio=!0),o("listening")},onLevel:R,onSilence:()=>{C({type:"commit"}),i.current&&(i.current.awaitingTurn=!0),o("thinking")},silenceDurationMs:u,silenceThreshold:g});i.current===n?(n.microphone=V,U(!1),n.speaking||o("listening")):V.stop()}catch(t){i.current===n&&(E(t instanceof Error?t:new Error(String(t))),A())}finally{_.current=!1}},[a,r,c,D,L,d,l,C,u,g,A,p,w]),K=y(()=>{const n=!I;return i.current?.microphone?.setMuted(n),U(n),n},[I]),J=y(n=>{C({text:n,type:"text"})&&(i.current&&(i.current.awaitingTurn=!0),o("thinking"))},[C]);return G(()=>A,[A]),{audioLevel:$,connected:f,endCall:A,error:B,interimTranscript:H,isMuted:I,sendText:J,startCall:q,status:h,toggleMute:K,transcript:x}};export{he as useVoiceAgent};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/react",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.248",
|
|
4
4
|
"description": "React hooks for Lunora: useQuery, useMutation, useSubscription, and useAuth",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -57,10 +57,10 @@
|
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@lunora/client": "1.0.0-alpha.
|
|
60
|
+
"@lunora/client": "1.0.0-alpha.235",
|
|
61
61
|
"@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
|
|
62
|
-
"@lunora/ratelimit": "1.0.0-alpha.
|
|
63
|
-
"@lunora/wire": "1.0.0-alpha.
|
|
62
|
+
"@lunora/ratelimit": "1.0.0-alpha.157",
|
|
63
|
+
"@lunora/wire": "1.0.0-alpha.2",
|
|
64
64
|
"@visulima/storage-client": "1.0.9"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{reconcileOptimistic as M,maxSeq as R}from"@lunora/client";import{useState as Q,useRef as S}from"react";import{useMutation as u}from"./useMutation-Bz9uwvGf.mjs";import{useStream as V}from"./useStream-D8GB__4j.mjs";import A from"./useSubscription-D9QkGhO3.mjs";const W={__lunoraRef:""},X={__lunoraRef:""},Z=[],it=E=>{const{api:a,cancel:m,limit:d,onError:l,send:_,sendArgs:k,stream:p,threadKey:e}=E,x=d===void 0?{key:e}:{key:e,limit:d},{data:w,error:O}=A(a.agents.agentMessages,x,{onError:l}),{data:T,error:b}=A(a.agents.agentThread,{key:e},{onError:l}),I=p===void 0?"skip":{key:e},{chunks:j}=V(p??X,I),q=u(_),C=u(m??W),D=u(a.agents.agentResolveApproval),[K,c]=Q([]),f=S(0),h=S(e);h.current!==e&&(h.current=e,c([]));const g=T,N=g?.status,o=g?.instanceId,s=w??Z,v=M(K,s),F=R(s),G=v.length===0?s:[...s,...v.map((t,n)=>({content:t.content,optimistic:!0,role:"user",seq:F+1+n}))],P=s.filter(t=>t.role==="assistant").length,U=j.filter(t=>t.kind!=="progress"&&t.threadKey===e&&t.turn>=P).map(t=>t.text).join(""),{mutate:Y}=q,{mutate:$}=C,{mutate:z}=D,B=async(t,n)=>{const r=f.current;f.current+=1;const H=R(s);c(i=>[...M(i,s),{content:t,id:r,maxDurableSeqAtSend:H}]);try{await Y({input:t,threadKey:e,...k,...n})}catch(i){throw c(J=>J.filter(L=>L.id!==r)),i}},y=async(t,n,r)=>{if(o===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await z({decision:t,instanceId:o,threadKey:e,toolCallId:n,...r===void 0?{}:{note:r}})};return{approve:(t,n)=>y("approve",t,n),cancel:async()=>{m===void 0||o===void 0||await $({instanceId:o,threadKey:e})},error:O??b,messages:G,reject:(t,n)=>y("reject",t,n),send:B,status:N,streamingText:U}};export{it as useAgentChat};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{c as y}from"react/compiler-runtime";import{useStream as I}from"./useStream-D8GB__4j.mjs";import N from"./useSubscription-D9QkGhO3.mjs";const E={__lunoraRef:""},_=[],k=o=>{if(o.role==="assistant"&&o.toolCalls)return o.toolCalls.map(t=>({input:t.input,seq:o.seq,toolCallId:t.id,toolName:t.name,type:"call"}));if(o.role==="tool")return o.status==="awaiting_approval"?[{seq:o.seq,type:"awaiting-approval",...o.toolCallId===void 0?{}:{toolCallId:o.toolCallId},...o.toolName===void 0?{}:{toolName:o.toolName}}]:[{output:o.content,seq:o.seq,type:"result",...o.status==="approved"||o.status==="rejected"?{status:o.status}:{},...o.toolCallId===void 0?{}:{toolCallId:o.toolCallId},...o.toolName===void 0?{}:{toolName:o.toolName}}]},A=o=>{const t=y(12),{api:c,limit:r,stream:n,threadKey:l}=o;let a;t[0]!==r||t[1]!==l?(a=r===void 0?{key:l}:{key:l,limit:r},t[0]=r,t[1]=l,t[2]=a):a=t[2];const f=a,{data:v}=N(c.agents.agentMessages,f);let i;t[3]!==n||t[4]!==l?(i=n===void 0?"skip":{key:l},t[3]=n,t[4]=l,t[5]=i):i=t[5];const C=i,{chunks:p}=I(n??E,C),s=v??_;let e;if(t[6]!==p||t[7]!==s||t[8]!==l){e=s.flatMap(q);for(const d of p)d.kind==="progress"&&d.threadKey===l&&e.push({data:d.data,toolCallId:d.toolCallId,type:"progress"});t[6]=p,t[7]=s,t[8]=l,t[9]=e}else e=t[9];let u;return t[10]!==e?(u={events:e},t[10]=e,t[11]=u):u=t[11],u};function q(o){return k(o)??[]}export{A as useAgentToolEvents};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{useMutation as y,onlineManager as p}from"@tanstack/react-query";import{useRef as O,useState as h,useCallback as l}from"react";import{u as k}from"./lunora-provider-_WqSuvf9.mjs";const C=async()=>new Promise(r=>{if(p.isOnline()){r();return}const s=p.subscribe(t=>{t&&(s(),r())})}),U=r=>{const s=k(),t=O(0),[u,d]=h(!1),M=y({mutationFn:async({args:n,options:e})=>(s.canQueueOffline(e?.shardKey)||await C(),s.mutation(r,n,e)),networkMode:"always",retry:0,onMutate:()=>{t.current+=1,d(!0)},onSettled:()=>{t.current-=1,d(t.current>0)}}),{data:a,error:i,isError:c,mutateAsync:o,reset:m}=M,b=l((n,e)=>o({args:n,options:e}),[o]),f=l(n=>({data:a,error:i,isError:c,mutate:(g,w)=>o({args:g,options:{optimisticUpdate:n,...w}}),pending:u,reset:m,withOptimisticUpdate:f}),[o,a,i,c,u,m]);return{data:a,error:i,isError:c,mutate:b,pending:u,reset:m,withOptimisticUpdate:f}};export{U as useMutation};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import{useState as T,useRef as W,useCallback as y,useEffect as G}from"react";import{u as X}from"./lunora-provider-_WqSuvf9.mjs";const N="/_lunora/ws",j="/_lunora/voice/",z=4001,O=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,Q=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},Y=(e,r)=>{if(r===void 0||r==="")return O(e);if(r.endsWith(N))return r.slice(0,-N.length);try{return new URL(r).origin}catch{return O(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),o=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${o}${j}${encodeURIComponent(e.agent)}?${i.toString()}`},ee=(e,r)=>{if(r?.code===z)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},te=(e,r,o)=>{const i=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==i&&o(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},ne=16e3,re=e=>{if(e.length===0)return 0;let r=0;for(const o of e)r+=o*o;return Math.sqrt(r/e.length)},oe=(e,r)=>{const o=r/ne,i=o>1?Math.floor(e.length/o):e.length,d=new ArrayBuffer(i*2),l=new DataView(d);for(let u=0;u<i;u+=1){const g=e[Math.floor(u*o)]??0,p=Math.max(-1,Math.min(1,g));l.setInt16(u*2,p<0?p*32768:p*32767,!0)}return new Uint8Array(d)},se=async e=>{const r=globalThis,o=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),i=r.AudioContext??r.webkitAudioContext;if(!o||!i)throw new Error("useVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const d=await o({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new i,u=l.createMediaStreamSource(d),g=l.createScriptProcessor(4096,1,1);let p=!1,w=!1,a=0,h=0;return g.onaudioprocess=s=>{const f=s.inputBuffer.getChannelData(0),m=p?0:re(f);if(e.onLevel(m),p)return;if(e.onAudio(oe(f,l.sampleRate)),e.isTurnActive()){h=m>=e.interruptThreshold?h+1:0,h>=e.interruptChunks&&(h=0,e.onInterrupt());return}h=0;const x=f.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,a=0;return}w&&(a+=x,a>=e.silenceDurationMs&&(w=!1,a=0,e.onSilence()))},u.connect(g),g.connect(l.destination),{setMuted:s=>{p=s},stop:()=>{g.disconnect(),u.disconnect();for(const s of d.getTracks())s.stop();l.close()}}},ce=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("useVoiceAgent: audio playback requires AudioContext (no browser audio available)");const o=new r,i=new Set;let d=0,l=Promise.resolve(),u=0;const g=async(a,h)=>{if(h!==u)return;let s;try{s=await o.decodeAudioData(a.buffer)}catch{return}if(h!==u)return;const f=o.createBufferSource();f.buffer=s,f.connect(o.destination);const m=Math.max(o.currentTime,d);f.start(m),d=m+s.duration,i.add(f),f.onended=()=>{i.delete(f)}},p=a=>{const h=Uint8Array.from(a),s=u;l=l.then(()=>g(h,s))},w=()=>{u+=1;for(const a of i)try{a.stop()}catch{}i.clear(),d=o.currentTime};return{enqueue:p,interrupt:w,stop:()=>{w(),o.close()}}},P=1,ie=.01,ae=1200,ue=.15,le=3,he=e=>{const{createMicrophone:r=se,createSpeaker:o=ce,createSocket:i,interruptChunks:d=le,interruptThreshold:l=ue,silenceDurationMs:u=ae,silenceThreshold:g=ie,threadKey:p,voice:w}=e,a=X(),[h,s]=T("idle"),[f,m]=T(!1),[x,M]=T(""),[H,b]=T(""),[$,R]=T(0),[I,U]=T(!1),[B,E]=T(void 0),c=W(void 0),_=W(!1),v=y(t=>{const n=c.current?.socket;return n?.readyState===P?(n.send(JSON.stringify(t)),!0):!1},[]),A=y(()=>{const t=c.current;if(c.current=void 0,t){t.unwatchIdentity?.(),t.microphone?.stop(),t.speaker?.stop(),t.socket.onmessage=null,t.socket.onerror=null,t.socket.onclose=null;try{t.socket.close()}catch{}}_.current=!1,m(!1),s("idle"),R(0)},[]),L=y(t=>{const n=c.current;switch(t.type){case"assistant_delta":{n&&(n.speaking=!0),s("speaking"),b(F=>F+t.text);break}case"assistant_done":{n&&(n.awaitingTurn=!1,n.speaking=!1),b(t.text),s("listening");break}case"error":{n&&(n.awaitingTurn=!1,n.speaking=!1),E(new Error(t.message)),s("listening");break}case"interrupted":{n&&(n.awaitingTurn=!1,n.speaking=!1,n.suppressAudio=!1),n?.speaker?.interrupt(),s("listening");break}case"ready":{n&&(n.audioFormat=t.audioFormat,n.suppressAudio=!1),m(!0),s("listening");break}case"user_transcript":{n&&(n.suppressAudio=!1),M(t.text),b(""),s("thinking");break}}},[]),D=y(t=>{const n=c.current;!n||n.suppressAudio||(n.speaker??=o({audioFormat:n.audioFormat}),n.speaking=!0,s("speaking"),n.speaker.enqueue(t))},[o]),q=y(async()=>{if(c.current||_.current)return;_.current=!0,E(void 0),M(""),b("");let t;try{const n=Z({agent:Q(w.__lunoraRef),httpUrl:a.url,threadKey:p,wsUrl:a.wsUrl}),S=(i??(k=>{const C=a.getWebSocketImpl();if(!C)throw new Error("useVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new C(k)}))(n);S.binaryType="arraybuffer",t={audioFormat:"mp3",microphone:void 0,socket:S,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},c.current=t,t.unwatchIdentity=te(a,"useVoiceAgent",k=>{c.current===t&&(E(k),A())}),S.onmessage=k=>{if(typeof k.data=="string"){try{L(JSON.parse(k.data))}catch{}return}D(new Uint8Array(k.data))},S.onerror=()=>{E(new Error("useVoiceAgent: voice socket error"))},S.onclose=k=>{if(c.current!==t)return;const C=ee("useVoiceAgent",k);C&&E(C),A()};const V=await r({interruptChunks:d,interruptThreshold:l,isTurnActive:()=>(c.current?.speaking??!1)||(c.current?.awaitingTurn??!1),onAudio:k=>{S.readyState===P&&S.send(k)},onInterrupt:()=>{v({type:"interrupt"}),c.current?.speaker?.interrupt(),c.current&&(c.current.awaitingTurn=!1,c.current.speaking=!1,c.current.suppressAudio=!0),s("listening")},onLevel:R,onSilence:()=>{v({type:"commit"}),c.current&&(c.current.awaitingTurn=!0),s("thinking")},silenceDurationMs:u,silenceThreshold:g});c.current===t?(t.microphone=V,U(!1),t.speaking||s("listening")):V.stop()}catch(n){c.current===t&&(E(n instanceof Error?n:new Error(String(n))),A())}finally{_.current=!1}},[a,r,i,D,L,d,l,v,u,g,A,p,w]),K=y(()=>{const t=!I;return c.current?.microphone?.setMuted(t),U(t),t},[I]),J=y(t=>{v({text:t,type:"text"})&&(c.current&&(c.current.awaitingTurn=!0),s("thinking"))},[v]);return G(()=>A,[A]),{audioLevel:$,connected:f,endCall:A,error:B,interimTranscript:H,isMuted:I,sendText:J,startCall:q,status:h,toggleMute:K,transcript:x}};export{he as useVoiceAgent};
|