@securecoms/agent-bridge 0.26.0 → 0.26.2
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/connectors/hermes/adapter.py +24 -0
- package/connectors/hermes/tests/test_adapter_wiring.py +29 -0
- package/connectors/openclaw/openclaw-entry.inbound.test.ts +16 -0
- package/connectors/openclaw/openclaw-entry.js +23 -0
- package/dist/bin.js +565 -90
- package/dist/bridge-agent.d.ts +199 -35
- package/dist/config.d.ts +8 -0
- package/dist/index.js +565 -90
- package/dist/memory-taps.d.ts +3 -2
- package/dist/version.d.ts +1 -1
- package/dist/voice/defer-intent.d.ts +22 -0
- package/dist/voice/fast-prompt.d.ts +14 -0
- package/dist/voice/prompt-compiler.d.ts +8 -0
- package/package.json +1 -1
package/dist/bridge-agent.d.ts
CHANGED
|
@@ -51,10 +51,32 @@ export type BridgeToolGrant = {
|
|
|
51
51
|
};
|
|
52
52
|
/**
|
|
53
53
|
* Immutable authorization context derived from authenticated backend roster
|
|
54
|
-
* data. The E2E plaintext never contributes to these claims
|
|
55
|
-
*
|
|
56
|
-
*
|
|
54
|
+
* data. The E2E plaintext never contributes to these claims, with ONE bounded
|
|
55
|
+
* exception: a relayed voice turn's `speaker_identity_id`, honoured only when
|
|
56
|
+
* the envelope's authenticated sender is the channel's server-marked relay.
|
|
57
|
+
*
|
|
58
|
+
* Tool grants (architect ruling, 2026-10-02): until channel-grant persistence
|
|
59
|
+
* lands, the ONLY non-empty grant list is OWNER_DM_DEFAULT_READ_GRANTS
|
|
60
|
+
* (`current_time` + `web_search`, read mode), and only on a DM whose sender is
|
|
61
|
+
* the pinned structural owner (or a relayed voice turn whose speaker is). Every
|
|
62
|
+
* other audience, an unpinned or anomalous owner, and the kill switch
|
|
63
|
+
* `SECURECOMS_OWNER_DM_DEFAULT_GRANTS` (anything but unset/`on`) get `[]`.
|
|
64
|
+
* SEC-06 is LIVE for these two tools: docs/security/sec-06-runtime-bounds-audit.md.
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Architect ruling 2026-10-02: the default read grants an owner DM carries.
|
|
68
|
+
* A frozen constant in the daemon, NOT runtime config: a runtime cannot widen
|
|
69
|
+
* it, and the runtime's own tool allow-list still intersects it (a tool the
|
|
70
|
+
* runtime does not load is never offered). `fetch_url`, `echo`, `sql_query`
|
|
71
|
+
* and `http_request` are deliberately absent.
|
|
57
72
|
*/
|
|
73
|
+
export declare const OWNER_DM_DEFAULT_READ_GRANTS: readonly BridgeToolGrant[];
|
|
74
|
+
/**
|
|
75
|
+
* Kill switch for OWNER_DM_DEFAULT_READ_GRANTS, read once at BridgeAgent
|
|
76
|
+
* construction (daemon startup). Unset or exactly `on` keeps the grants;
|
|
77
|
+
* any other value (`off`, `0`, `false`, empty) sends `[]` on every turn.
|
|
78
|
+
*/
|
|
79
|
+
export declare function ownerDmDefaultGrantsEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
58
80
|
export interface BridgeAuthorization {
|
|
59
81
|
readonly version: 1;
|
|
60
82
|
readonly audience: AgentAudience;
|
|
@@ -272,6 +294,13 @@ export interface BridgeAgentDeps {
|
|
|
272
294
|
fastLlm?: {
|
|
273
295
|
complete(messages: ChatMessage[]): Promise<string>;
|
|
274
296
|
};
|
|
297
|
+
/**
|
|
298
|
+
* Voice repeats (a): how long a relayed transcribed voice turn waits for
|
|
299
|
+
* the rest of a VAD-split utterance, measured from its first fragment
|
|
300
|
+
* (default: env `SECURECOMS_VOICE_COALESCE_MS`, else 0 = disabled).
|
|
301
|
+
* Injected so tests do not wait the full window.
|
|
302
|
+
*/
|
|
303
|
+
voiceCoalesceWindowMs?: number;
|
|
275
304
|
/**
|
|
276
305
|
* B7 (FileSafe vault): persistence for the vault kekset's owner-pin TOFU
|
|
277
306
|
* state. Defaults to a {@link FileOwnerAuthorityStore} at
|
|
@@ -280,6 +309,22 @@ export interface BridgeAgentDeps {
|
|
|
280
309
|
*/
|
|
281
310
|
vaultOwnerStore?: OwnerAuthorityStore;
|
|
282
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* Voice repeats (a), owner report 2026-10-02: one spoken question reached the
|
|
314
|
+
* bridge as two relayed turns ~2 s apart (the relay's VAD split it), which
|
|
315
|
+
* produced a fast reply to the fragment, an ack, and a runtime answer.
|
|
316
|
+
* Relayed transcribed voice turns from the same speaker on the same channel
|
|
317
|
+
* that arrive within this window of the FIRST fragment are joined into one
|
|
318
|
+
* turn before the fast path plans it. The cost is that every relayed voice
|
|
319
|
+
* turn waits this long before it is answered, so it is OFF by default (0):
|
|
320
|
+
* the observed ~2 s split would not fit a window short enough for live
|
|
321
|
+
* voice. Enable with env `SECURECOMS_VOICE_COALESCE_MS` (read at startup).
|
|
322
|
+
*/
|
|
323
|
+
export declare const VOICE_COALESCE_WINDOW_MS = 0;
|
|
324
|
+
/** Upper bound for the window: a typo must not park every voice turn for minutes. */
|
|
325
|
+
export declare const VOICE_COALESCE_WINDOW_MAX_MS = 5000;
|
|
326
|
+
/** `SECURECOMS_VOICE_COALESCE_MS` as integer ms, clamped to VOICE_COALESCE_WINDOW_MAX_MS; anything else is 0 (disabled). */
|
|
327
|
+
export declare function voiceCoalesceWindowFromEnv(env?: NodeJS.ProcessEnv): number;
|
|
283
328
|
/** Default inbound-buffer cap (messages) when deps.maxBuffer is unset. */
|
|
284
329
|
export declare const DEFAULT_MAX_BUFFER = 1000;
|
|
285
330
|
/**
|
|
@@ -382,7 +427,7 @@ export declare class InvalidMessageIdError extends Error {
|
|
|
382
427
|
* `messageId`, formatted as an RFC 4122 UUID. Live finding 2026-09-06: the
|
|
383
428
|
* previous `fast-<messageId>` string failed `resolveMessageId` ("message_id
|
|
384
429
|
* must be a UUID") on every turn, so the fast path never sent once. Same input
|
|
385
|
-
* → same UUID, so the idempotency argument in `
|
|
430
|
+
* → same UUID, so the idempotency argument in `runFastReply`'s doc still holds.
|
|
386
431
|
*
|
|
387
432
|
* SEC-06 #18: KEYED with the identity-seed-derived reply key and bound to the
|
|
388
433
|
* agent and channel. It used to be SHA-256 of `fast:<messageId>` alone, which
|
|
@@ -732,6 +777,29 @@ export declare class BridgeAgent {
|
|
|
732
777
|
private fastPathFailed;
|
|
733
778
|
/** Cumulative count of fast-path turns skipped in a room channel because the shared send-floor bucket lacked headroom for both the ack and the runtime's own reply (controller ruling) — surfaced on health()/metrics(). */
|
|
734
779
|
private fastPathSkipped;
|
|
780
|
+
/** Off-cycle fast replies: per-channel promise chains + the in-flight job count. */
|
|
781
|
+
private readonly fastReplyChains;
|
|
782
|
+
private fastReplyJobs;
|
|
783
|
+
/** Room send-floor tokens reserved by queued fast replies, per channel (F3). */
|
|
784
|
+
private readonly fastReplyReserved;
|
|
785
|
+
private static readonly FAST_REPLY_MAX_JOBS;
|
|
786
|
+
/** Voice repeats (a): see {@link VOICE_COALESCE_WINDOW_MS}. */
|
|
787
|
+
private readonly voiceCoalesceWindowMs;
|
|
788
|
+
/** H1: fast-path reply ids being published right now (recorded as voice memory). */
|
|
789
|
+
private readonly spokenReplyIds;
|
|
790
|
+
/** Open coalescing windows, keyed by channel + speaker. */
|
|
791
|
+
private readonly voiceCoalescing;
|
|
792
|
+
/** Ids of every coalesced fragment (capped FIFO): a redelivered row is acked, never a second turn. */
|
|
793
|
+
private readonly voiceCoalescedIds;
|
|
794
|
+
/** Merged turn id -> the absorbed fragments' held frames, retired with it. */
|
|
795
|
+
private readonly voiceCoalescedTails;
|
|
796
|
+
/** (4) recv.lag: application queue ids already measured (capped FIFO), so a re-pulled row is not re-counted. */
|
|
797
|
+
private readonly recvLagSeen;
|
|
798
|
+
private static readonly RECV_LAG_SEEN_CAP;
|
|
799
|
+
/** Fast-path turns handed to the runtime behind a spoken ack (LLM [[DEFER]], pre-check, or ack_only). */
|
|
800
|
+
private fastPathDeferred;
|
|
801
|
+
/** Of those, `full`-mode turns the deterministic pre-check deferred without calling the fast model. */
|
|
802
|
+
private fastPathIntentDeferred;
|
|
735
803
|
/**
|
|
736
804
|
* Task 8: count of live AUTHENTICATED /v1/ws sessions, so a later `status`
|
|
737
805
|
* verb can tell "bridge process up" (the app's green dot, which only
|
|
@@ -820,6 +888,8 @@ export declare class BridgeAgent {
|
|
|
820
888
|
* back to the delivery-row-driven Task 11 behaviour only.
|
|
821
889
|
*/
|
|
822
890
|
private readonly selfHealSweepEnabled;
|
|
891
|
+
/** Read once at startup; see ownerDmDefaultGrantsEnabled. */
|
|
892
|
+
private readonly ownerDmDefaultGrants;
|
|
823
893
|
/** Task 12: proactive sweep cadence (in addition to the once-at-boot fire). */
|
|
824
894
|
private static readonly SELF_HEAL_SWEEP_INTERVAL_MS;
|
|
825
895
|
/**
|
|
@@ -1632,37 +1702,96 @@ export declare class BridgeAgent {
|
|
|
1632
1702
|
private memoryForTurn;
|
|
1633
1703
|
memoryContext(conversationId: string, limit?: number): Promise<import("@agentvault/connect-mls-store").MemoryContextResult>;
|
|
1634
1704
|
/**
|
|
1635
|
-
*
|
|
1636
|
-
*
|
|
1637
|
-
*
|
|
1638
|
-
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1641
|
-
*
|
|
1642
|
-
*
|
|
1643
|
-
*
|
|
1644
|
-
*
|
|
1645
|
-
*
|
|
1646
|
-
*
|
|
1647
|
-
*
|
|
1648
|
-
*
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1656
|
-
*
|
|
1657
|
-
*
|
|
1658
|
-
*
|
|
1659
|
-
*
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1705
|
+
* Voice front desk, step 1 — decided SYNCHRONOUSLY inside the ingest cycle,
|
|
1706
|
+
* so the cycle never waits on a model call or a publish (Cortina011
|
|
1707
|
+
* recv.cycle max 10.8 s came from two inline fast replies back to back).
|
|
1708
|
+
* Pure: it changes no state; the caller commits a plan (markFastPathSeen,
|
|
1709
|
+
* counters) only after the turn is durably staged.
|
|
1710
|
+
* - "dup": this turn already went through the fast path (a redelivery);
|
|
1711
|
+
* it is neither spoken again nor handed to the runtime again.
|
|
1712
|
+
* - "skip": no fast path; the runtime gets the turn with plain guidance
|
|
1713
|
+
* (mode `off`, no fast client, or the reply queue is full).
|
|
1714
|
+
* - "ack": the turn certainly goes to the runtime (mode `ack_only`, or the
|
|
1715
|
+
* deterministic pre-check in `full`): `line` is spoken first.
|
|
1716
|
+
* - "fast": the fast model (or, in `ack_only`, the greeting template)
|
|
1717
|
+
* decides whether the runtime answers next.
|
|
1718
|
+
* Owner report 2026-10-02 (calls never used tools) motivates "ack".
|
|
1719
|
+
*/
|
|
1720
|
+
private planFastPath;
|
|
1721
|
+
private noteVoiceCoalesced;
|
|
1722
|
+
private markFastPathSeen;
|
|
1723
|
+
/**
|
|
1724
|
+
* Off-cycle per-channel queue: one promise chain per channel, so within a
|
|
1725
|
+
* channel spoken lines publish, and runtime frames are released, strictly
|
|
1726
|
+
* in turn order (a turn's ack always publishes before its frame reaches
|
|
1727
|
+
* the runtime). `spends` marks a job that will publish a fast reply: those
|
|
1728
|
+
* are bounded by FAST_REPLY_MAX_JOBS (planFastPath degrades to "skip") and
|
|
1729
|
+
* reserve a room send-floor token until they finish. A job never throws.
|
|
1730
|
+
*/
|
|
1731
|
+
private enqueueFastReply;
|
|
1732
|
+
/** Count a fast reply against FAST_REPLY_MAX_JOBS and reserve its room send-floor token; returns the release. */
|
|
1733
|
+
private reserveFastReply;
|
|
1734
|
+
/**
|
|
1735
|
+
* Speak a planned fast turn ("ack" or "fast") and settle its held frame:
|
|
1736
|
+
* retired when the fast model answered alone, otherwise released to the
|
|
1737
|
+
* runtime (with the "ack already spoken" guidance only when an ack or a
|
|
1738
|
+
* deferring fast reply was actually published — F3).
|
|
1739
|
+
*/
|
|
1740
|
+
private speakAndSettle;
|
|
1741
|
+
/**
|
|
1742
|
+
* Stage a runtime frame without overtaking a turn of the same channel that
|
|
1743
|
+
* is still queued behind the fast path (F2): while the channel has a queue,
|
|
1744
|
+
* the frame is staged durably but held, and released in queue order.
|
|
1745
|
+
*/
|
|
1746
|
+
private stageRuntimeMessageInOrder;
|
|
1747
|
+
/** Test seam: resolves once every queued fast reply has settled. */
|
|
1748
|
+
settleFastReplies(): Promise<void>;
|
|
1749
|
+
/** Send a line the voice fast path speaks: its memory record is "voice" (H1). */
|
|
1750
|
+
private sendSpoken;
|
|
1751
|
+
/** Speak a fixed acknowledgement line; failures are counted, never thrown. */
|
|
1752
|
+
private sendFastLine;
|
|
1753
|
+
/**
|
|
1754
|
+
* Voice front desk, step 2 for a "fast" plan (runs off the ingest cycle):
|
|
1755
|
+
* the fast model's reply — or, in `ack_only`, the greeting template — is
|
|
1756
|
+
* spoken, and the outcome decides whether the runtime answers next.
|
|
1757
|
+
*
|
|
1758
|
+
* MUST NEVER throw: every failure path (memory lookup, the LLM call,
|
|
1759
|
+
* normalization, or the send itself) is caught, counted in
|
|
1760
|
+
* `fastPathFailed`, and logged WITHOUT the turn text or the model's reply.
|
|
1761
|
+
* The `fastReplyId(...)` send id is deterministic, so a duplicate that
|
|
1762
|
+
* slipped past the in-memory dedupe (e.g. a restart) resolves to the same
|
|
1763
|
+
* envelope message id rather than a second spoken reply.
|
|
1764
|
+
*
|
|
1765
|
+
* Room token reservation (controller ruling): the CALL SITE only plans a
|
|
1766
|
+
* fast path when the room bucket has headroom for this reply AND the
|
|
1767
|
+
* runtime's, and decides the buffered guidance from that same decision.
|
|
1768
|
+
*/
|
|
1769
|
+
private runFastReply;
|
|
1770
|
+
/**
|
|
1771
|
+
* Durably stage a runtime frame WITHOUT handing it to the runtime yet (a
|
|
1772
|
+
* "fast" plan: the fast reply decides). Same durability and backpressure
|
|
1773
|
+
* as stageRuntimeMessage; a restart restores it as an ordinary pending
|
|
1774
|
+
* frame (the "fast path failed" semantics), so a crash mid-call never loses
|
|
1775
|
+
* the turn.
|
|
1776
|
+
*/
|
|
1777
|
+
private stageHeldRuntimeMessage;
|
|
1778
|
+
/** Settle a held frame: the fast path answered alone (retire it) or the runtime answers next (release it, in channel order). */
|
|
1779
|
+
private settleHeldRuntimeMessage;
|
|
1780
|
+
/**
|
|
1781
|
+
* Voice repeats (b): a held frame's memory was read when its turn ARRIVED,
|
|
1782
|
+
* before the replies queued ahead of it (an earlier turn's fast reply, this
|
|
1783
|
+
* turn's own ack) were spoken. The runtime replaces its history with the
|
|
1784
|
+
* frame's memory, so with the arrival snapshot it answered an
|
|
1785
|
+
* already-answered turn again. At release the context is re-read and the
|
|
1786
|
+
* AGENT turns it holds beyond the snapshot (afterPublish ->
|
|
1787
|
+
* recordOutboundMemory) are appended to the snapshot. Peer turns recorded
|
|
1788
|
+
* since (this turn itself, later turns) are not, so the frame stays
|
|
1789
|
+
* prior-turn-only for what the runtime is about to answer. New turns are
|
|
1790
|
+
* found by recorded time, never by `seq` (the OpenClaw provider renumbers
|
|
1791
|
+
* seq per read). A failed re-read keeps the arrival snapshot.
|
|
1792
|
+
*/
|
|
1793
|
+
private memoryAtRelease;
|
|
1794
|
+
private static readonly TURN_MEMORY_LIMIT;
|
|
1666
1795
|
/**
|
|
1667
1796
|
* List channels in one enclave (default: the daemon's own home enclave).
|
|
1668
1797
|
* Task 3: called per-*known* enclave by refreshChannelMeta so a
|
|
@@ -1717,6 +1846,15 @@ export declare class BridgeAgent {
|
|
|
1717
1846
|
* 5xx, and genuine non-member 404s only.
|
|
1718
1847
|
*/
|
|
1719
1848
|
private refreshChannelMeta;
|
|
1849
|
+
/**
|
|
1850
|
+
* Cache server-listed channel metadata (is_dm, name) for the receive cycle.
|
|
1851
|
+
* The ONLY input is a `listChannels` result, the same backend rows
|
|
1852
|
+
* refreshChannelMeta has always cached: refreshChannelMeta and the
|
|
1853
|
+
* self-heal sweep both feed it, so the sweep's own listing (every 90-120 s)
|
|
1854
|
+
* keeps the 5 min cache warm and a turn arriving after idle does not pay a
|
|
1855
|
+
* listing round trip per enclave before it reaches the runtime.
|
|
1856
|
+
*/
|
|
1857
|
+
private recordListedChannelMeta;
|
|
1720
1858
|
/** Cache for the server-side enclave enumeration (see enclavesToCover). */
|
|
1721
1859
|
private enclaveEnumCache;
|
|
1722
1860
|
/** Enclaves whose channel listing failed on the NEWEST sweep (audit HIGH:
|
|
@@ -1816,6 +1954,17 @@ export declare class BridgeAgent {
|
|
|
1816
1954
|
* Missing or stale metadata is UNKNOWN with zero grants, never a permissive
|
|
1817
1955
|
* guess. The returned object and grant array are frozen before they cross the
|
|
1818
1956
|
* daemon boundary so one consumer cannot widen a later execution check.
|
|
1957
|
+
*
|
|
1958
|
+
* Grants (architect ruling 2026-10-02): OWNER_DM_DEFAULT_READ_GRANTS only when
|
|
1959
|
+
* the kill switch is on, the channel is a DM, and EITHER
|
|
1960
|
+
* (a) audience is owner_dm AND the sender is the pinned structural owner
|
|
1961
|
+
* (`channelOwner`, never "anomalous") — a lying `is_agent_owner` flag
|
|
1962
|
+
* alone gets nothing; OR
|
|
1963
|
+
* (b) the sender is this channel's server-marked relay (`is_relay`) and the
|
|
1964
|
+
* relayed `speaker_identity_id` (passed by the caller only for relay
|
|
1965
|
+
* turns) is that same pinned owner, whose roster row is the agent's
|
|
1966
|
+
* owner. A speaker claim from any non-relay sender gets nothing.
|
|
1967
|
+
* Everything else gets the frozen empty list.
|
|
1819
1968
|
*/
|
|
1820
1969
|
private authorizationFor;
|
|
1821
1970
|
/**
|
|
@@ -1964,6 +2113,15 @@ export declare class BridgeAgent {
|
|
|
1964
2113
|
*/
|
|
1965
2114
|
private ingestOnce;
|
|
1966
2115
|
private startIngestCycle;
|
|
2116
|
+
/**
|
|
2117
|
+
* (4) recv.lag = server message created_at -> this pull's completion, per
|
|
2118
|
+
* application row, counted once per queue id. It makes the daemon-side
|
|
2119
|
+
* receive delay measurable (recv.pull alone times only the HTTP call).
|
|
2120
|
+
* Cross-clock: daemon-vs-server skew lands in the sample; a negative lag
|
|
2121
|
+
* is clamped to 0. The server serialises a naive UTC datetime (no offset),
|
|
2122
|
+
* which Date.parse would read as LOCAL time, so a bare timestamp is UTC.
|
|
2123
|
+
*/
|
|
2124
|
+
private recordRecvLag;
|
|
1967
2125
|
private ingestCycle;
|
|
1968
2126
|
drain(channelId: string | undefined, waitSeconds: number): Promise<BridgeMessage[]>;
|
|
1969
2127
|
/** Notify-only SSE signal: fired after a buffer push. Listener pulls via takeBuffered. */
|
|
@@ -2164,6 +2322,12 @@ export declare class BridgeAgent {
|
|
|
2164
2322
|
fast_path_failed: number;
|
|
2165
2323
|
/** Task 4 (self-hosted fast voice): cumulative fast-path turns skipped in a room because the send-floor bucket lacked headroom for both the ack and the runtime's reply. */
|
|
2166
2324
|
fast_path_skipped: number;
|
|
2325
|
+
/** Fast-path turns handed to the runtime behind a spoken ack (LLM [[DEFER]], pre-check, or ack_only). */
|
|
2326
|
+
fast_path_deferred: number;
|
|
2327
|
+
/** `full`-mode turns deferred by the deterministic pre-check (no fast model call). */
|
|
2328
|
+
fast_path_intent_deferred: number;
|
|
2329
|
+
/** Credential `voice_fast_path_mode`: "full" (default), "ack_only" or "off". */
|
|
2330
|
+
fast_path_mode: "full" | "ack_only" | "off";
|
|
2167
2331
|
/** Plan 2026-09-06 (agent voice settings): version of the loaded backend
|
|
2168
2332
|
* voice-settings row, or null when no backend row has ever loaded
|
|
2169
2333
|
* (source is "file" or "none"). */
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type VoiceConfig } from "./voice/persona.js";
|
|
2
|
+
import { type FastPathMode } from "./voice/defer-intent.js";
|
|
2
3
|
export interface BridgeConfig {
|
|
3
4
|
apiKey: string;
|
|
4
5
|
identityId: string;
|
|
@@ -30,6 +31,13 @@ export interface BridgeConfig {
|
|
|
30
31
|
memoryFactsCharBudget?: number;
|
|
31
32
|
/** Optional voice persona + fast-path LLM config (self-hosted fast voice reply). Undefined when the credential has no `voice` block. */
|
|
32
33
|
voice?: VoiceConfig;
|
|
34
|
+
/**
|
|
35
|
+
* Voice fast-path mode (credential top-level `voice_fast_path_mode`):
|
|
36
|
+
* "full" (default), "ack_only" or "off" — see voice/defer-intent.ts. Kept
|
|
37
|
+
* outside `voice` because backend-managed agents have no `voice` block and
|
|
38
|
+
* a backend voice-settings refetch replaces `voice` wholesale.
|
|
39
|
+
*/
|
|
40
|
+
voiceFastPathMode?: FastPathMode;
|
|
33
41
|
}
|
|
34
42
|
export declare const REQUIRED: readonly ["api_key", "identity_id", "device_id", "signing_private_key", "enclave_id", "api_base"];
|
|
35
43
|
export declare function loadConfig(opts: {
|