{"x402Version":2,"service":"HALOWERK agentenwerk","version":"1.0.0","network":"eip155:8453","network_name":"Base Mainnet","chain_id":8453,"recipient":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","asset":{"symbol":"USDC","address":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","decimals":6},"facilitators":["CDP","https://facilitator.xpay.sh"],"payment_headers":{"primary":"PAYMENT-SIGNATURE","accepted":["PAYMENT-SIGNATURE","X-Payment","PAYMENT"],"challenge":["PAYMENT-REQUIRED"],"response":["PAYMENT-RESPONSE"]},"resources":[{"url":"https://agent.halowerk.com/v1/webhook-inbox","method":"POST","name":"webhook_inbox","description":"Gives an agent without a reachable server a place to receive callbacks. create returns a public URL that accepts any POST, GET or PUT from a third party; poll returns the events that arrived since a cursor you carry forward, with headers, parsed body and arrival time. The inbox expires after at most seven days and holds at most 500 events, oldest dropped first. Reading requires the secret returned at creation. Do not point payment or authentication callbacks here: anyone who learns the URL can post to it, and stored bodies are readable with the secret alone.","summary":"Create a short-lived public receive URL, then poll it for the events that arrived, parsed and in order.","inputSchema":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["create","poll","delete"],"description":"create makes a new inbox, poll reads events, delete removes it."},"inbox_id":{"type":"string","minLength":8,"maxLength":64,"description":"Required for poll and delete."},"secret":{"type":"string","minLength":8,"maxLength":128,"description":"The secret returned by create. Required for poll and delete."},"cursor":{"type":"integer","minimum":0,"default":0,"description":"Only events with a higher sequence number are returned."},"limit":{"type":"integer","minimum":1,"maximum":200,"default":50,"description":"Maximum events per poll."},"ttl_seconds":{"type":"integer","minimum":60,"maximum":604800,"default":3600,"description":"Lifetime of a new inbox, at most seven days."},"max_events":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"How many events the inbox keeps before dropping the oldest."},"note":{"type":"string","maxLength":200,"description":"Free label carried through."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/state-store","method":"POST","name":"state_store","description":"Key-value state for agents that need to survive between calls. Every write carries a time-to-live; the maximum is 30 days and there is no way to store something permanently. Values are opaque JSON up to 64 KB, at most 1000 live keys per namespace. Actions: set, get, list, delete. A get on a missing or expired key answers found=false, it is not an error. The namespace is a plain string chosen by the caller and is not authenticated — anyone who knows it can read it, so do not put secrets in it. Expired rows are removed on access, not on a timer, so a list can lag a few seconds behind the exact expiry moment.","summary":"Store, read, list and delete small pieces of agent state under a namespace, with a mandatory expiry so nothing is kept forever.","inputSchema":{"type":"object","required":["action","namespace"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["set","get","list","delete"],"description":"What to do."},"namespace":{"type":"string","minLength":3,"maxLength":128,"description":"Namespace the key lives in. Not a secret and not authenticated."},"key":{"type":"string","minLength":1,"maxLength":256,"description":"Key. Required for set, get and delete."},"value":{"description":"Any JSON value. Required for set. Serialised size must stay under 64 KB."},"ttl_seconds":{"type":"integer","minimum":1,"maximum":2592000,"default":3600,"description":"Lifetime in seconds, at most 30 days."},"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Maximum keys returned by list."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/wakeup","method":"POST","name":"wakeup_schedule","description":"Books a single POST to a URL you own, at a time you name, with a payload you supply. Delivery is retried up to five times with growing gaps and every attempt is recorded with its status. Lead time is between 10 seconds and 30 days, and at most 200 pending wakeups per target URL. The target must be a public https address: private, loopback and link-local addresses are refused, so this cannot be pointed at an internal network. Delivery is at-least-once and the time is a floor, not a guarantee — the dispatcher checks every 15 seconds, so expect a few seconds of lag. Actions: schedule, status, cancel, list.","summary":"Schedule one HTTP callback to your own URL at a fixed time, then check or cancel it — for agents that are not running when the moment arrives.","inputSchema":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["schedule","status","cancel","list"],"description":"What to do."},"target_url":{"type":"string","maxLength":2000,"description":"Public https URL that receives the POST. Required for schedule and list."},"due_at":{"type":"string","description":"Absolute time as ISO 8601, e.g. 2026-08-12T09:00:00Z. Either this or delay_seconds."},"delay_seconds":{"type":"integer","minimum":10,"maximum":2592000,"description":"Relative lead time in seconds. Either this or due_at."},"payload":{"description":"JSON body delivered with the callback. Up to 16 KB."},"header_name":{"type":"string","maxLength":64,"description":"Optional header name sent with the callback, e.g. X-Agent-Token."},"header_value":{"type":"string","maxLength":512,"description":"Value for that header. Stored as given."},"wakeup_id":{"type":"string","minLength":8,"maxLength":64,"description":"Required for status and cancel."},"note":{"type":"string","maxLength":200,"description":"Free label carried through."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum entries returned by list."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/job-runner","method":"POST","name":"job_runner","description":"For work that outlives one HTTP response. You submit steps, each an HTTP request against a public address; the job is acknowledged at once and runs in the background, and the collected results are POSTed to your callback URL when finished. Every step reports its status, timing, response headers and body up to 256 KB, and a failing step never aborts the others. Price is 0.003 USDC per step, quoted before payment. Only http and https against public hosts are performed — private and loopback addresses are refused and no supplied code is ever executed. Steps run one after another with a 20 second cap each, so a 50-step job can take several minutes. Actions: submit, status, cancel.","summary":"Hand over a list of up to 50 HTTP calls, get an immediate job id, and have the collected results posted to your callback when they are done.","inputSchema":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["submit","status","cancel"],"description":"What to do."},"steps":{"type":"array","minItems":1,"maxItems":50,"description":"The calls to make, in order. Required for submit.","items":{"type":"object","required":["url"],"additionalProperties":false,"properties":{"url":{"type":"string","maxLength":2000,"description":"Public http or https address."},"method":{"type":"string","enum":["GET","POST","PUT","HEAD"],"default":"GET","description":"HTTP method."},"headers":{"type":"object","description":"Extra request headers."},"body":{"description":"Request body. Objects are sent as JSON."},"label":{"type":"string","maxLength":100,"description":"Name for this step in the result."}}}},"callback_url":{"type":"string","maxLength":2000,"description":"Public https URL that receives the finished job. Required for submit."},"callback_header_name":{"type":"string","maxLength":64,"description":"Optional header sent with the callback."},"callback_header_value":{"type":"string","maxLength":512,"description":"Value for that header."},"job_id":{"type":"string","minLength":8,"maxLength":64,"description":"Required for status and cancel."},"token":{"type":"string","minLength":16,"maxLength":128,"description":"The token from submit. Required for status and cancel."},"include_results":{"type":"boolean","default":false,"description":"Return the collected results with status as well as via callback."},"note":{"type":"string","maxLength":200,"description":"Free label carried through."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"3000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/file-vault","method":"POST","name":"file_vault","description":"Takes a base64 file up to 25 MB and stores it for as long as you say, at most seven days. You get a download URL carrying a 32-byte token; whoever holds the link can fetch the file once or up to a limit you set, with no payment and no account. Price is 0.004 USDC per started megabyte, quoted before payment from the size you declare. Actions: store, status, delete. Anything expired is deleted with its contents, and a link is only as private as you keep it, so this is not a place for personal or secret material. Content is stored and served unchanged and is never inspected or scanned.","summary":"Park a file for a limited time and get back an unguessable download URL that anyone you send it to can fetch without a wallet.","inputSchema":{"type":"object","required":["action"],"additionalProperties":false,"properties":{"action":{"type":"string","enum":["store","status","delete"],"description":"What to do."},"content_base64":{"type":"string","description":"File content, base64 encoded. Required for store."},"filename":{"type":"string","maxLength":255,"description":"Name suggested to the downloader."},"content_type":{"type":"string","maxLength":128,"default":"application/octet-stream","description":"MIME type served on download."},"ttl_seconds":{"type":"integer","minimum":60,"maximum":604800,"default":3600,"description":"Lifetime, at most seven days."},"max_downloads":{"type":"integer","minimum":1,"maximum":1000,"description":"Delete after this many downloads. Unlimited within the lifetime if omitted."},"size_bytes":{"type":"integer","minimum":1,"maximum":26214400,"description":"Declared size, used to quote the price before payment. Must match the real size."},"file_id":{"type":"string","minLength":8,"maxLength":64,"description":"Required for status and delete."},"token":{"type":"string","minLength":16,"maxLength":128,"description":"The token returned by store. Required for status and delete."},"note":{"type":"string","maxLength":200,"description":"Free label carried through."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"4000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/a2a-card-validate","method":"POST","name":"a2a_card_validate","description":"Validates an Agent Card document against the A2A convention and returns findings by severity: error (the card is unusable as published), warning (works, but a consuming agent will guess), info (recommended field absent). Checked: the required fields name, description, url, version, capabilities and skills; that url is absolute and https; that every skill carries id, name, description and tags and that skill ids are unique; that declared securitySchemes use a known type and that every entry in security refers to a defined scheme; that input and output modes are declared; that streaming and pushNotifications are booleans. This endpoint does not fetch the card and never contacts the agent: it judges only the document handed to it, so a passing card is not proof that the endpoint is reachable or honest.","summary":"Check an A2A Agent Card for required fields, skill definitions, authentication declarations and transport hygiene, and get every deviation listed with its JSON path.","inputSchema":{"type":"object","required":["card"],"additionalProperties":false,"properties":{"card":{"type":"object","description":"The Agent Card document as JSON."},"strict":{"type":"boolean","default":false,"description":"If true, recommended-field findings count as warnings and lower the verdict."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/mcp-inspect","method":"POST","name":"mcp_inspect","description":"Performs the MCP handshake against a streamable-HTTP endpoint and then reads the catalogue: tools with their input schemas, resources with their URIs and mime types, and prompts with their arguments. Servers answering as an event stream are handled as well as plain JSON, and a session id is carried across calls. Only listing methods are sent — no tool of the inspected server is ever executed, nothing is written, and no resource contents are read. The target must be a public address; private and loopback addresses are refused. An unreachable or non-conforming server yields a reachable=false report with the reason, not an error.","summary":"Look at a remote MCP server from the outside: whether it answers, which protocol it speaks, and the tools, resources and prompts it offers with their schemas.","inputSchema":{"type":"object","required":["url"],"additionalProperties":false,"properties":{"url":{"type":"string","maxLength":2000,"description":"The MCP endpoint, e.g. https://example.com/mcp. Public https address."},"include":{"type":"array","default":["tools","resources","prompts"],"items":{"type":"string","enum":["tools","resources","prompts"]},"description":"Which catalogues to read."},"include_schemas":{"type":"boolean","default":true,"description":"Return the full input schema per tool. If false, only names and descriptions."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/mcp-normalize","method":"POST","name":"mcp_normalize","description":"Takes a list of MCP tool definitions, as returned by tools/list on any number of servers, and rewrites them into one common form. Servers disagree on where the schema lives — inputSchema, input_schema, parameters, schema or arguments are all in use — and a consumer reading only one of them loses the others silently; every spelling is accepted and the one found is reported. For each tool the result carries a flat field list with type, required flag and description, a synthetic example call built from the schema, and the tool name normalised to snake_case. Name collisions across servers are detected and reported with the servers involved. The example call shows the shape only: values like \"string\" and 0 are placeholders and must never be sent to a live server. No network access happens here — only the definitions handed in are read.","summary":"Bring MCP tool definitions from different servers into one shape: uniform input schemas, a field list, a synthetic example call and a common set of error codes.","inputSchema":{"type":"object","required":["tools"],"additionalProperties":false,"properties":{"tools":{"type":"array","minItems":1,"maxItems":200,"description":"The MCP tool definitions to normalise.","items":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"description":"Tool name."},"server":{"type":"string","description":"Which server the tool came from. Used for collision reporting."}}}},"include_examples":{"type":"boolean","default":true,"description":"Build a synthetic example call per tool."},"naming":{"type":"string","enum":["snake_case","preserve"],"default":"snake_case","description":"How to normalise tool names."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/fallback-resolve","method":"POST","name":"fallback_resolve","description":"Searches the public x402 discovery catalogue for services able to replace a broken dependency. Give the failed URL and, better still, a short description of what it did and the fields you need back; matches are scored on overlap between your task words and the candidate name, description and path, then ordered by score and price. Every hit carries the reason it matched, its price in USDC, its network and when the catalogue last saw it. The endpoint that failed is excluded from its own replacement list. This reads a public index and never calls a candidate: a listed service is not proof that it works today, and the input schema of a replacement will differ, so treat the result as a shortlist to test, not a drop-in.","summary":"Find paid x402 endpoints that can stand in for one that stopped answering, ranked by how well they match the task and what they cost.","inputSchema":{"type":"object","required":["failed_url"],"additionalProperties":false,"properties":{"failed_url":{"type":"string","maxLength":2000,"description":"The endpoint that stopped working."},"task":{"type":"string","maxLength":500,"description":"What it did, in a few words. The single strongest signal for a good match."},"required_fields":{"type":"array","items":{"type":"string"},"default":[],"description":"Field names you need in the answer. Candidates mentioning them score higher."},"max_price_usdc":{"type":"number","minimum":0,"description":"Ignore candidates above this price per call."},"network":{"type":"string","maxLength":64,"description":"Only candidates on this network, e.g. eip155:8453."},"limit":{"type":"integer","minimum":1,"maximum":25,"default":10,"description":"How many candidates to return."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/task-quote-compare","method":"POST","name":"task_quote_compare","description":"Normalises offers that describe the same task in different shapes and ranks them. Each offer may carry a price, a delivery time, a list of capabilities and one or more delivery formats. You state which capabilities and formats the task requires; offers missing a required capability or format are marked ineligible and ranked last, never silently dropped. The ranking is a weighted score over price, speed and capability coverage, with weights you supply and which are echoed back. Every ranked entry carries the sub-scores it was built from, so the order can be recomputed by hand. Prices must already be in one currency: no conversion happens here, and a mixed-currency input is rejected rather than compared wrongly.","summary":"Compare competing agent offers for one task on price, delivery time, required capabilities and output format, and get a ranked list with the reason for every position.","inputSchema":{"type":"object","required":["offers"],"additionalProperties":false,"properties":{"offers":{"type":"array","minItems":1,"maxItems":25,"description":"The competing offers.","items":{"type":"object","required":["agent"],"additionalProperties":false,"properties":{"agent":{"type":"string","minLength":1,"maxLength":128,"description":"Name of the offering agent."},"price":{"type":"number","minimum":0,"description":"Price for the whole task."},"currency":{"type":"string","minLength":2,"maxLength":10,"default":"USDC","description":"Currency. Must be the same across all offers."},"delivery_seconds":{"type":"integer","minimum":0,"description":"Promised delivery time in seconds."},"capabilities":{"type":"array","items":{"type":"string"},"default":[],"description":"What the agent says it can do."},"formats":{"type":"array","items":{"type":"string"},"default":[],"description":"Delivery formats offered, e.g. json, pdf, markdown."},"note":{"type":"string","maxLength":500,"description":"Free text carried through unchanged."}}}},"required_capabilities":{"type":"array","items":{"type":"string"},"default":[],"description":"Capabilities the task cannot do without."},"required_formats":{"type":"array","items":{"type":"string"},"default":[],"description":"Acceptable delivery formats. An offer matching any one of them qualifies."},"max_price":{"type":"number","minimum":0,"description":"Offers above this are marked ineligible."},"max_delivery_seconds":{"type":"integer","minimum":0,"description":"Offers slower than this are marked ineligible."},"weights":{"type":"object","additionalProperties":false,"description":"Weighting of the three criteria. Normalised to sum 1.","properties":{"price":{"type":"number","minimum":0,"default":0.4},"speed":{"type":"number","minimum":0,"default":0.3},"capability":{"type":"number","minimum":0,"default":0.3}}}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/result-consensus","method":"POST","name":"result_consensus","description":"Takes two to twelve answers and returns a field-by-field comparison. For JSON answers every leaf path is compared across responders: a path is agreed when all responders that supplied it carry the same value, conflicting when they differ, and partial when some omitted it. Numbers count as equal inside a relative tolerance you set. For plain-text answers the comparison is word-overlap similarity, which measures shared vocabulary and not meaning — two correct answers in different words will score low, and that is reported as low agreement, not as a contradiction. The result names a majority value per conflicting path together with how many responders backed it. This endpoint does not decide who is right: it has no ground truth and no model, it only shows where the answers part company.","summary":"Compare several agent answers to the same question, report where they agree, and list every field where they contradict each other with the competing values.","inputSchema":{"type":"object","required":["answers"],"additionalProperties":false,"properties":{"answers":{"type":"array","minItems":2,"maxItems":12,"description":"The answers to compare. Two to twelve entries.","items":{"type":"object","required":["responder","value"],"additionalProperties":false,"properties":{"responder":{"type":"string","minLength":1,"maxLength":128,"description":"Name of the answering agent."},"value":{"description":"The answer: a JSON document or a string."},"weight":{"type":"number","minimum":0,"maximum":100,"default":1,"description":"Optional weight for the majority count."}}}},"number_tolerance":{"type":"number","minimum":0,"maximum":1,"default":0.001,"description":"Relative tolerance below which two numbers count as equal."},"text_similarity_threshold":{"type":"number","minimum":0,"maximum":1,"default":0.6,"description":"Word-overlap ratio from which two texts count as agreeing."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/twin-diff","method":"POST","name":"twin_diff","description":"Takes two state documents — target (what the twin should look like) and observed (what was measured) — and returns a leaf-by-leaf comparison. Every leaf path carries one of five states: in_tolerance, out_of_tolerance, missing_in_observed, unexpected_in_observed or type_mismatch. Numeric leaves are judged against a tolerance you set per path, either absolute (tolerance_abs) or relative (tolerance_ratio); paths without an entry fall back to default_tolerance_ratio, which is 0, meaning exact equality. Strings, booleans and null are compared for equality only, with optional case folding for strings. Arrays are addressed by index, so a reordered list reads as a set of deviations and not as a match. Units are never inferred from field names: a unit appears in the result only where you declared one, otherwise unit is null and unit_source says not_declared. This endpoint is stateless — it stores no twin, tracks no history and performs no synchronisation; it reports the gap between the two documents handed to it at this moment and nothing else.","summary":"Compare a desired state document against an observed one field by field and get every deviation with its absolute and relative size, the tolerance that was applied and the declared unit.","inputSchema":{"type":"object","required":["target","observed"],"additionalProperties":false,"properties":{"target":{"type":"object","description":"The desired state document (the twin)."},"observed":{"type":"object","description":"The observed state document (the measurement)."},"tolerances":{"type":"array","maxItems":200,"description":"Per-path tolerances. Give tolerance_abs or tolerance_ratio, not both.","items":{"type":"object","required":["field"],"additionalProperties":false,"properties":{"field":{"type":"string","minLength":1,"maxLength":400,"description":"Leaf path as it appears in the result, e.g. /pump/pressure_bar. A trailing /* applies the entry to every leaf below that prefix."},"unit":{"type":"string","maxLength":32,"description":"Unit of this field, echoed into the result. Declared by you, never inferred."},"tolerance_abs":{"type":"number","minimum":0,"description":"Absolute tolerance in the unit of this field."},"tolerance_ratio":{"type":"number","minimum":0,"maximum":1,"description":"Relative tolerance as a ratio of the larger of the two values."}}}},"default_tolerance_ratio":{"type":"number","minimum":0,"maximum":1,"default":0,"description":"Relative tolerance for numeric paths without their own entry. 0 means exact equality."},"ignore_fields":{"type":"array","maxItems":200,"items":{"type":"string","minLength":1,"maxLength":400},"description":"Paths to leave out of the comparison. A trailing /* ignores everything below that prefix."},"case_insensitive_strings":{"type":"boolean","default":false,"description":"Compare string leaves without regard to case."},"max_fields":{"type":"integer","minimum":1,"maximum":2000,"default":2000,"description":"Reject the request if the two documents together hold more leaf paths than this."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"3000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/memory-compact","method":"POST","name":"memory_compact","description":"Takes a message history and a character budget and returns a shortened history together with a full account of what it cost. Four stages run in fixed order: pin protects messages that must survive (roles listed in keep_roles, the last keep_last_n messages, and anything you marked pin), dedupe removes later near-duplicates of an earlier message of the same role using word-overlap similarity, trim shortens unprotected survivors to max_message_chars at the last sentence boundary, and drop removes the lowest-scoring unprotected messages until the budget is met. The score is disclosed in the response and is a fixed weighting of recency, role and overlap with the vocabulary of the whole history. This endpoint uses no language model and does not summarise, paraphrase or rewrite anything: every character in the output appears verbatim in the input, and nothing is appended, not even an ellipsis. Consequences follow from that and are reported rather than hidden — word overlap measures shared vocabulary and not meaning, so two differently worded messages about the same fact are not recognised as duplicates, and trimming cuts at a sentence boundary and can therefore remove the point of a long message. Protected messages are never dropped, so a budget smaller than the protected content cannot be met; the response then says budget_met false and reports the shortfall instead of discarding something it promised to keep.","summary":"Compact a long agent conversation to a character budget in four declared stages and get back exactly which messages stayed verbatim, which were trimmed and which were dropped, with the loss quantified.","inputSchema":{"type":"object","required":["messages","budget_chars"],"additionalProperties":false,"properties":{"messages":{"type":"array","minItems":2,"maxItems":200,"description":"The conversation in order, oldest first.","items":{"type":"object","required":["role","content"],"additionalProperties":false,"properties":{"role":{"type":"string","enum":["system","user","assistant","tool"],"description":"Speaker role."},"content":{"type":"string","minLength":1,"maxLength":8000,"description":"Message text."},"id":{"type":"string","maxLength":128,"description":"Optional caller-side identifier, echoed unchanged."},"pin":{"type":"boolean","default":false,"description":"If true this message is protected: never trimmed, never dropped."}}}},"budget_chars":{"type":"integer","minimum":100,"maximum":400000,"description":"Character budget for the sum of all returned message contents."},"keep_last_n":{"type":"integer","minimum":0,"maximum":50,"default":5,"description":"How many of the most recent messages are protected."},"keep_roles":{"type":"array","maxItems":4,"default":["system"],"items":{"type":"string","enum":["system","user","assistant","tool"]},"description":"Roles whose messages are protected."},"duplicate_threshold":{"type":"number","minimum":0.5,"maximum":1,"default":0.9,"description":"Word-overlap ratio from which a later message of the same role counts as a near-duplicate of an earlier one."},"max_message_chars":{"type":"integer","minimum":80,"maximum":4000,"default":400,"description":"Length to which unprotected survivors are trimmed in the trim stage."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/state-machine-step","method":"POST","name":"state_machine_step","description":"Takes a machine definition, the current state, one event and an optional context, and computes a single step. Transitions may carry a guard, which is a declared comparison — field, operator, value — and never an expression: the field is a dotted path into context or payload, so a machine handed in by a stranger cannot execute anything on this server. Supported operators are eq, ne, gt, gte, lt, lte, in, not_in, exists and not_exists; a guard whose field does not resolve evaluates to false and says so rather than passing silently. Deadlines are computed from elapsed_in_state_s, which you supply, so the result does not depend on this server clock and the same request always yields the same answer. When a state carries timeout_s and the elapsed time exceeds it, timeout_precedence decides whether the timeout transition or a matching event transition wins; the default is timeout. A breached deadline is reported even when the state defines no timeout_target, in which case the machine does not move on account of it. The definition is checked for referential integrity before the step runs: transitions pointing at states that do not exist, and an initial state that does not exist, are rejected as a bad machine rather than silently followed. This endpoint is stateless: it stores no machine, no state and no history, and it applies exactly one step per call — use /v1/state-store to keep the state between calls.","summary":"Apply one event to a state machine definition and get back the next state, the actions it triggers, whether a deadline was breached and which events the machine will accept next.","inputSchema":{"type":"object","required":["machine","current_state","event"],"additionalProperties":false,"properties":{"machine":{"type":"object","required":["initial","states"],"additionalProperties":false,"description":"The automaton definition.","properties":{"initial":{"type":"string","minLength":1,"maxLength":64,"description":"Name of the initial state. Must be one of the defined states."},"states":{"type":"array","minItems":1,"maxItems":200,"description":"The states of the machine.","items":{"type":"object","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":64,"description":"State name, unique within the machine."},"final":{"type":"boolean","default":false,"description":"If true no event is accepted in this state."},"timeout_s":{"type":"number","minimum":0,"maximum":31536000,"description":"Deadline for this state in seconds."},"timeout_target":{"type":"string","minLength":1,"maxLength":64,"description":"State to move to when the deadline is exceeded. Without it a breach is only reported."},"timeout_actions":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":64},"description":"Actions triggered by the deadline transition."},"on":{"type":"array","maxItems":50,"description":"Event-driven transitions out of this state, evaluated in order.","items":{"type":"object","required":["event","target"],"additionalProperties":false,"properties":{"event":{"type":"string","minLength":1,"maxLength":64,"description":"Event name this transition reacts to."},"target":{"type":"string","minLength":1,"maxLength":64,"description":"State to move to."},"actions":{"type":"array","maxItems":20,"items":{"type":"string","minLength":1,"maxLength":64},"description":"Actions triggered by this transition."},"guard":{"type":"object","required":["field","op"],"additionalProperties":false,"description":"Condition that must hold for this transition to be taken.","properties":{"field":{"type":"string","minLength":1,"maxLength":200,"description":"Dotted path starting with context. or payload., e.g. context.attempts."},"op":{"type":"string","enum":["eq","ne","gt","gte","lt","lte","in","not_in","exists","not_exists"],"description":"Comparison operator."},"value":{"description":"Right-hand operand. Not used by exists and not_exists; an array for in and not_in."}}}}}}}}}}},"current_state":{"type":"string","minLength":1,"maxLength":64,"description":"The state the machine is in right now."},"event":{"type":"object","required":["name"],"additionalProperties":false,"description":"The event to apply.","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"description":"Event name."},"payload":{"type":"object","description":"Event data, addressable in guards as payload.<field>."}}},"context":{"type":"object","description":"Machine context, addressable in guards as context.<field>. Never modified."},"elapsed_in_state_s":{"type":"number","minimum":0,"maximum":31536000,"default":0,"description":"Seconds already spent in current_state. Supplied by you, so the result does not depend on this server clock."},"timeout_precedence":{"type":"string","enum":["timeout","event"],"default":"timeout","description":"Which side wins when the deadline is breached and an event transition also matches."}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"2000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]},{"url":"https://agent.halowerk.com/v1/intent-clarify","method":"POST","name":"intent_clarify","description":"Takes a list of candidate intents, each described by attributes, plus whatever is already known, and returns the one attribute worth asking about next. Candidates contradicted by the known values are ruled out first and listed with the attribute that excluded them; a candidate that simply does not declare a known attribute is kept, because silence is not a contradiction. For every remaining attribute the endpoint builds the branches an answer would create and ranks them by the prior-weighted expected number of candidates left, then by the worst case, then by the number of options; a candidate that does not declare the attribute survives every branch, which is counted rather than ignored. Attributes on which all remaining candidates agree carry no information and are returned separately as unusable_attributes, so they are not asked by mistake. When an attribute has more distinct values than max_options, the largest options are shown and the omitted values are named explicitly — nothing is capped silently. The answer also carries a greedy worst-case estimate of how many further questions would be needed. This endpoint uses no language model and does not read natural language: it never invents a candidate, an attribute or a value, and the question wording is a fixed template over the attribute name unless you supply your own phrasing in attribute_prompts. It is stateless — it remembers no dialogue, so pass the accumulated answers back in known on the next call.","summary":"Given several candidate intents and what tells them apart, get the single follow-up question that narrows the set fastest, with the expected and worst-case number of candidates left after each possible answer.","inputSchema":{"type":"object","required":["candidates"],"additionalProperties":false,"properties":{"candidates":{"type":"array","minItems":2,"maxItems":50,"description":"The competing intents, two to fifty.","items":{"type":"object","required":["id","attributes"],"additionalProperties":false,"properties":{"id":{"type":"string","minLength":1,"maxLength":128,"description":"Identifier, unique within the call."},"label":{"type":"string","maxLength":300,"description":"Optional human-readable name, echoed unchanged."},"attributes":{"type":"object","description":"What distinguishes this candidate. Values must be scalar.","additionalProperties":{"type":["string","number","boolean","null"]}},"prior":{"type":"number","minimum":0,"maximum":1000,"default":1,"description":"Relative likelihood of this candidate before asking. Used to weight the expected outcome."}}}},"known":{"type":"object","description":"Attribute values already established, for example from earlier answers.","additionalProperties":{"type":["string","number","boolean","null"]}},"ask_about":{"type":"array","maxItems":50,"items":{"type":"string","minLength":1,"maxLength":128},"description":"Restrict the question to these attributes. Empty or absent means all of them."},"max_options":{"type":"integer","minimum":2,"maximum":10,"default":5,"description":"How many answer options the question may offer. Excess values are named under omitted_values, never dropped silently."},"attribute_prompts":{"type":"object","description":"Your own question wording per attribute. Used verbatim where given.","additionalProperties":{"type":"string","maxLength":300}}}},"mimeType":"application/json","accepts":[{"scheme":"exact","network":"eip155:8453","payTo":"0x2880EdfFF13100677Bf97A3CBdF3Bc34771C4E5E","price":{"amount":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","extra":{"asset":"USDC","network_name":"Base Mainnet","name":"USD Coin","version":"2","assetTransferMethod":"eip3009","eip712Domain":{"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}}},"maxTimeoutSeconds":300}]}]}