@ottocode/web-sdk 0.1.314 → 0.1.316
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/components/common/ProviderLogo.d.ts.map +1 -1
- package/dist/components/index.js +153 -44
- package/dist/components/index.js.map +10 -9
- package/dist/hooks/index.js +150 -40
- package/dist/hooks/index.js.map +8 -7
- package/dist/hooks/tool-preview-helpers.d.ts +6 -0
- package/dist/hooks/tool-preview-helpers.d.ts.map +1 -0
- package/dist/hooks/useAgents.d.ts +1 -0
- package/dist/hooks/useAgents.d.ts.map +1 -1
- package/dist/hooks/useChatComposer.d.ts +1 -0
- package/dist/hooks/useChatComposer.d.ts.map +1 -1
- package/dist/hooks/useConfig.d.ts +4 -0
- package/dist/hooks/useConfig.d.ts.map +1 -1
- package/dist/hooks/useSessionStream.d.ts.map +1 -1
- package/dist/hooks/useVoiceInput.d.ts.map +1 -1
- package/dist/index.js +153 -44
- package/dist/index.js.map +10 -9
- package/dist/lib/api-client/config.d.ts +3 -0
- package/dist/lib/api-client/config.d.ts.map +1 -1
- package/dist/lib/api-client/index.d.ts +3 -0
- package/dist/lib/api-client/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +2 -2
- package/package.json +3 -3
package/dist/hooks/index.js
CHANGED
|
@@ -3124,6 +3124,78 @@ var useSecureInputStore = create11((set) => ({
|
|
|
3124
3124
|
clearPendingInputs: () => set({ pendingInputs: [] })
|
|
3125
3125
|
}));
|
|
3126
3126
|
|
|
3127
|
+
// src/hooks/tool-preview-helpers.ts
|
|
3128
|
+
function bestEffortUnescapeJsonString(value) {
|
|
3129
|
+
try {
|
|
3130
|
+
return JSON.parse(`"${value.replace(/\\$/, "")}"`);
|
|
3131
|
+
} catch {
|
|
3132
|
+
return value.replace(/\\n/g, `
|
|
3133
|
+
`).replace(/\\t/g, "\t").replace(/\\r/g, "\r").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
function extractJsonStringFieldAt(text, field, startIndex, requireClosed = false) {
|
|
3137
|
+
const marker = `"${field}"`;
|
|
3138
|
+
const markerIndex = text.indexOf(marker, Math.max(0, startIndex));
|
|
3139
|
+
if (markerIndex === -1)
|
|
3140
|
+
return;
|
|
3141
|
+
const colonIndex = text.indexOf(":", markerIndex + marker.length);
|
|
3142
|
+
if (colonIndex === -1)
|
|
3143
|
+
return;
|
|
3144
|
+
const quoteIndex = text.indexOf('"', colonIndex + 1);
|
|
3145
|
+
if (quoteIndex === -1)
|
|
3146
|
+
return;
|
|
3147
|
+
let escaped = "";
|
|
3148
|
+
let escaping = false;
|
|
3149
|
+
let closed = false;
|
|
3150
|
+
let endIndex = text.length;
|
|
3151
|
+
for (let i = quoteIndex + 1;i < text.length; i += 1) {
|
|
3152
|
+
const char = text[i];
|
|
3153
|
+
if (escaping) {
|
|
3154
|
+
escaped += `\\${char}`;
|
|
3155
|
+
escaping = false;
|
|
3156
|
+
continue;
|
|
3157
|
+
}
|
|
3158
|
+
if (char === "\\") {
|
|
3159
|
+
escaping = true;
|
|
3160
|
+
continue;
|
|
3161
|
+
}
|
|
3162
|
+
if (char === '"') {
|
|
3163
|
+
closed = true;
|
|
3164
|
+
endIndex = i + 1;
|
|
3165
|
+
break;
|
|
3166
|
+
}
|
|
3167
|
+
escaped += char;
|
|
3168
|
+
}
|
|
3169
|
+
if (requireClosed && !closed)
|
|
3170
|
+
return;
|
|
3171
|
+
return {
|
|
3172
|
+
value: bestEffortUnescapeJsonString(escaped),
|
|
3173
|
+
endIndex,
|
|
3174
|
+
closed
|
|
3175
|
+
};
|
|
3176
|
+
}
|
|
3177
|
+
function extractStreamingMultiEditPreviewEdits(buffer) {
|
|
3178
|
+
const editsStart = buffer.indexOf('"edits"');
|
|
3179
|
+
if (editsStart === -1)
|
|
3180
|
+
return [];
|
|
3181
|
+
const edits = [];
|
|
3182
|
+
let cursor = editsStart;
|
|
3183
|
+
const maxPreviewEdits = 50;
|
|
3184
|
+
while (cursor < buffer.length && edits.length < maxPreviewEdits) {
|
|
3185
|
+
const oldString = extractJsonStringFieldAt(buffer, "oldString", cursor, true);
|
|
3186
|
+
if (!oldString)
|
|
3187
|
+
break;
|
|
3188
|
+
const newString = extractJsonStringFieldAt(buffer, "newString", oldString.endIndex, false);
|
|
3189
|
+
if (!newString)
|
|
3190
|
+
break;
|
|
3191
|
+
edits.push({ oldString: oldString.value, newString: newString.value });
|
|
3192
|
+
cursor = Math.max(newString.endIndex, oldString.endIndex + 1);
|
|
3193
|
+
if (!newString.closed)
|
|
3194
|
+
break;
|
|
3195
|
+
}
|
|
3196
|
+
return edits;
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3127
3199
|
// src/hooks/useSessionStream.ts
|
|
3128
3200
|
var TOOL_PREVIEW_THROTTLE_MS = 500;
|
|
3129
3201
|
var TOOL_PREVIEW_THROTTLE_MIN_CHARS = 8000;
|
|
@@ -3277,7 +3349,7 @@ ${value.slice(-STREAMING_TOOL_INPUT_TAIL_CHARS)}`;
|
|
|
3277
3349
|
toolInputBuffersRef.current.set(key, next);
|
|
3278
3350
|
return parseArgsRecord(next);
|
|
3279
3351
|
};
|
|
3280
|
-
const
|
|
3352
|
+
const bestEffortUnescapeJsonString2 = (value) => {
|
|
3281
3353
|
try {
|
|
3282
3354
|
return JSON.parse(`"${value.replace(/\\$/, "")}"`);
|
|
3283
3355
|
} catch {
|
|
@@ -3318,7 +3390,7 @@ ${value.slice(-STREAMING_TOOL_INPUT_TAIL_CHARS)}`;
|
|
|
3318
3390
|
}
|
|
3319
3391
|
if (requireClosed && !closed)
|
|
3320
3392
|
return;
|
|
3321
|
-
return
|
|
3393
|
+
return bestEffortUnescapeJsonString2(escaped);
|
|
3322
3394
|
};
|
|
3323
3395
|
const getBufferedToolInput = (payload) => {
|
|
3324
3396
|
const key = getToolBufferKey(payload);
|
|
@@ -3355,7 +3427,7 @@ ${argContent.slice(-STREAMING_WRITE_CONTENT_PREVIEW_CHARS)}`;
|
|
|
3355
3427
|
}
|
|
3356
3428
|
const rawTail = buffer.slice(Math.max(valueStart, buffer.length - STREAMING_WRITE_CONTENT_PREVIEW_CHARS));
|
|
3357
3429
|
return `… showing latest streamed content only …
|
|
3358
|
-
${
|
|
3430
|
+
${bestEffortUnescapeJsonString2(rawTail)}`;
|
|
3359
3431
|
};
|
|
3360
3432
|
const getStreamingPatchPreviewContent = (args, buffer) => {
|
|
3361
3433
|
const argPatch = args?.patch;
|
|
@@ -3384,9 +3456,9 @@ ${argPatch.slice(-STREAMING_PATCH_PREVIEW_TAIL_CHARS)}`;
|
|
|
3384
3456
|
}
|
|
3385
3457
|
const rawHead = buffer.slice(valueStart, valueStart + STREAMING_PATCH_PREVIEW_HEAD_CHARS);
|
|
3386
3458
|
const rawTail = buffer.slice(-STREAMING_PATCH_PREVIEW_TAIL_CHARS);
|
|
3387
|
-
return `${
|
|
3459
|
+
return `${bestEffortUnescapeJsonString2(rawHead)}
|
|
3388
3460
|
… patch preview truncated while streaming …
|
|
3389
|
-
${
|
|
3461
|
+
${bestEffortUnescapeJsonString2(rawTail)}`;
|
|
3390
3462
|
};
|
|
3391
3463
|
const getResultRecord = (payload) => payload?.result && typeof payload.result === "object" && !Array.isArray(payload.result) ? payload.result : null;
|
|
3392
3464
|
const getArtifactRecord = (payload) => {
|
|
@@ -3562,14 +3634,15 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
3562
3634
|
return lines.join(`
|
|
3563
3635
|
`);
|
|
3564
3636
|
};
|
|
3565
|
-
const getMultiEditPreviewEdits = (args) => {
|
|
3637
|
+
const getMultiEditPreviewEdits = (args, buffer) => {
|
|
3566
3638
|
const edits = Array.isArray(args?.edits) ? args.edits : [];
|
|
3567
|
-
|
|
3639
|
+
const parsedEdits = edits.flatMap((edit) => {
|
|
3568
3640
|
if (!edit || typeof edit !== "object" || Array.isArray(edit))
|
|
3569
3641
|
return [];
|
|
3570
3642
|
const record = edit;
|
|
3571
3643
|
return typeof record.oldString === "string" && typeof record.newString === "string" ? [{ oldString: record.oldString, newString: record.newString }] : [];
|
|
3572
3644
|
});
|
|
3645
|
+
return parsedEdits.length > 0 ? parsedEdits : extractStreamingMultiEditPreviewEdits(buffer);
|
|
3573
3646
|
};
|
|
3574
3647
|
const getEditPreviewPatch = (toolName, path, args, buffer, artifact) => {
|
|
3575
3648
|
if (typeof artifact?.patch === "string")
|
|
@@ -3579,7 +3652,7 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
3579
3652
|
const newString = getStringArg(args, buffer, "newString");
|
|
3580
3653
|
return oldString !== undefined && newString !== undefined ? buildStringEditPatchPreview(path, [{ oldString, newString }]) : undefined;
|
|
3581
3654
|
}
|
|
3582
|
-
const edits = getMultiEditPreviewEdits(args);
|
|
3655
|
+
const edits = getMultiEditPreviewEdits(args, buffer);
|
|
3583
3656
|
return buildStringEditPatchPreview(path, edits);
|
|
3584
3657
|
};
|
|
3585
3658
|
const handleReadToolActivity = (eventType, payload, delta) => {
|
|
@@ -8069,6 +8142,7 @@ function useEdgeHover({
|
|
|
8069
8142
|
import { useCallback as useCallback14, useEffect as useEffect22, useRef as useRef11, useState as useState10 } from "react";
|
|
8070
8143
|
var TARGET_SAMPLE_RATE = 16000;
|
|
8071
8144
|
var PCM_FRAME_BYTES = 3200;
|
|
8145
|
+
var PROCESSOR_BUFFER_SIZE = 4096;
|
|
8072
8146
|
function getAudioContextConstructor() {
|
|
8073
8147
|
if (typeof window === "undefined")
|
|
8074
8148
|
return null;
|
|
@@ -8213,8 +8287,7 @@ function useVoiceInput({
|
|
|
8213
8287
|
}, []);
|
|
8214
8288
|
const handleAudioProcess = useCallback14((event) => {
|
|
8215
8289
|
const audioContext = audioContextRef.current;
|
|
8216
|
-
|
|
8217
|
-
if (!audioContext || !socket || socket.readyState !== WebSocket.OPEN || stoppingRef.current) {
|
|
8290
|
+
if (!audioContext || stoppingRef.current) {
|
|
8218
8291
|
return;
|
|
8219
8292
|
}
|
|
8220
8293
|
const input = event.inputBuffer.getChannelData(0);
|
|
@@ -8246,9 +8319,53 @@ function useVoiceInput({
|
|
|
8246
8319
|
setIsTranscribing(false);
|
|
8247
8320
|
stoppingRef.current = false;
|
|
8248
8321
|
try {
|
|
8249
|
-
const
|
|
8322
|
+
const streamPromise = navigator.mediaDevices.getUserMedia({
|
|
8323
|
+
audio: {
|
|
8324
|
+
echoCancellation: true,
|
|
8325
|
+
noiseSuppression: true,
|
|
8326
|
+
autoGainControl: true
|
|
8327
|
+
}
|
|
8328
|
+
});
|
|
8329
|
+
const statusPromise = apiClient.getDictationStatus().then((status2) => ({ status: status2 }), (error2) => ({ error: error2 }));
|
|
8330
|
+
const stream = await streamPromise;
|
|
8331
|
+
if (stoppingRef.current) {
|
|
8332
|
+
for (const track of stream.getTracks())
|
|
8333
|
+
track.stop();
|
|
8334
|
+
return;
|
|
8335
|
+
}
|
|
8336
|
+
streamRef.current = stream;
|
|
8337
|
+
const AudioContextCtor = getAudioContextConstructor();
|
|
8338
|
+
if (!AudioContextCtor)
|
|
8339
|
+
throw new Error("AudioContext is unavailable");
|
|
8340
|
+
const audioContext = new AudioContextCtor;
|
|
8341
|
+
audioContextRef.current = audioContext;
|
|
8342
|
+
const source = audioContext.createMediaStreamSource(stream);
|
|
8343
|
+
const analyserNode = audioContext.createAnalyser();
|
|
8344
|
+
analyserNode.fftSize = 256;
|
|
8345
|
+
analyserNode.smoothingTimeConstant = 0.55;
|
|
8346
|
+
const processor = audioContext.createScriptProcessor(PROCESSOR_BUFFER_SIZE, 1, 1);
|
|
8347
|
+
processor.onaudioprocess = handleAudioProcess;
|
|
8348
|
+
source.connect(analyserNode);
|
|
8349
|
+
source.connect(processor);
|
|
8350
|
+
processor.connect(audioContext.destination);
|
|
8351
|
+
sourceRef.current = source;
|
|
8352
|
+
processorRef.current = processor;
|
|
8353
|
+
if (audioContext.state === "suspended") {
|
|
8354
|
+
await audioContext.resume();
|
|
8355
|
+
}
|
|
8356
|
+
if (stoppingRef.current)
|
|
8357
|
+
return;
|
|
8358
|
+
setAnalyser(analyserNode);
|
|
8359
|
+
setIsListening(true);
|
|
8360
|
+
const statusResult = await statusPromise;
|
|
8361
|
+
if ("error" in statusResult)
|
|
8362
|
+
throw statusResult.error;
|
|
8363
|
+
const { status } = statusResult;
|
|
8364
|
+
if (stoppingRef.current)
|
|
8365
|
+
return;
|
|
8250
8366
|
const model = status.models.find((item) => item.id === status.defaultModel);
|
|
8251
8367
|
if (!model?.installed) {
|
|
8368
|
+
cleanup();
|
|
8252
8369
|
handleMissingModel();
|
|
8253
8370
|
return;
|
|
8254
8371
|
}
|
|
@@ -8256,7 +8373,10 @@ function useVoiceInput({
|
|
|
8256
8373
|
model: status.defaultModel,
|
|
8257
8374
|
language: toLanguageCode(lang)
|
|
8258
8375
|
});
|
|
8376
|
+
if (stoppingRef.current)
|
|
8377
|
+
return;
|
|
8259
8378
|
if (!session.modelInstalled) {
|
|
8379
|
+
cleanup();
|
|
8260
8380
|
handleMissingModel();
|
|
8261
8381
|
return;
|
|
8262
8382
|
}
|
|
@@ -8269,7 +8389,6 @@ function useVoiceInput({
|
|
|
8269
8389
|
reject(new Error("Timed out connecting to local dictation"));
|
|
8270
8390
|
}, 5000);
|
|
8271
8391
|
socket.onopen = () => {
|
|
8272
|
-
window.clearTimeout(timeout);
|
|
8273
8392
|
socket.send(JSON.stringify({
|
|
8274
8393
|
type: "start",
|
|
8275
8394
|
model: session.model,
|
|
@@ -8281,7 +8400,23 @@ function useVoiceInput({
|
|
|
8281
8400
|
},
|
|
8282
8401
|
partialResults: false
|
|
8283
8402
|
}));
|
|
8284
|
-
|
|
8403
|
+
};
|
|
8404
|
+
socket.onmessage = (event) => {
|
|
8405
|
+
if (typeof event.data !== "string")
|
|
8406
|
+
return;
|
|
8407
|
+
const payload = parseServerEvent(event.data);
|
|
8408
|
+
if (!payload)
|
|
8409
|
+
return;
|
|
8410
|
+
if (payload.type === "ready") {
|
|
8411
|
+
window.clearTimeout(timeout);
|
|
8412
|
+
flushFrameBuffer(false);
|
|
8413
|
+
resolve();
|
|
8414
|
+
return;
|
|
8415
|
+
}
|
|
8416
|
+
if (payload.type === "error") {
|
|
8417
|
+
window.clearTimeout(timeout);
|
|
8418
|
+
reject(new Error(payload.message));
|
|
8419
|
+
}
|
|
8285
8420
|
};
|
|
8286
8421
|
socket.onerror = () => {
|
|
8287
8422
|
window.clearTimeout(timeout);
|
|
@@ -8309,32 +8444,6 @@ function useVoiceInput({
|
|
|
8309
8444
|
setIsListening(false);
|
|
8310
8445
|
setIsTranscribing(false);
|
|
8311
8446
|
};
|
|
8312
|
-
const stream = await navigator.mediaDevices.getUserMedia({
|
|
8313
|
-
audio: {
|
|
8314
|
-
echoCancellation: true,
|
|
8315
|
-
noiseSuppression: true,
|
|
8316
|
-
autoGainControl: true
|
|
8317
|
-
}
|
|
8318
|
-
});
|
|
8319
|
-
streamRef.current = stream;
|
|
8320
|
-
const AudioContextCtor = getAudioContextConstructor();
|
|
8321
|
-
if (!AudioContextCtor)
|
|
8322
|
-
throw new Error("AudioContext is unavailable");
|
|
8323
|
-
const audioContext = new AudioContextCtor;
|
|
8324
|
-
const source = audioContext.createMediaStreamSource(stream);
|
|
8325
|
-
const analyserNode = audioContext.createAnalyser();
|
|
8326
|
-
analyserNode.fftSize = 256;
|
|
8327
|
-
analyserNode.smoothingTimeConstant = 0.55;
|
|
8328
|
-
const processor = audioContext.createScriptProcessor(4096, 1, 1);
|
|
8329
|
-
processor.onaudioprocess = handleAudioProcess;
|
|
8330
|
-
source.connect(analyserNode);
|
|
8331
|
-
source.connect(processor);
|
|
8332
|
-
processor.connect(audioContext.destination);
|
|
8333
|
-
audioContextRef.current = audioContext;
|
|
8334
|
-
sourceRef.current = source;
|
|
8335
|
-
processorRef.current = processor;
|
|
8336
|
-
setAnalyser(analyserNode);
|
|
8337
|
-
setIsListening(true);
|
|
8338
8447
|
} catch (err) {
|
|
8339
8448
|
const name = err instanceof Error ? err.name : "";
|
|
8340
8449
|
const msg = name === "NotAllowedError" ? "Microphone permission denied" : err instanceof Error ? err.message : "Could not start voice input";
|
|
@@ -8346,6 +8455,7 @@ function useVoiceInput({
|
|
|
8346
8455
|
emitError,
|
|
8347
8456
|
handleAudioProcess,
|
|
8348
8457
|
handleMissingModel,
|
|
8458
|
+
flushFrameBuffer,
|
|
8349
8459
|
isSupported,
|
|
8350
8460
|
lang
|
|
8351
8461
|
]);
|
|
@@ -8591,4 +8701,4 @@ export {
|
|
|
8591
8701
|
getAgentToolCount
|
|
8592
8702
|
};
|
|
8593
8703
|
|
|
8594
|
-
//# debugId=
|
|
8704
|
+
//# debugId=43D698DB1EF766A364756E2164756E21
|