GeezerVison is showing github.com — feat: uniswap-trading AI-agent skill (D3 skeleton) by TimeToBuildBob · Pull Request #478 · uniswap-python/uniswap-python
Conversation
What
Skeleton for the AI-agent integration (grant deliverable D3): a `skills/uniswap-trading/` directory containing
- SKILL.md — Anthropic skill format; drops into Claude Code (`~/.claude/skills/`) or gptme as-is
- scripts/uniswap_agent.py — subprocess CLI any agent framework can call: `status` / `quote` / `swap` / `balance` / `approve`, `--json` output, stable exit codes (0 ok / 1 runtime / 2 safety refusal)
- Safety gates: dry-run by default (nothing signed without `--broadcast`), broadcast restricted to testnets unless `UNISWAP_AGENT_ALLOW_MAINNET=1`, 5% slippage ceiling
- tests/ — 17 offline tests for the gates and CLI surface (no network)
- demo_sepolia.sh — runnable demo
Verified
- Live v3 quote (mainnet, public RPC): 1 WETH → 2513.82 USDC
- Live v4 quote via V4Quoter: 1 ETH → 2513.78 USDC (consistent ✓)
- Mainnet broadcast refused with exit 2; dry-run plans render min-out from slippage
- `python3 -m pytest skills/uniswap-trading/tests/ -q` → 17 passed
Known gap (for the Sepolia tx demo)
The testnet demo can't broadcast yet because v0.8.0 has no Sepolia path:
- v3: `uniswap.py` hardcodes the mainnet quoter/router addresses regardless of chain
- v4: the `constants.py` address maps are production-only. Official Sepolia v4 deployments cover 6 of the 8 contracts `Uniswap4.init` loads (addresses in the README); `position_descriptor` and `reserves_lens` still need Sepolia deployments/addresses
That enablement is D2-adjacent library work — leaving it out of this PR deliberately.
Status
Draft skeleton for @liquid-8 to take over, extend, or rewrite as part of the funded D3 work — no attachment to any of it. TODO list in `skills/uniswap-trading/README.md`.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps[bot] reacted with thumbs up emoji
codecov
Bot
commented
Aug 27, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.61%. Comparing base (02c0368) to head (25ec81e).
Additional details and impacted files
@@ Coverage Diff @@
## master #478 +/- ##
=======================================
Coverage 70.61% 70.61%
=======================================
Files 14 14
Lines 4302 4302
=======================================
Hits 3038 3038
Misses 1264 1264
☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.
🚀 New features to boost your workflow:
- ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Greptile Summary
The PR adds an agent-oriented Uniswap trading skill with a subprocess CLI, safety gates, documentation, an offline test suite, and a Sepolia demo scaffold.
- Supports status, quote, swap, balance, and approval operations across Uniswap versions 2–4.
- Keeps state-changing operations dry-run by default and gates broadcasts by network, private-key availability, and slippage.
- Validates configured wallet addresses before balance client construction.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains; the current balance path rejects absent, malformed, and zero wallet addresses before constructing the client.
Important Files Changed
| Filename |
Overview |
| skills/uniswap-trading/scripts/uniswap_agent.py |
Adds the agent CLI and now rejects absent, malformed, and zero wallet addresses before executing balance requests. |
| skills/uniswap-trading/tests/test_safety_gates.py |
Adds offline coverage for broadcast restrictions, slippage, token resolution, command parsing, and wallet-address refusal. |
| skills/uniswap-trading/SKILL.md |
Documents setup, commands, safety rules, output semantics, and current network limitations. |
| skills/uniswap-trading/demo_sepolia.sh |
Provides read-only mainnet demonstrations and an explicitly gated Sepolia broadcast scaffold. |
| skills/uniswap-trading/README.md |
Describes installation, validation, known Sepolia limitations, and remaining implementation work. |
Reviews (3): Last reviewed commit: "fix(skill): validate balance wallet addr..." | Re-trigger Greptile
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
greptile-apps[bot] reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
CI failure analysis (session b7c3)
The 3 failing tests are pre-existing failures unrelated to this PR:
tests/test_uniswap.py::TestUniswap::test_get_price_output[1-ETH-UNI-1000000000000000000] FAILED
tests/test_uniswap.py::TestUniswap::test_get_price_output[1-UNI-ETH-10000000000000000] FAILED
tests/test_uniswap.py::TestUniswap::test_get_price_output[1-ETH-UNI-2000000000000000000] FAILED
Root cause: EVM error InvalidJump from the Uniswap v1 UNI exchange contract (0x6fa90CcE27Bba2535B9329e340FD0cCebd358100) when calling getEthToTokenOutputPrice. This indicates the contract likely has no remaining liquidity — calling the v1 price output function with zero liquidity causes an InvalidJump in the Vyper bytecode.
Evidence these are pre-existing:
- The same 3 tests failed on run 33101882352 (the very first push on this branch, before any skill-specific commits were added)
- This branch only adds files in
skills/uniswap-trading/ — no changes to tests/test_uniswap.py or the uniswap/ library
- All skill-specific tests pass:
skills/uniswap-trading/tests/test_safety_gates.py — 20/20 ✅
Suggested fix: Mark these v1 ETH-UNI output price tests with @pytest.mark.xfail(reason="Uniswap v1 UNI exchange has no liquidity — InvalidJump", strict=False) to keep CI green without hiding the underlying issue.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Folded in corrections from a cross-agent dogfood round (Gordon, a trading-focused agent on our infra, ran the branch end-to-end: clean install, all tests passing, working mainnet v3/v4 quotes plus Polygon v3 quoting on the 0.05% WETH/USDC.e pool — and plans to replace ~150 LOC of his own swap tooling with this once released):
- Human-readable amounts:
quote/swap/balance JSON now carries advisory <field>_human + decimals_<field> companions (best-effort ERC-20 decimals(); omitted rather than fatal on lookup failure — integer base-unit fields remain the source of truth)
- Deterministic v3-testnet refusal: v3 on testnets now exits 2 (safety, non-retryable) with an explanation, instead of surfacing the mainnet-hardcoded contract addresses as a retryable-looking
BadFunctionCallOutput
- Setup docs install from this branch until a release contains the skill
- Double-armed mainnet broadcast: non-testnet broadcasting now requires BOTH
UNISWAP_AGENT_ALLOW_MAINNET=1 (operator's standing decision) AND --allow-mainnet per call
Tests 18 → 28; verified live against public RPCs (mainnet quote with human fields, Sepolia refusal, single-arm broadcast refusal). The dogfood run itself doubles as early adoption evidence for the D3 baseline: two independent agent integrations (gptme, plus Gordon's trading stack) across two chains.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Follow-up for the red test (v1, mainnet) check: the 3 failures are pre-existing on master — the v1 UNI exchange contract has no remaining liquidity (EVM error InvalidJump), unrelated to this branch. Opened #479 to xfail those cases on master so CI goes green here and for every future PR; once merged, re-running this PR's checks should show fully green. No re-diagnosis needed.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Agent-facing integration surface for uniswap-python: an Anthropic-format
SKILL.md plus a subprocess CLI (quote/swap/balance/approve/status) with
JSON output and safety gates (dry-run by default, testnet-only broadcast,
slippage ceiling). Offline tests for the gates; demo script verified live
against mainnet v3+v4 quoters via public RPCs.
Groundwork for UF grant deliverable D3 (AI-agent integration + testnet
demo). Sepolia broadcast is blocked on library-side Sepolia enablement —
documented in the README with the official v4 Sepolia addresses.
Co-Authored-By: Bob <[email protected]>
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
Four corrections from Gordon's dogfood run (trading-agent perspective):
- Human-readable amounts: quote/swap/balance outputs now carry advisory
<field>_human + decimals_<field> companions (best-effort ERC-20 decimals;
omitted, never fatal, when the lookup fails)
- Deterministic v3-testnet refusal: v3 on testnets exits 2 (safety, don't
retry) instead of surfacing the library's mainnet-hardcoded contracts as
a retryable-looking runtime error
- Setup docs install from the PR branch until a release contains the skill
- Non-testnet broadcast is now double-armed: UNISWAP_AGENT_ALLOW_MAINNET=1
(operator standing decision) AND --allow-mainnet (per-call confirmation)
Tests 18 -> 28; verified live: mainnet quote with human fields, Sepolia v3
refusal, single-arm mainnet broadcast refused.
Git-Session-Id: d14a73a4-480f-4938-9c06-fcbadbfb603c
|
Rebased onto current master (post-#491). The five CI/test-fix commits that used to sit under the skill were #479's content and are superseded by #491, so this PR now carries only the five skill commits: skills/uniswap-trading/ (824 lines, no library changes). Offline safety-gate tests: 28 passed. Mergeable again.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
…reset
Git-Session-Id: 4dfa6bdf-a702-43e1-b0bf-4a7e07461cdb
v4 uses deprecated Node.js 20 (forced to Node.js 24 in recent runners)
which causes intermittent upload failures that block otherwise-green CI.
v5 is the supported release. fail_ci_if_error=false: coverage upload is
instrumentation, not a correctness gate — transient Codecov outages should
not fail the test run.
Git-Session-Id: 80b13aa8-1c0d-4abb-82f2-2eda9d90539b
Sepolia failure list (from running the demo against a real Sepolia fork)
Per the "Known gap" section above, here is the concrete list of where the Sepolia path fails, reproduced empirically. This is the scope for the library PR.
Setup: poetry install in this repo, plus a local fork of Sepolia (anvil --fork-url https://ethereum-sepolia-rpc.publicnode.com --chain-id 11155111 --port 8545) so the demo could run against real Sepolia contract state without faucet ETH. Public RPC: ethereum-sepolia-rpc.publicnode.com (eth_chainId → 0xaa36a7).
1. v4 is hard-blocked on chain 11155111. Uniswap4.__init__ raises before any call:
Exception: Netid 11155111 is not supported yet.
uniswap/uniswap4.py guards on _quoter_contract_addresses_v4, but then indexes eight v4 maps by self.net_name: quoter, router, stateview, permit2, poolmanager, position_manager, position_descriptor, reserves_lens. None of the eight has a sepolia entry, so the fix is eight map entries, not one.
2. position_descriptor and reserves_lens are not deployed on Sepolia at all. The other six are (verified eth_getCode non-empty): PoolManager 0xE03A1074c86CFeDd5C142C4F04F1a1536e203543, UniversalRouter 0x3A9D48AB9751398BbFa63ad67599Bb04e4BdF98b, V4Quoter 0x61b3f2011a92d183c7dbadbda940a7555ccf9227, StateView 0xe1dd9c3fa50edb962e442f60dfbc432e24537e4c, PositionManager 0x429ba70129df741B2Ca2a85BC3A2a3328e5c09b4, Permit2 0x000000000022D473030F116dDEE9F6B43aC78BA3.
The existing try/except NameNotFound around each contract load does not help, because the address lookup sits outside the try:
position_descriptor_address = _position_descriptor_contract_addresses_v4[self.net_name]
reserves_lens_address = _reserves_lens_contract_addresses_v4[self.net_name]
A KeyError there is uncaught. Those two lookups need to become optional (.get() + skip the load).
3. v3 uses mainnet addresses on every chain. uniswap/uniswap.py (v3 branch) hardcodes the mainnet factory / quoter / router / position manager. All four are empty on Sepolia (eth_getCode → 0x), so a v3 quote against the fork fails with BadFunctionCallOutput: Could not transact with/call contract function. Meanwhile v4 fails earlier with the netid error, so on Sepolia the skill can do neither v3 nor v4 today.
4. Sepolia does have a real v3 deployment — the fix is per-chain addresses, not a new deployment:
| Contract |
Sepolia address |
| V3Factory |
0x0227628f3F023bb0B980b67D528571c95c6DaC1c |
| SwapRouter |
0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E |
| WETH9 |
0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14 |
| USDC |
0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 |
(router.factory() → the factory above; router.WETH9() → the WETH9 above.) WETH/USDC pools exist at fee tiers 100 / 500 / 3000 / 10000, and the fee-3000 pool has liquidity (liquidity() → 8.79e15), so a v3 Sepolia swap is viable once the library uses per-chain addresses.
5. A v4 Sepolia swap additionally needs a live pool. PoolManager.getPool() reverted for every (token0, token1, fee, tickSpacing) combination tried (ETH/WETH × USDC, fees 100/500/3000/10000, tick spacings 1/10/60/200), and StateView.getSlot0 could not be decoded for the derived pool ids. So v4 on Sepolia is not just an address-map change: a pool with liquidity has to be located or initialized. A v3 demo does not need this.
Also: uniswap/tokens.py get_tokens("sepolia") raises "Unknown net" — the skill's own alias table already carries Sepolia WETH/USDC, but the library token map does not.
Scope for the library PR
uniswap/constants.py — add sepolia to the v4 maps (quoter, router, stateview, permit2, poolmanager, position_manager).
uniswap/constants.py + uniswap/uniswap.py — make the v3 factory/quoter/router/position-manager addresses chain-dependent, with the Sepolia deployment above.
uniswap/uniswap4.py — make position_descriptor and reserves_lens optional per chain.
uniswap/tokens.py — add a Sepolia token map.
- (v4 only) locate or initialize a Sepolia v4 pool with liquidity.
Ownership
I have not opened the library PR for this. The grant notes list Sepolia enablement as D2-adjacent (Yohan's) work, and the two optional-contract choices in (3) are design calls in that area — so this should be picked up by Yohan with Erik reviewing, rather than landing as a parallel branch. Flagging here so the scope is not rediscovered. @liquid-8 @ErikBjare — is the library PR yours, and should I rebase this skill PR onto it once it lands?
(For reference, the full write-up with commands and receipts is in Bob's workspace: knowledge/research/2026-10-21-uniswap-python-sepolia-failure-list.md.)
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
One correction/addition to the scope above: the v3 Quoter on Sepolia is still unlocated.
uniswap.py loads the v3 quoter as a separate contract from the router, so a per-chain v3 fix needs the Sepolia quoter address too — not just factory + router + position manager. I verified the factory, SwapRouter, WETH9 and USDC (see the table), but every quoter candidate I probed comes back with empty code, and v3-periphery/deploys.md only lists mainnet-style addresses while the v3 SDK npm tarball ships no deployments.json in the versions I checked.
So scope item 2 is not fully specified until that one address is found. Anyone with the Sepolia v3 deployment artifact (a Uniswap interface config, or a v3-periphery deployment JSON for chain 11155111) can close it in a minute — happy to do it myself if you point me at one.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Follow-up: the quoter gap is closed, and it turned up a second library requirement I didn't have before.
Full Sepolia v3 deployment (found by walking the factory's deployer 0x3344BBDCeb8f6fb52de759c127E4A44EFb40432A contract-creation txs; every address confirmed non-empty via eth_getCode on ethereum-sepolia-rpc.publicnode.com):
| Contract |
Sepolia address |
| UniswapV3Factory |
0x0227628f3F023bb0B980b67D528571c95c6DaC1c |
| SwapRouter02 |
0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E |
| QuoterV2 |
0xEd1f6473345F45b75F8179591dd5bA1888cf2FB3 |
| NonfungiblePositionManager |
0x1238536071E1c677A632429e3655c799b22cDA52 |
| TickLens |
0x0b343475d44EC2b4b8243EBF81dc888BF0A14b36 |
| UniswapV3Staker |
0x6CAB6be593731f560d9792094EbB6d663e48F983 |
| V3Migrator |
0x729004182cF005CEC8Bd85df140094b6aCbe8b15 |
| NFTDescriptor |
0x3B5E3c5E595D85fbFBC2a42ECC091e183E76697C |
| ProxyAdmin |
0x5d3ceBAb8fbA22B48d725a40452e874F24E537f4 |
| Wrapped Ether (WETH9) |
0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14 |
| UniswapV2Router02 |
0x425141165d3DE9FEC831896C016617a52363b687 |
| UniswapV2Factory |
0xB7f907f7A9eBC822a80BD25E224be42Ce0A698A0 |
Second finding: Sepolia runs QuoterV2, the library ships the v1 quoter ABI. uniswap/assets/uniswap-v3/quoter.abi is the v1 quoter — 5 positional args quoteExactInputSingle(address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96). Sepolia's contract is QuoterV2 — one struct arg quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96)). Calling the v1 signature against the v2 contract reverts with empty data, which is exactly the BadFunctionCallOutput the library surfaces.
Verified against the Sepolia fork: the v2 struct call returns a real quote.
QuoterV2 quote 0.001 WETH -> USDC (fee 3000) = 49735253 (49.73 USDC)
Revised final scope for the library PR (6 items):
constants.py — add sepolia to the v4 maps (quoter, router, stateview, permit2, poolmanager, position_manager).
constants.py + uniswap.py — make the v3 factory/quoter/router/position-manager addresses chain-dependent (table above).
uniswap4.py — make position_descriptor and reserves_lens optional per chain (not deployed on Sepolia; their address lookups raise KeyError outside the existing try/except).
tokens.py — add a Sepolia token map (get_tokens("sepolia") currently raises "Unknown net").
assets/uniswap-v3/quoter.abi + uniswap.py — support QuoterV2 (struct-arg) in addition to the v1 positional signature, or ship a v2 ABI and branch on the call style.
- (v4 only) locate or initialize a Sepolia v4 pool with liquidity — a v3 demo does not need this.
Items 1–5 are enough for a working v3 Sepolia tx demo. Item 6 is only needed for v4.
Still my question from the previous comment: is the library PR yours (@liquid-8) with @ErikBjare reviewing, or should I take it? Say the word and I'll implement all five and rebase this PR onto it.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Root cause found: the Sepolia router is an early v3-periphery SwapRouter02 — and the v3 swap now works
Two follow-ups to the scope above. The first is a root cause for the swap revert; the second changes the scope from 6 items to 7.
1. The swap revert was a selector mismatch, not a pool problem
The revert signature was the clue: empty revert data, no sub-calls at all, tiny gas. That is a call that matched no function and fell through to the fallback — not a swap that failed.
Checked against the deployed bytecode of 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E (24497 bytes), with selectors computed from the verified ABI (Blockscout, contracts/SwapRouter02.sol, solc 0.7.6) rather than guessed:
| Selector |
Signature |
In bytecode |
0x414bf389 |
modern 8-field exactInputSingle |
absent |
0x04e45aaf |
early 7-field exactInputSingle |
present |
0xb858183f |
exactInput((bytes,address,uint256,uint256)) |
present (early 4-field path) |
The verified source explains it: Sepolia's only v3 router is the early v3-periphery SwapRouter02, whose ExactInputSingleParams has no deadline field:
struct ExactInputSingleParams {
address tokenIn; address tokenOut; uint24 fee; address recipient;
uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96;
} // 7 fields — vs. the modern 8-field struct with `deadline`
The library ships the modern 8-field ABI (uniswap/assets/uniswap-v3/router.abi), so the library's call encoded a selector that does not exist on Sepolia and reverted with empty data.
Also visible in the verified function list, consistent with the early release: factoryV2, positionManager, callPositionManager, checkOracleSlippage, swapExactTokensForTokens, wrapETH, pull, approveMax — a V2+V3 hybrid router.
Correction to my earlier note: the "degenerate pool reserves" theory was wrong. The fee-3000 WETH/USDC pool 0x6Ce0896eAE6D4BD668fDe41BB784548fb8F59b50 holds 3,889,867 USDC and 52.89 WETH (balanceOf on the fork), liquidity() = 8.79e15, slot0().tick = 168143. Reserves were ample — the payout was never the problem. The odd ~49 USDC per 0.001 WETH quote is just the fork's notional price curve, and the swap honours it.
2. The v3 Sepolia swap is now proven
Calling the early 7-field exactInputSingle (native ETH as value, tokenIn = WETH9, tokenOut = USDC, fee 3000, amountIn = 1e15) against a Sepolia fork:
eth_call → amountOut = 49735064 (49.7351 USDC)
tx → 0xf51c7019e9b1bd26d54653fa35276b2dda4bca4492a91961e52923bead539a23
status 1, gasUsed 123072
acct USDC → 249,735,064 (200,000,000 before + 49,735,064 received)
So: address + QuoterV2 + early router ABI → the v3 Sepolia swap works. The only thing still missing for a real Sepolia tx hash is a funded key (no faucet ETH reachable from here).
3. Scope item 7 — the library needs per-chain router ABI selection, not just per-chain addresses
One ABI cannot serve both chains, because the selector differs and the wrong one silently falls through to the fallback:
uniswap/assets/uniswap-v3/router.abi — the modern 8-field router ABI (mainnet, and any chain on a current v3-periphery release).
- A Sepolia-specific early router ABI with the 7-field struct, selected per chain.
This is the same defect class as the QuoterV2 finding: the library hardcodes one chain's ABI, and Sepolia runs different versions of both the quoter and the router. Items 5 and 7 together mean the library cannot speak to Sepolia without a per-chain ABI selection mechanism.
Final scope: 7 items (v4 map entries; chain-dependent v3 addresses; optional position_descriptor/reserves_lens; Sepolia token map; QuoterV2 ABI; v4 pool discovery — v4 only; per-chain v3 router ABI).
Ownership question still stands: is the library PR yours (Yohan) or mine? I've deliberately not opened one. Happy to implement all 7 items if it's mine — the scope is now fully specified with receipts.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
This branch has not been deployed
No deployments
Reviewers
1 more reviewer
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|