Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
Warning Rate limit exceeded
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 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughIntegrates external network topology (schemas, TRPC proxy, per-asset 1‑hop subgraphs), renders Sankey network flows in the asset drawer, extends recommendation context with workflows/network/utilization, switches agent model/prompt, refactors workflow serialization, and performs a large seed/data overhaul including workflows and memories. ChangesNetwork Flow Integration and Recommendations Context Enhancement
Seed Data Overhaul and Markdown Rendering
Sequence Diagram(s)sequenceDiagram
participant Client
participant NetworkRouter
participant Upstream
participant Prisma
Client->>NetworkRouter: getFlowForAsset(assetId)
NetworkRouter->>Upstream: fetch topology (NETWORK_FLOW_URL, optional token, timeout)
Upstream-->>NetworkRouter: topology JSON
alt focal asset exists
NetworkRouter->>NetworkRouter: compute 1-hop connections & neighbor IDs
NetworkRouter->>Prisma: findMany assets by neighbor IDs
Prisma-->>NetworkRouter: asset metadata
NetworkRouter-->>Client: { in_flow: true, focal_asset_id, assets, connections }
else focal asset missing
NetworkRouter-->>Client: { in_flow: false }
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
There was a problem hiding this comment.
Actionable comments posted: 8
🧹 Nitpick comments (1)
scripts/print-recommendations-context.ts (1)
2-3: ⚡ Quick winAdd the server-side module marker.
This is a server-side TypeScript entrypoint and should include the server-only directive at module top.
Proposed fix
#!/usr/bin/env tsx +import "server-only"; import { getRecommendationsContext } from "`@/features/chat/viper-agent/tools/get-recommendations-context`"; import prisma from "`@/lib/db`";As per coding guidelines:
**/*.{ts,tsx}: Mark server-side files with 'server-only' directive and client components with 'use client' directive.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/print-recommendations-context.ts` around lines 2 - 3, This module imports getRecommendationsContext and prisma but is a server-side entrypoint and missing the server-only directive; add the server-side module marker ("server-only") as the first line of the file so the module is treated as server-only and keeps server-only imports like getRecommendationsContext and prisma valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/print-recommendations-context.ts`:
- Around line 5-7: The script's Prisma client may not be disconnected if an
exception occurs in main; modify the async function main() so its body is
wrapped in a try/finally where prisma.$disconnect() is called in finally
(ensuring disconnection on both success and error), and add a top-level .catch
on main() (or a surrounding try/catch when invoking main) to log the error and
exit appropriately; update any other similar invocations (lines referenced) to
follow the same try/finally + top-level catch pattern, referencing the main
function and prisma.$disconnect() to locate the changes.
- Around line 10-14: The code currently bypasses type safety by double-casting
getRecommendationsContext to unknown and forcing a handler signature; instead
declare a narrow handler type (e.g., RecommendationsContextHandler) matching the
real handler signature (args: Record<string, never>, ctx: { network?: { state?:
{ data?: { userId?: string; userRole?: string } } } }) => Promise<string>, cast
getRecommendationsContext to an object with an optional handler property of that
type (e.g., getRecommendationsContext as { handler?:
RecommendationsContextHandler }), perform a runtime guard that throws if
tool.handler is not a function, and then call tool.handler({}, { network: {
state: { data: { userId: user.id, userRole: "hospital administration" } } } })
so the call is both type-safe and verified at runtime.
In `@src/features/assets/components/asset-drawer.tsx`:
- Around line 241-263: Guard against unknown proto or peer lookups when building
Sankey links: before creating each link from protoToPeer, verify
protoSet.indexOf(proto) !== -1 and peers.findIndex(a => a.id === peerId) !== -1
(i.e. that protoIdx(proto) and peerIdx(peerId) would be valid), and skip entries
where either lookup is missing; similarly ensure items from focalToProto use a
proto that exists in protoSet. Update the mapping that builds links (the
protoToPeer and focalToProto -> links sections, referencing protoIdx, peerIdx,
protoSet, peers, mapped, focalToProto, and protoToPeer) to filter out or ignore
entries with unknown proto or peer IDs so no invalid Sankey targets are emitted.
In `@src/features/chat/utils.ts`:
- Around line 99-127: The rendering currently iterates only the keys present in
dayData so missing hours are omitted; change the hours loop to iterate the full
0–23 range (or build hours as [0..23]) and for each hour call
utilizationBucket(dayData[String(hour)] ?? 0) so absent keys are treated as
0/Offline, thereby generating segments that include offline windows; update the
variable references used in the diff (data, dayData, UTILIZATION_DAY_NAMES,
utilizationBucket, segments) and keep the same segment-merging logic so
contiguous absent hours collapse into Offline ranges.
In `@src/features/chat/viper-agent/agents/give-recommendations.ts`:
- Around line 29-31: The MODEL constant uses anthropic(...) with an unsupported
model id "claude-opus-4-6"; update the model string in the MODEL definition to a
supported Anthropic id (for example a claude-3 or claude-2 family id such as
"claude-3-opus-*" or "claude-2.*") while keeping the existing defaultParameters
key, or alternatively update the pinned `@inngest/agent-kit` SDK to a version that
supports "claude-opus-4-6". Target the MODEL constant and the anthropic(...)
call when making this change.
In `@src/features/chat/viper-agent/tools/get-recommendations-context.ts`:
- Around line 132-147: generateWorkflowsMarkdown currently embeds entire
serialized workflows (via serializeWorkflow and shortId) which can create huge
prompt payloads; limit the amount of data by truncating/capping: restrict the
number of workflows included (e.g., take first N), and when embedding serialized
JSON only include a whitelist of small fields or truncate long arrays/strings
(e.g., topology/utilization lists) and append a "...(truncated)" marker; apply
the same bounding logic to the other serialization helpers referenced in the
review (the blocks around lines 339-368 and 403) so networks/utilization lists
are similarly capped before JSON.stringify is added to the markdown.
In `@src/features/network/types.ts`:
- Around line 16-17: The ipv4_address and ipv6_address fields on
networkInterfaceSchema currently allow any string; replace their definitions to
use Zod's IP validators (e.g., for IPv4: use z.string().ip({ version: "ipv4"
}).optional().nullable(), and for IPv6: use z.string().ip({ version: "ipv6"
}).optional().nullable()) so malformed addresses fail validation; update the
properties named ipv4_address and ipv6_address in networkInterfaceSchema
accordingly.
In `@src/features/workflows/utils.ts`:
- Around line 12-24: serializeWorkflow currently returns { id, name,
description, nodes } but callers (e.g., workflowToMermaidJSON) expect
serialized.edges; fix serializeWorkflow to also serialize and return an edges
array by mapping WorkflowWithRelations.edges into the SerializedEdge shape used
elsewhere (mirror how nodes are built from workflow.nodes), then include edges
in the returned object so serialized.edges exists for workflowToMermaidJSON;
update references to WorkflowWithRelations, serializeWorkflow, workflow.nodes
and workflow.edges accordingly.
---
Nitpick comments:
In `@scripts/print-recommendations-context.ts`:
- Around line 2-3: This module imports getRecommendationsContext and prisma but
is a server-side entrypoint and missing the server-only directive; add the
server-side module marker ("server-only") as the first line of the file so the
module is treated as server-only and keeps server-only imports like
getRecommendationsContext and prisma valid.
🪄 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: 8d7fa853-2e73-420a-ab7e-40e0d11a3e03
📒 Files selected for processing (14)
.env.exampleprisma/flow.jsonprisma/seed.tsscripts/print-recommendations-context.tssrc/features/assets/components/asset-drawer.tsxsrc/features/assets/components/dashboard-columns.tsxsrc/features/chat/utils.tssrc/features/chat/viper-agent/agents/give-recommendations.tssrc/features/chat/viper-agent/tools/get-recommendations-context.tssrc/features/network/server/router.tssrc/features/network/types.tssrc/features/workflows/server/routers.tssrc/features/workflows/utils.tssrc/trpc/routers/_app.ts
| const MODEL = anthropic({ | ||
| model: "claude-opus-4-6", | ||
| defaultParameters: { max_tokens: 4096 }, |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For @inngest/agent-kitv0.13.2, what are the supported Anthropic model IDs and valid anthropic() configuration keys? Specifically, isanthropic({ model: "claude-opus-4-6", defaultParameters: { max_tokens: 4096 } }) valid?
💡 Result:
For @inngest/agent-kit v0.13.2, the supported Anthropic model IDs (as listed in the AgentKit Anthropic model reference) are: - claude-3-5-haiku-latest [1] - claude-3-5-haiku-20241022 [1] - claude-3-5-sonnet-latest [1] - claude-3-5-sonnet-20241022 [1] - claude-3-5-sonnet-20240620 [1] - claude-3-opus-latest [1] - claude-3-opus-20240229 [1] - claude-3-sonnet-20240229 [1] - claude-3-haiku-20240307 [1] - claude-2.1 [1] - claude-2.0 [1] - claude-instant-1.2 [1] Valid anthropic configuration keys (i.e., the options accepted by AgentKit’s anthropic configuration object) are [1]: - model (string, required) [1] - apiKey (string; defaults to ANTHROPIC_API_KEY) [1] - baseUrl (string; default https://api.anthropic.com/v1/) [1] - betaHeaders (string[]) [1] - defaultParameters (object, required) [1] - And within defaultParameters, AgentKit explicitly requires defaultParameters.max_tokens [1] - The docs also show defaultParameters being used for other Anthropic generation parameters like temperature [1] Is anthropic({ model: "claude-opus-4-6", defaultParameters: { max_tokens: 4096 } }) valid? No, not according to AgentKit’s supported Anthropic model ID list for the anthropic helper, because "claude-opus-4-6" is not among the model IDs AgentKit lists as available [1]. Even though the shape of your configuration matches what the docs describe (model + defaultParameters with max_tokens) [1], AgentKit would not consider that model ID supported based on its reference list [1].
Citations:
Fix Anthropic model-id for the pinned @inngest/agent-kit version (config key is fine)
In src/features/chat/viper-agent/agents/give-recommendations.ts (lines 29-31), defaultParameters.max_tokens is a supported anthropic() key for @inngest/agent-kit v0.13.2, but model: "claude-opus-4-6" is not among the supported Anthropic model IDs in that version’s reference (claude-3-opus-*, claude-3-5-*, claude-2.*, etc. only). Replace the model id with one of the supported values (or adjust the pinned SDK if you need claude-opus-4-6).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/chat/viper-agent/agents/give-recommendations.ts` around lines 29
- 31, The MODEL constant uses anthropic(...) with an unsupported model id
"claude-opus-4-6"; update the model string in the MODEL definition to a
supported Anthropic id (for example a claude-3 or claude-2 family id such as
"claude-3-opus-*" or "claude-2.*") while keeping the existing defaultParameters
key, or alternatively update the pinned `@inngest/agent-kit` SDK to a version that
supports "claude-opus-4-6". Target the MODEL constant and the anthropic(...)
call when making this change.
| function generateWorkflowsMarkdown(workflows: WorkflowWithRelations[]): string { | ||
| if (workflows.length === 0) return "_No clinical workflows defined._"; | ||
|
|
||
| return workflows | ||
| .map((wf) => { | ||
| const serialized = serializeWorkflow(wf); | ||
| const lines = [`### ${serialized.name} (${shortId(serialized.id)})`]; | ||
| if (serialized.description) { | ||
| lines.push(`\n${serialized.description}`); | ||
| } | ||
| lines.push( | ||
| `\n\`\`\`json\n${JSON.stringify(serialized, null, 2)}\n\`\`\``, | ||
| ); | ||
| return lines.join("\n"); | ||
| }) | ||
| .join("\n\n"); |
There was a problem hiding this comment.
Bound the added workflow/network/utilization markdown to avoid oversized context payloads.
The new sections append full serialized workflows plus full topology/utilization lists without caps. On larger datasets, this can bloat prompt context and degrade response reliability.
Suggested patch
+const MAX_WORKFLOWS_IN_CONTEXT = 20;
+const MAX_CONNECTIONS_IN_CONTEXT = 200;
+const MAX_UTILIZATION_ASSETS_IN_CONTEXT = 100;
+
function generateWorkflowsMarkdown(workflows: WorkflowWithRelations[]): string {
if (workflows.length === 0) return "_No clinical workflows defined._";
- return workflows
+ const shown = workflows.slice(0, MAX_WORKFLOWS_IN_CONTEXT);
+ const body = shown
.map((wf) => {
const serialized = serializeWorkflow(wf);
const lines = [`### ${serialized.name} (${shortId(serialized.id)})`];
if (serialized.description) {
lines.push(`\n${serialized.description}`);
@@
})
- .join("\n\n");
+ .join("\n\n");
+ const remaining = workflows.length - shown.length;
+ return remaining > 0
+ ? `${body}\n\n_…${remaining} additional workflows omitted for brevity._`
+ : body;
}
@@
- const connections = topology.connections ?? [];
+ const connections = (topology.connections ?? []).slice(
+ 0,
+ MAX_CONNECTIONS_IN_CONTEXT,
+ );
@@
- for (const asset of assets) {
+ for (const asset of assets.slice(0, MAX_UTILIZATION_ASSETS_IN_CONTEXT)) {Also applies to: 339-368, 403-403
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/chat/viper-agent/tools/get-recommendations-context.ts` around
lines 132 - 147, generateWorkflowsMarkdown currently embeds entire serialized
workflows (via serializeWorkflow and shortId) which can create huge prompt
payloads; limit the amount of data by truncating/capping: restrict the number of
workflows included (e.g., take first N), and when embedding serialized JSON only
include a whitelist of small fields or truncate long arrays/strings (e.g.,
topology/utilization lists) and append a "...(truncated)" marker; apply the same
bounding logic to the other serialization helpers referenced in the review (the
blocks around lines 339-368 and 403) so networks/utilization lists are similarly
capped before JSON.stringify is added to the markdown.
There was a problem hiding this comment.
For now I think this is fine, I want to make sure we have all workflows present, and a lot of this tool will be rewritten after using it to test what we should spend engineering effort on next
There was a problem hiding this comment.
@0xcad, understood — keeping it unbounded makes sense while you're using this to explore what's worth investing in. Would you like me to open a follow-up issue to track the context payload bounding work for when the tool gets rewritten?
(ᵔᴥᵔ)
🧠 Learnings used
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 107
File: src/features/advisories/server/routers.ts:96-103
Timestamp: 2026-04-02T18:16:00.222Z
Learning: When reviewing TypeScript code that uses Zod v4 with Prisma-generated const enum objects, do not suggest replacing enum usage with `z.nativeEnum()`. In this project, `z.nativeEnum()` is deprecated under Zod v4—use the idiomatic pattern `z.enum(PrismaEnumObject)` (e.g., `z.enum(MyPrismaConstEnum)`), and treat direct `z.enum(PrismaEnumObject)` as the correct approach.
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 107
File: src/features/advisories/server/routers.ts:96-103
Timestamp: 2026-04-02T18:16:00.223Z
Learning: When writing Zod schemas in this repository (PATCH-UPGRADE/viper), do not use `z.nativeEnum()`. The project uses Zod v4 where `z.nativeEnum()` is deprecated; prefer `z.enum(PrismaEnumObject)` as the idiomatic pattern, including for Prisma-generated const enum objects (e.g., `IssueStatus`). Review Zod code to ensure enums are validated with `z.enum(...)` rather than `z.nativeEnum(...)`.
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 130
File: src/features/chat/viper-agent/tools/get-recommendations-context.ts:203-205
Timestamp: 2026-05-18T16:33:45.705Z
Learning: In PATCH-UPGRADE/viper, treat `Asset`, `Vulnerability`, and `Remediation` records as shared/global resources. Their `userId` field is audit/attribution only and is not intended to enforce access-control scoping. Therefore, during review, do NOT flag cross-tenant data-leakage concerns for unscoped `prisma.asset.findMany`, `prisma.vulnerability.findMany`, or `prisma.remediation.findMany` queries on these models when no tenant scoping is expected. Only raise data-leakage flags when a query involves tenant-scoped resources/models (i.e., where tenant filtering is required), not these explicitly global ones.
| ipv4_address: z.string().nullable().optional(), | ||
| ipv6_address: z.string().nullable().optional(), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Show the relevant section of the file
sed -n '1,120p' src/features/network/types.ts | nl -ba | sed -n '1,120p' > /tmp/types_head.txt
sed -n '1,60p' src/features/network/types.ts | nl -ba | sed -n '1,60p' > /tmp/types_top.txt
sed -n '10,40p' src/features/network/types.ts | nl -ba | sed -n '1,40p' > /tmp/types_10_40.txt
# 2) Find Zod import/version
rg -n "from ['\"]zod['\"]|require\(['\"]zod['\"]\)|zod" src/features/network/types.ts package.json pnpm-lock.yaml yarn.lock package-lock.json 2>/dev/null || true
# 3) Determine Zod version from lockfile/package.json
if [ -f package.json ]; then
cat package.json > /tmp/package.json.txt
fi
# Try to read version from lockfiles (best-effort)
if [ -f pnpm-lock.yaml ]; then
rg -n "zod@" pnpm-lock.yaml | head -n 20 > /tmp/zod_versions_lock.txt || true
fi
if [ -f package-lock.json ]; then
rg -n "\"zod\"" package-lock.json | head -n 20 > /tmp/zod_versions_lock_npm.txt || true
fi
if [ -f yarn.lock ]; then
rg -n "zod@" yarn.lock | head -n 20 > /tmp/zod_versions_lock_yarn.txt || true
fi
# 4) Print the captured outputs
echo "=== types.ts (lines 1-40) ==="
cat /tmp/types_10_40.txt
echo "=== package.json ==="
[ -f /tmp/package.json.txt ] && sed -n '1,160p' /tmp/package.json.txt || echo "No package.json found"
echo "=== zod references in relevant files ==="
ls -1 src/features/network/types.ts 2>/dev/null || true
echo "Search results: (may be empty)"
cat /tmp/zod_versions_lock.txt 2>/dev/null || true
cat /tmp/zod_versions_lock_npm.txt 2>/dev/null || true
cat /tmp/zod_versions_lock_yarn.txt 2>/dev/null || trueRepository: PATCH-UPGRADE/viper
Length of output: 106
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Helpers: line-numbered views without `nl`
ln_view() { awk '{printf "%6d\t%s\n", NR, $0}' "$1" | sed -n "${2},${3}p"; }
# 1) Verify file exists + show relevant lines
echo "=== File existence ==="
ls -la src/features/network/types.ts || true
echo "=== types.ts lines 1-80 ==="
ln_view src/features/network/types.ts 1 80
echo "=== types.ts lines 10-30 ==="
ln_view src/features/network/types.ts 10 30
# 2) Find Zod import + usage
echo "=== Zod import/usage search (types.ts) ==="
rg -n "import .*zod|from ['\"]zod['\"]|require\(['\"]zod['\"]\)|\bz\.ipv[46]\b|\bzod\b" src/features/network/types.ts || true
# 3) Determine Zod version from package/lockfiles (best-effort)
echo "=== dependency files ==="
ls -ლა package.json pnpm-lock.yaml yarn.lock package-lock.json 2>/dev/null || true
if [ -f package.json ]; then
echo "=== package.json (first 200 lines) ==="
sed -n '1,200p' package.json
fi
# Grep lockfiles for zod version strings (best-effort)
for f in pnpm-lock.yaml package-lock.json yarn.lock; do
if [ -f "$f" ]; then
echo "=== Searching $f for zod ==="
rg -n "zod" "$f" | head -n 30 || true
fi
doneRepository: PATCH-UPGRADE/viper
Length of output: 10681
🌐 Web query:
Zod v4.1.11 z.ipv4 z.ipv6 methods availability
💡 Result:
In Zod v4, the z.ipv4() and z.ipv6() methods are available as top-level functions on the z module [1][2][3]. Key details regarding IP validation in Zod v4: 1. Method Availability: The previous approach of using z.string().ip() has been replaced by explicit, top-level validators: z.ipv4() and z.ipv6() [1][2]. While the old z.string().ip() method may still exist in some contexts as a deprecated feature, the official recommendation is to use the new, more tree-shakable top-level functions [2]. 2. Usage: You can use these methods directly to validate strings [3]. If you need to accept either an IPv4 or an IPv6 address, you can combine them using z.union() [1][4]: const ipSchema = z.union([z.ipv4, z.ipv6]); 3. Additional Validation: Zod v4 also provides top-level methods for CIDR block validation: z.cidrv4() and z.cidrv6() [5][2][3]. These changes improve performance and allow for better tree-shaking by removing the need to chain methods off z.string() [2].
Citations:
- 1: https://zod.dev/v4/changelog
- 2: https://zod.dev/v4
- 3: https://zod.dev/api
- 4: https://chanfana.pages.dev/migration-to-chanfana-3
- 5: [Zod 4]: CidrSchema test fails for invalid IPv6 CIDR input colinhacks/zod#5184
Harden IPv4/IPv6 address validation in networkInterfaceSchema.
ipv4_address and ipv6_address are currently z.string()..., so malformed addresses can pass validation at the contract boundary. Use Zod’s dedicated IPv4/IPv6 validators instead.
Suggested patch
- ipv4_address: z.string().nullable().optional(),
- ipv6_address: z.string().nullable().optional(),
+ ipv4_address: z.ipv4().nullable().optional(),
+ ipv6_address: z.ipv6().nullable().optional(),📝 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.
| ipv4_address: z.string().nullable().optional(), | |
| ipv6_address: z.string().nullable().optional(), | |
| ipv4_address: z.ipv4().nullable().optional(), | |
| ipv6_address: z.ipv6().nullable().optional(), |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/network/types.ts` around lines 16 - 17, The ipv4_address and
ipv6_address fields on networkInterfaceSchema currently allow any string;
replace their definitions to use Zod's IP validators (e.g., for IPv4: use
z.string().ip({ version: "ipv4" }).optional().nullable(), and for IPv6: use
z.string().ip({ version: "ipv6" }).optional().nullable()) so malformed addresses
fail validation; update the properties named ipv4_address and ipv6_address in
networkInterfaceSchema accordingly.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/features/chat/viper-agent/tools/get-recommendations-context.ts`:
- Around line 138-145: The code is stripping dependency edges by destructuring
out edges into _edges and building withoutEdges, losing workflow dependency
data; update the logic in get-recommendations-context (where serialized is
handled and withoutEdges is created) to include the edges property in the JSON
payload for the "Clinical Workflows" context (i.e., do not remove edges or merge
serialized.edges back into withoutEdges) so the output JSON.stringify contains
the full node + edges structure required by the model to represent dependencies,
CVSS, patch status and life_safety flags.
🪄 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: 9646a321-48ea-4dc1-be15-f9dc5c4e9060
📒 Files selected for processing (5)
scripts/print-recommendations-context.tssrc/features/assets/components/asset-drawer.tsxsrc/features/chat/utils.tssrc/features/chat/viper-agent/tools/get-recommendations-context.tssrc/features/workflows/utils.ts
| const { edges: _edges, ...withoutEdges } = serialized; | ||
| const lines = [`### ${serialized.name} (${shortId(serialized.id)})`]; | ||
| if (serialized.description) { | ||
| lines.push(`\n${serialized.description}`); | ||
| } | ||
| lines.push( | ||
| `\n\`\`\`json\n${JSON.stringify(withoutEdges, null, 2)}\n\`\`\``, | ||
| ); |
There was a problem hiding this comment.
Don’t drop workflow dependency edges from context payload.
Line 138 and Line 144 remove edges from serialized workflows, which strips dependency structure from the “Clinical Workflows” context section.
Suggested patch
- const { edges: _edges, ...withoutEdges } = serialized;
+ const workflowForContext = {
+ ...serialized,
+ edges: serialized.edges.map((e) => ({
+ source: e.source,
+ target: e.target,
+ sourceHandle: e.sourceHandle ?? null,
+ targetHandle: e.targetHandle ?? null,
+ })),
+ };
@@
- `\n\`\`\`json\n${JSON.stringify(withoutEdges, null, 2)}\n\`\`\``,
+ `\n\`\`\`json\n${JSON.stringify(workflowForContext, null, 2)}\n\`\`\``,
);As per coding guidelines src/features/**/*.{ts,tsx}: “Model hospital systems as nodes representing clinical functions with edges for dependencies, including CVSS scores, patch status, and life_safety flags”.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/features/chat/viper-agent/tools/get-recommendations-context.ts` around
lines 138 - 145, The code is stripping dependency edges by destructuring out
edges into _edges and building withoutEdges, losing workflow dependency data;
update the logic in get-recommendations-context (where serialized is handled and
withoutEdges is created) to include the edges property in the JSON payload for
the "Clinical Workflows" context (i.e., do not remove edges or merge
serialized.edges back into withoutEdges) so the output JSON.stringify contains
the full node + edges structure required by the model to represent dependencies,
CVSS, patch status and life_safety flags.
There was a problem hiding this comment.
I dropped edges because nodes are pretty much these very iterative steps, step 1, step 2, etc, and are enumerated in order. having edges to link step 1 to step 2 in the model context is a waste of tokens -- writing this for humans, not the rabbit
There was a problem hiding this comment.
@0xcad — That makes sense. If the workflow nodes are already ordered sequential steps, the edges are structurally redundant and stripping them is the right call for token efficiency. Acknowledged!
(ↂ_ↂ) 🐇
✏️ Learnings added
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 138
File: src/features/chat/viper-agent/tools/get-recommendations-context.ts:138-145
Timestamp: 2026-05-22T15:43:42.654Z
Learning: In PATCH-UPGRADE/viper, workflow nodes in the `generateWorkflowsMarkdown` function (in `src/features/chat/viper-agent/tools/get-recommendations-context.ts`) are sequential steps (step 1, step 2, etc.) enumerated in order. Edges are intentionally stripped from the serialized workflow JSON sent to the LLM context to avoid wasting tokens — the ordering alone implies the dependencies. Do not flag the omission of edges in the Clinical Workflows context section as a bug or missing data.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 107
File: src/features/advisories/server/routers.ts:96-103
Timestamp: 2026-04-02T18:16:00.222Z
Learning: When reviewing TypeScript code that uses Zod v4 with Prisma-generated const enum objects, do not suggest replacing enum usage with `z.nativeEnum()`. In this project, `z.nativeEnum()` is deprecated under Zod v4—use the idiomatic pattern `z.enum(PrismaEnumObject)` (e.g., `z.enum(MyPrismaConstEnum)`), and treat direct `z.enum(PrismaEnumObject)` as the correct approach.
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 107
File: src/features/advisories/server/routers.ts:96-103
Timestamp: 2026-04-02T18:16:00.223Z
Learning: When writing Zod schemas in this repository (PATCH-UPGRADE/viper), do not use `z.nativeEnum()`. The project uses Zod v4 where `z.nativeEnum()` is deprecated; prefer `z.enum(PrismaEnumObject)` as the idiomatic pattern, including for Prisma-generated const enum objects (e.g., `IssueStatus`). Review Zod code to ensure enums are validated with `z.enum(...)` rather than `z.nativeEnum(...)`.
Learnt from: 0xcad
Repo: PATCH-UPGRADE/viper PR: 130
File: src/features/chat/viper-agent/tools/get-recommendations-context.ts:203-205
Timestamp: 2026-05-18T16:33:45.705Z
Learning: In PATCH-UPGRADE/viper, treat `Asset`, `Vulnerability`, and `Remediation` records as shared/global resources. Their `userId` field is audit/attribution only and is not intended to enforce access-control scoping. Therefore, during review, do NOT flag cross-tenant data-leakage concerns for unscoped `prisma.asset.findMany`, `prisma.vulnerability.findMany`, or `prisma.remediation.findMany` queries on these models when no tenant scoping is expected. Only raise data-leakage flags when a query involves tenant-scoped resources/models (i.e., where tenant filtering is required), not these explicitly global ones.
There was a problem hiding this comment.
should disappear with main rebase if VW-269 gets approved
There was a problem hiding this comment.
Big overhaul of seed.ts file, to try to more realistically model a rural hospital's imaging department (used for the demo narrative), rather than just throw random devices/vulnerabilities into our db
Also seeded workflows and memories for AI agent
I will, barring being hit by bus or something, modify this seed.ts file later to make it even more realistic for our hackathon challenge set scenario, but for now this is a good spot
There was a problem hiding this comment.
Debug script used to return tool call output, I just use this for token counting
There was a problem hiding this comment.
I believe I have to rebase off of main, once VW-269 gets merged in, to get this to disappear? But this was added in VW-269 (stacked git branches)
There was a problem hiding this comment.
new updated at column makes it more obvious which assets were recently added from BF
There was a problem hiding this comment.
- Add network topology data to AI context
- Add device utilization data to AI context
- Add serialized hospital workflow data to AI context
For now, all of these are pre-seeded in the db. We have ideas on how to eventually get these from a real hospital network/environment, but let's just give it to an AI and see if we can do anything useful with this first
There was a problem hiding this comment.
should disappear with main rebase if VW-269 gets approved
There was a problem hiding this comment.
should disappear with main rebase if VW-269 gets approved
There was a problem hiding this comment.
should disappear with main rebase if VW-269 gets approved
There was a problem hiding this comment.
should disappear with main rebase if VW-269 gets approved
Summary by CodeRabbit
New Features
Improvements
Chores
Tools