Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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. Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (22)
📝 WalkthroughWalkthroughThis PR introduces version centralization via a new VERSION constant, implements per-key concurrency control through a keyed-mutex utility, hardens authentication with timing-safe comparisons, adds schema support for version 0.4.0, expands secret redaction patterns, and makes type and validation improvements across multiple functions. Changes
Sequence DiagramsequenceDiagram
actor Client
participant Function as observe/relations/<br/>remember Function
participant KeyedLock as withKeyedLock
participant StateKV as State/KV
participant Lock as Per-Key<br/>Promise Lock
Client->>Function: Request
Function->>KeyedLock: withKeyedLock(key, operation)
KeyedLock->>Lock: Enqueue operation<br/>for this key
Lock->>Lock: Await prior<br/>key-specific promise
KeyedLock->>StateKV: Validate & Update<br/>(inside lock)
StateKV-->>KeyedLock: Result
KeyedLock->>Lock: Cleanup & Dequeue
KeyedLock-->>Function: Return result
Function-->>Client: Response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
b1cb9a1 to
dd0a1b0
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
src/functions/export-import.ts (1)
105-106: Keep import compatibility explicit, not implicitly coupled to current runtime version.Including
VERSIONin the allowlist can auto-admit future formats before migration logic is defined. Prefer an explicit compatibility list.♻️ Suggested change
- const supportedVersions = new Set(["0.3.0", "0.4.0", VERSION]); + const supportedVersions = new Set<ExportData["version"]>([ + "0.3.0", + "0.4.0", + ]);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/functions/export-import.ts` around lines 105 - 106, Remove the implicit coupling to the current runtime by not including the global VERSION in the allowlist; update the supportedVersions Set (the variable supportedVersions) to contain only explicitly-approved schema strings (e.g., "0.3.0", "0.4.0") and ensure the import check that uses importData.version continues to reject unknown versions; when you add migration/compatibility logic in the future, explicitly add new version strings to supportedVersions rather than re-adding VERSION.src/types.ts (1)
288-288: Prefer JSON-serializable typing over unconstrainedunknown.
Record<string, unknown>is very broad for persisted/exported graph payloads. A JSON value type keeps flexibility while preserving storage/export safety.♻️ Suggested typing refinement
+export type JsonPrimitive = string | number | boolean | null; +export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }; + export interface GraphNode { id: string; @@ - properties: Record<string, unknown>; + properties: Record<string, JsonValue>; sourceObservationIds: string[]; createdAt: string; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/types.ts` at line 288, The field named properties currently typed as Record<string, unknown> should be changed to a JSON-serializable type to guarantee persisted/exported graph payloads are safe; replace Record<string, unknown> with Record<string, JSONValue> (or JSONValue for non-object cases) and add/export a JSONValue union/type (e.g., type JSONValue = string | number | boolean | null | JSONObject | JSONArray; type JSONObject = Record<string, JSONValue>; type JSONArray = JSONValue[] ) so all values are constrained to JSON-serializable primitives/objects/arrays and preserve backward compatibility for storage and export operations.src/mcp/standalone.ts (1)
9-15: Consider derivingIMPLEMENTED_TOOLSfrom dispatch handlers to avoid drift.This set is now a second source of truth versus
handleToolCall; a small handler map refactor would keep them auto-synced.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/mcp/standalone.ts` around lines 9 - 15, IMPLEMENTED_TOOLS is a hard-coded second source of truth; instead derive it from the dispatch/handler registry to avoid drift by building the set from the keys of the handler map used by handleToolCall (or whichever dispatch function registers handlers). Change code to export or read the unified handler map (e.g., the map/object that maps tool names to handler functions used by handleToolCall) and compute IMPLEMENTED_TOOLS = new Set(Object.keys(handlerMap)) (or equivalent) so the set is always in sync with the handlers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/functions/observe.ts`:
- Around line 90-99: Session-limit rejection can leave dedup state recorded even
though no observation was persisted; ensure dedup hashes are only written after
successful persistence inside the withKeyedLock(`obs:${payload.sessionId}`)
block. Move any dedup recording logic (where the observation hash is stored) out
of pre-check code and into the post-success path after kv.put/kv.putMany (or
whatever persistence method is used), or if you prefer to keep current ordering,
roll back/remove the dedup entry when returning the limit error in the
withKeyedLock branch; reference withKeyedLock, payload.sessionId,
maxObservationsPerSession, kv.list and KV.observations to locate and adjust the
code paths.
In `@src/functions/relations.ts`:
- Around line 50-85: The current single pair lock (lockKey) only serializes
identical pairs and allows concurrent mutations to the same memory (e.g.,
relate(A,B) vs relate(A,C)); fix by acquiring per-memory locks in a
deterministic order: replace the single withKeyedLock(lockKey, ...) call with
nested withKeyedLock calls on the two memory IDs sorted (e.g., await
withKeyedLock(sortedIds[0], async () => await withKeyedLock(sortedIds[1], async
() => { ... }))). Update the block that builds lockKey and the withKeyedLock
call so both memory IDs are locked individually (use data.sourceId and
data.targetId sorted) before reading/updating kv.get(KV.memories, ...), pushing
to relatedIds, and kv.set(...).
In `@src/functions/team.ts`:
- Around line 13-14: The code currently excludes the "observation" item type
causing valid callers to be rejected; update VALID_ITEM_TYPES (and any checks
around it in src/functions/team.ts) to include "observation" so it matches
TeamSharedItem.type and the tool schema, and then adjust the content-read logic
that branches on itemType (used around the item lookup code referenced in lines
~31-33) to route observation IDs to KV.memories (i.e., when itemType ===
"observation" use the KV.memories path) to avoid false "Item not found" errors.
---
Nitpick comments:
In `@src/functions/export-import.ts`:
- Around line 105-106: Remove the implicit coupling to the current runtime by
not including the global VERSION in the allowlist; update the supportedVersions
Set (the variable supportedVersions) to contain only explicitly-approved schema
strings (e.g., "0.3.0", "0.4.0") and ensure the import check that uses
importData.version continues to reject unknown versions; when you add
migration/compatibility logic in the future, explicitly add new version strings
to supportedVersions rather than re-adding VERSION.
In `@src/mcp/standalone.ts`:
- Around line 9-15: IMPLEMENTED_TOOLS is a hard-coded second source of truth;
instead derive it from the dispatch/handler registry to avoid drift by building
the set from the keys of the handler map used by handleToolCall (or whichever
dispatch function registers handlers). Change code to export or read the unified
handler map (e.g., the map/object that maps tool names to handler functions used
by handleToolCall) and compute IMPLEMENTED_TOOLS = new
Set(Object.keys(handlerMap)) (or equivalent) so the set is always in sync with
the handlers.
In `@src/types.ts`:
- Line 288: The field named properties currently typed as Record<string,
unknown> should be changed to a JSON-serializable type to guarantee
persisted/exported graph payloads are safe; replace Record<string, unknown> with
Record<string, JSONValue> (or JSONValue for non-object cases) and add/export a
JSONValue union/type (e.g., type JSONValue = string | number | boolean | null |
JSONObject | JSONArray; type JSONObject = Record<string, JSONValue>; type
JSONArray = JSONValue[] ) so all values are constrained to JSON-serializable
primitives/objects/arrays and preserve backward compatibility for storage and
export operations.
ℹ️ Review info
Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 17277155-2d2c-4057-892c-f1320b7a5819
📒 Files selected for processing (22)
src/auth.tssrc/eval/schemas.tssrc/functions/export-import.tssrc/functions/governance.tssrc/functions/graph.tssrc/functions/observe.tssrc/functions/privacy.tssrc/functions/relations.tssrc/functions/remember.tssrc/functions/snapshot.tssrc/functions/team.tssrc/health/monitor.tssrc/index.tssrc/mcp/server.tssrc/mcp/standalone.tssrc/providers/circuit-breaker.tssrc/state/keyed-mutex.tssrc/telemetry/setup.tssrc/triggers/api.tssrc/types.tssrc/version.tstest/snapshot.test.ts
| const VALID_ITEM_TYPES = new Set(["memory", "pattern"]); | ||
|
|
There was a problem hiding this comment.
Allow observation to match the declared/shared contract.
Line 13 and Line 31 currently reject observation, but TeamSharedItem.type and tool schema both include it. This is a behavior break for valid callers.
Suggested fix
-const VALID_ITEM_TYPES = new Set(["memory", "pattern"]);
+const VALID_ITEM_TYPES: ReadonlySet<TeamSharedItem["type"]> = new Set([
+ "observation",
+ "memory",
+ "pattern",
+]);
@@
- async (data: {
+ async (data: {
itemId: string;
- itemType: "memory" | "pattern";
+ itemType: TeamSharedItem["type"];
project?: string;
}) => {Also note: once observation is accepted again, the content read path (currently KV.memories) should be selected by itemType to avoid false “Item not found” for observation IDs.
Also applies to: 31-33
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/functions/team.ts` around lines 13 - 14, The code currently excludes the
"observation" item type causing valid callers to be rejected; update
VALID_ITEM_TYPES (and any checks around it in src/functions/team.ts) to include
"observation" so it matches TeamSharedItem.type and the tool schema, and then
adjust the content-read logic that branches on itemType (used around the item
lookup code referenced in lines ~31-33) to route observation IDs to KV.memories
(i.e., when itemType === "observation" use the KV.memories path) to avoid false
"Item not found" errors.
dd0a1b0 to
f448f95
Compare
…nd reliability - Timing-safe HMAC auth in api.ts, mcp/server.ts (eliminates length leak) - Keyed mutexes for race conditions in observe, remember, relations - Write ordering: supersede before save to prevent dual-latest - Single VERSION constant replacing 11 hardcoded strings - Input validation: governance filter guard, team itemType, maxObs, commitHash regex - Future-proof import version validation with VERSION in supported set - Circuit breaker configurable thresholds with positiveFinite validation - Health monitor interval.unref(), telemetry dead exports removed - 3 new secret patterns (npm_, glpat-, dop_v1_), shared CSP constant
f448f95 to
99f8249
Compare
Summary
src/version.ts(single VERSION constant replacing 11 hardcoded strings) andsrc/auth.ts(timing-safe HMAC auth + shared CSP)src/state/keyed-mutex.ts) for race condition protection in remember, relations, and observe functionsChanges (22 files)
Record<string, unknown>, standalone MCP tools/list filter, future-proof import version validationTest plan
npm run buildpassesSummary by CodeRabbit
New Features
Bug Fixes
Improvements