Skip to content

fix(state): harden maintenance findings#98

Merged
duyet merged 1 commit into
mainfrom
codex/code-smell-detector-maintenance
May 20, 2026
Merged

fix(state): harden maintenance findings#98
duyet merged 1 commit into
mainfrom
codex/code-smell-detector-maintenance

Conversation

@duyet
Copy link
Copy Markdown
Owner

@duyet duyet commented May 20, 2026

Summary

  • fix sparse /api/v2/states/query pagination so tag/JSON-path filters keep scanning past nonmatching rows
  • avoid mutating query predicates while filtering rows
  • make the TS LangGraph saver extend the real BaseCheckpointSaver and validate that contract in SDK builds
  • replace dated AI review snapshots with durable core memory and docs index entries

Evidence

  • Recent commits inspected: last 7 days from cbc5df6 through c957835
  • Confirmed bugs: capped candidate scan in packages/api/src/services/states.ts, predicate mutation in matchesPredicates, local empty LangGraph base class in packages/sdk/src/langgraph.ts
  • Existing AI snapshot docs removed: docs/API_DOCS_REVIEW.md, docs/test-coverage-analysis.md

Verification

  • bun install --frozen-lockfile
  • bunx biome check packages/*/src/
  • bunx tsc --noEmit -p packages/api/tsconfig.json
  • cd packages/dashboard && bunx tsc --noEmit
  • cd packages/api && bunx vitest run (306 passed)
  • cd packages/api && bunx vitest run test/state-platform.test.ts (7 passed)
  • cd packages/sdk && bun run typecheck
  • cd packages/sdk && bun run test (11 passed)
  • cd packages/sdk && bun run build
  • bun run test:sdk-examples
  • bun run build

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Sorry @duyet, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@duyet has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 37 minutes and 39 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 66aed687-ef03-4393-8bd8-f6f1ef2766c1

📥 Commits

Reviewing files that changed from the base of the PR and between 47530c0 and e68b3aa.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • AGENTS.md
  • CLAUDE.md
  • PLAN.md
  • README.md
  • docs/API_DOCS_REVIEW.md
  • docs/INDEX.md
  • docs/knowledge/core-memory.md
  • docs/test-coverage-analysis.md
  • packages/api/src/routes/v2/states/index.ts
  • packages/api/src/services/states.ts
  • packages/api/test/state-platform.test.ts
  • packages/sdk/package.json
  • packages/sdk/src/langgraph.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/code-smell-detector-maintenance

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.

@duyet
Copy link
Copy Markdown
Owner Author

duyet commented May 20, 2026

@codex review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a "core memory" system for project maintenance, replacing dated AI review reports with a centralized core-memory.md and updating documentation across the repository. The state platform's query service was modified to handle sparse matches by implementing a scanning loop that continues until the requested limit is met, and the SDK was refactored to formally integrate with LangChain's BaseCheckpointSaver. Feedback identifies high-severity risks regarding the new scanning logic, specifically the potential for unbounded execution times and Worker timeouts during extremely sparse queries. Additionally, the reviewer suggested optimizing the row filtering within these loops to reduce redundant processing overhead.

Comment thread packages/api/src/services/states.ts Outdated
let cursor = Number(input.cursor);
const pageSize = Math.max(limit * 5, limit);

while (rows.length < limit) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

This while loop implements a scan that continues until the limit is satisfied. While this fixes the issue with sparse matches, it introduces a risk of unbounded execution time. If a query is extremely sparse (e.g., matching 1 row out of 100,000), this could trigger hundreds of sequential D1 queries, likely exceeding the Cloudflare Worker CPU time limit or D1's request limits.

Consider adding a safety limit on the number of iterations or the total number of rows scanned. If the limit is reached, return the results found so far with a next_cursor pointing to the next sequence to scan, allowing the client to continue in a subsequent request.

Comment thread packages/api/src/services/states.ts Outdated
let cursor = Number(input.cursor);
const pageSize = Math.max(limit * 5, limit);

while (rows.length < limit) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Similar to the historical query path, this unbounded while loop poses a timeout risk for very sparse queries. Implementing a maximum scan limit per request is recommended to ensure stability in a serverless environment.

Comment thread packages/api/src/services/states.ts Outdated
updated_at: row.created_at,
deleted_at: null,
};
if (!filterStateRows([state], input).length) continue;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Calling filterStateRows([state], input) inside the loop is inefficient. It creates a new array and re-allocates/re-processes the query predicates for every single row fetched from the database.

Since this loop is intended to handle potentially many non-matching rows, this overhead adds up quickly. Consider preparing the predicates once outside the loop and calling an optimized matching function directly.

@duyet duyet force-pushed the codex/code-smell-detector-maintenance branch from dceaf87 to 1385ec4 Compare May 20, 2026 21:26
@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​langchain/​langgraph-checkpoint@​1.0.21001009992100
Addednpm/​@​langchain/​core@​1.1.47100100100100100

View full report

Co-Authored-By: Duyet Le <me@duyet.net>

Co-Authored-By: duyetbot <bot@duyet.net>
@duyet duyet force-pushed the codex/code-smell-detector-maintenance branch from 1385ec4 to e68b3aa Compare May 20, 2026 21:29
@duyet
Copy link
Copy Markdown
Owner Author

duyet commented May 20, 2026

Addressed Gemini review: added a per-request sparse-query scan cap, returns a continuation cursor when the cap is reached, and precomputes predicates instead of rebuilding them per row. Re-verified locally with API typecheck, Biome, focused state-platform test, and full API tests (307 passed). @codex review

@duyet duyet merged commit 949d208 into main May 20, 2026
4 checks passed
@duyet duyet deleted the codex/code-smell-detector-maintenance branch May 20, 2026 21:32
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e68b3aa2dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +594 to +597
return {
rows,
nextCursor: Number.isFinite(cursor) && cursor > 0 ? String(cursor) : null,
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Follow continuation cursors even for empty sparse pages

This new return path can emit a non-null nextCursor with rows still empty when the scan cap is reached, but AgentStateCheckpointSaver.queryRecords currently stops pagination on rows.length === 0 (packages/sdk/src/langgraph.ts:338). In sparse datasets, that means the SDK will terminate early and miss valid later matches even though the API explicitly provides a continuation cursor (as covered by the new sparse-cap test), so LangGraph checkpoint queries can become incomplete.

Useful? React with 👍 / 👎.

Comment thread packages/sdk/package.json
Comment on lines 30 to 32
"peerDependencies": {
"@langchain/langgraph-checkpoint": "^1.0.0"
"@langchain/langgraph-checkpoint": "^1.0.2"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Declare @langchain/core as a peer for the langgraph entry

The commit adds a direct import from @langchain/core/runnables in packages/sdk/src/langgraph.ts, but package.json still exposes only @langchain/langgraph-checkpoint as a peer. In environments that do not auto-install transitive peers, importing @agentstate/sdk/langgraph can fail with a module-resolution error for @langchain/core, so the SDK’s runtime dependency contract is now incomplete.

Useful? React with 👍 / 👎.

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