@nordsym/apiclaw 1.4.0 → 1.4.2
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/PRD-ANALYTICS-AGENTS-TEAMS.md +710 -0
- package/PRD-LOGS-SUBAGENTS-V2.md +267 -0
- package/convex/_generated/api.d.ts +4 -0
- package/convex/agents.ts +188 -0
- package/convex/chains.ts +257 -104
- package/convex/logs.ts +94 -0
- package/convex/schema.ts +38 -0
- package/convex/searchLogs.ts +141 -0
- package/convex/teams.ts +243 -0
- package/dist/index.js +97 -2
- package/dist/index.js.map +1 -1
- package/docs/SUBAGENT-NAMING.md +94 -0
- package/landing/src/app/workspace/chains/page.tsx +3 -3
- package/landing/src/app/workspace/page.tsx +1903 -224
- package/landing/src/lib/stats.json +1 -1
- package/package.json +14 -2
- package/src/index.ts +102 -2
- package/src/chain-types.ts +0 -270
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nordsym/apiclaw",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "The API layer for AI agents. 22,000+ APIs. Direct Call. Works with any MCP-compatible agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -42,7 +42,19 @@
|
|
|
42
42
|
"anthropic",
|
|
43
43
|
"mcp-server",
|
|
44
44
|
"tool-use",
|
|
45
|
-
"function-calling"
|
|
45
|
+
"function-calling",
|
|
46
|
+
"api-aggregator",
|
|
47
|
+
"multi-api",
|
|
48
|
+
"unified-api",
|
|
49
|
+
"api-hub",
|
|
50
|
+
"llm-tools",
|
|
51
|
+
"agent-tools",
|
|
52
|
+
"ai-sdk",
|
|
53
|
+
"api-client",
|
|
54
|
+
"ai-api",
|
|
55
|
+
"claude-tools",
|
|
56
|
+
"gpt-tools",
|
|
57
|
+
"api-marketplace"
|
|
46
58
|
],
|
|
47
59
|
"author": "NordSym",
|
|
48
60
|
"license": "MIT",
|
package/src/index.ts
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
const DEFAULT_AGENT_ID = 'agent_default';
|
|
67
67
|
|
|
68
68
|
// Convex client for workspace management
|
|
69
|
-
const CONVEX_URL = process.env.CONVEX_URL || 'https://
|
|
69
|
+
const CONVEX_URL = process.env.CONVEX_URL || 'https://brilliant-puffin-712.eu-west-1.convex.cloud';
|
|
70
70
|
const convex = new ConvexHttpClient(CONVEX_URL);
|
|
71
71
|
|
|
72
72
|
// Global workspace context (set on startup if session is valid)
|
|
@@ -243,6 +243,14 @@ const tools: Tool[] = [
|
|
|
243
243
|
region: {
|
|
244
244
|
type: 'string',
|
|
245
245
|
description: 'Filter by region (e.g., "SE", "EU", "global")'
|
|
246
|
+
},
|
|
247
|
+
subagent_id: {
|
|
248
|
+
type: 'string',
|
|
249
|
+
description: 'Optional subagent identifier for multi-agent tracking'
|
|
250
|
+
},
|
|
251
|
+
ai_backend: {
|
|
252
|
+
type: 'string',
|
|
253
|
+
description: 'AI backend making this request (e.g., "claude-3-sonnet", "gpt-4"). Used for analytics.'
|
|
246
254
|
}
|
|
247
255
|
},
|
|
248
256
|
required: ['query']
|
|
@@ -428,6 +436,14 @@ Example chain:
|
|
|
428
436
|
webhook: {
|
|
429
437
|
type: 'string',
|
|
430
438
|
description: 'URL to POST results when async chain completes'
|
|
439
|
+
},
|
|
440
|
+
subagent_id: {
|
|
441
|
+
type: 'string',
|
|
442
|
+
description: 'Optional subagent identifier for multi-agent tracking'
|
|
443
|
+
},
|
|
444
|
+
ai_backend: {
|
|
445
|
+
type: 'string',
|
|
446
|
+
description: 'AI backend making this request (e.g., "claude-3-sonnet", "gpt-4"). Used for analytics.'
|
|
431
447
|
}
|
|
432
448
|
},
|
|
433
449
|
required: []
|
|
@@ -468,6 +484,14 @@ Example chain:
|
|
|
468
484
|
preferredProvider: { type: 'string', description: 'Hint to prefer a specific provider' },
|
|
469
485
|
fallback: { type: 'boolean', description: 'Enable fallback to other providers (default: true)' }
|
|
470
486
|
}
|
|
487
|
+
},
|
|
488
|
+
subagent_id: {
|
|
489
|
+
type: 'string',
|
|
490
|
+
description: 'Optional subagent identifier for multi-agent tracking'
|
|
491
|
+
},
|
|
492
|
+
ai_backend: {
|
|
493
|
+
type: 'string',
|
|
494
|
+
description: 'AI backend making this request (e.g., "claude-3-sonnet", "gpt-4"). Used for analytics.'
|
|
471
495
|
}
|
|
472
496
|
},
|
|
473
497
|
required: ['capability', 'action', 'params']
|
|
@@ -678,10 +702,50 @@ Docs: https://apiclaw.nordsym.com
|
|
|
678
702
|
const category = args?.category as string | undefined;
|
|
679
703
|
const maxResults = (args?.max_results as number) || 5;
|
|
680
704
|
const region = args?.region as string | undefined;
|
|
705
|
+
const subagentId = args?.subagent_id as string | undefined;
|
|
706
|
+
const aiBackend = args?.ai_backend as string | undefined;
|
|
681
707
|
|
|
682
708
|
const startTime = Date.now();
|
|
683
709
|
const results = discoverAPIs(query, { category, maxResults, region });
|
|
684
|
-
|
|
710
|
+
const responseTimeMs = Date.now() - startTime;
|
|
711
|
+
trackSearch(query, results.length, responseTimeMs);
|
|
712
|
+
|
|
713
|
+
// Log search to Convex for analytics
|
|
714
|
+
if (workspaceContext?.sessionToken) {
|
|
715
|
+
const searchLogPayload = {
|
|
716
|
+
path: 'searchLogs:log',
|
|
717
|
+
args: {
|
|
718
|
+
sessionToken: workspaceContext.sessionToken,
|
|
719
|
+
subagentId: subagentId || undefined,
|
|
720
|
+
query,
|
|
721
|
+
resultCount: results.length,
|
|
722
|
+
matchedProviders: results.slice(0, 10).map(r => r.provider.id),
|
|
723
|
+
responseTimeMs,
|
|
724
|
+
},
|
|
725
|
+
};
|
|
726
|
+
|
|
727
|
+
fetch('https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation', {
|
|
728
|
+
method: 'POST',
|
|
729
|
+
headers: { 'Content-Type': 'application/json' },
|
|
730
|
+
body: JSON.stringify(searchLogPayload),
|
|
731
|
+
}).catch(() => {}); // Fire and forget
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Update AI backend tracking if provided
|
|
735
|
+
if (aiBackend && workspaceContext?.sessionToken) {
|
|
736
|
+
fetch('https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation', {
|
|
737
|
+
method: 'POST',
|
|
738
|
+
headers: { 'Content-Type': 'application/json' },
|
|
739
|
+
body: JSON.stringify({
|
|
740
|
+
path: 'agents:updateAIBackend',
|
|
741
|
+
args: {
|
|
742
|
+
token: workspaceContext.sessionToken,
|
|
743
|
+
subagentId: subagentId || undefined,
|
|
744
|
+
aiBackend,
|
|
745
|
+
},
|
|
746
|
+
}),
|
|
747
|
+
}).catch(() => {}); // Fire and forget
|
|
748
|
+
}
|
|
685
749
|
|
|
686
750
|
if (results.length === 0) {
|
|
687
751
|
return {
|
|
@@ -897,6 +961,24 @@ Docs: https://apiclaw.nordsym.com
|
|
|
897
961
|
const confirmToken = args?.confirm_token as string | undefined;
|
|
898
962
|
const dryRun = args?.dry_run as boolean | undefined;
|
|
899
963
|
const chain = args?.chain as ChainStepUnion[] | undefined;
|
|
964
|
+
const subagentId = args?.subagent_id as string | undefined;
|
|
965
|
+
const aiBackend = args?.ai_backend as string | undefined;
|
|
966
|
+
|
|
967
|
+
// Track AI backend if provided
|
|
968
|
+
if (aiBackend && workspaceContext?.sessionToken) {
|
|
969
|
+
fetch('https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation', {
|
|
970
|
+
method: 'POST',
|
|
971
|
+
headers: { 'Content-Type': 'application/json' },
|
|
972
|
+
body: JSON.stringify({
|
|
973
|
+
path: 'agents:updateAIBackend',
|
|
974
|
+
args: {
|
|
975
|
+
token: workspaceContext.sessionToken,
|
|
976
|
+
subagentId: subagentId || undefined,
|
|
977
|
+
aiBackend,
|
|
978
|
+
},
|
|
979
|
+
}),
|
|
980
|
+
}).catch(() => {}); // Fire and forget
|
|
981
|
+
}
|
|
900
982
|
|
|
901
983
|
// ============================================
|
|
902
984
|
// CHAIN EXECUTION MODE
|
|
@@ -1255,6 +1337,24 @@ Docs: https://apiclaw.nordsym.com
|
|
|
1255
1337
|
const action = args?.action as string;
|
|
1256
1338
|
const params = (args?.params as Record<string, any>) || {};
|
|
1257
1339
|
const preferences = (args?.preferences as Record<string, any>) || {};
|
|
1340
|
+
const subagentId = args?.subagent_id as string | undefined;
|
|
1341
|
+
const aiBackend = args?.ai_backend as string | undefined;
|
|
1342
|
+
|
|
1343
|
+
// Track AI backend if provided
|
|
1344
|
+
if (aiBackend && workspaceContext?.sessionToken) {
|
|
1345
|
+
fetch('https://brilliant-puffin-712.eu-west-1.convex.cloud/api/mutation', {
|
|
1346
|
+
method: 'POST',
|
|
1347
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1348
|
+
body: JSON.stringify({
|
|
1349
|
+
path: 'agents:updateAIBackend',
|
|
1350
|
+
args: {
|
|
1351
|
+
token: workspaceContext.sessionToken,
|
|
1352
|
+
subagentId: subagentId || undefined,
|
|
1353
|
+
aiBackend,
|
|
1354
|
+
},
|
|
1355
|
+
}),
|
|
1356
|
+
}).catch(() => {}); // Fire and forget
|
|
1357
|
+
}
|
|
1258
1358
|
|
|
1259
1359
|
// Check if capability exists
|
|
1260
1360
|
const exists = await hasCapability(capabilityId);
|
package/src/chain-types.ts
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chain Execution Types for APIClaw
|
|
3
|
-
*
|
|
4
|
-
* Enables multi-step API orchestration with:
|
|
5
|
-
* - Sequential execution
|
|
6
|
-
* - Parallel execution
|
|
7
|
-
* - Conditional branching
|
|
8
|
-
* - Loops (forEach, map-reduce)
|
|
9
|
-
* - Error handling & retry
|
|
10
|
-
* - Cross-step references ($stepId.property)
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
// ============================================
|
|
14
|
-
// CHAIN STEP TYPES
|
|
15
|
-
// ============================================
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Base step configuration
|
|
19
|
-
*/
|
|
20
|
-
export interface ChainStepBase {
|
|
21
|
-
id: string;
|
|
22
|
-
provider: string;
|
|
23
|
-
action: string;
|
|
24
|
-
params?: Record<string, any>;
|
|
25
|
-
onError?: ErrorHandler;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parallel execution step - runs multiple steps concurrently
|
|
30
|
-
*/
|
|
31
|
-
export interface ParallelStep {
|
|
32
|
-
parallel: ChainStepBase[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Conditional step - executes based on condition
|
|
37
|
-
*/
|
|
38
|
-
export interface ConditionalStep {
|
|
39
|
-
if: string; // Expression like "$step1.success === true"
|
|
40
|
-
then: ChainStepBase | ChainStep;
|
|
41
|
-
else?: ChainStepBase | ChainStep;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Loop step - iterates over array
|
|
46
|
-
*/
|
|
47
|
-
export interface ForEachStep {
|
|
48
|
-
forEach: string; // Reference like "$step1.results"
|
|
49
|
-
as: string; // Variable name for current item
|
|
50
|
-
do: ChainStepBase;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Map step - transforms array
|
|
55
|
-
*/
|
|
56
|
-
export interface MapStep {
|
|
57
|
-
map: {
|
|
58
|
-
input: string;
|
|
59
|
-
fn: ChainStepBase;
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Reduce step - aggregates results
|
|
65
|
-
*/
|
|
66
|
-
export interface ReduceStep {
|
|
67
|
-
reduce: {
|
|
68
|
-
input: string;
|
|
69
|
-
fn: ChainStepBase;
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Union type for all step variants
|
|
75
|
-
*/
|
|
76
|
-
export type ChainStep =
|
|
77
|
-
| ChainStepBase
|
|
78
|
-
| ParallelStep
|
|
79
|
-
| ConditionalStep
|
|
80
|
-
| ForEachStep
|
|
81
|
-
| MapStep
|
|
82
|
-
| ReduceStep;
|
|
83
|
-
|
|
84
|
-
// ============================================
|
|
85
|
-
// ERROR HANDLING
|
|
86
|
-
// ============================================
|
|
87
|
-
|
|
88
|
-
export interface RetryConfig {
|
|
89
|
-
attempts?: number;
|
|
90
|
-
maxAttempts?: number;
|
|
91
|
-
backoff?: number[] | 'exponential' | 'linear';
|
|
92
|
-
backoffMs?: number;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface ErrorHandler {
|
|
96
|
-
retry?: RetryConfig;
|
|
97
|
-
fallback?: ChainStepBase;
|
|
98
|
-
abort?: boolean;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export type ErrorPolicy = 'fail-fast' | 'best-effort' | 'transactional';
|
|
102
|
-
|
|
103
|
-
export interface RollbackAction {
|
|
104
|
-
if: string;
|
|
105
|
-
do: ChainStepBase;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface ChainErrorPolicy {
|
|
109
|
-
mode: ErrorPolicy;
|
|
110
|
-
rollback?: RollbackAction[];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// ============================================
|
|
114
|
-
// CHAIN CONFIGURATION
|
|
115
|
-
// ============================================
|
|
116
|
-
|
|
117
|
-
export interface ChainLimits {
|
|
118
|
-
maxSteps?: number;
|
|
119
|
-
maxParallel?: number;
|
|
120
|
-
maxCost?: { cents: number };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface ChainOptions {
|
|
124
|
-
continueOnError?: boolean;
|
|
125
|
-
timeout?: number; // Max execution time in ms
|
|
126
|
-
async?: boolean; // Return immediately with chainId
|
|
127
|
-
webhook?: string; // URL to call on completion
|
|
128
|
-
errorPolicy?: ChainErrorPolicy;
|
|
129
|
-
limits?: ChainLimits;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ============================================
|
|
133
|
-
// CHAIN EXECUTION REQUEST
|
|
134
|
-
// ============================================
|
|
135
|
-
|
|
136
|
-
export interface ChainRequest extends ChainOptions {
|
|
137
|
-
chain: ChainStep[];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ============================================
|
|
141
|
-
// STEP RESULT
|
|
142
|
-
// ============================================
|
|
143
|
-
|
|
144
|
-
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
|
145
|
-
|
|
146
|
-
export interface StepResult {
|
|
147
|
-
id: string;
|
|
148
|
-
status: StepStatus;
|
|
149
|
-
result?: any;
|
|
150
|
-
error?: string;
|
|
151
|
-
errorCode?: string;
|
|
152
|
-
latencyMs: number;
|
|
153
|
-
cost?: { cents: number };
|
|
154
|
-
retryAttempts?: number;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// ============================================
|
|
158
|
-
// CHAIN RESPONSE
|
|
159
|
-
// ============================================
|
|
160
|
-
|
|
161
|
-
export interface ChainSuccessResponse {
|
|
162
|
-
success: true;
|
|
163
|
-
chainId: string;
|
|
164
|
-
steps: StepResult[];
|
|
165
|
-
finalResult: any;
|
|
166
|
-
totalLatencyMs: number;
|
|
167
|
-
totalCost: { cents: number };
|
|
168
|
-
tokensSaved: number;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export interface ChainErrorResponse {
|
|
172
|
-
success: false;
|
|
173
|
-
chainId: string;
|
|
174
|
-
completedSteps: string[];
|
|
175
|
-
failedStep: {
|
|
176
|
-
id: string;
|
|
177
|
-
error: string;
|
|
178
|
-
code?: string;
|
|
179
|
-
retryAfter?: number;
|
|
180
|
-
};
|
|
181
|
-
partialResults: Record<string, any>;
|
|
182
|
-
canResume: boolean;
|
|
183
|
-
resumeToken?: string;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
export type ChainResponse = ChainSuccessResponse | ChainErrorResponse;
|
|
187
|
-
|
|
188
|
-
// ============================================
|
|
189
|
-
// ASYNC CHAIN STATUS
|
|
190
|
-
// ============================================
|
|
191
|
-
|
|
192
|
-
export interface AsyncChainResponse {
|
|
193
|
-
chainId: string;
|
|
194
|
-
status: 'running' | 'completed' | 'failed';
|
|
195
|
-
estimatedCompletion?: string;
|
|
196
|
-
statusUrl: string;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export interface ChainStatusResponse {
|
|
200
|
-
chainId: string;
|
|
201
|
-
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
202
|
-
progress: {
|
|
203
|
-
completedSteps: number;
|
|
204
|
-
totalSteps: number;
|
|
205
|
-
currentStep?: string;
|
|
206
|
-
};
|
|
207
|
-
startedAt: string;
|
|
208
|
-
completedAt?: string;
|
|
209
|
-
result?: ChainResponse;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// ============================================
|
|
213
|
-
// RESUME CHAIN
|
|
214
|
-
// ============================================
|
|
215
|
-
|
|
216
|
-
export interface ResumeChainRequest {
|
|
217
|
-
resumeToken: string;
|
|
218
|
-
overrides?: Record<string, Record<string, any>>; // stepId -> params overrides
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// ============================================
|
|
222
|
-
// STORED CHAIN TEMPLATES
|
|
223
|
-
// ============================================
|
|
224
|
-
|
|
225
|
-
export interface ChainInput {
|
|
226
|
-
type: 'string' | 'number' | 'boolean' | 'object' | 'array';
|
|
227
|
-
required?: boolean;
|
|
228
|
-
default?: any;
|
|
229
|
-
description?: string;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
export interface ChainTemplate {
|
|
233
|
-
name: string;
|
|
234
|
-
description?: string;
|
|
235
|
-
inputs: Record<string, ChainInput>;
|
|
236
|
-
chain: ChainStep[];
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export interface UseChainRequest {
|
|
240
|
-
useChain: string;
|
|
241
|
-
inputs: Record<string, any>;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// ============================================
|
|
245
|
-
// TYPE GUARDS
|
|
246
|
-
// ============================================
|
|
247
|
-
|
|
248
|
-
export function isParallelStep(step: ChainStep): step is ParallelStep {
|
|
249
|
-
return 'parallel' in step;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export function isConditionalStep(step: ChainStep): step is ConditionalStep {
|
|
253
|
-
return 'if' in step && 'then' in step;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export function isForEachStep(step: ChainStep): step is ForEachStep {
|
|
257
|
-
return 'forEach' in step && 'do' in step;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
export function isMapStep(step: ChainStep): step is MapStep {
|
|
261
|
-
return 'map' in step;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
export function isReduceStep(step: ChainStep): step is ReduceStep {
|
|
265
|
-
return 'reduce' in step;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export function isBaseStep(step: ChainStep): step is ChainStepBase {
|
|
269
|
-
return 'provider' in step && 'action' in step;
|
|
270
|
-
}
|