@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.
@@ -4,7 +4,7 @@
4
4
  "directCallCount": 18,
5
5
  "categoryCount": 13,
6
6
  "lastUpdated": "2026-02-27T09:10:41.344767",
7
- "generatedAt": "2026-03-02T00:02:51.920Z",
7
+ "generatedAt": "2026-03-03T16:58:33.036Z",
8
8
  "categoryBreakdown": {
9
9
  "Finance": 1179,
10
10
  "Auth & Security": 491,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nordsym/apiclaw",
3
- "version": "1.4.0",
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://adventurous-avocet-799.convex.cloud';
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
- trackSearch(query, results.length, Date.now() - startTime);
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);
@@ -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
- }