@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,195 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import {
5
+ CallToolRequestSchema,
6
+ ListToolsRequestSchema,
7
+ } from "@modelcontextprotocol/sdk/types.js";
8
+ import { Redis } from "ioredis";
9
+ import { randomUUID } from "crypto";
10
+
11
+ const USER_ID = process.env.USER_ID ?? "";
12
+ const redis = new Redis(process.env.REDIS_URL ?? "redis://localhost:6379");
13
+
14
+ const server = new Server(
15
+ { name: "dating-tools", version: "1.0.0" },
16
+ { capabilities: { tools: {} } }
17
+ );
18
+
19
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
20
+ tools: [
21
+ {
22
+ name: "create_profile",
23
+ description: "Create or update a dating profile for the current user",
24
+ inputSchema: {
25
+ type: "object" as const,
26
+ properties: {
27
+ name: { type: "string", description: "User's display name" },
28
+ age: { type: "number", description: "User's age" },
29
+ bio: { type: "string", description: "Short bio" },
30
+ preferences: { type: "string", description: "What user is looking for in a partner" },
31
+ dealbreakers: { type: "string", description: "User's dealbreakers" },
32
+ },
33
+ required: ["name", "age", "bio", "preferences", "dealbreakers"],
34
+ },
35
+ },
36
+ {
37
+ name: "get_my_profile",
38
+ description: "Get the current user's dating profile",
39
+ inputSchema: { type: "object" as const, properties: {} },
40
+ },
41
+ {
42
+ name: "list_profiles",
43
+ description: "List all profiles in the system (for matchmaking evaluation)",
44
+ inputSchema: { type: "object" as const, properties: {} },
45
+ },
46
+ {
47
+ name: "request_match",
48
+ description: "Send a match request with an intro message to another user",
49
+ inputSchema: {
50
+ type: "object" as const,
51
+ properties: {
52
+ target_profile_id: { type: "string", description: "The user ID to request a match with" },
53
+ intro_message: { type: "string", description: "Personalized introduction message" },
54
+ },
55
+ required: ["target_profile_id", "intro_message"],
56
+ },
57
+ },
58
+ {
59
+ name: "get_match_requests",
60
+ description: "Get incoming match requests for the current user",
61
+ inputSchema: { type: "object" as const, properties: {} },
62
+ },
63
+ {
64
+ name: "respond_to_match",
65
+ description: "Accept or decline a match request",
66
+ inputSchema: {
67
+ type: "object" as const,
68
+ properties: {
69
+ request_id: { type: "string", description: "The match request ID" },
70
+ accepted: { type: "boolean", description: "Whether to accept the match" },
71
+ message: { type: "string", description: "Optional response message" },
72
+ },
73
+ required: ["request_id", "accepted"],
74
+ },
75
+ },
76
+ {
77
+ name: "get_matched_pairs",
78
+ description: "Get all accepted matches in the system",
79
+ inputSchema: { type: "object" as const, properties: {} },
80
+ },
81
+ ],
82
+ }));
83
+
84
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
85
+ const { name, arguments: args } = request.params;
86
+ const a = (args ?? {}) as Record<string, unknown>;
87
+
88
+ try {
89
+ switch (name) {
90
+ case "create_profile": {
91
+ const profile = {
92
+ id: USER_ID,
93
+ name: a.name,
94
+ age: a.age,
95
+ bio: a.bio,
96
+ preferences: a.preferences,
97
+ dealbreakers: a.dealbreakers,
98
+ createdAt: new Date().toISOString(),
99
+ };
100
+ await redis.set(`dating:profile:${USER_ID}`, JSON.stringify(profile));
101
+ return { content: [{ type: "text" as const, text: `Profile created! Your ID: ${USER_ID}` }] };
102
+ }
103
+
104
+ case "get_my_profile": {
105
+ const data = await redis.get(`dating:profile:${USER_ID}`);
106
+ if (!data) {
107
+ return { content: [{ type: "text" as const, text: "No profile yet — let's create one!" }] };
108
+ }
109
+ return { content: [{ type: "text" as const, text: data }] };
110
+ }
111
+
112
+ case "list_profiles": {
113
+ const keys = await redis.keys("dating:profile:*");
114
+ if (keys.length === 0) {
115
+ return { content: [{ type: "text" as const, text: "[]" }] };
116
+ }
117
+ const profiles = await Promise.all(keys.map((k: string) => redis.get(k)));
118
+ const result = profiles.filter(Boolean).map((p: string | null) => JSON.parse(p!));
119
+ return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
120
+ }
121
+
122
+ case "request_match": {
123
+ const id = randomUUID();
124
+ const req = {
125
+ id,
126
+ fromUserId: USER_ID,
127
+ toUserId: a.target_profile_id,
128
+ introMessage: a.intro_message,
129
+ status: "pending",
130
+ createdAt: new Date().toISOString(),
131
+ };
132
+ await redis.set(`dating:match_request:${id}`, JSON.stringify(req));
133
+ await redis.sadd(`dating:requests_to:${a.target_profile_id}`, id);
134
+ return { content: [{ type: "text" as const, text: `Match request sent! Request ID: ${id}` }] };
135
+ }
136
+
137
+ case "get_match_requests": {
138
+ const requestIds = await redis.smembers(`dating:requests_to:${USER_ID}`);
139
+ if (requestIds.length === 0) {
140
+ return { content: [{ type: "text" as const, text: "No pending match requests." }] };
141
+ }
142
+ const requests = await Promise.all(
143
+ requestIds.map((id: string) => redis.get(`dating:match_request:${id}`))
144
+ );
145
+ const result = requests.filter(Boolean).map((r: string | null) => JSON.parse(r!));
146
+ return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
147
+ }
148
+
149
+ case "respond_to_match": {
150
+ const data = await redis.get(`dating:match_request:${a.request_id}`);
151
+ if (!data) {
152
+ return { content: [{ type: "text" as const, text: "Request not found." }] };
153
+ }
154
+ const req = JSON.parse(data) as Record<string, unknown>;
155
+ req.status = a.accepted ? "accepted" : "declined";
156
+ if (a.message) req.responseMessage = a.message;
157
+ req.respondedAt = new Date().toISOString();
158
+ await redis.set(`dating:match_request:${a.request_id}`, JSON.stringify(req));
159
+ if (a.accepted) {
160
+ const pairId = randomUUID();
161
+ const pair = {
162
+ id: pairId,
163
+ user1: req.fromUserId,
164
+ user2: req.toUserId,
165
+ matchedAt: new Date().toISOString(),
166
+ };
167
+ await redis.set(`dating:match:${pairId}`, JSON.stringify(pair));
168
+ await redis.sadd("dating:matches", pairId);
169
+ }
170
+ return {
171
+ content: [{ type: "text" as const, text: `Request ${a.accepted ? "accepted! You have a new match 🎉" : "declined."}` }],
172
+ };
173
+ }
174
+
175
+ case "get_matched_pairs": {
176
+ const pairIds = await redis.smembers("dating:matches");
177
+ if (pairIds.length === 0) {
178
+ return { content: [{ type: "text" as const, text: "No matches yet." }] };
179
+ }
180
+ const pairs = await Promise.all(pairIds.map((id: string) => redis.get(`dating:match:${id}`)));
181
+ const result = pairs.filter(Boolean).map((p: string | null) => JSON.parse(p!));
182
+ return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }] };
183
+ }
184
+
185
+ default:
186
+ return { content: [{ type: "text" as const, text: `Unknown tool: ${name}` }], isError: true };
187
+ }
188
+ } catch (error) {
189
+ const msg = error instanceof Error ? error.message : String(error);
190
+ return { content: [{ type: "text" as const, text: `Error: ${msg}` }], isError: true };
191
+ }
192
+ });
193
+
194
+ const transport = new StdioServerTransport();
195
+ await server.connect(transport);
@@ -0,0 +1,146 @@
1
+ // ─── User & Identity ──────────────────────────────────────────────────────────
2
+
3
+ export type Brand =
4
+ | "meet-the-one"
5
+ | "casual"
6
+ | "kink"
7
+ | "adventure"
8
+ | "open-poly";
9
+
10
+ export interface User {
11
+ id: string;
12
+ phone_e164: string;
13
+ email?: string;
14
+ brand: Brand;
15
+ created_at: string;
16
+ verified_at?: string;
17
+ }
18
+
19
+ // ─── Sessions ─────────────────────────────────────────────────────────────────
20
+
21
+ export type SessionSource = "vapi" | "twilio_direct" | "text";
22
+
23
+ export type TimeOfDayBucket =
24
+ | "morning"
25
+ | "afternoon"
26
+ | "evening"
27
+ | "late_night";
28
+
29
+ export type AnalysisStatus = "pending" | "processing" | "complete" | "failed" | "stale";
30
+
31
+ export interface Session {
32
+ session_id: string;
33
+ user_id: string;
34
+ started_at: string;
35
+ ended_at?: string;
36
+ duration_seconds?: number;
37
+ source: SessionSource;
38
+ time_of_day_bucket: TimeOfDayBucket;
39
+ session_number: number;
40
+ late_night_flag: boolean;
41
+ audio_r2_key?: string;
42
+ transcript_r2_key?: string;
43
+ transcription_status: "pending" | "processing" | "complete" | "failed";
44
+ analysis_status: AnalysisStatus;
45
+ }
46
+
47
+ // ─── Identity ─────────────────────────────────────────────────────────────────
48
+
49
+ export type Modality =
50
+ | "long-term"
51
+ | "casual"
52
+ | "kink"
53
+ | "open-relationship"
54
+ | "polyamory"
55
+ | "swinging"
56
+ | "friends";
57
+
58
+ export type ModalityWeights = Record<Modality, number>;
59
+
60
+ export interface DomainProfile {
61
+ confidence: number; // 0–1
62
+ evidence: string[];
63
+ [key: string]: unknown;
64
+ }
65
+
66
+ export interface BaseIdentityProfile {
67
+ updated_at: string;
68
+ session_count: number;
69
+ total_minutes: number;
70
+ relationships: DomainProfile & {
71
+ attachment_style: string;
72
+ trust_pattern: string;
73
+ conflict_mode: string;
74
+ depth_vs_breadth: number;
75
+ };
76
+ desire: DomainProfile & {
77
+ expressed_desires: string[];
78
+ inferred_desires: string[];
79
+ kink_vanilla_spectrum: number; // 0=vanilla, 1=kink
80
+ shame_sovereignty_score: number; // 0=shame, 1=sovereignty
81
+ };
82
+ money: DomainProfile & {
83
+ scarcity_abundance_orientation: number; // 0=scarcity, 1=abundance
84
+ risk_tolerance: number;
85
+ ambition_contentment: number;
86
+ financial_mythology_active: string[];
87
+ };
88
+ health: DomainProfile & {
89
+ energy_pattern: string;
90
+ physicality_orientation: number;
91
+ self_care_mode: string;
92
+ };
93
+ worldview: {
94
+ world_danger_adventure: number; // 0=dangerous, 1=adventurous
95
+ people_good_bad: number; // 0=bad, 1=good
96
+ vals_type: string;
97
+ vals_confidence: number;
98
+ games_active: string[];
99
+ symbolic_responses: Array<{
100
+ prompt: string;
101
+ response: string;
102
+ valence: string;
103
+ }>;
104
+ };
105
+ }
106
+
107
+ export interface Identity {
108
+ user_id: string;
109
+ updated_at: string;
110
+ version: number;
111
+ base_profile: BaseIdentityProfile;
112
+ modality_weights: ModalityWeights;
113
+ signal_completeness_score: number; // 0–1
114
+ ready_for_matching: boolean;
115
+ embedding_id?: string;
116
+ }
117
+
118
+ // ─── Matches ──────────────────────────────────────────────────────────────────
119
+
120
+ export type MatchStatus =
121
+ | "pending_consent"
122
+ | "a_accepted"
123
+ | "b_accepted"
124
+ | "both_accepted"
125
+ | "declined"
126
+ | "introduced"
127
+ | "stale";
128
+
129
+ export interface Match {
130
+ match_id: string;
131
+ user_a_id: string;
132
+ user_b_id: string;
133
+ primary_modality: Modality;
134
+ cross_modality: boolean;
135
+ cross_modality_bridge?: string;
136
+ confidence_score: number;
137
+ resonances: string[];
138
+ tensions: string[];
139
+ tension_fatal: boolean;
140
+ consent_call_framing: string;
141
+ status: MatchStatus;
142
+ created_at: string;
143
+ a_consented_at?: string;
144
+ b_consented_at?: string;
145
+ outcome?: "positive" | "negative";
146
+ }
@@ -0,0 +1 @@
1
+ main
@@ -0,0 +1 @@
1
+ v2.75.0
@@ -0,0 +1 @@
1
+ v2.187.0
@@ -0,0 +1 @@
1
+ postgresql://postgres.tqjlucpdjwxlxkvlqjhs@aws-1-us-east-2.pooler.supabase.com:5432/postgres
@@ -0,0 +1 @@
1
+ 17.6.1.063
@@ -0,0 +1 @@
1
+ tqjlucpdjwxlxkvlqjhs
@@ -0,0 +1 @@
1
+ v14.1
@@ -0,0 +1 @@
1
+ fix-optimized-search-function
@@ -0,0 +1 @@
1
+ v1.37.7