@yieldfabric/terminal 1.2.0 → 1.3.1
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.cjs +169 -23
- package/dist/index.d.cts +59 -3
- package/dist/index.d.ts +59 -3
- package/dist/index.js +170 -25
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2234,18 +2234,21 @@ function CopyButton({ content }) {
|
|
|
2234
2234
|
}
|
|
2235
2235
|
);
|
|
2236
2236
|
}
|
|
2237
|
+
var MESSAGES = {
|
|
2238
|
+
rounds_exhausted: "Partial answer \u2014 I reached the step limit. Ask a narrower follow-up to continue.",
|
|
2239
|
+
budget_exhausted: "Partial answer \u2014 this question needs more context than fits in one answer. Try narrowing the question.",
|
|
2240
|
+
deadline: "Partial answer \u2014 I ran out of time before finishing. Ask a narrower follow-up to continue.",
|
|
2241
|
+
output_limit: "Partial answer \u2014 it was cut off at its length limit. Ask for the rest, or a narrower follow-up.",
|
|
2242
|
+
awaiting_tool_results: "This answer paused before its next step. Ask again to review a fresh answer.",
|
|
2243
|
+
empty: "No answer was returned. Please try again.",
|
|
2244
|
+
failed: "The answer could not be completed. What arrived so far is kept here.",
|
|
2245
|
+
interrupted: "Connection interrupted. The assistant may still be working; check the conversation before sending again.",
|
|
2246
|
+
cancelled: "Stopped. You can change your question and ask again."
|
|
2247
|
+
};
|
|
2237
2248
|
function AgentCompletionNotice({ completion }) {
|
|
2238
2249
|
const t = useTheme();
|
|
2239
2250
|
if (!completion || completion.stop_reason === "answered") return null;
|
|
2240
|
-
const message =
|
|
2241
|
-
rounds_exhausted: "Partial answer \u2014 I reached the step limit. Ask a narrower follow-up to continue.",
|
|
2242
|
-
budget_exhausted: "Partial answer \u2014 this question needs more context than fits in one answer. Try narrowing the question.",
|
|
2243
|
-
awaiting_tool_results: "This answer paused before its next step. Ask again to review a fresh answer.",
|
|
2244
|
-
empty: "No answer was returned. Please try again.",
|
|
2245
|
-
failed: "The answer could not be completed. What arrived so far is kept here.",
|
|
2246
|
-
interrupted: "Connection interrupted. The assistant may still be working; check the conversation before sending again.",
|
|
2247
|
-
cancelled: "Stopped. You can change your question and ask again."
|
|
2248
|
-
}[completion.stop_reason];
|
|
2251
|
+
const message = MESSAGES[completion.stop_reason];
|
|
2249
2252
|
if (!message) return null;
|
|
2250
2253
|
return /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", className: "mt-2 rounded-md px-3 py-2 text-xs", style: { color: t.textSecondary, backgroundColor: t.bgRaisedAlt, border: `1px solid ${t.border}` }, children: message });
|
|
2251
2254
|
}
|
|
@@ -7856,6 +7859,54 @@ function encodePersona(persona) {
|
|
|
7856
7859
|
return Object.keys(fields).length ? JSON.stringify(fields) : null;
|
|
7857
7860
|
}
|
|
7858
7861
|
|
|
7862
|
+
// src/voice/screenAwake.ts
|
|
7863
|
+
function browserWakeLock() {
|
|
7864
|
+
return typeof navigator === "undefined" ? void 0 : navigator.wakeLock;
|
|
7865
|
+
}
|
|
7866
|
+
var ScreenAwake = class {
|
|
7867
|
+
constructor(api = browserWakeLock()) {
|
|
7868
|
+
this.api = api;
|
|
7869
|
+
this.sentinel = null;
|
|
7870
|
+
this.wanted = false;
|
|
7871
|
+
this.requesting = false;
|
|
7872
|
+
this.onVisibility = () => {
|
|
7873
|
+
if (document.visibilityState === "visible") void this.take();
|
|
7874
|
+
};
|
|
7875
|
+
}
|
|
7876
|
+
/** The screen is being kept on right now. */
|
|
7877
|
+
get held() {
|
|
7878
|
+
return !!this.sentinel && !this.sentinel.released;
|
|
7879
|
+
}
|
|
7880
|
+
/** Keep the screen on until `release`. Call it from the tap that starts
|
|
7881
|
+
* the session. */
|
|
7882
|
+
hold() {
|
|
7883
|
+
if (!this.api || this.wanted) return;
|
|
7884
|
+
this.wanted = true;
|
|
7885
|
+
document.addEventListener("visibilitychange", this.onVisibility);
|
|
7886
|
+
void this.take();
|
|
7887
|
+
}
|
|
7888
|
+
release() {
|
|
7889
|
+
if (!this.wanted) return;
|
|
7890
|
+
this.wanted = false;
|
|
7891
|
+
document.removeEventListener("visibilitychange", this.onVisibility);
|
|
7892
|
+
const sentinel = this.sentinel;
|
|
7893
|
+
this.sentinel = null;
|
|
7894
|
+
void sentinel?.release().catch(() => void 0);
|
|
7895
|
+
}
|
|
7896
|
+
async take() {
|
|
7897
|
+
if (!this.api || !this.wanted || this.held || this.requesting || document.visibilityState !== "visible") return;
|
|
7898
|
+
this.requesting = true;
|
|
7899
|
+
try {
|
|
7900
|
+
const sentinel = await this.api.request("screen");
|
|
7901
|
+
if (this.wanted) this.sentinel = sentinel;
|
|
7902
|
+
else void sentinel.release().catch(() => void 0);
|
|
7903
|
+
} catch {
|
|
7904
|
+
} finally {
|
|
7905
|
+
this.requesting = false;
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
};
|
|
7909
|
+
|
|
7859
7910
|
// src/voice/worklet.ts
|
|
7860
7911
|
var VOICE_CAPTURE_WORKLET_SOURCE = `class YfVoiceCapture extends AudioWorkletProcessor {
|
|
7861
7912
|
constructor() {
|
|
@@ -7991,6 +8042,8 @@ var VoiceSession = class {
|
|
|
7991
8042
|
this.ready = false;
|
|
7992
8043
|
this.ended = false;
|
|
7993
8044
|
this.phase = null;
|
|
8045
|
+
/** Keeps a phone from locking mid-conversation (see `screenAwake.ts`). */
|
|
8046
|
+
this.awake = new ScreenAwake();
|
|
7994
8047
|
/** The voice's questions to the host, one at a time (see `askQueue.ts`). */
|
|
7995
8048
|
this.asks = new AskQueue(
|
|
7996
8049
|
(ask, signal) => {
|
|
@@ -8013,6 +8066,7 @@ var VoiceSession = class {
|
|
|
8013
8066
|
this.saying = "";
|
|
8014
8067
|
this.endingReason = null;
|
|
8015
8068
|
this.finishTimer = null;
|
|
8069
|
+
this.muted = false;
|
|
8016
8070
|
this.blobUrl = null;
|
|
8017
8071
|
}
|
|
8018
8072
|
/** Call from the tap itself: iOS only lets audio start inside a gesture,
|
|
@@ -8026,6 +8080,7 @@ var VoiceSession = class {
|
|
|
8026
8080
|
const ctx = new Ctx();
|
|
8027
8081
|
this.ctx = ctx;
|
|
8028
8082
|
void ctx.resume();
|
|
8083
|
+
this.awake.hold();
|
|
8029
8084
|
this.setPhase("connecting");
|
|
8030
8085
|
const status = await getVoiceStatus(this.connection);
|
|
8031
8086
|
if (this.ended) return;
|
|
@@ -8041,6 +8096,7 @@ var VoiceSession = class {
|
|
|
8041
8096
|
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
8042
8097
|
audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true }
|
|
8043
8098
|
});
|
|
8099
|
+
this.applyMute();
|
|
8044
8100
|
} catch (e) {
|
|
8045
8101
|
this.end("mic_denied", e?.message);
|
|
8046
8102
|
return;
|
|
@@ -8112,6 +8168,24 @@ var VoiceSession = class {
|
|
|
8112
8168
|
stop() {
|
|
8113
8169
|
this.end("stopped");
|
|
8114
8170
|
}
|
|
8171
|
+
/**
|
|
8172
|
+
* Mute the microphone, or not. The track goes silent rather than the
|
|
8173
|
+
* stream stopping: the service keeps hearing (silence), so whatever the
|
|
8174
|
+
* person was saying ends as a turn and nothing hangs half-heard. The
|
|
8175
|
+
* voice can still talk while they are muted.
|
|
8176
|
+
*/
|
|
8177
|
+
setMuted(muted) {
|
|
8178
|
+
this.muted = muted;
|
|
8179
|
+
this.applyMute();
|
|
8180
|
+
}
|
|
8181
|
+
get isMuted() {
|
|
8182
|
+
return this.muted;
|
|
8183
|
+
}
|
|
8184
|
+
applyMute() {
|
|
8185
|
+
this.stream?.getAudioTracks().forEach((track) => {
|
|
8186
|
+
track.enabled = !this.muted;
|
|
8187
|
+
});
|
|
8188
|
+
}
|
|
8115
8189
|
/** Cheap enough to call every animation frame. */
|
|
8116
8190
|
levels() {
|
|
8117
8191
|
if (this.ended) return SILENT;
|
|
@@ -8235,6 +8309,7 @@ var VoiceSession = class {
|
|
|
8235
8309
|
this.finishTimer = null;
|
|
8236
8310
|
}
|
|
8237
8311
|
release() {
|
|
8312
|
+
this.awake.release();
|
|
8238
8313
|
this.node?.port.close();
|
|
8239
8314
|
this.node?.disconnect();
|
|
8240
8315
|
this.stream?.getTracks().forEach((t) => t.stop());
|
|
@@ -8329,6 +8404,7 @@ function useVoiceSession(host, connection) {
|
|
|
8329
8404
|
const [saying, setSaying] = React15.useState("");
|
|
8330
8405
|
const [ended, setEnded] = React15.useState(null);
|
|
8331
8406
|
const [startedAt, setStartedAt] = React15.useState(null);
|
|
8407
|
+
const [muted, setMuted] = React15.useState(false);
|
|
8332
8408
|
const session = React15.useRef(null);
|
|
8333
8409
|
const hostRef = React15.useRef(host);
|
|
8334
8410
|
hostRef.current = host;
|
|
@@ -8351,6 +8427,7 @@ function useVoiceSession(host, connection) {
|
|
|
8351
8427
|
setHeard("");
|
|
8352
8428
|
setSaying("");
|
|
8353
8429
|
setStartedAt(null);
|
|
8430
|
+
setMuted(false);
|
|
8354
8431
|
const s = new VoiceSession(
|
|
8355
8432
|
{
|
|
8356
8433
|
onPhase: (p) => {
|
|
@@ -8364,6 +8441,7 @@ function useVoiceSession(host, connection) {
|
|
|
8364
8441
|
onReply: (r) => hostRef.current.onReply?.(r),
|
|
8365
8442
|
onEnd: (reason, detail) => {
|
|
8366
8443
|
if (session.current === s) session.current = null;
|
|
8444
|
+
setMuted(false);
|
|
8367
8445
|
setPhase("off");
|
|
8368
8446
|
setStartedAt(null);
|
|
8369
8447
|
setEnded(reason === "stopped" || reason === "finished" ? null : { reason, detail });
|
|
@@ -8377,6 +8455,12 @@ function useVoiceSession(host, connection) {
|
|
|
8377
8455
|
const stop = React15.useCallback(() => session.current?.stop(), []);
|
|
8378
8456
|
const toggle = React15.useCallback(() => session.current ? stop() : start(), [start, stop]);
|
|
8379
8457
|
const dismiss = React15.useCallback(() => setEnded(null), []);
|
|
8458
|
+
const toggleMute = React15.useCallback(() => {
|
|
8459
|
+
const s = session.current;
|
|
8460
|
+
if (!s) return;
|
|
8461
|
+
s.setMuted(!s.isMuted);
|
|
8462
|
+
setMuted(s.isMuted);
|
|
8463
|
+
}, []);
|
|
8380
8464
|
const levels = React15.useCallback(() => session.current?.levels() ?? SILENT, []);
|
|
8381
8465
|
const level = React15.useCallback(() => {
|
|
8382
8466
|
const l = levels();
|
|
@@ -8395,6 +8479,8 @@ function useVoiceSession(host, connection) {
|
|
|
8395
8479
|
levels,
|
|
8396
8480
|
level,
|
|
8397
8481
|
buttonState: phase === "off" ? "off" : phase === "connecting" ? "connecting" : "live",
|
|
8482
|
+
muted,
|
|
8483
|
+
toggleMute,
|
|
8398
8484
|
start,
|
|
8399
8485
|
stop,
|
|
8400
8486
|
toggle,
|
|
@@ -8478,6 +8564,7 @@ var VOICE_DECK_CSS = `
|
|
|
8478
8564
|
}
|
|
8479
8565
|
.yf-voice-deck[data-phase='listening'] .yf-voice-beacon { animation-duration: 3.2s; }
|
|
8480
8566
|
.yf-voice-phase {
|
|
8567
|
+
white-space: nowrap;
|
|
8481
8568
|
font-size: 10.5px;
|
|
8482
8569
|
font-weight: 600;
|
|
8483
8570
|
letter-spacing: 0.14em;
|
|
@@ -8505,12 +8592,36 @@ var VOICE_DECK_CSS = `
|
|
|
8505
8592
|
.yf-voice-end:hover { background: color-mix(in srgb, var(--yf-voice-ink) 10%, transparent); border-color: color-mix(in srgb, var(--yf-voice-ink) 28%, transparent); color: var(--yf-voice-ink); }
|
|
8506
8593
|
.yf-voice-end:active { transform: scale(0.97); }
|
|
8507
8594
|
.yf-voice-end__mark { width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
|
|
8595
|
+
.yf-voice-mute {
|
|
8596
|
+
display: inline-flex;
|
|
8597
|
+
align-items: center;
|
|
8598
|
+
justify-content: center;
|
|
8599
|
+
width: 28px;
|
|
8600
|
+
height: 28px;
|
|
8601
|
+
border-radius: 999px;
|
|
8602
|
+
border: 1px solid color-mix(in srgb, var(--yf-voice-ink) 16%, transparent);
|
|
8603
|
+
background: color-mix(in srgb, var(--yf-voice-ink) 5%, transparent);
|
|
8604
|
+
color: color-mix(in srgb, var(--yf-voice-ink) 85%, transparent);
|
|
8605
|
+
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
|
8606
|
+
-webkit-tap-highlight-color: transparent;
|
|
8607
|
+
}
|
|
8608
|
+
.yf-voice-mute svg { width: 14px; height: 14px; }
|
|
8609
|
+
.yf-voice-mute:hover { background: color-mix(in srgb, var(--yf-voice-ink) 10%, transparent); color: var(--yf-voice-ink); }
|
|
8610
|
+
.yf-voice-mute:active { transform: scale(0.95); }
|
|
8611
|
+
.yf-voice-mute:disabled { opacity: 0.4; }
|
|
8612
|
+
.yf-voice-mute[aria-pressed='true'] {
|
|
8613
|
+
border-color: color-mix(in srgb, var(--yf-voice-accent) 55%, transparent);
|
|
8614
|
+
background: color-mix(in srgb, var(--yf-voice-accent) 18%, transparent);
|
|
8615
|
+
color: var(--yf-voice-accent);
|
|
8616
|
+
}
|
|
8617
|
+
.yf-voice-deck[data-muted] .yf-voice-beacon { background: var(--yf-voice-muted); animation: none; }
|
|
8618
|
+
.yf-voice-deck[data-muted] .yf-voice-phase { color: var(--yf-voice-muted); }
|
|
8508
8619
|
.yf-voice-print {
|
|
8509
8620
|
-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 100%);
|
|
8510
8621
|
mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 100%);
|
|
8511
8622
|
}
|
|
8512
8623
|
.yf-voice-caption { display: flex; min-width: 0; align-items: baseline; gap: 8px; color: color-mix(in srgb, var(--yf-voice-ink) 72%, transparent); }
|
|
8513
|
-
.yf-voice-caption--javier { display: block; color: var(--yf-voice-ink); font-weight: 450; text-wrap: pretty; }
|
|
8624
|
+
.yf-voice-caption--javier { display: block; color: var(--yf-voice-ink); font-weight: 450; text-wrap: pretty; overflow-wrap: anywhere; }
|
|
8514
8625
|
.yf-voice-hint { color: var(--yf-voice-muted); }
|
|
8515
8626
|
.yf-voice-who {
|
|
8516
8627
|
flex-shrink: 0;
|
|
@@ -8520,9 +8631,27 @@ var VOICE_DECK_CSS = `
|
|
|
8520
8631
|
text-transform: uppercase;
|
|
8521
8632
|
color: var(--yf-voice-muted);
|
|
8522
8633
|
}
|
|
8634
|
+
.yf-voice-deck[data-fill] { display: flex; flex-direction: column; height: 100%; min-height: 0; }
|
|
8635
|
+
.yf-voice-deck[data-fill] .yf-voice-deck__panel { flex: 1; display: flex; flex-direction: column; min-height: 0; }
|
|
8636
|
+
.yf-voice-detail {
|
|
8637
|
+
flex: 1;
|
|
8638
|
+
min-height: 0;
|
|
8639
|
+
overflow-y: auto;
|
|
8640
|
+
overflow-x: hidden;
|
|
8641
|
+
overflow-wrap: anywhere;
|
|
8642
|
+
overscroll-behavior: contain;
|
|
8643
|
+
-webkit-overflow-scrolling: touch;
|
|
8644
|
+
padding: 10px 16px 16px;
|
|
8645
|
+
border-top: 1px solid color-mix(in srgb, var(--yf-voice-ink) 8%, transparent);
|
|
8646
|
+
-webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 18px), transparent 100%);
|
|
8647
|
+
mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 18px), transparent 100%);
|
|
8648
|
+
animation: yf-voice-rise 0.32s cubic-bezier(0.2, 0.7, 0.2, 1) both;
|
|
8649
|
+
}
|
|
8523
8650
|
.yf-voice-deck[data-phone] { border-radius: 20px; }
|
|
8524
8651
|
.yf-voice-deck[data-phone] .yf-voice-deck__panel { border-radius: 19px; }
|
|
8525
8652
|
.yf-voice-deck[data-phone] .yf-voice-end { height: 40px; padding: 0 16px 0 14px; font-size: 14px; }
|
|
8653
|
+
.yf-voice-deck[data-phone] .yf-voice-mute { width: 40px; height: 40px; margin-right: 2px; }
|
|
8654
|
+
.yf-voice-deck[data-phone] .yf-voice-mute svg { width: 18px; height: 18px; }
|
|
8526
8655
|
.yf-voice-deck[data-phone] .yf-voice-phase { font-size: 11.5px; }
|
|
8527
8656
|
@media (prefers-reduced-motion: reduce) {
|
|
8528
8657
|
.yf-voice-deck, .yf-voice-beacon, .yf-voice-deck__panel { animation: none; }
|
|
@@ -8536,7 +8665,7 @@ function ensureVoiceDeckStyles(doc = typeof document === "undefined" ? void 0 :
|
|
|
8536
8665
|
style.textContent = VOICE_DECK_CSS;
|
|
8537
8666
|
doc.head.appendChild(style);
|
|
8538
8667
|
}
|
|
8539
|
-
function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
8668
|
+
function VoiceDeck({ voice, name, phone = false, hint, fill = false, children }) {
|
|
8540
8669
|
const t = useTheme();
|
|
8541
8670
|
React15.useEffect(() => ensureVoiceDeckStyles(), []);
|
|
8542
8671
|
const now = useClock(voice.startedAt !== null);
|
|
@@ -8546,9 +8675,10 @@ function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
|
8546
8675
|
connecting: "Connecting",
|
|
8547
8676
|
listening: "Listening",
|
|
8548
8677
|
hearing: "Hearing you",
|
|
8549
|
-
thinking: "Working
|
|
8678
|
+
thinking: "Working",
|
|
8550
8679
|
speaking: speaker
|
|
8551
8680
|
};
|
|
8681
|
+
const phaseWord = voice.muted && voice.phase !== "speaking" && voice.phase !== "connecting" ? "Muted" : phaseWords[voice.phase];
|
|
8552
8682
|
const { startedAt, maxSessionSecs } = voice;
|
|
8553
8683
|
const elapsed = startedAt === null ? 0 : now - startedAt;
|
|
8554
8684
|
const remaining = maxSessionSecs > 0 && startedAt !== null ? maxSessionSecs * 1e3 - elapsed : Infinity;
|
|
@@ -8561,26 +8691,40 @@ function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
|
8561
8691
|
"--yf-voice-muted": t.textMuted,
|
|
8562
8692
|
"--yf-voice-panel": t.bgRaised
|
|
8563
8693
|
};
|
|
8564
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yf-voice-deck", "data-phase": voice.phase, "data-phone": phone ? "" : void 0, style: vars, children: [
|
|
8694
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yf-voice-deck", "data-phase": voice.phase, "data-phone": phone ? "" : void 0, "data-fill": fill ? "" : void 0, "data-muted": voice.muted ? "" : void 0, style: vars, children: [
|
|
8565
8695
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "yf-voice-deck__panel", children: [
|
|
8566
8696
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center gap-2.5 ${phone ? "px-4 pt-3.5" : "px-4 pt-3"}`, children: [
|
|
8567
8697
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "yf-voice-beacon", "aria-hidden": "true" }),
|
|
8568
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", "aria-live": "polite", className: "yf-voice-phase", children:
|
|
8698
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", "aria-live": "polite", className: "yf-voice-phase", children: phaseWord }),
|
|
8569
8699
|
startedAt !== null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "yf-voice-clock", "data-soon": endingSoon ? "" : void 0, title: endingSoon ? "Voice ends soon" : "Time in this voice session", children: endingSoon && Number.isFinite(remaining) ? `ends in ${clock(remaining)}` : clock(elapsed) }) : null,
|
|
8570
8700
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1" }),
|
|
8701
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8702
|
+
"button",
|
|
8703
|
+
{
|
|
8704
|
+
type: "button",
|
|
8705
|
+
onClick: voice.toggleMute,
|
|
8706
|
+
className: "yf-voice-mute",
|
|
8707
|
+
"aria-pressed": voice.muted,
|
|
8708
|
+
"aria-label": voice.muted ? "Unmute microphone" : "Mute microphone",
|
|
8709
|
+
title: voice.muted ? "Unmute" : "Mute",
|
|
8710
|
+
disabled: voice.phase === "connecting",
|
|
8711
|
+
children: voice.muted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MicOff, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { "aria-hidden": "true" })
|
|
8712
|
+
}
|
|
8713
|
+
),
|
|
8571
8714
|
/* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", onClick: voice.stop, className: "yf-voice-end", "aria-label": "End voice", children: [
|
|
8572
8715
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "yf-voice-end__mark", "aria-hidden": "true" }),
|
|
8573
8716
|
"End"
|
|
8574
8717
|
] })
|
|
8575
8718
|
] }),
|
|
8576
|
-
/* @__PURE__ */ jsxRuntime.jsx(Voiceprint, { phase: voice.phase, levels: voice.levels, height: phone ? 104 : 76, cell: phone ? 13 : 11 }),
|
|
8719
|
+
/* @__PURE__ */ jsxRuntime.jsx(Voiceprint, { phase: voice.phase, levels: voice.levels, height: fill ? 148 : phone ? 104 : 76, cell: fill ? 14 : phone ? 13 : 11 }),
|
|
8577
8720
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col gap-1.5 ${phone ? "px-4 pb-4" : "px-4 pb-3.5"}`, style: { minHeight: "1.25rem" }, "aria-live": "off", children: [
|
|
8578
8721
|
words ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "yf-voice-caption", style: { fontSize: phone ? 13.5 : 12.5 }, children: [
|
|
8579
8722
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "yf-voice-who", children: "You" }),
|
|
8580
8723
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: words })
|
|
8581
8724
|
] }) : null,
|
|
8582
|
-
said ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "yf-voice-caption yf-voice-caption--javier", style: { fontSize: phone ? 16 : 14, lineHeight: phone ? 1.45 : 1.5 }, children: said }) : !words ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "yf-voice-hint", style: { fontSize: phone ? 14 : 12.5 }, children: voice.phase === "connecting" ? "Opening the line\u2026" : hint ?? "Ask anything. Talk over me to interrupt." }) : null
|
|
8583
|
-
] })
|
|
8725
|
+
said ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "yf-voice-caption yf-voice-caption--javier", style: { fontSize: phone ? 16 : 14, lineHeight: phone ? 1.45 : 1.5 }, children: said }) : !words ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "yf-voice-hint", style: { fontSize: phone ? 14 : 12.5 }, children: voice.phase === "connecting" ? "Opening the line\u2026" : voice.muted ? "Your microphone is off. Tap it to talk." : hint ?? "Ask anything. Talk over me to interrupt." }) : null
|
|
8726
|
+
] }),
|
|
8727
|
+
fill && children ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "yf-voice-detail", children }) : null
|
|
8584
8728
|
] }),
|
|
8585
8729
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-voice-probe": "ink", hidden: true, style: { color: "var(--yf-voice-ink)" } }),
|
|
8586
8730
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-voice-probe": "accent", hidden: true, style: { color: "var(--yf-voice-accent)" } }),
|
|
@@ -10511,8 +10655,9 @@ function EdgeDetailDrawer({ edge, annotations, onClose, onNavigate }) {
|
|
|
10511
10655
|
]
|
|
10512
10656
|
}
|
|
10513
10657
|
),
|
|
10514
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-1", style: { backgroundColor: "#1e1e1e", borderTop: "1px solid #282828", borderBottom: "1px solid #282828" }, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-gray-500", children: [
|
|
10515
|
-
"
|
|
10658
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-1", style: { backgroundColor: "#1e1e1e", borderTop: "1px solid #282828", borderBottom: "1px solid #282828" }, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-gray-500", children: [
|
|
10659
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3" }),
|
|
10660
|
+
" ",
|
|
10516
10661
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color }, children: typeLabel })
|
|
10517
10662
|
] }) }),
|
|
10518
10663
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -11433,7 +11578,7 @@ function SchemaStage({
|
|
|
11433
11578
|
style: { flex: 1, fontSize: 11, color: "#aaa", backgroundColor: "transparent", border: "1px solid #333", borderRadius: 4, padding: "5px 8px", outline: "none" }
|
|
11434
11579
|
}
|
|
11435
11580
|
),
|
|
11436
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#555", alignSelf: "center", fontSize: 12 }, children: "\
|
|
11581
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#555", alignSelf: "center", fontSize: 12 }, children: "\u203A" }),
|
|
11437
11582
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
11438
11583
|
"input",
|
|
11439
11584
|
{
|
|
@@ -11543,7 +11688,7 @@ function SchemaStage({
|
|
|
11543
11688
|
onMouseUp: (e) => {
|
|
11544
11689
|
e.currentTarget.style.transform = "translateY(0)";
|
|
11545
11690
|
},
|
|
11546
|
-
children: "Looks good \u2014 read the document \
|
|
11691
|
+
children: "Looks good \u2014 read the document \u203A"
|
|
11547
11692
|
}
|
|
11548
11693
|
)
|
|
11549
11694
|
]
|
|
@@ -12228,7 +12373,7 @@ function StageCanvas({ nodeCount, onForceGraph, initialPhase, initialTeam, kgId
|
|
|
12228
12373
|
{
|
|
12229
12374
|
onClick: onForceGraph,
|
|
12230
12375
|
style: { display: "block", margin: "16px auto 0", color: "#ff8c42", fontSize: 12, background: "none", border: "1px solid #ff8c4230", padding: "6px 16px", borderRadius: 8, cursor: "pointer" },
|
|
12231
|
-
children: "Show
|
|
12376
|
+
children: "Show graph \u203A"
|
|
12232
12377
|
}
|
|
12233
12378
|
)
|
|
12234
12379
|
] })
|
|
@@ -15685,7 +15830,7 @@ function CheckpointCard({
|
|
|
15685
15830
|
style: { backgroundColor: `${config.color}20`, color: config.color, border: `1px solid ${config.color}30` },
|
|
15686
15831
|
children: [
|
|
15687
15832
|
config.proceedLabel,
|
|
15688
|
-
" \
|
|
15833
|
+
" \u203A"
|
|
15689
15834
|
]
|
|
15690
15835
|
}
|
|
15691
15836
|
)
|
|
@@ -15801,6 +15946,7 @@ exports.SSE_KEEPALIVE_MS = SSE_KEEPALIVE_MS;
|
|
|
15801
15946
|
exports.SSE_STALL_MS = SSE_STALL_MS;
|
|
15802
15947
|
exports.SYNTHESIS_DONE_SIGNAL = SYNTHESIS_DONE_SIGNAL;
|
|
15803
15948
|
exports.ScopedReasoningProvider = ScopedReasoningProvider;
|
|
15949
|
+
exports.ScreenAwake = ScreenAwake;
|
|
15804
15950
|
exports.SettlementBar = SettlementBar;
|
|
15805
15951
|
exports.SlashMentionPicker = SlashMentionPicker;
|
|
15806
15952
|
exports.StageCanvas = StageCanvas;
|
package/dist/index.d.cts
CHANGED
|
@@ -639,7 +639,7 @@ interface AgentToolStep {
|
|
|
639
639
|
ms: number;
|
|
640
640
|
}
|
|
641
641
|
interface AgentCompletion {
|
|
642
|
-
stop_reason: 'answered' | 'rounds_exhausted' | 'budget_exhausted' | 'empty' | 'failed' | 'interrupted' | 'cancelled' | 'awaiting_tool_results';
|
|
642
|
+
stop_reason: 'answered' | 'rounds_exhausted' | 'budget_exhausted' | 'empty' | 'output_limit' | 'deadline' | 'failed' | 'interrupted' | 'cancelled' | 'awaiting_tool_results';
|
|
643
643
|
truncated?: boolean;
|
|
644
644
|
rounds_used?: number;
|
|
645
645
|
prompt_tokens?: number;
|
|
@@ -1477,6 +1477,8 @@ declare class VoiceSession {
|
|
|
1477
1477
|
private ready;
|
|
1478
1478
|
private ended;
|
|
1479
1479
|
private phase;
|
|
1480
|
+
/** Keeps a phone from locking mid-conversation (see `screenAwake.ts`). */
|
|
1481
|
+
private readonly awake;
|
|
1480
1482
|
/** The voice's questions to the host, one at a time (see `askQueue.ts`). */
|
|
1481
1483
|
private readonly asks;
|
|
1482
1484
|
private heard;
|
|
@@ -1484,12 +1486,22 @@ declare class VoiceSession {
|
|
|
1484
1486
|
private saying;
|
|
1485
1487
|
private endingReason;
|
|
1486
1488
|
private finishTimer;
|
|
1489
|
+
private muted;
|
|
1487
1490
|
private blobUrl;
|
|
1488
1491
|
constructor(h: VoiceHandlers, connection: VoiceConnection);
|
|
1489
1492
|
/** Call from the tap itself: iOS only lets audio start inside a gesture,
|
|
1490
1493
|
* so the AudioContext is created before the first `await`. */
|
|
1491
1494
|
start(): Promise<void>;
|
|
1492
1495
|
stop(): void;
|
|
1496
|
+
/**
|
|
1497
|
+
* Mute the microphone, or not. The track goes silent rather than the
|
|
1498
|
+
* stream stopping: the service keeps hearing (silence), so whatever the
|
|
1499
|
+
* person was saying ends as a turn and nothing hangs half-heard. The
|
|
1500
|
+
* voice can still talk while they are muted.
|
|
1501
|
+
*/
|
|
1502
|
+
setMuted(muted: boolean): void;
|
|
1503
|
+
get isMuted(): boolean;
|
|
1504
|
+
private applyMute;
|
|
1493
1505
|
/** Cheap enough to call every animation frame. */
|
|
1494
1506
|
levels(): VoiceLevels;
|
|
1495
1507
|
private setPhase;
|
|
@@ -1532,6 +1544,9 @@ interface VoiceSessionState {
|
|
|
1532
1544
|
level: () => number;
|
|
1533
1545
|
/** For `VoiceInputButton`. */
|
|
1534
1546
|
buttonState: VoiceButtonState;
|
|
1547
|
+
/** The microphone is muted (the voice can still talk). */
|
|
1548
|
+
muted: boolean;
|
|
1549
|
+
toggleMute: () => void;
|
|
1535
1550
|
start: () => void;
|
|
1536
1551
|
stop: () => void;
|
|
1537
1552
|
toggle: () => void;
|
|
@@ -1577,6 +1592,13 @@ interface VoiceDeckProps {
|
|
|
1577
1592
|
phone?: boolean;
|
|
1578
1593
|
/** What to show before anything has been said. */
|
|
1579
1594
|
hint?: string;
|
|
1595
|
+
/** Take the whole height it is given (a phone, where the transcript
|
|
1596
|
+
* behind it is too small to read): a taller band, and `children` in a
|
|
1597
|
+
* scrolling area beneath the live words. */
|
|
1598
|
+
fill?: boolean;
|
|
1599
|
+
/** What the host has worth reading while the voice runs — its agent's
|
|
1600
|
+
* steps, the answer and its sources. Shown with `fill`. */
|
|
1601
|
+
children?: React.ReactNode;
|
|
1580
1602
|
}
|
|
1581
1603
|
/**
|
|
1582
1604
|
* Live voice, above a composer: a band that weaves the conversation into
|
|
@@ -1588,7 +1610,7 @@ interface VoiceDeckProps {
|
|
|
1588
1610
|
* Styled from the terminal theme (`TerminalThemeProvider`): render it inside
|
|
1589
1611
|
* the same provider as your input bar.
|
|
1590
1612
|
*/
|
|
1591
|
-
declare function VoiceDeck({ voice, name, phone, hint }: VoiceDeckProps): react_jsx_runtime.JSX.Element;
|
|
1613
|
+
declare function VoiceDeck({ voice, name, phone, hint, fill, children }: VoiceDeckProps): react_jsx_runtime.JSX.Element;
|
|
1592
1614
|
|
|
1593
1615
|
/**
|
|
1594
1616
|
* The voice's questions to the host, one at a time.
|
|
@@ -1626,6 +1648,40 @@ declare class AskQueue<A extends QueuedAsk> {
|
|
|
1626
1648
|
private next;
|
|
1627
1649
|
}
|
|
1628
1650
|
|
|
1651
|
+
/**
|
|
1652
|
+
* Keeps the screen on while a voice session runs.
|
|
1653
|
+
*
|
|
1654
|
+
* A phone that locks mid-conversation suspends the page — on iOS the
|
|
1655
|
+
* microphone stops and the session ends — so a live session holds a Screen
|
|
1656
|
+
* Wake Lock (`navigator.wakeLock`) from the tap that starts it until it ends.
|
|
1657
|
+
* The browser drops the lock whenever the page is hidden (another app, the
|
|
1658
|
+
* tab switcher), so it is taken again when the page is visible again, as
|
|
1659
|
+
* long as the session is still on. Where the API is missing or refuses
|
|
1660
|
+
* (battery saver, policy), the screen simply locks as it always did.
|
|
1661
|
+
*/
|
|
1662
|
+
interface Sentinel {
|
|
1663
|
+
readonly released?: boolean;
|
|
1664
|
+
release(): Promise<void>;
|
|
1665
|
+
}
|
|
1666
|
+
interface WakeLockApi {
|
|
1667
|
+
request(type: 'screen'): Promise<Sentinel>;
|
|
1668
|
+
}
|
|
1669
|
+
declare class ScreenAwake {
|
|
1670
|
+
private readonly api;
|
|
1671
|
+
private sentinel;
|
|
1672
|
+
private wanted;
|
|
1673
|
+
private requesting;
|
|
1674
|
+
private readonly onVisibility;
|
|
1675
|
+
constructor(api?: WakeLockApi | undefined);
|
|
1676
|
+
/** The screen is being kept on right now. */
|
|
1677
|
+
get held(): boolean;
|
|
1678
|
+
/** Keep the screen on until `release`. Call it from the tap that starts
|
|
1679
|
+
* the session. */
|
|
1680
|
+
hold(): void;
|
|
1681
|
+
release(): void;
|
|
1682
|
+
private take;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1629
1685
|
/**
|
|
1630
1686
|
* The microphone capture AudioWorklet, as source.
|
|
1631
1687
|
*
|
|
@@ -2909,4 +2965,4 @@ declare const terminalClassNames: {
|
|
|
2909
2965
|
promptSymbol: string;
|
|
2910
2966
|
};
|
|
2911
2967
|
|
|
2912
|
-
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, type AIAction, type ActivityItem, AgentAvatar, type AgentAvatarProps, type AgentAvatarSize, type AgentCompletion, AgentPresenceBar, AgentStepTrace, type AgentToolStep, type Annotation, AnnotationThread, type ApiEndpoint, type ApiParameter, AskQueue, type BaseTerminalProps, CLAIM_STATUS_COLORS, ChatTerminal, type ChatTerminalProps, CheckpointCard, type CheckpointType, ClaimNode, type ClaimNodeData, type ClaimStatus, ConstructionProgress, CoreTerminal, type CoreTerminalProps, type CreateNoteResult, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, type DocumentProcessingEvent, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, type CoreTerminalProps as EmbeddedTerminalProps, ExpandableTerminal, type ExpandableTerminalProps, type FileUploadResult, type GapOption, type GapQuestion, type GenericKGSnapshot, type GenericSnapshotEdge, type GenericSnapshotNode, GraphChatPanel, type GraphChatPanelProps, GraphEdge, type GraphEdgeData, type GraphLayer, GraphNode, type GraphNodeData, type HelpTopic, InlineTerminal, type InlineTerminalProps, type KGAnnotation, type KGChunkLink$1 as KGChunkLink, type KGScope, type KGSearchResult, type KGSnapshot, type KGSnapshotEdge, type KGSnapshotNode, type KnowledgeGraphDataCallbacks, KnowledgeGraphView, LIVE_KG_ID, type LegacyKGSnapshot, type LegacyKGSnapshotEdge, type LegacyKGSnapshotNode, type LineageEntry, type ListRagFilesResult, type ListedRagFile, LiveActivityTicker, MarkdownContent, MarkdownEditor, type Mention, type MentionTarget, type MessageAudience, type MessageSender, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, type PageSuggestion, type ParsedCommand, type PipelineBuilderAction, type PipelineDraft, type PipelineDraftStep, PipelineProgressBar, type PluginContext, type ProcessingDetail, type ProgressEventDetail, type ProgressState, type QueuedAsk, REPLACED_OUTPUT, type RagFileActionResult, ReasoningHistoryCard, ReasoningOverlay, type ReasoningOverlayProps, type ReasoningProgressEvent, type ReasoningSnapshot, ReasoningView, type ReasoningViewProps, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, type SaveNoteResult, ScopedReasoningProvider, SettlementBar, type SlashMentionCandidate, SlashMentionPicker, StageCanvas, StandardTerminal, type StandardTerminalProps, type StreamChunk, type StreamHandler, type StreamHandlers, type SubgraphEdge, type SubgraphNode, type TeamSetupAgent, type TerminalCommand, type TerminalCommandResult, type TerminalConfig, type TerminalEntry, TerminalInputBar, type TerminalInputBarProps, type TerminalPlugin, type TerminalSlots, type TerminalSource, type TerminalTheme, TerminalThemeProvider, type TerminalWidget, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, type VoiceButtonState, type VoiceConnection, VoiceDeck, type VoiceDeckProps, type VoiceEndReason, type VoiceEnded, type VoiceHandlers, type VoiceHost, VoiceInputButton, type VoiceInputButtonProps, type VoiceLanguage, type VoiceLevels, type VoiceName, type VoicePersona, type VoicePhase, type VoiceProgress, type VoiceReply, VoiceSession, type VoiceSessionState, type VoiceStatus, type VoiceUtterance, type WorkingGroupContext, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|
|
2968
|
+
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, type AIAction, type ActivityItem, AgentAvatar, type AgentAvatarProps, type AgentAvatarSize, type AgentCompletion, AgentPresenceBar, AgentStepTrace, type AgentToolStep, type Annotation, AnnotationThread, type ApiEndpoint, type ApiParameter, AskQueue, type BaseTerminalProps, CLAIM_STATUS_COLORS, ChatTerminal, type ChatTerminalProps, CheckpointCard, type CheckpointType, ClaimNode, type ClaimNodeData, type ClaimStatus, ConstructionProgress, CoreTerminal, type CoreTerminalProps, type CreateNoteResult, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, type DocumentProcessingEvent, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, type CoreTerminalProps as EmbeddedTerminalProps, ExpandableTerminal, type ExpandableTerminalProps, type FileUploadResult, type GapOption, type GapQuestion, type GenericKGSnapshot, type GenericSnapshotEdge, type GenericSnapshotNode, GraphChatPanel, type GraphChatPanelProps, GraphEdge, type GraphEdgeData, type GraphLayer, GraphNode, type GraphNodeData, type HelpTopic, InlineTerminal, type InlineTerminalProps, type KGAnnotation, type KGChunkLink$1 as KGChunkLink, type KGScope, type KGSearchResult, type KGSnapshot, type KGSnapshotEdge, type KGSnapshotNode, type KnowledgeGraphDataCallbacks, KnowledgeGraphView, LIVE_KG_ID, type LegacyKGSnapshot, type LegacyKGSnapshotEdge, type LegacyKGSnapshotNode, type LineageEntry, type ListRagFilesResult, type ListedRagFile, LiveActivityTicker, MarkdownContent, MarkdownEditor, type Mention, type MentionTarget, type MessageAudience, type MessageSender, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, type PageSuggestion, type ParsedCommand, type PipelineBuilderAction, type PipelineDraft, type PipelineDraftStep, PipelineProgressBar, type PluginContext, type ProcessingDetail, type ProgressEventDetail, type ProgressState, type QueuedAsk, REPLACED_OUTPUT, type RagFileActionResult, ReasoningHistoryCard, ReasoningOverlay, type ReasoningOverlayProps, type ReasoningProgressEvent, type ReasoningSnapshot, ReasoningView, type ReasoningViewProps, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, type SaveNoteResult, ScopedReasoningProvider, ScreenAwake, SettlementBar, type SlashMentionCandidate, SlashMentionPicker, StageCanvas, StandardTerminal, type StandardTerminalProps, type StreamChunk, type StreamHandler, type StreamHandlers, type SubgraphEdge, type SubgraphNode, type TeamSetupAgent, type TerminalCommand, type TerminalCommandResult, type TerminalConfig, type TerminalEntry, TerminalInputBar, type TerminalInputBarProps, type TerminalPlugin, type TerminalSlots, type TerminalSource, type TerminalTheme, TerminalThemeProvider, type TerminalWidget, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, type VoiceButtonState, type VoiceConnection, VoiceDeck, type VoiceDeckProps, type VoiceEndReason, type VoiceEnded, type VoiceHandlers, type VoiceHost, VoiceInputButton, type VoiceInputButtonProps, type VoiceLanguage, type VoiceLevels, type VoiceName, type VoicePersona, type VoicePhase, type VoiceProgress, type VoiceReply, VoiceSession, type VoiceSessionState, type VoiceStatus, type VoiceUtterance, type WorkingGroupContext, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|
package/dist/index.d.ts
CHANGED
|
@@ -639,7 +639,7 @@ interface AgentToolStep {
|
|
|
639
639
|
ms: number;
|
|
640
640
|
}
|
|
641
641
|
interface AgentCompletion {
|
|
642
|
-
stop_reason: 'answered' | 'rounds_exhausted' | 'budget_exhausted' | 'empty' | 'failed' | 'interrupted' | 'cancelled' | 'awaiting_tool_results';
|
|
642
|
+
stop_reason: 'answered' | 'rounds_exhausted' | 'budget_exhausted' | 'empty' | 'output_limit' | 'deadline' | 'failed' | 'interrupted' | 'cancelled' | 'awaiting_tool_results';
|
|
643
643
|
truncated?: boolean;
|
|
644
644
|
rounds_used?: number;
|
|
645
645
|
prompt_tokens?: number;
|
|
@@ -1477,6 +1477,8 @@ declare class VoiceSession {
|
|
|
1477
1477
|
private ready;
|
|
1478
1478
|
private ended;
|
|
1479
1479
|
private phase;
|
|
1480
|
+
/** Keeps a phone from locking mid-conversation (see `screenAwake.ts`). */
|
|
1481
|
+
private readonly awake;
|
|
1480
1482
|
/** The voice's questions to the host, one at a time (see `askQueue.ts`). */
|
|
1481
1483
|
private readonly asks;
|
|
1482
1484
|
private heard;
|
|
@@ -1484,12 +1486,22 @@ declare class VoiceSession {
|
|
|
1484
1486
|
private saying;
|
|
1485
1487
|
private endingReason;
|
|
1486
1488
|
private finishTimer;
|
|
1489
|
+
private muted;
|
|
1487
1490
|
private blobUrl;
|
|
1488
1491
|
constructor(h: VoiceHandlers, connection: VoiceConnection);
|
|
1489
1492
|
/** Call from the tap itself: iOS only lets audio start inside a gesture,
|
|
1490
1493
|
* so the AudioContext is created before the first `await`. */
|
|
1491
1494
|
start(): Promise<void>;
|
|
1492
1495
|
stop(): void;
|
|
1496
|
+
/**
|
|
1497
|
+
* Mute the microphone, or not. The track goes silent rather than the
|
|
1498
|
+
* stream stopping: the service keeps hearing (silence), so whatever the
|
|
1499
|
+
* person was saying ends as a turn and nothing hangs half-heard. The
|
|
1500
|
+
* voice can still talk while they are muted.
|
|
1501
|
+
*/
|
|
1502
|
+
setMuted(muted: boolean): void;
|
|
1503
|
+
get isMuted(): boolean;
|
|
1504
|
+
private applyMute;
|
|
1493
1505
|
/** Cheap enough to call every animation frame. */
|
|
1494
1506
|
levels(): VoiceLevels;
|
|
1495
1507
|
private setPhase;
|
|
@@ -1532,6 +1544,9 @@ interface VoiceSessionState {
|
|
|
1532
1544
|
level: () => number;
|
|
1533
1545
|
/** For `VoiceInputButton`. */
|
|
1534
1546
|
buttonState: VoiceButtonState;
|
|
1547
|
+
/** The microphone is muted (the voice can still talk). */
|
|
1548
|
+
muted: boolean;
|
|
1549
|
+
toggleMute: () => void;
|
|
1535
1550
|
start: () => void;
|
|
1536
1551
|
stop: () => void;
|
|
1537
1552
|
toggle: () => void;
|
|
@@ -1577,6 +1592,13 @@ interface VoiceDeckProps {
|
|
|
1577
1592
|
phone?: boolean;
|
|
1578
1593
|
/** What to show before anything has been said. */
|
|
1579
1594
|
hint?: string;
|
|
1595
|
+
/** Take the whole height it is given (a phone, where the transcript
|
|
1596
|
+
* behind it is too small to read): a taller band, and `children` in a
|
|
1597
|
+
* scrolling area beneath the live words. */
|
|
1598
|
+
fill?: boolean;
|
|
1599
|
+
/** What the host has worth reading while the voice runs — its agent's
|
|
1600
|
+
* steps, the answer and its sources. Shown with `fill`. */
|
|
1601
|
+
children?: React.ReactNode;
|
|
1580
1602
|
}
|
|
1581
1603
|
/**
|
|
1582
1604
|
* Live voice, above a composer: a band that weaves the conversation into
|
|
@@ -1588,7 +1610,7 @@ interface VoiceDeckProps {
|
|
|
1588
1610
|
* Styled from the terminal theme (`TerminalThemeProvider`): render it inside
|
|
1589
1611
|
* the same provider as your input bar.
|
|
1590
1612
|
*/
|
|
1591
|
-
declare function VoiceDeck({ voice, name, phone, hint }: VoiceDeckProps): react_jsx_runtime.JSX.Element;
|
|
1613
|
+
declare function VoiceDeck({ voice, name, phone, hint, fill, children }: VoiceDeckProps): react_jsx_runtime.JSX.Element;
|
|
1592
1614
|
|
|
1593
1615
|
/**
|
|
1594
1616
|
* The voice's questions to the host, one at a time.
|
|
@@ -1626,6 +1648,40 @@ declare class AskQueue<A extends QueuedAsk> {
|
|
|
1626
1648
|
private next;
|
|
1627
1649
|
}
|
|
1628
1650
|
|
|
1651
|
+
/**
|
|
1652
|
+
* Keeps the screen on while a voice session runs.
|
|
1653
|
+
*
|
|
1654
|
+
* A phone that locks mid-conversation suspends the page — on iOS the
|
|
1655
|
+
* microphone stops and the session ends — so a live session holds a Screen
|
|
1656
|
+
* Wake Lock (`navigator.wakeLock`) from the tap that starts it until it ends.
|
|
1657
|
+
* The browser drops the lock whenever the page is hidden (another app, the
|
|
1658
|
+
* tab switcher), so it is taken again when the page is visible again, as
|
|
1659
|
+
* long as the session is still on. Where the API is missing or refuses
|
|
1660
|
+
* (battery saver, policy), the screen simply locks as it always did.
|
|
1661
|
+
*/
|
|
1662
|
+
interface Sentinel {
|
|
1663
|
+
readonly released?: boolean;
|
|
1664
|
+
release(): Promise<void>;
|
|
1665
|
+
}
|
|
1666
|
+
interface WakeLockApi {
|
|
1667
|
+
request(type: 'screen'): Promise<Sentinel>;
|
|
1668
|
+
}
|
|
1669
|
+
declare class ScreenAwake {
|
|
1670
|
+
private readonly api;
|
|
1671
|
+
private sentinel;
|
|
1672
|
+
private wanted;
|
|
1673
|
+
private requesting;
|
|
1674
|
+
private readonly onVisibility;
|
|
1675
|
+
constructor(api?: WakeLockApi | undefined);
|
|
1676
|
+
/** The screen is being kept on right now. */
|
|
1677
|
+
get held(): boolean;
|
|
1678
|
+
/** Keep the screen on until `release`. Call it from the tap that starts
|
|
1679
|
+
* the session. */
|
|
1680
|
+
hold(): void;
|
|
1681
|
+
release(): void;
|
|
1682
|
+
private take;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1629
1685
|
/**
|
|
1630
1686
|
* The microphone capture AudioWorklet, as source.
|
|
1631
1687
|
*
|
|
@@ -2909,4 +2965,4 @@ declare const terminalClassNames: {
|
|
|
2909
2965
|
promptSymbol: string;
|
|
2910
2966
|
};
|
|
2911
2967
|
|
|
2912
|
-
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, type AIAction, type ActivityItem, AgentAvatar, type AgentAvatarProps, type AgentAvatarSize, type AgentCompletion, AgentPresenceBar, AgentStepTrace, type AgentToolStep, type Annotation, AnnotationThread, type ApiEndpoint, type ApiParameter, AskQueue, type BaseTerminalProps, CLAIM_STATUS_COLORS, ChatTerminal, type ChatTerminalProps, CheckpointCard, type CheckpointType, ClaimNode, type ClaimNodeData, type ClaimStatus, ConstructionProgress, CoreTerminal, type CoreTerminalProps, type CreateNoteResult, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, type DocumentProcessingEvent, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, type CoreTerminalProps as EmbeddedTerminalProps, ExpandableTerminal, type ExpandableTerminalProps, type FileUploadResult, type GapOption, type GapQuestion, type GenericKGSnapshot, type GenericSnapshotEdge, type GenericSnapshotNode, GraphChatPanel, type GraphChatPanelProps, GraphEdge, type GraphEdgeData, type GraphLayer, GraphNode, type GraphNodeData, type HelpTopic, InlineTerminal, type InlineTerminalProps, type KGAnnotation, type KGChunkLink$1 as KGChunkLink, type KGScope, type KGSearchResult, type KGSnapshot, type KGSnapshotEdge, type KGSnapshotNode, type KnowledgeGraphDataCallbacks, KnowledgeGraphView, LIVE_KG_ID, type LegacyKGSnapshot, type LegacyKGSnapshotEdge, type LegacyKGSnapshotNode, type LineageEntry, type ListRagFilesResult, type ListedRagFile, LiveActivityTicker, MarkdownContent, MarkdownEditor, type Mention, type MentionTarget, type MessageAudience, type MessageSender, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, type PageSuggestion, type ParsedCommand, type PipelineBuilderAction, type PipelineDraft, type PipelineDraftStep, PipelineProgressBar, type PluginContext, type ProcessingDetail, type ProgressEventDetail, type ProgressState, type QueuedAsk, REPLACED_OUTPUT, type RagFileActionResult, ReasoningHistoryCard, ReasoningOverlay, type ReasoningOverlayProps, type ReasoningProgressEvent, type ReasoningSnapshot, ReasoningView, type ReasoningViewProps, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, type SaveNoteResult, ScopedReasoningProvider, SettlementBar, type SlashMentionCandidate, SlashMentionPicker, StageCanvas, StandardTerminal, type StandardTerminalProps, type StreamChunk, type StreamHandler, type StreamHandlers, type SubgraphEdge, type SubgraphNode, type TeamSetupAgent, type TerminalCommand, type TerminalCommandResult, type TerminalConfig, type TerminalEntry, TerminalInputBar, type TerminalInputBarProps, type TerminalPlugin, type TerminalSlots, type TerminalSource, type TerminalTheme, TerminalThemeProvider, type TerminalWidget, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, type VoiceButtonState, type VoiceConnection, VoiceDeck, type VoiceDeckProps, type VoiceEndReason, type VoiceEnded, type VoiceHandlers, type VoiceHost, VoiceInputButton, type VoiceInputButtonProps, type VoiceLanguage, type VoiceLevels, type VoiceName, type VoicePersona, type VoicePhase, type VoiceProgress, type VoiceReply, VoiceSession, type VoiceSessionState, type VoiceStatus, type VoiceUtterance, type WorkingGroupContext, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|
|
2968
|
+
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, type AIAction, type ActivityItem, AgentAvatar, type AgentAvatarProps, type AgentAvatarSize, type AgentCompletion, AgentPresenceBar, AgentStepTrace, type AgentToolStep, type Annotation, AnnotationThread, type ApiEndpoint, type ApiParameter, AskQueue, type BaseTerminalProps, CLAIM_STATUS_COLORS, ChatTerminal, type ChatTerminalProps, CheckpointCard, type CheckpointType, ClaimNode, type ClaimNodeData, type ClaimStatus, ConstructionProgress, CoreTerminal, type CoreTerminalProps, type CreateNoteResult, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, type DocumentProcessingEvent, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, type CoreTerminalProps as EmbeddedTerminalProps, ExpandableTerminal, type ExpandableTerminalProps, type FileUploadResult, type GapOption, type GapQuestion, type GenericKGSnapshot, type GenericSnapshotEdge, type GenericSnapshotNode, GraphChatPanel, type GraphChatPanelProps, GraphEdge, type GraphEdgeData, type GraphLayer, GraphNode, type GraphNodeData, type HelpTopic, InlineTerminal, type InlineTerminalProps, type KGAnnotation, type KGChunkLink$1 as KGChunkLink, type KGScope, type KGSearchResult, type KGSnapshot, type KGSnapshotEdge, type KGSnapshotNode, type KnowledgeGraphDataCallbacks, KnowledgeGraphView, LIVE_KG_ID, type LegacyKGSnapshot, type LegacyKGSnapshotEdge, type LegacyKGSnapshotNode, type LineageEntry, type ListRagFilesResult, type ListedRagFile, LiveActivityTicker, MarkdownContent, MarkdownEditor, type Mention, type MentionTarget, type MessageAudience, type MessageSender, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, type PageSuggestion, type ParsedCommand, type PipelineBuilderAction, type PipelineDraft, type PipelineDraftStep, PipelineProgressBar, type PluginContext, type ProcessingDetail, type ProgressEventDetail, type ProgressState, type QueuedAsk, REPLACED_OUTPUT, type RagFileActionResult, ReasoningHistoryCard, ReasoningOverlay, type ReasoningOverlayProps, type ReasoningProgressEvent, type ReasoningSnapshot, ReasoningView, type ReasoningViewProps, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, type SaveNoteResult, ScopedReasoningProvider, ScreenAwake, SettlementBar, type SlashMentionCandidate, SlashMentionPicker, StageCanvas, StandardTerminal, type StandardTerminalProps, type StreamChunk, type StreamHandler, type StreamHandlers, type SubgraphEdge, type SubgraphNode, type TeamSetupAgent, type TerminalCommand, type TerminalCommandResult, type TerminalConfig, type TerminalEntry, TerminalInputBar, type TerminalInputBarProps, type TerminalPlugin, type TerminalSlots, type TerminalSource, type TerminalTheme, TerminalThemeProvider, type TerminalWidget, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, type VoiceButtonState, type VoiceConnection, VoiceDeck, type VoiceDeckProps, type VoiceEndReason, type VoiceEnded, type VoiceHandlers, type VoiceHost, VoiceInputButton, type VoiceInputButtonProps, type VoiceLanguage, type VoiceLevels, type VoiceName, type VoicePersona, type VoicePhase, type VoiceProgress, type VoiceReply, VoiceSession, type VoiceSessionState, type VoiceStatus, type VoiceUtterance, type WorkingGroupContext, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Runtime use requires a separate express license.
|
|
7
7
|
*/
|
|
8
8
|
import React15, { createContext, memo, useMemo, useRef, useEffect, useCallback, useContext, useState, useReducer } from 'react';
|
|
9
|
-
import { X, Check, Plus, FileText, MessageCircle, ChevronRight, Paperclip, FolderOpen, Brain, XCircle, Loader2, Minimize2, Maximize2, Mic, AlertTriangle, HelpCircle, ChevronLeft, Pencil, ChevronDown, ExternalLink, Search, Network, Boxes, Settings, Terminal, CheckCircle, ArrowRight, Users, Eye, AlertCircle, CheckCircle2, Copy, Zap, Download, Trash2, Link2 } from 'lucide-react';
|
|
9
|
+
import { X, Check, Plus, FileText, MessageCircle, ChevronRight, Paperclip, FolderOpen, Brain, XCircle, Loader2, Minimize2, Maximize2, Mic, MicOff, AlertTriangle, HelpCircle, ChevronLeft, Pencil, ChevronDown, ExternalLink, Search, Network, Boxes, Settings, Terminal, CheckCircle, ArrowRight, Users, Eye, AlertCircle, CheckCircle2, Copy, Zap, Download, Trash2, Link2 } from 'lucide-react';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
11
|
import ReactMarkdown from 'react-markdown';
|
|
12
12
|
import remarkGfm from 'remark-gfm';
|
|
@@ -2225,18 +2225,21 @@ function CopyButton({ content }) {
|
|
|
2225
2225
|
}
|
|
2226
2226
|
);
|
|
2227
2227
|
}
|
|
2228
|
+
var MESSAGES = {
|
|
2229
|
+
rounds_exhausted: "Partial answer \u2014 I reached the step limit. Ask a narrower follow-up to continue.",
|
|
2230
|
+
budget_exhausted: "Partial answer \u2014 this question needs more context than fits in one answer. Try narrowing the question.",
|
|
2231
|
+
deadline: "Partial answer \u2014 I ran out of time before finishing. Ask a narrower follow-up to continue.",
|
|
2232
|
+
output_limit: "Partial answer \u2014 it was cut off at its length limit. Ask for the rest, or a narrower follow-up.",
|
|
2233
|
+
awaiting_tool_results: "This answer paused before its next step. Ask again to review a fresh answer.",
|
|
2234
|
+
empty: "No answer was returned. Please try again.",
|
|
2235
|
+
failed: "The answer could not be completed. What arrived so far is kept here.",
|
|
2236
|
+
interrupted: "Connection interrupted. The assistant may still be working; check the conversation before sending again.",
|
|
2237
|
+
cancelled: "Stopped. You can change your question and ask again."
|
|
2238
|
+
};
|
|
2228
2239
|
function AgentCompletionNotice({ completion }) {
|
|
2229
2240
|
const t = useTheme();
|
|
2230
2241
|
if (!completion || completion.stop_reason === "answered") return null;
|
|
2231
|
-
const message =
|
|
2232
|
-
rounds_exhausted: "Partial answer \u2014 I reached the step limit. Ask a narrower follow-up to continue.",
|
|
2233
|
-
budget_exhausted: "Partial answer \u2014 this question needs more context than fits in one answer. Try narrowing the question.",
|
|
2234
|
-
awaiting_tool_results: "This answer paused before its next step. Ask again to review a fresh answer.",
|
|
2235
|
-
empty: "No answer was returned. Please try again.",
|
|
2236
|
-
failed: "The answer could not be completed. What arrived so far is kept here.",
|
|
2237
|
-
interrupted: "Connection interrupted. The assistant may still be working; check the conversation before sending again.",
|
|
2238
|
-
cancelled: "Stopped. You can change your question and ask again."
|
|
2239
|
-
}[completion.stop_reason];
|
|
2242
|
+
const message = MESSAGES[completion.stop_reason];
|
|
2240
2243
|
if (!message) return null;
|
|
2241
2244
|
return /* @__PURE__ */ jsx("p", { role: "status", className: "mt-2 rounded-md px-3 py-2 text-xs", style: { color: t.textSecondary, backgroundColor: t.bgRaisedAlt, border: `1px solid ${t.border}` }, children: message });
|
|
2242
2245
|
}
|
|
@@ -7847,6 +7850,54 @@ function encodePersona(persona) {
|
|
|
7847
7850
|
return Object.keys(fields).length ? JSON.stringify(fields) : null;
|
|
7848
7851
|
}
|
|
7849
7852
|
|
|
7853
|
+
// src/voice/screenAwake.ts
|
|
7854
|
+
function browserWakeLock() {
|
|
7855
|
+
return typeof navigator === "undefined" ? void 0 : navigator.wakeLock;
|
|
7856
|
+
}
|
|
7857
|
+
var ScreenAwake = class {
|
|
7858
|
+
constructor(api = browserWakeLock()) {
|
|
7859
|
+
this.api = api;
|
|
7860
|
+
this.sentinel = null;
|
|
7861
|
+
this.wanted = false;
|
|
7862
|
+
this.requesting = false;
|
|
7863
|
+
this.onVisibility = () => {
|
|
7864
|
+
if (document.visibilityState === "visible") void this.take();
|
|
7865
|
+
};
|
|
7866
|
+
}
|
|
7867
|
+
/** The screen is being kept on right now. */
|
|
7868
|
+
get held() {
|
|
7869
|
+
return !!this.sentinel && !this.sentinel.released;
|
|
7870
|
+
}
|
|
7871
|
+
/** Keep the screen on until `release`. Call it from the tap that starts
|
|
7872
|
+
* the session. */
|
|
7873
|
+
hold() {
|
|
7874
|
+
if (!this.api || this.wanted) return;
|
|
7875
|
+
this.wanted = true;
|
|
7876
|
+
document.addEventListener("visibilitychange", this.onVisibility);
|
|
7877
|
+
void this.take();
|
|
7878
|
+
}
|
|
7879
|
+
release() {
|
|
7880
|
+
if (!this.wanted) return;
|
|
7881
|
+
this.wanted = false;
|
|
7882
|
+
document.removeEventListener("visibilitychange", this.onVisibility);
|
|
7883
|
+
const sentinel = this.sentinel;
|
|
7884
|
+
this.sentinel = null;
|
|
7885
|
+
void sentinel?.release().catch(() => void 0);
|
|
7886
|
+
}
|
|
7887
|
+
async take() {
|
|
7888
|
+
if (!this.api || !this.wanted || this.held || this.requesting || document.visibilityState !== "visible") return;
|
|
7889
|
+
this.requesting = true;
|
|
7890
|
+
try {
|
|
7891
|
+
const sentinel = await this.api.request("screen");
|
|
7892
|
+
if (this.wanted) this.sentinel = sentinel;
|
|
7893
|
+
else void sentinel.release().catch(() => void 0);
|
|
7894
|
+
} catch {
|
|
7895
|
+
} finally {
|
|
7896
|
+
this.requesting = false;
|
|
7897
|
+
}
|
|
7898
|
+
}
|
|
7899
|
+
};
|
|
7900
|
+
|
|
7850
7901
|
// src/voice/worklet.ts
|
|
7851
7902
|
var VOICE_CAPTURE_WORKLET_SOURCE = `class YfVoiceCapture extends AudioWorkletProcessor {
|
|
7852
7903
|
constructor() {
|
|
@@ -7982,6 +8033,8 @@ var VoiceSession = class {
|
|
|
7982
8033
|
this.ready = false;
|
|
7983
8034
|
this.ended = false;
|
|
7984
8035
|
this.phase = null;
|
|
8036
|
+
/** Keeps a phone from locking mid-conversation (see `screenAwake.ts`). */
|
|
8037
|
+
this.awake = new ScreenAwake();
|
|
7985
8038
|
/** The voice's questions to the host, one at a time (see `askQueue.ts`). */
|
|
7986
8039
|
this.asks = new AskQueue(
|
|
7987
8040
|
(ask, signal) => {
|
|
@@ -8004,6 +8057,7 @@ var VoiceSession = class {
|
|
|
8004
8057
|
this.saying = "";
|
|
8005
8058
|
this.endingReason = null;
|
|
8006
8059
|
this.finishTimer = null;
|
|
8060
|
+
this.muted = false;
|
|
8007
8061
|
this.blobUrl = null;
|
|
8008
8062
|
}
|
|
8009
8063
|
/** Call from the tap itself: iOS only lets audio start inside a gesture,
|
|
@@ -8017,6 +8071,7 @@ var VoiceSession = class {
|
|
|
8017
8071
|
const ctx = new Ctx();
|
|
8018
8072
|
this.ctx = ctx;
|
|
8019
8073
|
void ctx.resume();
|
|
8074
|
+
this.awake.hold();
|
|
8020
8075
|
this.setPhase("connecting");
|
|
8021
8076
|
const status = await getVoiceStatus(this.connection);
|
|
8022
8077
|
if (this.ended) return;
|
|
@@ -8032,6 +8087,7 @@ var VoiceSession = class {
|
|
|
8032
8087
|
this.stream = await navigator.mediaDevices.getUserMedia({
|
|
8033
8088
|
audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true, autoGainControl: true }
|
|
8034
8089
|
});
|
|
8090
|
+
this.applyMute();
|
|
8035
8091
|
} catch (e) {
|
|
8036
8092
|
this.end("mic_denied", e?.message);
|
|
8037
8093
|
return;
|
|
@@ -8103,6 +8159,24 @@ var VoiceSession = class {
|
|
|
8103
8159
|
stop() {
|
|
8104
8160
|
this.end("stopped");
|
|
8105
8161
|
}
|
|
8162
|
+
/**
|
|
8163
|
+
* Mute the microphone, or not. The track goes silent rather than the
|
|
8164
|
+
* stream stopping: the service keeps hearing (silence), so whatever the
|
|
8165
|
+
* person was saying ends as a turn and nothing hangs half-heard. The
|
|
8166
|
+
* voice can still talk while they are muted.
|
|
8167
|
+
*/
|
|
8168
|
+
setMuted(muted) {
|
|
8169
|
+
this.muted = muted;
|
|
8170
|
+
this.applyMute();
|
|
8171
|
+
}
|
|
8172
|
+
get isMuted() {
|
|
8173
|
+
return this.muted;
|
|
8174
|
+
}
|
|
8175
|
+
applyMute() {
|
|
8176
|
+
this.stream?.getAudioTracks().forEach((track) => {
|
|
8177
|
+
track.enabled = !this.muted;
|
|
8178
|
+
});
|
|
8179
|
+
}
|
|
8106
8180
|
/** Cheap enough to call every animation frame. */
|
|
8107
8181
|
levels() {
|
|
8108
8182
|
if (this.ended) return SILENT;
|
|
@@ -8226,6 +8300,7 @@ var VoiceSession = class {
|
|
|
8226
8300
|
this.finishTimer = null;
|
|
8227
8301
|
}
|
|
8228
8302
|
release() {
|
|
8303
|
+
this.awake.release();
|
|
8229
8304
|
this.node?.port.close();
|
|
8230
8305
|
this.node?.disconnect();
|
|
8231
8306
|
this.stream?.getTracks().forEach((t) => t.stop());
|
|
@@ -8320,6 +8395,7 @@ function useVoiceSession(host, connection) {
|
|
|
8320
8395
|
const [saying, setSaying] = useState("");
|
|
8321
8396
|
const [ended, setEnded] = useState(null);
|
|
8322
8397
|
const [startedAt, setStartedAt] = useState(null);
|
|
8398
|
+
const [muted, setMuted] = useState(false);
|
|
8323
8399
|
const session = useRef(null);
|
|
8324
8400
|
const hostRef = useRef(host);
|
|
8325
8401
|
hostRef.current = host;
|
|
@@ -8342,6 +8418,7 @@ function useVoiceSession(host, connection) {
|
|
|
8342
8418
|
setHeard("");
|
|
8343
8419
|
setSaying("");
|
|
8344
8420
|
setStartedAt(null);
|
|
8421
|
+
setMuted(false);
|
|
8345
8422
|
const s = new VoiceSession(
|
|
8346
8423
|
{
|
|
8347
8424
|
onPhase: (p) => {
|
|
@@ -8355,6 +8432,7 @@ function useVoiceSession(host, connection) {
|
|
|
8355
8432
|
onReply: (r) => hostRef.current.onReply?.(r),
|
|
8356
8433
|
onEnd: (reason, detail) => {
|
|
8357
8434
|
if (session.current === s) session.current = null;
|
|
8435
|
+
setMuted(false);
|
|
8358
8436
|
setPhase("off");
|
|
8359
8437
|
setStartedAt(null);
|
|
8360
8438
|
setEnded(reason === "stopped" || reason === "finished" ? null : { reason, detail });
|
|
@@ -8368,6 +8446,12 @@ function useVoiceSession(host, connection) {
|
|
|
8368
8446
|
const stop = useCallback(() => session.current?.stop(), []);
|
|
8369
8447
|
const toggle = useCallback(() => session.current ? stop() : start(), [start, stop]);
|
|
8370
8448
|
const dismiss = useCallback(() => setEnded(null), []);
|
|
8449
|
+
const toggleMute = useCallback(() => {
|
|
8450
|
+
const s = session.current;
|
|
8451
|
+
if (!s) return;
|
|
8452
|
+
s.setMuted(!s.isMuted);
|
|
8453
|
+
setMuted(s.isMuted);
|
|
8454
|
+
}, []);
|
|
8371
8455
|
const levels = useCallback(() => session.current?.levels() ?? SILENT, []);
|
|
8372
8456
|
const level = useCallback(() => {
|
|
8373
8457
|
const l = levels();
|
|
@@ -8386,6 +8470,8 @@ function useVoiceSession(host, connection) {
|
|
|
8386
8470
|
levels,
|
|
8387
8471
|
level,
|
|
8388
8472
|
buttonState: phase === "off" ? "off" : phase === "connecting" ? "connecting" : "live",
|
|
8473
|
+
muted,
|
|
8474
|
+
toggleMute,
|
|
8389
8475
|
start,
|
|
8390
8476
|
stop,
|
|
8391
8477
|
toggle,
|
|
@@ -8469,6 +8555,7 @@ var VOICE_DECK_CSS = `
|
|
|
8469
8555
|
}
|
|
8470
8556
|
.yf-voice-deck[data-phase='listening'] .yf-voice-beacon { animation-duration: 3.2s; }
|
|
8471
8557
|
.yf-voice-phase {
|
|
8558
|
+
white-space: nowrap;
|
|
8472
8559
|
font-size: 10.5px;
|
|
8473
8560
|
font-weight: 600;
|
|
8474
8561
|
letter-spacing: 0.14em;
|
|
@@ -8496,12 +8583,36 @@ var VOICE_DECK_CSS = `
|
|
|
8496
8583
|
.yf-voice-end:hover { background: color-mix(in srgb, var(--yf-voice-ink) 10%, transparent); border-color: color-mix(in srgb, var(--yf-voice-ink) 28%, transparent); color: var(--yf-voice-ink); }
|
|
8497
8584
|
.yf-voice-end:active { transform: scale(0.97); }
|
|
8498
8585
|
.yf-voice-end__mark { width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
|
|
8586
|
+
.yf-voice-mute {
|
|
8587
|
+
display: inline-flex;
|
|
8588
|
+
align-items: center;
|
|
8589
|
+
justify-content: center;
|
|
8590
|
+
width: 28px;
|
|
8591
|
+
height: 28px;
|
|
8592
|
+
border-radius: 999px;
|
|
8593
|
+
border: 1px solid color-mix(in srgb, var(--yf-voice-ink) 16%, transparent);
|
|
8594
|
+
background: color-mix(in srgb, var(--yf-voice-ink) 5%, transparent);
|
|
8595
|
+
color: color-mix(in srgb, var(--yf-voice-ink) 85%, transparent);
|
|
8596
|
+
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
|
8597
|
+
-webkit-tap-highlight-color: transparent;
|
|
8598
|
+
}
|
|
8599
|
+
.yf-voice-mute svg { width: 14px; height: 14px; }
|
|
8600
|
+
.yf-voice-mute:hover { background: color-mix(in srgb, var(--yf-voice-ink) 10%, transparent); color: var(--yf-voice-ink); }
|
|
8601
|
+
.yf-voice-mute:active { transform: scale(0.95); }
|
|
8602
|
+
.yf-voice-mute:disabled { opacity: 0.4; }
|
|
8603
|
+
.yf-voice-mute[aria-pressed='true'] {
|
|
8604
|
+
border-color: color-mix(in srgb, var(--yf-voice-accent) 55%, transparent);
|
|
8605
|
+
background: color-mix(in srgb, var(--yf-voice-accent) 18%, transparent);
|
|
8606
|
+
color: var(--yf-voice-accent);
|
|
8607
|
+
}
|
|
8608
|
+
.yf-voice-deck[data-muted] .yf-voice-beacon { background: var(--yf-voice-muted); animation: none; }
|
|
8609
|
+
.yf-voice-deck[data-muted] .yf-voice-phase { color: var(--yf-voice-muted); }
|
|
8499
8610
|
.yf-voice-print {
|
|
8500
8611
|
-webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 100%);
|
|
8501
8612
|
mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 100%);
|
|
8502
8613
|
}
|
|
8503
8614
|
.yf-voice-caption { display: flex; min-width: 0; align-items: baseline; gap: 8px; color: color-mix(in srgb, var(--yf-voice-ink) 72%, transparent); }
|
|
8504
|
-
.yf-voice-caption--javier { display: block; color: var(--yf-voice-ink); font-weight: 450; text-wrap: pretty; }
|
|
8615
|
+
.yf-voice-caption--javier { display: block; color: var(--yf-voice-ink); font-weight: 450; text-wrap: pretty; overflow-wrap: anywhere; }
|
|
8505
8616
|
.yf-voice-hint { color: var(--yf-voice-muted); }
|
|
8506
8617
|
.yf-voice-who {
|
|
8507
8618
|
flex-shrink: 0;
|
|
@@ -8511,9 +8622,27 @@ var VOICE_DECK_CSS = `
|
|
|
8511
8622
|
text-transform: uppercase;
|
|
8512
8623
|
color: var(--yf-voice-muted);
|
|
8513
8624
|
}
|
|
8625
|
+
.yf-voice-deck[data-fill] { display: flex; flex-direction: column; height: 100%; min-height: 0; }
|
|
8626
|
+
.yf-voice-deck[data-fill] .yf-voice-deck__panel { flex: 1; display: flex; flex-direction: column; min-height: 0; }
|
|
8627
|
+
.yf-voice-detail {
|
|
8628
|
+
flex: 1;
|
|
8629
|
+
min-height: 0;
|
|
8630
|
+
overflow-y: auto;
|
|
8631
|
+
overflow-x: hidden;
|
|
8632
|
+
overflow-wrap: anywhere;
|
|
8633
|
+
overscroll-behavior: contain;
|
|
8634
|
+
-webkit-overflow-scrolling: touch;
|
|
8635
|
+
padding: 10px 16px 16px;
|
|
8636
|
+
border-top: 1px solid color-mix(in srgb, var(--yf-voice-ink) 8%, transparent);
|
|
8637
|
+
-webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 18px), transparent 100%);
|
|
8638
|
+
mask-image: linear-gradient(180deg, transparent 0, #000 14px, #000 calc(100% - 18px), transparent 100%);
|
|
8639
|
+
animation: yf-voice-rise 0.32s cubic-bezier(0.2, 0.7, 0.2, 1) both;
|
|
8640
|
+
}
|
|
8514
8641
|
.yf-voice-deck[data-phone] { border-radius: 20px; }
|
|
8515
8642
|
.yf-voice-deck[data-phone] .yf-voice-deck__panel { border-radius: 19px; }
|
|
8516
8643
|
.yf-voice-deck[data-phone] .yf-voice-end { height: 40px; padding: 0 16px 0 14px; font-size: 14px; }
|
|
8644
|
+
.yf-voice-deck[data-phone] .yf-voice-mute { width: 40px; height: 40px; margin-right: 2px; }
|
|
8645
|
+
.yf-voice-deck[data-phone] .yf-voice-mute svg { width: 18px; height: 18px; }
|
|
8517
8646
|
.yf-voice-deck[data-phone] .yf-voice-phase { font-size: 11.5px; }
|
|
8518
8647
|
@media (prefers-reduced-motion: reduce) {
|
|
8519
8648
|
.yf-voice-deck, .yf-voice-beacon, .yf-voice-deck__panel { animation: none; }
|
|
@@ -8527,7 +8656,7 @@ function ensureVoiceDeckStyles(doc = typeof document === "undefined" ? void 0 :
|
|
|
8527
8656
|
style.textContent = VOICE_DECK_CSS;
|
|
8528
8657
|
doc.head.appendChild(style);
|
|
8529
8658
|
}
|
|
8530
|
-
function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
8659
|
+
function VoiceDeck({ voice, name, phone = false, hint, fill = false, children }) {
|
|
8531
8660
|
const t = useTheme();
|
|
8532
8661
|
useEffect(() => ensureVoiceDeckStyles(), []);
|
|
8533
8662
|
const now = useClock(voice.startedAt !== null);
|
|
@@ -8537,9 +8666,10 @@ function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
|
8537
8666
|
connecting: "Connecting",
|
|
8538
8667
|
listening: "Listening",
|
|
8539
8668
|
hearing: "Hearing you",
|
|
8540
|
-
thinking: "Working
|
|
8669
|
+
thinking: "Working",
|
|
8541
8670
|
speaking: speaker
|
|
8542
8671
|
};
|
|
8672
|
+
const phaseWord = voice.muted && voice.phase !== "speaking" && voice.phase !== "connecting" ? "Muted" : phaseWords[voice.phase];
|
|
8543
8673
|
const { startedAt, maxSessionSecs } = voice;
|
|
8544
8674
|
const elapsed = startedAt === null ? 0 : now - startedAt;
|
|
8545
8675
|
const remaining = maxSessionSecs > 0 && startedAt !== null ? maxSessionSecs * 1e3 - elapsed : Infinity;
|
|
@@ -8552,26 +8682,40 @@ function VoiceDeck({ voice, name, phone = false, hint }) {
|
|
|
8552
8682
|
"--yf-voice-muted": t.textMuted,
|
|
8553
8683
|
"--yf-voice-panel": t.bgRaised
|
|
8554
8684
|
};
|
|
8555
|
-
return /* @__PURE__ */ jsxs("div", { className: "yf-voice-deck", "data-phase": voice.phase, "data-phone": phone ? "" : void 0, style: vars, children: [
|
|
8685
|
+
return /* @__PURE__ */ jsxs("div", { className: "yf-voice-deck", "data-phase": voice.phase, "data-phone": phone ? "" : void 0, "data-fill": fill ? "" : void 0, "data-muted": voice.muted ? "" : void 0, style: vars, children: [
|
|
8556
8686
|
/* @__PURE__ */ jsxs("div", { className: "yf-voice-deck__panel", children: [
|
|
8557
8687
|
/* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2.5 ${phone ? "px-4 pt-3.5" : "px-4 pt-3"}`, children: [
|
|
8558
8688
|
/* @__PURE__ */ jsx("span", { className: "yf-voice-beacon", "aria-hidden": "true" }),
|
|
8559
|
-
/* @__PURE__ */ jsx("span", { role: "status", "aria-live": "polite", className: "yf-voice-phase", children:
|
|
8689
|
+
/* @__PURE__ */ jsx("span", { role: "status", "aria-live": "polite", className: "yf-voice-phase", children: phaseWord }),
|
|
8560
8690
|
startedAt !== null ? /* @__PURE__ */ jsx("span", { className: "yf-voice-clock", "data-soon": endingSoon ? "" : void 0, title: endingSoon ? "Voice ends soon" : "Time in this voice session", children: endingSoon && Number.isFinite(remaining) ? `ends in ${clock(remaining)}` : clock(elapsed) }) : null,
|
|
8561
8691
|
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
8692
|
+
/* @__PURE__ */ jsx(
|
|
8693
|
+
"button",
|
|
8694
|
+
{
|
|
8695
|
+
type: "button",
|
|
8696
|
+
onClick: voice.toggleMute,
|
|
8697
|
+
className: "yf-voice-mute",
|
|
8698
|
+
"aria-pressed": voice.muted,
|
|
8699
|
+
"aria-label": voice.muted ? "Unmute microphone" : "Mute microphone",
|
|
8700
|
+
title: voice.muted ? "Unmute" : "Mute",
|
|
8701
|
+
disabled: voice.phase === "connecting",
|
|
8702
|
+
children: voice.muted ? /* @__PURE__ */ jsx(MicOff, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Mic, { "aria-hidden": "true" })
|
|
8703
|
+
}
|
|
8704
|
+
),
|
|
8562
8705
|
/* @__PURE__ */ jsxs("button", { type: "button", onClick: voice.stop, className: "yf-voice-end", "aria-label": "End voice", children: [
|
|
8563
8706
|
/* @__PURE__ */ jsx("span", { className: "yf-voice-end__mark", "aria-hidden": "true" }),
|
|
8564
8707
|
"End"
|
|
8565
8708
|
] })
|
|
8566
8709
|
] }),
|
|
8567
|
-
/* @__PURE__ */ jsx(Voiceprint, { phase: voice.phase, levels: voice.levels, height: phone ? 104 : 76, cell: phone ? 13 : 11 }),
|
|
8710
|
+
/* @__PURE__ */ jsx(Voiceprint, { phase: voice.phase, levels: voice.levels, height: fill ? 148 : phone ? 104 : 76, cell: fill ? 14 : phone ? 13 : 11 }),
|
|
8568
8711
|
/* @__PURE__ */ jsxs("div", { className: `flex flex-col gap-1.5 ${phone ? "px-4 pb-4" : "px-4 pb-3.5"}`, style: { minHeight: "1.25rem" }, "aria-live": "off", children: [
|
|
8569
8712
|
words ? /* @__PURE__ */ jsxs("p", { className: "yf-voice-caption", style: { fontSize: phone ? 13.5 : 12.5 }, children: [
|
|
8570
8713
|
/* @__PURE__ */ jsx("span", { className: "yf-voice-who", children: "You" }),
|
|
8571
8714
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: words })
|
|
8572
8715
|
] }) : null,
|
|
8573
|
-
said ? /* @__PURE__ */ jsx("p", { className: "yf-voice-caption yf-voice-caption--javier", style: { fontSize: phone ? 16 : 14, lineHeight: phone ? 1.45 : 1.5 }, children: said }) : !words ? /* @__PURE__ */ jsx("p", { className: "yf-voice-hint", style: { fontSize: phone ? 14 : 12.5 }, children: voice.phase === "connecting" ? "Opening the line\u2026" : hint ?? "Ask anything. Talk over me to interrupt." }) : null
|
|
8574
|
-
] })
|
|
8716
|
+
said ? /* @__PURE__ */ jsx("p", { className: "yf-voice-caption yf-voice-caption--javier", style: { fontSize: phone ? 16 : 14, lineHeight: phone ? 1.45 : 1.5 }, children: said }) : !words ? /* @__PURE__ */ jsx("p", { className: "yf-voice-hint", style: { fontSize: phone ? 14 : 12.5 }, children: voice.phase === "connecting" ? "Opening the line\u2026" : voice.muted ? "Your microphone is off. Tap it to talk." : hint ?? "Ask anything. Talk over me to interrupt." }) : null
|
|
8717
|
+
] }),
|
|
8718
|
+
fill && children ? /* @__PURE__ */ jsx("div", { className: "yf-voice-detail", children }) : null
|
|
8575
8719
|
] }),
|
|
8576
8720
|
/* @__PURE__ */ jsx("span", { "data-voice-probe": "ink", hidden: true, style: { color: "var(--yf-voice-ink)" } }),
|
|
8577
8721
|
/* @__PURE__ */ jsx("span", { "data-voice-probe": "accent", hidden: true, style: { color: "var(--yf-voice-accent)" } }),
|
|
@@ -10502,8 +10646,9 @@ function EdgeDetailDrawer({ edge, annotations, onClose, onNavigate }) {
|
|
|
10502
10646
|
]
|
|
10503
10647
|
}
|
|
10504
10648
|
),
|
|
10505
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-1", style: { backgroundColor: "#1e1e1e", borderTop: "1px solid #282828", borderBottom: "1px solid #282828" }, children: /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-gray-500", children: [
|
|
10506
|
-
"
|
|
10649
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-1", style: { backgroundColor: "#1e1e1e", borderTop: "1px solid #282828", borderBottom: "1px solid #282828" }, children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] text-gray-500", children: [
|
|
10650
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }),
|
|
10651
|
+
" ",
|
|
10507
10652
|
/* @__PURE__ */ jsx("span", { style: { color }, children: typeLabel })
|
|
10508
10653
|
] }) }),
|
|
10509
10654
|
/* @__PURE__ */ jsxs(
|
|
@@ -11424,7 +11569,7 @@ function SchemaStage({
|
|
|
11424
11569
|
style: { flex: 1, fontSize: 11, color: "#aaa", backgroundColor: "transparent", border: "1px solid #333", borderRadius: 4, padding: "5px 8px", outline: "none" }
|
|
11425
11570
|
}
|
|
11426
11571
|
),
|
|
11427
|
-
/* @__PURE__ */ jsx("span", { style: { color: "#555", alignSelf: "center", fontSize: 12 }, children: "\
|
|
11572
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#555", alignSelf: "center", fontSize: 12 }, children: "\u203A" }),
|
|
11428
11573
|
/* @__PURE__ */ jsx(
|
|
11429
11574
|
"input",
|
|
11430
11575
|
{
|
|
@@ -11534,7 +11679,7 @@ function SchemaStage({
|
|
|
11534
11679
|
onMouseUp: (e) => {
|
|
11535
11680
|
e.currentTarget.style.transform = "translateY(0)";
|
|
11536
11681
|
},
|
|
11537
|
-
children: "Looks good \u2014 read the document \
|
|
11682
|
+
children: "Looks good \u2014 read the document \u203A"
|
|
11538
11683
|
}
|
|
11539
11684
|
)
|
|
11540
11685
|
]
|
|
@@ -12219,7 +12364,7 @@ function StageCanvas({ nodeCount, onForceGraph, initialPhase, initialTeam, kgId
|
|
|
12219
12364
|
{
|
|
12220
12365
|
onClick: onForceGraph,
|
|
12221
12366
|
style: { display: "block", margin: "16px auto 0", color: "#ff8c42", fontSize: 12, background: "none", border: "1px solid #ff8c4230", padding: "6px 16px", borderRadius: 8, cursor: "pointer" },
|
|
12222
|
-
children: "Show
|
|
12367
|
+
children: "Show graph \u203A"
|
|
12223
12368
|
}
|
|
12224
12369
|
)
|
|
12225
12370
|
] })
|
|
@@ -15676,7 +15821,7 @@ function CheckpointCard({
|
|
|
15676
15821
|
style: { backgroundColor: `${config.color}20`, color: config.color, border: `1px solid ${config.color}30` },
|
|
15677
15822
|
children: [
|
|
15678
15823
|
config.proceedLabel,
|
|
15679
|
-
" \
|
|
15824
|
+
" \u203A"
|
|
15680
15825
|
]
|
|
15681
15826
|
}
|
|
15682
15827
|
)
|
|
@@ -15748,4 +15893,4 @@ var terminalClassNames = {
|
|
|
15748
15893
|
promptSymbol: "terminal-prompt-symbol"
|
|
15749
15894
|
};
|
|
15750
15895
|
|
|
15751
|
-
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, AgentAvatar, AgentPresenceBar, AgentStepTrace, AnnotationThread, AskQueue, CLAIM_STATUS_COLORS, ChatTerminal, CheckpointCard, ClaimNode, ConstructionProgress, CoreTerminal, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, ExpandableTerminal, GraphChatPanel, GraphEdge, GraphNode, InlineTerminal, KnowledgeGraphView, LIVE_KG_ID, LiveActivityTicker, MarkdownContent, MarkdownEditor, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, PipelineProgressBar, REPLACED_OUTPUT, ReasoningHistoryCard, ReasoningOverlay, ReasoningView, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, ScopedReasoningProvider, SettlementBar, SlashMentionPicker, StageCanvas, StandardTerminal, TerminalInputBar, TerminalThemeProvider, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, VoiceDeck, VoiceInputButton, VoiceSession, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|
|
15896
|
+
export { ADVANCE_PHASE_SIGNAL, AGENT_PALETTE, AgentAvatar, AgentPresenceBar, AgentStepTrace, AnnotationThread, AskQueue, CLAIM_STATUS_COLORS, ChatTerminal, CheckpointCard, ClaimNode, ConstructionProgress, CoreTerminal, DEFAULT_AGENT_LABEL, DOCUMENT_PIPELINE_STEPS, DocumentProcessingProgress, EDGE_TYPE_COLORS, EdgeDetailDrawer, EdgeMarkerDefs, CoreTerminal as EmbeddedTerminal, ExpandableTerminal, GraphChatPanel, GraphEdge, GraphNode, InlineTerminal, KnowledgeGraphView, LIVE_KG_ID, LiveActivityTicker, MarkdownContent, MarkdownEditor, NODE_TYPE_COLORS, NODE_TYPE_LABELS, NodeDetailDrawer, PROGRESS_EVENT_NAME, PipelineProgressBar, REPLACED_OUTPUT, ReasoningHistoryCard, ReasoningOverlay, ReasoningView, SILENT, SSE_KEEPALIVE_MS, SSE_STALL_MS, SYNTHESIS_DONE_SIGNAL, ScopedReasoningProvider, ScreenAwake, SettlementBar, SlashMentionPicker, StageCanvas, StandardTerminal, TerminalInputBar, TerminalThemeProvider, VOICE_CAPTURE_WORKLET_SOURCE, VOICE_LANGUAGES, VOICE_NAMES, VoiceDeck, VoiceInputButton, VoiceSession, agentSeed, agentStepTraceExtra, avatarColor, blueScope, buildClaimsGraph, buildTerminalCommand, buttonShadow, captureReasoningSnapshot, defaultTheme, dispatchProgressEvent, documentEventToActivity, emeraldCollab, emeraldRevised, encodePersona, eventToActivity, extractKGSources, extractKgId, filterCommands, formatAssetDisplay, formatPaymentAmount, formatTokenAssetId, getAgentColor, getBuiltInCommands, getClaimStatusColors, getEdgeColor, getEdgeTypeLabel, getNodeColors, getNodeTypeLabel, getVocabTypeColors, getVocabTypeLabel, getVoiceStatus, greenAction, handleSSEStream, handleStreamingResponse, hostApp, initials, isFixedKgId, isNaturalLanguage, layoutGraph, mergeTheme, openPipelineEventStream, orangeRebuttal, parseTerminalCommand, pipelineBg, processStreamLines, purple, reduceProgress, renderMarkdownBlock, resolvePaymentAssetDisplay, snapshotToSubgraph, socketBase, terminalClassNames, terminalColors, useScopedProgressEvent, useSlashMentionPicker, useTheme, useVoiceSession, voiceEndedMessage, voiceSocketUrl, warmBg, withStallTimeout };
|