@lunora/vue 1.0.0-alpha.273 → 1.0.0-alpha.274
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +69 -11
- package/dist/index.d.ts +69 -11
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/useAgentChat-CVgX8Z-J.mjs +1 -0
- package/dist/packem_shared/useAgentToolEvents-CWHORsCT.mjs +1 -0
- package/dist/packem_shared/useVoiceAgent-Dz1t4xgi.mjs +1 -0
- package/package.json +3 -3
- package/dist/packem_shared/useAgentChat-CNBm2vp1.mjs +0 -1
- package/dist/packem_shared/useAgentToolEvents-CFGnBjKS.mjs +0 -1
- package/dist/packem_shared/useVoiceAgent-BEGHhbmX.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component, Ref, InjectionKey, App, MaybeRefOrGetter, ComputedRef, DeepReadonly, ShallowRef } from 'vue';
|
|
2
|
-
import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutationCallOptions, MutatorHandle, SubscriptionError } from '@lunora/client';
|
|
2
|
+
import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutationCallOptions, OnlineOnlyOption, MutatorHandle, SubscriptionError } from '@lunora/client';
|
|
3
3
|
export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, MutatorHandle, MutatorTransaction, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe, User } from '@lunora/client';
|
|
4
4
|
import { AuthStatus } from '@lunora/client/auth';
|
|
5
5
|
import { PaginationStatus } from '@lunora/client/pagination';
|
|
@@ -262,8 +262,8 @@ interface AgentChatMessage {
|
|
|
262
262
|
optimistic?: boolean;
|
|
263
263
|
role: "assistant" | "system" | "tool" | "user";
|
|
264
264
|
seq: number;
|
|
265
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
266
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
265
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
266
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
267
267
|
toolCallId?: string;
|
|
268
268
|
toolCalls?: ReadonlyArray<{
|
|
269
269
|
id: string;
|
|
@@ -317,7 +317,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
317
317
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
318
318
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
319
319
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
320
|
-
decision: "approve" | "reject";
|
|
320
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
321
321
|
instanceId: string;
|
|
322
322
|
note?: string;
|
|
323
323
|
threadKey: string;
|
|
@@ -325,10 +325,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
325
325
|
}, {
|
|
326
326
|
resolved: boolean;
|
|
327
327
|
}>;
|
|
328
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
329
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
330
|
+
secret: string;
|
|
331
|
+
threadKey: string;
|
|
332
|
+
toolCallId: string;
|
|
333
|
+
}, {
|
|
334
|
+
resolved: boolean;
|
|
335
|
+
}>;
|
|
336
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
337
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
338
|
+
threadKey: string;
|
|
339
|
+
toolCallId: string;
|
|
340
|
+
}, {
|
|
341
|
+
resolved: boolean;
|
|
342
|
+
}>;
|
|
328
343
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
329
344
|
type AgentThreadReference = FunctionReference<"query", {
|
|
330
345
|
key: string;
|
|
331
346
|
}, Record<string, unknown> | undefined>;
|
|
347
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
348
|
+
interface AgentApprovalGrant {
|
|
349
|
+
createdAt: number;
|
|
350
|
+
toolName: string;
|
|
351
|
+
}
|
|
352
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
353
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
354
|
+
key: string;
|
|
355
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
356
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
357
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
358
|
+
threadKey: string;
|
|
359
|
+
toolName: string;
|
|
360
|
+
}, {
|
|
361
|
+
revoked: boolean;
|
|
362
|
+
}>;
|
|
332
363
|
/**
|
|
333
364
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
334
365
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -344,8 +375,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
344
375
|
*/
|
|
345
376
|
interface UseAgentChatApi {
|
|
346
377
|
agents: {
|
|
378
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
379
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
347
380
|
agentMessages: AgentMessagesReference$1;
|
|
348
381
|
agentResolveApproval: AgentApprovalReference;
|
|
382
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
383
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
349
384
|
agentThread: AgentThreadReference;
|
|
350
385
|
};
|
|
351
386
|
}
|
|
@@ -362,7 +397,7 @@ interface UseAgentChatOptions {
|
|
|
362
397
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
363
398
|
limit?: number;
|
|
364
399
|
/**
|
|
365
|
-
* Called when the live history or
|
|
400
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
366
401
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
367
402
|
* such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
|
|
368
403
|
*/
|
|
@@ -385,29 +420,47 @@ interface UseAgentChatOptions {
|
|
|
385
420
|
threadKey: MaybeRefOrGetter<string>;
|
|
386
421
|
}
|
|
387
422
|
interface UseAgentChatResult {
|
|
423
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
424
|
+
approvalGrants: ComputedRef<ReadonlyArray<AgentApprovalGrant>>;
|
|
388
425
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
389
426
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
427
|
+
/**
|
|
428
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
429
|
+
* later calls to it run without pausing. Undo with {@link UseAgentChatResult.revokeGrant}.
|
|
430
|
+
*/
|
|
431
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
390
432
|
/**
|
|
391
433
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
392
434
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
393
435
|
*/
|
|
394
436
|
cancel: () => Promise<void>;
|
|
395
|
-
/**
|
|
437
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
438
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
439
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
396
440
|
error: ComputedRef<Error | undefined>;
|
|
397
441
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
398
442
|
messages: ComputedRef<ReadonlyArray<AgentChatMessage>>;
|
|
399
443
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
400
444
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
445
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
446
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
401
447
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
402
448
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
403
449
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
404
450
|
status: ComputedRef<AgentThreadStatus | undefined>;
|
|
405
451
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
406
452
|
streamingText: ComputedRef<string>;
|
|
453
|
+
/**
|
|
454
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
455
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
456
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The composable keeps no copy;
|
|
457
|
+
* a failure rethrows the original error.
|
|
458
|
+
*/
|
|
459
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
407
460
|
}
|
|
408
461
|
/**
|
|
409
462
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
410
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey` —
|
|
463
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey` —
|
|
411
464
|
* the Vue counterpart to React's `useAgentChat`, re-expressed with refs.
|
|
412
465
|
*
|
|
413
466
|
* It composes the existing primitives rather than adding transport:
|
|
@@ -503,7 +556,7 @@ interface UseAgentToolEventsOptions {
|
|
|
503
556
|
* Optional live event stream — the same app stream function `useAgentChat`
|
|
504
557
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
505
558
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
506
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
559
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
507
560
|
*/
|
|
508
561
|
stream?: AgentLiveStreamReference;
|
|
509
562
|
/** The thread whose tool activity to observe — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
|
|
@@ -511,7 +564,7 @@ interface UseAgentToolEventsOptions {
|
|
|
511
564
|
}
|
|
512
565
|
/**
|
|
513
566
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
514
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
567
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
515
568
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
516
569
|
* stream and has no `seq`. Discriminate on `type`.
|
|
517
570
|
*/
|
|
@@ -537,6 +590,11 @@ type AgentToolEvent = {
|
|
|
537
590
|
toolCallId?: string;
|
|
538
591
|
toolName?: string;
|
|
539
592
|
type: "awaiting-approval";
|
|
593
|
+
} | {
|
|
594
|
+
seq: number;
|
|
595
|
+
toolCallId?: string;
|
|
596
|
+
toolName?: string;
|
|
597
|
+
type: "awaiting-secret";
|
|
540
598
|
};
|
|
541
599
|
interface UseAgentToolEventsResult {
|
|
542
600
|
/**
|
|
@@ -698,7 +756,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
698
756
|
/** The latest invocation's error, or `undefined`. */
|
|
699
757
|
error: Ref<Error | undefined>;
|
|
700
758
|
/** Invoke the mutation. Resolves with the server value; rejects on failure. */
|
|
701
|
-
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
759
|
+
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
702
760
|
/** `true` while ANY invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
|
|
703
761
|
pending: Ref<boolean>;
|
|
704
762
|
/** Clear the latest `data`/`error` back to idle. */
|
|
@@ -1192,7 +1250,7 @@ interface UseVoiceAgentResult {
|
|
|
1192
1250
|
* `createSocket`) so the composable is drivable outside a browser.
|
|
1193
1251
|
*/
|
|
1194
1252
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1195
|
-
export { type ActionHandle, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type FlagValue, type HeartbeatReference,
|
|
1253
|
+
export { type ActionHandle, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type FlagValue, type HeartbeatReference,
|
|
1196
1254
|
/**
|
|
1197
1255
|
* `@lunora/vue` — the Vue adapter for Lunora.
|
|
1198
1256
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component, Ref, InjectionKey, App, MaybeRefOrGetter, ComputedRef, DeepReadonly, ShallowRef } from 'vue';
|
|
2
|
-
import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutationCallOptions, MutatorHandle, SubscriptionError } from '@lunora/client';
|
|
2
|
+
import { Preloaded, SubscriptionErrorCallback, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, LiveTopicOptions, LiveStreamSubscribeError, LiveTopicRef, MutationCallOptions, OnlineOnlyOption, MutatorHandle, SubscriptionError } from '@lunora/client';
|
|
3
3
|
export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, MutatorHandle, MutatorTransaction, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe, User } from '@lunora/client';
|
|
4
4
|
import { AuthStatus } from '@lunora/client/auth';
|
|
5
5
|
import { PaginationStatus } from '@lunora/client/pagination';
|
|
@@ -262,8 +262,8 @@ interface AgentChatMessage {
|
|
|
262
262
|
optimistic?: boolean;
|
|
263
263
|
role: "assistant" | "system" | "tool" | "user";
|
|
264
264
|
seq: number;
|
|
265
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
266
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
265
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
266
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
267
267
|
toolCallId?: string;
|
|
268
268
|
toolCalls?: ReadonlyArray<{
|
|
269
269
|
id: string;
|
|
@@ -317,7 +317,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
317
317
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
318
318
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
319
319
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
320
|
-
decision: "approve" | "reject";
|
|
320
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
321
321
|
instanceId: string;
|
|
322
322
|
note?: string;
|
|
323
323
|
threadKey: string;
|
|
@@ -325,10 +325,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
325
325
|
}, {
|
|
326
326
|
resolved: boolean;
|
|
327
327
|
}>;
|
|
328
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
329
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
330
|
+
secret: string;
|
|
331
|
+
threadKey: string;
|
|
332
|
+
toolCallId: string;
|
|
333
|
+
}, {
|
|
334
|
+
resolved: boolean;
|
|
335
|
+
}>;
|
|
336
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
337
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
338
|
+
threadKey: string;
|
|
339
|
+
toolCallId: string;
|
|
340
|
+
}, {
|
|
341
|
+
resolved: boolean;
|
|
342
|
+
}>;
|
|
328
343
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
329
344
|
type AgentThreadReference = FunctionReference<"query", {
|
|
330
345
|
key: string;
|
|
331
346
|
}, Record<string, unknown> | undefined>;
|
|
347
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
348
|
+
interface AgentApprovalGrant {
|
|
349
|
+
createdAt: number;
|
|
350
|
+
toolName: string;
|
|
351
|
+
}
|
|
352
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
353
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
354
|
+
key: string;
|
|
355
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
356
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
357
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
358
|
+
threadKey: string;
|
|
359
|
+
toolName: string;
|
|
360
|
+
}, {
|
|
361
|
+
revoked: boolean;
|
|
362
|
+
}>;
|
|
332
363
|
/**
|
|
333
364
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
334
365
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -344,8 +375,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
344
375
|
*/
|
|
345
376
|
interface UseAgentChatApi {
|
|
346
377
|
agents: {
|
|
378
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
379
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
347
380
|
agentMessages: AgentMessagesReference$1;
|
|
348
381
|
agentResolveApproval: AgentApprovalReference;
|
|
382
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
383
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
349
384
|
agentThread: AgentThreadReference;
|
|
350
385
|
};
|
|
351
386
|
}
|
|
@@ -362,7 +397,7 @@ interface UseAgentChatOptions {
|
|
|
362
397
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
363
398
|
limit?: number;
|
|
364
399
|
/**
|
|
365
|
-
* Called when the live history or
|
|
400
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
366
401
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
367
402
|
* such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
|
|
368
403
|
*/
|
|
@@ -385,29 +420,47 @@ interface UseAgentChatOptions {
|
|
|
385
420
|
threadKey: MaybeRefOrGetter<string>;
|
|
386
421
|
}
|
|
387
422
|
interface UseAgentChatResult {
|
|
423
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
424
|
+
approvalGrants: ComputedRef<ReadonlyArray<AgentApprovalGrant>>;
|
|
388
425
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
389
426
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
427
|
+
/**
|
|
428
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
429
|
+
* later calls to it run without pausing. Undo with {@link UseAgentChatResult.revokeGrant}.
|
|
430
|
+
*/
|
|
431
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
390
432
|
/**
|
|
391
433
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
392
434
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
393
435
|
*/
|
|
394
436
|
cancel: () => Promise<void>;
|
|
395
|
-
/**
|
|
437
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
438
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
439
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
396
440
|
error: ComputedRef<Error | undefined>;
|
|
397
441
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
398
442
|
messages: ComputedRef<ReadonlyArray<AgentChatMessage>>;
|
|
399
443
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
400
444
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
445
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
446
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
401
447
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
402
448
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
403
449
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
404
450
|
status: ComputedRef<AgentThreadStatus | undefined>;
|
|
405
451
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
406
452
|
streamingText: ComputedRef<string>;
|
|
453
|
+
/**
|
|
454
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
455
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
456
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The composable keeps no copy;
|
|
457
|
+
* a failure rethrows the original error.
|
|
458
|
+
*/
|
|
459
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
407
460
|
}
|
|
408
461
|
/**
|
|
409
462
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
410
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey` —
|
|
463
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey` —
|
|
411
464
|
* the Vue counterpart to React's `useAgentChat`, re-expressed with refs.
|
|
412
465
|
*
|
|
413
466
|
* It composes the existing primitives rather than adding transport:
|
|
@@ -503,7 +556,7 @@ interface UseAgentToolEventsOptions {
|
|
|
503
556
|
* Optional live event stream — the same app stream function `useAgentChat`
|
|
504
557
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
505
558
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
506
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
559
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
507
560
|
*/
|
|
508
561
|
stream?: AgentLiveStreamReference;
|
|
509
562
|
/** The thread whose tool activity to observe — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
|
|
@@ -511,7 +564,7 @@ interface UseAgentToolEventsOptions {
|
|
|
511
564
|
}
|
|
512
565
|
/**
|
|
513
566
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
514
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
567
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
515
568
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
516
569
|
* stream and has no `seq`. Discriminate on `type`.
|
|
517
570
|
*/
|
|
@@ -537,6 +590,11 @@ type AgentToolEvent = {
|
|
|
537
590
|
toolCallId?: string;
|
|
538
591
|
toolName?: string;
|
|
539
592
|
type: "awaiting-approval";
|
|
593
|
+
} | {
|
|
594
|
+
seq: number;
|
|
595
|
+
toolCallId?: string;
|
|
596
|
+
toolName?: string;
|
|
597
|
+
type: "awaiting-secret";
|
|
540
598
|
};
|
|
541
599
|
interface UseAgentToolEventsResult {
|
|
542
600
|
/**
|
|
@@ -698,7 +756,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
698
756
|
/** The latest invocation's error, or `undefined`. */
|
|
699
757
|
error: Ref<Error | undefined>;
|
|
700
758
|
/** Invoke the mutation. Resolves with the server value; rejects on failure. */
|
|
701
|
-
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
759
|
+
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
702
760
|
/** `true` while ANY invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
|
|
703
761
|
pending: Ref<boolean>;
|
|
704
762
|
/** Clear the latest `data`/`error` back to idle. */
|
|
@@ -1192,7 +1250,7 @@ interface UseVoiceAgentResult {
|
|
|
1192
1250
|
* `createSocket`) so the composable is drivable outside a browser.
|
|
1193
1251
|
*/
|
|
1194
1252
|
declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
|
|
1195
|
-
export { type ActionHandle, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type FlagValue, type HeartbeatReference,
|
|
1253
|
+
export { type ActionHandle, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type FlagValue, type HeartbeatReference,
|
|
1196
1254
|
/**
|
|
1197
1255
|
* `@lunora/vue` — the Vue adapter for Lunora.
|
|
1198
1256
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthLoading as r,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-ZXVgXos1.mjs";import{hydratePreloaded as p}from"./packem_shared/hydratePreloaded-DicHNxhB.mjs";import{LUNORA_INJECTION_KEY as f,createLunora as m,provideLunora as n,useLunora as x}from"./packem_shared/LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{useAction as c}from"./packem_shared/useAction-C4VLsh4M.mjs";import{useAgent as d}from"./packem_shared/useAgent-Bp5UEoEp.mjs";import{useAgentChat as L}from"./packem_shared/useAgentChat-
|
|
1
|
+
import{AuthLoading as r,Authenticated as t,Unauthenticated as u}from"./packem_shared/AuthLoading-ZXVgXos1.mjs";import{hydratePreloaded as p}from"./packem_shared/hydratePreloaded-DicHNxhB.mjs";import{LUNORA_INJECTION_KEY as f,createLunora as m,provideLunora as n,useLunora as x}from"./packem_shared/LUNORA_INJECTION_KEY-Bct9tKCj.mjs";import{useAction as c}from"./packem_shared/useAction-C4VLsh4M.mjs";import{useAgent as d}from"./packem_shared/useAgent-Bp5UEoEp.mjs";import{useAgentChat as L}from"./packem_shared/useAgentChat-CVgX8Z-J.mjs";import{useAgentState as l}from"./packem_shared/useAgentState-DpFm2lH0.mjs";import{useAgentToolEvents as Q}from"./packem_shared/useAgentToolEvents-CWHORsCT.mjs";import{useAuth as T}from"./packem_shared/useAuth-QDllAwZL.mjs";import{default as v}from"./packem_shared/useConnectionStatus-CCUbKnj2.mjs";import{useFlag as E,useFlags as I}from"./packem_shared/useFlag-xVfWC_c6.mjs";import{useLiveTopic as P}from"./packem_shared/useLiveTopic-B0HA04MY.mjs";import{useMutation as M}from"./packem_shared/useMutation-D6PkaNaE.mjs";import{useMutator as R}from"./packem_shared/useMutator-CO7nXlRf.mjs";import{useInfiniteQuery as _,usePaginatedQuery as J}from"./packem_shared/useInfiniteQuery-Clqt_MYU.mjs";import{usePresence as V}from"./packem_shared/usePresence-Dpnb4kjv.mjs";import{subscribeToQuery as j,useQuery as k}from"./packem_shared/subscribeToQuery-BvnA8ErG.mjs";import{useRateLimit as w}from"./packem_shared/useRateLimit-zoPsflSG.mjs";import{useStream as B}from"./packem_shared/useStream-COVzNdKq.mjs";import{useSubscription as G}from"./packem_shared/useSubscription-cTKyOIAv.mjs";import{useVoiceAgent as W}from"./packem_shared/useVoiceAgent-Dz1t4xgi.mjs";export{r as AuthLoading,t as Authenticated,f as LUNORA_INJECTION_KEY,u as Unauthenticated,m as createLunora,p as hydratePreloaded,n as provideLunora,j as subscribeToQuery,c as useAction,d as useAgent,L as useAgentChat,l as useAgentState,Q as useAgentToolEvents,T as useAuth,v as useConnectionStatus,E as useFlag,I as useFlags,_ as useInfiniteQuery,P as useLiveTopic,x as useLunora,M as useMutation,R as useMutator,J as usePaginatedQuery,V as usePresence,k as useQuery,w as useRateLimit,B as useStream,G as useSubscription,W as useVoiceAgent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{reconcileOptimistic as A,maxSeq as k}from"@lunora/client";import{computed as s,ref as X,watch as Z,toValue as n}from"vue";import{NO_MUTATION_REF as tt}from"./useAgent-Bp5UEoEp.mjs";import{useMutation as u}from"./useMutation-D6PkaNaE.mjs";import{useStream as et}from"./useStream-COVzNdKq.mjs";import{useSubscription as y}from"./useSubscription-cTKyOIAv.mjs";const at={__lunoraRef:""},rt=[],lt=w=>{const{api:o,cancel:h,limit:g,onError:p,send:M,sendArgs:E,stream:f,threadKey:r}=w,{data:R,error:_}=y(o.agents.agentMessages,()=>{const t=n(r);return g===void 0?{key:t}:{key:t,limit:g}},{onError:p}),{data:K,error:T}=y(o.agents.agentThread,()=>({key:n(r)}),{onError:p}),{data:x,error:I}=y(o.agents.agentApprovalGrants,()=>({key:n(r)}),{onError:p}),b=s(()=>_.value??T.value??I.value),D=f===void 0?"skip":()=>({key:n(r)}),{chunks:G}=et(f??at,D),O=u(M),q=u(h??tt),N=u(o.agents.agentResolveApproval),j=u(o.agents.agentRevokeApprovalGrant),C=u(o.agents.agentSupplySecret),F=u(o.agents.agentDeclineSecret),c=X([]);let S=0;Z(()=>n(r),()=>{c.value=[]});const d=s(()=>K.value),P=s(()=>d.value?.status),l=s(()=>R.value??[]),U=s(()=>{const t=l.value,e=A(c.value,t);if(e.length===0)return t;const a=k(t);return[...t,...e.map((i,m)=>({content:i.content,optimistic:!0,role:"user",seq:a+1+m}))]}),V=s(()=>{const t=n(r),e=l.value.filter(a=>a.role==="assistant").length;return G.value.filter(a=>a.kind!=="progress"&&a.threadKey===t&&a.turn>=e).map(a=>a.text).join("")}),Y=async(t,e)=>{const a=S;S+=1;const i=k(l.value);c.value=[...A(c.value,l.value),{content:t,id:a,maxDurableSeqAtSend:i}];try{await O.mutate({input:t,threadKey:n(r),...E,...e})}catch(m){throw c.value=c.value.filter(W=>W.id!==a),m}},v=async(t,e,a)=>{const i=d.value?.instanceId;if(i===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await N.mutate({decision:t,instanceId:i,threadKey:n(r),toolCallId:e,...a===void 0?{}:{note:a}})},$=async(t,e)=>v("approve",t,e),z=async(t,e)=>v("approve_for_thread",t,e),B=async(t,e)=>v("reject",t,e),H=async t=>{await j.mutate({threadKey:n(r),toolName:t})},J=async(t,e)=>{await C.mutate({secret:e,threadKey:n(r),toolCallId:t},{onlineOnly:!0})},L=async t=>{await F.mutate({threadKey:n(r),toolCallId:t})},Q=async()=>{const t=d.value?.instanceId;h===void 0||t===void 0||await q.mutate({instanceId:t,threadKey:n(r)})};return{approvalGrants:s(()=>x.value??rt),approve:$,approveForThread:z,cancel:Q,declineSecret:L,error:b,messages:U,reject:B,revokeGrant:H,send:Y,status:P,streamingText:V,supplySecret:J}};export{lt as useAgentChat};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{computed as v,toValue as a}from"vue";import{useStream as f}from"./useStream-COVzNdKq.mjs";import{useSubscription as E}from"./useSubscription-cTKyOIAv.mjs";const C={__lunoraRef:""},y=[],I={awaiting_approval:"awaiting-approval",awaiting_secret:"awaiting-secret"},N=t=>{const o=t.status===void 0?void 0:I[t.status];if(o!==void 0)return{seq:t.seq,type:o,...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}},_=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(r=>({input:r.input,seq:t.seq,toolCallId:r.id,toolName:r.name,type:"call"}));if(t.role!=="tool")return;const o=N(t);return o!==void 0?[o]:[{output:t.content,seq:t.seq,type:"result",...t.status==="approved"||t.status==="rejected"?{status:t.status}:{},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]},M=t=>{const{api:o,limit:r,stream:i,threadKey:e}=t,d=()=>{const l=a(e);return r===void 0?{key:l}:{key:l,limit:r}},{data:s}=E(o.agents.agentMessages,d),p=i===void 0?"skip":()=>({key:a(e)}),{chunks:c}=f(i??C,p);return{events:v(()=>{const l=a(e),u=(s.value??y).flatMap(n=>_(n)??[]);for(const n of c.value)n.kind==="progress"&&n.threadKey===l&&u.push({data:n.data,toolCallId:n.toolCallId,type:"progress"});return u})}};export{M as useAgentToolEvents};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ref as y,onScopeDispose as N,toValue as O}from"vue";import{useLunora as P}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const M="/_lunora/ws",H="/_lunora/voice/",$=4001,I=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,B=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},K=(e,r)=>{if(r===void 0||r==="")return I(e);if(r.endsWith(M))return r.slice(0,-M.length);try{return new URL(r).origin}catch{return I(e)}},q=e=>{const r=K(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${H}${encodeURIComponent(e.agent)}?${i.toString()}`},J=(e,r)=>{if(r?.code===$)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},G=(e,r,s)=>{const i=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==i&&s(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},X=16e3,j=e=>{if(e.length===0)return 0;let r=0;for(const s of e)r+=s*s;return Math.sqrt(r/e.length)},z=(e,r)=>{const s=r/X,i=s>1?Math.floor(e.length/s):e.length,g=new ArrayBuffer(i*2),p=new DataView(g);for(let l=0;l<i;l+=1){const k=e[Math.floor(l*s)]??0,v=Math.max(-1,Math.min(1,k));p.setInt16(l*2,v<0?v*32768:v*32767,!0)}return new Uint8Array(g)},Q=async e=>{const r=globalThis,s=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),i=r.AudioContext??r.webkitAudioContext;if(!s||!i)throw new Error("useVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const g=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),p=new i,l=p.createMediaStreamSource(g),k=p.createScriptProcessor(4096,1,1);let v=!1,w=!1,c=0,o=0;return k.onaudioprocess=u=>{const d=u.inputBuffer.getChannelData(0),h=v?0:j(d);if(e.onLevel(h),v)return;if(e.onAudio(z(d,p.sampleRate)),e.isTurnActive()){o=h>=e.interruptThreshold?o+1:0,o>=e.interruptChunks&&(o=0,e.onInterrupt());return}o=0;const S=d.length/p.sampleRate*1e3;if(h>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=S,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},l.connect(k),k.connect(p.destination),{setMuted:u=>{v=u},stop:()=>{k.disconnect(),l.disconnect();for(const u of g.getTracks())u.stop();p.close()}}},Y=()=>{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,i=new Set;let g=0,p=Promise.resolve(),l=0;const k=async(c,o)=>{if(o!==l)return;let u;try{u=await s.decodeAudioData(c.buffer)}catch{return}if(o!==l)return;const d=s.createBufferSource();d.buffer=u,d.connect(s.destination);const h=Math.max(s.currentTime,g);d.start(h),g=h+u.duration,i.add(d),d.onended=()=>{i.delete(d)}},v=c=>{const o=Uint8Array.from(c),u=l;p=p.then(()=>k(o,u))},w=()=>{l+=1;for(const c of i)try{c.stop()}catch{}i.clear(),g=s.currentTime};return{enqueue:v,interrupt:w,stop:()=>{w(),s.close()}}},U=1,Z=.01,ee=1200,te=.15,ne=3,ae=e=>{const{createMicrophone:r=Q,createSpeaker:s=Y,createSocket:i,interruptChunks:g=ne,interruptThreshold:p=te,silenceDurationMs:l=ee,silenceThreshold:k=Z,threadKey:v,voice:w}=e,c=P(),o=y("idle"),u=y(!1),d=y(""),h=y(""),S=y(0),b=y(!1),m=y(void 0);let a,C=!1;const _=n=>{const t=a?.socket;return t?.readyState===U?(t.send(JSON.stringify(n)),!0):!1},T=()=>{const n=a;if(a=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{}}C=!1,u.value=!1,o.value="idle",S.value=0},R=T,D=n=>{const t=a;switch(n.type){case"assistant_delta":{t&&(t.speaking=!0),o.value="speaking",h.value+=n.text;break}case"assistant_discarded":{t&&(t.suppressAudio=!0),t?.speaker?.interrupt(),h.value="";break}case"assistant_done":{t&&(t.awaitingTurn=!1,t.speaking=!1),h.value=n.text,o.value="listening";break}case"error":{t&&(t.awaitingTurn=!1,t.speaking=!1),m.value=new Error(n.message),o.value="listening";break}case"interrupted":{t&&(t.awaitingTurn=!1,t.speaking=!1,t.suppressAudio=!1),t?.speaker?.interrupt(),o.value="listening";break}case"ready":{t&&(t.audioFormat=n.audioFormat,t.suppressAudio=!1),u.value=!0,o.value="listening";break}case"user_transcript":{t&&(t.suppressAudio=!1),d.value=n.text,h.value="",o.value="thinking";break}}},L=n=>{const t=a;!t||t.suppressAudio||(t.speaker??=s({audioFormat:t.audioFormat}),t.speaking=!0,o.value="speaking",t.speaker.enqueue(n))},V=async()=>{if(a||C)return;C=!0,m.value=void 0,d.value="",h.value="";let n;try{const t=q({agent:B(w.__lunoraRef),httpUrl:c.url,threadKey:O(v),wsUrl:c.wsUrl}),A=(i??(f=>{const E=c.getWebSocketImpl();if(!E)throw new Error("useVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new E(f)}))(t);A.binaryType="arraybuffer",n={audioFormat:"mp3",microphone:void 0,socket:A,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},a=n,n.unwatchIdentity=G(c,"useVoiceAgent",f=>{a===n&&(m.value=f,T())}),A.onmessage=f=>{if(typeof f.data=="string"){try{D(JSON.parse(f.data))}catch{}return}L(new Uint8Array(f.data))},A.onerror=()=>{m.value=new Error("useVoiceAgent: voice socket error")},A.onclose=f=>{if(a!==n)return;const E=J("useVoiceAgent",f);E&&(m.value=E),T()};const x=await r({interruptChunks:g,interruptThreshold:p,isTurnActive:()=>(a?.speaking??!1)||(a?.awaitingTurn??!1),onAudio:f=>{A.readyState===U&&A.send(f)},onInterrupt:()=>{_({type:"interrupt"}),a?.speaker?.interrupt(),a&&(a.awaitingTurn=!1,a.speaking=!1,a.suppressAudio=!0),o.value="listening"},onLevel:f=>{S.value=f},onSilence:()=>{_({type:"commit"}),a&&(a.awaitingTurn=!0),o.value="thinking"},silenceDurationMs:l,silenceThreshold:k});a===n?(n.microphone=x,b.value=!1,n.speaking||(o.value="listening")):x.stop()}catch(t){a===n&&(m.value=t instanceof Error?t:new Error(String(t)),T())}finally{C=!1}},F=()=>{const n=!b.value;return a?.microphone?.setMuted(n),b.value=n,n},W=n=>{_({text:n,type:"text"})&&(a&&(a.awaitingTurn=!0),o.value="thinking")};return N(T),{audioLevel:S,connected:u,endCall:R,error:m,interimTranscript:h,isMuted:b,sendText:W,startCall:V,status:o,toggleMute:F,transcript:d}};export{ae as useVoiceAgent};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/vue",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.274",
|
|
4
4
|
"description": "Vue adapter for Lunora — live composables, optimistic mutations, and reactive loaders",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"access": "public"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@lunora/client": "1.0.0-alpha.
|
|
57
|
+
"@lunora/client": "1.0.0-alpha.234",
|
|
58
58
|
"@lunora/errors": ">=1.0.0-alpha.51 <2.0.0-0",
|
|
59
|
-
"@lunora/ratelimit": "1.0.0-alpha.
|
|
59
|
+
"@lunora/ratelimit": "1.0.0-alpha.156",
|
|
60
60
|
"@lunora/wire": "1.0.0-alpha.1",
|
|
61
61
|
"@visulima/storage-client": "1.0.9"
|
|
62
62
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{reconcileOptimistic as A,maxSeq as w}from"@lunora/client";import{computed as c,ref as V,watch as $,toValue as a}from"vue";import{NO_MUTATION_REF as z}from"./useAgent-Bp5UEoEp.mjs";import{useMutation as m}from"./useMutation-D6PkaNaE.mjs";import{useStream as B}from"./useStream-COVzNdKq.mjs";import{useSubscription as E}from"./useSubscription-cTKyOIAv.mjs";const G={__lunoraRef:""},tt=R=>{const{api:u,cancel:v,limit:p,onError:h,send:k,sendArgs:x,stream:f,threadKey:n}=R,{data:I,error:M}=E(u.agents.agentMessages,()=>{const t=a(n);return p===void 0?{key:t}:{key:t,limit:p}},{onError:h}),{data:S,error:b}=E(u.agents.agentThread,()=>({key:a(n)}),{onError:h}),_=c(()=>M.value??b.value),K=f===void 0?"skip":()=>({key:a(n)}),{chunks:T}=B(f??G,K),j=m(k),q=m(v??z),O=m(u.agents.agentResolveApproval),o=V([]);let g=0;$(()=>a(n),()=>{o.value=[]});const l=c(()=>S.value),C=c(()=>l.value?.status),i=c(()=>I.value??[]),D=c(()=>{const t=i.value,r=A(o.value,t);if(r.length===0)return t;const e=w(t);return[...t,...r.map((s,d)=>({content:s.content,optimistic:!0,role:"user",seq:e+1+d}))]}),N=c(()=>{const t=a(n),r=i.value.filter(e=>e.role==="assistant").length;return T.value.filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=r).map(e=>e.text).join("")}),F=async(t,r)=>{const e=g;g+=1;const s=w(i.value);o.value=[...A(o.value,i.value),{content:t,id:e,maxDurableSeqAtSend:s}];try{await j.mutate({input:t,threadKey:a(n),...x,...r})}catch(d){throw o.value=o.value.filter(U=>U.id!==e),d}},y=async(t,r,e)=>{const s=l.value?.instanceId;if(s===void 0)throw new Error(`useAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await O.mutate({decision:t,instanceId:s,threadKey:a(n),toolCallId:r,...e===void 0?{}:{note:e}})};return{approve:async(t,r)=>y("approve",t,r),cancel:async()=>{const t=l.value?.instanceId;v===void 0||t===void 0||await q.mutate({instanceId:t,threadKey:a(n)})},error:_,messages:D,reject:async(t,r)=>y("reject",t,r),send:F,status:C,streamingText:N}};export{tt as useAgentChat};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{computed as v,toValue as e}from"vue";import{useStream as f}from"./useStream-COVzNdKq.mjs";import{useSubscription as C}from"./useSubscription-cTKyOIAv.mjs";const y={__lunoraRef:""},I=[],N=t=>{if(t.role==="assistant"&&t.toolCalls)return t.toolCalls.map(l=>({input:l.input,seq:t.seq,toolCallId:l.id,toolName:l.name,type:"call"}));if(t.role==="tool")return t.status==="awaiting_approval"?[{seq:t.seq,type:"awaiting-approval",...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]:[{output:t.content,seq:t.seq,type:"result",...t.status==="approved"||t.status==="rejected"?{status:t.status}:{},...t.toolCallId===void 0?{}:{toolCallId:t.toolCallId},...t.toolName===void 0?{}:{toolName:t.toolName}}]},h=t=>{const{api:l,limit:a,stream:u,threadKey:n}=t,d=()=>{const r=e(n);return a===void 0?{key:r}:{key:r,limit:a}},{data:p}=C(l.agents.agentMessages,d),s=u===void 0?"skip":()=>({key:e(n)}),{chunks:c}=f(u??y,s);return{events:v(()=>{const r=e(n),i=(p.value??I).flatMap(o=>N(o)??[]);for(const o of c.value)o.kind==="progress"&&o.threadKey===r&&i.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return i})}};export{h as useAgentToolEvents};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ref as y,onScopeDispose as N,toValue as O}from"vue";import{useLunora as P}from"./LUNORA_INJECTION_KEY-Bct9tKCj.mjs";const M="/_lunora/ws",H="/_lunora/voice/",$=4001,I=e=>e.startsWith("https://")?`wss://${e.slice(8)}`:e.startsWith("http://")?`ws://${e.slice(7)}`:e,B=e=>{const r=e.startsWith("agents:")?e.slice(7):e;return r.endsWith("Voice")?r.slice(0,-5):r},K=(e,r)=>{if(r===void 0||r==="")return I(e);if(r.endsWith(M))return r.slice(0,-M.length);try{return new URL(r).origin}catch{return I(e)}},q=e=>{const r=K(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${H}${encodeURIComponent(e.agent)}?${i.toString()}`},J=(e,r)=>{if(r?.code===$)return new Error(`${e}: authentication token expired — refresh the credential and start a new call`)},G=(e,r,s)=>{const i=e.currentIdentity();return e.onAuthTokenChange(()=>{e.currentIdentity()!==i&&s(new Error(`${r}: the signed-in identity changed during the call — the session was ended; start a new call`))})},X=16e3,j=e=>{if(e.length===0)return 0;let r=0;for(const s of e)r+=s*s;return Math.sqrt(r/e.length)},z=(e,r)=>{const s=r/X,i=s>1?Math.floor(e.length/s):e.length,g=new ArrayBuffer(i*2),p=new DataView(g);for(let l=0;l<i;l+=1){const k=e[Math.floor(l*s)]??0,v=Math.max(-1,Math.min(1,k));p.setInt16(l*2,v<0?v*32768:v*32767,!0)}return new Uint8Array(g)},Q=async e=>{const r=globalThis,s=r.navigator?.mediaDevices?.getUserMedia.bind(r.navigator.mediaDevices),i=r.AudioContext??r.webkitAudioContext;if(!s||!i)throw new Error("useVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const g=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),p=new i,l=p.createMediaStreamSource(g),k=p.createScriptProcessor(4096,1,1);let v=!1,w=!1,c=0,o=0;return k.onaudioprocess=u=>{const d=u.inputBuffer.getChannelData(0),f=v?0:j(d);if(e.onLevel(f),v)return;if(e.onAudio(z(d,p.sampleRate)),e.isTurnActive()){o=f>=e.interruptThreshold?o+1:0,o>=e.interruptChunks&&(o=0,e.onInterrupt());return}o=0;const S=d.length/p.sampleRate*1e3;if(f>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=S,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},l.connect(k),k.connect(p.destination),{setMuted:u=>{v=u},stop:()=>{k.disconnect(),l.disconnect();for(const u of g.getTracks())u.stop();p.close()}}},Y=()=>{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,i=new Set;let g=0,p=Promise.resolve(),l=0;const k=async(c,o)=>{if(o!==l)return;let u;try{u=await s.decodeAudioData(c.buffer)}catch{return}if(o!==l)return;const d=s.createBufferSource();d.buffer=u,d.connect(s.destination);const f=Math.max(s.currentTime,g);d.start(f),g=f+u.duration,i.add(d),d.onended=()=>{i.delete(d)}},v=c=>{const o=Uint8Array.from(c),u=l;p=p.then(()=>k(o,u))},w=()=>{l+=1;for(const c of i)try{c.stop()}catch{}i.clear(),g=s.currentTime};return{enqueue:v,interrupt:w,stop:()=>{w(),s.close()}}},U=1,Z=.01,ee=1200,te=.15,ne=3,ae=e=>{const{createMicrophone:r=Q,createSpeaker:s=Y,createSocket:i,interruptChunks:g=ne,interruptThreshold:p=te,silenceDurationMs:l=ee,silenceThreshold:k=Z,threadKey:v,voice:w}=e,c=P(),o=y("idle"),u=y(!1),d=y(""),f=y(""),S=y(0),C=y(!1),m=y(void 0);let a,b=!1;const _=t=>{const n=a?.socket;return n?.readyState===U?(n.send(JSON.stringify(t)),!0):!1},T=()=>{const t=a;if(a=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{}}b=!1,u.value=!1,o.value="idle",S.value=0},R=T,D=t=>{const n=a;switch(t.type){case"assistant_delta":{n&&(n.speaking=!0),o.value="speaking",f.value+=t.text;break}case"assistant_done":{n&&(n.awaitingTurn=!1,n.speaking=!1),f.value=t.text,o.value="listening";break}case"error":{n&&(n.awaitingTurn=!1,n.speaking=!1),m.value=new Error(t.message),o.value="listening";break}case"interrupted":{n&&(n.awaitingTurn=!1,n.speaking=!1,n.suppressAudio=!1),n?.speaker?.interrupt(),o.value="listening";break}case"ready":{n&&(n.audioFormat=t.audioFormat,n.suppressAudio=!1),u.value=!0,o.value="listening";break}case"user_transcript":{n&&(n.suppressAudio=!1),d.value=t.text,f.value="",o.value="thinking";break}}},L=t=>{const n=a;!n||n.suppressAudio||(n.speaker??=s({audioFormat:n.audioFormat}),n.speaking=!0,o.value="speaking",n.speaker.enqueue(t))},V=async()=>{if(a||b)return;b=!0,m.value=void 0,d.value="",f.value="";let t;try{const n=q({agent:B(w.__lunoraRef),httpUrl:c.url,threadKey:O(v),wsUrl:c.wsUrl}),A=(i??(h=>{const E=c.getWebSocketImpl();if(!E)throw new Error("useVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new E(h)}))(n);A.binaryType="arraybuffer",t={audioFormat:"mp3",microphone:void 0,socket:A,speaker:void 0,speaking:!1,awaitingTurn:!1,suppressAudio:!1,unwatchIdentity:void 0},a=t,t.unwatchIdentity=G(c,"useVoiceAgent",h=>{a===t&&(m.value=h,T())}),A.onmessage=h=>{if(typeof h.data=="string"){try{D(JSON.parse(h.data))}catch{}return}L(new Uint8Array(h.data))},A.onerror=()=>{m.value=new Error("useVoiceAgent: voice socket error")},A.onclose=h=>{if(a!==t)return;const E=J("useVoiceAgent",h);E&&(m.value=E),T()};const x=await r({interruptChunks:g,interruptThreshold:p,isTurnActive:()=>(a?.speaking??!1)||(a?.awaitingTurn??!1),onAudio:h=>{A.readyState===U&&A.send(h)},onInterrupt:()=>{_({type:"interrupt"}),a?.speaker?.interrupt(),a&&(a.awaitingTurn=!1,a.speaking=!1,a.suppressAudio=!0),o.value="listening"},onLevel:h=>{S.value=h},onSilence:()=>{_({type:"commit"}),a&&(a.awaitingTurn=!0),o.value="thinking"},silenceDurationMs:l,silenceThreshold:k});a===t?(t.microphone=x,C.value=!1,t.speaking||(o.value="listening")):x.stop()}catch(n){a===t&&(m.value=n instanceof Error?n:new Error(String(n)),T())}finally{b=!1}},F=()=>{const t=!C.value;return a?.microphone?.setMuted(t),C.value=t,t},W=t=>{_({text:t,type:"text"})&&(a&&(a.awaitingTurn=!0),o.value="thinking")};return N(T),{audioLevel:S,connected:u,endCall:R,error:m,interimTranscript:f,isMuted:C,sendText:W,startCall:V,status:o,toggleMute:F,transcript:d}};export{ae as useVoiceAgent};
|