Skip to content

Commit 78918bb

Browse files
lshalarenovate[bot]konradweissoxistoco-de-pot
authored
CodAIze Agent (#2574)
* Chat interface for AI assistant * Format * Update dependency io.ktor.plugin to v3.3.0 (#2412) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency com.charleskorn.kaml:kaml to v0.96.0 (#2430) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.39.1 (#2429) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update CODEOWNERS (#2425) * Update CODEOWNERS The Code owners are updated with specific responsibilities for passes. * Add Second responsible to language frontends and remove the language specific pass responsibles * Dokka v2 (#2413) * Change dokka config to new dsl * Delete unused code * Delete .kotlin/sessions directory * Add V2Enabled mode to gradle.properties * Delete tmp.json * Remove set previous docs folder --------- Co-authored-by: Konrad Weiss <konrad.weiss@aisec.fraunhofer.de> * Update dependency eslint-plugin-svelte to v3.12.4 (#2433) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.42.2 (#2432) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency com.vanniktech:gradle-maven-publish-plugin to v0.34.0 (#2397) * Update dependency com.vanniktech:gradle-maven-publish-plugin to v0.34.0 * Fixed --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Christian Banse <christian.banse@aisec.fraunhofer.de> * Moving `group` back to `allprojects` (#2435) * Update dependency @eslint/compat to v1.4.0 (#2436) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.43.5 (#2437) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Abstract Value Analysis (#1759) * create initial Size evaluator for modifiable lists * move all collection dependant logic into collection class * add support for static arrays * implement narrowing and widening operations * add narrowing and widening to loop analysis * handle branches in analysis * improve loops by preprocessing, better narrowing and valid starting ranges * improve subtraction by handling 0 as lowest possible value * mark branching nodes as nodes with an effect * correctly identify nodes of deeper branch layers in a loop * add documentation * temporarily repurpose cpg-neo4j for debugging * rework lattice intervals to support negative values * rename target package to circumvent gitignore * implement comparable for the LatticeInterval * implement the IntervalState * update the evaluator name in tests * implement equals check for intervals * add method stub for condition evaluation * Spotless * Squashed commit of the following: commit 5c20b05 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 13:25:06 2024 +0200 fix breaking merge changes commit cc8eb48 Merge: 3e3c094 344ea58 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 13:08:46 2024 +0200 Merge branch 'rh/abstract-value-analysis' into rh/abstract-value-analysis-worklist # Conflicts: # cpg-analysis/src/main/kotlin/de/fraunhofer/aisec/cpg/analysis/abstracteval/AbstractEvaluator.kt # cpg-core/src/main/kotlin/de/fraunhofer/aisec/cpg/helpers/EOGWorklist.kt commit 3e3c094 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 13:04:45 2024 +0200 remove redundant pushes to the worklist itself commit 6d731f2 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 13:04:21 2024 +0200 override methods to use custom functionality in IntervalStates commit 1eb5a51 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 13:03:57 2024 +0200 enhance analysis for simple value operations commit 108f374 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 09:56:22 2024 +0200 join intervals for multiple EOG (branch joins) commit d4383b4 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 09:33:41 2024 +0200 revert the change to the worklist pop to make it FIFO again commit 46798c5 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Wed Oct 16 09:33:23 2024 +0200 return a new altered state instead of directly modifying the current state commit c634646 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 13:12:46 2024 +0200 remove getInitialRange from the evaluator commit f984a2c Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 13:11:58 2024 +0200 remove the "getInitialRange" method for values and instead mark declarations as operations with effect commit beb4d38 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 12:26:22 2024 +0200 simplify evaluator to only use one worklist without special handling for loops and branches commit 6ec77dc Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 12:25:04 2024 +0200 add "until" to iteration, add state information to Worklist, fix pop order commit 253debb Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 12:23:17 2024 +0200 remove all modes from the IntervalState commit 31ca4ac Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 12:17:45 2024 +0200 remove boolean information about whether the operation had an impact commit ccd839e Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 14 09:17:11 2024 +0200 add three different state modes commit e0e1a28 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 7 12:08:52 2024 +0200 rewrite the handleBranch branch commit 672f27f Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 7 11:45:10 2024 +0200 rewrite the handleLoop branch commit 33f3531 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 7 10:54:15 2024 +0200 rewrite the applyEffect branch commit ca88bb7 Author: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Date: Mon Oct 7 10:20:39 2024 +0200 rewrite evaluate function to use "iterateEOG" * fix LatticeInterval.push to join with the previous value as it is already propagated from predecessors * Fix Declaration to only effect matching integers * correctly propagate widening only within loops * added second evaluate call with more defined arguments * support functions with side effects by creating a function-local evaluator * moved side effect analysis to list instead of integer... * add new 'assignMinus' expression and add the name as code when creating a reference * cleanup * add tests for the new Evaluator * first implementation for other integer operations * add prefix versions of the inc and dec operator * Add test case for all implemented Integer operations * add auto-generated hashcode function * cleanup and documentation * remove old code * import cleanup * automatically switch interval bounds if the lower bound is greater than the upper bound * remove min and max comparisons after multiplication as the constructor now handles the order * convert Bounded from data class to real class to remove constructor variables * fix division to estimate x / ∞ = 0 * simplify division cases * Fix invalid division cases * make modulo calculation more concise * beautify toString representation * add first LatticeInterval tests * fix meet of intervals when they do not overlap * add equals operator for the Interval wrapper * add tests for meet, widen, narrow and the wrapper * fix meet test method * change default of plusAssign and minusAssign to lose all information * add tests for the Integer Value * check name of array declaration * move code block for function side effects further up * add tests for array and mutable list * remove unfinished code block in MutableList * made spotless * changed the name of the Value classes to prevent confusion with builtin classes * Some renaming and extended test * formatting * Do not stop on target node and change int to long * Template for eventually using new iteration * Fix comment * Minor cosmetic changes * Move code to correct location * Several updates, missing widening and narrowing for integer tests * Some fixes * Fix integer tests * Some idea on integrating widening and narrowing * Try to integrate widening * Integrate widening and fix comparisons * Try to include conditions * Fix * Also handle negated condition * Redesign of list size evaluation * Small cleanup * Rework array value * Small cleanup * Fix list removeall * Size evaluation for sets * test set size evaluator * Improvements and more tests for sets * Integration into value evaluator system and query API * Revert unnecessary changes in EOGWorklist.kt * Split division by 0 and other test * Try to fix problematic integer lookup - no success * somewhat fix problem with equal but non-identical Integer objects used as keys * Fix min and max operations * Add more operators, implement shl * right shifting * bitwise and and or * trigger build * define some of the exceptional cases to avoid exceptions * Several fixes in tests and in minus * throw less exceptions and catch them * Fix asserts * Less unsupported operators * Some cleanup * Fix test * Remove commented out code --------- Co-authored-by: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Co-authored-by: KuechA <31155350+KuechA@users.noreply.github.com> Co-authored-by: Alexander Kuechler <alexander.kuechler@aisec.fraunhofer.de> * Update dependency @sveltejs/kit to v2.44.0 (#2441) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency com.charleskorn.kaml:kaml to v0.97.0 (#2442) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Timeout for CDG and CFSensitiveDFG pass (#2417) * Timeout for CDG and CFSensitiveDFG pass * Make the timeout an argument of iterateEOG * remove existing dfg edges only on success * apply strategy usage to to timeoutless invocation * updating call due to having non positional argument * Returning a non null time to solve the issue because apparently we are able to * Adding Test. Fixing coding issue that actually reran the iteration without timeout if the iteration timeouted * Add nullness conditional checks * Fixing coding issue that actually reran the iteration without timeout if the iteration timeouted * Spotless --------- Co-authored-by: Konrad Weiss <konrad.weiss@aisec.fraunhofer.de> * Only put AST nodes in `fields`/`methods`/... in `RecordDeclaration` that are part of the AST (#2403) * Added API to return methods of a Type * Added members, fields and methods * Add `declaringScope` to `Declaration`. * Extended unit test * Rename fields/methods/... in `RecordDeclaration` to `innerFields`, ... This should make it clear that it only contains those that are directly embedded into the AST structure. * Do not add Go's method to innerMethod AST property anymore * Fixed Go tests by using the correct Type API * Do not add outside methods in C++ to record inner methods * Trying to get rid of addXXX functions * Fixed test * Removed INNER_ * Make MCP configurable (#2444) * Make MCP configurable * Readme++ * Changing function signature of `parse` to accept the file content instead of a file (#1706) * Changing function signature of `parse` to accept the file content instead of a file This PR changes the way `parse` works (in a backwards compatible way). Instead of parsing a `File`, we parse the file contents (and a path). The reasoning behind this is that almost all language frontends currently need to read the file contents and we can harmonize this. This will also allow us to provide more common statistics about the parsing context in the future. * Fixed spotless * fixing uri handling due to it being nullable now * Fixing parameter order * Addign a Converter for the newly introduced TranslationStats --------- Co-authored-by: Konrad Weiss <konrad.weiss@aisec.fraunhofer.de> * Transition to integration tests for MCP (#2445) * Move unit tests depending on Python language frontend to integration test * Add missing dependency for Python language frontend in integration tests * Remove test condition for available Python language frontend --------- Co-authored-by: Christian Banse <christian.banse@aisec.fraunhofer.de> * Update dependency com.charleskorn.kaml:kaml to v0.98.0 (#2448) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.46.4 (#2447) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Fixing comment matching on multiple nested namespaces with no location (#2446) * Merging namespace skip if it has no location with ast tree exploration if nodes have no location to better match * moving iterative search into getEnclosingChild * Add condidate search to enclosing node search and neares node search in comment matcher * Move back testfile * Some refactoring * Nesting the comment test file into several folders to implicitly create namespaces * Update dependency globals to v16.4.0 (#2451) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.47.2 (#2450) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency vite to v6.4.1 [SECURITY] (#2453) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency com.charleskorn.kaml:kaml to v0.102.0 (#2457) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency @sveltejs/kit to v2.48.1 (#2456) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Expose host and port config in codyze API (#2458) * Metric and evidence ids in query trees (#2440) Metric and evidence ids * Remove `evidenceID` from `QueryTree` (#2460) Remove evidence ID from QueryTree * Update dependency eslint-plugin-svelte to v3.13.0 (#2462) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency black.ninia:jep to v4.3.1 (#2461) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Propagate information from underlying node to overlay node (#2466) * Propagate information from underlying node to overlay node Set `code` and `location` from `underlyingNode` when setting it * Spotless * Rework information propagation using the onChange callback from `EdgeSingletonList` Pulled callback into `OverlaySingleEdge` to use it. * Python: remove unsupported versions/add current & future versions (#2467) * Update dependency com.vanniktech:gradle-maven-publish-plugin to v0.35.0 (#2470) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Update dependency globals to v16.5.0 (#2464) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * Use koog for LLM stuff; Fix Chat UI bugs * feat(console): rename to CodAIze Agent, update sidebar icon to robot, gradient styling, route /ai-agent * Add a custom MCP Client + UI Widgets * Update mcp sdk types in cpg-mcp modules due to version upgrade * Update imports of kotlin mcp sdk in cpg-mcp module * Update imports of kotlin mcp sdk in cpg-mcp module * Replace netty with cio * Add thinking * Fix mcp util * Add gemini client; Update widgets * Refactor clients * Add logs for token usage * Change model * Refactor sending conversation history to LLM; Extend config for mlx llms * Some refactoring * Change listing tools returning summaries instead of complete node * New tool and refactoring * Minor changes * Minor changes 2 * Set noEdges to false for query tree * Remove debug logs * Add missing payload for concept assignment * Revert CLI run command back to clikt and add wait parameter * Downgrade ktor to 3.2.3 due to kotlin-mcp-sdk * Change cpg_llm_analyze tool in prompt * Remove sampling since llm_analyze mcp tool is changed to a prompt * Minor changes * Change urls of mlx and vllm models * Add prompts and resources support * Revert ChatClient back using SSE instead of http * Configure streamable http connection in MCP client * Add application.conf.example file * Remove application.conf from tracking * Fix svelte deprececated issues in layout.svelte * Fix svelte modal issue * Fix svelte warnings: add $derived * Change integration tests due to latest kotlin-sdk release of 0.9.0 According to the release notes for version 0.9.0 there is a breaking change regarding the "handler" function, which we use in almost every test. It now accepts a ClientConnection as receiver, which for our tests would mean creating a dummy class with some boilerplate code. The better way is using the newly introduced kotlin-sdk-testing, which provides a way to test the client-server functionalities without network (in-memory). The test setup implementation follows the sample here: https://github.com/modelcontextprotocol/kotlin-sdk/blob/5b58814613069babb1bbd5cab4572331eaed4b45/kotlin-sdk-testing/Module.md * Fix warnings in ListCommandsTest * Fix failing tests * Change JsonSChemaGeneratorTest using a test payload making the test more stable * Fix mcp integration tests * Uncomment prompt test * Uncomment suggestConceptsPromptTest * Refactor mcp integration tests * Add mcp sdk ServerSession in tests * Try fixing tests again * Add example python files back in codyze-core * Fix svelte issues * Cleanup * Revert mcp sdk version back to 0.8.4 due to flaky tests * Make ChatService creation dependend on config file * Minor fixes * Make CodeViewer, Filetree and NodeTable components reusable for ChatInterface * Fix issues when starting codyze webconsole and mcp module disabled * Upgrade mcp sdk to 0.9.0 * First try with ChannelTransport * Add cancel and close in finally block * Try more tests * Try ListCommandsTest * Use new test function in ApplyConceptsTest * Fix remaining tests * Add join() to wait until cancel is done * Fix imports * Revert changes back * Refactor test setup * Add missing functionality from mcp-sdk-testing example * Get rid of unnecessary functions * Add comment * Replace runTest with runBlocking to use the ChannelTransport's default dispatcher * Replace runTest in all remaining tests * Use CompletableDeferred as in the example * Remove unnecessary launch/join for client.connect * Try tests with timeout * Refactor test setup again * Refactor McpTestSetup * Add unconfined dispatcher for channel transport * Remove runBlocking in tests * Refactor setup * Add comment * Fix imports * Fix listFunctionsTest * Add ServerSession in testsetup * Set default dispatcher * Create session before client connection * Change frontend-dependency-conventions to runTimeOnly * Revert setting back * DocStrings * Use logger instead of println * More logs * Exclude shadowJar, shadowDistZip, and shadowDistTar in ci build * Add missing mcp integration tests * Add tests for ChatClient * Replace println's * Add MCP application tests * Merge ChatService and ChatClient * Rename test * Refactor data flow widget * Replace schema of getNode tool * Fix docstrings, host propagation and imports * Rename mcp models from '*summary' back to '*info' * Fix JsonSchemaGeneratorTest by adding descriptions * Readme * Fix test ListCommandsTest in mcp module * Revert unintended changes --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Konrad Weiss <konrad.weiss@aisec.fraunhofer.de> Co-authored-by: Christian Banse <christian.banse@aisec.fraunhofer.de> Co-authored-by: Robert Haimerl <robert-haimerl@mailbox.org> Co-authored-by: Robert Haimerl <robert.haimerl@aisec.fraunhofer.de> Co-authored-by: KuechA <31155350+KuechA@users.noreply.github.com> Co-authored-by: Alexander Kuechler <alexander.kuechler@aisec.fraunhofer.de> Co-authored-by: Maximilian Kaul <maximilian.kaul@aisec.fraunhofer.de> Co-authored-by: Florian Wendland <florian.wendland@aisec.fraunhofer.de>
1 parent 428c48a commit 78918bb

73 files changed

Lines changed: 4886 additions & 835 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
uses: gradle/actions/setup-gradle@v5
6868
- name: Build ${{ env.version }}
6969
run: |
70-
./gradlew --parallel spotlessCheck -x spotlessApply build -x distZip -x distTar koverXmlReport koverHtmlReport performanceTest integrationTest
70+
./gradlew --parallel spotlessCheck -x spotlessApply build -x distZip -x distTar -x shadowJar -x shadowDistZip -x shadowDistTar koverXmlReport koverHtmlReport performanceTest integrationTest
7171
id: build
7272
env:
7373
ORG_GRADLE_PROJECT_version: ${{ env.version }}

AGENTS.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# AGENTS.md
2+
3+
This file provides guidance to AI coding agents (Claude Code, Cursor, Codex, Gemini CLI, etc.) working in this repository.
4+
5+
## Project Overview
6+
7+
**CPG** is a code property graph library and analysis platform.
8+
9+
Key modules:
10+
- **cpg-core** – Core library: AST nodes, graph structures, passes, type system
11+
- **cpg-analysis** – Higher-level analyses built on top of cpg-core (dataflow, control flow, call graphs, etc.)
12+
- **cpg-language-\*** – Language frontends, one module per language (e.g., `cpg-language-go`, `cpg-language-python`)
13+
- **cpg-concepts** – Concept and operation definitions
14+
- **cpg-mcp** – MCP server exposing CPG analysis tools (dataflow, symbol analysis, concept application) to LLMs via streamable HTTP
15+
- **codyze-console** – Web-based analysis UI with AI agent chat (see [Architecture](#codyze-console-architecture) below)
16+
17+
## Technology Stack
18+
19+
### Backend
20+
- **Language**: Kotlin (requires Java 21)
21+
- **Build**: Gradle with Kotlin DSL
22+
- **Testing**: JUnit 5, kotlin.test
23+
- **Formatting**: Google Java Style via spotless plugin
24+
25+
### Frontend (`codyze-console/src/main/webapp`)
26+
- **Framework**: Svelte 5 with SvelteKit
27+
- **Styling**: Tailwind CSS
28+
- **Package Manager**: pnpm (not npm)
29+
30+
## Development Commands
31+
32+
### Build
33+
34+
```bash
35+
# Full build (format + test + publish locally)
36+
./gradlew clean spotlessApply build publishToMavenLocal
37+
38+
# Quick build
39+
./gradlew build
40+
41+
# Build a single module
42+
./gradlew :cpg-core:build
43+
./gradlew :codyze-console:build
44+
```
45+
46+
### Test & Quality
47+
48+
```bash
49+
./gradlew test # Unit tests
50+
./gradlew integrationTest # Integration tests
51+
./gradlew performanceTest # Performance tests
52+
./gradlew spotlessApply # Auto-format
53+
./gradlew spotlessCheck # Check formatting only
54+
```
55+
56+
### Frontend (`codyze-console`)
57+
58+
```bash
59+
cd codyze-console/src/main/webapp
60+
pnpm install # Install dependencies
61+
pnpm run dev # Dev server
62+
pnpm run build # Production build
63+
pnpm run check # Type check
64+
pnpm run lint # Lint
65+
pnpm run format # Format
66+
```
67+
68+
### Backend (`codyze-console`)
69+
70+
```bash
71+
./gradlew :codyze-console:compileKotlin --console=plain
72+
```
73+
74+
### MCP Server (`cpg-mcp`)
75+
76+
```bash
77+
./gradlew :cpg-mcp:installDist # Build & install
78+
./gradlew :cpg-mcp:run # Run (stdio)
79+
./gradlew :cpg-mcp:run --args="--http 8080" # Run with streamable HTTP on port 8080
80+
```
81+
82+
## Code Conventions
83+
84+
- Follow **Google Java Style** (enforced by spotless – run `./gradlew spotlessApply` before committing)
85+
- Kotlin idioms preferred over Java-style patterns
86+
- Use `kotlin.test` assertions in tests, not JUnit assertions directly
87+
- Frontend: use **Svelte 5 runes** exclusively (no legacy `$:` reactive syntax)
88+
89+
## codyze-console Architecture
90+
91+
codyze-console is a full-stack web application with a Ktor backend and a Svelte 5 SPA frontend. It provides code analysis capabilities and an AI agent chat interface.
92+
93+
### Backend (`codyze-console/src/main/kotlin/.../console/`)
94+
95+
| File / Package | Responsibility |
96+
|---|---|
97+
| `Main.kt` | Ktor/Netty entry point (port 8080), optionally starts MCP server on port 8081 |
98+
| `Router.kt` | REST API routes (`/api/analyze`, `/api/chat`, `/api/querytrees`, etc.) |
99+
| `ConsoleService.kt` | Core business logic: CPG analysis, QueryTree caching, concept management |
100+
| `Nodes.kt` | JSON serialization models and CPG node-to-JSON conversion |
101+
| `ai/ChatClient.kt` | MCP client + agentic tool-calling loop (connects to cpg-mcp via streamable HTTP) |
102+
| `ai/ChatService.kt` | Loads LLM config from HOCON, creates `ChatClient` with configured provider |
103+
| `ai/LlmClient.kt` | Provider-agnostic LLM interface (`sendPrompt` -> `List<ToolCall>`) |
104+
| `ai/OpenAiClient.kt` | OpenAI-compatible client (also works with Ollama, vLLM, MLX) |
105+
| `ai/GeminiClient.kt` | Google Gemini API client |
106+
| `ai/McpServerHelper.kt` | Reflection-based bridge to cpg-mcp; loads module dynamically so it remains an optional dependency |
107+
| `ai/ClientModels.kt` | Data classes for OpenAI/Gemini request/response formats |
108+
109+
#### AI Agent Data Flow
110+
111+
1. Frontend sends chat messages via `POST /api/chat` (SSE stream)
112+
2. `ChatClient` forwards to LLM with MCP tool definitions
113+
3. If LLM returns tool calls, `ChatClient` executes them against cpg-mcp via `mcp.callTool()`
114+
4. Tool results are streamed to the frontend and fed back to the LLM
115+
5. Loop repeats (max 8 iterations) until the LLM produces a text response
116+
117+
#### MCP Integration
118+
119+
codyze-console acts as both **MCP server host** and **MCP client**:
120+
- It starts the cpg-mcp server on port 8081 (via reflection, so cpg-mcp is an optional dependency)
121+
- `ChatClient` connects to it as a client using `StreamableHttpClientTransport`
122+
- After analysis, the global `TranslationResult` is injected into the MCP server so tools can access the CPG
123+
124+
### Frontend (`codyze-console/src/main/webapp/src/`)
125+
126+
| Directory | Content |
127+
|---|---|
128+
| `routes/` | SvelteKit pages: dashboard, components, requirements, chat, new-analysis |
129+
| `lib/components/ai-agent/` | Chat UI: `ChatInterface`, `WelcomeScreen`, `MessageInput`, `McpCapabilitiesModal` |
130+
| `lib/components/analysis/` | Code viewer, node tables, findings list, file tree |
131+
| `lib/components/requirements/` | Requirement cards, charts, QueryTree explorer (lazy-loading) |
132+
| `lib/services/apiService.ts` | SSE streaming utility (`streamPost` for `/api/chat`) |
133+
| `lib/services/llmAgent.ts` | Chat API facade wrapping `apiService` |
134+
| `lib/stores/queryTreeStore.ts` | In-memory cache for QueryTrees with batch fetching and lazy loading |
135+
| `lib/types.ts` | TypeScript interfaces mirroring backend JSON models |
136+
137+
### API Endpoints
138+
139+
**Analysis:** `POST /api/analyze`, `POST /api/reanalyze`, `GET /api/result`, `GET /api/component/{name}`
140+
141+
**Chat & MCP:** `POST /api/chat` (SSE), `GET /api/chat/mcp/capabilities`, `POST /api/chat/mcp/prompts/{name}`, `GET /api/features`
142+
143+
**Requirements:** `GET /api/requirement/{id}`, `GET /api/querytree/{id}`, `POST /api/querytrees` (batch), `GET /api/querytrees/{id}/parents`

codyze-console/README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Codyze Console
2+
3+
A web application for Codyze with an optional AI chat, which is enhanced by an MCP client that acts as an agent.
4+
The agent uses the tools of the CPG MCP server to analyze code and answer questions.
5+
6+
## Getting Started
7+
8+
The easiest way to get started is by using the predefined IntelliJ run configurations in the `.run/` directory:
9+
- *Codyze Console* (standalone)
10+
- *Codyze Compliance Scan (with Console and Example)* (with an example project).
11+
12+
Alternatively, starting the application from the command line:
13+
14+
```bash
15+
# Start the console only
16+
./gradlew :codyze:run --args="console"
17+
18+
# With an analysis of a project
19+
./gradlew :codyze:run --args="compliance scan --project-dir <path> --console=true"
20+
```
21+
22+
The web console is available at `http://localhost:8080`.
23+
24+
## AI Chat Features
25+
26+
The AI chat requires the `cpg-mcp` module to be enabled and a configured LLM provider.
27+
28+
### 1. Enable the `cpg-mcp` module
29+
30+
Run the configuration script:
31+
32+
```bash
33+
./configure_frontends.sh
34+
```
35+
36+
Or enable it manually by setting `enableMCPModule=true` in `gradle.properties`.
37+
38+
### 2. Configure your LLM provider
39+
40+
Copy the example configuration:
41+
42+
```bash
43+
cp codyze-console/src/main/resources/application.conf.example codyze-console/src/main/resources/application.conf
44+
```
45+
46+
Then edit `application.conf` and set the `client` field of the provider:
47+
48+
```hocon
49+
llm {
50+
client = "ollama"
51+
52+
ollama {
53+
baseUrl = "http://localhost:11434"
54+
model = "llama3"
55+
}
56+
57+
# ... other providers are preconfigured as placeholders.
58+
}
59+
```
60+
61+
Currently, only Gemini and OpenAI-compatible endpoints are supported. The predefined clients (`ollama`, `vLLM`, `mlx`, etc.) use all the same OpenAI-compatible client internally. They are intended for testing and development and allows to switch between different server URLs without reconfiguring every time.
62+
63+
### 3. MCP Server
64+
65+
When `cpg-mcp` is enabled, the MCP server is automatically started on port `8081`. The AI chat connects to it as an MCP client to access the CPG tools (e.g., listing functions, records, and calls).

codyze-console/build.gradle.kts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,32 @@ mavenPublishing {
1414
}
1515
}
1616

17+
val mcpEnabled = findProject(":cpg-mcp") != null
18+
1719
dependencies {
1820
// CPG modules
1921
implementation(projects.cpgConcepts)
22+
implementation(projects.cpgSerialization)
23+
24+
// MCP dependencies
25+
if (mcpEnabled) {
26+
implementation(project(":cpg-mcp"))
27+
// MCP SDK
28+
implementation(libs.mcp)
29+
// MCP Client SDK - for custom MCP client implementation
30+
implementation(libs.mcp.client)
31+
} else {
32+
// MCP SDK only available at compile time so the files in `/ai` compile,
33+
compileOnly(libs.mcp)
34+
compileOnly(libs.mcp.client)
35+
}
2036

2137
// Ktor server dependencies
2238
implementation(libs.bundles.ktor)
2339

40+
// Ktor client dependencies
41+
implementation(libs.bundles.ktor.client)
42+
2443
// Serialization
2544
implementation(libs.kotlinx.serialization.json)
2645
implementation(libs.jacksonyml)

codyze-console/src/main/kotlin/de/fraunhofer/aisec/codyze/console/ConsoleService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.SerializationFeature
3030
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
3131
import de.fraunhofer.aisec.codyze.AnalysisProject
3232
import de.fraunhofer.aisec.codyze.AnalysisResult
33+
import de.fraunhofer.aisec.codyze.console.ai.McpServerHelper
3334
import de.fraunhofer.aisec.cpg.TranslationConfiguration
3435
import de.fraunhofer.aisec.cpg.graph.concepts.Concept
3536
import de.fraunhofer.aisec.cpg.graph.concepts.conceptBuildHelper
@@ -40,6 +41,8 @@ import de.fraunhofer.aisec.cpg.passes.concepts.LoadPersistedConcepts.PersistedCo
4041
import de.fraunhofer.aisec.cpg.passes.concepts.LoadPersistedConcepts.PersistedConcepts
4142
import de.fraunhofer.aisec.cpg.passes.concepts.config.python.PythonStdLibConfigurationPass
4243
import de.fraunhofer.aisec.cpg.query.QueryTree
44+
import de.fraunhofer.aisec.cpg.serialization.NodeJSON
45+
import de.fraunhofer.aisec.cpg.serialization.toJSON
4346
import java.io.File
4447
import java.nio.file.Path
4548
import kotlin.uuid.Uuid
@@ -125,6 +128,9 @@ class ConsoleService {
125128

126129
val result = project.analyze()
127130

131+
// Update the global analysis result in the MCP server
132+
McpServerHelper.setGlobalAnalysisResult(result.translationResult)
133+
128134
// Populate QueryTree cache for lazy loading
129135
populateQueryTreeCache(result.requirementsResults)
130136

codyze-console/src/main/kotlin/de/fraunhofer/aisec/codyze/console/Main.kt

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,34 +25,66 @@
2525
*/
2626
package de.fraunhofer.aisec.codyze.console
2727

28-
import io.ktor.http.HttpHeaders
28+
import de.fraunhofer.aisec.codyze.console.ai.ChatService
29+
import de.fraunhofer.aisec.codyze.console.ai.McpServerHelper
30+
import io.ktor.http.*
2931
import io.ktor.serialization.kotlinx.json.*
3032
import io.ktor.server.application.*
3133
import io.ktor.server.engine.*
3234
import io.ktor.server.netty.*
3335
import io.ktor.server.plugins.contentnegotiation.*
3436
import io.ktor.server.plugins.cors.routing.*
3537
import io.ktor.server.routing.*
38+
import kotlinx.coroutines.runBlocking
3639
import kotlinx.serialization.json.Json
40+
import org.slf4j.LoggerFactory
41+
42+
private val log = LoggerFactory.getLogger("de.fraunhofer.aisec.codyze.console.Main")
3743

3844
/**
3945
* This function starts the embedded server for the web console. It uses the Netty engine and
4046
* listens on [host] (default: localhost) at [port] (default: 8080). The server is configured using
4147
* the [configureWebconsole] function.
4248
*/
4349
fun ConsoleService.startConsole(host: String = "localhost", port: Int = 8080) {
44-
embeddedServer(Netty, host = host, port = port) { configureWebconsole(this@startConsole) }
50+
val chatService: ChatService? =
51+
if (McpServerHelper.isEnabled) {
52+
runBlocking { initChatService() }
53+
} else {
54+
log.info("MCP module not enabled, AI chat features will be disabled")
55+
null
56+
}
57+
embeddedServer(Netty, host = host, port = port) {
58+
configureWebconsole(this@startConsole, chatService)
59+
}
4560
.start(wait = true)
4661
}
4762

63+
private suspend fun ConsoleService.initChatService(): ChatService? {
64+
val chatService = ChatService.createIfConfigExist() ?: return null
65+
66+
McpServerHelper.startMcpServer(8081)
67+
68+
val translationResult = getTranslationResult()?.analysisResult?.translationResult
69+
if (translationResult != null) {
70+
McpServerHelper.setGlobalAnalysisResult(translationResult)
71+
}
72+
chatService.connect()
73+
log.info("MCP client connected")
74+
return chatService
75+
}
76+
4877
/**
4978
* This function takes care of configuring the web console based on the [service]. It sets up the
5079
* CORS policy, content negotiation, and routing.
5180
*
5281
* Note: Currently, the CORS policy allows any host. This should be restricted to specific hosts in
5382
* a production environment and will be made available as an option later.
5483
*/
55-
fun Application.configureWebconsole(service: ConsoleService = ConsoleService()) {
84+
fun Application.configureWebconsole(
85+
service: ConsoleService = ConsoleService(),
86+
chatService: ChatService? = null,
87+
) {
5688
install(CORS) {
5789
anyHost()
5890
allowHeader(HttpHeaders.ContentType)
@@ -67,17 +99,21 @@ fun Application.configureWebconsole(service: ConsoleService = ConsoleService())
6799
)
68100
}
69101

70-
configureRouting(service)
102+
configureRouting(service, chatService)
71103
}
72104

73105
/**
74106
* This function sets up the routing for the web console. It defines the API routes and static
75107
* resources (for serving the single-page application frontend).
76108
*/
77-
fun Application.configureRouting(service: ConsoleService) {
109+
fun Application.configureRouting(service: ConsoleService, chatService: ChatService? = null) {
78110
routing {
79-
// We'll add routes here
80111
apiRoutes(service)
112+
// If the cpg-mcp module is enabled, chatService won't be null, so the endpoints will be
113+
// reachable
114+
if (chatService != null) {
115+
chatRoutes(chatService)
116+
}
81117
frontendRoutes()
82118
}
83119
}

0 commit comments

Comments
 (0)