@nordsym/apiclaw 1.0.0 → 1.1.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.
Files changed (161) hide show
  1. package/AGENTS.md +74 -0
  2. package/HEARTBEAT.md +4 -0
  3. package/IDENTITY.md +22 -0
  4. package/README.md +193 -202
  5. package/SOUL.md +36 -0
  6. package/STATUS.md +237 -0
  7. package/TOOLS.md +36 -0
  8. package/USER.md +17 -0
  9. package/{backend/convex → convex}/_generated/api.d.ts +12 -6
  10. package/convex/analytics.ts +90 -0
  11. package/convex/credits.ts +211 -0
  12. package/convex/http.ts +578 -0
  13. package/convex/providers.ts +516 -0
  14. package/convex/purchases.ts +183 -0
  15. package/convex/ratelimit.ts +104 -0
  16. package/convex/schema.ts +220 -0
  17. package/convex/telemetry.ts +81 -0
  18. package/convex.json +3 -0
  19. package/dist/credentials.d.ts +19 -0
  20. package/dist/credentials.d.ts.map +1 -0
  21. package/dist/credentials.js +158 -0
  22. package/dist/credentials.js.map +1 -0
  23. package/dist/credits.d.ts +14 -11
  24. package/dist/credits.d.ts.map +1 -1
  25. package/dist/credits.js +151 -99
  26. package/dist/credits.js.map +1 -1
  27. package/dist/discovery.d.ts +7 -16
  28. package/dist/discovery.d.ts.map +1 -1
  29. package/dist/discovery.js +33 -40
  30. package/dist/discovery.js.map +1 -1
  31. package/dist/execute.d.ts +19 -0
  32. package/dist/execute.d.ts.map +1 -0
  33. package/dist/execute.js +285 -0
  34. package/dist/execute.js.map +1 -0
  35. package/dist/index.js +175 -31
  36. package/dist/index.js.map +1 -1
  37. package/dist/proxy.d.ts +6 -0
  38. package/dist/proxy.d.ts.map +1 -0
  39. package/dist/proxy.js +19 -0
  40. package/dist/proxy.js.map +1 -0
  41. package/dist/registry/apis.json +95362 -202
  42. package/dist/registry/apis_expanded.json +100853 -0
  43. package/dist/stripe.d.ts +68 -0
  44. package/dist/stripe.d.ts.map +1 -0
  45. package/dist/stripe.js +196 -0
  46. package/dist/stripe.js.map +1 -0
  47. package/dist/telemetry.d.ts +28 -0
  48. package/dist/telemetry.d.ts.map +1 -0
  49. package/dist/telemetry.js +50 -0
  50. package/dist/telemetry.js.map +1 -0
  51. package/dist/test.d.ts +3 -2
  52. package/dist/test.d.ts.map +1 -1
  53. package/dist/test.js +105 -75
  54. package/dist/test.js.map +1 -1
  55. package/dist/types.d.ts +0 -28
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/webhook.d.ts +2 -0
  58. package/dist/webhook.d.ts.map +1 -0
  59. package/dist/webhook.js +90 -0
  60. package/dist/webhook.js.map +1 -0
  61. package/landing/DESIGN.md +343 -0
  62. package/landing/package-lock.json +1196 -7
  63. package/landing/package.json +5 -1
  64. package/landing/public/android-chrome-192x192.png +0 -0
  65. package/landing/public/android-chrome-512x512.png +0 -0
  66. package/landing/public/apple-touch-icon.png +0 -0
  67. package/landing/public/demo.gif +0 -0
  68. package/landing/public/demo.mp4 +0 -0
  69. package/landing/public/favicon-16x16.png +0 -0
  70. package/landing/public/favicon-32x32.png +0 -0
  71. package/landing/public/favicon.ico +0 -0
  72. package/landing/public/favicon.svg +3 -0
  73. package/landing/public/icon.svg +47 -0
  74. package/landing/public/logo-mono.svg +37 -0
  75. package/landing/public/logo-simple.svg +45 -0
  76. package/landing/public/logo.svg +84 -0
  77. package/landing/public/og-template.html +184 -0
  78. package/landing/public/site.webmanifest +31 -0
  79. package/landing/scripts/generate-assets.js +284 -0
  80. package/landing/scripts/generate-pngs.js +48 -0
  81. package/landing/scripts/generate-stats.js +42 -0
  82. package/landing/src/app/admin/page.tsx +348 -0
  83. package/landing/src/app/api/auth/magic-link/route.ts +73 -0
  84. package/landing/src/app/api/auth/session/route.ts +38 -0
  85. package/landing/src/app/api/auth/verify/route.ts +43 -0
  86. package/landing/src/app/api/og/route.tsx +84 -0
  87. package/landing/src/app/globals.css +439 -100
  88. package/landing/src/app/layout.tsx +37 -7
  89. package/landing/src/app/page.tsx +627 -552
  90. package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
  91. package/landing/src/app/providers/dashboard/page.tsx +589 -0
  92. package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
  93. package/landing/src/app/providers/layout.tsx +14 -0
  94. package/landing/src/app/providers/page.tsx +402 -0
  95. package/landing/src/app/providers/register/page.tsx +670 -0
  96. package/landing/src/components/ProviderDashboard.tsx +794 -0
  97. package/landing/src/hooks/useDashboardData.ts +99 -0
  98. package/landing/src/lib/apis.json +116054 -0
  99. package/landing/src/lib/convex-client.ts +106 -0
  100. package/landing/src/lib/mock-data.ts +285 -0
  101. package/landing/src/lib/stats.json +6 -0
  102. package/landing/tailwind.config.ts +12 -11
  103. package/landing/tsconfig.tsbuildinfo +1 -0
  104. package/package.json +21 -20
  105. package/scripts/SYMBOT-FIX.md +238 -0
  106. package/scripts/demo-simulation.py +177 -0
  107. package/scripts/expand-more.py +502 -0
  108. package/scripts/expand-registry.py +434 -0
  109. package/scripts/history-sanitizer.ts +272 -0
  110. package/scripts/mass-scrape.py +1308 -0
  111. package/scripts/sync-and-deploy.sh +36 -0
  112. package/src/credentials.ts +177 -0
  113. package/src/credits.ts +190 -122
  114. package/src/discovery.ts +45 -58
  115. package/src/execute.ts +350 -0
  116. package/src/index.ts +184 -32
  117. package/src/proxy.ts +24 -0
  118. package/src/registry/apis.json +95362 -202
  119. package/src/registry/apis_expanded.json +100853 -0
  120. package/src/stripe.ts +243 -0
  121. package/src/telemetry.ts +71 -0
  122. package/src/test.ts +127 -89
  123. package/src/types.ts +0 -34
  124. package/src/webhook.ts +107 -0
  125. package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
  126. package/BRIEFING.md +0 -30
  127. package/backend/convex/apiKeys.ts +0 -75
  128. package/backend/convex/purchases.ts +0 -74
  129. package/backend/convex/schema.ts +0 -45
  130. package/backend/convex/transactions.ts +0 -57
  131. package/backend/convex/users.ts +0 -94
  132. package/backend/package-lock.json +0 -521
  133. package/backend/package.json +0 -15
  134. package/dist/registry/parse_apis.py +0 -146
  135. package/dist/revenuecat.d.ts +0 -61
  136. package/dist/revenuecat.d.ts.map +0 -1
  137. package/dist/revenuecat.js +0 -166
  138. package/dist/revenuecat.js.map +0 -1
  139. package/dist/webhooks/revenuecat.d.ts +0 -48
  140. package/dist/webhooks/revenuecat.d.ts.map +0 -1
  141. package/dist/webhooks/revenuecat.js +0 -119
  142. package/dist/webhooks/revenuecat.js.map +0 -1
  143. package/docs/revenuecat-setup.md +0 -89
  144. package/landing/src/app/api/keys/route.ts +0 -71
  145. package/landing/src/app/api/log/route.ts +0 -37
  146. package/landing/src/app/api/stats/route.ts +0 -37
  147. package/landing/src/app/page.tsx.bak +0 -567
  148. package/landing/src/components/AddKeyModal.tsx +0 -159
  149. package/newsletter-template.html +0 -71
  150. package/outreach/OUTREACH-SYSTEM.md +0 -211
  151. package/outreach/email-template.html +0 -179
  152. package/outreach/targets.md +0 -133
  153. package/src/registry/parse_apis.py +0 -146
  154. package/src/revenuecat.ts +0 -239
  155. package/src/webhooks/revenuecat.ts +0 -187
  156. /package/{backend/convex → convex}/README.md +0 -0
  157. /package/{backend/convex → convex}/_generated/api.js +0 -0
  158. /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
  159. /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
  160. /package/{backend/convex → convex}/_generated/server.js +0 -0
  161. /package/{backend/convex → convex}/tsconfig.json +0 -0
@@ -0,0 +1,272 @@
1
+ /**
2
+ * SYMBOT/CLAWDBOT MESSAGE HISTORY SANITIZER
3
+ *
4
+ * Fixar: "unexpected tool_use_id found in tool_result blocks"
5
+ *
6
+ * Problem: tool_result-block refererar till tool_use_id som saknas i föregående meddelande.
7
+ * Lösning: Skanna messages-arrayen och ta bort orphaned tool_results.
8
+ */
9
+
10
+ interface MessageBlock {
11
+ type: string;
12
+ tool_use_id?: string;
13
+ id?: string;
14
+ [key: string]: any;
15
+ }
16
+
17
+ interface Message {
18
+ role: 'user' | 'assistant' | 'system';
19
+ content: string | MessageBlock[];
20
+ }
21
+
22
+ /**
23
+ * Extraherar alla tool_use IDs från ett assistant-meddelande
24
+ */
25
+ function extractToolUseIds(message: Message): Set<string> {
26
+ const ids = new Set<string>();
27
+
28
+ if (typeof message.content === 'string') return ids;
29
+
30
+ for (const block of message.content) {
31
+ if (block.type === 'tool_use' && block.id) {
32
+ ids.add(block.id);
33
+ }
34
+ }
35
+
36
+ return ids;
37
+ }
38
+
39
+ /**
40
+ * Tar bort tool_result-block som saknar matchande tool_use_id
41
+ */
42
+ function sanitizeMessage(message: Message, validToolIds: Set<string>): Message {
43
+ if (typeof message.content === 'string') return message;
44
+
45
+ const sanitizedContent = message.content.filter(block => {
46
+ // Behåll allt som INTE är tool_result
47
+ if (block.type !== 'tool_result') return true;
48
+
49
+ // Behåll endast tool_result som har en matchande tool_use
50
+ if (block.tool_use_id && validToolIds.has(block.tool_use_id)) {
51
+ return true;
52
+ }
53
+
54
+ // Logga borttagna orphaned results
55
+ console.warn(`🧹 Removed orphaned tool_result: ${block.tool_use_id}`);
56
+ return false;
57
+ });
58
+
59
+ return {
60
+ ...message,
61
+ content: sanitizedContent
62
+ };
63
+ }
64
+
65
+ /**
66
+ * HUVUDFUNKTION: Sanerar hela message history
67
+ *
68
+ * Körs ALLTID innan anthropic.messages.create()
69
+ */
70
+ export function sanitizeHistory(messages: Message[]): Message[] {
71
+ const sanitized: Message[] = [];
72
+ let previousToolIds = new Set<string>();
73
+
74
+ for (let i = 0; i < messages.length; i++) {
75
+ const message = messages[i];
76
+
77
+ if (message.role === 'assistant') {
78
+ // Extrahera tool_use IDs från detta assistant-meddelande
79
+ const toolIds = extractToolUseIds(message);
80
+ previousToolIds = toolIds;
81
+ sanitized.push(message);
82
+ }
83
+ else if (message.role === 'user') {
84
+ // Sanera user-meddelande baserat på föregående assistant's tool_use IDs
85
+ const sanitizedMessage = sanitizeMessage(message, previousToolIds);
86
+
87
+ // Endast lägg till om meddelandet har content kvar
88
+ if (typeof sanitizedMessage.content === 'string' || sanitizedMessage.content.length > 0) {
89
+ sanitized.push(sanitizedMessage);
90
+ } else {
91
+ console.warn(`🧹 Removed empty user message at index ${i}`);
92
+ }
93
+
94
+ // Reset tool IDs efter user-meddelande
95
+ previousToolIds = new Set();
96
+ }
97
+ else {
98
+ // System-meddelanden går igenom oförändrade
99
+ sanitized.push(message);
100
+ }
101
+ }
102
+
103
+ return sanitized;
104
+ }
105
+
106
+ /**
107
+ * VALIDERING: Kollar att message history följer korrekt sekvens
108
+ *
109
+ * Korrekt ordning:
110
+ * user -> assistant (tool_use) -> user (tool_result) -> assistant -> ...
111
+ */
112
+ export function validateMessageSequence(messages: Message[]): {
113
+ valid: boolean;
114
+ errors: string[];
115
+ } {
116
+ const errors: string[] = [];
117
+ let expectingToolResult = false;
118
+ let pendingToolIds = new Set<string>();
119
+
120
+ for (let i = 0; i < messages.length; i++) {
121
+ const message = messages[i];
122
+
123
+ // Skip system messages
124
+ if (message.role === 'system') continue;
125
+
126
+ if (message.role === 'assistant') {
127
+ const toolIds = extractToolUseIds(message);
128
+
129
+ if (toolIds.size > 0) {
130
+ expectingToolResult = true;
131
+ pendingToolIds = toolIds;
132
+ } else {
133
+ expectingToolResult = false;
134
+ pendingToolIds.clear();
135
+ }
136
+ }
137
+
138
+ if (message.role === 'user' && typeof message.content !== 'string') {
139
+ const hasToolResult = message.content.some(block => block.type === 'tool_result');
140
+
141
+ if (hasToolResult && !expectingToolResult) {
142
+ errors.push(`Message ${i}: tool_result without preceding tool_use`);
143
+ }
144
+
145
+ if (hasToolResult) {
146
+ // Validera att alla tool_result har matchande tool_use
147
+ for (const block of message.content) {
148
+ if (block.type === 'tool_result') {
149
+ if (!block.tool_use_id || !pendingToolIds.has(block.tool_use_id)) {
150
+ errors.push(`Message ${i}: tool_result ${block.tool_use_id} has no matching tool_use`);
151
+ }
152
+ }
153
+ }
154
+
155
+ expectingToolResult = false;
156
+ pendingToolIds.clear();
157
+ }
158
+ }
159
+ }
160
+
161
+ return {
162
+ valid: errors.length === 0,
163
+ errors
164
+ };
165
+ }
166
+
167
+ /**
168
+ * HARD RESET: Rensar ALL history för en användare
169
+ *
170
+ * Använd för /start och /stop kommandon
171
+ */
172
+ export async function hardResetHistory(userId: string, db: any): Promise<void> {
173
+ try {
174
+ // Convex example
175
+ await db.delete({ userId });
176
+ console.log(`✅ Hard reset: Cleared all history for user ${userId}`);
177
+ } catch (error) {
178
+ console.error(`❌ Hard reset failed for user ${userId}:`, error);
179
+ throw error;
180
+ }
181
+ }
182
+
183
+ /**
184
+ * GRACEFUL ERROR RECOVERY
185
+ *
186
+ * Om Anthropic API kastar error, försök igen med saniterad history
187
+ */
188
+ export async function callAnthropicWithRecovery(
189
+ messages: Message[],
190
+ anthropicClient: any,
191
+ maxRetries = 2
192
+ ): Promise<any> {
193
+ let attempt = 0;
194
+ let currentMessages = messages;
195
+
196
+ while (attempt < maxRetries) {
197
+ try {
198
+ // Sanera innan varje försök
199
+ const sanitized = sanitizeHistory(currentMessages);
200
+
201
+ // Validera
202
+ const validation = validateMessageSequence(sanitized);
203
+ if (!validation.valid) {
204
+ console.warn('⚠️ Message sequence validation failed:', validation.errors);
205
+ }
206
+
207
+ // Kör API-anrop
208
+ const response = await anthropicClient.messages.create({
209
+ model: 'claude-3-5-sonnet-20241022',
210
+ max_tokens: 4096,
211
+ messages: sanitized
212
+ });
213
+
214
+ return response;
215
+
216
+ } catch (error: any) {
217
+ attempt++;
218
+
219
+ if (error.message?.includes('unexpected tool_use_id')) {
220
+ console.warn(`🔄 Attempt ${attempt}: tool_use_id error, retrying with deeper sanitization...`);
221
+
222
+ // Aggressiv sanering: Ta bort alla tool_result block
223
+ currentMessages = messages.map(msg => {
224
+ if (msg.role === 'user' && typeof msg.content !== 'string') {
225
+ return {
226
+ ...msg,
227
+ content: msg.content.filter(block => block.type !== 'tool_result')
228
+ };
229
+ }
230
+ return msg;
231
+ });
232
+
233
+ continue;
234
+ }
235
+
236
+ // Annat fel - kasta vidare
237
+ throw error;
238
+ }
239
+ }
240
+
241
+ throw new Error(`Failed after ${maxRetries} attempts`);
242
+ }
243
+
244
+ /**
245
+ * EXEMPEL PÅ ANVÄNDNING
246
+ */
247
+ export function example() {
248
+ const messages: Message[] = [
249
+ { role: 'user', content: 'Hello' },
250
+ {
251
+ role: 'assistant',
252
+ content: [
253
+ { type: 'text', text: 'Let me help' },
254
+ { type: 'tool_use', id: 'toolu_123', name: 'search', input: {} }
255
+ ]
256
+ },
257
+ {
258
+ role: 'user',
259
+ content: [
260
+ { type: 'tool_result', tool_use_id: 'toolu_123', content: 'Result' },
261
+ // Detta skulle vara orphaned om föregående tool_use saknas:
262
+ // { type: 'tool_result', tool_use_id: 'toolu_999', content: 'Bad' }
263
+ ]
264
+ }
265
+ ];
266
+
267
+ const sanitized = sanitizeHistory(messages);
268
+ const validation = validateMessageSequence(sanitized);
269
+
270
+ console.log('Sanitized:', sanitized);
271
+ console.log('Valid:', validation);
272
+ }