osborn 0.8.17 → 0.8.18
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.js +28 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -491,6 +491,11 @@ async function main() {
|
|
|
491
491
|
let userState = 'listening'; // Track user speech state for queue safety
|
|
492
492
|
let currentVoiceMode = voiceMode; // Track active voice mode for data handlers
|
|
493
493
|
let currentProvider = realtimeConfig.provider; // Track active realtime provider
|
|
494
|
+
// Authenticated Supabase userId from participant metadata. Used to scope
|
|
495
|
+
// workspace artifact uploads to the owner's prefix in Supabase Storage.
|
|
496
|
+
// Empty string = anonymous / unauthenticated; uploads fall back to a
|
|
497
|
+
// session-only path (no user prefix).
|
|
498
|
+
let currentUserId = '';
|
|
494
499
|
// Track the active resume session ID across scopes (ParticipantConnected + DataReceived)
|
|
495
500
|
// Updated by resume_session, session_selected, continue_session, switch_session handlers
|
|
496
501
|
let currentResumeSessionId;
|
|
@@ -1776,6 +1781,15 @@ async function main() {
|
|
|
1776
1781
|
try {
|
|
1777
1782
|
const metadata = JSON.parse(participant.metadata || '{}');
|
|
1778
1783
|
console.log(`📋 Participant metadata:`, metadata);
|
|
1784
|
+
// userId from authenticated Supabase session — used to scope Supabase
|
|
1785
|
+
// Storage uploads so each user's workspace artifacts live under their
|
|
1786
|
+
// own prefix. Falls through to '' (anonymous) if not authenticated.
|
|
1787
|
+
if (typeof metadata.userId === 'string' && metadata.userId.length > 0) {
|
|
1788
|
+
currentUserId = metadata.userId;
|
|
1789
|
+
}
|
|
1790
|
+
else {
|
|
1791
|
+
currentUserId = '';
|
|
1792
|
+
}
|
|
1779
1793
|
if (metadata.voiceArch === 'realtime' || metadata.voiceArch === 'direct' || metadata.voiceArch === 'pipeline') {
|
|
1780
1794
|
sessionVoiceMode = metadata.voiceArch;
|
|
1781
1795
|
console.log(`🎙️ Using voice mode from frontend: ${sessionVoiceMode}`);
|
|
@@ -2733,6 +2747,20 @@ async function main() {
|
|
|
2733
2747
|
const form = new FormData();
|
|
2734
2748
|
form.append('file', new Blob([buf], { type: mimeType }), fileName);
|
|
2735
2749
|
form.append('folder', 'artifacts');
|
|
2750
|
+
// Pass userId + sessionId so /api/upload can place the file
|
|
2751
|
+
// under `{userId}/{sessionId}/...` in Supabase Storage for
|
|
2752
|
+
// easy ownership queries and future RLS policies. Both are
|
|
2753
|
+
// optional — route falls back to `artifacts/...` if missing.
|
|
2754
|
+
if (currentUserId)
|
|
2755
|
+
form.append('userId', currentUserId);
|
|
2756
|
+
// Prefer the live resume session id (updated by session
|
|
2757
|
+
// switches), fall back to whatever SDK session id the LLM
|
|
2758
|
+
// reports, fall back to empty.
|
|
2759
|
+
const uploadSessionId = currentResumeSessionId
|
|
2760
|
+
|| currentLLM?.sessionId
|
|
2761
|
+
|| '';
|
|
2762
|
+
if (uploadSessionId)
|
|
2763
|
+
form.append('sessionId', uploadSessionId);
|
|
2736
2764
|
const r = await fetch(`${FRONTEND_URL.replace(/\/$/, '')}/api/upload`, {
|
|
2737
2765
|
method: 'POST', body: form,
|
|
2738
2766
|
signal: AbortSignal.timeout(15_000),
|