@nordsym/apiclaw 1.5.17 → 1.5.19
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/convex/http.js.map +1 -1
- package/convex/http.ts +516 -0
- package/dist/analytics.d.ts +0 -4
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +0 -1
- package/dist/analytics.js.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/cli/commands/mcp-install.d.ts.map +1 -1
- package/dist/cli/commands/mcp-install.js +8 -87
- package/dist/cli/commands/mcp-install.js.map +1 -1
- package/dist/cli/index.js +0 -7
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +38 -43
- package/dist/credentials.js.map +1 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +82 -191
- package/dist/discovery.js.map +1 -1
- package/dist/http-api.d.ts.map +1 -1
- package/dist/http-api.js +33 -17
- package/dist/http-api.js.map +1 -1
- package/dist/proxy.js +1 -1
- package/dist/proxy.js.map +1 -1
- package/landing/next-env.d.ts +0 -1
- package/landing/src/app/api/auth/magic-link/route.ts +1 -1
- package/landing/src/app/auth/verify/page.tsx +0 -6
- package/landing/src/app/dashboard/verify/page.tsx +0 -6
- package/landing/src/app/join/page.tsx +0 -6
- package/landing/src/app/layout.tsx +2 -2
- package/landing/src/app/login/page.tsx +1 -1
- package/landing/src/app/mou/[partnerId]/page.tsx +0 -6
- package/landing/src/app/page.tsx +18 -39
- package/landing/src/app/providers/dashboard/[apiId]/actions/[actionId]/edit/page.tsx +0 -6
- package/landing/src/app/providers/dashboard/[apiId]/actions/new/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/actions/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/direct-call/page.tsx +1 -6
- package/landing/src/app/providers/dashboard/[apiId]/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/[apiId]/test/page.tsx +0 -5
- package/landing/src/app/providers/dashboard/layout.tsx +6 -6
- package/landing/src/app/providers/dashboard/login/page.tsx +1 -1
- package/landing/src/app/providers/dashboard/page.tsx +1 -1
- package/landing/src/app/providers/dashboard/verify/page.tsx +0 -6
- package/landing/src/app/providers/layout.tsx +1 -1
- package/landing/src/app/upgrade/page.tsx +0 -6
- package/landing/src/app/workspace/page.tsx +0 -6
- package/landing/src/components/HeroTabs.tsx +2 -2
- package/landing/src/components/{Workspace.tsx → ProviderDashboard.tsx} +2 -2
- package/landing/src/components/VideoDemo.tsx +10 -21
- package/landing/src/lib/mock-data.ts +1 -1
- package/landing/src/lib/stats.json +1 -1
- package/package.json +3 -8
- package/src/analytics.ts +0 -5
- package/src/bin.ts +1 -1
- package/src/cli/commands/mcp-install.ts +8 -90
- package/src/cli/index.ts +0 -8
- package/src/credentials.ts +39 -44
- package/src/discovery.ts +82 -191
- package/src/http-api.ts +34 -18
- package/src/proxy.ts +1 -1
- package/APILAYER_STATUS_2026-03-24.md +0 -38
- package/CHANGELOG-WHITELIST-V2.md +0 -269
- package/HIVR-WHITELIST-STATUS.md +0 -205
- package/HIVR-WHITELIST.md +0 -148
- package/TERMINOLOGY-AUDIT.md +0 -99
- package/TERMINOLOGY-FIXED.md +0 -74
- package/VIDEO-DEMO-GUIDE.md +0 -82
- package/WHITELIST-ARCHITECTURE.md +0 -379
- package/api/discover.ts +0 -71
- package/api/health.ts +0 -20
- package/convex/adminActivate.d.ts +0 -3
- package/convex/adminActivate.js +0 -47
- package/convex/adminStats.d.ts +0 -3
- package/convex/adminStats.js +0 -42
- package/convex/agents.d.ts +0 -54
- package/convex/agents.js +0 -499
- package/convex/analytics.d.ts +0 -5
- package/convex/analytics.js +0 -166
- package/convex/billing.d.ts +0 -88
- package/convex/billing.js +0 -655
- package/convex/capabilities.d.ts +0 -9
- package/convex/capabilities.js +0 -145
- package/convex/chains.d.ts +0 -67
- package/convex/chains.js +0 -1042
- package/convex/credits.d.ts +0 -25
- package/convex/credits.js +0 -186
- package/convex/crons.d.ts +0 -3
- package/convex/crons.js +0 -17
- package/convex/directCall.d.ts +0 -72
- package/convex/directCall.js +0 -627
- package/convex/earnProgress.d.ts +0 -58
- package/convex/earnProgress.js +0 -649
- package/convex/email.d.ts +0 -14
- package/convex/email.js +0 -300
- package/convex/feedback.d.ts +0 -7
- package/convex/feedback.js +0 -227
- package/convex/http.d.ts +0 -3
- package/convex/http.js +0 -910
- package/convex/logs.d.ts +0 -38
- package/convex/logs.js +0 -487
- package/convex/mou.d.ts +0 -6
- package/convex/mou.js +0 -82
- package/convex/providerKeys.d.ts +0 -31
- package/convex/providerKeys.js +0 -257
- package/convex/providers.d.ts +0 -29
- package/convex/providers.js +0 -756
- package/convex/purchases.d.ts +0 -7
- package/convex/purchases.js +0 -157
- package/convex/ratelimit.d.ts +0 -4
- package/convex/ratelimit.js +0 -91
- package/convex/searchLogs.d.ts +0 -4
- package/convex/searchLogs.js +0 -129
- package/convex/spendAlerts.d.ts +0 -36
- package/convex/spendAlerts.js +0 -380
- package/convex/stripeActions.d.ts +0 -19
- package/convex/stripeActions.js +0 -411
- package/convex/teams.d.ts +0 -21
- package/convex/teams.js +0 -215
- package/convex/telemetry.d.ts +0 -4
- package/convex/telemetry.js +0 -74
- package/convex/usage.d.ts +0 -27
- package/convex/usage.js +0 -229
- package/convex/waitlist.d.ts +0 -4
- package/convex/waitlist.js +0 -49
- package/convex/webhooks.d.ts +0 -12
- package/convex/webhooks.js +0 -410
- package/convex/workspaces.d.ts +0 -29
- package/convex/workspaces.js +0 -880
- package/direct-test.mjs +0 -51
- package/dist/access-control.d.ts +0 -45
- package/dist/access-control.d.ts.map +0 -1
- package/dist/access-control.js +0 -142
- package/dist/access-control.js.map +0 -1
- package/dist/chain-types.d.ts +0 -187
- package/dist/chain-types.d.ts.map +0 -1
- package/dist/chain-types.js +0 -33
- package/dist/chain-types.js.map +0 -1
- package/dist/convex/adminActivate.js +0 -46
- package/dist/convex/adminStats.js +0 -41
- package/dist/convex/agents.js +0 -498
- package/dist/convex/analytics.js +0 -165
- package/dist/convex/billing.js +0 -654
- package/dist/convex/capabilities.js +0 -144
- package/dist/convex/chains.js +0 -1041
- package/dist/convex/credits.js +0 -185
- package/dist/convex/crons.js +0 -16
- package/dist/convex/directCall.js +0 -626
- package/dist/convex/earnProgress.js +0 -648
- package/dist/convex/email.js +0 -299
- package/dist/convex/feedback.js +0 -226
- package/dist/convex/http.js +0 -909
- package/dist/convex/logs.js +0 -486
- package/dist/convex/mou.js +0 -81
- package/dist/convex/providerKeys.js +0 -256
- package/dist/convex/providers.js +0 -755
- package/dist/convex/purchases.js +0 -156
- package/dist/convex/ratelimit.js +0 -90
- package/dist/convex/schema.js +0 -709
- package/dist/convex/searchLogs.js +0 -128
- package/dist/convex/spendAlerts.js +0 -379
- package/dist/convex/stripeActions.js +0 -410
- package/dist/convex/teams.js +0 -214
- package/dist/convex/telemetry.js +0 -73
- package/dist/convex/usage.js +0 -228
- package/dist/convex/waitlist.js +0 -48
- package/dist/convex/webhooks.js +0 -409
- package/dist/convex/workspaces.js +0 -879
- package/dist/hivr-whitelist.d.ts +0 -18
- package/dist/hivr-whitelist.d.ts.map +0 -1
- package/dist/hivr-whitelist.js +0 -95
- package/dist/hivr-whitelist.js.map +0 -1
- package/dist/http-server-minimal.d.ts +0 -7
- package/dist/http-server-minimal.d.ts.map +0 -1
- package/dist/http-server-minimal.js +0 -126
- package/dist/http-server-minimal.js.map +0 -1
- package/dist/product-whitelist.d.ts +0 -37
- package/dist/product-whitelist.d.ts.map +0 -1
- package/dist/product-whitelist.js +0 -203
- package/dist/product-whitelist.js.map +0 -1
- package/dist/src/analytics.js +0 -129
- package/dist/src/bin.js +0 -17
- package/dist/src/capability-router.js +0 -240
- package/dist/src/chainExecutor.js +0 -451
- package/dist/src/chainResolver.js +0 -518
- package/dist/src/cli/commands/doctor.js +0 -324
- package/dist/src/cli/commands/mcp-install.js +0 -255
- package/dist/src/cli/commands/restore.js +0 -259
- package/dist/src/cli/commands/setup.js +0 -205
- package/dist/src/cli/commands/uninstall.js +0 -188
- package/dist/src/cli/index.js +0 -111
- package/dist/src/cli.js +0 -302
- package/dist/src/confirmation.js +0 -240
- package/dist/src/credentials.js +0 -357
- package/dist/src/credits.js +0 -260
- package/dist/src/crypto.js +0 -66
- package/dist/src/discovery.js +0 -504
- package/dist/src/enterprise/env.js +0 -123
- package/dist/src/enterprise/script-generator.js +0 -460
- package/dist/src/execute-dynamic.js +0 -473
- package/dist/src/execute.js +0 -1727
- package/dist/src/index.js +0 -2062
- package/dist/src/metered.js +0 -80
- package/dist/src/open-apis.js +0 -276
- package/dist/src/proxy.js +0 -28
- package/dist/src/session.js +0 -86
- package/dist/src/stripe.js +0 -407
- package/dist/src/telemetry.js +0 -49
- package/dist/src/types.js +0 -2
- package/dist/src/utils/backup.js +0 -181
- package/dist/src/utils/config.js +0 -220
- package/dist/src/utils/os.js +0 -105
- package/dist/src/utils/paths.js +0 -159
- package/landing/pages/api/discover.ts +0 -43
- package/landing/pages/api/health.ts +0 -20
- package/scripts/test-whitelist-v2.sh +0 -128
- package/src/access-control.ts +0 -174
- package/src/hivr-whitelist.ts +0 -110
- package/src/http-server-minimal.ts +0 -154
- package/src/product-whitelist.ts +0 -246
- package/test-actual-handlers.ts +0 -92
- package/test-apilayer-all-14.ts +0 -249
- package/test-apilayer-fixed.ts +0 -248
- package/test-direct-endpoints.ts +0 -174
- package/test-exact-endpoints.ts +0 -144
- package/test-final.ts +0 -83
- package/test-full-routing.ts +0 -100
- package/test-handlers-correct.ts +0 -217
- package/test-numverify-key.ts +0 -41
- package/test-via-handlers.ts +0 -92
- package/test-worldnews.mjs +0 -26
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
# APIClaw Multi-Product Whitelist Architecture
|
|
2
|
-
|
|
3
|
-
**Version:** 2.0
|
|
4
|
-
**Date:** 2026-03-18
|
|
5
|
-
**Status:** Production Ready
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Overview
|
|
10
|
-
|
|
11
|
-
APIClaw supports multiple products (Hivr, NordSym, partners) accessing Direct Call APIs via HTTP endpoints with:
|
|
12
|
-
- **Product-namespaced agentIds** (`product:agentName`)
|
|
13
|
-
- **Per-provider access control** (some products get certain APIs only)
|
|
14
|
-
- **Dynamic whitelist syncing** from product Convex deployments
|
|
15
|
-
- **Per-product analytics** tracking
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Architecture
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
23
|
-
│ Products │
|
|
24
|
-
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
25
|
-
│ │ Hivr │ │ NordSym │ │Partner X │ │
|
|
26
|
-
│ │ Convex │ │ Convex │ │ Convex │ │
|
|
27
|
-
│ └─────┬────┘ └─────┬────┘ └─────┬────┘ │
|
|
28
|
-
└────────┼─────────────┼─────────────┼────────────────────────┘
|
|
29
|
-
│ │ │
|
|
30
|
-
│ agents:list │ team:list │ agents:list
|
|
31
|
-
│ │ │
|
|
32
|
-
└─────────────┴─────────────┴────────────────────┐
|
|
33
|
-
│
|
|
34
|
-
┌──────────────────────────────────────────────────────────────┤
|
|
35
|
-
│ APIClaw Product Whitelist │
|
|
36
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
37
|
-
│ │ product-whitelist.ts │ │
|
|
38
|
-
│ │ - Fetch from multiple Convex sources │ │
|
|
39
|
-
│ │ - Cache per product (5 min TTL) │ │
|
|
40
|
-
│ │ - Namespace: product:agentId │ │
|
|
41
|
-
│ │ - Fallback to static whitelist │ │
|
|
42
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
43
|
-
│ │
|
|
44
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
45
|
-
│ │ access-control.ts │ │
|
|
46
|
-
│ │ - Per-provider permissions │ │
|
|
47
|
-
│ │ - Pattern matching (hivr:*, nordsym:*) │ │
|
|
48
|
-
│ │ - Deny by default │ │
|
|
49
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
50
|
-
│ │
|
|
51
|
-
│ ┌────────────────────────────────────────────────────────┐ │
|
|
52
|
-
│ │ http-api.ts │ │
|
|
53
|
-
│ │ - /api/discover?agentId=hivr:bytebee │ │
|
|
54
|
-
│ │ - POST /api/call_api { agentId, provider, ... } │ │
|
|
55
|
-
│ └────────────────────────────────────────────────────────┘ │
|
|
56
|
-
└───────────────────────────────────────────────────────────────┘
|
|
57
|
-
│
|
|
58
|
-
│ Logs usage
|
|
59
|
-
▼
|
|
60
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
61
|
-
│ Analytics │
|
|
62
|
-
│ - Product-level tracking │
|
|
63
|
-
│ - Per-agent usage │
|
|
64
|
-
│ - Provider access logs │
|
|
65
|
-
└──────────────────────────────────────────────────────────────┘
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Product Configuration
|
|
71
|
-
|
|
72
|
-
**File:** `src/product-whitelist.ts`
|
|
73
|
-
|
|
74
|
-
### Adding a New Product
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
const PRODUCT_SOURCES: ProductSource[] = [
|
|
78
|
-
{
|
|
79
|
-
name: 'hivr',
|
|
80
|
-
convexUrl: 'https://sensible-quail-275.convex.cloud',
|
|
81
|
-
queryPath: 'agents:list',
|
|
82
|
-
agentIdField: 'agentId',
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'nordsym',
|
|
86
|
-
convexUrl: 'https://nordsym-deployment.convex.cloud',
|
|
87
|
-
queryPath: 'team:listAgents',
|
|
88
|
-
agentIdField: 'memberId',
|
|
89
|
-
authToken: process.env.NORDSYM_API_TOKEN, // Optional
|
|
90
|
-
},
|
|
91
|
-
];
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
**Fields:**
|
|
95
|
-
- `name` — Product identifier (used in namespace)
|
|
96
|
-
- `convexUrl` — Convex deployment URL
|
|
97
|
-
- `queryPath` — Convex query function path
|
|
98
|
-
- `agentIdField` — Field name for agent identifier
|
|
99
|
-
- `authToken` — Optional Bearer token for auth
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Access Control Rules
|
|
104
|
-
|
|
105
|
-
**File:** `src/access-control.ts`
|
|
106
|
-
|
|
107
|
-
### Rule Format
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
interface AccessRule {
|
|
111
|
-
agentPattern: string; // e.g., "hivr:*", "nordsym:mollebot"
|
|
112
|
-
allowedProviders: string[]; // e.g., ["*"], ["brave_search", "groq"]
|
|
113
|
-
description?: string;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Default Rules
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
const DEFAULT_RULES: AccessRule[] = [
|
|
121
|
-
{
|
|
122
|
-
agentPattern: 'hivr:*',
|
|
123
|
-
allowedProviders: ['*'], // All providers
|
|
124
|
-
description: 'Hivr bees get full access',
|
|
125
|
-
},
|
|
126
|
-
{
|
|
127
|
-
agentPattern: 'nordsym:*',
|
|
128
|
-
allowedProviders: ['brave_search', 'groq', 'replicate'],
|
|
129
|
-
description: 'NordSym team gets selected providers',
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Pattern Matching
|
|
135
|
-
|
|
136
|
-
- `hivr:*` — All Hivr agents
|
|
137
|
-
- `hivr:bytebee` — Specific agent
|
|
138
|
-
- `nordsym:molle*` — Prefix match
|
|
139
|
-
|
|
140
|
-
### Provider Wildcards
|
|
141
|
-
|
|
142
|
-
- `*` — All providers
|
|
143
|
-
- `brave_*` — All Brave providers
|
|
144
|
-
- `["brave_search", "groq"]` — Specific list
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Usage Examples
|
|
149
|
-
|
|
150
|
-
### HTTP API Request (Namespaced)
|
|
151
|
-
|
|
152
|
-
```bash
|
|
153
|
-
curl -X POST "https://apiclaw.com/api/call_api" \
|
|
154
|
-
-H "Content-Type: application/json" \
|
|
155
|
-
-d '{
|
|
156
|
-
"agentId": "hivr:bytebee",
|
|
157
|
-
"provider": "brave_search",
|
|
158
|
-
"action": "search",
|
|
159
|
-
"params": {"query": "AI news"}
|
|
160
|
-
}'
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### HTTP API Request (Legacy)
|
|
164
|
-
|
|
165
|
-
```bash
|
|
166
|
-
# Legacy format (no namespace) still works
|
|
167
|
-
curl -X POST "https://apiclaw.com/api/call_api" \
|
|
168
|
-
-H "Content-Type: application/json" \
|
|
169
|
-
-d '{
|
|
170
|
-
"agentId": "bytebee",
|
|
171
|
-
"provider": "brave_search",
|
|
172
|
-
"action": "search",
|
|
173
|
-
"params": {"query": "AI news"}
|
|
174
|
-
}'
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Discovery Endpoint
|
|
178
|
-
|
|
179
|
-
```bash
|
|
180
|
-
curl "https://apiclaw.com/api/discover?query=web+search&agentId=hivr:bytebee"
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
---
|
|
184
|
-
|
|
185
|
-
## Security Model
|
|
186
|
-
|
|
187
|
-
### 1. Whitelist Check
|
|
188
|
-
- Agent must exist in product's Convex deployment
|
|
189
|
-
- Fetched dynamically (cached 5 min)
|
|
190
|
-
- Fallback to static list if all sources fail
|
|
191
|
-
|
|
192
|
-
### 2. Access Control
|
|
193
|
-
- Per-provider permissions checked
|
|
194
|
-
- Pattern-based rules (`hivr:*`, `nordsym:mollebot`)
|
|
195
|
-
- Deny by default
|
|
196
|
-
|
|
197
|
-
### 3. Response on Denial
|
|
198
|
-
|
|
199
|
-
```json
|
|
200
|
-
{
|
|
201
|
-
"error": "Access Denied",
|
|
202
|
-
"message": "Provider not in access list",
|
|
203
|
-
"hint": "Contact admin@nordsym.com for access"
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
## Analytics Tracking
|
|
210
|
-
|
|
211
|
-
**Product-level metrics tracked:**
|
|
212
|
-
- Total calls per product
|
|
213
|
-
- Per-agent usage within product
|
|
214
|
-
- Provider access patterns
|
|
215
|
-
- Success/error rates
|
|
216
|
-
- Latency per product
|
|
217
|
-
|
|
218
|
-
**Log format:**
|
|
219
|
-
```jsonl
|
|
220
|
-
{
|
|
221
|
-
"timestamp": "2026-03-18T16:00:00.000Z",
|
|
222
|
-
"provider": "brave_search",
|
|
223
|
-
"action": "search",
|
|
224
|
-
"type": "direct",
|
|
225
|
-
"userId": "hivr:bytebee",
|
|
226
|
-
"success": true,
|
|
227
|
-
"latencyMs": 150,
|
|
228
|
-
"metadata": {
|
|
229
|
-
"product": "hivr"
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Cache Management
|
|
237
|
-
|
|
238
|
-
### Per-Product Caching
|
|
239
|
-
- Each product cached separately
|
|
240
|
-
- TTL: 5 minutes
|
|
241
|
-
- Parallel fetches from all sources
|
|
242
|
-
|
|
243
|
-
### Manual Invalidation
|
|
244
|
-
|
|
245
|
-
```typescript
|
|
246
|
-
import { invalidateCache } from './product-whitelist.js';
|
|
247
|
-
|
|
248
|
-
// Invalidate specific product
|
|
249
|
-
invalidateCache('hivr');
|
|
250
|
-
|
|
251
|
-
// Invalidate all
|
|
252
|
-
invalidateCache();
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## Error Handling
|
|
258
|
-
|
|
259
|
-
### Product Source Down
|
|
260
|
-
|
|
261
|
-
- Other products continue working
|
|
262
|
-
- Falls back to static whitelist if ALL sources fail
|
|
263
|
-
- Logs warning, no crash
|
|
264
|
-
|
|
265
|
-
### Partial Failures
|
|
266
|
-
|
|
267
|
-
```
|
|
268
|
-
[Whitelist] hivr: Fetched 12 agents
|
|
269
|
-
[Whitelist] nordsym: HTTP 500
|
|
270
|
-
[Whitelist] Total agents: 12 (1 source failed)
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Migration Guide
|
|
276
|
-
|
|
277
|
-
### From v1 (Hivr-only) to v2 (Multi-product)
|
|
278
|
-
|
|
279
|
-
**Old code:**
|
|
280
|
-
```typescript
|
|
281
|
-
const authorized = await isAuthorized('bytebee');
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
**New code:**
|
|
285
|
-
```typescript
|
|
286
|
-
const authorized = await isAuthorized('hivr:bytebee');
|
|
287
|
-
// OR legacy format still works
|
|
288
|
-
const authorized = await isAuthorized('bytebee');
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Breaking changes:** None (backward compatible)
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## Testing
|
|
296
|
-
|
|
297
|
-
### Local Test
|
|
298
|
-
|
|
299
|
-
```bash
|
|
300
|
-
# Start HTTP API
|
|
301
|
-
npm run start:http
|
|
302
|
-
|
|
303
|
-
# Test whitelisted agent
|
|
304
|
-
curl "http://localhost:3000/api/discover?query=web&agentId=hivr:bytebee"
|
|
305
|
-
# → 200 OK
|
|
306
|
-
|
|
307
|
-
# Test unauthorized agent
|
|
308
|
-
curl "http://localhost:3000/api/discover?query=web&agentId=hacker:evil"
|
|
309
|
-
# → 403 Access Denied
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Test Access Control
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
# Hivr bee accessing allowed provider
|
|
316
|
-
curl -X POST "http://localhost:3000/api/call_api" \
|
|
317
|
-
-d '{"agentId":"hivr:bytebee","provider":"brave_search","action":"search","params":{}}'
|
|
318
|
-
# → 200 OK
|
|
319
|
-
|
|
320
|
-
# NordSym accessing restricted provider (if not in allowlist)
|
|
321
|
-
curl -X POST "http://localhost:3000/api/call_api" \
|
|
322
|
-
-d '{"agentId":"nordsym:bot","provider":"restricted_api","action":"call","params":{}}'
|
|
323
|
-
# → 403 Provider not in access list
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Future Enhancements
|
|
329
|
-
|
|
330
|
-
### Planned
|
|
331
|
-
- [ ] Convex table for access rules (dynamic updates)
|
|
332
|
-
- [ ] Webhook triggers when new agent added (instant sync)
|
|
333
|
-
- [ ] Per-agent rate limits
|
|
334
|
-
- [ ] Usage quotas per product
|
|
335
|
-
- [ ] Admin UI for whitelist management
|
|
336
|
-
|
|
337
|
-
### Possible
|
|
338
|
-
- [ ] Geographic restrictions
|
|
339
|
-
- [ ] Time-based access windows
|
|
340
|
-
- [ ] Cost allocation per product
|
|
341
|
-
- [ ] Audit logs
|
|
342
|
-
|
|
343
|
-
---
|
|
344
|
-
|
|
345
|
-
## Troubleshooting
|
|
346
|
-
|
|
347
|
-
### New agent not authorized immediately
|
|
348
|
-
**Solution:** Wait 5 minutes (cache TTL) or restart APIClaw HTTP server
|
|
349
|
-
|
|
350
|
-
### All agents unauthorized
|
|
351
|
-
**Check:**
|
|
352
|
-
1. Product source Convex URL correct?
|
|
353
|
-
2. Query path returns array?
|
|
354
|
-
3. agentIdField matches response structure?
|
|
355
|
-
|
|
356
|
-
**Debug:**
|
|
357
|
-
```bash
|
|
358
|
-
# Check logs
|
|
359
|
-
tail -f ~/.apiclaw/logs/api-calls.jsonl | grep whitelist
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
### Access denied despite whitelist
|
|
363
|
-
**Check:**
|
|
364
|
-
1. Is provider in access rules?
|
|
365
|
-
2. Does pattern match agentId?
|
|
366
|
-
3. Check logs for reason
|
|
367
|
-
|
|
368
|
-
---
|
|
369
|
-
|
|
370
|
-
## Contact
|
|
371
|
-
|
|
372
|
-
**Questions:** admin@nordsym.com
|
|
373
|
-
**Issues:** GitHub issues (APIClaw repo)
|
|
374
|
-
**Docs:** https://apiclaw.com/docs/whitelist
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
**Last updated:** 2026-03-18
|
|
379
|
-
**Architecture version:** 2.0
|
package/api/discover.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APIClaw Discovery API - Vercel Serverless Function
|
|
3
|
-
* GET /api/discover?query=...&agentId=...
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
7
|
-
import { isAuthorized, getProduct } from '../dist/product-whitelist.js';
|
|
8
|
-
import { discoverAPIs } from '../dist/discovery.js';
|
|
9
|
-
import { logAPICall } from '../dist/analytics.js';
|
|
10
|
-
|
|
11
|
-
export default async function handler(
|
|
12
|
-
req: VercelRequest,
|
|
13
|
-
res: VercelResponse
|
|
14
|
-
) {
|
|
15
|
-
// CORS
|
|
16
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
17
|
-
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
|
|
18
|
-
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Agent-Id');
|
|
19
|
-
|
|
20
|
-
if (req.method === 'OPTIONS') {
|
|
21
|
-
return res.status(200).end();
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (req.method !== 'GET') {
|
|
25
|
-
return res.status(405).json({ error: 'Method not allowed' });
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const { query, agentId, category, maxResults } = req.query;
|
|
29
|
-
|
|
30
|
-
if (!query || typeof query !== 'string') {
|
|
31
|
-
return res.status(400).json({ error: 'Missing query parameter' });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const agentIdStr = typeof agentId === 'string' ? agentId : undefined;
|
|
35
|
-
|
|
36
|
-
if (!(await isAuthorized(agentIdStr))) {
|
|
37
|
-
return res.status(403).json({
|
|
38
|
-
error: 'Unauthorized',
|
|
39
|
-
message: 'This endpoint is restricted. Contact admin@nordsym.com',
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const startTime = Date.now();
|
|
44
|
-
const results = discoverAPIs(query, {
|
|
45
|
-
category: typeof category === 'string' ? category : undefined,
|
|
46
|
-
maxResults: typeof maxResults === 'string' ? parseInt(maxResults) : 5,
|
|
47
|
-
});
|
|
48
|
-
const responseTimeMs = Date.now() - startTime;
|
|
49
|
-
|
|
50
|
-
// Log to analytics
|
|
51
|
-
const product = agentIdStr ? getProduct(agentIdStr) : null;
|
|
52
|
-
logAPICall({
|
|
53
|
-
timestamp: new Date().toISOString(),
|
|
54
|
-
provider: 'apiclaw_discovery',
|
|
55
|
-
action: 'discover',
|
|
56
|
-
type: 'open',
|
|
57
|
-
userId: agentIdStr || 'unknown',
|
|
58
|
-
success: true,
|
|
59
|
-
latencyMs: responseTimeMs,
|
|
60
|
-
metadata: product ? { product } : undefined,
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return res.status(200).json({
|
|
64
|
-
success: true,
|
|
65
|
-
query,
|
|
66
|
-
agentId: agentIdStr,
|
|
67
|
-
product,
|
|
68
|
-
results,
|
|
69
|
-
responseTimeMs,
|
|
70
|
-
});
|
|
71
|
-
}
|
package/api/health.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* APIClaw Health Check - Vercel Serverless Function
|
|
3
|
-
* GET /api/health
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { VercelRequest, VercelResponse } from '@vercel/node';
|
|
7
|
-
|
|
8
|
-
export default async function handler(
|
|
9
|
-
req: VercelRequest,
|
|
10
|
-
res: VercelResponse
|
|
11
|
-
) {
|
|
12
|
-
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
13
|
-
|
|
14
|
-
return res.status(200).json({
|
|
15
|
-
status: 'ok',
|
|
16
|
-
service: 'apiclaw-http-api',
|
|
17
|
-
version: '2.0.0',
|
|
18
|
-
timestamp: new Date().toISOString(),
|
|
19
|
-
});
|
|
20
|
-
}
|
package/convex/adminActivate.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { mutation } from "./_generated/server";
|
|
2
|
-
import { v } from "convex/values";
|
|
3
|
-
export const activateWorkspace = mutation({
|
|
4
|
-
args: { workspaceId: v.id("workspaces") },
|
|
5
|
-
handler: async (ctx, { workspaceId }) => {
|
|
6
|
-
const workspace = await ctx.db.get(workspaceId);
|
|
7
|
-
if (!workspace) {
|
|
8
|
-
return { success: false, error: "not_found" };
|
|
9
|
-
}
|
|
10
|
-
await ctx.db.patch(workspaceId, {
|
|
11
|
-
status: "active",
|
|
12
|
-
tier: "backer", // Give Hivr bees backer status
|
|
13
|
-
weeklyUsageLimit: 999999,
|
|
14
|
-
usageLimit: 999999,
|
|
15
|
-
backerUntil: new Date("2026-12-31T23:59:59Z").getTime(), // Founding Backer until end of 2026
|
|
16
|
-
updatedAt: Date.now(),
|
|
17
|
-
});
|
|
18
|
-
return { success: true };
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
function generateToken() {
|
|
22
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
23
|
-
let result = '';
|
|
24
|
-
for (let i = 0; i < 32; i++) {
|
|
25
|
-
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
26
|
-
}
|
|
27
|
-
return result;
|
|
28
|
-
}
|
|
29
|
-
export const createSessionForWorkspace = mutation({
|
|
30
|
-
args: { workspaceId: v.id("workspaces") },
|
|
31
|
-
handler: async (ctx, { workspaceId }) => {
|
|
32
|
-
const workspace = await ctx.db.get(workspaceId);
|
|
33
|
-
if (!workspace || workspace.status !== "active") {
|
|
34
|
-
return { success: false, error: "workspace_not_active" };
|
|
35
|
-
}
|
|
36
|
-
const sessionToken = "apiclaw_" + generateToken();
|
|
37
|
-
await ctx.db.insert("agentSessions", {
|
|
38
|
-
workspaceId,
|
|
39
|
-
sessionToken,
|
|
40
|
-
fingerprint: "hivr-bees",
|
|
41
|
-
lastUsedAt: Date.now(),
|
|
42
|
-
createdAt: Date.now(),
|
|
43
|
-
});
|
|
44
|
-
return { success: true, sessionToken };
|
|
45
|
-
},
|
|
46
|
-
});
|
|
47
|
-
//# sourceMappingURL=adminActivate.js.map
|
package/convex/adminStats.d.ts
DELETED
package/convex/adminStats.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { query } from "./_generated/server";
|
|
2
|
-
// Get total user/workspace count
|
|
3
|
-
export const getTotalWorkspaces = query({
|
|
4
|
-
args: {},
|
|
5
|
-
handler: async (ctx) => {
|
|
6
|
-
const workspaces = await ctx.db.query("workspaces").collect();
|
|
7
|
-
const providers = await ctx.db.query("providers").collect();
|
|
8
|
-
return {
|
|
9
|
-
totalWorkspaces: workspaces.length,
|
|
10
|
-
totalProviders: providers.length,
|
|
11
|
-
activeWorkspaces: workspaces.filter(w => w.status === "active").length,
|
|
12
|
-
backers: workspaces.filter(w => w.tier === "backer").length,
|
|
13
|
-
workspaceBreakdown: {
|
|
14
|
-
free: workspaces.filter(w => w.tier === "free").length,
|
|
15
|
-
pro: workspaces.filter(w => w.tier === "pro").length,
|
|
16
|
-
enterprise: workspaces.filter(w => w.tier === "enterprise").length,
|
|
17
|
-
backer: workspaces.filter(w => w.tier === "backer").length,
|
|
18
|
-
},
|
|
19
|
-
providerBreakdown: {
|
|
20
|
-
pending: providers.filter(p => p.status === "pending").length,
|
|
21
|
-
approved: providers.filter(p => p.status === "approved").length,
|
|
22
|
-
rejected: providers.filter(p => p.status === "rejected").length,
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
// List all workspace emails (for inspection)
|
|
28
|
-
export const listWorkspaces = query({
|
|
29
|
-
args: {},
|
|
30
|
-
handler: async (ctx) => {
|
|
31
|
-
const workspaces = await ctx.db.query("workspaces").collect();
|
|
32
|
-
return workspaces.map(w => ({
|
|
33
|
-
email: w.email,
|
|
34
|
-
status: w.status,
|
|
35
|
-
tier: w.tier,
|
|
36
|
-
usageCount: w.usageCount,
|
|
37
|
-
createdAt: w.createdAt,
|
|
38
|
-
lastActiveAt: w.lastActiveAt,
|
|
39
|
-
}));
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
//# sourceMappingURL=adminStats.js.map
|
package/convex/agents.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get main agent info for a workspace
|
|
3
|
-
*/
|
|
4
|
-
export declare const getMainAgent: any;
|
|
5
|
-
/**
|
|
6
|
-
* Rename the main agent
|
|
7
|
-
*/
|
|
8
|
-
export declare const renameMainAgent: any;
|
|
9
|
-
/**
|
|
10
|
-
* Initialize main agent (auto-generate name and ID if not set)
|
|
11
|
-
* Called on first API call
|
|
12
|
-
*/
|
|
13
|
-
export declare const ensureMainAgent: any;
|
|
14
|
-
/**
|
|
15
|
-
* Get all subagents for a workspace
|
|
16
|
-
*/
|
|
17
|
-
export declare const getSubagents: any;
|
|
18
|
-
/**
|
|
19
|
-
* Get stats for a specific subagent
|
|
20
|
-
*/
|
|
21
|
-
export declare const getSubagentStats: any;
|
|
22
|
-
/**
|
|
23
|
-
* Rename a subagent
|
|
24
|
-
*/
|
|
25
|
-
export declare const renameSubagent: any;
|
|
26
|
-
/**
|
|
27
|
-
* Track a subagent call (upsert subagent record)
|
|
28
|
-
* Called when X-APIClaw-Subagent header is present
|
|
29
|
-
*/
|
|
30
|
-
export declare const trackSubagentCall: any;
|
|
31
|
-
/**
|
|
32
|
-
* Pre-register a task agent (subagent)
|
|
33
|
-
* Allows agents to be registered before they make their first call
|
|
34
|
-
*/
|
|
35
|
-
export declare const registerTaskAgent: any;
|
|
36
|
-
/**
|
|
37
|
-
* Update AI backend for workspace or subagent
|
|
38
|
-
* Called when X-APIClaw-AI-Backend header is present
|
|
39
|
-
*/
|
|
40
|
-
export declare const updateAIBackend: any;
|
|
41
|
-
/**
|
|
42
|
-
* Get agent overview for workspace (main + subagents summary)
|
|
43
|
-
*/
|
|
44
|
-
export declare const getAgentOverview: any;
|
|
45
|
-
/**
|
|
46
|
-
* Delete a subagent
|
|
47
|
-
*/
|
|
48
|
-
export declare const deleteSubagent: any;
|
|
49
|
-
/**
|
|
50
|
-
* Update subagent stats (call count, last active)
|
|
51
|
-
* Internal helper for tracking
|
|
52
|
-
*/
|
|
53
|
-
export declare const updateSubagentStats: any;
|
|
54
|
-
//# sourceMappingURL=agents.d.ts.map
|