@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.
- package/AGENTS.md +74 -0
- package/HEARTBEAT.md +4 -0
- package/IDENTITY.md +22 -0
- package/README.md +193 -202
- package/SOUL.md +36 -0
- package/STATUS.md +237 -0
- package/TOOLS.md +36 -0
- package/USER.md +17 -0
- package/{backend/convex → convex}/_generated/api.d.ts +12 -6
- package/convex/analytics.ts +90 -0
- package/convex/credits.ts +211 -0
- package/convex/http.ts +578 -0
- package/convex/providers.ts +516 -0
- package/convex/purchases.ts +183 -0
- package/convex/ratelimit.ts +104 -0
- package/convex/schema.ts +220 -0
- package/convex/telemetry.ts +81 -0
- package/convex.json +3 -0
- package/dist/credentials.d.ts +19 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +158 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credits.d.ts +14 -11
- package/dist/credits.d.ts.map +1 -1
- package/dist/credits.js +151 -99
- package/dist/credits.js.map +1 -1
- package/dist/discovery.d.ts +7 -16
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +33 -40
- package/dist/discovery.js.map +1 -1
- package/dist/execute.d.ts +19 -0
- package/dist/execute.d.ts.map +1 -0
- package/dist/execute.js +285 -0
- package/dist/execute.js.map +1 -0
- package/dist/index.js +175 -31
- package/dist/index.js.map +1 -1
- package/dist/proxy.d.ts +6 -0
- package/dist/proxy.d.ts.map +1 -0
- package/dist/proxy.js +19 -0
- package/dist/proxy.js.map +1 -0
- package/dist/registry/apis.json +95362 -202
- package/dist/registry/apis_expanded.json +100853 -0
- package/dist/stripe.d.ts +68 -0
- package/dist/stripe.d.ts.map +1 -0
- package/dist/stripe.js +196 -0
- package/dist/stripe.js.map +1 -0
- package/dist/telemetry.d.ts +28 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +50 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/test.d.ts +3 -2
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +105 -75
- package/dist/test.js.map +1 -1
- package/dist/types.d.ts +0 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/webhook.d.ts +2 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +90 -0
- package/dist/webhook.js.map +1 -0
- package/landing/DESIGN.md +343 -0
- package/landing/package-lock.json +1196 -7
- package/landing/package.json +5 -1
- package/landing/public/android-chrome-192x192.png +0 -0
- package/landing/public/android-chrome-512x512.png +0 -0
- package/landing/public/apple-touch-icon.png +0 -0
- package/landing/public/demo.gif +0 -0
- package/landing/public/demo.mp4 +0 -0
- package/landing/public/favicon-16x16.png +0 -0
- package/landing/public/favicon-32x32.png +0 -0
- package/landing/public/favicon.ico +0 -0
- package/landing/public/favicon.svg +3 -0
- package/landing/public/icon.svg +47 -0
- package/landing/public/logo-mono.svg +37 -0
- package/landing/public/logo-simple.svg +45 -0
- package/landing/public/logo.svg +84 -0
- package/landing/public/og-template.html +184 -0
- package/landing/public/site.webmanifest +31 -0
- package/landing/scripts/generate-assets.js +284 -0
- package/landing/scripts/generate-pngs.js +48 -0
- package/landing/scripts/generate-stats.js +42 -0
- package/landing/src/app/admin/page.tsx +348 -0
- package/landing/src/app/api/auth/magic-link/route.ts +73 -0
- package/landing/src/app/api/auth/session/route.ts +38 -0
- package/landing/src/app/api/auth/verify/route.ts +43 -0
- package/landing/src/app/api/og/route.tsx +84 -0
- package/landing/src/app/globals.css +439 -100
- package/landing/src/app/layout.tsx +37 -7
- package/landing/src/app/page.tsx +627 -552
- package/landing/src/app/providers/dashboard/login/page.tsx +176 -0
- package/landing/src/app/providers/dashboard/page.tsx +589 -0
- package/landing/src/app/providers/dashboard/verify/page.tsx +106 -0
- package/landing/src/app/providers/layout.tsx +14 -0
- package/landing/src/app/providers/page.tsx +402 -0
- package/landing/src/app/providers/register/page.tsx +670 -0
- package/landing/src/components/ProviderDashboard.tsx +794 -0
- package/landing/src/hooks/useDashboardData.ts +99 -0
- package/landing/src/lib/apis.json +116054 -0
- package/landing/src/lib/convex-client.ts +106 -0
- package/landing/src/lib/mock-data.ts +285 -0
- package/landing/src/lib/stats.json +6 -0
- package/landing/tailwind.config.ts +12 -11
- package/landing/tsconfig.tsbuildinfo +1 -0
- package/package.json +21 -20
- package/scripts/SYMBOT-FIX.md +238 -0
- package/scripts/demo-simulation.py +177 -0
- package/scripts/expand-more.py +502 -0
- package/scripts/expand-registry.py +434 -0
- package/scripts/history-sanitizer.ts +272 -0
- package/scripts/mass-scrape.py +1308 -0
- package/scripts/sync-and-deploy.sh +36 -0
- package/src/credentials.ts +177 -0
- package/src/credits.ts +190 -122
- package/src/discovery.ts +45 -58
- package/src/execute.ts +350 -0
- package/src/index.ts +184 -32
- package/src/proxy.ts +24 -0
- package/src/registry/apis.json +95362 -202
- package/src/registry/apis_expanded.json +100853 -0
- package/src/stripe.ts +243 -0
- package/src/telemetry.ts +71 -0
- package/src/test.ts +127 -89
- package/src/types.ts +0 -34
- package/src/webhook.ts +107 -0
- package/.github/ISSUE_TEMPLATE/add-api.yml +0 -123
- package/BRIEFING.md +0 -30
- package/backend/convex/apiKeys.ts +0 -75
- package/backend/convex/purchases.ts +0 -74
- package/backend/convex/schema.ts +0 -45
- package/backend/convex/transactions.ts +0 -57
- package/backend/convex/users.ts +0 -94
- package/backend/package-lock.json +0 -521
- package/backend/package.json +0 -15
- package/dist/registry/parse_apis.py +0 -146
- package/dist/revenuecat.d.ts +0 -61
- package/dist/revenuecat.d.ts.map +0 -1
- package/dist/revenuecat.js +0 -166
- package/dist/revenuecat.js.map +0 -1
- package/dist/webhooks/revenuecat.d.ts +0 -48
- package/dist/webhooks/revenuecat.d.ts.map +0 -1
- package/dist/webhooks/revenuecat.js +0 -119
- package/dist/webhooks/revenuecat.js.map +0 -1
- package/docs/revenuecat-setup.md +0 -89
- package/landing/src/app/api/keys/route.ts +0 -71
- package/landing/src/app/api/log/route.ts +0 -37
- package/landing/src/app/api/stats/route.ts +0 -37
- package/landing/src/app/page.tsx.bak +0 -567
- package/landing/src/components/AddKeyModal.tsx +0 -159
- package/newsletter-template.html +0 -71
- package/outreach/OUTREACH-SYSTEM.md +0 -211
- package/outreach/email-template.html +0 -179
- package/outreach/targets.md +0 -133
- package/src/registry/parse_apis.py +0 -146
- package/src/revenuecat.ts +0 -239
- package/src/webhooks/revenuecat.ts +0 -187
- /package/{backend/convex → convex}/README.md +0 -0
- /package/{backend/convex → convex}/_generated/api.js +0 -0
- /package/{backend/convex → convex}/_generated/dataModel.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.d.ts +0 -0
- /package/{backend/convex → convex}/_generated/server.js +0 -0
- /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
|
+
}
|