@gonzih/meet-the-one-ai 1.0.0

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.
Files changed (175) hide show
  1. package/.env.example +41 -0
  2. package/.node-version +1 -0
  3. package/basis/BERNAYS.md +233 -0
  4. package/basis/FOUNDING_TRANSCRIPT.md +218 -0
  5. package/basis/TECH_SPEC.md +303 -0
  6. package/basis/VALS.md +255 -0
  7. package/basis/layers/L1_IDENTITY_AUTH.md +78 -0
  8. package/basis/layers/L2_CONVERSATION.md +159 -0
  9. package/basis/layers/L3_RECORDING_STORE.md +104 -0
  10. package/basis/layers/L4_ANALYSIS_PIPELINE.md +257 -0
  11. package/basis/layers/L5_MATCHING_ENGINE.md +164 -0
  12. package/basis/layers/L6_CONSENT_INTRODUCTION.md +143 -0
  13. package/basis/layers/L7_PORTABLE_IDENTITY.md +139 -0
  14. package/basis/layers/STACK.md +64 -0
  15. package/basis/schema.sql +203 -0
  16. package/dist/agent.d.ts +2 -0
  17. package/dist/agent.d.ts.map +1 -0
  18. package/dist/agent.js +114 -0
  19. package/dist/agent.js.map +1 -0
  20. package/dist/api/routes/auth.d.ts +2 -0
  21. package/dist/api/routes/auth.d.ts.map +1 -0
  22. package/dist/api/routes/auth.js +79 -0
  23. package/dist/api/routes/auth.js.map +1 -0
  24. package/dist/api/routes/identity.d.ts +2 -0
  25. package/dist/api/routes/identity.d.ts.map +1 -0
  26. package/dist/api/routes/identity.js +92 -0
  27. package/dist/api/routes/identity.js.map +1 -0
  28. package/dist/api/routes/text-submission.d.ts +2 -0
  29. package/dist/api/routes/text-submission.d.ts.map +1 -0
  30. package/dist/api/routes/text-submission.js +56 -0
  31. package/dist/api/routes/text-submission.js.map +1 -0
  32. package/dist/api/webhooks/twilio.d.ts +2 -0
  33. package/dist/api/webhooks/twilio.d.ts.map +1 -0
  34. package/dist/api/webhooks/twilio.js +144 -0
  35. package/dist/api/webhooks/twilio.js.map +1 -0
  36. package/dist/api/webhooks/vapi.d.ts +2 -0
  37. package/dist/api/webhooks/vapi.d.ts.map +1 -0
  38. package/dist/api/webhooks/vapi.js +177 -0
  39. package/dist/api/webhooks/vapi.js.map +1 -0
  40. package/dist/bot.d.ts +3 -0
  41. package/dist/bot.d.ts.map +1 -0
  42. package/dist/bot.js +39 -0
  43. package/dist/bot.js.map +1 -0
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +9 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/jobs/compact-identity.d.ts +2 -0
  49. package/dist/jobs/compact-identity.d.ts.map +1 -0
  50. package/dist/jobs/compact-identity.js +159 -0
  51. package/dist/jobs/compact-identity.js.map +1 -0
  52. package/dist/jobs/consent-call.d.ts +2 -0
  53. package/dist/jobs/consent-call.d.ts.map +1 -0
  54. package/dist/jobs/consent-call.js +70 -0
  55. package/dist/jobs/consent-call.js.map +1 -0
  56. package/dist/jobs/export-identity.d.ts +2 -0
  57. package/dist/jobs/export-identity.d.ts.map +1 -0
  58. package/dist/jobs/export-identity.js +129 -0
  59. package/dist/jobs/export-identity.js.map +1 -0
  60. package/dist/jobs/introduction-call.d.ts +2 -0
  61. package/dist/jobs/introduction-call.d.ts.map +1 -0
  62. package/dist/jobs/introduction-call.js +86 -0
  63. package/dist/jobs/introduction-call.js.map +1 -0
  64. package/dist/jobs/reanalyze-identity.d.ts +2 -0
  65. package/dist/jobs/reanalyze-identity.d.ts.map +1 -0
  66. package/dist/jobs/reanalyze-identity.js +56 -0
  67. package/dist/jobs/reanalyze-identity.js.map +1 -0
  68. package/dist/jobs/run-matching.d.ts +2 -0
  69. package/dist/jobs/run-matching.d.ts.map +1 -0
  70. package/dist/jobs/run-matching.js +200 -0
  71. package/dist/jobs/run-matching.js.map +1 -0
  72. package/dist/jobs/scheduled-matching.d.ts +2 -0
  73. package/dist/jobs/scheduled-matching.d.ts.map +1 -0
  74. package/dist/jobs/scheduled-matching.js +44 -0
  75. package/dist/jobs/scheduled-matching.js.map +1 -0
  76. package/dist/jobs/transcribe-session.d.ts +2 -0
  77. package/dist/jobs/transcribe-session.d.ts.map +1 -0
  78. package/dist/jobs/transcribe-session.js +66 -0
  79. package/dist/jobs/transcribe-session.js.map +1 -0
  80. package/dist/lib/anthropic.d.ts +4 -0
  81. package/dist/lib/anthropic.d.ts.map +1 -0
  82. package/dist/lib/anthropic.js +32 -0
  83. package/dist/lib/anthropic.js.map +1 -0
  84. package/dist/lib/config.d.ts +57 -0
  85. package/dist/lib/config.d.ts.map +1 -0
  86. package/dist/lib/config.js +73 -0
  87. package/dist/lib/config.js.map +1 -0
  88. package/dist/lib/deepgram.d.ts +15 -0
  89. package/dist/lib/deepgram.d.ts.map +1 -0
  90. package/dist/lib/deepgram.js +37 -0
  91. package/dist/lib/deepgram.js.map +1 -0
  92. package/dist/lib/inngest.d.ts +42 -0
  93. package/dist/lib/inngest.d.ts.map +1 -0
  94. package/dist/lib/inngest.js +7 -0
  95. package/dist/lib/inngest.js.map +1 -0
  96. package/dist/lib/openai.d.ts +3 -0
  97. package/dist/lib/openai.d.ts.map +1 -0
  98. package/dist/lib/openai.js +13 -0
  99. package/dist/lib/openai.js.map +1 -0
  100. package/dist/lib/prompts.d.ts +8 -0
  101. package/dist/lib/prompts.d.ts.map +1 -0
  102. package/dist/lib/prompts.js +258 -0
  103. package/dist/lib/prompts.js.map +1 -0
  104. package/dist/lib/r2.d.ts +7 -0
  105. package/dist/lib/r2.d.ts.map +1 -0
  106. package/dist/lib/r2.js +49 -0
  107. package/dist/lib/r2.js.map +1 -0
  108. package/dist/lib/session-helpers.d.ts +8 -0
  109. package/dist/lib/session-helpers.d.ts.map +1 -0
  110. package/dist/lib/session-helpers.js +31 -0
  111. package/dist/lib/session-helpers.js.map +1 -0
  112. package/dist/lib/supabase.d.ts +2 -0
  113. package/dist/lib/supabase.d.ts.map +1 -0
  114. package/dist/lib/supabase.js +11 -0
  115. package/dist/lib/supabase.js.map +1 -0
  116. package/dist/lib/twilio.d.ts +7 -0
  117. package/dist/lib/twilio.d.ts.map +1 -0
  118. package/dist/lib/twilio.js +34 -0
  119. package/dist/lib/twilio.js.map +1 -0
  120. package/dist/lib/vapi.d.ts +4 -0
  121. package/dist/lib/vapi.d.ts.map +1 -0
  122. package/dist/lib/vapi.js +59 -0
  123. package/dist/lib/vapi.js.map +1 -0
  124. package/dist/mcp-server.d.ts +3 -0
  125. package/dist/mcp-server.d.ts.map +1 -0
  126. package/dist/mcp-server.js +177 -0
  127. package/dist/mcp-server.js.map +1 -0
  128. package/dist/types/index.d.ts +104 -0
  129. package/dist/types/index.d.ts.map +1 -0
  130. package/dist/types/index.js +3 -0
  131. package/dist/types/index.js.map +1 -0
  132. package/package.json +28 -0
  133. package/railway.json +14 -0
  134. package/src/agent.ts +123 -0
  135. package/src/api/routes/auth.ts +95 -0
  136. package/src/api/routes/identity.ts +112 -0
  137. package/src/api/routes/text-submission.ts +64 -0
  138. package/src/api/webhooks/twilio.ts +181 -0
  139. package/src/api/webhooks/vapi.ts +219 -0
  140. package/src/bot.ts +44 -0
  141. package/src/index.ts +11 -0
  142. package/src/jobs/compact-identity.ts +211 -0
  143. package/src/jobs/consent-call.ts +87 -0
  144. package/src/jobs/export-identity.ts +166 -0
  145. package/src/jobs/introduction-call.ts +101 -0
  146. package/src/jobs/reanalyze-identity.ts +65 -0
  147. package/src/jobs/run-matching.ts +243 -0
  148. package/src/jobs/scheduled-matching.ts +59 -0
  149. package/src/jobs/transcribe-session.ts +77 -0
  150. package/src/lib/anthropic.ts +37 -0
  151. package/src/lib/config.ts +81 -0
  152. package/src/lib/deepgram.ts +57 -0
  153. package/src/lib/inngest.ts +33 -0
  154. package/src/lib/openai.ts +14 -0
  155. package/src/lib/prompts.ts +266 -0
  156. package/src/lib/r2.ts +79 -0
  157. package/src/lib/session-helpers.ts +37 -0
  158. package/src/lib/supabase.ts +15 -0
  159. package/src/lib/twilio.ts +49 -0
  160. package/src/lib/vapi.ts +80 -0
  161. package/src/mcp-server.ts +195 -0
  162. package/src/types/index.ts +146 -0
  163. package/supabase/.branches/_current_branch +1 -0
  164. package/supabase/.temp/cli-latest +1 -0
  165. package/supabase/.temp/gotrue-version +1 -0
  166. package/supabase/.temp/pooler-url +1 -0
  167. package/supabase/.temp/postgres-version +1 -0
  168. package/supabase/.temp/project-ref +1 -0
  169. package/supabase/.temp/rest-version +1 -0
  170. package/supabase/.temp/storage-migration +1 -0
  171. package/supabase/.temp/storage-version +1 -0
  172. package/supabase/config.toml +384 -0
  173. package/supabase/migrations/20260303000000_initial_schema.sql +203 -0
  174. package/supabase/migrations/20260304000000_brand_consents.sql +13 -0
  175. package/tsconfig.json +25 -0
@@ -0,0 +1,56 @@
1
+ import { inngest } from "../lib/inngest.js";
2
+ import { supabase } from "../lib/supabase.js";
3
+ // Triggered manually or after prompt changes
4
+ // Replays all completed sessions through the current prompt version
5
+ // by re-firing session/transcribed for each session in order
6
+ export const reanalyze_identity = inngest.createFunction({ id: "reanalyze-identity", retries: 1 }, { event: "identity/reanalyze" }, async ({ event, step }) => {
7
+ const { user_id } = event.data;
8
+ // Load all completed sessions in chronological order
9
+ const sessions = await step.run("load-sessions", async () => {
10
+ const { data, error } = await supabase
11
+ .from("sessions")
12
+ .select("id, transcript_r2_key, raw_text, analysis_status")
13
+ .eq("user_id", user_id)
14
+ .in("analysis_status", ["complete", "error"])
15
+ .order("created_at", { ascending: true });
16
+ if (error)
17
+ throw new Error(`Failed to load sessions: ${error.message}`);
18
+ return data ?? [];
19
+ });
20
+ if (sessions.length === 0) {
21
+ return { skipped: true, reason: "no completed sessions" };
22
+ }
23
+ // Reset identity
24
+ await step.run("reset-identity", async () => {
25
+ await supabase
26
+ .from("identities")
27
+ .update({
28
+ base_profile: {},
29
+ modality_weights: {},
30
+ signal_completeness_score: 0,
31
+ session_count: 0,
32
+ ready_for_matching: false,
33
+ last_updated: new Date().toISOString(),
34
+ })
35
+ .eq("user_id", user_id);
36
+ // Clear all modality embeddings
37
+ await supabase
38
+ .from("identity_modality_embeddings")
39
+ .delete()
40
+ .eq("user_id", user_id);
41
+ });
42
+ // Re-fire each session through compact-identity sequentially
43
+ // Inngest will process them in order via event fan-out
44
+ for (const session of sessions) {
45
+ await step.sendEvent(`replay-${session.id}`, {
46
+ name: "session/transcribed",
47
+ data: {
48
+ user_id,
49
+ session_id: session.id,
50
+ transcript_r2_key: session.transcript_r2_key ?? "",
51
+ },
52
+ });
53
+ }
54
+ return { user_id, replayed: sessions.length };
55
+ });
56
+ //# sourceMappingURL=reanalyze-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reanalyze-identity.js","sourceRoot":"","sources":["../../src/jobs/reanalyze-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,6CAA6C;AAC7C,oEAAoE;AACpE,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc,CACtD,EAAE,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC,EAAE,EACxC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAC/B,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;IACxB,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;IAE/B,qDAAqD;IACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,QAAQ;aACnC,IAAI,CAAC,UAAU,CAAC;aAChB,MAAM,CAAC,kDAAkD,CAAC;aAC1D,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC;aACtB,EAAE,CAAC,iBAAiB,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;aAC5C,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,OAAO,IAAI,IAAI,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAC5D,CAAC;IAED,iBAAiB;IACjB,MAAM,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,QAAQ;aACX,IAAI,CAAC,YAAY,CAAC;aAClB,MAAM,CAAC;YACN,YAAY,EAAE,EAAE;YAChB,gBAAgB,EAAE,EAAE;YACpB,yBAAyB,EAAE,CAAC;YAC5B,aAAa,EAAE,CAAC;YAChB,kBAAkB,EAAE,KAAK;YACzB,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;aACD,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAE1B,gCAAgC;QAChC,MAAM,QAAQ;aACX,IAAI,CAAC,8BAA8B,CAAC;aACpC,MAAM,EAAE;aACR,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,6DAA6D;IAC7D,uDAAuD;IACvD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,OAAO,CAAC,EAAE,EAAE,EAAE;YAC3C,IAAI,EAAE,qBAAqB;YAC3B,IAAI,EAAE;gBACJ,OAAO;gBACP,UAAU,EAAE,OAAO,CAAC,EAAE;gBACtB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,EAAE;aACnD;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AAChD,CAAC,CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const run_matching: any;
2
+ //# sourceMappingURL=run-matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-matching.d.ts","sourceRoot":"","sources":["../../src/jobs/run-matching.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,YAAY,KAoNxB,CAAC"}
@@ -0,0 +1,200 @@
1
+ import { inngest } from "../lib/inngest.js";
2
+ import { supabase } from "../lib/supabase.js";
3
+ import { complete, extract_json } from "../lib/anthropic.js";
4
+ import { SYSTEM_MATCH_VALIDATION } from "../lib/prompts.js";
5
+ const WORLD_VIEW_DELTA_MAX = 0.5;
6
+ const CONFIDENCE_THRESHOLD = 0.70;
7
+ const MAX_MATCHES_IN_QUEUE = 10;
8
+ const VECTOR_CANDIDATES_PER_MODALITY = 30;
9
+ // Triggered when a user's identity is updated
10
+ // 1. Vector search per active modality via pgvector RPC
11
+ // 2. Hard-filter on worldview bifurcations
12
+ // 3. LLM-validate each candidate
13
+ // 4. Insert confirmed matches + fire match/confirmed
14
+ export const run_matching = inngest.createFunction({ id: "run-matching", retries: 2 }, { event: "identity/updated" }, async ({ event, step }) => {
15
+ const { user_id } = event.data;
16
+ // ── Load identity ─────────────────────────────────────────────────────────
17
+ const identity = await step.run("load-identity", async () => {
18
+ const { data, error } = await supabase
19
+ .from("identities")
20
+ .select("base_profile, modality_weights, signal_completeness_score, ready_for_matching")
21
+ .eq("user_id", user_id)
22
+ .single();
23
+ if (error || !data)
24
+ throw new Error("Identity not found");
25
+ return data;
26
+ });
27
+ if (!identity.ready_for_matching) {
28
+ return { skipped: true, reason: "not ready for matching" };
29
+ }
30
+ // ── Check queue capacity ──────────────────────────────────────────────────
31
+ const { count: pending_count } = await supabase
32
+ .from("matches")
33
+ .select("*", { count: "exact", head: true })
34
+ .or(`user_a_id.eq.${user_id},user_b_id.eq.${user_id}`)
35
+ .eq("status", "pending_consent");
36
+ if ((pending_count ?? 0) >= MAX_MATCHES_IN_QUEUE) {
37
+ return { skipped: true, reason: "match queue full" };
38
+ }
39
+ const slots_available = MAX_MATCHES_IN_QUEUE - (pending_count ?? 0);
40
+ // ── Load user's modality embeddings ───────────────────────────────────────
41
+ const my_embeddings = await step.run("load-embeddings", async () => {
42
+ const { data } = await supabase
43
+ .from("identity_modality_embeddings")
44
+ .select("modality, embedding")
45
+ .eq("user_id", user_id);
46
+ return data ?? [];
47
+ });
48
+ if (my_embeddings.length === 0) {
49
+ return { skipped: true, reason: "no embeddings yet" };
50
+ }
51
+ // ── Build exclusion set (existing matches + declined pairs) ───────────────
52
+ const [existing_matches, declined_pairs] = await Promise.all([
53
+ supabase
54
+ .from("matches")
55
+ .select("user_a_id, user_b_id")
56
+ .or(`user_a_id.eq.${user_id},user_b_id.eq.${user_id}`),
57
+ supabase
58
+ .from("declined_pairs")
59
+ .select("user_a_id, user_b_id")
60
+ .or(`user_a_id.eq.${user_id},user_b_id.eq.${user_id}`),
61
+ ]);
62
+ const excluded_ids = new Set([user_id]); // always exclude self
63
+ for (const p of existing_matches.data ?? []) {
64
+ excluded_ids.add(p.user_a_id);
65
+ excluded_ids.add(p.user_b_id);
66
+ }
67
+ for (const p of declined_pairs.data ?? []) {
68
+ excluded_ids.add(p.user_a_id);
69
+ excluded_ids.add(p.user_b_id);
70
+ }
71
+ // ── Vector search per active modality ─────────────────────────────────────
72
+ // Best similarity per candidate across all modality searches
73
+ const candidate_scores = new Map();
74
+ const vector_results = await step.run("vector-search", async () => {
75
+ const results = [];
76
+ for (const { modality, embedding } of my_embeddings) {
77
+ const { data, error } = await supabase.rpc("match_identities", {
78
+ p_user_id: user_id,
79
+ p_modality: modality,
80
+ p_embedding: embedding,
81
+ p_limit: VECTOR_CANDIDATES_PER_MODALITY,
82
+ });
83
+ if (error) {
84
+ console.error(`match_identities RPC error for modality ${modality}:`, error);
85
+ continue;
86
+ }
87
+ for (const row of data ?? []) {
88
+ results.push(row);
89
+ }
90
+ }
91
+ return results;
92
+ });
93
+ for (const row of vector_results) {
94
+ if (excluded_ids.has(row.user_id))
95
+ continue;
96
+ const existing = candidate_scores.get(row.user_id);
97
+ if (!existing || row.similarity > existing.similarity) {
98
+ candidate_scores.set(row.user_id, {
99
+ similarity: row.similarity,
100
+ modality: row.modality,
101
+ });
102
+ }
103
+ }
104
+ // Sort by similarity descending, take top 20 for LLM validation
105
+ const ranked_candidates = Array.from(candidate_scores.entries())
106
+ .sort((a, b) => b[1].similarity - a[1].similarity)
107
+ .slice(0, 20)
108
+ .map(([cid, meta]) => ({ user_id: cid, ...meta }));
109
+ if (ranked_candidates.length === 0) {
110
+ return { user_id, confirmed_matches: 0, reason: "no vector candidates" };
111
+ }
112
+ // ── Load candidate full profiles ──────────────────────────────────────────
113
+ const candidate_ids = ranked_candidates.map((c) => c.user_id);
114
+ const { data: candidate_profiles } = await supabase
115
+ .from("identities")
116
+ .select("user_id, base_profile, modality_weights")
117
+ .in("user_id", candidate_ids);
118
+ const profile_map = new Map((candidate_profiles ?? []).map((p) => [p.user_id, p]));
119
+ // ── Hard filter: worldview bifurcation gates ──────────────────────────────
120
+ const a_wv = identity.base_profile.worldview;
121
+ const passing_candidates = ranked_candidates.filter((c) => {
122
+ const profile = profile_map.get(c.user_id);
123
+ if (!profile)
124
+ return false;
125
+ const b_wv = profile.base_profile.worldview;
126
+ const danger_delta = Math.abs(a_wv.world_danger_adventure - b_wv.world_danger_adventure);
127
+ const people_delta = Math.abs(a_wv.people_good_bad - b_wv.people_good_bad);
128
+ return danger_delta <= WORLD_VIEW_DELTA_MAX && people_delta <= WORLD_VIEW_DELTA_MAX;
129
+ });
130
+ // ── LLM validation ────────────────────────────────────────────────────────
131
+ const confirmed_matches = [];
132
+ for (const candidate of passing_candidates) {
133
+ if (confirmed_matches.length >= slots_available)
134
+ break;
135
+ const profile = profile_map.get(candidate.user_id);
136
+ const primary_modality = dominant_shared_modality(identity.modality_weights, profile.modality_weights);
137
+ const assessment_raw = await step.run(`validate-${candidate.user_id}`, async () => complete("matching", SYSTEM_MATCH_VALIDATION, [
138
+ `Person A profile (${primary_modality} lens):\n${JSON.stringify(identity.base_profile, null, 2)}`,
139
+ `Person A modality weights: ${JSON.stringify(identity.modality_weights)}`,
140
+ `\nPerson B profile (${primary_modality} lens):\n${JSON.stringify(profile.base_profile, null, 2)}`,
141
+ `Person B modality weights: ${JSON.stringify(profile.modality_weights)}`,
142
+ `\nVector similarity score: ${candidate.similarity.toFixed(3)} (modality: ${candidate.modality})`,
143
+ ].join("\n\n")));
144
+ let assessment;
145
+ try {
146
+ assessment = JSON.parse(extract_json(assessment_raw));
147
+ }
148
+ catch {
149
+ console.error(`Failed to parse assessment for ${candidate.user_id}`);
150
+ continue;
151
+ }
152
+ if (!assessment.compatible || assessment.tension_fatal)
153
+ continue;
154
+ if (assessment.confidence < CONFIDENCE_THRESHOLD)
155
+ continue;
156
+ // Insert match and capture the generated UUID
157
+ const { data: match_row, error: insert_error } = await supabase
158
+ .from("matches")
159
+ .insert({
160
+ user_a_id: user_id,
161
+ user_b_id: candidate.user_id,
162
+ primary_modality,
163
+ cross_modality: assessment.cross_modality ?? false,
164
+ cross_modality_bridge: assessment.cross_modality_bridge ?? null,
165
+ confidence_score: assessment.confidence,
166
+ resonances: assessment.resonances ?? [],
167
+ tensions: assessment.tensions ?? [],
168
+ tension_fatal: false,
169
+ consent_call_framing: assessment.consent_call_framing ?? "",
170
+ status: "pending_consent",
171
+ created_at: new Date().toISOString(),
172
+ })
173
+ .select("id")
174
+ .single();
175
+ if (insert_error || !match_row) {
176
+ console.error("Failed to insert match:", insert_error);
177
+ continue;
178
+ }
179
+ confirmed_matches.push(candidate.user_id);
180
+ await step.sendEvent(`match-confirmed-${match_row.id}`, {
181
+ name: "match/confirmed",
182
+ data: { match_id: match_row.id },
183
+ });
184
+ }
185
+ return { user_id, confirmed_matches: confirmed_matches.length };
186
+ });
187
+ function dominant_shared_modality(a, b) {
188
+ const modalities = Object.keys(a);
189
+ let best = modalities[0];
190
+ let best_score = 0;
191
+ for (const m of modalities) {
192
+ const score = Math.min(a[m], b[m]);
193
+ if (score > best_score) {
194
+ best_score = score;
195
+ best = m;
196
+ }
197
+ }
198
+ return best;
199
+ }
200
+ //# sourceMappingURL=run-matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-matching.js","sourceRoot":"","sources":["../../src/jobs/run-matching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const scheduled_matching: any;
2
+ //# sourceMappingURL=scheduled-matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-matching.d.ts","sourceRoot":"","sources":["../../src/jobs/scheduled-matching.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kBAAkB,KAmD9B,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { inngest } from "../lib/inngest.js";
2
+ import { supabase } from "../lib/supabase.js";
3
+ const MAX_MATCHES_IN_QUEUE = 10;
4
+ // Hourly cron — finds all ready users with queue capacity and re-runs matching
5
+ // Ensures new users get found by existing users even without a new session
6
+ export const scheduled_matching = inngest.createFunction({ id: "scheduled-matching", retries: 1 }, { cron: "0 * * * *" }, // every hour on the hour
7
+ async ({ step }) => {
8
+ // Find all users ready for matching
9
+ const eligible_users = await step.run("find-eligible-users", async () => {
10
+ const { data, error } = await supabase
11
+ .from("identities")
12
+ .select("user_id")
13
+ .eq("ready_for_matching", true);
14
+ if (error)
15
+ throw new Error(`Failed to load eligible users: ${error.message}`);
16
+ return data ?? [];
17
+ });
18
+ if (eligible_users.length === 0) {
19
+ return { triggered: 0 };
20
+ }
21
+ // Filter to those with queue capacity
22
+ const user_ids = eligible_users.map((u) => u.user_id);
23
+ const { data: queue_counts } = await supabase
24
+ .from("matches")
25
+ .select("user_a_id, user_b_id")
26
+ .or(user_ids.map((id) => `user_a_id.eq.${id},user_b_id.eq.${id}`).join(","))
27
+ .eq("status", "pending_consent");
28
+ // Count pending matches per user
29
+ const pending_per_user = new Map();
30
+ for (const row of queue_counts ?? []) {
31
+ pending_per_user.set(row.user_a_id, (pending_per_user.get(row.user_a_id) ?? 0) + 1);
32
+ pending_per_user.set(row.user_b_id, (pending_per_user.get(row.user_b_id) ?? 0) + 1);
33
+ }
34
+ const users_with_capacity = user_ids.filter((id) => (pending_per_user.get(id) ?? 0) < MAX_MATCHES_IN_QUEUE);
35
+ // Fan out identity/updated events — run_matching handles each
36
+ if (users_with_capacity.length > 0) {
37
+ await step.sendEvent("scheduled-matching-fanout", users_with_capacity.map((user_id) => ({
38
+ name: "identity/updated",
39
+ data: { user_id },
40
+ })));
41
+ }
42
+ return { triggered: users_with_capacity.length, total_eligible: eligible_users.length };
43
+ });
44
+ //# sourceMappingURL=scheduled-matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-matching.js","sourceRoot":"","sources":["../../src/jobs/scheduled-matching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const transcribe_session: any;
2
+ //# sourceMappingURL=transcribe-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcribe-session.d.ts","sourceRoot":"","sources":["../../src/jobs/transcribe-session.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kBAAkB,KAqE9B,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { inngest } from "../lib/inngest.js";
2
+ import { supabase } from "../lib/supabase.js";
3
+ import { transcribe_url, user_speech_only } from "../lib/deepgram.js";
4
+ import { generate_presigned_get_url, upload_json } from "../lib/r2.js";
5
+ // Triggered when a voice session recording lands in R2
6
+ // Runs transcription, stores result, fires next event
7
+ export const transcribe_session = inngest.createFunction({ id: "transcribe-session", retries: 3 }, { event: "session/completed" }, async ({ event, step }) => {
8
+ const { user_id, session_id } = event.data;
9
+ // Mark as processing
10
+ await step.run("mark-processing", async () => {
11
+ await supabase
12
+ .from("sessions")
13
+ .update({ analysis_status: "processing" })
14
+ .eq("id", session_id);
15
+ });
16
+ // Get session record to find audio key
17
+ const session = await step.run("get-session", async () => {
18
+ const { data, error } = await supabase
19
+ .from("sessions")
20
+ .select("audio_r2_key")
21
+ .eq("id", session_id)
22
+ .single();
23
+ if (error || !data)
24
+ throw new Error(`Session not found: ${session_id}`);
25
+ if (!data.audio_r2_key)
26
+ throw new Error(`No audio_r2_key for session: ${session_id}`);
27
+ return data;
28
+ });
29
+ // Generate presigned URL for Deepgram to fetch audio from R2
30
+ const audio_url = await step.run("presign-url", async () => {
31
+ return generate_presigned_get_url(session.audio_r2_key, 3600);
32
+ });
33
+ // Transcribe via Deepgram
34
+ const result = await step.run("transcribe", async () => {
35
+ return transcribe_url(audio_url);
36
+ });
37
+ // Extract user-only speech (speaker 0 = user)
38
+ const user_transcript = user_speech_only(result);
39
+ // Store transcript JSON to R2
40
+ const transcript_r2_key = `transcripts/${user_id}/${session_id}.json`;
41
+ await step.run("store-transcript", async () => {
42
+ await upload_json(transcript_r2_key, {
43
+ full: result,
44
+ text: user_transcript,
45
+ stored_at: new Date().toISOString(),
46
+ });
47
+ });
48
+ // Update session record
49
+ await step.run("update-session", async () => {
50
+ await supabase
51
+ .from("sessions")
52
+ .update({
53
+ transcript_r2_key,
54
+ analysis_status: "pending", // reset so compact-identity picks it up
55
+ duration_seconds: Math.round(result.duration_seconds),
56
+ })
57
+ .eq("id", session_id);
58
+ });
59
+ // Fire next job
60
+ await step.sendEvent("trigger-analysis", {
61
+ name: "session/transcribed",
62
+ data: { user_id, session_id, transcript_r2_key },
63
+ });
64
+ return { session_id, duration_seconds: result.duration_seconds };
65
+ });
66
+ //# sourceMappingURL=transcribe-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcribe-session.js","sourceRoot":"","sources":["../../src/jobs/transcribe-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const anthropic: any;
2
+ export declare function extract_json(raw: string): string;
3
+ export declare function complete(model: "conversation" | "analysis" | "matching", system: string, user: string, max_tokens?: number): Promise<string>;
4
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/lib/anthropic.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,SAAS,KAEpB,CAAC;AAGH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQhD;AAGD,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,cAAc,GAAG,UAAU,GAAG,UAAU,EAC/C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,CAYjB"}
@@ -0,0 +1,32 @@
1
+ import Anthropic from "@anthropic-ai/sdk";
2
+ import { config } from "./config.js";
3
+ export const anthropic = new Anthropic({
4
+ apiKey: config.anthropic.api_key,
5
+ });
6
+ // Strip markdown code fences from LLM output and return raw JSON string
7
+ export function extract_json(raw) {
8
+ const fence = raw.match(/```(?:json)?\s*([\s\S]*?)```/);
9
+ if (fence)
10
+ return fence[1].trim();
11
+ // Try to find first { or [ and last } or ]
12
+ const start = raw.search(/[{[]/);
13
+ const end = Math.max(raw.lastIndexOf("}"), raw.lastIndexOf("]"));
14
+ if (start !== -1 && end !== -1 && end > start)
15
+ return raw.slice(start, end + 1);
16
+ return raw.trim();
17
+ }
18
+ // Thin wrapper — returns text content from a single-turn message
19
+ export async function complete(model, system, user, max_tokens) {
20
+ const default_tokens = model === "analysis" ? 8192 : 4096;
21
+ const response = await anthropic.messages.create({
22
+ model: config.anthropic.models[model],
23
+ max_tokens: max_tokens ?? default_tokens,
24
+ system,
25
+ messages: [{ role: "user", content: user }],
26
+ });
27
+ const block = response.content[0];
28
+ if (block.type !== "text")
29
+ throw new Error("Unexpected non-text response");
30
+ return block.text;
31
+ }
32
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/lib/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO;CACjC,CAAC,CAAC;AAEH,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACxD,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,2CAA2C;IAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,KAAK;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;AACpB,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAA+C,EAC/C,MAAc,EACd,IAAY,EACZ,UAAmB;IAEnB,MAAM,cAAc,GAAG,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC/C,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;QACrC,UAAU,EAAE,UAAU,IAAI,cAAc;QACxC,MAAM;QACN,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;KAC5C,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC3E,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import "dotenv/config";
2
+ export declare const config: {
3
+ readonly supabase: {
4
+ readonly url: string;
5
+ readonly service_role_key: string;
6
+ };
7
+ readonly twilio: {
8
+ readonly account_sid: string;
9
+ readonly auth_token: string;
10
+ readonly verify_service_sid: string;
11
+ readonly numbers: {
12
+ readonly "meet-the-one": string;
13
+ readonly casual: any;
14
+ readonly kink: any;
15
+ readonly adventure: any;
16
+ readonly "open-poly": any;
17
+ };
18
+ };
19
+ readonly vapi: {
20
+ readonly api_key: string;
21
+ readonly intake_assistant_id: string;
22
+ readonly consent_assistant_id: string;
23
+ };
24
+ readonly anthropic: {
25
+ readonly api_key: string;
26
+ readonly models: {
27
+ readonly conversation: "claude-sonnet-4-6";
28
+ readonly analysis: "claude-opus-4-6";
29
+ readonly matching: "claude-sonnet-4-6";
30
+ };
31
+ };
32
+ readonly openai: {
33
+ readonly api_key: string;
34
+ readonly embedding_model: "text-embedding-3-large";
35
+ readonly embedding_dimensions: 1536;
36
+ };
37
+ readonly deepgram: {
38
+ readonly api_key: string;
39
+ readonly model: "nova-2";
40
+ };
41
+ readonly r2: {
42
+ readonly account_id: string;
43
+ readonly access_key_id: string;
44
+ readonly secret_access_key: string;
45
+ readonly bucket: string;
46
+ readonly endpoint: `https://${string}.r2.cloudflarestorage.com`;
47
+ };
48
+ readonly inngest: {
49
+ readonly event_key: string;
50
+ readonly signing_key: string;
51
+ };
52
+ readonly app: {
53
+ readonly url: any;
54
+ readonly port: number;
55
+ };
56
+ };
57
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAQvB,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwET,CAAC"}
@@ -0,0 +1,73 @@
1
+ import "dotenv/config";
2
+ function require_env(key) {
3
+ const val = process.env[key];
4
+ if (!val)
5
+ throw new Error(`Missing required env var: ${key}`);
6
+ return val;
7
+ }
8
+ export const config = {
9
+ // Supabase
10
+ supabase: {
11
+ url: require_env("SUPABASE_URL"),
12
+ service_role_key: require_env("SUPABASE_SERVICE_ROLE_KEY"),
13
+ },
14
+ // Twilio
15
+ twilio: {
16
+ account_sid: require_env("TWILIO_ACCOUNT_SID"),
17
+ auth_token: require_env("TWILIO_AUTH_TOKEN"),
18
+ verify_service_sid: require_env("TWILIO_VERIFY_SERVICE_SID"),
19
+ // Phone numbers per brand
20
+ numbers: {
21
+ "meet-the-one": require_env("TWILIO_NUMBER_FLAGSHIP"),
22
+ casual: process.env["TWILIO_NUMBER_CASUAL"] ?? "",
23
+ kink: process.env["TWILIO_NUMBER_KINK"] ?? "",
24
+ adventure: process.env["TWILIO_NUMBER_ADVENTURE"] ?? "",
25
+ "open-poly": process.env["TWILIO_NUMBER_OPEN_POLY"] ?? "",
26
+ },
27
+ },
28
+ // Vapi (voice AI — v0.1)
29
+ vapi: {
30
+ api_key: require_env("VAPI_API_KEY"),
31
+ intake_assistant_id: require_env("VAPI_INTAKE_ASSISTANT_ID"),
32
+ consent_assistant_id: require_env("VAPI_CONSENT_ASSISTANT_ID"),
33
+ },
34
+ // Anthropic
35
+ anthropic: {
36
+ api_key: require_env("ANTHROPIC_API_KEY"),
37
+ models: {
38
+ conversation: "claude-sonnet-4-6",
39
+ analysis: "claude-opus-4-6",
40
+ matching: "claude-sonnet-4-6",
41
+ },
42
+ },
43
+ // OpenAI (embeddings)
44
+ openai: {
45
+ api_key: require_env("OPENAI_API_KEY"),
46
+ embedding_model: "text-embedding-3-large",
47
+ embedding_dimensions: 1536, // truncated — pgvector local limit is 2000
48
+ },
49
+ // Deepgram (transcription)
50
+ deepgram: {
51
+ api_key: require_env("DEEPGRAM_API_KEY"),
52
+ model: "nova-2",
53
+ },
54
+ // Cloudflare R2 (audio/transcript storage)
55
+ r2: {
56
+ account_id: require_env("CLOUDFLARE_ACCOUNT_ID"),
57
+ access_key_id: require_env("R2_ACCESS_KEY_ID"),
58
+ secret_access_key: require_env("R2_SECRET_ACCESS_KEY"),
59
+ bucket: require_env("R2_BUCKET_NAME"),
60
+ endpoint: `https://${require_env("CLOUDFLARE_ACCOUNT_ID")}.r2.cloudflarestorage.com`,
61
+ },
62
+ // Inngest
63
+ inngest: {
64
+ event_key: require_env("INNGEST_EVENT_KEY"),
65
+ signing_key: require_env("INNGEST_SIGNING_KEY"),
66
+ },
67
+ // App
68
+ app: {
69
+ url: process.env["APP_URL"] ?? "http://localhost:3000",
70
+ port: parseInt(process.env["PORT"] ?? "3000", 10),
71
+ },
72
+ };
73
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AAEvB,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;IAC9D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,WAAW;IACX,QAAQ,EAAE;QACR,GAAG,EAAE,WAAW,CAAC,cAAc,CAAC;QAChC,gBAAgB,EAAE,WAAW,CAAC,2BAA2B,CAAC;KAC3D;IAED,SAAS;IACT,MAAM,EAAE;QACN,WAAW,EAAE,WAAW,CAAC,oBAAoB,CAAC;QAC9C,UAAU,EAAE,WAAW,CAAC,mBAAmB,CAAC;QAC5C,kBAAkB,EAAE,WAAW,CAAC,2BAA2B,CAAC;QAC5D,0BAA0B;QAC1B,OAAO,EAAE;YACP,cAAc,EAAE,WAAW,CAAC,wBAAwB,CAAC;YACrD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE;YACjD,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,EAAE;YAC7C,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,EAAE;YACvD,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,EAAE;SAC1D;KACF;IAED,yBAAyB;IACzB,IAAI,EAAE;QACJ,OAAO,EAAE,WAAW,CAAC,cAAc,CAAC;QACpC,mBAAmB,EAAE,WAAW,CAAC,0BAA0B,CAAC;QAC5D,oBAAoB,EAAE,WAAW,CAAC,2BAA2B,CAAC;KAC/D;IAED,YAAY;IACZ,SAAS,EAAE;QACT,OAAO,EAAE,WAAW,CAAC,mBAAmB,CAAC;QACzC,MAAM,EAAE;YACN,YAAY,EAAE,mBAAmB;YACjC,QAAQ,EAAE,iBAAiB;YAC3B,QAAQ,EAAE,mBAAmB;SAC9B;KACF;IAED,sBAAsB;IACtB,MAAM,EAAE;QACN,OAAO,EAAE,WAAW,CAAC,gBAAgB,CAAC;QACtC,eAAe,EAAE,wBAAwB;QACzC,oBAAoB,EAAE,IAAI,EAAE,2CAA2C;KACxE;IAED,2BAA2B;IAC3B,QAAQ,EAAE;QACR,OAAO,EAAE,WAAW,CAAC,kBAAkB,CAAC;QACxC,KAAK,EAAE,QAAQ;KAChB;IAED,2CAA2C;IAC3C,EAAE,EAAE;QACF,UAAU,EAAE,WAAW,CAAC,uBAAuB,CAAC;QAChD,aAAa,EAAE,WAAW,CAAC,kBAAkB,CAAC;QAC9C,iBAAiB,EAAE,WAAW,CAAC,sBAAsB,CAAC;QACtD,MAAM,EAAE,WAAW,CAAC,gBAAgB,CAAC;QACrC,QAAQ,EAAE,WAAW,WAAW,CAAC,uBAAuB,CAAC,2BAA2B;KACrF;IAED,UAAU;IACV,OAAO,EAAE;QACP,SAAS,EAAE,WAAW,CAAC,mBAAmB,CAAC;QAC3C,WAAW,EAAE,WAAW,CAAC,qBAAqB,CAAC;KAChD;IAED,MAAM;IACN,GAAG,EAAE;QACH,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,uBAAuB;QACtD,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,EAAE,CAAC;KAClD;CACO,CAAC"}
@@ -0,0 +1,15 @@
1
+ export declare const deepgram: any;
2
+ export interface TranscriptResult {
3
+ transcript: string;
4
+ words: Array<{
5
+ word: string;
6
+ start: number;
7
+ end: number;
8
+ confidence: number;
9
+ speaker: number;
10
+ }>;
11
+ duration_seconds: number;
12
+ }
13
+ export declare function transcribe_url(audio_url: string): Promise<TranscriptResult>;
14
+ export declare function user_speech_only(result: TranscriptResult): string;
15
+ //# sourceMappingURL=deepgram.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deepgram.d.ts","sourceRoot":"","sources":["../../src/lib/deepgram.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,KAAwC,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAGD,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,CAAC,CA4B3B;AAGD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAKjE"}