{"id":21543,"date":"2026-06-19T05:04:33","date_gmt":"2026-06-19T03:04:33","guid":{"rendered":"https:\/\/www.juust.org\/?p=21543"},"modified":"2026-06-19T05:04:37","modified_gmt":"2026-06-19T03:04:37","slug":"agentanycast-p2p-for-hermes-agent-on-wsl-windows","status":"publish","type":"post","link":"https:\/\/www.juust.org\/index.php\/agentanycast-p2p-for-hermes-agent-on-wsl-windows\/2026\/06\/","title":{"rendered":"AgentAnyCast P2P for Hermes Agent on WSL (Windows)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I wanted to give my Hermes Agent P2P capabilities, and develop a peer discovery server like SoulSeek. Nice side project for this week. I let Hermes install most of it itself, and then asked it to write down what it encountered, maybe it is of some help to others ?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/agentanycast.io\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/agentanycast.io\/\" rel=\"noreferrer noopener\">AgentAnyCast<\/a> is a P2P agent networking library built on top of libp2p and NATS for AI agents. <strong>There is currently no native Windows binary.<\/strong> The daemon (<code>agentanycastd<\/code>) only runs on Linux, which means <strong>WSL is required<\/strong> when running AgentAnyCast on Windows. This (first attempt at a) guide covers both the installation process and the pitfalls encountered during real-world deployment.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Preparing the WSL Environment<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Run from Windows Terminal or Git Bash\nwsl -d Ubuntu -u root -- apt-get install -y -qq python3-venv sshpass\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #1: MSYS2 Path Translation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Git Bash automatically translates paths such as <code>\/opt<\/code> into Windows paths like:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\Program Files\\Git\\opt\\\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To prevent this behavior, always use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export MSYS2_ARG_CONV_EXCL=\"*\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Or prefix individual commands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MSYS2_ARG_CONV_EXCL=\"*\" wsl -d Ubuntu -u root -- &lt;command&gt;\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Without this environment variable, absolute Linux paths passed to WSL may break unexpectedly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Installing the AgentAnyCast SDK<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code># Create a virtual environment\n# Avoid using \/mnt\/c\/, as filesystem performance is significantly slower there.\nwsl -d Ubuntu -u root -- python3 -m venv \/opt\/agentanycast-venv\n\n# Install the SDK\nwsl -d Ubuntu -u root -- \/opt\/agentanycast-venv\/bin\/pip install agentanycast\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The SDK automatically downloads the appropriate Linux version of <code>agentanycastd<\/code> the first time a <code>Node()<\/code> instance is created.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Verify Installation<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>wsl -d Ubuntu -u root -- \/opt\/agentanycast-venv\/bin\/agentanycast --version\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>agentanycast, version 0.7.3 (SDK)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">At the time of writing, the bundled daemon binary is version <strong>0.7.2<\/strong>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Starting Your First Node<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Note : about RELAY :<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">relay multiaddress format: \/ip4\/\/tcp\/\/p2p\/<br \/>The Peer ID comes from the relay logs at startup: &#8220;peer_id&#8221;:&#8221;12D3KooW\u2026&#8221;<br \/>Find it with : <strong>curl -s http:\/(peer discovery server)\/:8081\/api\/v1\/agents | head<\/strong><br \/><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RELAY = &#8220;\/ip4\/<strong>(peer discovery server)<\/strong>\/tcp\/4001\/p2p\/12D3KooWxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Minimal working example (<code>my_agent.py<\/code>):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/opt\/agentanycast-venv\/bin\/python3\nimport asyncio\nimport json\nfrom agentanycast import Node, AgentCard, Skill\n\nRELAY = \"\/ip4\/144.172.102.63\/tcp\/4001\/p2p\/12D3KooWGMySnMqYHGxihHKJ68FgzGu87HknV8XTa7VNfcJftkNU\"\n\ncard = AgentCard(\n    name=\"MyAgent\",\n    description=\"My first agent\",\n    skills=&#91;Skill(id=\"echo\", description=\"Echo input\")]\n)\n\nasync def main():\n    async with Node(card=card, relay=RELAY, home=\"\/tmp\/my-agent\") as node:\n        print(json.dumps({\"peer_id\": node.peer_id}))\n\n        @node.on_task\n        async def handle(task):\n            text = task.messages&#91;-1].parts&#91;0].text\n            print(f\"GOT: {text}\")\n\n            await task.update_status(\"working\")  # REQUIRED\n\n            await task.complete(\n                artifacts=&#91;\n                    {\n                        \"parts\": &#91;\n                            {\"text\": f\"ECHO: {text}\"}\n                        ]\n                    }\n                ]\n            )\n\n        stop = asyncio.Event()\n        await stop.wait()\n\nasyncio.run(main())\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #2: <code>update_status(\"working\")<\/code> Is Mandatory<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Calling <code>complete()<\/code> directly produces:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FAILED_PRECONDITION: invalid transition: SUBMITTED -&gt; COMPLETED\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The daemon enforces the following state transition:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SUBMITTED \u2192 WORKING \u2192 COMPLETED\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Always call:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>await task.update_status(\"working\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">before:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>await task.complete(...)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Running Nodes in the Background<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Avoid shell tricks such as <code>&amp;<\/code> or <code>nohup<\/code>. Hermes&#8217; <code>terminal()<\/code> helper already supports background execution:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>from hermes_tools import terminal\n\nterminal(\n    command='MSYS2_ARG_CONV_EXCL=\"*\" wsl -d Ubuntu -u root -- \/opt\/agentanycast-venv\/bin\/python3 \/\/mnt\/c\/nous\/my_agent.py',\n    background=True,\n    notify_on_complete=True,\n    timeout=300\n)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #3: Missing Stdout When Running WSL in the Background<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Background WSL processes do not always expose stdout through the process tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A more reliable approach is to write the peer ID to a file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>with open(\"\/tmp\/my-agent\/peer_id.json\", \"w\") as f:\n    json.dump({\"peer_id\": node.peer_id}, f)\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Each Node Has Its Own Daemon<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Every unique <code>home=<\/code> directory receives its own:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Daemon binary (<code>bin\/agentanycastd<\/code>)<\/li>\n\n\n\n<li>Ed25519 keypair (<code>key<\/code>)<\/li>\n\n\n\n<li>gRPC Unix socket (<code>daemon.sock<\/code>)<\/li>\n\n\n\n<li>Peer ID (derived from the key)<\/li>\n\n\n\n<li>Datastore (<code>data\/<\/code>)<\/li>\n\n\n\n<li>Logs (<code>logs\/<\/code>)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/tmp\/my-agent\/\n\u251c\u2500\u2500 bin\/agentanycastd\n\u251c\u2500\u2500 key\n\u251c\u2500\u2500 daemon.sock\n\u251c\u2500\u2500 data\/\n\u2514\u2500\u2500 logs\/\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Important<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If the daemon is killed, the socket file often remains behind.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The SDK then attempts to connect to a dead socket and fails with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>DaemonConnectionError: failed to connect to all addresses\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fix:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rm \/tmp\/my-agent\/daemon.sock\nrm -rf \/tmp\/my-agent\/data\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Alternatively, create a new <code>home=<\/code> directory.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #4: The Socket Survives a Kill<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A <code>kill -9<\/code> terminates the daemon but leaves <code>daemon.sock<\/code> behind.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The SDK assumes the daemon is still alive and reconnect attempts fail until the socket is removed manually.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Node-to-Node Communication with <code>send_task()<\/code><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>task = await node.send_task(\n    peer_id=\"12D3KooW...\",\n    message={\n        \"role\": \"user\",\n        \"parts\": &#91;\n            {\"text\": \"Hello\"}\n        ]\n    }\n)\n\nresult = await task.wait(timeout=30)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tasks are delivered peer-to-peer through libp2p.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The receiving daemon logs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>incoming task registered\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #5: Task Reaches the Daemon but Not the Python Handler<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The daemon successfully receives the task but does not forward it to the Python <code>on_task<\/code> handler unless the gRPC subscription (<code>serve_forever()<\/code>) is actively running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In practice, this currently works reliably when:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Client and server run inside the same Python process, or<\/li>\n\n\n\n<li>Both nodes are connected through the same daemon\/bridge setup.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Cross-daemon task delivery appears to have a routing issue in version 0.7.2.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #6: Empty Artifacts After <code>task.wait()<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The task status becomes <code>COMPLETED<\/code>, but:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>result.artifacts == &#91;]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This appears to be a daemon bug in v0.7.2.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>CompleteTask<\/code> updates the task status correctly but does not return artifacts in the response payload.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Running a Relay \/ Bootstrap Node on a VPS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A central relay is required for:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bootstrap peer discovery<\/li>\n\n\n\n<li>Skill registry via gRPC (<code>:50052<\/code>)<\/li>\n\n\n\n<li>MCP StreamableHTTP (<code>:8080<\/code>)<\/li>\n\n\n\n<li>REST API (<code>:8081<\/code>)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The relay uses the dedicated <code>relay<\/code> binary, not <code>agentanycastd<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>relay \\\n  --listen \/ip4\/0.0.0.0\/tcp\/4001 \\\n  --key \/opt\/relay-data\/relay.key \\\n  --registry-listen :50052 \\\n  --mcp-listen :8080 \\\n  --api-listen :8081 \\\n  --registry-ttl 300s \\\n  --log-level debug\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #7: <code>discover()<\/code> Does Not Work Through the Daemon<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>await node.discover(\"chat\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Returns:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>anycast routing is not configured\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Although the relay exposes a skill registry on port <code>50052<\/code>, the daemon currently does not provide a <code>Discover<\/code> RPC implementation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, use the relay REST API:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl http:\/\/&lt;vps&gt;:8081\/api\/v1\/agents\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Peer Discovery Server Integration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">PeerDisco <a href=\"https:\/\/peerdisco.com)\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/peerdisco.com<\/a> (my recently developed peer discovery server) exposes an HTTP endpoint:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/mcp\/agents\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To make AgentAnyCast agents visible in PeerDisco:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PeerDisco\n    \u2502\n    \u2514\u2500\u2500 agntcy\n            \u2502\n            \u25bc\nAgentAnyCast HTTP Bridge (:8888)\n            \u2502\n            \u25bc\nRelay (:4001)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The bridge daemon must run separately on the VPS:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>agentanycastd \\\n  --bridge-listen :8888 \\\n  --grpc-listen unix:\/\/\/tmp\/agntcy-bridge\/daemon.sock \\\n  --bootstrap-peers \/ip4\/&lt;vps-ip&gt;\/tcp\/4001\/p2p\/&lt;relay-peer-id&gt; \\\n  --log-level info\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #8: Socket Directory Must Exist<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Before starting the bridge:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/tmp\/agntcy-bridge\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Otherwise startup fails with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ERROR: gRPC server error: bind: no such file or directory\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">PeerDisco&#8217;s health check should point to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;localhost:8888\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">9. SSH Access to the VPS from Windows<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install <code>sshpass<\/code> inside WSL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wsl -d Ubuntu -u root -- apt-get install -y sshpass\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Execute commands without an interactive password prompt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sshpass -p \"&lt;password&gt;\" ssh -o StrictHostKeyChecking=no root@&lt;vps-ip&gt; \"&lt;command&gt;\"\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #9: Never Use <code>pty=true<\/code> on Windows<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Using:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>terminal(pty=True)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">with SSH often triggers Git for Windows&#8217; password popup dialog.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Instead, use <code>sshpass<\/code> through WSL.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pitfall #10: <code>sshpass<\/code> Is Linux-Only<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>sshpass<\/code> does not run natively on Windows.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Always execute it inside WSL rather than directly through Windows process execution.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">10. Known Issues (v0.7.2 \/ v0.7.3)<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Issue<\/th><th>Impact<\/th><th>Workaround<\/th><\/tr><\/thead><tbody><tr><td><code>FAILED_PRECONDITION: SUBMITTED -&gt; COMPLETED<\/code><\/td><td>Tasks cannot be completed<\/td><td>Call <code>task.update_status(\"working\")<\/code> first<\/td><\/tr><tr><td>Empty artifacts after <code>task.wait()<\/code><\/td><td>Response payload is missing<\/td><td>Read task messages directly or use status checks<\/td><\/tr><tr><td><code>discover()<\/code> fails<\/td><td>Skill discovery unavailable<\/td><td>Query relay REST API (<code>:8081\/api\/v1\/agents<\/code>)<\/td><\/tr><tr><td>Daemon socket survives process kill<\/td><td>Restart fails<\/td><td>Remove <code>daemon.sock<\/code> before restarting<\/td><\/tr><tr><td>Cross-daemon task routing<\/td><td>Tasks never reach Python handler<\/td><td>Run client and server in the same Python process<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">11. Quick Checklist<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>WSL Ubuntu installed with <code>python3-venv<\/code> and <code>sshpass<\/code><\/li>\n\n\n\n<li><code>MSYS2_ARG_CONV_EXCL=\"*\"<\/code> applied to every WSL command<\/li>\n\n\n\n<li>Unique <code>home=<\/code> directory for each node<\/li>\n\n\n\n<li><code>update_status(\"working\")<\/code> before <code>complete()<\/code><\/li>\n\n\n\n<li><code>serve_forever()<\/code> or <code>async with Node<\/code> active for task reception<\/li>\n\n\n\n<li>VPS relay uses the <code>relay<\/code> binary, not <code>agentanycastd<\/code><\/li>\n\n\n\n<li>PeerDisco bridge running via <code>agentanycastd --bridge-listen :8888<\/code><\/li>\n\n\n\n<li>Socket directory created with <code>mkdir -p<\/code><\/li>\n\n\n\n<li><code>peer_id.json<\/code> written for debugging and process verification<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Some notes about installing AgentAnyCast for Hermes Agent to gain P2P abilities<\/p>\n","protected":false},"author":5796,"featured_media":21544,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[484,543],"tags":[95],"class_list":["post-21543","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-agents","tag-juust"],"_links":{"self":[{"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/posts\/21543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/users\/5796"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/comments?post=21543"}],"version-history":[{"count":1,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/posts\/21543\/revisions"}],"predecessor-version":[{"id":21545,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/posts\/21543\/revisions\/21545"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/media\/21544"}],"wp:attachment":[{"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/media?parent=21543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/categories?post=21543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juust.org\/index.php\/wp-json\/wp\/v2\/tags?post=21543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}