{"id":13766881,"url":"https://github.com/semiotic-ai/autoagora","last_synced_at":"2025-05-10T22:31:23.569Z","repository":{"id":61019344,"uuid":"533509854","full_name":"semiotic-ai/autoagora","owner":"semiotic-ai","description":null,"archived":false,"fork":false,"pushed_at":"2024-01-16T21:58:46.000Z","size":1049,"stargazers_count":11,"open_issues_count":15,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-17T02:34:18.552Z","etag":null,"topics":["graphprotocol"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/semiotic-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-30T20:57:07.000Z","updated_at":"2024-09-17T01:11:11.000Z","dependencies_parsed_at":"2024-01-11T23:45:36.517Z","dependency_job_id":"8614d9d4-e80b-470b-973f-ffed92d15d91","html_url":"https://github.com/semiotic-ai/autoagora","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semiotic-ai%2Fautoagora","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semiotic-ai%2Fautoagora/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semiotic-ai%2Fautoagora/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/semiotic-ai%2Fautoagora/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/semiotic-ai","download_url":"https://codeload.github.com/semiotic-ai/autoagora/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253492529,"owners_count":21916959,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphprotocol"],"created_at":"2024-08-03T16:01:02.154Z","updated_at":"2025-05-10T22:31:23.072Z","avatar_url":"https://github.com/semiotic-ai.png","language":"Python","funding_links":[],"categories":["Participating on The Graph's decentralized network"],"sub_categories":["Indexers"],"readme":"[![Coveralls](https://img.shields.io/coveralls/github/semiotic-ai/autoagora)](https://coveralls.io/github/semiotic-ai/autoagora)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat\u0026labelColor=ef8336)](https://pycqa.github.io/isort/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits\u0026logoColor=white)](https://conventionalcommits.org)\n[![Semantic Versioning](https://img.shields.io/badge/semver-2.0.0-green)](https://semver.org/spec/v2.0.0.html)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Docs](https://img.shields.io/github/actions/workflow/status/semiotic-ai/autoagora/semver.yml?label=docs)](https://semoitic-ai.github.io/autoagora/)\n\n# AutoAgora\n\n**AutoAgora is *beta* software. Please use responsibly, monitor it (Prometheus metrics)\n, [write issues and contribute](CONTRIBUTING.md)!**\n\nAn [Agora](https://github.com/graphprotocol/agora) cost model automation tool for The Graph indexers:\n\n- Automates the creation of relative prices for commonly seen query skeletons. (Off by default).\n- Continuously tunes a per-subgraph absolute price multiplier, using continuous online reinforcement learning.\n\n## Indexer's guide\n\n### ⚠️ WARNING\n\nNote that, as of as of [indexer v0.20.20](https://github.com/graphprotocol/indexer/releases/tag/v0.20.20), AutoAgora\nworks only with The Graph's protocol on *Ethereum mainnet*. This is due to the indexer stack not yet supporting cost\nmodels on Arbitrum (as of [v0.20.20](https://github.com/graphprotocol/indexer/releases/tag/v0.20.20)).\n\nAs such, `--indexer-service-metrics-endpoint` should only point to the `indexer-service` instances operating on the\n*Ethereum mainnet* protocol, as it would otherwise make decisions based on wrong observations.\n\n### Installation\n\nWe recommend using the AutoAgora container at `ghcr.io/semiotic-ai/autoagora`.\n\n### Build\n\nIf you'd like to build the container yourself, we recommend that you download the repo with `git` rather than\ndownloading a tarball:\n\n```console\ngit clone https://github.com/semiotic-ai/autoagora.git\n```\n\nSo that the build process can read the `git` metadata from the repo:\n\n```console\ncd autoagora\ndocker build -t autoagora .\n```\n\n### Usage\n\nFor AutoAgora's relative query costs generator, you will also need to set up:\n\n- [AutoAgora indexer-service](https://github.com/semiotic-ai/autoagora-indexer-service)\n- [AutoAgora Processor](https://github.com/semiotic-ai/autoagora-processor)\n\nAutoAgora will continuously:\n\n- Watch for the indexer's current allocations by querying the `indexer-agent`'s management GraphQL endpoint.\n- Analyze the query logs stored in a PostgreSQL database (relative query costs generator) -- logs that were previously\n  processed by the `AutoAgora indexer-service` wrapper and the `AutoAgora Processor`.\n- Gather query metrics from the `indexer-service`'s prometheus metrics endpoint.\n- Update the allocated subgraph's cost models by sending mutations to the `indexer-agent`'s management GraphQL endpoint.\n\nTherefore, only a single instance of `AutoAgora` should be running against an `indexer-agent`.\n\nConfiguration:\n\n```txt\nusage: autoagora [-h] [--log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}] [--json-logs JSON_LOGS]\n                 --postgres-host POSTGRES_HOST [--postgres-port POSTGRES_PORT]\n                 [--postgres-database POSTGRES_DATABASE] --postgres-username POSTGRES_USERNAME\n                 --postgres-password POSTGRES_PASSWORD\n                 [--postgres-max-connections POSTGRES_MAX_CONNECTIONS]\n                 --indexer-agent-mgmt-endpoint INDEXER_AGENT_MGMT_ENDPOINT\n                 [--indexer-agent-protocol-network INDEXER_AGENT_PROTOCOL_NETWORK]\n                 (--indexer-service-metrics-endpoint INDEXER_SERVICE_METRICS_ENDPOINT | --indexer-service-metrics-k8s-service INDEXER_SERVICE_METRICS_K8S_SERVICE)\n                 [--qps-observation-duration QPS_OBSERVATION_DURATION] [--relative-query-costs]\n                 [--relative-query-costs-exclude-subgraphs RELATIVE_QUERY_COSTS_EXCLUDE_SUBGRAPHS]\n                 [--relative-query-costs-refresh-interval RELATIVE_QUERY_COSTS_REFRESH_INTERVAL]\n                 [--manual-entry-path MANUAL_ENTRY_PATH]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --log-level {DEBUG,INFO,WARNING,ERROR,CRITICAL}\n                        [env var: LOG_LEVEL] (default: WARNING)\n  --json-logs JSON_LOGS\n                        Output logs in JSON format. Compatible with GKE. [env var: JSON_LOGS]\n                        (default: False)\n  --indexer-agent-mgmt-endpoint INDEXER_AGENT_MGMT_ENDPOINT\n                        URL to the indexer-agent management GraphQL endpoint. [env var:\n                        INDEXER_AGENT_MGMT_ENDPOINT] (default: None)\n  --indexer-agent-protocol-network INDEXER_AGENT_PROTOCOL_NETWORK\n                        Network identifier of the Graph network to operate on. Uses the network\n                        identifier format expected by the indexer-agent. [env var:\n                        INDEXER_AGENT_PROTOCOL_NETWORK] (default: eip155:1)\n  --qps-observation-duration QPS_OBSERVATION_DURATION\n                        Duration of the measurement period of the query-per-second after a price\n                        multiplier update. [env var: QPS_OBSERVATION_DURATION] (default: 60)\n  --manual-entry-path MANUAL_ENTRY_PATH\n                        Path to find manual agora entries, this expects Agora model files named\n                        {subgraph_hash}.agora [env var: MANUAL_ENTRY_PATH] (default: None)\n\nDatabase settings:\n  Must be the same database as AutoAgora Processor's if the relative costs models generator is\n  enabled.\n\n  --postgres-host POSTGRES_HOST\n                        Host of the postgres instance to be used by AutoAgora. [env var:\n                        POSTGRES_HOST] (default: None)\n  --postgres-port POSTGRES_PORT\n                        Port of the postgres instance to be used by AutoAgora. [env var:\n                        POSTGRES_PORT] (default: 5432)\n  --postgres-database POSTGRES_DATABASE\n                        Name of the database to be used by AutoAgora. [env var:\n                        POSTGRES_DATABASE] (default: autoagora)\n  --postgres-username POSTGRES_USERNAME\n                        Username for the database to be used by AutoAgora. [env var:\n                        POSTGRES_USERNAME] (default: None)\n  --postgres-password POSTGRES_PASSWORD\n                        Password for the database to be used by AutoAgora. [env var:\n                        POSTGRES_PASSWORD] (default: None)\n  --postgres-max-connections POSTGRES_MAX_CONNECTIONS\n                        Maximum postgres connections (internal pool). [env var:\n                        POSTGRES_MAX_CONNECTIONS] (default: 1)\n\nIndexer-service metrics endpoint. Exactly one argument required:\n  --indexer-service-metrics-endpoint INDEXER_SERVICE_METRICS_ENDPOINT\n                        HTTP endpoint for the indexer-service metrics. Can be a comma-separated\n                        for multiple endpoints. [env var: INDEXER_SERVICE_METRICS_ENDPOINT]\n                        (default: None)\n  --indexer-service-metrics-k8s-service INDEXER_SERVICE_METRICS_K8S_SERVICE\n                        Kubernetes service name for the indexer-service and pod port serving its\n                        metrics. Will watch the service's endpoint IPs continuously for changes.\n                        Format: \u003cscheme\u003e://\u003cservice_name\u003e:\u003cpod_metrics_port\u003e/\u003cpath\u003e. [env var:\n                        INDEXER_SERVICE_METRICS_K8S_SERVICE] (default: None)\n\nRelative query costs generator settings:\n  --relative-query-costs\n                        (EXPERIMENTAL) Enables the relative query cost generator. Otherwise only\n                        builds a default query pricing model with automated market price\n                        discovery. [env var: RELATIVE_QUERY_COSTS] (default: False)\n  --relative-query-costs-exclude-subgraphs RELATIVE_QUERY_COSTS_EXCLUDE_SUBGRAPHS\n                        Comma delimited list of subgraphs (ipfs hash) to exclude from the\n                        relative query costs model generator. [env var:\n                        RELATIVE_QUERY_COSTS_EXCLUDE_SUBGRAPHS] (default: None)\n  --relative-query-costs-refresh-interval RELATIVE_QUERY_COSTS_REFRESH_INTERVAL\n                        (Seconds) Interval between rebuilds of the relative query costs models.\n                        [env var: RELATIVE_QUERY_COSTS_REFRESH_INTERVAL] (default: 3600)\n\n If an arg is specified in more than one place, then commandline values override environment\nvariables which override defaults.\n```\n\nAutoAgora also exposes metrics for Prometheus on port `8000` (Example values):\n\n```txt\n# HELP bandit_reward Reward of the bandit training: queries_per_second * price_multiplier.\n# TYPE bandit_reward gauge\nbandit_reward{subgraph=\"QmRDGLp6BHwiH9HAE2NYEE3f7LrKuRqziHBv76trT4etgU\"} 1.577651313168855e-07\n# HELP bandit_price_multiplier Price multiplier sampled from the Gaussian model.\n# TYPE bandit_price_multiplier gauge\nbandit_price_multiplier{subgraph=\"QmRDGLp6BHwiH9HAE2NYEE3f7LrKuRqziHBv76trT4etgU\"} 2.60150080442184e-07\n# HELP bandit_stddev Standard deviation of the Gaussian price multiplier model.\n# TYPE bandit_stddev gauge\nbandit_stddev{subgraph=\"QmRDGLp6BHwiH9HAE2NYEE3f7LrKuRqziHBv76trT4etgU\"} 1.843469500541687\n# HELP bandit_mean Mean of the Gaussian price multiplier model.\n# TYPE bandit_mean gauge\nbandit_mean{subgraph=\"QmRDGLp6BHwiH9HAE2NYEE3f7LrKuRqziHBv76trT4etgU\"} 3.653126148672616e-05\n```\n\nWhere \"bandit\" refers to the reinforcement learning method (Continuum-armed bandit) used to track the market price for\neach subgraph.\n\n## Developer's guide\n\nIf you would like to contribute, please consult [`CONTRIBUTING.md`](CONTRIBUTING.md).\n\n### Installation directly from the source code\n\nTo install AutoAgora directly from the source code please clone the repository and install package in the virtual\nenvironment using `poetry`:\n\n```console\ngit clone https://github.com/semiotic-ai/autoagora.git\ncd autoagora\npoetry install\n```\n\n### Running the AutoAgora code\n\nAll scripts should be executed in the virtual environment managed by `poetry`.\n\n### Running the test suite\n\n```console\npoetry run python -m pytest\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemiotic-ai%2Fautoagora","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsemiotic-ai%2Fautoagora","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsemiotic-ai%2Fautoagora/lists"}