@agentlensai/server 0.7.0 → 0.9.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/dist/db/anonymous-id-manager.d.ts +44 -0
- package/dist/db/anonymous-id-manager.d.ts.map +1 -0
- package/dist/db/anonymous-id-manager.js +90 -0
- package/dist/db/anonymous-id-manager.js.map +1 -0
- package/dist/db/capability-store.d.ts +78 -0
- package/dist/db/capability-store.d.ts.map +1 -0
- package/dist/db/capability-store.js +201 -0
- package/dist/db/capability-store.js.map +1 -0
- package/dist/db/guardrail-store.d.ts +34 -0
- package/dist/db/guardrail-store.d.ts.map +1 -0
- package/dist/db/guardrail-store.js +221 -0
- package/dist/db/guardrail-store.js.map +1 -0
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +200 -0
- package/dist/db/migrate.js.map +1 -1
- package/dist/db/schema.sqlite.d.ts +1719 -1
- package/dist/db/schema.sqlite.d.ts.map +1 -1
- package/dist/db/schema.sqlite.js +141 -1
- package/dist/db/schema.sqlite.js.map +1 -1
- package/dist/db/sqlite-store.d.ts +12 -0
- package/dist/db/sqlite-store.d.ts.map +1 -1
- package/dist/db/sqlite-store.js +47 -0
- package/dist/db/sqlite-store.js.map +1 -1
- package/dist/db/tenant-scoped-store.d.ts +1 -0
- package/dist/db/tenant-scoped-store.d.ts.map +1 -1
- package/dist/db/tenant-scoped-store.js +3 -0
- package/dist/db/tenant-scoped-store.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/guardrails/actions.d.ts +28 -0
- package/dist/lib/guardrails/actions.d.ts.map +1 -0
- package/dist/lib/guardrails/actions.js +126 -0
- package/dist/lib/guardrails/actions.js.map +1 -0
- package/dist/lib/guardrails/conditions.d.ts +13 -0
- package/dist/lib/guardrails/conditions.d.ts.map +1 -0
- package/dist/lib/guardrails/conditions.js +188 -0
- package/dist/lib/guardrails/conditions.js.map +1 -0
- package/dist/lib/guardrails/engine.d.ts +24 -0
- package/dist/lib/guardrails/engine.d.ts.map +1 -0
- package/dist/lib/guardrails/engine.js +122 -0
- package/dist/lib/guardrails/engine.js.map +1 -0
- package/dist/lib/redaction/human-review-layer.d.ts +37 -0
- package/dist/lib/redaction/human-review-layer.d.ts.map +1 -0
- package/dist/lib/redaction/human-review-layer.js +62 -0
- package/dist/lib/redaction/human-review-layer.js.map +1 -0
- package/dist/lib/redaction/index.d.ts +12 -0
- package/dist/lib/redaction/index.d.ts.map +1 -0
- package/dist/lib/redaction/index.js +12 -0
- package/dist/lib/redaction/index.js.map +1 -0
- package/dist/lib/redaction/pii-detection-layer.d.ts +30 -0
- package/dist/lib/redaction/pii-detection-layer.d.ts.map +1 -0
- package/dist/lib/redaction/pii-detection-layer.js +183 -0
- package/dist/lib/redaction/pii-detection-layer.js.map +1 -0
- package/dist/lib/redaction/pipeline.d.ts +26 -0
- package/dist/lib/redaction/pipeline.d.ts.map +1 -0
- package/dist/lib/redaction/pipeline.js +91 -0
- package/dist/lib/redaction/pipeline.js.map +1 -0
- package/dist/lib/redaction/secret-detection-layer.d.ts +10 -0
- package/dist/lib/redaction/secret-detection-layer.d.ts.map +1 -0
- package/dist/lib/redaction/secret-detection-layer.js +79 -0
- package/dist/lib/redaction/secret-detection-layer.js.map +1 -0
- package/dist/lib/redaction/secret-patterns.d.ts +29 -0
- package/dist/lib/redaction/secret-patterns.d.ts.map +1 -0
- package/dist/lib/redaction/secret-patterns.js +133 -0
- package/dist/lib/redaction/secret-patterns.js.map +1 -0
- package/dist/lib/redaction/semantic-denylist-layer.d.ts +10 -0
- package/dist/lib/redaction/semantic-denylist-layer.d.ts.map +1 -0
- package/dist/lib/redaction/semantic-denylist-layer.js +64 -0
- package/dist/lib/redaction/semantic-denylist-layer.js.map +1 -0
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts +10 -0
- package/dist/lib/redaction/tenant-deidentification-layer.d.ts.map +1 -0
- package/dist/lib/redaction/tenant-deidentification-layer.js +64 -0
- package/dist/lib/redaction/tenant-deidentification-layer.js.map +1 -0
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts +14 -0
- package/dist/lib/redaction/url-path-scrubbing-layer.d.ts.map +1 -0
- package/dist/lib/redaction/url-path-scrubbing-layer.js +156 -0
- package/dist/lib/redaction/url-path-scrubbing-layer.js.map +1 -0
- package/dist/routes/agents.d.ts +4 -3
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +31 -12
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/audit.d.ts +15 -0
- package/dist/routes/audit.d.ts.map +1 -0
- package/dist/routes/audit.js +177 -0
- package/dist/routes/audit.js.map +1 -0
- package/dist/routes/capabilities.d.ts +15 -0
- package/dist/routes/capabilities.d.ts.map +1 -0
- package/dist/routes/capabilities.js +86 -0
- package/dist/routes/capabilities.js.map +1 -0
- package/dist/routes/community.d.ts +24 -0
- package/dist/routes/community.d.ts.map +1 -0
- package/dist/routes/community.js +190 -0
- package/dist/routes/community.js.map +1 -0
- package/dist/routes/delegation.d.ts +20 -0
- package/dist/routes/delegation.d.ts.map +1 -0
- package/dist/routes/delegation.js +108 -0
- package/dist/routes/delegation.js.map +1 -0
- package/dist/routes/discovery.d.ts +19 -0
- package/dist/routes/discovery.d.ts.map +1 -0
- package/dist/routes/discovery.js +96 -0
- package/dist/routes/discovery.js.map +1 -0
- package/dist/routes/guardrails.d.ts +18 -0
- package/dist/routes/guardrails.d.ts.map +1 -0
- package/dist/routes/guardrails.js +184 -0
- package/dist/routes/guardrails.js.map +1 -0
- package/dist/routes/redaction-test.d.ts +14 -0
- package/dist/routes/redaction-test.d.ts.map +1 -0
- package/dist/routes/redaction-test.js +33 -0
- package/dist/routes/redaction-test.js.map +1 -0
- package/dist/routes/trust.d.ts +16 -0
- package/dist/routes/trust.d.ts.map +1 -0
- package/dist/routes/trust.js +23 -0
- package/dist/routes/trust.js.map +1 -0
- package/dist/services/community-service.d.ts +277 -0
- package/dist/services/community-service.d.ts.map +1 -0
- package/dist/services/community-service.js +785 -0
- package/dist/services/community-service.js.map +1 -0
- package/dist/services/delegation-service.d.ts +149 -0
- package/dist/services/delegation-service.d.ts.map +1 -0
- package/dist/services/delegation-service.js +605 -0
- package/dist/services/delegation-service.js.map +1 -0
- package/dist/services/discovery-service.d.ts +39 -0
- package/dist/services/discovery-service.d.ts.map +1 -0
- package/dist/services/discovery-service.js +186 -0
- package/dist/services/discovery-service.js.map +1 -0
- package/dist/services/trust-service.d.ts +59 -0
- package/dist/services/trust-service.d.ts.map +1 -0
- package/dist/services/trust-service.js +139 -0
- package/dist/services/trust-service.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery Service (Story 5.3 — Discovery Protocol + Story 5.4 — Permission Model)
|
|
3
|
+
*
|
|
4
|
+
* Handles capability discovery with composite ranking and permission enforcement.
|
|
5
|
+
*/
|
|
6
|
+
import type { SqliteDb } from '../db/index.js';
|
|
7
|
+
import type { DiscoveryQuery, DiscoveryResult } from '@agentlensai/core';
|
|
8
|
+
export declare class RateLimiter {
|
|
9
|
+
private buckets;
|
|
10
|
+
check(key: string, limit: number): boolean;
|
|
11
|
+
/** Reset for testing */
|
|
12
|
+
reset(): void;
|
|
13
|
+
}
|
|
14
|
+
export interface DiscoveryConfigData {
|
|
15
|
+
tenantId: string;
|
|
16
|
+
minTrustThreshold: number;
|
|
17
|
+
delegationEnabled: boolean;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
}
|
|
20
|
+
export interface AgentPermissionUpdate {
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
acceptDelegations?: boolean;
|
|
23
|
+
inboundRateLimit?: number;
|
|
24
|
+
outboundRateLimit?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare class DiscoveryService {
|
|
27
|
+
private readonly db;
|
|
28
|
+
private readonly anonIdManager;
|
|
29
|
+
readonly inboundLimiter: RateLimiter;
|
|
30
|
+
readonly outboundLimiter: RateLimiter;
|
|
31
|
+
constructor(db: SqliteDb);
|
|
32
|
+
getDiscoveryConfig(tenantId: string): DiscoveryConfigData;
|
|
33
|
+
updateDiscoveryConfig(tenantId: string, updates: Partial<Pick<DiscoveryConfigData, 'minTrustThreshold' | 'delegationEnabled'>>): DiscoveryConfigData;
|
|
34
|
+
updateAgentPermissions(tenantId: string, capabilityId: string, updates: AgentPermissionUpdate): boolean;
|
|
35
|
+
checkInboundRateLimit(agentId: string, limit: number): boolean;
|
|
36
|
+
checkOutboundRateLimit(agentId: string, limit: number): boolean;
|
|
37
|
+
discover(tenantId: string, query: DiscoveryQuery): DiscoveryResult[];
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=discovery-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery-service.d.ts","sourceRoot":"","sources":["../../src/services/discovery-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAY,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAanF,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAiC;IAEhD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAc1C,wBAAwB;IACxB,KAAK,IAAI,IAAI;CAGd;AAID,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,qBAAa,gBAAgB;IAKf,OAAO,CAAC,QAAQ,CAAC,EAAE;IAJ/B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,QAAQ,CAAC,cAAc,cAAqB;IAC5C,QAAQ,CAAC,eAAe,cAAqB;gBAEhB,EAAE,EAAE,QAAQ;IAMzC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB;IAyBzD,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,mBAAmB,CAAC,CAAC,GAAG,mBAAmB;IA2BpJ,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO;IAkBvG,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI9D,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAM/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,eAAe,EAAE;CA4FrE"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discovery Service (Story 5.3 — Discovery Protocol + Story 5.4 — Permission Model)
|
|
3
|
+
*
|
|
4
|
+
* Handles capability discovery with composite ranking and permission enforcement.
|
|
5
|
+
*/
|
|
6
|
+
import { eq, and } from 'drizzle-orm';
|
|
7
|
+
import { capabilityRegistry, discoveryConfig } from '../db/schema.sqlite.js';
|
|
8
|
+
import { TASK_TYPES } from '@agentlensai/core';
|
|
9
|
+
import { AnonymousIdManager } from '../db/anonymous-id-manager.js';
|
|
10
|
+
const RATE_WINDOW_MS = 60_000; // 1 minute
|
|
11
|
+
export class RateLimiter {
|
|
12
|
+
buckets = new Map();
|
|
13
|
+
check(key, limit) {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
const bucket = this.buckets.get(key);
|
|
16
|
+
if (!bucket || now - bucket.windowStart >= RATE_WINDOW_MS) {
|
|
17
|
+
this.buckets.set(key, { count: 1, windowStart: now });
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
if (bucket.count >= limit) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
bucket.count++;
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
/** Reset for testing */
|
|
27
|
+
reset() {
|
|
28
|
+
this.buckets.clear();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// ─── Discovery Service ───────────────────────────────────
|
|
32
|
+
export class DiscoveryService {
|
|
33
|
+
db;
|
|
34
|
+
anonIdManager;
|
|
35
|
+
inboundLimiter = new RateLimiter();
|
|
36
|
+
outboundLimiter = new RateLimiter();
|
|
37
|
+
constructor(db) {
|
|
38
|
+
this.db = db;
|
|
39
|
+
this.anonIdManager = new AnonymousIdManager(db);
|
|
40
|
+
}
|
|
41
|
+
// ─── Discovery Config (tenant-wide) ─────────────────
|
|
42
|
+
getDiscoveryConfig(tenantId) {
|
|
43
|
+
const row = this.db
|
|
44
|
+
.select()
|
|
45
|
+
.from(discoveryConfig)
|
|
46
|
+
.where(eq(discoveryConfig.tenantId, tenantId))
|
|
47
|
+
.get();
|
|
48
|
+
if (row) {
|
|
49
|
+
return {
|
|
50
|
+
tenantId: row.tenantId,
|
|
51
|
+
minTrustThreshold: row.minTrustThreshold,
|
|
52
|
+
delegationEnabled: row.delegationEnabled,
|
|
53
|
+
updatedAt: row.updatedAt,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Return defaults
|
|
57
|
+
return {
|
|
58
|
+
tenantId,
|
|
59
|
+
minTrustThreshold: 60,
|
|
60
|
+
delegationEnabled: false,
|
|
61
|
+
updatedAt: new Date().toISOString(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
updateDiscoveryConfig(tenantId, updates) {
|
|
65
|
+
const now = new Date().toISOString();
|
|
66
|
+
const existing = this.db
|
|
67
|
+
.select()
|
|
68
|
+
.from(discoveryConfig)
|
|
69
|
+
.where(eq(discoveryConfig.tenantId, tenantId))
|
|
70
|
+
.get();
|
|
71
|
+
if (existing) {
|
|
72
|
+
const setObj = { updatedAt: now };
|
|
73
|
+
if (updates.minTrustThreshold !== undefined)
|
|
74
|
+
setObj.minTrustThreshold = updates.minTrustThreshold;
|
|
75
|
+
if (updates.delegationEnabled !== undefined)
|
|
76
|
+
setObj.delegationEnabled = updates.delegationEnabled;
|
|
77
|
+
this.db.update(discoveryConfig).set(setObj).where(eq(discoveryConfig.tenantId, tenantId)).run();
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.db.insert(discoveryConfig).values({
|
|
81
|
+
tenantId,
|
|
82
|
+
minTrustThreshold: updates.minTrustThreshold ?? 60,
|
|
83
|
+
delegationEnabled: updates.delegationEnabled ?? false,
|
|
84
|
+
updatedAt: now,
|
|
85
|
+
}).run();
|
|
86
|
+
}
|
|
87
|
+
return this.getDiscoveryConfig(tenantId);
|
|
88
|
+
}
|
|
89
|
+
// ─── Permission: per-agent config ───────────────────
|
|
90
|
+
updateAgentPermissions(tenantId, capabilityId, updates) {
|
|
91
|
+
const setObj = { updatedAt: new Date().toISOString() };
|
|
92
|
+
if (updates.enabled !== undefined)
|
|
93
|
+
setObj.enabled = updates.enabled;
|
|
94
|
+
if (updates.acceptDelegations !== undefined)
|
|
95
|
+
setObj.acceptDelegations = updates.acceptDelegations;
|
|
96
|
+
if (updates.inboundRateLimit !== undefined)
|
|
97
|
+
setObj.inboundRateLimit = updates.inboundRateLimit;
|
|
98
|
+
if (updates.outboundRateLimit !== undefined)
|
|
99
|
+
setObj.outboundRateLimit = updates.outboundRateLimit;
|
|
100
|
+
const result = this.db
|
|
101
|
+
.update(capabilityRegistry)
|
|
102
|
+
.set(setObj)
|
|
103
|
+
.where(and(eq(capabilityRegistry.id, capabilityId), eq(capabilityRegistry.tenantId, tenantId)))
|
|
104
|
+
.run();
|
|
105
|
+
return result.changes > 0;
|
|
106
|
+
}
|
|
107
|
+
// ─── Rate Limit Checks ─────────────────────────────
|
|
108
|
+
checkInboundRateLimit(agentId, limit) {
|
|
109
|
+
return this.inboundLimiter.check(`inbound:${agentId}`, limit);
|
|
110
|
+
}
|
|
111
|
+
checkOutboundRateLimit(agentId, limit) {
|
|
112
|
+
return this.outboundLimiter.check(`outbound:${agentId}`, limit);
|
|
113
|
+
}
|
|
114
|
+
// ─── Discovery ─────────────────────────────────────
|
|
115
|
+
discover(tenantId, query) {
|
|
116
|
+
// Scope=internal: only local query, never hits external pool
|
|
117
|
+
// (pool integration comes in B4)
|
|
118
|
+
const rows = this.db
|
|
119
|
+
.select()
|
|
120
|
+
.from(capabilityRegistry)
|
|
121
|
+
.where(eq(capabilityRegistry.tenantId, tenantId))
|
|
122
|
+
.all();
|
|
123
|
+
// Get tenant config for trust threshold
|
|
124
|
+
const config = this.getDiscoveryConfig(tenantId);
|
|
125
|
+
let results = rows
|
|
126
|
+
// Only enabled capabilities are discoverable (5.4 opt-in)
|
|
127
|
+
.filter((r) => r.enabled)
|
|
128
|
+
// Filter by taskType
|
|
129
|
+
.filter((r) => r.taskType === query.taskType)
|
|
130
|
+
// Filter by customType if specified
|
|
131
|
+
.filter((r) => !query.customType || r.customType === query.customType);
|
|
132
|
+
// Apply trust filter (minTrustScore from query or tenant minimum)
|
|
133
|
+
const effectiveMinTrust = Math.max(query.minTrustScore ?? 0, config.minTrustThreshold);
|
|
134
|
+
results = results.filter((r) => {
|
|
135
|
+
const metrics = JSON.parse(r.qualityMetrics);
|
|
136
|
+
const trustScore = metrics.trustScorePercentile ?? 50;
|
|
137
|
+
return trustScore >= effectiveMinTrust;
|
|
138
|
+
});
|
|
139
|
+
// Apply cost filter
|
|
140
|
+
if (query.maxCostUsd !== undefined) {
|
|
141
|
+
results = results.filter((r) => r.estimatedCostUsd === null || r.estimatedCostUsd <= query.maxCostUsd);
|
|
142
|
+
}
|
|
143
|
+
// Apply latency filter
|
|
144
|
+
if (query.maxLatencyMs !== undefined) {
|
|
145
|
+
results = results.filter((r) => r.estimatedLatencyMs === null || r.estimatedLatencyMs <= query.maxLatencyMs);
|
|
146
|
+
}
|
|
147
|
+
// Compute composite scores and rank
|
|
148
|
+
const maxCost = query.maxCostUsd ?? 100;
|
|
149
|
+
const maxLatency = query.maxLatencyMs ?? 30000;
|
|
150
|
+
const scored = results.map((r) => {
|
|
151
|
+
const metrics = JSON.parse(r.qualityMetrics);
|
|
152
|
+
const trustScore = (metrics.trustScorePercentile ?? 50) / 100;
|
|
153
|
+
const normalizedCost = r.estimatedCostUsd != null ? Math.min(r.estimatedCostUsd / maxCost, 1.0) : 0.5;
|
|
154
|
+
const normalizedLatency = r.estimatedLatencyMs != null ? Math.min(r.estimatedLatencyMs / maxLatency, 1.0) : 0.5;
|
|
155
|
+
const compositeScore = 0.5 * trustScore +
|
|
156
|
+
0.3 * (1 - normalizedCost) +
|
|
157
|
+
0.2 * (1 - normalizedLatency);
|
|
158
|
+
return { row: r, compositeScore, metrics };
|
|
159
|
+
});
|
|
160
|
+
scored.sort((a, b) => b.compositeScore - a.compositeScore);
|
|
161
|
+
// Limit results (max 20)
|
|
162
|
+
const limit = Math.min(query.limit ?? 20, 20);
|
|
163
|
+
const topResults = scored.slice(0, limit);
|
|
164
|
+
// Map to DiscoveryResult with anonymous IDs
|
|
165
|
+
return topResults.map(({ row, metrics }) => {
|
|
166
|
+
const anonymousAgentId = this.anonIdManager.getOrRotateAnonymousId(tenantId, row.agentId);
|
|
167
|
+
const completedTasks = metrics.completedTasks ?? 0;
|
|
168
|
+
return {
|
|
169
|
+
anonymousAgentId,
|
|
170
|
+
taskType: row.taskType,
|
|
171
|
+
customType: row.customType ?? undefined,
|
|
172
|
+
inputSchema: JSON.parse(row.inputSchema),
|
|
173
|
+
outputSchema: JSON.parse(row.outputSchema),
|
|
174
|
+
trustScorePercentile: (metrics.trustScorePercentile ?? 50),
|
|
175
|
+
provisional: completedTasks < 10,
|
|
176
|
+
estimatedLatencyMs: row.estimatedLatencyMs ?? undefined,
|
|
177
|
+
estimatedCostUsd: row.estimatedCostUsd ?? undefined,
|
|
178
|
+
qualityMetrics: {
|
|
179
|
+
successRate: metrics.successRate ?? undefined,
|
|
180
|
+
completedTasks: completedTasks || undefined,
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=discovery-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery-service.js","sourceRoot":"","sources":["../../src/services/discovery-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Service (Story 6.3 — Trust Scoring)
|
|
3
|
+
*
|
|
4
|
+
* Computes trust scores for agents based on health score history and delegation success rate.
|
|
5
|
+
* Formula: 0.6 * healthComponent + 0.4 * delegationSuccessRate (both normalized 0-100)
|
|
6
|
+
*/
|
|
7
|
+
import type { SqliteDb } from '../db/index.js';
|
|
8
|
+
export interface TrustScore {
|
|
9
|
+
agentId: string;
|
|
10
|
+
rawScore: number;
|
|
11
|
+
healthComponent: number;
|
|
12
|
+
delegationComponent: number;
|
|
13
|
+
percentile: number;
|
|
14
|
+
provisional: boolean;
|
|
15
|
+
totalDelegations: number;
|
|
16
|
+
successfulDelegations: number;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
}
|
|
19
|
+
export interface DelegationStats {
|
|
20
|
+
total: number;
|
|
21
|
+
successful: number;
|
|
22
|
+
failed: number;
|
|
23
|
+
timedOut: number;
|
|
24
|
+
}
|
|
25
|
+
export declare class TrustService {
|
|
26
|
+
private readonly db;
|
|
27
|
+
private readonly healthStore;
|
|
28
|
+
constructor(db: SqliteDb);
|
|
29
|
+
/**
|
|
30
|
+
* Get delegation stats for an agent in a tenant.
|
|
31
|
+
*/
|
|
32
|
+
getDelegationStats(tenantId: string, agentId: string): DelegationStats;
|
|
33
|
+
/**
|
|
34
|
+
* Compute the health component (average of last 30 days of health scores).
|
|
35
|
+
*/
|
|
36
|
+
computeHealthComponent(tenantId: string, agentId: string): number;
|
|
37
|
+
/**
|
|
38
|
+
* Compute the delegation success rate component (0-100).
|
|
39
|
+
*/
|
|
40
|
+
computeDelegationComponent(stats: DelegationStats): number;
|
|
41
|
+
/**
|
|
42
|
+
* Compute the raw trust score for an agent.
|
|
43
|
+
*/
|
|
44
|
+
computeRawTrustScore(tenantId: string, agentId: string): number;
|
|
45
|
+
/**
|
|
46
|
+
* Compute percentile rank of an agent's trust score among all agents in the tenant.
|
|
47
|
+
*/
|
|
48
|
+
computePercentile(tenantId: string, agentId: string): number;
|
|
49
|
+
/**
|
|
50
|
+
* Get the full trust score for an agent.
|
|
51
|
+
*/
|
|
52
|
+
getTrustScore(tenantId: string, agentId: string): TrustScore;
|
|
53
|
+
/**
|
|
54
|
+
* Update trust-related quality metrics on the capability registry after a delegation outcome.
|
|
55
|
+
* Called after delegation success/failure/timeout to keep trust score percentile fresh.
|
|
56
|
+
*/
|
|
57
|
+
updateAfterDelegation(tenantId: string, agentId: string): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=trust-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-service.d.ts","sourceRoot":"","sources":["../../src/services/trust-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK/C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAUD,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;gBAErB,EAAE,EAAE,QAAQ;IAIzC;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,eAAe;IAqBtE;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAOjE;;OAEG;IACH,0BAA0B,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM;IAK1D;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAO/D;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAwB5D;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU;IAqB5D;;;OAGG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;CAgB/D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Service (Story 6.3 — Trust Scoring)
|
|
3
|
+
*
|
|
4
|
+
* Computes trust scores for agents based on health score history and delegation success rate.
|
|
5
|
+
* Formula: 0.6 * healthComponent + 0.4 * delegationSuccessRate (both normalized 0-100)
|
|
6
|
+
*/
|
|
7
|
+
import { sql } from 'drizzle-orm';
|
|
8
|
+
import { HealthSnapshotStore } from '../db/health-snapshot-store.js';
|
|
9
|
+
// ─── Trust Service ────────────────────────────────────────
|
|
10
|
+
const PROVISIONAL_THRESHOLD = 10;
|
|
11
|
+
const HEALTH_WEIGHT = 0.6;
|
|
12
|
+
const DELEGATION_WEIGHT = 0.4;
|
|
13
|
+
const DEFAULT_HEALTH_SCORE = 50;
|
|
14
|
+
const HEALTH_HISTORY_DAYS = 30;
|
|
15
|
+
export class TrustService {
|
|
16
|
+
db;
|
|
17
|
+
healthStore;
|
|
18
|
+
constructor(db) {
|
|
19
|
+
this.db = db;
|
|
20
|
+
this.healthStore = new HealthSnapshotStore(db);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get delegation stats for an agent in a tenant.
|
|
24
|
+
*/
|
|
25
|
+
getDelegationStats(tenantId, agentId) {
|
|
26
|
+
const rows = this.db.all(sql `
|
|
27
|
+
SELECT status, COUNT(*) as cnt FROM delegation_log
|
|
28
|
+
WHERE tenant_id = ${tenantId}
|
|
29
|
+
AND agent_id = ${agentId}
|
|
30
|
+
AND direction = 'outbound'
|
|
31
|
+
AND (status = 'completed' OR status = 'error' OR status = 'timeout' OR status = 'rejected')
|
|
32
|
+
GROUP BY status
|
|
33
|
+
`);
|
|
34
|
+
const stats = { total: 0, successful: 0, failed: 0, timedOut: 0 };
|
|
35
|
+
for (const row of rows) {
|
|
36
|
+
const count = Number(row.cnt);
|
|
37
|
+
stats.total += count;
|
|
38
|
+
if (row.status === 'completed')
|
|
39
|
+
stats.successful += count;
|
|
40
|
+
else if (row.status === 'timeout')
|
|
41
|
+
stats.timedOut += count;
|
|
42
|
+
else
|
|
43
|
+
stats.failed += count;
|
|
44
|
+
}
|
|
45
|
+
return stats;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Compute the health component (average of last 30 days of health scores).
|
|
49
|
+
*/
|
|
50
|
+
computeHealthComponent(tenantId, agentId) {
|
|
51
|
+
const history = this.healthStore.getHistory(tenantId, agentId, HEALTH_HISTORY_DAYS);
|
|
52
|
+
if (history.length === 0)
|
|
53
|
+
return DEFAULT_HEALTH_SCORE;
|
|
54
|
+
const sum = history.reduce((acc, s) => acc + s.overallScore, 0);
|
|
55
|
+
return sum / history.length;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Compute the delegation success rate component (0-100).
|
|
59
|
+
*/
|
|
60
|
+
computeDelegationComponent(stats) {
|
|
61
|
+
if (stats.total === 0)
|
|
62
|
+
return DEFAULT_HEALTH_SCORE; // default when no data
|
|
63
|
+
return (stats.successful / stats.total) * 100;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Compute the raw trust score for an agent.
|
|
67
|
+
*/
|
|
68
|
+
computeRawTrustScore(tenantId, agentId) {
|
|
69
|
+
const healthComponent = this.computeHealthComponent(tenantId, agentId);
|
|
70
|
+
const stats = this.getDelegationStats(tenantId, agentId);
|
|
71
|
+
const delegationComponent = this.computeDelegationComponent(stats);
|
|
72
|
+
return HEALTH_WEIGHT * healthComponent + DELEGATION_WEIGHT * delegationComponent;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Compute percentile rank of an agent's trust score among all agents in the tenant.
|
|
76
|
+
*/
|
|
77
|
+
computePercentile(tenantId, agentId) {
|
|
78
|
+
// Get all unique agent IDs in the tenant (from delegation_log + capability_registry)
|
|
79
|
+
const agentRows = this.db.all(sql `
|
|
80
|
+
SELECT DISTINCT agent_id FROM capability_registry WHERE tenant_id = ${tenantId}
|
|
81
|
+
UNION
|
|
82
|
+
SELECT DISTINCT agent_id FROM delegation_log WHERE tenant_id = ${tenantId}
|
|
83
|
+
`);
|
|
84
|
+
const agentIds = agentRows.map((r) => r.agent_id);
|
|
85
|
+
if (agentIds.length <= 1)
|
|
86
|
+
return 100; // Only agent → 100th percentile
|
|
87
|
+
// Compute scores for all agents
|
|
88
|
+
const scores = agentIds.map((id) => ({
|
|
89
|
+
agentId: id,
|
|
90
|
+
score: this.computeRawTrustScore(tenantId, id),
|
|
91
|
+
}));
|
|
92
|
+
scores.sort((a, b) => a.score - b.score);
|
|
93
|
+
const targetScore = scores.find((s) => s.agentId === agentId)?.score ?? 0;
|
|
94
|
+
const belowCount = scores.filter((s) => s.score < targetScore).length;
|
|
95
|
+
return Math.round((belowCount / (scores.length - 1)) * 100);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get the full trust score for an agent.
|
|
99
|
+
*/
|
|
100
|
+
getTrustScore(tenantId, agentId) {
|
|
101
|
+
const healthComponent = this.computeHealthComponent(tenantId, agentId);
|
|
102
|
+
const stats = this.getDelegationStats(tenantId, agentId);
|
|
103
|
+
const delegationComponent = this.computeDelegationComponent(stats);
|
|
104
|
+
const rawScore = HEALTH_WEIGHT * healthComponent + DELEGATION_WEIGHT * delegationComponent;
|
|
105
|
+
const percentile = this.computePercentile(tenantId, agentId);
|
|
106
|
+
const provisional = stats.total < PROVISIONAL_THRESHOLD;
|
|
107
|
+
return {
|
|
108
|
+
agentId,
|
|
109
|
+
rawScore: Math.round(rawScore * 100) / 100,
|
|
110
|
+
healthComponent: Math.round(healthComponent * 100) / 100,
|
|
111
|
+
delegationComponent: Math.round(delegationComponent * 100) / 100,
|
|
112
|
+
percentile,
|
|
113
|
+
provisional,
|
|
114
|
+
totalDelegations: stats.total,
|
|
115
|
+
successfulDelegations: stats.successful,
|
|
116
|
+
updatedAt: new Date().toISOString(),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Update trust-related quality metrics on the capability registry after a delegation outcome.
|
|
121
|
+
* Called after delegation success/failure/timeout to keep trust score percentile fresh.
|
|
122
|
+
*/
|
|
123
|
+
updateAfterDelegation(tenantId, agentId) {
|
|
124
|
+
const score = this.getTrustScore(tenantId, agentId);
|
|
125
|
+
// Update all capability_registry entries for this agent with the new trust percentile
|
|
126
|
+
this.db.run(sql `
|
|
127
|
+
UPDATE capability_registry
|
|
128
|
+
SET quality_metrics = json_set(
|
|
129
|
+
quality_metrics,
|
|
130
|
+
'$.trustScorePercentile', ${score.percentile},
|
|
131
|
+
'$.trustRawScore', ${score.rawScore},
|
|
132
|
+
'$.provisional', ${score.provisional ? 1 : 0}
|
|
133
|
+
),
|
|
134
|
+
updated_at = ${new Date().toISOString()}
|
|
135
|
+
WHERE tenant_id = ${tenantId} AND agent_id = ${agentId}
|
|
136
|
+
`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=trust-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-service.js","sourceRoot":"","sources":["../../src/services/trust-service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentlensai/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "AgentLens API server — event ingestion, querying, dashboard, and alerting for AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dev": "tsx watch src/index.ts"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@agentlensai/core": "
|
|
48
|
+
"@agentlensai/core": "workspace:*",
|
|
49
49
|
"drizzle-orm": "^0.44.2",
|
|
50
50
|
"better-sqlite3": "^11.9.1",
|
|
51
51
|
"hono": "^4.7.10",
|