@lunora/solid 1.0.0-alpha.242 → 1.0.0-alpha.243
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 +70 -12
- package/dist/index.d.ts +70 -12
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/createAgentChat-CS3PI19y.mjs +1 -0
- package/dist/packem_shared/createAgentToolEvents-Sjkq8qXp.mjs +1 -0
- package/dist/packem_shared/{createVoiceAgent-CEuW4ux5.mjs → createVoiceAgent-D42ylvG0.mjs} +1 -1
- package/package.json +3 -3
- package/dist/packem_shared/createAgentChat-jPhnwbdQ.mjs +0 -1
- package/dist/packem_shared/createAgentToolEvents-WUQRSY8o.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, LiveStreamSubscribeError, LiveTopicRef, LiveTopicOptions, MutationCallOptions, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
|
|
1
|
+
import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, LiveStreamSubscribeError, LiveTopicRef, LiveTopicOptions, MutationCallOptions, OnlineOnlyOption, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
|
|
2
2
|
export type { ArgsOf, FunctionReference, MutatorHandle, MutatorTransaction, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe } from '@lunora/client';
|
|
3
3
|
import { Context, Accessor } from 'solid-js';
|
|
4
4
|
import { AuthStatus } from '@lunora/client/auth';
|
|
@@ -190,8 +190,8 @@ interface AgentChatMessage {
|
|
|
190
190
|
optimistic?: boolean;
|
|
191
191
|
role: "assistant" | "system" | "tool" | "user";
|
|
192
192
|
seq: number;
|
|
193
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
194
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
193
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
194
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
195
195
|
toolCallId?: string;
|
|
196
196
|
toolCalls?: ReadonlyArray<{
|
|
197
197
|
id: string;
|
|
@@ -245,7 +245,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
245
245
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
246
246
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
247
247
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
248
|
-
decision: "approve" | "reject";
|
|
248
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
249
249
|
instanceId: string;
|
|
250
250
|
note?: string;
|
|
251
251
|
threadKey: string;
|
|
@@ -253,10 +253,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
253
253
|
}, {
|
|
254
254
|
resolved: boolean;
|
|
255
255
|
}>;
|
|
256
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
257
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
258
|
+
secret: string;
|
|
259
|
+
threadKey: string;
|
|
260
|
+
toolCallId: string;
|
|
261
|
+
}, {
|
|
262
|
+
resolved: boolean;
|
|
263
|
+
}>;
|
|
264
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
265
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
266
|
+
threadKey: string;
|
|
267
|
+
toolCallId: string;
|
|
268
|
+
}, {
|
|
269
|
+
resolved: boolean;
|
|
270
|
+
}>;
|
|
256
271
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
257
272
|
type AgentThreadReference = FunctionReference<"query", {
|
|
258
273
|
key: string;
|
|
259
274
|
}, Record<string, unknown> | undefined>;
|
|
275
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
276
|
+
interface AgentApprovalGrant {
|
|
277
|
+
createdAt: number;
|
|
278
|
+
toolName: string;
|
|
279
|
+
}
|
|
280
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
281
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
282
|
+
key: string;
|
|
283
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
284
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
285
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
286
|
+
threadKey: string;
|
|
287
|
+
toolName: string;
|
|
288
|
+
}, {
|
|
289
|
+
revoked: boolean;
|
|
290
|
+
}>;
|
|
260
291
|
/**
|
|
261
292
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
262
293
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -272,8 +303,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
272
303
|
*/
|
|
273
304
|
interface CreateAgentChatApi {
|
|
274
305
|
agents: {
|
|
306
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
307
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
275
308
|
agentMessages: AgentMessagesReference$1;
|
|
276
309
|
agentResolveApproval: AgentApprovalReference;
|
|
310
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
311
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
277
312
|
agentThread: AgentThreadReference;
|
|
278
313
|
};
|
|
279
314
|
}
|
|
@@ -290,7 +325,7 @@ interface CreateAgentChatOptions {
|
|
|
290
325
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
291
326
|
limit?: number;
|
|
292
327
|
/**
|
|
293
|
-
* Called when the live history or
|
|
328
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
294
329
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
295
330
|
* such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
|
|
296
331
|
*/
|
|
@@ -313,29 +348,47 @@ interface CreateAgentChatOptions {
|
|
|
313
348
|
threadKey: MaybeAccessor<string>;
|
|
314
349
|
}
|
|
315
350
|
interface CreateAgentChatResult {
|
|
351
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
352
|
+
approvalGrants: Accessor<ReadonlyArray<AgentApprovalGrant>>;
|
|
316
353
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
317
354
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
357
|
+
* later calls to it run without pausing. Undo with {@link CreateAgentChatResult.revokeGrant}.
|
|
358
|
+
*/
|
|
359
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
318
360
|
/**
|
|
319
361
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
320
362
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
321
363
|
*/
|
|
322
364
|
cancel: () => Promise<void>;
|
|
323
|
-
/**
|
|
365
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
366
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
367
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
324
368
|
error: Accessor<Error | undefined>;
|
|
325
369
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
326
370
|
messages: Accessor<ReadonlyArray<AgentChatMessage>>;
|
|
327
371
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
328
372
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
373
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
374
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
329
375
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
330
376
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
331
377
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
332
378
|
status: Accessor<AgentThreadStatus | undefined>;
|
|
333
379
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
334
380
|
streamingText: Accessor<string>;
|
|
381
|
+
/**
|
|
382
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
383
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
384
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The primitive keeps no copy;
|
|
385
|
+
* a failure rethrows the original error.
|
|
386
|
+
*/
|
|
387
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
335
388
|
}
|
|
336
389
|
/**
|
|
337
390
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
338
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey` —
|
|
391
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey` —
|
|
339
392
|
* the Solid counterpart to React's `useAgentChat`, re-expressed with signals.
|
|
340
393
|
*
|
|
341
394
|
* It composes the existing primitives rather than adding transport:
|
|
@@ -429,7 +482,7 @@ interface CreateAgentToolEventsOptions {
|
|
|
429
482
|
* Optional live event stream — the same app stream function `createAgentChat`
|
|
430
483
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
431
484
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
432
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
485
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
433
486
|
*/
|
|
434
487
|
stream?: AgentLiveStreamReference;
|
|
435
488
|
/** The thread whose tool activity to observe — a plain value or accessor (an accessor re-subscribes on change). */
|
|
@@ -437,7 +490,7 @@ interface CreateAgentToolEventsOptions {
|
|
|
437
490
|
}
|
|
438
491
|
/**
|
|
439
492
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
440
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
493
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
441
494
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
442
495
|
* stream and has no `seq`. Discriminate on `type`.
|
|
443
496
|
*/
|
|
@@ -463,6 +516,11 @@ type AgentToolEvent = {
|
|
|
463
516
|
toolCallId?: string;
|
|
464
517
|
toolName?: string;
|
|
465
518
|
type: "awaiting-approval";
|
|
519
|
+
} | {
|
|
520
|
+
seq: number;
|
|
521
|
+
toolCallId?: string;
|
|
522
|
+
toolName?: string;
|
|
523
|
+
type: "awaiting-secret";
|
|
466
524
|
};
|
|
467
525
|
interface CreateAgentToolEventsResult {
|
|
468
526
|
/**
|
|
@@ -643,7 +701,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
643
701
|
/** The latest invocation's error, or `undefined`. */
|
|
644
702
|
error: Accessor<Error | undefined>;
|
|
645
703
|
/** Invoke the mutation. Resolves with the server result; rejects on failure. */
|
|
646
|
-
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
704
|
+
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
647
705
|
/** `true` while any invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
|
|
648
706
|
pending: Accessor<boolean>;
|
|
649
707
|
/** Clear `data`/`error` back to idle. */
|
|
@@ -655,7 +713,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
655
713
|
* in tests without constructing a full `LunoraClient`.
|
|
656
714
|
*/
|
|
657
715
|
interface MutationClient<F extends FunctionReference> {
|
|
658
|
-
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
716
|
+
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
659
717
|
}
|
|
660
718
|
/**
|
|
661
719
|
* Build a mutation handle bound to an explicit client. Internal seam used by the
|
|
@@ -1213,7 +1271,7 @@ interface LunoraProviderProps {
|
|
|
1213
1271
|
* itself is resolved per-major by {@link providerOf}.
|
|
1214
1272
|
*/
|
|
1215
1273
|
declare const LunoraProvider: (props: LunoraProviderProps) => SolidElement;
|
|
1216
|
-
export { type ActionClient, type ActionHandle, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type CreateAgentApi, type CreateAgentChatApi, type CreateAgentChatOptions, type CreateAgentChatResult, type CreateAgentOptions, type CreateAgentResult, type CreateAgentStateApi, type CreateAgentStateOptions, type CreateAgentStateResult, type CreateAgentToolEventsApi, type CreateAgentToolEventsOptions, type CreateAgentToolEventsResult, type CreateInfiniteQueryOptions, type CreateInfiniteQueryResult, type CreateLiveTopicResult, type CreatePaginatedQueryOptions, type CreatePaginatedQueryResult, type CreatePresenceOptions, type CreatePresenceResult, type CreateQueryOptions, type CreateRateLimitOptions, type CreateRateLimitResult, type CreateStreamOptions, type CreateStreamResult, type CreateStreamStatus, type CreateSubscriptionResult, type CreateVoiceAgentOptions, type CreateVoiceAgentResult, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraContext, LunoraProvider,
|
|
1274
|
+
export { type ActionClient, type ActionHandle, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type CreateAgentApi, type CreateAgentChatApi, type CreateAgentChatOptions, type CreateAgentChatResult, type CreateAgentOptions, type CreateAgentResult, type CreateAgentStateApi, type CreateAgentStateOptions, type CreateAgentStateResult, type CreateAgentToolEventsApi, type CreateAgentToolEventsOptions, type CreateAgentToolEventsResult, type CreateInfiniteQueryOptions, type CreateInfiniteQueryResult, type CreateLiveTopicResult, type CreatePaginatedQueryOptions, type CreatePaginatedQueryResult, type CreatePresenceOptions, type CreatePresenceResult, type CreateQueryOptions, type CreateRateLimitOptions, type CreateRateLimitResult, type CreateStreamOptions, type CreateStreamResult, type CreateStreamStatus, type CreateSubscriptionResult, type CreateVoiceAgentOptions, type CreateVoiceAgentResult, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraContext, LunoraProvider,
|
|
1217
1275
|
/**
|
|
1218
1276
|
* SolidJS adapter for Lunora.
|
|
1219
1277
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, LiveStreamSubscribeError, LiveTopicRef, LiveTopicOptions, MutationCallOptions, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
|
|
1
|
+
import { LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, SubscriptionErrorCallback, User, ConnectionStatus, LiveStreamSubscribeError, LiveTopicRef, LiveTopicOptions, MutationCallOptions, OnlineOnlyOption, MutatorHandle, SubscriptionError, Preloaded } from '@lunora/client';
|
|
2
2
|
export type { ArgsOf, FunctionReference, MutatorHandle, MutatorTransaction, OptimisticUpdate, Preloaded, ReturnOf, SubscriptionError, SubscriptionErrorCallback, Unsubscribe } from '@lunora/client';
|
|
3
3
|
import { Context, Accessor } from 'solid-js';
|
|
4
4
|
import { AuthStatus } from '@lunora/client/auth';
|
|
@@ -190,8 +190,8 @@ interface AgentChatMessage {
|
|
|
190
190
|
optimistic?: boolean;
|
|
191
191
|
role: "assistant" | "system" | "tool" | "user";
|
|
192
192
|
seq: number;
|
|
193
|
-
/** Approval lifecycle marker on a human-in-the-loop tool message. */
|
|
194
|
-
status?: "approved" | "awaiting_approval" | "rejected";
|
|
193
|
+
/** Approval or secret-request lifecycle marker on a human-in-the-loop tool message. */
|
|
194
|
+
status?: "approved" | "awaiting_approval" | "awaiting_secret" | "rejected";
|
|
195
195
|
toolCallId?: string;
|
|
196
196
|
toolCalls?: ReadonlyArray<{
|
|
197
197
|
id: string;
|
|
@@ -245,7 +245,7 @@ type AgentMessagesReference$1 = FunctionReference<"query", {
|
|
|
245
245
|
}, ReadonlyArray<Record<string, unknown>>>;
|
|
246
246
|
/** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
|
|
247
247
|
type AgentApprovalReference = FunctionReference<"mutation", {
|
|
248
|
-
decision: "approve" | "reject";
|
|
248
|
+
decision: "approve" | "approve_for_thread" | "reject";
|
|
249
249
|
instanceId: string;
|
|
250
250
|
note?: string;
|
|
251
251
|
threadKey: string;
|
|
@@ -253,10 +253,41 @@ type AgentApprovalReference = FunctionReference<"mutation", {
|
|
|
253
253
|
}, {
|
|
254
254
|
resolved: boolean;
|
|
255
255
|
}>;
|
|
256
|
+
/** The `agents:agentSupplySecret` reference — stores a person's value for a paused `requestSecretTool` call. */
|
|
257
|
+
type AgentSupplySecretReference = FunctionReference<"mutation", {
|
|
258
|
+
secret: string;
|
|
259
|
+
threadKey: string;
|
|
260
|
+
toolCallId: string;
|
|
261
|
+
}, {
|
|
262
|
+
resolved: boolean;
|
|
263
|
+
}>;
|
|
264
|
+
/** The `agents:agentDeclineSecret` reference — refuses a paused `requestSecretTool` call. */
|
|
265
|
+
type AgentDeclineSecretReference = FunctionReference<"mutation", {
|
|
266
|
+
threadKey: string;
|
|
267
|
+
toolCallId: string;
|
|
268
|
+
}, {
|
|
269
|
+
resolved: boolean;
|
|
270
|
+
}>;
|
|
256
271
|
/** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
|
|
257
272
|
type AgentThreadReference = FunctionReference<"query", {
|
|
258
273
|
key: string;
|
|
259
274
|
}, Record<string, unknown> | undefined>;
|
|
275
|
+
/** A tool approved for the rest of a thread, as `agents:agentApprovalGrants` lists it. */
|
|
276
|
+
interface AgentApprovalGrant {
|
|
277
|
+
createdAt: number;
|
|
278
|
+
toolName: string;
|
|
279
|
+
}
|
|
280
|
+
/** The `agents:agentApprovalGrants` reference — live thread-scoped approval grants. */
|
|
281
|
+
type AgentApprovalGrantsReference = FunctionReference<"query", {
|
|
282
|
+
key: string;
|
|
283
|
+
}, ReadonlyArray<AgentApprovalGrant>>;
|
|
284
|
+
/** The `agents:agentRevokeApprovalGrant` reference — removes a thread-scoped approval grant. */
|
|
285
|
+
type AgentRevokeApprovalGrantReference = FunctionReference<"mutation", {
|
|
286
|
+
threadKey: string;
|
|
287
|
+
toolName: string;
|
|
288
|
+
}, {
|
|
289
|
+
revoked: boolean;
|
|
290
|
+
}>;
|
|
260
291
|
/**
|
|
261
292
|
* An app stream reference that tees the agent's in-flight live events, keyed by
|
|
262
293
|
* thread. Carries token deltas and — since `ctx.reportProgress` rides the same
|
|
@@ -272,8 +303,12 @@ type AgentTokenStreamReference = FunctionReference<"stream", {
|
|
|
272
303
|
*/
|
|
273
304
|
interface CreateAgentChatApi {
|
|
274
305
|
agents: {
|
|
306
|
+
agentApprovalGrants: AgentApprovalGrantsReference;
|
|
307
|
+
agentDeclineSecret: AgentDeclineSecretReference;
|
|
275
308
|
agentMessages: AgentMessagesReference$1;
|
|
276
309
|
agentResolveApproval: AgentApprovalReference;
|
|
310
|
+
agentRevokeApprovalGrant: AgentRevokeApprovalGrantReference;
|
|
311
|
+
agentSupplySecret: AgentSupplySecretReference;
|
|
277
312
|
agentThread: AgentThreadReference;
|
|
278
313
|
};
|
|
279
314
|
}
|
|
@@ -290,7 +325,7 @@ interface CreateAgentChatOptions {
|
|
|
290
325
|
/** History depth forwarded to `agents:agentMessages`. */
|
|
291
326
|
limit?: number;
|
|
292
327
|
/**
|
|
293
|
-
* Called when the live history or
|
|
328
|
+
* Called when the live history, thread, or grants subscription reports an error (a
|
|
294
329
|
* session expiry, an RLS denial). Without it — and without reading `error` —
|
|
295
330
|
* such a failure is invisible and `messages` / `status` are cleared until a later frame arrives.
|
|
296
331
|
*/
|
|
@@ -313,29 +348,47 @@ interface CreateAgentChatOptions {
|
|
|
313
348
|
threadKey: MaybeAccessor<string>;
|
|
314
349
|
}
|
|
315
350
|
interface CreateAgentChatResult {
|
|
351
|
+
/** The tools approved for the rest of this thread, live. Empty until the grants subscription answers. */
|
|
352
|
+
approvalGrants: Accessor<ReadonlyArray<AgentApprovalGrant>>;
|
|
316
353
|
/** Approve a paused human-in-the-loop tool call (optionally with a note). */
|
|
317
354
|
approve: (toolCallId: string, note?: string) => Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* Approve a paused tool call and grant that tool for the rest of the thread, so
|
|
357
|
+
* later calls to it run without pausing. Undo with {@link CreateAgentChatResult.revokeGrant}.
|
|
358
|
+
*/
|
|
359
|
+
approveForThread: (toolCallId: string, note?: string) => Promise<void>;
|
|
318
360
|
/**
|
|
319
361
|
* Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
|
|
320
362
|
* no-op when no `cancel` mutation was supplied or no run is in flight.
|
|
321
363
|
*/
|
|
322
364
|
cancel: () => Promise<void>;
|
|
323
|
-
/**
|
|
365
|
+
/** Refuse a paused `requestSecretTool` call: the run resumes with a "declined" result. */
|
|
366
|
+
declineSecret: (toolCallId: string) => Promise<void>;
|
|
367
|
+
/** The history, thread, or grants subscription's last error, or `undefined`. */
|
|
324
368
|
error: Accessor<Error | undefined>;
|
|
325
369
|
/** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
|
|
326
370
|
messages: Accessor<ReadonlyArray<AgentChatMessage>>;
|
|
327
371
|
/** Reject a paused human-in-the-loop tool call (optionally with a reason). */
|
|
328
372
|
reject: (toolCallId: string, note?: string) => Promise<void>;
|
|
373
|
+
/** Remove a thread-scoped approval grant so the tool's gate applies again to later calls. */
|
|
374
|
+
revokeGrant: (toolName: string) => Promise<void>;
|
|
329
375
|
/** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
|
|
330
376
|
send: (input: string, args?: Record<string, unknown>) => Promise<void>;
|
|
331
377
|
/** The live thread status, or `undefined` before the thread exists. */
|
|
332
378
|
status: Accessor<AgentThreadStatus | undefined>;
|
|
333
379
|
/** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
|
|
334
380
|
streamingText: Accessor<string>;
|
|
381
|
+
/**
|
|
382
|
+
* Give a paused `requestSecretTool` call its value. Always sent online-only: the
|
|
383
|
+
* value is never queued, persisted or replayed, and the call rejects with
|
|
384
|
+
* `OFFLINE_NOT_QUEUED` while the connection is down. The primitive keeps no copy;
|
|
385
|
+
* a failure rethrows the original error.
|
|
386
|
+
*/
|
|
387
|
+
supplySecret: (toolCallId: string, secret: string) => Promise<void>;
|
|
335
388
|
}
|
|
336
389
|
/**
|
|
337
390
|
* A first-class agent chat surface: live durable history + in-flight token
|
|
338
|
-
* streaming + the send / approve / reject / cancel writes, keyed by `threadKey` —
|
|
391
|
+
* streaming + the send / approve / reject / secret / cancel writes, keyed by `threadKey` —
|
|
339
392
|
* the Solid counterpart to React's `useAgentChat`, re-expressed with signals.
|
|
340
393
|
*
|
|
341
394
|
* It composes the existing primitives rather than adding transport:
|
|
@@ -429,7 +482,7 @@ interface CreateAgentToolEventsOptions {
|
|
|
429
482
|
* Optional live event stream — the same app stream function `createAgentChat`
|
|
430
483
|
* uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
|
|
431
484
|
* thread are surfaced as `{ type: "progress" }` entries; when omitted only the
|
|
432
|
-
* durable lifecycle (call / result / awaiting-approval) is returned.
|
|
485
|
+
* durable lifecycle (call / result / awaiting-approval / awaiting-secret) is returned.
|
|
433
486
|
*/
|
|
434
487
|
stream?: AgentLiveStreamReference;
|
|
435
488
|
/** The thread whose tool activity to observe — a plain value or accessor (an accessor re-subscribes on change). */
|
|
@@ -437,7 +490,7 @@ interface CreateAgentToolEventsOptions {
|
|
|
437
490
|
}
|
|
438
491
|
/**
|
|
439
492
|
* A single tool-lifecycle event for a thread. The durable arms
|
|
440
|
-
* (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
|
|
493
|
+
* (`call`/`result`/`awaiting-approval`/`awaiting-secret`) are derived from `agents:agentMessages`
|
|
441
494
|
* and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
|
|
442
495
|
* stream and has no `seq`. Discriminate on `type`.
|
|
443
496
|
*/
|
|
@@ -463,6 +516,11 @@ type AgentToolEvent = {
|
|
|
463
516
|
toolCallId?: string;
|
|
464
517
|
toolName?: string;
|
|
465
518
|
type: "awaiting-approval";
|
|
519
|
+
} | {
|
|
520
|
+
seq: number;
|
|
521
|
+
toolCallId?: string;
|
|
522
|
+
toolName?: string;
|
|
523
|
+
type: "awaiting-secret";
|
|
466
524
|
};
|
|
467
525
|
interface CreateAgentToolEventsResult {
|
|
468
526
|
/**
|
|
@@ -643,7 +701,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
643
701
|
/** The latest invocation's error, or `undefined`. */
|
|
644
702
|
error: Accessor<Error | undefined>;
|
|
645
703
|
/** Invoke the mutation. Resolves with the server result; rejects on failure. */
|
|
646
|
-
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
704
|
+
mutate: (args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
647
705
|
/** `true` while any invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
|
|
648
706
|
pending: Accessor<boolean>;
|
|
649
707
|
/** Clear `data`/`error` back to idle. */
|
|
@@ -655,7 +713,7 @@ interface MutationHandle<F extends FunctionReference> {
|
|
|
655
713
|
* in tests without constructing a full `LunoraClient`.
|
|
656
714
|
*/
|
|
657
715
|
interface MutationClient<F extends FunctionReference> {
|
|
658
|
-
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>>) => Promise<ReturnOf<F>>;
|
|
716
|
+
mutation: (function_: F, args: ArgsOf<F>, options?: MutationCallOptions<unknown, unknown, ArgsOf<F>> & OnlineOnlyOption<F>) => Promise<ReturnOf<F>>;
|
|
659
717
|
}
|
|
660
718
|
/**
|
|
661
719
|
* Build a mutation handle bound to an explicit client. Internal seam used by the
|
|
@@ -1213,7 +1271,7 @@ interface LunoraProviderProps {
|
|
|
1213
1271
|
* itself is resolved per-major by {@link providerOf}.
|
|
1214
1272
|
*/
|
|
1215
1273
|
declare const LunoraProvider: (props: LunoraProviderProps) => SolidElement;
|
|
1216
|
-
export { type ActionClient, type ActionHandle, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type CreateAgentApi, type CreateAgentChatApi, type CreateAgentChatOptions, type CreateAgentChatResult, type CreateAgentOptions, type CreateAgentResult, type CreateAgentStateApi, type CreateAgentStateOptions, type CreateAgentStateResult, type CreateAgentToolEventsApi, type CreateAgentToolEventsOptions, type CreateAgentToolEventsResult, type CreateInfiniteQueryOptions, type CreateInfiniteQueryResult, type CreateLiveTopicResult, type CreatePaginatedQueryOptions, type CreatePaginatedQueryResult, type CreatePresenceOptions, type CreatePresenceResult, type CreateQueryOptions, type CreateRateLimitOptions, type CreateRateLimitResult, type CreateStreamOptions, type CreateStreamResult, type CreateStreamStatus, type CreateSubscriptionResult, type CreateVoiceAgentOptions, type CreateVoiceAgentResult, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraContext, LunoraProvider,
|
|
1274
|
+
export { type ActionClient, type ActionHandle, type AgentApprovalGrant, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type CreateAgentApi, type CreateAgentChatApi, type CreateAgentChatOptions, type CreateAgentChatResult, type CreateAgentOptions, type CreateAgentResult, type CreateAgentStateApi, type CreateAgentStateOptions, type CreateAgentStateResult, type CreateAgentToolEventsApi, type CreateAgentToolEventsOptions, type CreateAgentToolEventsResult, type CreateInfiniteQueryOptions, type CreateInfiniteQueryResult, type CreateLiveTopicResult, type CreatePaginatedQueryOptions, type CreatePaginatedQueryResult, type CreatePresenceOptions, type CreatePresenceResult, type CreateQueryOptions, type CreateRateLimitOptions, type CreateRateLimitResult, type CreateStreamOptions, type CreateStreamResult, type CreateStreamStatus, type CreateSubscriptionResult, type CreateVoiceAgentOptions, type CreateVoiceAgentResult, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraContext, LunoraProvider,
|
|
1217
1275
|
/**
|
|
1218
1276
|
* SolidJS adapter for Lunora.
|
|
1219
1277
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraContext as r,useLunora as o}from"./packem_shared/LunoraContext-BWsj_3CK.mjs";import{createAction as c,createActionForClient as n}from"./packem_shared/createAction-BZkayM2R.mjs";import{createAgent as m}from"./packem_shared/createAgent-CWckPY7u.mjs";import{createAgentChat as x}from"./packem_shared/createAgentChat-
|
|
1
|
+
import{LunoraContext as r,useLunora as o}from"./packem_shared/LunoraContext-BWsj_3CK.mjs";import{createAction as c,createActionForClient as n}from"./packem_shared/createAction-BZkayM2R.mjs";import{createAgent as m}from"./packem_shared/createAgent-CWckPY7u.mjs";import{createAgentChat as x}from"./packem_shared/createAgentChat-CS3PI19y.mjs";import{createAgentState as u}from"./packem_shared/createAgentState-BPo1e_ih.mjs";import{createAgentToolEvents as A}from"./packem_shared/createAgentToolEvents-Sjkq8qXp.mjs";import{AuthLoading as l,Authenticated as s,Unauthenticated as h,createAuth as L}from"./packem_shared/AuthLoading-DjUnIaP5.mjs";import{default as y}from"./packem_shared/createConnectionStatus-D8bC05Jn.mjs";import{createFlag as P,createFlags as S}from"./packem_shared/createFlag-BwBkDAcT.mjs";import{createLiveTopic as M}from"./packem_shared/createLiveTopic-CgkjI8l8.mjs";import{createMutation as T,createMutationForClient as b}from"./packem_shared/createMutation-DM2mXpq3.mjs";import{createMutator as I}from"./packem_shared/createMutator-q9cMjGKv.mjs";import{createInfiniteQuery as U,createPaginatedQuery as V}from"./packem_shared/createInfiniteQuery-CwGPFeuc.mjs";import{createPresence as k}from"./packem_shared/createPresence-DkTotieP.mjs";import{createQuery as w}from"./packem_shared/createQuery-oNQqVGjE.mjs";import{createRateLimit as B}from"./packem_shared/createRateLimit-CIVWrD5H.mjs";import{createStream as G}from"./packem_shared/createStream-CCAOb9q1.mjs";import{createSubscription as J}from"./packem_shared/createSubscription-CF_00S2O.mjs";import{createVoiceAgent as N}from"./packem_shared/createVoiceAgent-D42ylvG0.mjs";import{default as W}from"./packem_shared/hydratePreloaded-DCi296oW.mjs";import{LunoraProvider as Y}from"./packem_shared/LunoraProvider-DMhpuxvx.mjs";export{l as AuthLoading,s as Authenticated,r as LunoraContext,Y as LunoraProvider,h as Unauthenticated,c as createAction,n as createActionForClient,m as createAgent,x as createAgentChat,u as createAgentState,A as createAgentToolEvents,L as createAuth,y as createConnectionStatus,P as createFlag,S as createFlags,U as createInfiniteQuery,M as createLiveTopic,T as createMutation,b as createMutationForClient,I as createMutator,V as createPaginatedQuery,k as createPresence,w as createQuery,B as createRateLimit,G as createStream,J as createSubscription,N as createVoiceAgent,W as hydratePreloaded,o as useLunora};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{reconcileOptimistic as M,maxSeq as A}from"@lunora/client";import{createMemo as c,createSignal as J}from"solid-js";import{resolveMaybe as a,NO_MUTATION_REF as L}from"./createAgent-CWckPY7u.mjs";import{createMutation as i}from"./createMutation-DM2mXpq3.mjs";import{createStream as Q}from"./createStream-CCAOb9q1.mjs";import{createSubscription as g}from"./createSubscription-CF_00S2O.mjs";import{t as V}from"./solid-compat-ByG5HD_F.mjs";const W={__lunoraRef:""},X=[],mt=E=>{const{api:o,cancel:h,limit:v,onError:l,send:w,sendArgs:R,stream:f,threadKey:n}=E,{data:T,error:_}=g(o.agents.agentMessages,()=>{const t=a(n);return v===void 0?{key:t}:{key:t,limit:v}},{onError:l}),{data:K,error:b}=g(o.agents.agentThread,()=>({key:a(n)}),{onError:l}),{data:x,error:I}=g(o.agents.agentApprovalGrants,()=>({key:a(n)}),{onError:l}),G=c(()=>_()??b()??I()),O=f===void 0?"skip":()=>({key:a(n)}),{chunks:D}=Q(f??W,O),j=i(w),q=i(h??L),F=i(o.agents.agentResolveApproval),N=i(o.agents.agentRevokeApprovalGrant),C=i(o.agents.agentSupplySecret),P=i(o.agents.agentDeclineSecret),[S,u]=J([]);let k=0;V(()=>a(n),()=>{S().length>0&&u([])});const m=c(()=>K()),U=c(()=>m()?.status),d=c(()=>T()??[]),Y=c(()=>{const t=d(),e=M(S(),t);if(e.length===0)return t;const r=A(t);return[...t,...e.map((s,p)=>({content:s.content,optimistic:!0,role:"user",seq:r+1+p}))]}),$=c(()=>{const t=a(n),e=d().filter(r=>r.role==="assistant").length;return D().filter(r=>r.kind!=="progress"&&r.threadKey===t&&r.turn>=e).map(r=>r.text).join("")}),z=async(t,e)=>{const r=k;k+=1;const s=A(d());u(p=>[...M(p,d()),{content:t,id:r,maxDurableSeqAtSend:s}]);try{await j.mutate({input:t,threadKey:a(n),...R,...e})}catch(p){throw u(B=>B.filter(H=>H.id!==r)),p}},y=async(t,e,r)=>{const s=m()?.instanceId;if(s===void 0)throw new Error(`createAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await F.mutate({decision:t,instanceId:s,threadKey:a(n),toolCallId:e,...r===void 0?{}:{note:r}})};return{approvalGrants:()=>x()??X,approve:async(t,e)=>y("approve",t,e),approveForThread:async(t,e)=>y("approve_for_thread",t,e),cancel:async()=>{const t=m()?.instanceId;h===void 0||t===void 0||await q.mutate({instanceId:t,threadKey:a(n)})},declineSecret:async t=>{await P.mutate({threadKey:a(n),toolCallId:t})},error:G,messages:Y,reject:async(t,e)=>y("reject",t,e),revokeGrant:async t=>{await N.mutate({threadKey:a(n),toolName:t})},send:z,status:U,streamingText:$,supplySecret:async(t,e)=>{await C.mutate({secret:e,threadKey:a(n),toolCallId:t},{onlineOnly:!0})}}};export{mt as createAgentChat};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createMemo as v}from"solid-js";import{resolveMaybe as a}from"./createAgent-CWckPY7u.mjs";import{createStream as f}from"./createStream-CCAOb9q1.mjs";import{createSubscription as E}from"./createSubscription-CF_00S2O.mjs";const y={__lunoraRef:""},C=[],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}}]},b=t=>{const{api:o,limit:r,stream:i,threadKey:l}=t,u=()=>{const n=a(l);return r===void 0?{key:n}:{key:n,limit:r}},{data:s}=E(o.agents.agentMessages,u),c=i===void 0?"skip":()=>({key:a(l)}),{chunks:p}=f(i??y,c);return{events:v(()=>{const n=a(l),d=(s()??C).flatMap(e=>_(e)??[]);for(const e of p())e.kind==="progress"&&e.threadKey===n&&d.push({data:e.data,toolCallId:e.toolCallId,type:"progress"});return d})}};export{b as createAgentToolEvents};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createSignal as y,onCleanup as J}from"solid-js";import{useLunora as G}from"./LunoraContext-BWsj_3CK.mjs";import{resolveMaybe as X}from"./createAgent-CWckPY7u.mjs";const D="/_lunora/ws",j="/_lunora/voice/",z=4001,F=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 F(e);if(r.endsWith(D))return r.slice(0,-D.length);try{return new URL(r).origin}catch{return F(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${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,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`))})},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)},oe=(e,r)=>{const s=r/ne,i=s>1?Math.floor(e.length/s):e.length,f=new ArrayBuffer(i*2),l=new DataView(f);for(let u=0;u<i;u+=1){const k=e[Math.floor(u*s)]??0,g=Math.max(-1,Math.min(1,k));l.setInt16(u*2,g<0?g*32768:g*32767,!0)}return new Uint8Array(f)},se=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("createVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const f=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new i,u=l.createMediaStreamSource(f),k=l.createScriptProcessor(4096,1,1);let g=!1,w=!1,c=0,p=0;return k.onaudioprocess=o=>{const h=o.inputBuffer.getChannelData(0),m=g?0:re(h);if(e.onLevel(m),g)return;if(e.onAudio(oe(h,l.sampleRate)),e.isTurnActive()){p=m>=e.interruptThreshold?p+1:0,p>=e.interruptChunks&&(p=0,e.onInterrupt());return}p=0;const b=h.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=b,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},u.connect(k),k.connect(l.destination),{setMuted:o=>{g=o},stop:()=>{k.disconnect(),u.disconnect();for(const o of f.getTracks())o.stop();l.close()}}},ae=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("createVoiceAgent: audio playback requires AudioContext (no browser audio available)");const s=new r,i=new Set;let f=0,l=Promise.resolve(),u=0;const k=async(c,p)=>{if(p!==u)return;let o;try{o=await s.decodeAudioData(c.buffer)}catch{return}if(p!==u)return;const h=s.createBufferSource();h.buffer=o,h.connect(s.destination);const m=Math.max(s.currentTime,f);h.start(m),f=m+o.duration,i.add(h),h.onended=()=>{i.delete(h)}},g=c=>{const p=Uint8Array.from(c),o=u;l=l.then(()=>k(p,o))},w=()=>{u+=1;for(const c of i)try{c.stop()}catch{}i.clear(),f=s.currentTime};return{enqueue:g,interrupt:w,stop:()=>{w(),s.close()}}},V=1,ie=.01,ce=1200,ue=.15,le=3,fe=e=>{const{createMicrophone:r=se,createSpeaker:s=ae,createSocket:i,interruptChunks:f=le,interruptThreshold:l=ue,silenceDurationMs:u=ce,silenceThreshold:k=ie,threadKey:g,voice:w}=e,c=G(),[p,o]=y("idle"),[h,m]=y(!1),[b,M]=y(""),[W,
|
|
1
|
+
import{createSignal as y,onCleanup as J}from"solid-js";import{useLunora as G}from"./LunoraContext-BWsj_3CK.mjs";import{resolveMaybe as X}from"./createAgent-CWckPY7u.mjs";const D="/_lunora/ws",j="/_lunora/voice/",z=4001,F=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 F(e);if(r.endsWith(D))return r.slice(0,-D.length);try{return new URL(r).origin}catch{return F(e)}},Z=e=>{const r=Y(e.httpUrl,e.wsUrl),s=r.endsWith("/")?r.slice(0,-1):r,i=new URLSearchParams({threadKey:e.threadKey});return`${s}${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,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`))})},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)},oe=(e,r)=>{const s=r/ne,i=s>1?Math.floor(e.length/s):e.length,f=new ArrayBuffer(i*2),l=new DataView(f);for(let u=0;u<i;u+=1){const k=e[Math.floor(u*s)]??0,g=Math.max(-1,Math.min(1,k));l.setInt16(u*2,g<0?g*32768:g*32767,!0)}return new Uint8Array(f)},se=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("createVoiceAgent: microphone capture requires getUserMedia + AudioContext (no browser audio available)");const f=await s({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0}}),l=new i,u=l.createMediaStreamSource(f),k=l.createScriptProcessor(4096,1,1);let g=!1,w=!1,c=0,p=0;return k.onaudioprocess=o=>{const h=o.inputBuffer.getChannelData(0),m=g?0:re(h);if(e.onLevel(m),g)return;if(e.onAudio(oe(h,l.sampleRate)),e.isTurnActive()){p=m>=e.interruptThreshold?p+1:0,p>=e.interruptChunks&&(p=0,e.onInterrupt());return}p=0;const b=h.length/l.sampleRate*1e3;if(m>=e.silenceThreshold){w=!0,c=0;return}w&&(c+=b,c>=e.silenceDurationMs&&(w=!1,c=0,e.onSilence()))},u.connect(k),k.connect(l.destination),{setMuted:o=>{g=o},stop:()=>{k.disconnect(),u.disconnect();for(const o of f.getTracks())o.stop();l.close()}}},ae=()=>{const e=globalThis,r=e.AudioContext??e.webkitAudioContext;if(!r)throw new Error("createVoiceAgent: audio playback requires AudioContext (no browser audio available)");const s=new r,i=new Set;let f=0,l=Promise.resolve(),u=0;const k=async(c,p)=>{if(p!==u)return;let o;try{o=await s.decodeAudioData(c.buffer)}catch{return}if(p!==u)return;const h=s.createBufferSource();h.buffer=o,h.connect(s.destination);const m=Math.max(s.currentTime,f);h.start(m),f=m+o.duration,i.add(h),h.onended=()=>{i.delete(h)}},g=c=>{const p=Uint8Array.from(c),o=u;l=l.then(()=>k(p,o))},w=()=>{u+=1;for(const c of i)try{c.stop()}catch{}i.clear(),f=s.currentTime};return{enqueue:g,interrupt:w,stop:()=>{w(),s.close()}}},V=1,ie=.01,ce=1200,ue=.15,le=3,fe=e=>{const{createMicrophone:r=se,createSpeaker:s=ae,createSocket:i,interruptChunks:f=le,interruptThreshold:l=ue,silenceDurationMs:u=ce,silenceThreshold:k=ie,threadKey:g,voice:w}=e,c=G(),[p,o]=y("idle"),[h,m]=y(!1),[b,M]=y(""),[W,T]=y(""),[N,x]=y(0),[I,U]=y(!1),[O,S]=y(void 0);let a,C=!1;const _=n=>{const t=a?.socket;return t?.readyState===V?(t.send(JSON.stringify(n)),!0):!1},E=()=>{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,m(!1),o("idle"),x(0)},P=E,H=n=>{const t=a;switch(n.type){case"assistant_delta":{t&&(t.speaking=!0),o("speaking"),T(R=>R+n.text);break}case"assistant_discarded":{t&&(t.suppressAudio=!0),t?.speaker?.interrupt(),T("");break}case"assistant_done":{t&&(t.awaitingTurn=!1,t.speaking=!1),T(n.text),o("listening");break}case"error":{t&&(t.awaitingTurn=!1,t.speaking=!1),S(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),T(""),o("thinking");break}}},$=n=>{const t=a;!t||t.suppressAudio||(t.speaker??=s({audioFormat:t.audioFormat}),t.speaking=!0,o("speaking"),t.speaker.enqueue(n))},B=async()=>{if(a||C)return;C=!0,S(void 0),M(""),T("");let n;try{const t=Z({agent:Q(w.__lunoraRef),httpUrl:c.url,threadKey:X(g),wsUrl:c.wsUrl}),A=(i??(d=>{const v=c.getWebSocketImpl();if(!v)throw new Error("createVoiceAgent: no WebSocket implementation available (pass createSocket explicitly)");return new v(d)}))(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=te(c,"createVoiceAgent",d=>{a===n&&(S(d),E())}),A.onmessage=d=>{if(typeof d.data=="string"){try{H(JSON.parse(d.data))}catch{}return}$(new Uint8Array(d.data))},A.onerror=()=>{S(new Error("createVoiceAgent: voice socket error"))},A.onclose=d=>{if(a!==n)return;const v=ee("createVoiceAgent",d);v&&S(v),E()};const L=await r({interruptChunks:f,interruptThreshold:l,isTurnActive:()=>(a?.speaking??!1)||(a?.awaitingTurn??!1),onAudio:d=>{A.readyState===V&&A.send(d)},onInterrupt:()=>{_({type:"interrupt"}),a?.speaker?.interrupt(),a&&(a.awaitingTurn=!1,a.speaking=!1,a.suppressAudio=!0),o("listening")},onLevel:d=>{x(d)},onSilence:()=>{_({type:"commit"}),a&&(a.awaitingTurn=!0),o("thinking")},silenceDurationMs:u,silenceThreshold:k});a===n?(n.microphone=L,U(!1),n.speaking||o("listening")):L.stop()}catch(t){a===n&&(S(t instanceof Error?t:new Error(String(t))),E())}finally{C=!1}},K=()=>{const n=!I();return a?.microphone?.setMuted(n),U(n),n},q=n=>{_({text:n,type:"text"})&&(a&&(a.awaitingTurn=!0),o("thinking"))};return J(E),{audioLevel:N,connected:h,endCall:P,error:O,interimTranscript:W,isMuted:I,sendText:q,startCall:B,status:p,toggleMute:K,transcript:b}};export{fe as createVoiceAgent};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/solid",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.243",
|
|
4
4
|
"description": "SolidJS adapter for Lunora — live queries, 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 E,maxSeq as M}from"@lunora/client";import{createMemo as s,createSignal as B}from"solid-js";import{resolveMaybe as o,NO_MUTATION_REF as G}from"./createAgent-CWckPY7u.mjs";import{createMutation as u}from"./createMutation-DM2mXpq3.mjs";import{createStream as H}from"./createStream-CCAOb9q1.mjs";import{createSubscription as k}from"./createSubscription-CF_00S2O.mjs";import{t as J}from"./solid-compat-ByG5HD_F.mjs";const L={__lunoraRef:""},nt=R=>{const{api:m,cancel:l,limit:h,onError:f,send:S,sendArgs:b,stream:g,threadKey:n}=R,{data:w,error:x}=k(m.agents.agentMessages,()=>{const t=o(n);return h===void 0?{key:t}:{key:t,limit:h}},{onError:f}),{data:I,error:_}=k(m.agents.agentThread,()=>({key:o(n)}),{onError:f}),K=s(()=>x()??_()),O=g===void 0?"skip":()=>({key:o(n)}),{chunks:T}=H(g??L,O),j=u(S),q=u(l??G),C=u(m.agents.agentResolveApproval),[y,d]=B([]);let v=0;J(()=>o(n),()=>{y().length>0&&d([])});const p=s(()=>I()),D=s(()=>p()?.status),i=s(()=>w()??[]),N=s(()=>{const t=i(),r=E(y(),t);if(r.length===0)return t;const e=M(t);return[...t,...r.map((a,c)=>({content:a.content,optimistic:!0,role:"user",seq:e+1+c}))]}),F=s(()=>{const t=o(n),r=i().filter(e=>e.role==="assistant").length;return T().filter(e=>e.kind!=="progress"&&e.threadKey===t&&e.turn>=r).map(e=>e.text).join("")}),U=async(t,r)=>{const e=v;v+=1;const a=M(i());d(c=>[...E(c,i()),{content:t,id:e,maxDurableSeqAtSend:a}]);try{await j.mutate({input:t,threadKey:o(n),...b,...r})}catch(c){throw d($=>$.filter(z=>z.id!==e)),c}},A=async(t,r,e)=>{const a=p()?.instanceId;if(a===void 0)throw new Error(`createAgentChat: cannot ${t} — no in-flight run (thread has no instanceId)`);await C.mutate({decision:t,instanceId:a,threadKey:o(n),toolCallId:r,...e===void 0?{}:{note:e}})};return{approve:async(t,r)=>A("approve",t,r),cancel:async()=>{const t=p()?.instanceId;l===void 0||t===void 0||await q.mutate({instanceId:t,threadKey:o(n)})},error:K,messages:N,reject:async(t,r)=>A("reject",t,r),send:U,status:D,streamingText:F}};export{nt as createAgentChat};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createMemo as v}from"solid-js";import{resolveMaybe as n}from"./createAgent-CWckPY7u.mjs";import{createStream as f}from"./createStream-CCAOb9q1.mjs";import{createSubscription as y}from"./createSubscription-CF_00S2O.mjs";const C={__lunoraRef:""},I=[],N=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 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}}]},_=t=>{const{api:r,limit:a,stream:i,threadKey:e}=t,u=()=>{const l=n(e);return a===void 0?{key:l}:{key:l,limit:a}},{data:p}=y(r.agents.agentMessages,u),s=i===void 0?"skip":()=>({key:n(e)}),{chunks:c}=f(i??C,s);return{events:v(()=>{const l=n(e),d=(p()??I).flatMap(o=>N(o)??[]);for(const o of c())o.kind==="progress"&&o.threadKey===l&&d.push({data:o.data,toolCallId:o.toolCallId,type:"progress"});return d})}};export{_ as createAgentToolEvents};
|