kompass-sdk 0.1.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/a2a/agent-card.d.ts +13 -0
- package/dist/a2a/agent-card.d.ts.map +1 -0
- package/dist/a2a/agent-card.js +52 -0
- package/dist/a2a/agent-card.js.map +1 -0
- package/dist/a2a/bridge.d.ts +52 -0
- package/dist/a2a/bridge.d.ts.map +1 -0
- package/dist/a2a/bridge.js +123 -0
- package/dist/a2a/bridge.js.map +1 -0
- package/dist/a2a/client.d.ts +34 -0
- package/dist/a2a/client.d.ts.map +1 -0
- package/dist/a2a/client.js +65 -0
- package/dist/a2a/client.js.map +1 -0
- package/dist/a2a/server.d.ts +17 -0
- package/dist/a2a/server.d.ts.map +1 -0
- package/dist/a2a/server.js +194 -0
- package/dist/a2a/server.js.map +1 -0
- package/dist/abi.d.ts +1068 -0
- package/dist/abi.d.ts.map +1 -0
- package/dist/abi.js +1372 -0
- package/dist/abi.js.map +1 -0
- package/dist/adapters/agentkit.d.ts +41 -0
- package/dist/adapters/agentkit.d.ts.map +1 -0
- package/dist/adapters/agentkit.js +67 -0
- package/dist/adapters/agentkit.js.map +1 -0
- package/dist/adapters/generic.d.ts +35 -0
- package/dist/adapters/generic.d.ts.map +1 -0
- package/dist/adapters/generic.js +47 -0
- package/dist/adapters/generic.js.map +1 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +5 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/langchain.d.ts +26 -0
- package/dist/adapters/langchain.d.ts.map +1 -0
- package/dist/adapters/langchain.js +228 -0
- package/dist/adapters/langchain.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +18 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +168 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/aggregator.d.ts +36 -0
- package/dist/aggregator.d.ts.map +1 -0
- package/dist/aggregator.js +168 -0
- package/dist/aggregator.js.map +1 -0
- package/dist/backends/acp.d.ts +29 -0
- package/dist/backends/acp.d.ts.map +1 -0
- package/dist/backends/acp.js +126 -0
- package/dist/backends/acp.js.map +1 -0
- package/dist/backends/types.d.ts +59 -0
- package/dist/backends/types.d.ts.map +1 -0
- package/dist/backends/types.js +2 -0
- package/dist/backends/types.js.map +1 -0
- package/dist/bridge.d.ts +35 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +192 -0
- package/dist/bridge.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +331 -0
- package/dist/cli.js.map +1 -0
- package/dist/discover.d.ts +15 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +163 -0
- package/dist/discover.js.map +1 -0
- package/dist/escrow.d.ts +45 -0
- package/dist/escrow.d.ts.map +1 -0
- package/dist/escrow.js +243 -0
- package/dist/escrow.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +145 -0
- package/dist/index.js.map +1 -0
- package/dist/intents.d.ts +28 -0
- package/dist/intents.d.ts.map +1 -0
- package/dist/intents.js +111 -0
- package/dist/intents.js.map +1 -0
- package/dist/matching.d.ts +29 -0
- package/dist/matching.d.ts.map +1 -0
- package/dist/matching.js +147 -0
- package/dist/matching.js.map +1 -0
- package/dist/pipelineAbi.d.ts +113 -0
- package/dist/pipelineAbi.d.ts.map +1 -0
- package/dist/pipelineAbi.js +74 -0
- package/dist/pipelineAbi.js.map +1 -0
- package/dist/pipelines.d.ts +42 -0
- package/dist/pipelines.d.ts.map +1 -0
- package/dist/pipelines.js +185 -0
- package/dist/pipelines.js.map +1 -0
- package/dist/registry.d.ts +36 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +187 -0
- package/dist/registry.js.map +1 -0
- package/dist/reputation.d.ts +10 -0
- package/dist/reputation.d.ts.map +1 -0
- package/dist/reputation.js +33 -0
- package/dist/reputation.js.map +1 -0
- package/dist/router.d.ts +72 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +190 -0
- package/dist/router.js.map +1 -0
- package/dist/simple.d.ts +160 -0
- package/dist/simple.d.ts.map +1 -0
- package/dist/simple.js +237 -0
- package/dist/simple.js.map +1 -0
- package/dist/sources/a2a-wellknown.d.ts +8 -0
- package/dist/sources/a2a-wellknown.d.ts.map +1 -0
- package/dist/sources/a2a-wellknown.js +104 -0
- package/dist/sources/a2a-wellknown.js.map +1 -0
- package/dist/sources/acp.d.ts +7 -0
- package/dist/sources/acp.d.ts.map +1 -0
- package/dist/sources/acp.js +86 -0
- package/dist/sources/acp.js.map +1 -0
- package/dist/sources/adp.d.ts +7 -0
- package/dist/sources/adp.d.ts.map +1 -0
- package/dist/sources/adp.js +59 -0
- package/dist/sources/adp.js.map +1 -0
- package/dist/sources/erc8004.d.ts +7 -0
- package/dist/sources/erc8004.d.ts.map +1 -0
- package/dist/sources/erc8004.js +150 -0
- package/dist/sources/erc8004.js.map +1 -0
- package/dist/sources/index.d.ts +17 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +35 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/kompass-registry.d.ts +8 -0
- package/dist/sources/kompass-registry.d.ts.map +1 -0
- package/dist/sources/kompass-registry.js +62 -0
- package/dist/sources/kompass-registry.js.map +1 -0
- package/dist/sources/l402-directory.d.ts +7 -0
- package/dist/sources/l402-directory.d.ts.map +1 -0
- package/dist/sources/l402-directory.js +42 -0
- package/dist/sources/l402-directory.js.map +1 -0
- package/dist/sources/mcp-registry.d.ts +8 -0
- package/dist/sources/mcp-registry.d.ts.map +1 -0
- package/dist/sources/mcp-registry.js +85 -0
- package/dist/sources/mcp-registry.js.map +1 -0
- package/dist/sources/skills.d.ts +8 -0
- package/dist/sources/skills.d.ts.map +1 -0
- package/dist/sources/skills.js +153 -0
- package/dist/sources/skills.js.map +1 -0
- package/dist/sources/types.d.ts +72 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +8 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/sources/x402-ecosystem.d.ts +7 -0
- package/dist/sources/x402-ecosystem.d.ts.map +1 -0
- package/dist/sources/x402-ecosystem.js +78 -0
- package/dist/sources/x402-ecosystem.js.map +1 -0
- package/dist/types.d.ts +133 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/unified.d.ts +90 -0
- package/dist/unified.d.ts.map +1 -0
- package/dist/unified.js +107 -0
- package/dist/unified.js.map +1 -0
- package/dist/x402.d.ts +30 -0
- package/dist/x402.d.ts.map +1 -0
- package/dist/x402.js +79 -0
- package/dist/x402.js.map +1 -0
- package/package.json +61 -0
- package/scripts/bootstrap-agents.mjs +246 -0
- package/src/.gitkeep +0 -0
- package/src/a2a/agent-card.ts +66 -0
- package/src/a2a/bridge.ts +168 -0
- package/src/a2a/client.ts +92 -0
- package/src/a2a/server.ts +234 -0
- package/src/abi.ts +1373 -0
- package/src/adapters/agentkit.ts +83 -0
- package/src/adapters/generic.ts +62 -0
- package/src/adapters/index.ts +4 -0
- package/src/adapters/langchain.ts +282 -0
- package/src/adapters/openclaw.ts +203 -0
- package/src/aggregator.ts +203 -0
- package/src/backends/acp.ts +199 -0
- package/src/backends/types.ts +78 -0
- package/src/bridge.ts +263 -0
- package/src/cli.ts +397 -0
- package/src/discover.ts +187 -0
- package/src/escrow.ts +284 -0
- package/src/index.ts +245 -0
- package/src/intents.ts +166 -0
- package/src/matching.ts +192 -0
- package/src/pipelineAbi.ts +74 -0
- package/src/pipelines.ts +253 -0
- package/src/registry.ts +232 -0
- package/src/reputation.ts +43 -0
- package/src/router.ts +279 -0
- package/src/simple.ts +366 -0
- package/src/sources/a2a-wellknown.ts +120 -0
- package/src/sources/acp.ts +91 -0
- package/src/sources/adp.ts +64 -0
- package/src/sources/erc8004.ts +166 -0
- package/src/sources/index.ts +52 -0
- package/src/sources/kompass-registry.ts +67 -0
- package/src/sources/l402-directory.ts +51 -0
- package/src/sources/mcp-registry.ts +104 -0
- package/src/sources/skills.ts +161 -0
- package/src/sources/types.ts +82 -0
- package/src/sources/x402-ecosystem.ts +86 -0
- package/src/types.ts +147 -0
- package/src/unified.ts +155 -0
- package/src/x402.ts +122 -0
- package/tests/pipelineFlow.test.ts +239 -0
- package/tsconfig.json +20 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { formatUnits, formatEther, type Address, type Hex } from "viem";
|
|
2
|
+
import type {
|
|
3
|
+
KompassConfig,
|
|
4
|
+
AgentProfile,
|
|
5
|
+
CreateJobOptions,
|
|
6
|
+
CreateJobResult,
|
|
7
|
+
DiscoverOptions,
|
|
8
|
+
Job,
|
|
9
|
+
MilestoneData,
|
|
10
|
+
PaymentMode,
|
|
11
|
+
RegisterProfile,
|
|
12
|
+
ReputationSummary,
|
|
13
|
+
TxResult,
|
|
14
|
+
} from "./types.js";
|
|
15
|
+
import type { AgentCapabilityRole, IntentRoute, YieldIntent } from "./intents.js";
|
|
16
|
+
import type {
|
|
17
|
+
X402ClientOptions,
|
|
18
|
+
X402PaymentRequestContext,
|
|
19
|
+
X402PaymentRequirement,
|
|
20
|
+
X402PaymentResponse,
|
|
21
|
+
} from "./x402.js";
|
|
22
|
+
import { discover, getAgent, findEvaluator } from "./discover.js";
|
|
23
|
+
import { createJob, setBudget, fund, submit, complete, completePartial, reject, getJob, getMilestones } from "./escrow.js";
|
|
24
|
+
import { register, updateProfile, deregister } from "./registry.js";
|
|
25
|
+
import { getReputation } from "./reputation.js";
|
|
26
|
+
import { routeYieldIntent } from "./intents.js";
|
|
27
|
+
import { parseX402Requirement, requestWithX402 } from "./x402.js";
|
|
28
|
+
import { buildYieldPipelinePlan, createYieldPipeline } from "./pipelines.js";
|
|
29
|
+
|
|
30
|
+
export class Kompass {
|
|
31
|
+
private config: KompassConfig;
|
|
32
|
+
|
|
33
|
+
constructor(config: KompassConfig) {
|
|
34
|
+
this.config = config;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ── Discovery ──────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
async discover(options?: DiscoverOptions): Promise<AgentProfile[]> {
|
|
40
|
+
return discover(this.config, options);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getAgent(address: string): Promise<AgentProfile | null> {
|
|
44
|
+
return getAgent(this.config, address);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async findEvaluator(domain: string): Promise<AgentProfile[]> {
|
|
48
|
+
return findEvaluator(this.config, domain);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async routeYieldIntent(intent: YieldIntent, options?: DiscoverOptions): Promise<IntentRoute> {
|
|
52
|
+
const agents = await discover(this.config, {
|
|
53
|
+
verifiedOnly: true,
|
|
54
|
+
...options,
|
|
55
|
+
});
|
|
56
|
+
return routeYieldIntent(agents, intent);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async requestWithX402(url: string, init: RequestInit, options: X402ClientOptions): Promise<Response> {
|
|
60
|
+
return requestWithX402(url, init, options);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
buildYieldPipelinePlan(route: IntentRoute) {
|
|
64
|
+
const token = this.config.paymentTokenAddress;
|
|
65
|
+
if (!token) {
|
|
66
|
+
throw new Error("paymentTokenAddress is required in KompassConfig");
|
|
67
|
+
}
|
|
68
|
+
return buildYieldPipelinePlan(route, { token });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async createYieldPipeline(route: IntentRoute) {
|
|
72
|
+
return createYieldPipeline(this.config, route);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ── Escrow ─────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
async createJob(options: CreateJobOptions): Promise<CreateJobResult> {
|
|
78
|
+
return createJob(this.config, options);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async setBudget(jobId: bigint, amount: bigint): Promise<TxResult> {
|
|
82
|
+
return setBudget(this.config, jobId, amount);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async fund(jobId: bigint): Promise<TxResult> {
|
|
86
|
+
return fund(this.config, jobId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async submit(jobId: bigint, deliverable: Hex, milestoneIndex?: number): Promise<TxResult> {
|
|
90
|
+
return submit(this.config, jobId, deliverable, milestoneIndex);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async complete(jobId: bigint, reason?: Hex, milestoneIndex?: number): Promise<TxResult> {
|
|
94
|
+
return complete(this.config, jobId, reason, milestoneIndex);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async completePartial(jobId: bigint, percentageBps: number, reason?: Hex): Promise<TxResult> {
|
|
98
|
+
return completePartial(this.config, jobId, percentageBps, reason);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async reject(jobId: bigint, reason?: Hex): Promise<TxResult> {
|
|
102
|
+
return reject(this.config, jobId, reason);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async getJob(jobId: bigint): Promise<Job> {
|
|
106
|
+
return getJob(this.config, jobId);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async getMilestones(jobId: bigint): Promise<MilestoneData[]> {
|
|
110
|
+
return getMilestones(this.config, jobId);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ── Registry ───────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
async register(profile: RegisterProfile): Promise<TxResult> {
|
|
116
|
+
return register(this.config, profile);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async updateProfile(ensNode: Hex, updates: Partial<Omit<RegisterProfile, "ensNode">>): Promise<TxResult> {
|
|
120
|
+
return updateProfile(this.config, ensNode, updates);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async deregister(): Promise<TxResult> {
|
|
124
|
+
return deregister(this.config);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Reputation ─────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
async getReputation(agentId: bigint, tag1?: string, tag2?: string): Promise<ReputationSummary> {
|
|
130
|
+
return getReputation(this.config, agentId, tag1, tag2);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ── Token Operations ─────────────────────────────────
|
|
134
|
+
|
|
135
|
+
async approveToken(spender: Address, amount: bigint): Promise<TxResult> {
|
|
136
|
+
if (!this.config.walletClient) throw new Error("WalletClient required for approveToken");
|
|
137
|
+
const tokenAddress = this.config.paymentTokenAddress;
|
|
138
|
+
if (!tokenAddress) throw new Error("paymentTokenAddress required in KompassConfig");
|
|
139
|
+
|
|
140
|
+
const txHash = await this.config.walletClient.writeContract({
|
|
141
|
+
address: tokenAddress,
|
|
142
|
+
abi: [{ type: "function", name: "approve", inputs: [{ name: "spender", type: "address" }, { name: "value", type: "uint256" }], outputs: [{ name: "", type: "bool" }], stateMutability: "nonpayable" }] as const,
|
|
143
|
+
functionName: "approve",
|
|
144
|
+
args: [spender, amount],
|
|
145
|
+
});
|
|
146
|
+
await this.config.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
147
|
+
return { txHash };
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async getBalance(): Promise<{ address: Address; eth: string; usdc: string; usdcRaw: string; ethRaw: string }> {
|
|
151
|
+
const address = this.config.walletClient?.account?.address;
|
|
152
|
+
if (!address) throw new Error("WalletClient required for getBalance");
|
|
153
|
+
|
|
154
|
+
const ethBalance = await this.config.publicClient.getBalance({ address });
|
|
155
|
+
let usdcBalance = 0n;
|
|
156
|
+
|
|
157
|
+
if (this.config.paymentTokenAddress) {
|
|
158
|
+
usdcBalance = await this.config.publicClient.readContract({
|
|
159
|
+
address: this.config.paymentTokenAddress,
|
|
160
|
+
abi: [{ type: "function", name: "balanceOf", inputs: [{ name: "account", type: "address" }], outputs: [{ name: "", type: "uint256" }], stateMutability: "view" }] as const,
|
|
161
|
+
functionName: "balanceOf",
|
|
162
|
+
args: [address],
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
address,
|
|
168
|
+
eth: formatEther(ethBalance),
|
|
169
|
+
usdc: formatUnits(usdcBalance, 6),
|
|
170
|
+
usdcRaw: usdcBalance.toString(),
|
|
171
|
+
ethRaw: ethBalance.toString(),
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Re-export everything for direct usage
|
|
177
|
+
export type {
|
|
178
|
+
KompassConfig,
|
|
179
|
+
AgentProfile,
|
|
180
|
+
AgentType,
|
|
181
|
+
PaymentMode,
|
|
182
|
+
CreateJobOptions,
|
|
183
|
+
CreateJobResult,
|
|
184
|
+
DiscoverOptions,
|
|
185
|
+
Job,
|
|
186
|
+
JobStatus,
|
|
187
|
+
MilestoneConfig,
|
|
188
|
+
MilestoneData,
|
|
189
|
+
MilestoneStatus,
|
|
190
|
+
RegisterProfile,
|
|
191
|
+
ReputationSummary,
|
|
192
|
+
TxResult,
|
|
193
|
+
} from "./types.js";
|
|
194
|
+
|
|
195
|
+
export type {
|
|
196
|
+
AgentCapabilityRole,
|
|
197
|
+
IntentRoute,
|
|
198
|
+
YieldIntent,
|
|
199
|
+
} from "./intents.js";
|
|
200
|
+
|
|
201
|
+
export type {
|
|
202
|
+
X402ClientOptions,
|
|
203
|
+
X402PaymentRequestContext,
|
|
204
|
+
X402PaymentRequirement,
|
|
205
|
+
X402PaymentResponse,
|
|
206
|
+
} from "./x402.js";
|
|
207
|
+
|
|
208
|
+
export type {
|
|
209
|
+
CreatePipelineOptions,
|
|
210
|
+
CreatePipelineResult,
|
|
211
|
+
PipelineSettlementMode,
|
|
212
|
+
YieldPipelinePlan,
|
|
213
|
+
YieldPipelineSubtask,
|
|
214
|
+
} from "./pipelines.js";
|
|
215
|
+
|
|
216
|
+
export { discover, getAgent, findEvaluator } from "./discover.js";
|
|
217
|
+
export { createJob, setBudget, fund, submit, complete, completePartial, reject, getJob, getMilestones } from "./escrow.js";
|
|
218
|
+
export { register, updateProfile, deregister, computeENSIP25Key, setENSIP25Record } from "./registry.js";
|
|
219
|
+
export { getReputation } from "./reputation.js";
|
|
220
|
+
export { routeYieldIntent } from "./intents.js";
|
|
221
|
+
export { parseX402Requirement, requestWithX402 } from "./x402.js";
|
|
222
|
+
export { buildYieldPipelinePlan, createYieldPipeline } from "./pipelines.js";
|
|
223
|
+
|
|
224
|
+
// Framework adapters
|
|
225
|
+
export * as adapters from "./adapters/index.js";
|
|
226
|
+
|
|
227
|
+
// Simplified API (Kompass intelligence layer on top of ACP)
|
|
228
|
+
export { KompassSimple } from "./simple.js";
|
|
229
|
+
export type { KompassSimpleConfig, HireOptions, HireResult, AcceptJobsOptions, OrchestrateOptions, OrchestrateResult } from "./simple.js";
|
|
230
|
+
|
|
231
|
+
// Backend adapters
|
|
232
|
+
export { AcpEscrowBackend } from "./backends/acp.js";
|
|
233
|
+
export type { EscrowBackend, AgentSearchResult, AgentOffering, JobResult, IncomingJob } from "./backends/types.js";
|
|
234
|
+
|
|
235
|
+
// Universal Discovery (Kompass v2 — cross-protocol)
|
|
236
|
+
export { KompassUnified } from "./unified.js";
|
|
237
|
+
export type { UnifiedConfig, FindOptions, FindResult } from "./unified.js";
|
|
238
|
+
export { Aggregator } from "./aggregator.js";
|
|
239
|
+
export { rankAgents } from "./matching.js";
|
|
240
|
+
export { ProtocolBridge } from "./bridge.js";
|
|
241
|
+
export type { BridgeHireOptions, BridgeHireResult } from "./bridge.js";
|
|
242
|
+
export { CapabilityRouter } from "./router.js";
|
|
243
|
+
export type { DoOptions, DoResult, CapabilityOption, CostPreference } from "./router.js";
|
|
244
|
+
export { createAllSources } from "./sources/index.js";
|
|
245
|
+
export type { UnifiedAgent, AgentSource, AgentProtocol, SourceAdapter } from "./sources/types.js";
|
package/src/intents.ts
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { AgentProfile, PaymentMode } from "./types.js";
|
|
2
|
+
|
|
3
|
+
export type YieldRiskTolerance = "conservative" | "balanced" | "aggressive";
|
|
4
|
+
export type YieldObjective = "best-yield" | "best-risk-adjusted";
|
|
5
|
+
export type AgentCapabilityRole = "research" | "premium-data" | "risk" | "execution";
|
|
6
|
+
|
|
7
|
+
export interface YieldIntent {
|
|
8
|
+
amount: bigint;
|
|
9
|
+
riskTolerance: YieldRiskTolerance;
|
|
10
|
+
objective?: YieldObjective;
|
|
11
|
+
stablecoin?: string;
|
|
12
|
+
chain?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface RouteStep {
|
|
16
|
+
role: AgentCapabilityRole;
|
|
17
|
+
title: string;
|
|
18
|
+
summary: string;
|
|
19
|
+
requiredPaymentMode: PaymentMode | "any";
|
|
20
|
+
categories: string[];
|
|
21
|
+
agent: AgentProfile | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IntentRoute {
|
|
25
|
+
intent: YieldIntent;
|
|
26
|
+
steps: RouteStep[];
|
|
27
|
+
recommendedAgents: AgentProfile[];
|
|
28
|
+
missingCapabilities: AgentCapabilityRole[];
|
|
29
|
+
summary: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ROLE_CONFIG: Record<
|
|
33
|
+
AgentCapabilityRole,
|
|
34
|
+
{
|
|
35
|
+
title: string;
|
|
36
|
+
summary: string;
|
|
37
|
+
categories: string[];
|
|
38
|
+
requiredPaymentMode: PaymentMode | "any";
|
|
39
|
+
preferredType?: AgentProfile["agentType"];
|
|
40
|
+
}
|
|
41
|
+
> = {
|
|
42
|
+
research: {
|
|
43
|
+
title: "Research",
|
|
44
|
+
summary: "Find candidate Base strategies and estimate raw yield.",
|
|
45
|
+
categories: ["defi", "analytics", "research", "yield"],
|
|
46
|
+
requiredPaymentMode: "any",
|
|
47
|
+
preferredType: "provider",
|
|
48
|
+
},
|
|
49
|
+
"premium-data": {
|
|
50
|
+
title: "Premium Data",
|
|
51
|
+
summary: "Buy market, protocol, or yield data over x402.",
|
|
52
|
+
categories: ["data", "analytics", "signals"],
|
|
53
|
+
requiredPaymentMode: "x402",
|
|
54
|
+
preferredType: "provider",
|
|
55
|
+
},
|
|
56
|
+
risk: {
|
|
57
|
+
title: "Risk Review",
|
|
58
|
+
summary: "Evaluate strategy safety, policy fit, and execution readiness.",
|
|
59
|
+
categories: ["risk", "security", "defi"],
|
|
60
|
+
requiredPaymentMode: "any",
|
|
61
|
+
preferredType: "evaluator",
|
|
62
|
+
},
|
|
63
|
+
execution: {
|
|
64
|
+
title: "Execution",
|
|
65
|
+
summary: "Prepare or submit the final Base execution plan.",
|
|
66
|
+
categories: ["yield", "swap", "bridge", "defi"],
|
|
67
|
+
requiredPaymentMode: "escrow",
|
|
68
|
+
preferredType: "provider",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
function parseCategories(value: string): string[] {
|
|
73
|
+
return value
|
|
74
|
+
.split(",")
|
|
75
|
+
.map((item) => item.trim().toLowerCase())
|
|
76
|
+
.filter(Boolean);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function scoreAgent(agent: AgentProfile, role: AgentCapabilityRole): number {
|
|
80
|
+
const config = ROLE_CONFIG[role];
|
|
81
|
+
const categories = parseCategories(agent.categories);
|
|
82
|
+
let score = 0;
|
|
83
|
+
|
|
84
|
+
for (const category of config.categories) {
|
|
85
|
+
if (categories.includes(category)) {
|
|
86
|
+
score += 3;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (config.preferredType && (agent.agentType === config.preferredType || agent.agentType === "both")) {
|
|
91
|
+
score += 3;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (agent.identityVerified) {
|
|
95
|
+
score += 2;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (config.requiredPaymentMode === "x402" && agent.x402Enabled) {
|
|
99
|
+
score += 4;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (config.requiredPaymentMode === "escrow" && (agent.paymentMode === "escrow" || agent.paymentMode === "hybrid")) {
|
|
103
|
+
score += 2;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (agent.paymentMode === "hybrid") {
|
|
107
|
+
score += 1;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return score;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function supportsPaymentMode(agent: AgentProfile, required: PaymentMode | "any"): boolean {
|
|
114
|
+
if (required === "any") return true;
|
|
115
|
+
if (required === "x402") {
|
|
116
|
+
return agent.x402Enabled || agent.paymentMode === "x402" || agent.paymentMode === "hybrid";
|
|
117
|
+
}
|
|
118
|
+
if (required === "escrow") {
|
|
119
|
+
return agent.paymentMode === "escrow" || agent.paymentMode === "hybrid";
|
|
120
|
+
}
|
|
121
|
+
return agent.paymentMode === required;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function selectBestAgent(agents: AgentProfile[], role: AgentCapabilityRole): AgentProfile | null {
|
|
125
|
+
const candidates = agents
|
|
126
|
+
.filter((agent) => supportsPaymentMode(agent, ROLE_CONFIG[role].requiredPaymentMode))
|
|
127
|
+
.map((agent) => ({ agent, score: scoreAgent(agent, role) }))
|
|
128
|
+
.filter((entry) => entry.score > 0)
|
|
129
|
+
.sort((a, b) => b.score - a.score);
|
|
130
|
+
|
|
131
|
+
return candidates[0]?.agent ?? null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function routeYieldIntent(agents: AgentProfile[], intent: YieldIntent): IntentRoute {
|
|
135
|
+
const orderedRoles: AgentCapabilityRole[] = ["research", "premium-data", "risk", "execution"];
|
|
136
|
+
const steps = orderedRoles.map((role) => {
|
|
137
|
+
const config = ROLE_CONFIG[role];
|
|
138
|
+
return {
|
|
139
|
+
role,
|
|
140
|
+
title: config.title,
|
|
141
|
+
summary: config.summary,
|
|
142
|
+
requiredPaymentMode: config.requiredPaymentMode,
|
|
143
|
+
categories: config.categories,
|
|
144
|
+
agent: selectBestAgent(agents, role),
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const missingCapabilities = steps
|
|
149
|
+
.filter((step) => !step.agent)
|
|
150
|
+
.map((step) => step.role);
|
|
151
|
+
|
|
152
|
+
const recommendedAgents = steps
|
|
153
|
+
.map((step) => step.agent)
|
|
154
|
+
.filter((agent): agent is AgentProfile => agent !== null);
|
|
155
|
+
|
|
156
|
+
const stablecoin = intent.stablecoin ?? "USDC";
|
|
157
|
+
const objective = intent.objective ?? "best-risk-adjusted";
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
intent,
|
|
161
|
+
steps,
|
|
162
|
+
recommendedAgents,
|
|
163
|
+
missingCapabilities,
|
|
164
|
+
summary: `Route ${stablecoin} capital on ${intent.chain ?? "Base"} for ${objective} yield using ${recommendedAgents.length} discovered agents.`,
|
|
165
|
+
};
|
|
166
|
+
}
|
package/src/matching.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kompass Multi-Layer Agent Matching
|
|
3
|
+
*
|
|
4
|
+
* Layer A: Structured capability matching (ontology-style)
|
|
5
|
+
* Layer B: BM25 text relevance scoring
|
|
6
|
+
* Layer C: LLM re-ranking (optional, for top candidates)
|
|
7
|
+
* Layer D: Multi-criteria scoring (reputation, price, protocol, recency)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { UnifiedAgent } from "./sources/types.js";
|
|
11
|
+
|
|
12
|
+
// ── Layer A: Structured Capability Matching ──────────────
|
|
13
|
+
|
|
14
|
+
interface ParsedIntent {
|
|
15
|
+
domain: string | null;
|
|
16
|
+
actions: string[];
|
|
17
|
+
protocols: string[];
|
|
18
|
+
chains: string[];
|
|
19
|
+
priceMax: number | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DOMAIN_KEYWORDS: Record<string, string[]> = {
|
|
23
|
+
defi: ["defi", "yield", "swap", "liquidity", "pool", "lending", "borrow", "stake", "vault", "farm"],
|
|
24
|
+
data: ["data", "analytics", "research", "market", "price", "chart", "feed", "api"],
|
|
25
|
+
trading: ["trade", "trading", "buy", "sell", "order", "exchange", "dex", "cex"],
|
|
26
|
+
risk: ["risk", "audit", "security", "vulnerability", "safe", "score"],
|
|
27
|
+
content: ["content", "write", "generate", "image", "video", "text", "create"],
|
|
28
|
+
development: ["code", "develop", "build", "deploy", "smart contract", "solidity"],
|
|
29
|
+
ai: ["ai", "llm", "model", "inference", "embedding", "prompt"],
|
|
30
|
+
social: ["social", "twitter", "post", "tweet", "farcaster"],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const PROTOCOL_KEYWORDS: Record<string, string[]> = {
|
|
34
|
+
x402: ["x402", "micropayment", "http 402", "pay per call"],
|
|
35
|
+
acp: ["acp", "virtuals", "escrow", "marketplace"],
|
|
36
|
+
mcp: ["mcp", "tool", "server", "model context"],
|
|
37
|
+
a2a: ["a2a", "agent to agent", "google"],
|
|
38
|
+
l402: ["l402", "lightning", "bitcoin", "sats"],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const CHAIN_KEYWORDS: Record<string, string[]> = {
|
|
42
|
+
base: ["base", "coinbase"],
|
|
43
|
+
ethereum: ["ethereum", "eth", "mainnet"],
|
|
44
|
+
solana: ["solana", "sol"],
|
|
45
|
+
bnb: ["bnb", "bsc", "binance"],
|
|
46
|
+
arbitrum: ["arbitrum", "arb"],
|
|
47
|
+
polygon: ["polygon", "matic"],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function parseIntent(query: string): ParsedIntent {
|
|
51
|
+
const lower = query.toLowerCase();
|
|
52
|
+
|
|
53
|
+
let domain: string | null = null;
|
|
54
|
+
for (const [d, keywords] of Object.entries(DOMAIN_KEYWORDS)) {
|
|
55
|
+
if (keywords.some((k) => lower.includes(k))) {
|
|
56
|
+
domain = d;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const actions = Object.entries(DOMAIN_KEYWORDS)
|
|
62
|
+
.flatMap(([, keywords]) => keywords.filter((k) => lower.includes(k)));
|
|
63
|
+
|
|
64
|
+
const protocols = Object.entries(PROTOCOL_KEYWORDS)
|
|
65
|
+
.filter(([, keywords]) => keywords.some((k) => lower.includes(k)))
|
|
66
|
+
.map(([p]) => p);
|
|
67
|
+
|
|
68
|
+
const chains = Object.entries(CHAIN_KEYWORDS)
|
|
69
|
+
.filter(([, keywords]) => keywords.some((k) => lower.includes(k)))
|
|
70
|
+
.map(([c]) => c);
|
|
71
|
+
|
|
72
|
+
const priceMatch = lower.match(/under\s*\$?(\d+(?:\.\d+)?)/);
|
|
73
|
+
const priceMax = priceMatch ? parseFloat(priceMatch[1]) : null;
|
|
74
|
+
|
|
75
|
+
return { domain, actions, protocols, chains, priceMax };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function structuredScore(agent: UnifiedAgent, intent: ParsedIntent): number {
|
|
79
|
+
let score = 0;
|
|
80
|
+
|
|
81
|
+
// Domain match
|
|
82
|
+
if (intent.domain && agent.categories.includes(intent.domain)) score += 15;
|
|
83
|
+
|
|
84
|
+
// Action keyword matches
|
|
85
|
+
const agentText = `${agent.name} ${agent.description} ${agent.categories.join(" ")}`.toLowerCase();
|
|
86
|
+
for (const action of intent.actions) {
|
|
87
|
+
if (agentText.includes(action)) score += 3;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Protocol match
|
|
91
|
+
if (intent.protocols.length > 0) {
|
|
92
|
+
if (intent.protocols.includes(agent.protocol)) score += 20;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Price filter
|
|
96
|
+
if (intent.priceMax && agent.pricing?.amount) {
|
|
97
|
+
const price = parseFloat(agent.pricing.amount);
|
|
98
|
+
if (price <= intent.priceMax) score += 10;
|
|
99
|
+
else score -= 10; // Penalize over budget
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return score;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ── Layer B: BM25-lite Text Relevance ────────────────────
|
|
106
|
+
|
|
107
|
+
function bm25Score(agent: UnifiedAgent, queryTerms: string[]): number {
|
|
108
|
+
const doc = `${agent.name} ${agent.description} ${agent.categories.join(" ")} ${agent.capabilities.join(" ")}`.toLowerCase();
|
|
109
|
+
const docTerms = doc.split(/\s+/);
|
|
110
|
+
const docLen = docTerms.length;
|
|
111
|
+
const avgDocLen = 50; // Approximate average
|
|
112
|
+
const k1 = 1.5;
|
|
113
|
+
const b = 0.75;
|
|
114
|
+
|
|
115
|
+
let score = 0;
|
|
116
|
+
for (const term of queryTerms) {
|
|
117
|
+
const tf = docTerms.filter((t) => t.includes(term)).length;
|
|
118
|
+
if (tf === 0) continue;
|
|
119
|
+
|
|
120
|
+
// Simplified BM25
|
|
121
|
+
const numerator = tf * (k1 + 1);
|
|
122
|
+
const denominator = tf + k1 * (1 - b + b * (docLen / avgDocLen));
|
|
123
|
+
score += numerator / denominator;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return score * 10; // Scale up
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ── Layer D: Multi-Criteria Scoring ──────────────────────
|
|
130
|
+
|
|
131
|
+
function multiCriteriaScore(agent: UnifiedAgent): number {
|
|
132
|
+
let score = 0;
|
|
133
|
+
|
|
134
|
+
// Reputation
|
|
135
|
+
if (agent.reputation) {
|
|
136
|
+
score += Math.min(agent.reputation.score * 0.2, 20);
|
|
137
|
+
score += Math.min(agent.reputation.count * 0.5, 10);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Verified identity
|
|
141
|
+
if (agent.verified) score += 5;
|
|
142
|
+
|
|
143
|
+
// Pricing transparency
|
|
144
|
+
if (agent.pricing && agent.pricing.model !== "unknown") score += 3;
|
|
145
|
+
|
|
146
|
+
// Endpoint richness (more protocols = more interoperable)
|
|
147
|
+
const endpointCount = Object.values(agent.endpoints).filter(Boolean).length;
|
|
148
|
+
score += endpointCount * 2;
|
|
149
|
+
|
|
150
|
+
// Recency
|
|
151
|
+
if (agent.lastSeen) {
|
|
152
|
+
const hoursSince = (Date.now() - agent.lastSeen) / (1000 * 60 * 60);
|
|
153
|
+
if (hoursSince < 1) score += 5;
|
|
154
|
+
else if (hoursSince < 24) score += 3;
|
|
155
|
+
else if (hoursSince < 168) score += 1;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return score;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ── Combined Ranking Pipeline ────────────────────────────
|
|
162
|
+
|
|
163
|
+
export interface MatchResult {
|
|
164
|
+
agent: UnifiedAgent;
|
|
165
|
+
scores: {
|
|
166
|
+
structured: number;
|
|
167
|
+
bm25: number;
|
|
168
|
+
multiCriteria: number;
|
|
169
|
+
total: number;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function rankAgents(agents: UnifiedAgent[], query: string): MatchResult[] {
|
|
174
|
+
const intent = parseIntent(query);
|
|
175
|
+
const queryTerms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 2);
|
|
176
|
+
|
|
177
|
+
return agents
|
|
178
|
+
.map((agent) => {
|
|
179
|
+
const structured = structuredScore(agent, intent);
|
|
180
|
+
const bm25 = bm25Score(agent, queryTerms);
|
|
181
|
+
const multi = multiCriteriaScore(agent);
|
|
182
|
+
const total = structured + bm25 + multi;
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
agent,
|
|
186
|
+
scores: { structured, bm25, multiCriteria: multi, total },
|
|
187
|
+
};
|
|
188
|
+
})
|
|
189
|
+
.sort((a, b) => b.scores.total - a.scores.total);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export { parseIntent, type ParsedIntent };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export const PipelineOrchestratorAbi = [
|
|
2
|
+
{
|
|
3
|
+
type: "event",
|
|
4
|
+
name: "PipelineCreated",
|
|
5
|
+
anonymous: false,
|
|
6
|
+
inputs: [
|
|
7
|
+
{ indexed: true, name: "pipelineId", type: "uint256" },
|
|
8
|
+
{ indexed: true, name: "client", type: "address" },
|
|
9
|
+
{ indexed: false, name: "intentHash", type: "bytes32" },
|
|
10
|
+
],
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
type: "function",
|
|
14
|
+
name: "createPipeline",
|
|
15
|
+
stateMutability: "nonpayable",
|
|
16
|
+
inputs: [
|
|
17
|
+
{ name: "token", type: "address" },
|
|
18
|
+
{ name: "intentHash", type: "bytes32" },
|
|
19
|
+
],
|
|
20
|
+
outputs: [{ name: "pipelineId", type: "uint256" }],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: "function",
|
|
24
|
+
name: "createPipelineWithHook",
|
|
25
|
+
stateMutability: "nonpayable",
|
|
26
|
+
inputs: [
|
|
27
|
+
{ name: "token", type: "address" },
|
|
28
|
+
{ name: "intentHash", type: "bytes32" },
|
|
29
|
+
{ name: "defaultHook", type: "address" },
|
|
30
|
+
],
|
|
31
|
+
outputs: [{ name: "pipelineId", type: "uint256" }],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: "function",
|
|
35
|
+
name: "addSubTask",
|
|
36
|
+
stateMutability: "nonpayable",
|
|
37
|
+
inputs: [
|
|
38
|
+
{ name: "pipelineId", type: "uint256" },
|
|
39
|
+
{ name: "provider", type: "address" },
|
|
40
|
+
{ name: "evaluator", type: "address" },
|
|
41
|
+
{ name: "budget", type: "uint256" },
|
|
42
|
+
{ name: "descriptionHash", type: "bytes32" },
|
|
43
|
+
{ name: "dependencies", type: "uint256[]" },
|
|
44
|
+
],
|
|
45
|
+
outputs: [{ name: "subTaskIndex", type: "uint256" }],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: "function",
|
|
49
|
+
name: "fundPipeline",
|
|
50
|
+
stateMutability: "nonpayable",
|
|
51
|
+
inputs: [{ name: "pipelineId", type: "uint256" }],
|
|
52
|
+
outputs: [],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "function",
|
|
56
|
+
name: "activateNextTasks",
|
|
57
|
+
stateMutability: "nonpayable",
|
|
58
|
+
inputs: [{ name: "pipelineId", type: "uint256" }],
|
|
59
|
+
outputs: [],
|
|
60
|
+
},
|
|
61
|
+
] as const;
|
|
62
|
+
|
|
63
|
+
export const Erc20ApproveAbi = [
|
|
64
|
+
{
|
|
65
|
+
type: "function",
|
|
66
|
+
name: "approve",
|
|
67
|
+
stateMutability: "nonpayable",
|
|
68
|
+
inputs: [
|
|
69
|
+
{ name: "spender", type: "address" },
|
|
70
|
+
{ name: "value", type: "uint256" },
|
|
71
|
+
],
|
|
72
|
+
outputs: [{ name: "", type: "bool" }],
|
|
73
|
+
},
|
|
74
|
+
] as const;
|