interact-agent
Skill15 starsChanged 57 days agoMITView on GitHub
- Category: agentic-id - SDK: @0gfoundation/0g-agenticid-sdk ^0.1.6, viem ^2.21.0 - Activation Triggers: "call an agent", "chat with an agent", "talk to my agent", "agent endpoints", "agent services", "agent logs" Call a deployed AgenticID agent: discover what it exposes, chat with it as its owner, invoke its signed /api/* services, and read its logs. The SDK resolves the agent's URL from chain, so an agentId is enough. This layer uses viem, not ethers. The repo-wide ethers rule does not apply to…
- Reads credentials
- Sends data out
In this repository26 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-accountsSkill
- agent-reputationSkill
- deploy-agentSkill
- manage-agentSkill
- deploy-contractSkill
- interact-contractSkill
- scaffold-projectSkill
- account-managementSkill
- embeddingsSkill
- fine-tuningSkill
- image-editingSkill
- provider-discoverySkill
- speech-to-textSkill
- streaming-chatSkill
- text-to-imageSkill
- video-generationSkill
- compute-plus-storageSkill
- storage-plus-chainSkill
- 0g-pc-setupSkill
- 0g-pc-switch-modelSkill
- 0g-pc-uninstallSkill
- download-fileSkill
- merkle-verificationSkill
- upload-fileSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 0 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 12
Call a deployed AgenticID agent: discover what it exposes, chat with it as its owner, invoke its signed /api/* services, and read its logs.
- Very specific: line 26
Only /api/* services carry X-Agent-Proof.
- Very specific: line 42
Call it: fetchWithProof() for services, chat() for chat routes
- Very specific: line 48
Use fetchWithProof() on /api/* services when you intend to leave feedback afterwards
- Very specific: line 49
Check agent.chat and agent.logs exist before calling them.
- Very specific: line 51
Read agent.services / agent.routes rather than guessing paths
- Very specific: line 52
Use connect() when you explicitly want a public handle with no token attached
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Interact with a Running AgenticID Agent
Metadata
- Category: agentic-id
- SDK:
@0gfoundation/0g-agenticid-sdk^0.1.6,viem^2.21.0 - Activation Triggers: "call an agent", "chat with an agent", "talk to my agent", "agent endpoints", "agent services", "agent logs"
Purpose
Call a deployed AgenticID agent: discover what it exposes, chat with it as its owner, invoke its
signed /api/* services, and read its logs. The SDK resolves the agent's URL from chain, so an
agentId is enough.
This layer uses
viem, notethers. The repo-wide ethers rule does not apply toagentic-idskills.
Two kinds of surface, and the difference matters
| Surface | Shape | Signed with a serve-proof? | Who can call it |
services | /api/* | yes | anyone (attributable) |
routes | framework prefixes, e.g. /v1/ | no | owner-authenticated |
Only /api/* services carry X-Agent-Proof. Chat and UI routes deliberately do not: signing an
owner-authenticated channel would let an owner manufacture their own reputation. If you need a proof
to leave feedback, call a service, not chat.
Prerequisites
- Node.js >= 20
@0gfoundation/0g-agenticid-sdkandvieminstalled- An agent in phase
running - A wallet only for owner-scoped calls (
chat,chatStream,logs); public calls need none
Quick Workflow
- Build the client; pass
accountonly if you need owner-scoped calls client(agentId)to get a handle, orconnect(agentId)to force a public one- Inspect
agent.servicesandagent.routesto see what exists - Call it:
fetchWithProof()for services,chat()for chat routes
Core Rules
ALWAYS
- Use
fetchWithProof()on/api/*services when you intend to leave feedback afterwards - Check
agent.chatandagent.logsexist before calling them; they are present only with an owner key and a declared route - Read
agent.services/agent.routesrather than guessing paths - Use
connect()when you explicitly want a public handle with no token attached - Remember
modelonchat()is the framework's selector, not an LLM name; the LLM is fixed at deploy time
NEVER
- Expect a serve-proof from a chat or UI route;
proofcomes backnull - Assume
chatis available on a handle built without an owner key - Hardcode the agent URL when an
agentIdwill resolve it - Pass an LLM model name to
chat()'smodeloption - Hardcode a private key
Code Examples
Discover what an agent exposes
sayHi() needs only the URL and no wallet.
import { AgenticID } from '@0gfoundation/0g-agenticid-sdk';
import 'dotenv/config';
async function discover(agentId: bigint) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai');
// connect() is the explicit PUBLIC handle: never attaches a token.
const agent = await ag.agent.connect(agentId);
console.log('signed services (attributable, /api/*):');
for (const s of agent.services) {
console.log(` ${s.method} ${s.path} ${s.description ?? ''}`);
}
console.log('framework routes (chat/UI, unsigned):');
for (const r of agent.routes) {
console.log(` ${r.prefix} kind=${r.kind ?? '?'} auth=${r.auth ?? 'none'} signed=${r.signed}`);
}
return { services: agent.services, routes: agent.routes };
}Or straight from a URL, without touching chain:
async function greet(agentUrl: string) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai');
const { hello, verification } = await ag.agent.sayHi(agentUrl);
console.log(hello.agent, hello.owner, hello.message);
console.log('verification:', JSON.stringify(verification));
return hello;
}Call a signed service and keep the proof
This is the call that produces a redeemable serve-proof.
async function summarize(agentId: bigint, text: string) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai');
const agent = await ag.agent.connect(agentId);
const { response, proof } = await agent.fetchWithProof('/api/summarize', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ q: text }),
});
const body = await response.json();
// proof is null when the route is not a signed /api/* service.
if (proof) {
console.log(`proof for agent ${proof.agentId}, redeemable by ${proof.submitter}`);
}
return { body, proof };
}Chat as the owner
chat and chatStream appear on the handle only when the client holds the owner key and the
agent declares a chat route.
async function chat(agentId: bigint, message: string) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai', {
account: process.env.PRIVATE_KEY as `0x${string}`,
});
const agent = await ag.agent.client(agentId);
if (!agent.chat) {
console.log('no chat route, or this handle is not the owner');
return null;
}
// `model` selects the FRAMEWORK, not an LLM. openclaw wants "openclaw".
const { choices } = await agent.chat([{ role: 'user', content: message }], {
model: 'openclaw',
});
return choices[0]?.message?.content;
}Streaming yields content deltas:
async function streamChat(agentId: bigint, message: string) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai', {
account: process.env.PRIVATE_KEY as `0x${string}`,
});
const agent = await ag.agent.client(agentId);
if (!agent.chatStream) return;
for await (const delta of agent.chatStream([{ role: 'user', content: message }], {
model: 'openclaw',
})) {
process.stdout.write(delta);
}
}Plain fetch, and owner-only logs
async function inspect(agentId: bigint) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai', {
account: process.env.PRIVATE_KEY as `0x${string}`,
});
const agent = await ag.agent.client(agentId);
// fetch() attaches the bearer token when the route asks for auth.
const models = await agent.fetch('/v1/models');
console.log(await models.json());
// logs() is owner-only, so it may be absent.
if (agent.logs) {
console.log(await agent.logs({ tail: 200 }));
}
}Choosing a handle
async function handles(agentId: bigint) {
const ag = await AgenticID.fromAttestor('https://agenticid.0g.ai', {
account: process.env.PRIVATE_KEY as `0x${string}`,
});
// client(): owner ops present when the key matches; accepts an id OR a url
const auto = await ag.agent.client(agentId);
// authenticate(): mint the owner token up front; fails without a wallet
const owner = await ag.agent.authenticate(agentId);
// connect(): explicitly public, never attaches a token
const publicHandle = await ag.agent.connect(agentId);
return { auto, owner, publicHandle };
}Anti-Patterns
// BAD: expecting a proof from a chat route — chat is deliberately unsigned
const agent = await ag.agent.client(agentId);
const { proof } = await agent.fetchWithProof('/v1/chat/completions', { method: 'POST' });
// proof === null; call an /api/* service instead
// BAD: calling chat() without checking it exists
await agent.chat!([{ role: 'user', content: 'hi' }]); // undefined on a public handle
// BAD: passing an LLM name as the framework selector
await agent.chat(msgs, { model: 'claude-opus-5' }); // the LLM is fixed at deploy
// BAD: hardcoding the URL when the id resolves it
await fetch('https://8080-abc.art.0g.ai/api/summarize', { method: 'POST' });
// BAD: guessing paths instead of reading the manifest
await agent.fetch('/api/summarise'); // check agent.services for the real spellingCommon Errors & Fixes
| Error | Cause | Fix |
proof is null | Route is not a signed /api/* service | Call a service from agent.services |
agent.chat is undefined | Public handle, or no chat route declared | Build with account; check agent.routes |
agent.logs is undefined | Not the owner | Owner key required |
| 404 on a path you expected | Path guessed rather than read | Enumerate agent.services / agent.routes |
| Agent unreachable | Phase is not running | start(sealId, …), then waitForRunning() |
| Chat rejects the model | Passed an LLM name, not the framework's | Use the framework selector, e.g. "openclaw" |
Related Skills
- Agent Reputation — redeem the proof this skill captures
- Manage Agent — get an agent into
running - Deploy Agent — mint and provision
- Agent Accounts — keep the runtime funded
References
- patterns/AGENTIC_ID.md
- SDK reference
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

