web-agent-bridge 3.2.0 β 3.4.0
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/LICENSE +84 -72
- package/README.ar.md +1304 -1152
- package/README.md +298 -1635
- package/bin/agent-runner.js +474 -474
- package/bin/cli.js +237 -138
- package/bin/wab-init.js +223 -0
- package/bin/wab.js +80 -80
- package/examples/azure-dns-wab.js +83 -0
- package/examples/bidi-agent.js +119 -119
- package/examples/cloudflare-wab-dns.js +121 -0
- package/examples/cpanel-wab-dns.js +114 -0
- package/examples/cross-site-agent.js +91 -91
- package/examples/dns-discovery-agent.js +166 -0
- package/examples/gcp-dns-wab.js +76 -0
- package/examples/governance-agent.js +169 -0
- package/examples/mcp-agent.js +94 -94
- package/examples/next-app-router/README.md +44 -44
- package/examples/plesk-wab-dns.js +103 -0
- package/examples/puppeteer-agent.js +108 -108
- package/examples/route53-wab-dns.js +144 -0
- package/examples/saas-dashboard/README.md +55 -55
- package/examples/safe-mode-agent.js +96 -0
- package/examples/shopify-hydrogen/README.md +74 -74
- package/examples/vision-agent.js +171 -171
- package/examples/wab-sign.js +74 -0
- package/examples/wab-verify.js +60 -0
- package/examples/wordpress-elementor/README.md +77 -77
- package/package.json +19 -6
- package/public/.well-known/agent-tools.json +180 -180
- package/public/.well-known/ai-assets.json +59 -59
- package/public/.well-known/security.txt +8 -0
- package/public/.well-known/wab.json +28 -0
- package/public/activate.html +368 -0
- package/public/adoption-metrics.html +188 -0
- package/public/agent-workspace.html +349 -349
- package/public/ai.html +198 -198
- package/public/api.html +413 -412
- package/public/azure-dns-integration.html +289 -0
- package/public/browser.html +486 -486
- package/public/cloudflare-integration.html +380 -0
- package/public/commander-dashboard.html +243 -243
- package/public/cookies.html +210 -210
- package/public/cpanel-integration.html +398 -0
- package/public/css/agent-workspace.css +1713 -1713
- package/public/css/premium.css +317 -317
- package/public/css/styles.css +1263 -1235
- package/public/dashboard.html +707 -706
- package/public/dns.html +436 -0
- package/public/docs.html +588 -587
- package/public/feed.xml +89 -89
- package/public/gcp-dns-integration.html +318 -0
- package/public/growth.html +465 -463
- package/public/index.html +1266 -982
- package/public/integrations.html +556 -0
- package/public/js/activate.js +145 -0
- package/public/js/agent-workspace.js +1740 -1740
- package/public/js/auth-nav.js +65 -31
- package/public/js/auth-redirect.js +12 -12
- package/public/js/cookie-consent.js +56 -56
- package/public/js/dns.js +438 -0
- package/public/js/wab-demo-page.js +721 -721
- package/public/js/ws-client.js +74 -74
- package/public/llms-full.txt +360 -360
- package/public/llms.txt +125 -125
- package/public/login.html +85 -85
- package/public/mesh-dashboard.html +328 -328
- package/public/openapi.json +669 -580
- package/public/phone-shield.html +281 -0
- package/public/plesk-integration.html +375 -0
- package/public/premium-dashboard.html +2489 -2489
- package/public/premium.html +793 -793
- package/public/privacy.html +297 -297
- package/public/provider-onboarding.html +172 -0
- package/public/provider-sandbox.html +134 -0
- package/public/providers.html +359 -0
- package/public/register.html +105 -105
- package/public/registrar-integrations.html +141 -0
- package/public/robots.txt +99 -87
- package/public/route53-integration.html +531 -0
- package/public/script/wab-consent.d.ts +36 -36
- package/public/script/wab-consent.js +104 -104
- package/public/script/wab-schema.js +131 -131
- package/public/script/wab.d.ts +108 -108
- package/public/script/wab.min.js +580 -580
- package/public/security.txt +8 -0
- package/public/shieldqr.html +231 -0
- package/public/sitemap.xml +6 -0
- package/public/terms.html +256 -256
- package/public/wab-trust.html +200 -0
- package/public/wab-vs-protocols.html +210 -0
- package/public/whitepaper.html +449 -0
- package/script/ai-agent-bridge.js +1754 -1754
- package/sdk/README.md +99 -99
- package/sdk/agent-mesh.js +449 -449
- package/sdk/auto-discovery.js +288 -0
- package/sdk/commander.js +262 -262
- package/sdk/governance.js +262 -0
- package/sdk/index.d.ts +464 -464
- package/sdk/index.js +25 -1
- package/sdk/multi-agent.js +318 -318
- package/sdk/package.json +2 -2
- package/sdk/safe-mode.js +221 -0
- package/sdk/safety-shield.js +219 -0
- package/sdk/schema-discovery.js +83 -83
- package/server/adapters/index.js +520 -520
- package/server/config/plans.js +367 -367
- package/server/config/secrets.js +102 -102
- package/server/control-plane/index.js +301 -301
- package/server/data-plane/index.js +354 -354
- package/server/index.js +670 -427
- package/server/llm/index.js +404 -404
- package/server/middleware/adminAuth.js +35 -35
- package/server/middleware/auth.js +50 -50
- package/server/middleware/featureGate.js +88 -88
- package/server/middleware/rateLimits.js +100 -100
- package/server/middleware/sensitiveAction.js +157 -0
- package/server/migrations/001_add_analytics_indexes.sql +7 -7
- package/server/migrations/002_premium_features.sql +418 -418
- package/server/migrations/003_ads_integer_cents.sql +33 -33
- package/server/migrations/004_agent_os.sql +158 -158
- package/server/migrations/005_marketplace_metering.sql +126 -126
- package/server/migrations/007_governance.sql +106 -0
- package/server/migrations/008_plans.sql +144 -0
- package/server/migrations/009_shieldqr.sql +30 -0
- package/server/migrations/010_extended_trust.sql +33 -0
- package/server/models/adapters/index.js +33 -33
- package/server/models/adapters/mysql.js +183 -183
- package/server/models/adapters/postgresql.js +172 -172
- package/server/models/adapters/sqlite.js +7 -7
- package/server/models/db.js +740 -681
- package/server/observability/failure-analysis.js +337 -337
- package/server/observability/index.js +394 -394
- package/server/protocol/capabilities.js +223 -223
- package/server/protocol/index.js +243 -243
- package/server/protocol/schema.js +584 -584
- package/server/registry/certification.js +271 -271
- package/server/registry/index.js +326 -326
- package/server/routes/admin-plans.js +76 -0
- package/server/routes/admin-premium.js +673 -671
- package/server/routes/admin-shieldqr.js +90 -0
- package/server/routes/admin-trust-monitor.js +83 -0
- package/server/routes/admin.js +549 -261
- package/server/routes/ads.js +130 -130
- package/server/routes/agent-workspace.js +540 -540
- package/server/routes/api.js +150 -150
- package/server/routes/auth.js +71 -71
- package/server/routes/billing.js +57 -45
- package/server/routes/commander.js +316 -316
- package/server/routes/demo-showcase.js +332 -332
- package/server/routes/demo-store.js +154 -0
- package/server/routes/discovery.js +2348 -417
- package/server/routes/gateway.js +173 -157
- package/server/routes/governance.js +208 -0
- package/server/routes/license.js +251 -240
- package/server/routes/mesh.js +469 -469
- package/server/routes/noscript.js +543 -543
- package/server/routes/plans.js +33 -0
- package/server/routes/premium-v2.js +686 -686
- package/server/routes/premium.js +724 -724
- package/server/routes/providers.js +650 -0
- package/server/routes/runtime.js +2148 -2147
- package/server/routes/shieldqr.js +88 -0
- package/server/routes/sovereign.js +465 -385
- package/server/routes/universal.js +200 -185
- package/server/routes/wab-api.js +850 -501
- package/server/runtime/container-worker.js +111 -111
- package/server/runtime/container.js +448 -448
- package/server/runtime/distributed-worker.js +362 -362
- package/server/runtime/event-bus.js +210 -210
- package/server/runtime/index.js +253 -253
- package/server/runtime/queue.js +599 -599
- package/server/runtime/replay.js +666 -666
- package/server/runtime/sandbox.js +266 -266
- package/server/runtime/scheduler.js +534 -534
- package/server/runtime/session-engine.js +293 -293
- package/server/runtime/state-manager.js +188 -188
- package/server/security/cross-site-redactor.js +196 -0
- package/server/security/dry-run.js +180 -0
- package/server/security/human-gate-rate-limit.js +147 -0
- package/server/security/human-gate-transports.js +178 -0
- package/server/security/human-gate.js +281 -0
- package/server/security/index.js +368 -368
- package/server/security/intent-engine.js +245 -0
- package/server/security/reward-guard.js +171 -0
- package/server/security/rollback-store.js +239 -0
- package/server/security/token-scope.js +404 -0
- package/server/security/url-policy.js +139 -0
- package/server/services/agent-chat.js +506 -506
- package/server/services/agent-learning.js +601 -575
- package/server/services/agent-memory.js +625 -625
- package/server/services/agent-mesh.js +555 -539
- package/server/services/agent-symphony.js +717 -717
- package/server/services/agent-tasks.js +1807 -1807
- package/server/services/api-key-engine.js +292 -261
- package/server/services/cluster.js +894 -894
- package/server/services/commander.js +738 -738
- package/server/services/edge-compute.js +440 -440
- package/server/services/email.js +233 -204
- package/server/services/governance.js +466 -0
- package/server/services/hosted-runtime.js +205 -205
- package/server/services/lfd.js +635 -635
- package/server/services/local-ai.js +389 -389
- package/server/services/marketplace.js +270 -270
- package/server/services/metering.js +182 -182
- package/server/services/modules/affiliate-intelligence.js +93 -93
- package/server/services/modules/agent-firewall.js +90 -90
- package/server/services/modules/bounty.js +89 -89
- package/server/services/modules/collective-bargaining.js +92 -92
- package/server/services/modules/dark-pattern.js +66 -66
- package/server/services/modules/gov-intelligence.js +45 -45
- package/server/services/modules/neural.js +55 -55
- package/server/services/modules/notary.js +49 -49
- package/server/services/modules/price-time-machine.js +86 -86
- package/server/services/modules/protocol.js +104 -104
- package/server/services/negotiation.js +439 -439
- package/server/services/plans.js +214 -0
- package/server/services/plugins.js +771 -771
- package/server/services/premium.js +1 -1
- package/server/services/price-intelligence.js +566 -566
- package/server/services/price-shield.js +1137 -1137
- package/server/services/provider-clients.js +740 -0
- package/server/services/reputation.js +465 -465
- package/server/services/search-engine.js +357 -357
- package/server/services/security.js +513 -513
- package/server/services/self-healing.js +843 -843
- package/server/services/shieldqr.js +322 -0
- package/server/services/sovereign-shield.js +542 -0
- package/server/services/ssl-inspector.js +42 -0
- package/server/services/ssl-monitor.js +167 -0
- package/server/services/stripe.js +205 -192
- package/server/services/swarm.js +788 -788
- package/server/services/universal-scraper.js +662 -661
- package/server/services/verification.js +481 -481
- package/server/services/vision.js +1163 -1163
- package/server/services/wab-crypto.js +178 -0
- package/server/utils/cache.js +125 -125
- package/server/utils/migrate.js +81 -81
- package/server/utils/safe-fetch.js +228 -0
- package/server/utils/secureFields.js +50 -50
- package/server/ws.js +161 -161
- package/templates/artisan-marketplace.yaml +104 -104
- package/templates/book-price-scout.yaml +98 -98
- package/templates/electronics-price-tracker.yaml +108 -108
- package/templates/flight-deal-hunter.yaml +113 -113
- package/templates/freelancer-direct.yaml +116 -116
- package/templates/grocery-price-compare.yaml +93 -93
- package/templates/hotel-direct-booking.yaml +113 -113
- package/templates/local-services.yaml +98 -98
- package/templates/olive-oil-tunisia.yaml +88 -88
- package/templates/organic-farm-fresh.yaml +101 -101
- package/templates/restaurant-direct.yaml +97 -97
- package/public/score.html +0 -263
- package/server/migrations/006_growth_suite.sql +0 -138
- package/server/routes/growth.js +0 -962
- package/server/services/fairness-engine.js +0 -409
- package/server/services/fairness.js +0 -420
|
@@ -1,223 +1,223 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* WAB Protocol (WABP) - Capabilities Negotiation
|
|
5
|
-
*
|
|
6
|
-
* Dynamic capability negotiation between agents and sites.
|
|
7
|
-
* Agents request capabilities β sites grant/deny based on policies.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const crypto = require('crypto');
|
|
11
|
-
|
|
12
|
-
// βββ Capability Grant βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
13
|
-
|
|
14
|
-
class CapabilityGrant {
|
|
15
|
-
constructor(agentId, capabilities, constraints = {}) {
|
|
16
|
-
this.id = `grant_${crypto.randomBytes(16).toString('hex')}`;
|
|
17
|
-
this.agentId = agentId;
|
|
18
|
-
this.capabilities = new Set(capabilities);
|
|
19
|
-
this.constraints = {
|
|
20
|
-
maxCalls: constraints.maxCalls || Infinity,
|
|
21
|
-
expiresAt: constraints.expiresAt || (Date.now() + 3600_000),
|
|
22
|
-
allowedDomains: constraints.allowedDomains || ['*'],
|
|
23
|
-
rateLimit: constraints.rateLimit || { maxPerMinute: 60 },
|
|
24
|
-
ipRestriction: constraints.ipRestriction || null,
|
|
25
|
-
};
|
|
26
|
-
this.usage = { calls: 0, lastUsed: 0 };
|
|
27
|
-
this.revoked = false;
|
|
28
|
-
this.createdAt = Date.now();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
has(capability) {
|
|
32
|
-
if (this.revoked) return false;
|
|
33
|
-
if (Date.now() > this.constraints.expiresAt) return false;
|
|
34
|
-
if (this.usage.calls >= this.constraints.maxCalls) return false;
|
|
35
|
-
return this.capabilities.has(capability);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
use(capability) {
|
|
39
|
-
if (!this.has(capability)) return false;
|
|
40
|
-
this.usage.calls++;
|
|
41
|
-
this.usage.lastUsed = Date.now();
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
revoke() {
|
|
46
|
-
this.revoked = true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
toJSON() {
|
|
50
|
-
return {
|
|
51
|
-
id: this.id,
|
|
52
|
-
agentId: this.agentId,
|
|
53
|
-
capabilities: [...this.capabilities],
|
|
54
|
-
constraints: this.constraints,
|
|
55
|
-
usage: this.usage,
|
|
56
|
-
revoked: this.revoked,
|
|
57
|
-
createdAt: this.createdAt,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// βββ Capability Negotiator ββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
63
|
-
|
|
64
|
-
class CapabilityNegotiator {
|
|
65
|
-
constructor() {
|
|
66
|
-
this._grants = new Map(); // grantId β CapabilityGrant
|
|
67
|
-
this._agentGrants = new Map(); // agentId β Set<grantId>
|
|
68
|
-
this._policies = new Map(); // siteId β policy object
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Set site-level capability policy
|
|
73
|
-
*/
|
|
74
|
-
setPolicy(siteId, policy) {
|
|
75
|
-
this._policies.set(siteId, {
|
|
76
|
-
allowedCapabilities: new Set(policy.allowedCapabilities || []),
|
|
77
|
-
deniedCapabilities: new Set(policy.deniedCapabilities || []),
|
|
78
|
-
requireApproval: new Set(policy.requireApproval || []),
|
|
79
|
-
maxGrantDuration: policy.maxGrantDuration || 3600_000,
|
|
80
|
-
defaultRateLimit: policy.defaultRateLimit || { maxPerMinute: 60 },
|
|
81
|
-
autoGrant: policy.autoGrant !== false,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Negotiate capabilities for an agent
|
|
87
|
-
* Returns: { granted: string[], denied: string[], pending: string[], grant: CapabilityGrant }
|
|
88
|
-
*/
|
|
89
|
-
negotiate(agentId, requestedCapabilities, siteId, constraints = {}) {
|
|
90
|
-
const policy = this._policies.get(siteId);
|
|
91
|
-
const granted = [];
|
|
92
|
-
const denied = [];
|
|
93
|
-
const pending = [];
|
|
94
|
-
|
|
95
|
-
for (const cap of requestedCapabilities) {
|
|
96
|
-
if (policy) {
|
|
97
|
-
if (policy.deniedCapabilities.has(cap)) {
|
|
98
|
-
denied.push(cap);
|
|
99
|
-
} else if (policy.requireApproval.has(cap)) {
|
|
100
|
-
pending.push(cap);
|
|
101
|
-
} else if (policy.allowedCapabilities.has(cap) || policy.allowedCapabilities.has('*')) {
|
|
102
|
-
granted.push(cap);
|
|
103
|
-
} else if (policy.autoGrant) {
|
|
104
|
-
granted.push(cap);
|
|
105
|
-
} else {
|
|
106
|
-
denied.push(cap);
|
|
107
|
-
}
|
|
108
|
-
} else {
|
|
109
|
-
// No policy = grant low-risk capabilities only
|
|
110
|
-
const riskLevel = _getCapabilityRisk(cap);
|
|
111
|
-
if (riskLevel === 'low') granted.push(cap);
|
|
112
|
-
else if (riskLevel === 'medium') pending.push(cap);
|
|
113
|
-
else denied.push(cap);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
let grant = null;
|
|
118
|
-
if (granted.length > 0) {
|
|
119
|
-
const maxDuration = policy ? policy.maxGrantDuration : 3600_000;
|
|
120
|
-
grant = new CapabilityGrant(agentId, granted, {
|
|
121
|
-
...constraints,
|
|
122
|
-
expiresAt: Date.now() + Math.min(constraints.duration || maxDuration, maxDuration),
|
|
123
|
-
rateLimit: policy ? policy.defaultRateLimit : constraints.rateLimit,
|
|
124
|
-
});
|
|
125
|
-
this._grants.set(grant.id, grant);
|
|
126
|
-
if (!this._agentGrants.has(agentId)) this._agentGrants.set(agentId, new Set());
|
|
127
|
-
this._agentGrants.get(agentId).add(grant.id);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return { granted, denied, pending, grant };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Check if agent has capability via any active grant
|
|
135
|
-
*/
|
|
136
|
-
check(agentId, capability) {
|
|
137
|
-
const grantIds = this._agentGrants.get(agentId);
|
|
138
|
-
if (!grantIds) return false;
|
|
139
|
-
for (const gid of grantIds) {
|
|
140
|
-
const grant = this._grants.get(gid);
|
|
141
|
-
if (grant && grant.has(capability)) return true;
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Use a capability (decrements usage counter)
|
|
148
|
-
*/
|
|
149
|
-
use(agentId, capability) {
|
|
150
|
-
const grantIds = this._agentGrants.get(agentId);
|
|
151
|
-
if (!grantIds) return false;
|
|
152
|
-
for (const gid of grantIds) {
|
|
153
|
-
const grant = this._grants.get(gid);
|
|
154
|
-
if (grant && grant.use(capability)) return true;
|
|
155
|
-
}
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Revoke all grants for an agent
|
|
161
|
-
*/
|
|
162
|
-
revokeAgent(agentId) {
|
|
163
|
-
const grantIds = this._agentGrants.get(agentId);
|
|
164
|
-
if (!grantIds) return;
|
|
165
|
-
for (const gid of grantIds) {
|
|
166
|
-
const grant = this._grants.get(gid);
|
|
167
|
-
if (grant) grant.revoke();
|
|
168
|
-
}
|
|
169
|
-
this._agentGrants.delete(agentId);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Get all active grants for an agent
|
|
174
|
-
*/
|
|
175
|
-
getGrants(agentId) {
|
|
176
|
-
const grantIds = this._agentGrants.get(agentId);
|
|
177
|
-
if (!grantIds) return [];
|
|
178
|
-
const grants = [];
|
|
179
|
-
for (const gid of grantIds) {
|
|
180
|
-
const grant = this._grants.get(gid);
|
|
181
|
-
if (grant && !grant.revoked && Date.now() <= grant.constraints.expiresAt) {
|
|
182
|
-
grants.push(grant.toJSON());
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return grants;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Cleanup expired grants
|
|
190
|
-
*/
|
|
191
|
-
cleanup() {
|
|
192
|
-
const now = Date.now();
|
|
193
|
-
for (const [gid, grant] of this._grants) {
|
|
194
|
-
if (grant.revoked || now > grant.constraints.expiresAt) {
|
|
195
|
-
this._grants.delete(gid);
|
|
196
|
-
const agentGrants = this._agentGrants.get(grant.agentId);
|
|
197
|
-
if (agentGrants) {
|
|
198
|
-
agentGrants.delete(gid);
|
|
199
|
-
if (agentGrants.size === 0) this._agentGrants.delete(grant.agentId);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// βββ Risk Assessment ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
207
|
-
|
|
208
|
-
const _riskMap = {
|
|
209
|
-
'browser.read': 'low', 'browser.scroll': 'low', 'browser.screenshot': 'low',
|
|
210
|
-
'browser.click': 'medium', 'browser.fill': 'medium', 'browser.navigate': 'medium',
|
|
211
|
-
'browser.execute': 'high',
|
|
212
|
-
'data.extract': 'low', 'data.compare': 'low', 'data.store': 'medium',
|
|
213
|
-
'agent.communicate': 'medium', 'agent.spawn': 'high', 'agent.delegate': 'high',
|
|
214
|
-
'system.api': 'high', 'system.webhook': 'high', 'system.schedule': 'medium',
|
|
215
|
-
'commerce.price': 'low', 'commerce.negotiate': 'high', 'commerce.purchase': 'critical',
|
|
216
|
-
'ai.infer': 'medium', 'ai.vision': 'low', 'ai.embed': 'low',
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
function _getCapabilityRisk(capability) {
|
|
220
|
-
return _riskMap[capability] || 'high';
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
module.exports = { CapabilityGrant, CapabilityNegotiator };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WAB Protocol (WABP) - Capabilities Negotiation
|
|
5
|
+
*
|
|
6
|
+
* Dynamic capability negotiation between agents and sites.
|
|
7
|
+
* Agents request capabilities β sites grant/deny based on policies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const crypto = require('crypto');
|
|
11
|
+
|
|
12
|
+
// βββ Capability Grant βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
13
|
+
|
|
14
|
+
class CapabilityGrant {
|
|
15
|
+
constructor(agentId, capabilities, constraints = {}) {
|
|
16
|
+
this.id = `grant_${crypto.randomBytes(16).toString('hex')}`;
|
|
17
|
+
this.agentId = agentId;
|
|
18
|
+
this.capabilities = new Set(capabilities);
|
|
19
|
+
this.constraints = {
|
|
20
|
+
maxCalls: constraints.maxCalls || Infinity,
|
|
21
|
+
expiresAt: constraints.expiresAt || (Date.now() + 3600_000),
|
|
22
|
+
allowedDomains: constraints.allowedDomains || ['*'],
|
|
23
|
+
rateLimit: constraints.rateLimit || { maxPerMinute: 60 },
|
|
24
|
+
ipRestriction: constraints.ipRestriction || null,
|
|
25
|
+
};
|
|
26
|
+
this.usage = { calls: 0, lastUsed: 0 };
|
|
27
|
+
this.revoked = false;
|
|
28
|
+
this.createdAt = Date.now();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
has(capability) {
|
|
32
|
+
if (this.revoked) return false;
|
|
33
|
+
if (Date.now() > this.constraints.expiresAt) return false;
|
|
34
|
+
if (this.usage.calls >= this.constraints.maxCalls) return false;
|
|
35
|
+
return this.capabilities.has(capability);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
use(capability) {
|
|
39
|
+
if (!this.has(capability)) return false;
|
|
40
|
+
this.usage.calls++;
|
|
41
|
+
this.usage.lastUsed = Date.now();
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
revoke() {
|
|
46
|
+
this.revoked = true;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
toJSON() {
|
|
50
|
+
return {
|
|
51
|
+
id: this.id,
|
|
52
|
+
agentId: this.agentId,
|
|
53
|
+
capabilities: [...this.capabilities],
|
|
54
|
+
constraints: this.constraints,
|
|
55
|
+
usage: this.usage,
|
|
56
|
+
revoked: this.revoked,
|
|
57
|
+
createdAt: this.createdAt,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// βββ Capability Negotiator ββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
63
|
+
|
|
64
|
+
class CapabilityNegotiator {
|
|
65
|
+
constructor() {
|
|
66
|
+
this._grants = new Map(); // grantId β CapabilityGrant
|
|
67
|
+
this._agentGrants = new Map(); // agentId β Set<grantId>
|
|
68
|
+
this._policies = new Map(); // siteId β policy object
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Set site-level capability policy
|
|
73
|
+
*/
|
|
74
|
+
setPolicy(siteId, policy) {
|
|
75
|
+
this._policies.set(siteId, {
|
|
76
|
+
allowedCapabilities: new Set(policy.allowedCapabilities || []),
|
|
77
|
+
deniedCapabilities: new Set(policy.deniedCapabilities || []),
|
|
78
|
+
requireApproval: new Set(policy.requireApproval || []),
|
|
79
|
+
maxGrantDuration: policy.maxGrantDuration || 3600_000,
|
|
80
|
+
defaultRateLimit: policy.defaultRateLimit || { maxPerMinute: 60 },
|
|
81
|
+
autoGrant: policy.autoGrant !== false,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Negotiate capabilities for an agent
|
|
87
|
+
* Returns: { granted: string[], denied: string[], pending: string[], grant: CapabilityGrant }
|
|
88
|
+
*/
|
|
89
|
+
negotiate(agentId, requestedCapabilities, siteId, constraints = {}) {
|
|
90
|
+
const policy = this._policies.get(siteId);
|
|
91
|
+
const granted = [];
|
|
92
|
+
const denied = [];
|
|
93
|
+
const pending = [];
|
|
94
|
+
|
|
95
|
+
for (const cap of requestedCapabilities) {
|
|
96
|
+
if (policy) {
|
|
97
|
+
if (policy.deniedCapabilities.has(cap)) {
|
|
98
|
+
denied.push(cap);
|
|
99
|
+
} else if (policy.requireApproval.has(cap)) {
|
|
100
|
+
pending.push(cap);
|
|
101
|
+
} else if (policy.allowedCapabilities.has(cap) || policy.allowedCapabilities.has('*')) {
|
|
102
|
+
granted.push(cap);
|
|
103
|
+
} else if (policy.autoGrant) {
|
|
104
|
+
granted.push(cap);
|
|
105
|
+
} else {
|
|
106
|
+
denied.push(cap);
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
// No policy = grant low-risk capabilities only
|
|
110
|
+
const riskLevel = _getCapabilityRisk(cap);
|
|
111
|
+
if (riskLevel === 'low') granted.push(cap);
|
|
112
|
+
else if (riskLevel === 'medium') pending.push(cap);
|
|
113
|
+
else denied.push(cap);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let grant = null;
|
|
118
|
+
if (granted.length > 0) {
|
|
119
|
+
const maxDuration = policy ? policy.maxGrantDuration : 3600_000;
|
|
120
|
+
grant = new CapabilityGrant(agentId, granted, {
|
|
121
|
+
...constraints,
|
|
122
|
+
expiresAt: Date.now() + Math.min(constraints.duration || maxDuration, maxDuration),
|
|
123
|
+
rateLimit: policy ? policy.defaultRateLimit : constraints.rateLimit,
|
|
124
|
+
});
|
|
125
|
+
this._grants.set(grant.id, grant);
|
|
126
|
+
if (!this._agentGrants.has(agentId)) this._agentGrants.set(agentId, new Set());
|
|
127
|
+
this._agentGrants.get(agentId).add(grant.id);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return { granted, denied, pending, grant };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Check if agent has capability via any active grant
|
|
135
|
+
*/
|
|
136
|
+
check(agentId, capability) {
|
|
137
|
+
const grantIds = this._agentGrants.get(agentId);
|
|
138
|
+
if (!grantIds) return false;
|
|
139
|
+
for (const gid of grantIds) {
|
|
140
|
+
const grant = this._grants.get(gid);
|
|
141
|
+
if (grant && grant.has(capability)) return true;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Use a capability (decrements usage counter)
|
|
148
|
+
*/
|
|
149
|
+
use(agentId, capability) {
|
|
150
|
+
const grantIds = this._agentGrants.get(agentId);
|
|
151
|
+
if (!grantIds) return false;
|
|
152
|
+
for (const gid of grantIds) {
|
|
153
|
+
const grant = this._grants.get(gid);
|
|
154
|
+
if (grant && grant.use(capability)) return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Revoke all grants for an agent
|
|
161
|
+
*/
|
|
162
|
+
revokeAgent(agentId) {
|
|
163
|
+
const grantIds = this._agentGrants.get(agentId);
|
|
164
|
+
if (!grantIds) return;
|
|
165
|
+
for (const gid of grantIds) {
|
|
166
|
+
const grant = this._grants.get(gid);
|
|
167
|
+
if (grant) grant.revoke();
|
|
168
|
+
}
|
|
169
|
+
this._agentGrants.delete(agentId);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get all active grants for an agent
|
|
174
|
+
*/
|
|
175
|
+
getGrants(agentId) {
|
|
176
|
+
const grantIds = this._agentGrants.get(agentId);
|
|
177
|
+
if (!grantIds) return [];
|
|
178
|
+
const grants = [];
|
|
179
|
+
for (const gid of grantIds) {
|
|
180
|
+
const grant = this._grants.get(gid);
|
|
181
|
+
if (grant && !grant.revoked && Date.now() <= grant.constraints.expiresAt) {
|
|
182
|
+
grants.push(grant.toJSON());
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return grants;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Cleanup expired grants
|
|
190
|
+
*/
|
|
191
|
+
cleanup() {
|
|
192
|
+
const now = Date.now();
|
|
193
|
+
for (const [gid, grant] of this._grants) {
|
|
194
|
+
if (grant.revoked || now > grant.constraints.expiresAt) {
|
|
195
|
+
this._grants.delete(gid);
|
|
196
|
+
const agentGrants = this._agentGrants.get(grant.agentId);
|
|
197
|
+
if (agentGrants) {
|
|
198
|
+
agentGrants.delete(gid);
|
|
199
|
+
if (agentGrants.size === 0) this._agentGrants.delete(grant.agentId);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// βββ Risk Assessment ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
207
|
+
|
|
208
|
+
const _riskMap = {
|
|
209
|
+
'browser.read': 'low', 'browser.scroll': 'low', 'browser.screenshot': 'low',
|
|
210
|
+
'browser.click': 'medium', 'browser.fill': 'medium', 'browser.navigate': 'medium',
|
|
211
|
+
'browser.execute': 'high',
|
|
212
|
+
'data.extract': 'low', 'data.compare': 'low', 'data.store': 'medium',
|
|
213
|
+
'agent.communicate': 'medium', 'agent.spawn': 'high', 'agent.delegate': 'high',
|
|
214
|
+
'system.api': 'high', 'system.webhook': 'high', 'system.schedule': 'medium',
|
|
215
|
+
'commerce.price': 'low', 'commerce.negotiate': 'high', 'commerce.purchase': 'critical',
|
|
216
|
+
'ai.infer': 'medium', 'ai.vision': 'low', 'ai.embed': 'low',
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
function _getCapabilityRisk(capability) {
|
|
220
|
+
return _riskMap[capability] || 'high';
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = { CapabilityGrant, CapabilityNegotiator };
|