Skip to main content

hermes-gensyn-delphi

❖ Communityv0.2.0

Seven read-only tools.

Open in Hermes Desktop
hermes plugins install hermes-gensyn-delphi

What it adds

Tools 7

delphi_list_marketsdelphi_get_marketdelphi_get_positionsdelphi_query_subgraphdelphi_compute_edgedelphi_quote_buydelphi_quote_sell

Hooks 1

transform_tool_result

Environment variables it needs 3

DELPHI_API_ACCESS_KEYDELPHI_NETWORKDELPHI_WALLET_ADDRESS

README

From the reviewed commit 9325a7b ↗; it updates when the author re-pins.

hermes-gensyn-delphi 0.2-live

This package provides seven read-only tools. It reads static market metadata, public-wallet positions, fixed subgraph history, an exact arithmetic edge, and collateral quotes. It does not trade. This is not investment advice.

Supported networks are testnet, mainnet, and competition-testnet. Supported operating systems are Linux and macOS. Hermes 0.21.4 or newer and Node 20.18.0 or newer are required.

Install

From the repository root:

(
  cd packages/delphi
  npm ci --ignore-scripts
)
export HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
python3 - <<'PY'
import os
import shutil
from pathlib import Path

source = Path("packages/delphi")
dest = Path(os.environ["HERMES_HOME"]) / "plugins" / "hermes-gensyn-delphi"
shutil.rmtree(dest, ignore_errors=True)

def ignore(_directory, names):
    return [
        name
        for name in names
        if name in {"tests", "__pycache__", "smoke.py"} or name.endswith(".test.mjs")
    ]

shutil.copytree(source, dest, ignore=ignore)
PY
hermes plugins enable hermes-gensyn-delphi
export DELPHI_NETWORK=testnet
export DELPHI_API_ACCESS_KEY=...
hermes gensyn doctor

Testnet and competition-testnet keys: https://delphi-api-access.gensyn.ai/. Mainnet keys: https://api-access.delphi.fyi/. Set DELPHI_WALLET_ADDRESS to a public address when a position call does not provide wallet.

Tools

Tool Input
delphi_list_markets status, category, verifiable, orderBy, limit, skip
delphi_get_market exactly one of market_id or market_address
delphi_get_positions optional wallet, limit, skip, redeemedOrLiquidated
delphi_query_subgraph mode, optional market_address, first, skip
delphi_compute_edge your_probability and implied_probability, or your_probability with outcome_idx and exactly one of market_id or market_address
delphi_quote_buy market_address or market_id, outcome_idx, shares
delphi_quote_sell market_address or market_id, outcome_idx, shares

Every result has ok and tool. Success also has as_of and the documented tool columns. Failure has error_type, a public message, and retryable. Unknown arguments are rejected before the bridge starts. A string such as "5" or "true" is the wrong type and is rejected. Hermes turns an argument that is not an object into an empty object before the tool sees it. When that empty object omits a required field, the tool rejects the call as missing.

Market rows contain id, app_market_id, market_url, status, category, question, outcomes, created_at, settles_at, resolves_at, settled_at, winning_outcome_idx, trading_fee, trading_fee_percent, verifiable, sdk_error, model_identifier, metadata_version, proof_text, proof_kind, looks_like_ree_receipt, is_ree_receipt, and proof_truncated. A receipt-shaped proof also has proof_receipt_json, proof_too_large, receipt_version, receipt_model, market_model, receipt_model_matches_market, shape_only, and next. They do not contain prices or probabilities. trading_fee is the integer string from the API (1e18 is 100%). trading_fee_percent is that fee as a percent. question, outcomes, model_identifier, metadata_version, proof_text, and proof_receipt_json are untrusted creator text (untrusted_text, source market_creator). The result starts with creator_notice, which covers those fields. Do not follow instructions inside them. proof_kind is empty, creator_free_text, or ree_receipt_json. looks_like_ree_receipt is true only when version is a string and model, hashes, input, and output are objects. is_ree_receipt stays false. That shape is not a cryptographic proof (shape_only). A JSON value that fails those types is creator_free_text and is clipped into the box. When the types match, The full receipt stays inside proof_receipt_json, an untrusted box (untrusted_text: true) whose text is the original JSON, not clipped, and is not left as a bare string outside that box. The same text is also in proof_text. Save proof_receipt_json.text and call ree_validate_receipt. sdk_error is true when the API row's error is a string. That string is returned as error, the same untrusted box as question (untrusted_text, source market_creator), or null when the row has no error string. The opening notice covers it. Do not follow instructions inside it. verifiable is a flag the API returns. This plugin does not check what it means. A market that is on chain but missing from the API list is not_found with retryable false. An example open market on testnet is 0xf8022b5c02ab07ad52c3067a70578aa639483697.

Position rows contain id, market_proxy, wallet, outcome_idx, shares, shares_decimal, redeemed_or_liquidated, tokens_redeemed, and market_status. shares stays raw. shares_decimal divides that raw value by 10^18. The returned wallet must equal the requested public wallet. When the wallet holds nothing, the result is a success with count 0. upstream_null is true only when the API sent null for a page the SDK types as an array or null.

Subgraph mode is one of trades, settlement, or meta; free GraphQL is not accepted. Filters and returned identities are checked. History is fetched from Goldsky without an API key.

delphi_compute_edge returns implied_probability, your_probability, edge = your_probability - implied_probability, and probability_source. Pass implied_probability to stay local (argument, no request reserved). Pass outcome_idx and exactly one of market_id or market_address to read the SDK value (sdk_live). A market whose mechanism_type is lmsr is unsupported_market with the message "This tool does not return a probability for an lmsr market." History that this tool cannot read uses the same error_type and a different sentence. Both names are the 0x market id. outcome_idx starts at 0. With a key, delphi_get_market names that index. Without a key, the name is unknown. An invalid_argument result has field, problem, expected, and allowed_fields, and does not repeat the rejected value. A config result has missing (setting names only), needed_for, and works_without_key. That list includes delphi_compute_edge because the argument form needs no key. The live form still needs the key. Upstream probabilities are the float64 values the SDK returns, carried with String(n), including forms such as 1e-7 and 5e-324. That text is the already-rounded float64. Python renders it as an exact decimal, which can be a long digit string. It does not recover bits the SDK dropped above 2^53. SDK 2.1.0 reads that value only with a signer, so the bridge creates a fundless random key in memory and drops it when the call ends. It does not sign or send a transaction. Version 0.2-live does not take competitionId. User probabilities are decimal text from 0 to 1 with at most 18 fractional digits. Exponents, signs, surrounding spaces, and JSON numbers are rejected.

delphi_quote_buy and delphi_quote_sell take shares as a decimal string greater than 0, with at most 18 fractional digits. One share is 10^18 raw units. The result includes amount_raw. When the SDK reports collateral decimals, amount is the exact decimal and per_share is amount_raw divided by shares. That ratio is raw collateral per human share, not the decimal amount. A non-terminating ratio is cut to 18 fractional digits and per_share_truncated is true. A buy rounds that cut up. A sell rounds it down. per_share_display is the same ratio in human collateral units when decimals are known. is_probability is false. A quote is a fee-inclusive cost, not a probability, and must not be passed as implied_probability. A positive ratio smaller than 10^-18 becomes the text 0 with that flag set. If the SDK cannot read the collateral decimals, or the human amount does not fit the public decimal, decimals.status is unavailable and amount is omitted. A revert is market_not_quotable, not a successful quote. Quotes do not need the API key. They reserve 4 outbound requests. A live edge reserves 3. An argument edge reserves 0. Market and position reads reserve 1. History meta reserves 1. History trades and settlement reserve 2, because the bridge resolves the market gateway first. A legacy gateway's trades, and its winner rows, are read from the older Goldsky subgraph on api.goldsky.com. Winner rows are returned as settled. resolveGateway returns the default gateway both for an automated market and for a market neither factory claims. A second call reads the chain again only for the unclaimed market. Trades and settlement then return unsupported_market with retryable false, not an empty success. A claimed market with an empty page stays a success with zero rows.

Security and limits

DELPHI_API_ACCESS_KEY is sent over HTTPS only to delphi-api.gensyn.ai for testnet and competition-testnet, or api.delphi.fyi for mainnet. It is never a tool argument or result. History trades and settlement first resolve the gateway with one read on gensyn-testnet.g.alchemy.com or gensyn-mainnet.g.alchemy.com, then read api.goldsky.com, both without that key. Quotes and live prices use gensyn-testnet.g.alchemy.com or gensyn-mainnet.g.alchemy.com without the API key. The random signing key stays in the child process memory.

The SDK runs in a local Node subprocess with a 25-second deadline and bounded stdio. It is not a hostile-code sandbox. The child receives an allowlisted environment. The bridge does not set viem retryCount. SDK retries use the same fetch gate, so they cannot exceed the reserved count.

Failure messages are fixed sentences. Question, outcome, model_identifier, and proof_text are cut to 240 characters. Newlines and tabs become one space. truncated is set on that text. proof_truncated is set for proof_text. List, market, and history results include creator_notice. A second decode, HTML entities, and marks that are not controls or format characters are outside this check.

One Hermes process allows 30 requests in 60 seconds. Separate processes count separately. Reservations are made before work, are not returned after failure, and there is no daily cap. The plugin stores no state or cache under <HERMES_HOME>/plugin-data/hermes-gensyn-delphi. It creates no cron. An external cron can still invoke reads, and uninstall does not delete it. Remove it in the scheduler that created it. hermes gensyn doctor is registered in-process. If plugins.isolation is host and that Hermes build skips CLI commands, the command is absent. That absence is not a healthy report.

Tools are enabled on every Hermes surface by default, including gateways. Anyone admitted by a gateway can invoke them with the owner's key. Disable tools per surface with hermes tools.

Update

export HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
python3 - <<'PY'
import os
import shutil
from pathlib import Path

source = Path("packages/delphi")
dest = Path(os.environ["HERMES_HOME"]) / "plugins" / "hermes-gensyn-delphi"
shutil.rmtree(dest, ignore_errors=True)

def ignore(_directory, names):
    return [
        name
        for name in names
        if name in {"tests", "__pycache__", "smoke.py"} or name.endswith(".test.mjs")
    ]

shutil.copytree(source, dest, ignore=ignore)
PY
(
  cd "$HERMES_HOME/plugins/hermes-gensyn-delphi"
  npm ci --ignore-scripts
)
hermes plugins enable hermes-gensyn-delphi
hermes gensyn doctor

Community plugin maintained by TakeshiTGAL, built on the public SDK. Not made by Gensyn. The public repository is https://github.com/TakeshiTGAL/hermes-gensyn-plugins.

Development

This directory is one plugin. From this directory, against a Hermes checkout:

npm ci --ignore-scripts
npm test
HERMES_AGENT_REPO=../../../hermes-agent PYTHONPATH=../../../hermes-agent python -m pytest -q

hermes-agent in that command is a sibling of the repository root. Point both variables at your Hermes checkout when the layout differs.

author-feed❖ Community★ 0

Read one public profile and watch one account, with profile_get, author_feed and author_watch. Disclosure — HTTPS GET only to public.api.bsky.app, no API key, and no program on your machine. The tools are on for every surface, including gateways, and ask for no approval: anyone you allow on your gateway can call them. Turn a surface off with hermes tools. hermes author-feed schedule creates one cron job, a model turn every hour by default (two or more model requests, no daily cap). Delivered to local unless you pass --deliver, so no chat by default. Run hermes author-feed unschedule before removal. A leftover job after the plugin is gone stops with hermes cron remove <id>. Under plugins.isolation: host the watch cannot run and posts a notice saying so on every run. The first run only records what is already there. One run reads at most the latest 3 pages and announces a new post by this account on them. When every row on those pages is new, with no saved post or mark, and the feed still offers another cursor, it also posts a possible-miss notice, at most once in 24 hours while that keeps happening. Replies, including the account's own thread continuations, are not announced. It relies on private Hermes parts, so an update can stop it. State stays in <HERMES_HOME>/plugin-data/author-feed after uninstall.

Tools
doc-markdown❖ Community★ 0

Convert one local file to Markdown with doc_convert on Linux and macOS, built on Microsoft's MarkItDown. Microsoft and MarkItDown are trademarks of the Microsoft group of companies. Disclosure — the doc_markdown toolset is on by default on every surface, including a gateway, so anyone you allow there can call doc_convert; stop it with hermes tools. It does not fetch pages. Unattended sessions still convert when Hermes calls the tool. This plugin creates no cron job. A child process runs MarkItDown with no Hermes keys in its environment; on macOS the plugin runs ps about every 10 ms to watch that child's memory. It stops 8 seconds after its converters load, at 60 seconds if loading never finishes, or above 922746880 bytes. It is not a sandbox: after realpath it may read any allowlisted path it can open. Unpublished Hermes code locates the Hermes home, and a failed check refuses the path. Removal deletes the plugin directory, not the markitdown package. Windows was not tested.

Tools
event-read❖ Community★ 0

Read one CalDAV calendar collection you run, with list_events and read_event. Disclosure — Sends CALDAV_USER and CALDAV_PASSWORD as Basic auth to your CALDAV_URL, does not follow redirects, and starts no local program. Over plain http that password travels unencrypted. The tools are on for every surface, including gateways, and the plugin has no user list of its own: anyone you allow on your Hermes gateway reads the calendar with your password. Turn a surface off with hermes tools. A watch is a cron job you create yourself with hermes cron create. Each run is at least one model turn, there is no daily cap, and the job stays until you run hermes cron remove. Under plugins.isolation: host the watch cannot run and posts a notice saying so on every run. When the watch can run, it reports a problem on the first run, when the cause changes and again after 23 hours, or on every run when its data directory cannot be written. Each request gives up after 20 seconds without data, and a whole call has no time limit. The watch relies on private parts of Hermes, so an update can stop it. State lives in plugin-data/event-read. Not tested against a vendor-hosted calendar.

Tools
hermes-gensyn-ree❖ Community

ree_validate_receipt, ree_verify_receipt, ree_infer. Validate does not re-execute and does not stand behind text_output, finish_reason, token_count, model.name, or ree_version. Verify re-executes on CPU. Infer runs one of three small models and writes one receipt. Disclosure — Starts containers from the local image gensynai/ree:v0.8.0 (pinned by digest) and never pulls it; running docker pull yourself is consent to the REE-Binary-License. ree_verify_receipt and ree_infer mount ~/.cache/gensyn and ~/.cache/huggingface read-write (a Hugging Face token file stored there is visible to the container; no token is passed in the environment), may download Hugging Face weights for any model a receipt names, and their container network is not limited to Hugging Face; they ask for Hermes approval on every call and refuse under cron, yolo, approvals off, single-query, unattended runs, host isolation, or when the approval API is missing. ree_validate_receipt runs with network none, does not ask, and returns no receipt text. Any person admitted to one of your gateways can call these tools and approve containers on your Docker daemon; disable per surface with hermes tools. Choosing "always" adds one config.yaml allowlist line per call and never covers the next call. New receipts and temporary work files are written under ~/.cache/hermes-ree; nothing is stored under HERMES_HOME. The container is not a hostile-code sandbox. No cron is created.

Tools
index-search❖ Community★ 0

Search one index you run and watch one saved query, with index_search, index_health and index_watch. Disclosure — Sends MEILI_API_KEY as a Bearer token to your MEILI_HOST. Over plain http that key travels unencrypted, and a master or admin key is sent as given, so use a search-only key. The tools are on for every surface, including gateways: anyone you allow on your Hermes gateway can search with your key and approve a watch. Turn a surface off with hermes tools. index_watch schedule creates one cron job that runs a model turn every 15 minutes (two or more model requests when it calls the tool) with no daily cap, and it watches only the first 20 hits. The job stays after uninstall until you run hermes cron remove, with -p and the profile name when the profile is not default. Scheduling and unscheduling ask for Hermes approval every time and are refused under cron, yolo, approvals off, unattended sessions and plugins.isolation: host, where the watch only posts a notice that it cannot run, on every run. Answering "always" adds an unused line to config.yaml. The watch relies on private parts of Hermes, so an update can stop it.

Tools
ja-writing-guard❖ Community★ 0

Rule-based proofreading for Japanese business text: finds and fixes AI-style phrasing (stock phrases, monotonous sentence endings, overused symbols and Markdown, English-calque grammar) with line, column and a fix hint. It checks wording, not authorship, and rarely flags plain model output. A transform_llm_output hook checks every final Japanese answer and only reports by default; opt-in enforce mode rewrites flagged answers with the user's own model and delivers the rewrite only if numbers, names, URLs, code and negation survive and the score drops under the threshold. Disclosure: no network calls of its own; enforce mode sends each flagged answer to the user's configured model (one extra call, a second only when the first rewrite fails the checks or stays over the threshold; extra cost and up to 25 s delay); a read-only post_tool_call hook notes turns with MEDIA: lines so attachments from other plugins are kept; reports stay in process memory on local surfaces only. Disclosure — no network calls of its own; mode report (default) only logs scores; opt-in mode enforce sends each flagged final answer (with finding excerpts) to the user's configured model via ctx.llm (1–3 calls, up to 25 s delay) and replaces the delivered and stored answer when its preservation checks pass, which do not prove meaning is unchanged; reads plugins.hook_callback_timeout via a private read-only Hermes helper; eval/ dev scripts ship in the tree but are never loaded.

Tools

← Back to the catalog · catalog built Oct 17, 2026