kompass-sdk 0.19.0 → 0.21.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,11 +1,11 @@
1
1
  /**
2
2
  * Olas Mech Marketplace Source Adapter
3
3
  * Queries the Olas marketplace subgraph (The Graph) to discover AI agent mechs.
4
- * Mechs are autonomous agents that accept prompts and return deliverables.
5
- * Supports Gnosis, Base, Polygon, Optimism chains.
4
+ * Mechs are autonomous agents that accept on-chain requests and return deliverables.
5
+ * Interaction is on-chain via the mech-client CLI or Python SDK — no HTTP API.
6
6
  *
7
7
  * Subgraph: https://api.subgraph.autonolas.tech/api/proxy/marketplace-{chain}
8
- * Docs: https://docs.olas.network
8
+ * Docs: https://docs.olas.network/mech-client/
9
9
  */
10
10
 
11
11
  import type { SourceAdapter, UnifiedAgent, SourceSearchOptions } from "./types.js";
@@ -15,43 +15,49 @@ const SUBGRAPH_URLS: Record<string, string> = {
15
15
  base: "https://api.subgraph.autonolas.tech/api/proxy/marketplace-base",
16
16
  };
17
17
 
18
- const MECH_AGENTS_QUERY = `{
19
- mechAgents(first: 50, orderBy: totalTransactions, orderDirection: desc) {
18
+ // Query the correct "meches" entity with real fields from the subgraph schema
19
+ const MECHES_QUERY = `{
20
+ meches(first: 50, orderBy: receivedRequests, orderDirection: desc) {
20
21
  id
21
22
  address
22
- agentHash
23
- totalTransactions
24
- service {
25
- serviceId
26
- totalRequests
27
- totalDeliveries
28
- }
23
+ configHash
24
+ owner
25
+ receivedRequests
26
+ totalDeliveriesTransactions
27
+ selfDeliveredFromReceived
28
+ deliveredByOthersFromReceived
29
+ karma
30
+ maxDeliveryRate
31
+ paymentType
29
32
  }
30
33
  }`;
31
34
 
32
- interface MechAgent {
35
+ interface MechData {
33
36
  id: string;
34
37
  address: string;
35
- agentHash: string;
36
- totalTransactions: string;
37
- service?: {
38
- serviceId: string;
39
- totalRequests: string;
40
- totalDeliveries: string;
41
- };
38
+ configHash: string;
39
+ owner: string;
40
+ receivedRequests: string;
41
+ totalDeliveriesTransactions: string;
42
+ selfDeliveredFromReceived: string;
43
+ deliveredByOthersFromReceived: string;
44
+ karma: string;
45
+ maxDeliveryRate: string | null;
46
+ paymentType: string;
47
+ _chain?: string;
42
48
  }
43
49
 
44
50
  // Cache mechs — refresh every 10 minutes
45
- let mechCache: MechAgent[] | null = null;
51
+ let mechCache: MechData[] | null = null;
46
52
  let cacheTime = 0;
47
53
  const CACHE_TTL = 10 * 60 * 1000;
48
54
 
49
- async function fetchMechs(timeout: number): Promise<MechAgent[]> {
55
+ async function fetchMechs(timeout: number): Promise<MechData[]> {
50
56
  if (mechCache && Date.now() - cacheTime < CACHE_TTL) {
51
57
  return mechCache;
52
58
  }
53
59
 
54
- const allMechs: MechAgent[] = [];
60
+ const allMechs: MechData[] = [];
55
61
 
56
62
  // Query both Gnosis and Base subgraphs
57
63
  for (const [chain, url] of Object.entries(SUBGRAPH_URLS)) {
@@ -59,17 +65,17 @@ async function fetchMechs(timeout: number): Promise<MechAgent[]> {
59
65
  const res = await fetch(url, {
60
66
  method: "POST",
61
67
  headers: { "Content-Type": "application/json" },
62
- body: JSON.stringify({ query: MECH_AGENTS_QUERY }),
68
+ body: JSON.stringify({ query: MECHES_QUERY }),
63
69
  signal: AbortSignal.timeout(timeout),
64
70
  });
65
71
 
66
72
  if (!res.ok) continue;
67
73
 
68
74
  const json = await res.json();
69
- const agents = json.data?.mechAgents ?? [];
75
+ const mechs = json.data?.meches ?? [];
70
76
 
71
- for (const agent of agents) {
72
- allMechs.push({ ...agent, _chain: chain } as any);
77
+ for (const mech of mechs) {
78
+ allMechs.push({ ...mech, _chain: chain });
73
79
  }
74
80
  } catch {
75
81
  // Chain subgraph unavailable, continue with others
@@ -98,7 +104,6 @@ export const olasAdapter: SourceAdapter = {
98
104
  if (!query) return mechs.slice(0, limit).map(mapMech);
99
105
 
100
106
  // Score mechs by transaction volume and filter by relevance
101
- // Since mechs don't have descriptions, match against known tool categories
102
107
  const lower = query.toLowerCase();
103
108
  const relevant = mechs.filter(() => {
104
109
  // Olas mechs handle: predictions, research, analysis, trading signals
@@ -107,7 +112,7 @@ export const olasAdapter: SourceAdapter = {
107
112
  });
108
113
 
109
114
  return relevant
110
- .sort((a, b) => parseInt(b.totalTransactions) - parseInt(a.totalTransactions))
115
+ .sort((a, b) => parseInt(b.receivedRequests) - parseInt(a.receivedRequests))
111
116
  .slice(0, limit)
112
117
  .map(mapMech);
113
118
  } catch {
@@ -120,7 +125,7 @@ export const olasAdapter: SourceAdapter = {
120
125
  const res = await fetch(SUBGRAPH_URLS.gnosis, {
121
126
  method: "POST",
122
127
  headers: { "Content-Type": "application/json" },
123
- body: JSON.stringify({ query: "{ global(id: \"global\") { totalMechs } }" }),
128
+ body: JSON.stringify({ query: "{ globals(first: 1) { id } }" }),
124
129
  signal: AbortSignal.timeout(5000),
125
130
  });
126
131
  return res.ok;
@@ -130,18 +135,20 @@ export const olasAdapter: SourceAdapter = {
130
135
  },
131
136
  };
132
137
 
133
- function mapMech(mech: MechAgent): UnifiedAgent {
134
- const chain = (mech as any)._chain || "gnosis";
135
- const txCount = parseInt(mech.totalTransactions) || 0;
136
- const deliveries = parseInt(mech.service?.totalDeliveries || "0");
137
- const requests = parseInt(mech.service?.totalRequests || "0");
138
- const successRate = requests > 0 ? Math.round((deliveries / requests) * 100) : 0;
138
+ function mapMech(mech: MechData): UnifiedAgent {
139
+ const chain = mech._chain || "gnosis";
140
+ const requests = parseInt(mech.receivedRequests) || 0;
141
+ const totalDeliveries = parseInt(mech.totalDeliveriesTransactions) || 0;
142
+ const selfDelivered = parseInt(mech.selfDeliveredFromReceived) || 0;
143
+ const othersDelivered = parseInt(mech.deliveredByOthersFromReceived) || 0;
144
+ const karma = parseInt(mech.karma) || 0;
145
+ const successRate = requests > 0 ? Math.round(((selfDelivered + othersDelivered) / requests) * 100) : 0;
139
146
 
140
147
  return {
141
148
  id: `olas:${chain}:${mech.address}`,
142
149
  nativeId: mech.address,
143
150
  name: `Olas Mech ${mech.address.slice(0, 8)}...${mech.address.slice(-4)}`,
144
- description: `Autonomous AI agent on Olas Marketplace (${chain}). ${txCount} transactions, ${deliveries} deliveries. Accepts prompts and returns AI-powered results via on-chain requests.`,
151
+ description: `Autonomous AI mech on Olas Marketplace (${chain}). ${requests} requests, ${totalDeliveries} deliveries, karma: ${karma}. Accepts on-chain requests via mech-client.`,
145
152
  categories: ["ai", "autonomous", "prediction"],
146
153
  capabilities: [
147
154
  "AI prompt execution",
@@ -150,22 +157,24 @@ function mapMech(mech: MechAgent): UnifiedAgent {
150
157
  "On-chain autonomous operation",
151
158
  ],
152
159
  source: "olas" as any,
153
- protocol: "http",
160
+ // Olas mechs are on-chain only — no HTTP API
161
+ protocol: "onchain",
154
162
  endpoints: {
155
- http: `https://mech.tech/mech/${mech.address}`,
163
+ // No HTTP endpoint — interaction is on-chain via mech-client
164
+ http: undefined,
156
165
  },
157
166
  reputation: {
158
167
  score: successRate,
159
- count: deliveries,
168
+ count: totalDeliveries,
160
169
  source: `olas-${chain}`,
161
170
  },
162
171
  pricing: {
163
172
  model: "per-call",
164
- amount: "0.01",
165
- currency: "OLAS",
173
+ amount: mech.maxDeliveryRate ? (parseInt(mech.maxDeliveryRate) / 1e18).toFixed(6) : "0.01",
174
+ currency: "xDAI",
166
175
  },
167
- verified: txCount > 10,
168
- lastSeen: txCount > 0 ? Date.now() : undefined,
176
+ verified: requests > 10,
177
+ lastSeen: requests > 0 ? Date.now() : undefined,
169
178
  raw: mech,
170
179
  };
171
180
  }
@@ -75,22 +75,24 @@ export async function handleBankrPayment(
75
75
  const pollData = await pollRes.json();
76
76
  const status = pollData.status?.toLowerCase();
77
77
 
78
- if (status === "completed" || status === "done" || status === "success") {
78
+ if (status === "completed") {
79
79
  return {
80
80
  success: true,
81
- deliverable: pollData.result ?? pollData.response ?? pollData,
81
+ deliverable: pollData.response ?? pollData.result ?? pollData,
82
82
  jobId,
83
83
  };
84
84
  }
85
85
 
86
- if (status === "failed" || status === "error") {
86
+ if (status === "failed" || status === "cancelled") {
87
87
  return {
88
88
  success: false,
89
- deliverable: { error: pollData.error ?? "Job failed", details: pollData },
89
+ deliverable: { error: pollData.error ?? `Job ${status}`, details: pollData },
90
90
  jobId,
91
91
  };
92
92
  }
93
93
 
94
+ // "pending" or "processing" — continue polling
95
+
94
96
  // Still pending, continue polling
95
97
  }
96
98
 
@@ -124,9 +124,10 @@ export async function handleLocusPayment(
124
124
  }
125
125
 
126
126
  const result = await callRes.json();
127
+ // Locus wraps responses in { success: true, data: {...} }
127
128
  return {
128
- success: true,
129
- deliverable: result,
129
+ success: result.success ?? true,
130
+ deliverable: result.data ?? result,
130
131
  };
131
132
  }
132
133
 
@@ -1,6 +1,10 @@
1
1
  /**
2
2
  * Olas Mech Handler
3
- * Sends requests to Olas autonomous mechs via their HTTP endpoint
3
+ * Olas mechs are on-chain agents — requests and deliveries happen via smart contracts.
4
+ * There is no HTTP API. Interaction requires the mech-client CLI/Python SDK
5
+ * or direct on-chain transactions.
6
+ *
7
+ * Docs: https://docs.olas.network/mech-client/
4
8
  */
5
9
  import type { KompassWallet } from "../index.js";
6
10
  import type { UnifiedAgent } from "../../sources/types.js";
@@ -10,34 +14,25 @@ export async function handleOlasPayment(
10
14
  agent: UnifiedAgent,
11
15
  task: string,
12
16
  ): Promise<{ success: boolean; deliverable?: unknown; jobId?: string }> {
13
- const endpoint = agent.endpoints.http;
14
- if (!endpoint) {
15
- return { success: false, deliverable: { error: "No Olas mech endpoint" } };
16
- }
17
+ // Olas mechs require on-chain interaction via the Mech Marketplace contract.
18
+ // Direct HTTP calls are not supported — the mech-client discovers the off-chain URL
19
+ // from on-chain metadata and handles the full request/delivery lifecycle.
20
+ const mechAddress = agent.nativeId;
21
+ const chain = (agent.raw as any)?._chain ?? "gnosis";
17
22
 
18
- try {
19
- // Olas mechs accept POST requests with prompt
20
- const res = await fetch(endpoint, {
21
- method: "POST",
22
- headers: { "Content-Type": "application/json" },
23
- body: JSON.stringify({
24
- prompt: task,
25
- tool: "openai-gpt-4", // Default tool
26
- }),
27
- signal: AbortSignal.timeout(30000),
28
- });
29
-
30
- if (!res.ok) {
31
- const err = await res.text().catch(() => "");
32
- return { success: false, deliverable: { error: `Olas mech error: ${res.status}`, details: err } };
33
- }
34
-
35
- const data = await res.json();
36
- return { success: true, deliverable: data };
37
- } catch (err) {
38
- return {
39
- success: false,
40
- deliverable: { error: err instanceof Error ? err.message : String(err) },
41
- };
42
- }
23
+ return {
24
+ success: false,
25
+ deliverable: {
26
+ error: "Olas mechs require on-chain interaction",
27
+ mechAddress,
28
+ chain,
29
+ hint: "Install mech-client: pip install mech-client. Then use: mechx request --prompts '<prompt>' --tools openai-gpt-4 --chain-config <chain>",
30
+ docsUrl: "https://docs.olas.network/mech-client/",
31
+ subgraphData: {
32
+ requests: (agent.raw as any)?.receivedRequests,
33
+ deliveries: (agent.raw as any)?.totalDeliveriesTransactions,
34
+ karma: (agent.raw as any)?.karma,
35
+ },
36
+ },
37
+ };
43
38
  }