kompass-sdk 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.
@@ -1,51 +1,55 @@
1
1
  /**
2
2
  * Agent Discovery Protocol (ADP) Source Adapter
3
- * agentdiscovery.io open protocol for autonomous agent commerce
3
+ * Uses the real ADP v2 API at agentdiscovery.io
4
4
  */
5
5
 
6
6
  import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
7
7
 
8
- const ADP_BASE = "https://agentdiscovery.io";
8
+ const ADP_BASE = "https://agentdiscovery.io/api/adp/v2";
9
9
 
10
10
  export const adpAdapter: SourceAdapter = {
11
11
  name: "adp",
12
- displayName: "Agent Discovery Protocol",
12
+ displayName: "Agent Discovery Protocol (ADP v2)",
13
13
 
14
14
  async search(query: string, options?: SourceSearchOptions): Promise<UnifiedAgent[]> {
15
15
  try {
16
- // Try the ADP API
17
- const res = await fetch(`${ADP_BASE}/api/agents?q=${encodeURIComponent(query)}&limit=${options?.limit ?? 20}`, {
16
+ // First try discovery endpoint with intent
17
+ const discoverRes = await fetch(`${ADP_BASE}/discover`, {
18
+ method: "POST",
19
+ headers: { "Content-Type": "application/json" },
20
+ body: JSON.stringify({ intent: query, category: query }),
18
21
  signal: AbortSignal.timeout(options?.timeout ?? 5000),
19
22
  });
20
23
 
21
- if (!res.ok) return [];
24
+ if (discoverRes.ok) {
25
+ const data = await discoverRes.json();
26
+ const agents = data.matches ?? data.agents ?? data.results ?? [];
27
+ if (Array.isArray(agents) && agents.length > 0) {
28
+ return agents.slice(0, options?.limit ?? 20).map(mapAdpAgent);
29
+ }
30
+ }
22
31
 
23
- const data = await res.json();
24
- const agents = Array.isArray(data) ? data : data.agents ?? data.data ?? [];
32
+ // Fallback: list all agents
33
+ const listRes = await fetch(`${ADP_BASE}/agents`, {
34
+ signal: AbortSignal.timeout(options?.timeout ?? 5000),
35
+ });
36
+
37
+ if (!listRes.ok) return [];
25
38
 
26
- return agents.map((agent: any) => ({
27
- id: `adp:${agent.id ?? agent.address}`,
28
- nativeId: String(agent.id ?? agent.address),
29
- name: agent.name ?? "ADP Agent",
30
- description: agent.description ?? "",
31
- categories: agent.categories ?? agent.tags ?? ["general"],
32
- capabilities: agent.capabilities ?? [agent.description ?? ""],
33
- source: "adp" as const,
34
- protocol: (agent.protocol ?? "http") as any,
35
- endpoints: {
36
- http: agent.endpoint ?? agent.url,
37
- a2a: agent.a2aEndpoint,
38
- x402: agent.x402Endpoint,
39
- },
40
- reputation: agent.reputation ? {
41
- score: agent.reputation.score ?? 0,
42
- count: agent.reputation.count ?? 0,
43
- source: "adp",
44
- } : undefined,
45
- pricing: agent.pricing,
46
- verified: agent.verified ?? false,
47
- raw: agent,
48
- }));
39
+ const data = await listRes.json();
40
+ const agents = data.agents ?? [];
41
+ if (!Array.isArray(agents)) return [];
42
+
43
+ // Client-side filter by query
44
+ const lower = query.toLowerCase();
45
+ return agents
46
+ .filter((a: any) => {
47
+ if (!query) return true;
48
+ const text = `${a.name ?? ""} ${a.role ?? ""} ${(a.categories ?? []).join(" ")} ${(a.capabilities ?? []).map((c: any) => c.description ?? c.key ?? "").join(" ")}`.toLowerCase();
49
+ return lower.split(/\s+/).some((t) => text.includes(t));
50
+ })
51
+ .slice(0, options?.limit ?? 20)
52
+ .map(mapAdpAgent);
49
53
  } catch {
50
54
  return [];
51
55
  }
@@ -53,12 +57,30 @@ export const adpAdapter: SourceAdapter = {
53
57
 
54
58
  async ping(): Promise<boolean> {
55
59
  try {
56
- const res = await fetch(`${ADP_BASE}/api/health`, {
57
- signal: AbortSignal.timeout(3000),
58
- });
60
+ const res = await fetch(`${ADP_BASE}/agents`, { signal: AbortSignal.timeout(3000) });
59
61
  return res.ok;
60
62
  } catch {
61
63
  return false;
62
64
  }
63
65
  },
64
66
  };
67
+
68
+ function mapAdpAgent(agent: any): UnifiedAgent {
69
+ return {
70
+ id: `adp:${agent.did ?? agent.id ?? agent.name}`,
71
+ nativeId: agent.did ?? agent.id ?? "",
72
+ name: agent.name ?? "ADP Agent",
73
+ description: (agent.capabilities ?? []).map((c: any) => c.description ?? c.key ?? "").join(". ") || (agent.role ?? ""),
74
+ categories: agent.categories ?? [agent.role ?? "general"],
75
+ capabilities: (agent.capabilities ?? []).map((c: any) => `${c.key}: ${c.description ?? ""}`),
76
+ source: "adp",
77
+ protocol: "a2a",
78
+ endpoints: {
79
+ http: agent.endpoint ?? agent.url,
80
+ a2a: agent.a2a_endpoint,
81
+ },
82
+ pricing: agent.pricing,
83
+ verified: !!agent.did,
84
+ raw: agent,
85
+ };
86
+ }
package/src/unified.ts CHANGED
@@ -13,6 +13,7 @@
13
13
  import { createAllSources, type SourceAdapter, type UnifiedAgent } from "./sources/index.js";
14
14
  import { Aggregator, type AggregatorOptions, type AggregatorResult } from "./aggregator.js";
15
15
  import { rankAgents, type MatchResult } from "./matching.js";
16
+ import { rankAgentsV2, type RankedAgent } from "./ranking.js";
16
17
  import { ProtocolBridge, type BridgeHireOptions, type BridgeHireResult } from "./bridge.js";
17
18
  import { CapabilityRouter, type DoOptions, type DoResult } from "./router.js";
18
19
  import type { ReputationWriterConfig } from "./reputation-writer.js";
@@ -44,8 +45,10 @@ export interface FindOptions {
44
45
  }
45
46
 
46
47
  export interface FindResult extends AggregatorResult {
47
- /** Agents re-ranked by multi-layer matching */
48
+ /** Agents re-ranked by multi-layer matching (v1) */
48
49
  ranked: MatchResult[];
50
+ /** Agents re-ranked by v2 engine (Bayesian + geometric + value) */
51
+ rankedV2?: RankedAgent[];
49
52
  }
50
53
 
51
54
  export class KompassUnified {
@@ -89,18 +92,22 @@ export class KompassUnified {
89
92
  timeout: options?.timeout,
90
93
  });
91
94
 
92
- // Re-rank with multi-layer matching
95
+ // Re-rank with v2 ranking engine (Bayesian + geometric + value-for-money)
96
+ const rankedV2 = rankAgentsV2(aggregatorResult.agents, query);
97
+
98
+ // Also keep v1 for backward compat
93
99
  const ranked = rankAgents(aggregatorResult.agents, query);
94
100
 
95
- // Apply limit and min score
101
+ // Apply limit and min score using v2 composite
96
102
  const filtered = options?.minScore
97
- ? ranked.filter((r) => r.scores.total >= options.minScore!)
98
- : ranked;
103
+ ? rankedV2.filter((r) => r.scores.composite >= options.minScore!)
104
+ : rankedV2;
99
105
 
100
106
  return {
101
107
  ...aggregatorResult,
102
108
  agents: filtered.slice(0, options?.limit ?? 20).map((r) => r.agent),
103
- ranked: filtered.slice(0, options?.limit ?? 20),
109
+ ranked: ranked.slice(0, options?.limit ?? 20), // v1 for backward compat
110
+ rankedV2: filtered.slice(0, options?.limit ?? 20), // v2 with proper scoring
104
111
  };
105
112
  }
106
113
 
@@ -0,0 +1,53 @@
1
+ import { KompassUnified } from './src/unified.js';
2
+
3
+ async function main() {
4
+ const kompass = await KompassUnified.create();
5
+ const result = await kompass.find('DeFi yield data', { limit: 20 });
6
+
7
+ console.log('=== SOURCES ===');
8
+ for (const s of result.sources) {
9
+ console.log(` ${s.name}: ${s.count} agents (${s.durationMs}ms)${s.error ? ' ERROR: '+s.error : ''}`);
10
+ }
11
+
12
+ console.log(`\nTotal: ${result.totalFound} found, ${result.deduplicated} deduped, ${result.queryTimeMs}ms`);
13
+
14
+ const bySrc: Record<string, number> = {};
15
+ const byProto: Record<string, number> = {};
16
+ for (const a of result.agents) {
17
+ bySrc[a.source] = (bySrc[a.source] || 0) + 1;
18
+ byProto[a.protocol] = (byProto[a.protocol] || 0) + 1;
19
+ }
20
+
21
+ console.log('\n=== BY SOURCE ===');
22
+ for (const [k, v] of Object.entries(bySrc).sort((a, b) => b[1] - a[1])) console.log(` ${k}: ${v}`);
23
+
24
+ console.log('\n=== BY PROTOCOL ===');
25
+ for (const [k, v] of Object.entries(byProto).sort((a, b) => b[1] - a[1])) console.log(` ${k}: ${v}`);
26
+
27
+ console.log('\n=== V2 RANKING (Bayesian + Geometric + Value-for-Money) ===');
28
+ console.log(' # Proto Name Source Cost Composite Relevance Quality Volume Value Explanation');
29
+ console.log(' ' + '─'.repeat(170));
30
+
31
+ const v2 = result.rankedV2 ?? [];
32
+ for (let i = 0; i < Math.min(20, v2.length); i++) {
33
+ const r = v2[i];
34
+ const a = r.agent;
35
+ const s = r.scores;
36
+ const proto = a.protocol.toUpperCase().padEnd(6);
37
+ const name = (a.name ?? '?').slice(0, 35).padEnd(35);
38
+ const src = a.source.padEnd(18);
39
+ const price = a.pricing?.amount ? `$${a.pricing.amount}` : 'free/?';
40
+
41
+ console.log(
42
+ ` ${String(i + 1).padStart(2)} [${proto}] ${name} | ${src} | ${price.padEnd(10)} | ` +
43
+ `comp=${s.composite.toFixed(1).padEnd(6)} | ` +
44
+ `rel=${s.relevance.toFixed(0).padEnd(4)} | ` +
45
+ `qual=${s.quality.toFixed(1).padEnd(6)} | ` +
46
+ `vol=${s.volume.toFixed(0).padEnd(4)} | ` +
47
+ `val=${s.value.toFixed(1).padEnd(6)} | ` +
48
+ `${r.explanation}`
49
+ );
50
+ }
51
+ }
52
+
53
+ main().catch(console.error);