Skip to content

fix: harden amount sanity checks for CoW order and swap flows#225

Draft
twblack88 wants to merge 7 commits into
mainfrom
fix/ss-5630-limit-order-base-units
Draft

fix: harden amount sanity checks for CoW order and swap flows#225
twblack88 wants to merge 7 commits into
mainfrom
fix/ss-5630-limit-order-base-units

Conversation

@twblack88
Copy link
Copy Markdown
Contributor

@twblack88 twblack88 commented Apr 22, 2026

Summary

  • harden limit, stop-loss, and TWAP inputs against base-unit style amounts and reduce LLM-visible base-unit leakage in tool outputs
  • add limit-order market sanity checks, including a guard for USD-price-vs-pair-price mixups on crypto-to-crypto pairs
  • improve swap amount safety by adding base-unit input validation and surfacing USD-amount guidance after insufficient-balance checks

Test plan

  • Place ARB -> USDC limit order and confirm human-readable amounts (no base-unit leakage)
  • Verify sub-dollar pair price inversion/USD-price mistakes fail with actionable errors
  • Verify stop-loss and TWAP reject base-unit-like sell amounts
  • Verify large legitimate swaps are not blocked when balance is sufficient
  • Verify insufficient-balance swap errors include USD-flow guidance when amount likely came from USD intent

Made with Cursor

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Added validation across swap and order creation tools to prevent users from accidentally submitting base unit amounts instead of human-readable token quantities
    • Implemented price validation for limit orders to detect inverted or incorrectly specified prices
    • Enhanced error messaging to guide users toward correct input formats when balance or unit conversion issues occur

Add base-unit input guards and stronger schema guidance for limit, stop-loss, and TWAP tools, plus LLM-visible output filtering to prevent base-unit field leakage. Also add limit price market-deviation sanity checks to catch inverted or wildly incorrect sub-dollar pricing.

Made-with: Cursor
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
shapeshift-agentic Ready Ready Preview, Comment Apr 27, 2026 5:13pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7a873b92-c81a-4c9b-9a36-731720bfe852

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request removes all environment variables from .env, adds Nx build cache metadata and workspace configuration files, enables an NX console setting in VS Code, and enhances validation logic across multiple trading tool implementations with stricter input constraints and price sanity checks.

Changes

Cohort / File(s) Summary
Environment & Configuration
.env, .vscode/settings.json
Removed all environment variable definitions from .env; added nxConsole.generateAiAgentRules: true setting in VS Code workspace config.
Nx Build Cache
.nx/cache/*.commit, .nx/cache/run.json, .nx/cache/terminalOutputs/*
Added multiple Nx cache entries tracking build task execution state, terminal output logs (TypeScript builds and Vite production build), and run metadata with cache hit statuses.
Nx Cloud Login Assets
.nx/cache/cloud/2506.06.6.hotfix1/package.json, .nx/cache/cloud/2506.06.6.hotfix1/static/login-*.html
Added Nx Cloud client bundle package definition and login flow HTML templates (with countdown redirect and completion pages) for authentication workflow.
Nx Workspace Metadata
.nx/workspace-data/eslint-*.hash, .nx/workspace-data/file-map.json, .nx/workspace-data/lockfile.hash, .nx/workspace-data/playwright-*.hash, .nx/workspace-data/react-router-*.hash, .nx/workspace-data/source-maps.json, .nx/workspace-data/tsc-*.hash, .nx/workspace-data/tsconfig-files.hash, .nx/workspace-data/vite-*.hash
Added comprehensive Nx workspace metadata including TypeScript/ESLint/Vite/Playwright target configurations, project file mappings, source map registrations, and build task definitions.
Server Tool Validation Enhancements
apps/agentic-server/src/tools/initiateSwap.ts, apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts, apps/agentic-server/src/tools/stopLoss/createStopLoss.ts, apps/agentic-server/src/tools/twap/createTwap.ts
Strengthened input validation across swap/limit-order/stop-loss/TWAP tools with base-unit detection (15+ digit rejection), enhanced error messaging for USD-as-token scenarios, added price sanity checks comparing provided prices against market USD rates, and configured experimental_toToolResultContent for LLM-visible result serialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop, hop, the cache files grow,
Validation guards now steal the show,
Base units caught, prices aligned,
A swap so safe, the user's peace of mind!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main change: hardening amount sanity checks for CoW (Coincidence of Wants) order and swap flows, which aligns with the core objectives of adding validation, price checks, and USD guidance.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ss-5630-limit-order-base-units

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@twblack88
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

♻️ Duplicate comments (7)
.nx/cache/terminalOutputs/13554052336615392278.commit (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This is a build cache artifact that should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/13554052336615392278.commit at line 1, The
committed Nx cache artifact
".nx/cache/terminalOutputs/13554052336615392278.commit" must be removed from the
repo and prevented from recurring: delete that file from the commit (or run git
rm --cached on it) and add a rule to ignore Nx cache files (e.g., add ".nx/" or
".nx/cache/" to .gitignore) so future cache artifacts are not tracked; ensure
the commit no longer contains the file before pushing.
.nx/cache/terminalOutputs/3221835782562372545 (1)

1-2: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This cached terminal output should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/3221835782562372545 around lines 1 - 2, Remove the
Nx cache file from the repository and ensure Nx cache is ignored: delete the
committed file entry (e.g., .nx/cache/terminalOutputs/3221835782562372545) from
the repo and commit that removal (use git rm --cached or equivalent), then add
the .nx/ directory or specifically .nx/cache/ to .gitignore so future cached
terminal outputs are not committed; verify by running git status to confirm the
file is no longer tracked.
.nx/cache/terminalOutputs/14206404844807895703 (1)

1-2: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This cached terminal output should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/14206404844807895703 around lines 1 - 2, Remove
the committed Nx cache file and ensure Nx cache is ignored: delete the file
(.nx/cache/terminalOutputs/14206404844807895703) from the repository, run git rm
--cached on it, and commit the removal; then add .nx/ (or at minimum .nx/cache/)
to .gitignore so future tsc --build outputs are not committed; finally verify no
other files under .nx/ are tracked and update the commit.
.nx/cache/terminalOutputs/3221835782562372545.commit (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This is a build cache artifact that should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/3221835782562372545.commit at line 1, A Nx build
cache artifact (terminalOutputs/*.commit) was committed; remove the file from
the repo and prevent future commits by adding the Nx cache pattern to .gitignore
and removing the file from Git's index: remove the specific committed file
(unstage/remove from commit), add "terminalOutputs/*.commit" or ".nx/cache/"
patterns to .gitignore, commit the .gitignore change, and ensure no other Nx
cache files remain staged; reference the committed artifact pattern
"terminalOutputs/*.commit" when locating the offending file.
.nx/cache/13554052336615392278.commit (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This is a build cache artifact that should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/13554052336615392278.commit at line 1, Remove the committed Nx
cache artifact and prevent future commits: delete the cache file (.nx/cache/...
.commit) from the repo, add the appropriate Nx cache patterns (e.g., .nx/ and/or
.nx/cache/) to .gitignore if not already present, and create a lightweight
commit that removes the file. Also ensure no CI step or script re-adds .nx cache
files to source control.
.nx/cache/terminalOutputs/14206404844807895703.commit (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This is a build cache artifact that should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/14206404844807895703.commit at line 1, Remove the
committed Nx build cache artifact from version control and stop tracking it:
remove the cached file from the index (git rm --cached) and commit that removal,
then add a .gitignore entry to ignore the Nx cache directory (e.g., the Nx cache
pattern) so it won’t be re-added; finally, ensure the cleanup commit is pushed
so CI and other collaborators no longer receive this build-cache artifact.
.nx/cache/terminalOutputs/17428515039638435960.commit (1)

1-1: ⚠️ Potential issue | 🔴 Critical

Do not commit Nx cache files.

This is a build cache artifact that should be excluded from version control.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/terminalOutputs/17428515039638435960.commit at line 1, The commit
contains an Nx build-cache artifact (file 17428515039638435960.commit) that must
be removed from version control; remove that file from the repository index (so
it’s no longer tracked), commit the removal, and add the Nx cache
directory/pattern to .gitignore so future cache files are not committed; finally
verify the change by committing the updated .gitignore and confirming the cache
file is absent from the repo and PR.
🧹 Nitpick comments (6)
.nx/cache/3221835782562372545.commit (1)

1-1: Remove Nx cache artifact from version control

This file looks like a generated local cache marker and should not be committed. Please remove .nx/cache/** tracked artifacts from the PR and ensure they’re ignored to avoid noisy diffs and merge churn.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/3221835782562372545.commit at line 1, Remove the generated Nx
cache artifact ".nx/cache/3221835782562372545.commit" from the commit and stop
tracking the .nx cache directory: delete the file from the repo index (git rm
--cached) so it’s removed from the PR, add the pattern ".nx/cache/**" to
.gitignore (or ensure existing ignore covers it), and commit the .gitignore
change so future cache files under .nx/cache are not tracked.
.nx/cache/7460006978003770812.commit (1)

1-1: Remove committed Nx cache artifact from source control.

Line 1 is a local cache marker (true) under .nx/cache, which should not be versioned in normal workflows. Please remove this file from the PR and ensure .nx/cache/ is gitignored to avoid noisy, non-functional diffs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/7460006978003770812.commit at line 1, Remove the committed Nx
cache artifact `.nx/cache/7460006978003770812.commit` from the PR by deleting
that file from the repository and removing it from the index (git rm --cached or
git rm), then ensure the `.nx/cache/` directory is listed in .gitignore so
future cache files are not committed; verify with git status and amend the
commit or create a follow-up commit that removes the file and adds `.nx/cache/`
to .gitignore.
.nx/cache/14206404844807895703.commit (1)

1-1: Exclude Nx cache artifacts from source control.

This file is a generated local cache marker and should not be committed. Keeping .nx/cache/** in git introduces noisy diffs and non-deterministic repository state. Please remove this artifact and ignore the cache directory.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/14206404844807895703.commit at line 1, Remove the generated Nx
cache marker file that was accidentally committed (the local cache artifact) and
stop tracking it: delete the committed cache artifact from the repository and
commit that deletion, and update the project ignore rules to add the Nx cache
directory pattern so it isn't re-committed (add the appropriate .nx cache
pattern to .gitignore or the repo's ignore file and commit that change). Ensure
you remove the file from git history/tracking (e.g., git rm or git rm --cached)
so future commits won't include the generated cache artifact.
.nx/workspace-data/tsconfig-files.hash (1)

1-1: Avoid committing Nx workspace cache artifacts

This file is generated local cache metadata and is unrelated to the functional changes in this PR. Keeping it in VCS increases noise and merge-conflict risk; please remove it from the PR and ensure .nx/workspace-data/** is gitignored (if not intentionally tracked).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/workspace-data/tsconfig-files.hash at line 1, The PR includes a
generated Nx workspace cache file that should not be committed; remove that file
from the commit (unstage and delete from the repo history if needed) and add a
gitignore rule to ignore the Nx workspace cache directory (add a pattern such as
.nx/workspace-data/** to .gitignore), then commit the .gitignore change and a
new commit that removes the cached file (use git rm --cached <file> if you want
to keep it locally) so the generated artifact is no longer tracked.
.nx/workspace-data/lockfile.hash (1)

1-1: Avoid committing Nx workspace cache hash artifacts.

Line 1 appears to be machine-generated workspace metadata (.nx/workspace-data/*). Tracking this in git usually causes noisy diffs and frequent conflicts without runtime benefit. Please remove it from version control and ensure this path is gitignored unless your repo intentionally versions Nx cache state.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/workspace-data/lockfile.hash at line 1, Remove the generated workspace
cache artifact lockfile.hash from version control and stop tracking future
changes: delete the tracked file (git rm --cached lockfile.hash or git rm
--cached .nx/workspace-data/lockfile.hash), add the workspace cache pattern to
.gitignore (e.g., ignore .nx/workspace-data/ or lockfile.hash) and commit that
change so the file is not committed again; if the repository intentionally
versions Nx cache state, instead document that decision in the repo README or CI
settings.
apps/agentic-server/src/tools/initiateSwap.ts (1)

299-305: Optional: consider tightening the 15-digit heuristic for ultra-high-supply tokens.

/^\d{15,}/ (no end anchor, no decimal point in the run) cleanly rejects base-unit integers while allowing fractional inputs. However, it will also reject legitimate integer amounts for ultra-high-supply memecoins (e.g., selling 1000000000000000 SHIB/PEPE/BONK = 1 quadrillion units is 16 digits but plausible as a human-readable amount). If that user flow matters, consider gating the rule on the asset's precision (e.g., only treat the input as base-unit-like when digit count ≥ precision), since the real failure mode is users pasting a value already scaled by 10**precision. Same pattern is duplicated across createLimitOrder.ts, createStopLoss.ts, and createTwap.ts — a shared helper would keep the behavior consistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/agentic-server/src/tools/initiateSwap.ts` around lines 299 - 305, The
/^\d{15,}/ heuristic in the sellAmount Zod refine (seen in initiateSwap.ts) can
false-positive for ultra-high-supply tokens; replace it with a precision-aware
check: fetch the asset's precision where sellAmount is validated (or accept a
precision parameter), strip whitespace, allow decimal points, and treat the
value as "base-unit-like" only when the integer digit count (digits before the
decimal) is >= precision (or a configured threshold), then fail with the same
message; extract this logic into a shared helper (used by createLimitOrder.ts,
createStopLoss.ts, createTwap.ts) so all validators call a function like
isBaseUnitLike(value, precision) instead of the hardcoded /^\d{15,}/ test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.nx/cache/17428515039638435960.commit:
- Line 1: Add an entry to the repository .gitignore to exclude Nx cache
artifacts by adding a line for ".nx/cache/" (or equivalent pattern like
".nx/cache/*") so .nx/cache/*.commit and related files are not tracked; update
the .gitignore file, commit that change, and then ensure any existing cached
files are removed from the index (git rm --cached) so future commits do not
include .nx/cache artifacts.

In @.nx/cache/cloud/2506.06.6.hotfix1/static/login-end.html:
- Around line 1-414: This PR accidentally includes generated Nx cache artifacts
under .nx/cache (example file shown), so remove the entire .nx/cache tree from
the commit and stop tracking it: remove those files from the branch
(unstage/delete them from VCS), add .nx/cache and .nx/workspace-data to
.gitignore, amend the commit (or create a new commit) and push the branch; do
not attempt to modify the upstream-generated HTML (it contains duplicate SVG ids
like nx-cloud-header-logo and nx-cloud-header-logo-stroke-1 which are
third-party artifacts and should be left unchanged).

In @.nx/cache/terminalOutputs/13554052336615392278:
- Around line 1-2: Remove the machine-local Nx cache/workspace metadata from the
PR and prevent future commits by adding ".nx/cache/" and ".nx/workspace-data/"
to .gitignore, then untrack the currently committed artifacts using git rm -r
--cached .nx/cache .nx/workspace-data and commit that removal; target the
offending entries shown in the diff (the .nx/cache terminalOutputs files) and
ensure both .nx/cache and .nx/workspace-data are ignored per Nx recommendation.

In @.nx/cache/terminalOutputs/1666183885798920482:
- Around line 1-167: The commit includes generated Nx terminal cache output
(.nx/cache/terminalOutputs/1666183885798920482) which should be removed; remove
that file from the commit (git rm --cached or delete and stage the deletion) and
amend the commit, then add the folder pattern ".nx/cache/terminalOutputs/" (or
".nx/cache/") to .gitignore so future generated logs are not tracked; ensure you
also run git add .gitignore and commit the ignore change and verify no other
cached terminalOutputs files remain tracked.

In @.nx/cache/terminalOutputs/7460006978003770812.commit:
- Line 1: Add an entry for the Nx build cache to .gitignore to prevent
machine-specific cache files from being committed; specifically add ".nx/cache/"
(or ".nx/cache" with a trailing slash) to the repository .gitignore, commit that
change, and then unstage/remove any existing .nx/cache artifacts from the index
so future commits do not include them.

In @.nx/workspace-data/react-router-8507840353650169656.hash:
- Line 1: The repository accidentally committed Nx cache artifacts (e.g., the
.nx workspace data file); update the .gitignore to exclude Nx caches by adding
an entry for ".nx/" and then finalize removal of the cached files by ensuring
the staged `git rm` is committed; specifically modify the .gitignore to include
the line ".nx/" and commit that change alongside the already staged removals so
future Nx cache files (like react-router-*.hash) are not tracked.

In `@apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts`:
- Around line 101-147: The limitPrice finite/positive validation is currently
inside the market-price block so it can be skipped when getSimplePrices returns
zeros; move the basic check for Number.isFinite(limitPriceNum) and limitPriceNum
> 0 (using input.limitPrice / limitPriceNum) to run before calling
getSimplePrices and before any call to calculateBuyAmount/toBaseUnit, throwing
the same Error when invalid; keep the more detailed market-comparison logic
(ratio, logRatio, USD-guard) inside the existing sellUsdPrice/buyUsdPrice
conditional.
- Around line 254-257: The experimental_toToolResultContent in createLimitOrder
currently removes orderParams but still returns signingData (type
CowOrderSigningData) which contains a message: CowOrderQuote with base-unit
sellAmount/buyAmount; update experimental_toToolResultContent to sanitize
signingData by removing or omitting the message field (e.g., create a shallow
copy of result.signingData without message) before JSON.stringify so base-unit
amounts are not returned to the LLM — touch the experimental_toToolResultContent
function and the CreateLimitOrderOutput handling to mirror the filtering used in
createTwap/createStopLoss.

---

Duplicate comments:
In @.nx/cache/13554052336615392278.commit:
- Line 1: Remove the committed Nx cache artifact and prevent future commits:
delete the cache file (.nx/cache/... .commit) from the repo, add the appropriate
Nx cache patterns (e.g., .nx/ and/or .nx/cache/) to .gitignore if not already
present, and create a lightweight commit that removes the file. Also ensure no
CI step or script re-adds .nx cache files to source control.

In @.nx/cache/terminalOutputs/13554052336615392278.commit:
- Line 1: The committed Nx cache artifact
".nx/cache/terminalOutputs/13554052336615392278.commit" must be removed from the
repo and prevented from recurring: delete that file from the commit (or run git
rm --cached on it) and add a rule to ignore Nx cache files (e.g., add ".nx/" or
".nx/cache/" to .gitignore) so future cache artifacts are not tracked; ensure
the commit no longer contains the file before pushing.

In @.nx/cache/terminalOutputs/14206404844807895703:
- Around line 1-2: Remove the committed Nx cache file and ensure Nx cache is
ignored: delete the file (.nx/cache/terminalOutputs/14206404844807895703) from
the repository, run git rm --cached on it, and commit the removal; then add .nx/
(or at minimum .nx/cache/) to .gitignore so future tsc --build outputs are not
committed; finally verify no other files under .nx/ are tracked and update the
commit.

In @.nx/cache/terminalOutputs/14206404844807895703.commit:
- Line 1: Remove the committed Nx build cache artifact from version control and
stop tracking it: remove the cached file from the index (git rm --cached) and
commit that removal, then add a .gitignore entry to ignore the Nx cache
directory (e.g., the Nx cache pattern) so it won’t be re-added; finally, ensure
the cleanup commit is pushed so CI and other collaborators no longer receive
this build-cache artifact.

In @.nx/cache/terminalOutputs/17428515039638435960.commit:
- Line 1: The commit contains an Nx build-cache artifact (file
17428515039638435960.commit) that must be removed from version control; remove
that file from the repository index (so it’s no longer tracked), commit the
removal, and add the Nx cache directory/pattern to .gitignore so future cache
files are not committed; finally verify the change by committing the updated
.gitignore and confirming the cache file is absent from the repo and PR.

In @.nx/cache/terminalOutputs/3221835782562372545:
- Around line 1-2: Remove the Nx cache file from the repository and ensure Nx
cache is ignored: delete the committed file entry (e.g.,
.nx/cache/terminalOutputs/3221835782562372545) from the repo and commit that
removal (use git rm --cached or equivalent), then add the .nx/ directory or
specifically .nx/cache/ to .gitignore so future cached terminal outputs are not
committed; verify by running git status to confirm the file is no longer
tracked.

In @.nx/cache/terminalOutputs/3221835782562372545.commit:
- Line 1: A Nx build cache artifact (terminalOutputs/*.commit) was committed;
remove the file from the repo and prevent future commits by adding the Nx cache
pattern to .gitignore and removing the file from Git's index: remove the
specific committed file (unstage/remove from commit), add
"terminalOutputs/*.commit" or ".nx/cache/" patterns to .gitignore, commit the
.gitignore change, and ensure no other Nx cache files remain staged; reference
the committed artifact pattern "terminalOutputs/*.commit" when locating the
offending file.

---

Nitpick comments:
In @.nx/cache/14206404844807895703.commit:
- Line 1: Remove the generated Nx cache marker file that was accidentally
committed (the local cache artifact) and stop tracking it: delete the committed
cache artifact from the repository and commit that deletion, and update the
project ignore rules to add the Nx cache directory pattern so it isn't
re-committed (add the appropriate .nx cache pattern to .gitignore or the repo's
ignore file and commit that change). Ensure you remove the file from git
history/tracking (e.g., git rm or git rm --cached) so future commits won't
include the generated cache artifact.

In @.nx/cache/3221835782562372545.commit:
- Line 1: Remove the generated Nx cache artifact
".nx/cache/3221835782562372545.commit" from the commit and stop tracking the .nx
cache directory: delete the file from the repo index (git rm --cached) so it’s
removed from the PR, add the pattern ".nx/cache/**" to .gitignore (or ensure
existing ignore covers it), and commit the .gitignore change so future cache
files under .nx/cache are not tracked.

In @.nx/cache/7460006978003770812.commit:
- Line 1: Remove the committed Nx cache artifact
`.nx/cache/7460006978003770812.commit` from the PR by deleting that file from
the repository and removing it from the index (git rm --cached or git rm), then
ensure the `.nx/cache/` directory is listed in .gitignore so future cache files
are not committed; verify with git status and amend the commit or create a
follow-up commit that removes the file and adds `.nx/cache/` to .gitignore.

In @.nx/workspace-data/lockfile.hash:
- Line 1: Remove the generated workspace cache artifact lockfile.hash from
version control and stop tracking future changes: delete the tracked file (git
rm --cached lockfile.hash or git rm --cached .nx/workspace-data/lockfile.hash),
add the workspace cache pattern to .gitignore (e.g., ignore .nx/workspace-data/
or lockfile.hash) and commit that change so the file is not committed again; if
the repository intentionally versions Nx cache state, instead document that
decision in the repo README or CI settings.

In @.nx/workspace-data/tsconfig-files.hash:
- Line 1: The PR includes a generated Nx workspace cache file that should not be
committed; remove that file from the commit (unstage and delete from the repo
history if needed) and add a gitignore rule to ignore the Nx workspace cache
directory (add a pattern such as .nx/workspace-data/** to .gitignore), then
commit the .gitignore change and a new commit that removes the cached file (use
git rm --cached <file> if you want to keep it locally) so the generated artifact
is no longer tracked.

In `@apps/agentic-server/src/tools/initiateSwap.ts`:
- Around line 299-305: The /^\d{15,}/ heuristic in the sellAmount Zod refine
(seen in initiateSwap.ts) can false-positive for ultra-high-supply tokens;
replace it with a precision-aware check: fetch the asset's precision where
sellAmount is validated (or accept a precision parameter), strip whitespace,
allow decimal points, and treat the value as "base-unit-like" only when the
integer digit count (digits before the decimal) is >= precision (or a configured
threshold), then fail with the same message; extract this logic into a shared
helper (used by createLimitOrder.ts, createStopLoss.ts, createTwap.ts) so all
validators call a function like isBaseUnitLike(value, precision) instead of the
hardcoded /^\d{15,}/ test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d840ecca-e7b1-425b-be2f-1d23cb996c2e

📥 Commits

Reviewing files that changed from the base of the PR and between 113fed0 and 9e48a66.

⛔ Files ignored due to path filters (14)
  • .nx/cache/12786974370515813638-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/12786974370515813638.tar.gz is excluded by !**/*.gz
  • .nx/cache/16223358955046570561-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/16223358955046570561.tar.gz is excluded by !**/*.gz
  • .nx/cache/16635151379768794721-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/16635151379768794721.tar.gz is excluded by !**/*.gz
  • .nx/cache/1666183885798920482-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/1666183885798920482.tar.gz is excluded by !**/*.gz
  • .nx/cache/16785014982916244893-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/16785014982916244893.tar.gz is excluded by !**/*.gz
  • .nx/cache/8707572495919475997-logs.tar.gz is excluded by !**/*.gz
  • .nx/cache/8707572495919475997.tar.gz is excluded by !**/*.gz
  • .nx/cache/cloud/verify.lock is excluded by !**/*.lock
  • .nx/workspace-data/d/daemon.log is excluded by !**/*.log
📒 Files selected for processing (39)
  • .env
  • .nx/cache/13554052336615392278.commit
  • .nx/cache/14206404844807895703.commit
  • .nx/cache/17428515039638435960.commit
  • .nx/cache/3221835782562372545.commit
  • .nx/cache/7460006978003770812.commit
  • .nx/cache/cloud/2506.06.6.hotfix1/index.js
  • .nx/cache/cloud/2506.06.6.hotfix1/lib/daemon/process-run-end.js
  • .nx/cache/cloud/2506.06.6.hotfix1/lib/heartbeat/heartbeat-process.js
  • .nx/cache/cloud/2506.06.6.hotfix1/package.json
  • .nx/cache/cloud/2506.06.6.hotfix1/static/login-end.html
  • .nx/cache/cloud/2506.06.6.hotfix1/static/login-start.html
  • .nx/cache/run.json
  • .nx/cache/terminalOutputs/13554052336615392278
  • .nx/cache/terminalOutputs/13554052336615392278.commit
  • .nx/cache/terminalOutputs/14206404844807895703
  • .nx/cache/terminalOutputs/14206404844807895703.commit
  • .nx/cache/terminalOutputs/1666183885798920482
  • .nx/cache/terminalOutputs/17428515039638435960.commit
  • .nx/cache/terminalOutputs/3221835782562372545
  • .nx/cache/terminalOutputs/3221835782562372545.commit
  • .nx/cache/terminalOutputs/7460006978003770812.commit
  • .nx/workspace-data/eslint-2654242865465226088.hash
  • .nx/workspace-data/file-map.json
  • .nx/workspace-data/lockfile.hash
  • .nx/workspace-data/nx_files.nxt
  • .nx/workspace-data/parsed-lock-file.json
  • .nx/workspace-data/playwright-5186013267177752385.hash
  • .nx/workspace-data/project-graph.json
  • .nx/workspace-data/react-router-8507840353650169656.hash
  • .nx/workspace-data/source-maps.json
  • .nx/workspace-data/tsc-2568428459166798129.hash
  • .nx/workspace-data/tsconfig-files.hash
  • .nx/workspace-data/vite-9347777721732807074.hash
  • .vscode/settings.json
  • apps/agentic-server/src/tools/initiateSwap.ts
  • apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts
  • apps/agentic-server/src/tools/stopLoss/createStopLoss.ts
  • apps/agentic-server/src/tools/twap/createTwap.ts
💤 Files with no reviewable changes (1)
  • .env

Comment thread .nx/cache/17428515039638435960.commit Outdated
Comment on lines +1 to +414
<html>
<head>
<title>Nx Cloud login</title>
<style>
*,
:before,
:after {
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
ui-sans-serif,
system-ui,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
Segoe UI Symbol,
'Noto Color Emoji';
font-feature-settings: normal;
font-variation-settings: normal;
-webkit-tap-highlight-color: transparent;
line-height: inherit;
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
box-sizing: border-box;
border-width: 0;
border-style: solid;
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-gradient-from-position: ;
--tw-gradient-via-position: ;
--tw-gradient-to-position: ;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
--tw-contain-size: ;
--tw-contain-layout: ;
--tw-contain-paint: ;
--tw-contain-style: ;
/*border-bottom-width: 1px;*/
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mt-20 {
margin-top: 5rem;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.h-14 {
height: 3.5rem;
}
.h-5 {
height: 1.25rem;
}
.h-6 {
height: 1.5rem;
}
.min-h-full {
min-height: 100%;
}
.w-5 {
width: 1.25rem;
}
.w-6 {
width: 1.5rem;
}
.w-auto {
width: auto;
}
.max-w-7xl {
max-width: 80rem;
}
.flex-shrink-0 {
flex-shrink: 0;
}
.flex-col {
flex-direction: column;
}
.items-start {
align-items: flex-start;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.gap-4 {
gap: 1rem;
}
.gap-8 {
gap: 2rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-slate-100 {
--tw-border-opacity: 1;
border-color: rgb(241 245 249 / var(--tw-border-opacity));
}
.border-slate-200 {
--tw-border-opacity: 1;
border-color: rgb(226 232 240 / var(--tw-border-opacity));
}
.bg-white {
--tw-bg-opacity: 1;
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}
.p-8 {
padding: 2rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.px-40 {
padding-left: 10rem;
padding-right: 10rem;
}
.py-10 {
padding-top: 2.5rem;
padding-bottom: 2.5rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.text-wrap {
max-width: 100%;
word-wrap: break-word;
}
.font-bold {
font-weight: 700;
}
.font-semibold {
font-weight: 600;
}
.italic {
font-style: italic;
}
.leading-7 {
line-height: 1.75rem;
}
.text-slate-400 {
--tw-text-opacity: 1;
color: rgb(148 163 184 / var(--tw-text-opacity));
}
.text-slate-700 {
--tw-text-opacity: 1;
color: rgb(51 65 85 / var(--tw-text-opacity));
}
.text-slate-900 {
--tw-text-opacity: 1;
color: rgb(15 23 42 / var(--tw-text-opacity));
}
.underline {
text-decoration-line: underline;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-25 {
opacity: 0.3;
}
.transition {
transition-property: color, background-color, border-color,
text-decoration-color, fill, stroke, opacity, box-shadow, transform,
filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 0.15s;
}
body {
min-height: 100%;
height: 100%;
}
a {
color: inherit;
text-decoration: inherit;
}
.hover\:opacity-100:hover {
opacity: 1;
}
@media (min-width: 640px) {
.sm\:-my-px {
margin-top: -1px;
margin-bottom: -1px;
}
.sm\:ml-6 {
margin-left: 1.5rem;
}
.sm\:flex {
display: flex;
}
.sm\:truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sm\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.sm\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.sm\:tracking-tight {
letter-spacing: -0.025em;
}
}
@media (min-width: 768px) {
.md\:grid {
display: grid;
}
.md\:grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.md\:gap-4 {
gap: 1rem;
}
.md\:p-2 {
padding: 0.5rem;
}
}
@media (min-width: 1024px) {
.lg\:flex {
display: flex;
}
.lg\:px-8 {
padding-left: 2rem;
padding-right: 2rem;
}
}
</style>
</head>
<body>
<div class="min-h-full">
<nav class="border-b border-slate-200 bg-white">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="flex h-14 justify-between">
<div class="flex">
<div class="flex flex-shrink-0 items-center">
<a href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-6 w-6"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
</div>
<div class="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8"></div>
</div>
</div>
</div>
</nav>
<div class="py-10">
<div
class="mx-auto flex max-w-7xl flex-col items-start justify-center gap-2 px-40"
>
<h1
class="text-2xl font-bold leading-7 text-slate-900 sm:truncate sm:text-3xl sm:tracking-tight"
>
Your workspace is connected to Nx Cloud
</h1>
<div>
<p class="mb-2">You may now close this window.</p>
</div>
</div>
</div>
<footer
class="mt-20 flex border-t border-slate-100 dark:border-slate-800"
>
<nav
role="menu"
aria-labelledby="bottom-navigation"
class="mx-auto flex w-auto max-w-7xl items-center px-4 text-slate-400 dark:text-slate-600"
>
<div class="flex items-center gap-4 p-8 opacity-50">
<a title="Nx Cloud" href="{{ nxCloudUrl }}">
<svg
id="nx-cloud-header-logo"
role="img"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="transparent"
viewBox="0 0 24 24"
class="h-5 w-5"
>
<path
stroke-width="2"
d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z"
id="nx-cloud-header-logo-stroke-1"
></path>
<path
stroke-width="2"
d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z"
id="nx-cloud-header-logo-stroke-2"
></path>
</svg>
</a>
<p class="text-xs transition">&copy; 2024 - Nx Cloud</p>
</div>
<section
class="hidden gap-8 p-8 text-xs opacity-25 transition hover:opacity-100 md:grid md:grid-cols-4 md:gap-4 md:p-2 lg:flex"
>
<a href="https://nx.app/terms" title="Terms of Service"
>Terms of Service</a
><a href="https://nx.app/privacy" title="Privacy Policy"
>Privacy Policy</a
><a
href="https://status.nx.app"
title="Status"
target="_blank"
rel="noopener"
>Status</a
><a
href="https://nx.dev/ci/intro/ci-with-nx?utm_source=nx.app"
title="Docs"
>Docs</a
><a href="mailto:cloud-support@nrwl.io" title="Contact Nx Cloud"
>Contact Nx Cloud</a
><a href="https://nx.dev/pricing?utm_source=nx.app" title="Pricing"
>Pricing</a
><a href="https://nx.dev/company?utm_source=nx.app" title="Company"
>Company</a
><a
href="https://twitter.com/nxdevtools"
title="@NxDevTools"
target="_blank"
rel="noopener"
>@NxDevTools</a
>
</section>
</nav>
</footer>
</div>
</body>
</html>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Do not commit Nx local cache artifacts.

This file lives under .nx/cache/…, which is a local Nx/Nx Cloud cache directory populated at build time. These assets are third-party, environment-specific, and will churn on every Nx Cloud version bump — they shouldn't be tracked in VCS. The PR description itself flags this as a chore commit.

Please remove the entire .nx/cache/ tree from this PR and add it to .gitignore (Nx's own nx init adds .nx/cache and .nx/workspace-data by default). Static-analysis findings here (missing doctype, duplicate SVG ids) belong to the upstream Nx Cloud bundle and aren't actionable in this repo.

Proposed .gitignore addition
+.nx/cache
+.nx/workspace-data
🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)


[error] 357-357: The id value [ nx-cloud-header-logo ] must be unique.

(id-unique)


[error] 368-368: The id value [ nx-cloud-header-logo-stroke-1 ] must be unique.

(id-unique)


[error] 373-373: The id value [ nx-cloud-header-logo-stroke-2 ] must be unique.

(id-unique)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.nx/cache/cloud/2506.06.6.hotfix1/static/login-end.html around lines 1 -
414, This PR accidentally includes generated Nx cache artifacts under .nx/cache
(example file shown), so remove the entire .nx/cache tree from the commit and
stop tracking it: remove those files from the branch (unstage/delete them from
VCS), add .nx/cache and .nx/workspace-data to .gitignore, amend the commit (or
create a new commit) and push the branch; do not attempt to modify the
upstream-generated HTML (it contains duplicate SVG ids like nx-cloud-header-logo
and nx-cloud-header-logo-stroke-1 which are third-party artifacts and should be
left unchanged).

Comment thread .nx/cache/terminalOutputs/13554052336615392278 Outdated
Comment thread .nx/cache/terminalOutputs/1666183885798920482 Outdated
Comment thread .nx/cache/terminalOutputs/7460006978003770812.commit Outdated
Comment thread .nx/workspace-data/react-router-8507840353650169656.hash Outdated
Comment on lines +101 to +147
// Sanity-check limitPrice against current market rate to catch LLM inversion/base-unit errors
const priceResults = await getSimplePrices([sellAsset.assetId, buyAsset.assetId])
const sellUsdPrice = Number(priceResults.find(p => p.assetId === sellAsset.assetId)?.price ?? '0')
const buyUsdPrice = Number(priceResults.find(p => p.assetId === buyAsset.assetId)?.price ?? '0')
if (sellUsdPrice > 0 && buyUsdPrice > 0) {
const marketLimitPrice = sellUsdPrice / buyUsdPrice
const limitPriceNum = Number(input.limitPrice)
if (!Number.isFinite(limitPriceNum) || limitPriceNum <= 0) {
throw new Error(`Invalid limitPrice "${input.limitPrice}". It must be a positive number.`)
}
const ratio = limitPriceNum / marketLimitPrice
if (!Number.isFinite(ratio) || ratio <= 0) {
throw new Error(
`Invalid limitPrice "${input.limitPrice}" for market comparison. ` +
`Expected a positive ${buyAsset.symbol}/${sellAsset.symbol} price.`
)
}
const logRatio = Math.abs(Math.log10(ratio))
const isNearUsdPrice = (usdPrice: number) =>
usdPrice > 0 && Math.abs(limitPriceNum - usdPrice) / usdPrice <= 0.25

// Guard likely "USD price leaked into pair price" mistakes.
// Example: ARB->EUL should be ~0.086 EUL/ARB, but passing 1.39 (EUL USD) is >10x off.
if (logRatio > 1 && (isNearUsdPrice(sellUsdPrice) || isNearUsdPrice(buyUsdPrice))) {
throw new Error(
`limitPrice ${input.limitPrice} appears to be a USD token price, not the pair price. ` +
`Expected approximately ${marketLimitPrice.toFixed(6)} ${buyAsset.symbol}/${sellAsset.symbol} ` +
`(1 ${sellAsset.symbol} = X ${buyAsset.symbol}).`
)
}

if (logRatio > 3) {
throw new Error(
`limitPrice ${input.limitPrice} is more than 1000× from the market rate (~${marketLimitPrice.toFixed(6)} ${buyAsset.symbol}/${sellAsset.symbol}). ` +
`Did you invert the price or pass a base-unit value? For ${sellAsset.symbol} at $${sellUsdPrice} selling for ${buyAsset.symbol}, limitPrice should be ~${marketLimitPrice.toFixed(6)}.`
)
}
if (logRatio > 1) {
console.warn('[createLimitOrder] limitPrice sanity check: suspicious deviation', {
inputLimitPrice: input.limitPrice,
marketLimitPrice,
ratio,
sellAsset: sellAsset.symbol,
buyAsset: buyAsset.symbol,
})
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: limitPrice positive/finite check is gated on price availability.

The Number.isFinite(limitPriceNum) / limitPriceNum > 0 validation at lines 107-110 only runs inside the if (sellUsdPrice > 0 && buyUsdPrice > 0) block. Per getSimplePrices behavior, either price can fall back to '0' on CoinGecko mapping miss or API error — in which case the entire sanity block is skipped and a non-positive limitPrice reaches calculateBuyAmount. calculateBuyAmount only rejects NaN, so a negative limitPrice will produce a negative buyAmountHuman that gets fed into toBaseUnit.

Hoist the basic validation above the market-comparison block so it always runs.

🛠️ Suggested restructure
+  const limitPriceNum = Number(input.limitPrice)
+  if (!Number.isFinite(limitPriceNum) || limitPriceNum <= 0) {
+    throw new Error(`Invalid limitPrice "${input.limitPrice}". It must be a positive number.`)
+  }
+
   // Sanity-check limitPrice against current market rate to catch LLM inversion/base-unit errors
   const priceResults = await getSimplePrices([sellAsset.assetId, buyAsset.assetId])
   const sellUsdPrice = Number(priceResults.find(p => p.assetId === sellAsset.assetId)?.price ?? '0')
   const buyUsdPrice = Number(priceResults.find(p => p.assetId === buyAsset.assetId)?.price ?? '0')
   if (sellUsdPrice > 0 && buyUsdPrice > 0) {
     const marketLimitPrice = sellUsdPrice / buyUsdPrice
-    const limitPriceNum = Number(input.limitPrice)
-    if (!Number.isFinite(limitPriceNum) || limitPriceNum <= 0) {
-      throw new Error(`Invalid limitPrice "${input.limitPrice}". It must be a positive number.`)
-    }
     const ratio = limitPriceNum / marketLimitPrice
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts` around lines
101 - 147, The limitPrice finite/positive validation is currently inside the
market-price block so it can be skipped when getSimplePrices returns zeros; move
the basic check for Number.isFinite(limitPriceNum) and limitPriceNum > 0 (using
input.limitPrice / limitPriceNum) to run before calling getSimplePrices and
before any call to calculateBuyAmount/toBaseUnit, throwing the same Error when
invalid; keep the more detailed market-comparison logic (ratio, logRatio,
USD-guard) inside the existing sellUsdPrice/buyUsdPrice conditional.

Comment on lines +254 to +257
experimental_toToolResultContent: (result: CreateLimitOrderOutput) => {
const { orderParams: _orderParams, ...llmVisible } = result
return [{ type: 'text' as const, text: JSON.stringify(llmVisible) }]
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect CowOrderSigningData shape to confirm whether it carries base-unit amounts.
fd -t f 'types.ts' apps/agentic-server/src/lib/cow | xargs -I{} sh -c 'echo "=== {} ==="; cat "{}"'
rg -nP -C3 '\b(CowOrderSigningData|prepareCowLimitOrder)\b' --type=ts

Repository: shapeshift/agentic-chat

Length of output: 8060


🏁 Script executed:

# Search for the other tools mentioned to see how they handle experimental_toToolResultContent
rg -nP 'experimental_toToolResultContent' apps/agentic-server/src/tools --type=ts -A 5

Repository: shapeshift/agentic-chat

Length of output: 1761


🏁 Script executed:

# Check the CreateLimitOrderOutput interface structure in createLimitOrder.ts
rg -nP 'interface CreateLimitOrderOutput' apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts -A 20

Repository: shapeshift/agentic-chat

Length of output: 707


Strip base-unit amounts from signingData before returning to LLM.

The other tools in this PR (createTwap, createStopLoss) explicitly exclude sellAmountBaseUnit/precision fields from LLM output. However, createLimitOrder only strips orderParams while including signingData: CowOrderSigningData, which contains a message: CowOrderQuote with sellAmount and buyAmount in base-unit format (required for EIP-712 signing). These base-unit amounts will leak into the JSON returned to the LLM, undermining the intent of the filter.

Consider stripping the message field from signingData:

Suggested fix
   experimental_toToolResultContent: (result: CreateLimitOrderOutput) => {
-    const { orderParams: _orderParams, ...llmVisible } = result
-    return [{ type: 'text' as const, text: JSON.stringify(llmVisible) }]
+    const { orderParams: _orderParams, signingData, ...rest } = result
+    // Strip base-unit amounts from EIP-712 signing data for LLM visibility
+    const { message: _message, ...signingRest } = signingData as Record<string, unknown>
+    return [
+      { type: 'text' as const, text: JSON.stringify({ ...rest, signingData: signingRest }) },
+    ]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
experimental_toToolResultContent: (result: CreateLimitOrderOutput) => {
const { orderParams: _orderParams, ...llmVisible } = result
return [{ type: 'text' as const, text: JSON.stringify(llmVisible) }]
},
experimental_toToolResultContent: (result: CreateLimitOrderOutput) => {
const { orderParams: _orderParams, signingData, ...rest } = result
// Strip base-unit amounts from EIP-712 signing data for LLM visibility
const { message: _message, ...signingRest } = signingData as Record<string, unknown>
return [
{ type: 'text' as const, text: JSON.stringify({ ...rest, signingData: signingRest }) },
]
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/agentic-server/src/tools/limitOrder/createLimitOrder.ts` around lines
254 - 257, The experimental_toToolResultContent in createLimitOrder currently
removes orderParams but still returns signingData (type CowOrderSigningData)
which contains a message: CowOrderQuote with base-unit sellAmount/buyAmount;
update experimental_toToolResultContent to sanitize signingData by removing or
omitting the message field (e.g., create a shallow copy of result.signingData
without message) before JSON.stringify so base-unit amounts are not returned to
the LLM — touch the experimental_toToolResultContent function and the
CreateLimitOrderOutput handling to mirror the filtering used in
createTwap/createStopLoss.

Prevent committing local Nx cache files to the repository so you don't end up with spew.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant