Skip to content

Commit 513d2aa

Browse files
committed
[ai checker] refactor
- refactor agent interface - refactor export generation - add rst report - move report generation from bazel build to bazel test - rework guidelines
1 parent 679060c commit 513d2aa

52 files changed

Lines changed: 4120 additions & 2415 deletions

Some content is hidden

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

.bazelrc.ai_checker

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,28 @@
1212
# *******************************************************************************
1313

1414
###############################################################################
15-
## GitHub Copilot SDK - Environment (config:copilot)
15+
## GitHub Copilot SDK - Environment
1616
###############################################################################
17-
# The Copilot CLI needs HOME (for stored OAuth credentials) and proxy vars
18-
# (to reach api.github.com behind a corporate proxy).
17+
# No environment configuration is required here. The AI analysis runs at TEST
18+
# time and the AI test rules bake the required environment-variable inheritance
19+
# (HOME, the GitHub tokens, and proxy variables) into each target via
20+
# RunEnvironmentInfo. Running `bazel test //path/to:my_ai_check` inherits those
21+
# variables from your shell automatically — no --config or --test_env needed.
1922
#
20-
# These are scoped to --config=copilot so they don't affect other builds.
21-
# The AI checker BUILD target applies this config automatically via a
22-
# test --config=copilot line below.
23+
# Provide credentials by exporting one of COPILOT_GITHUB_TOKEN / GH_TOKEN /
24+
# GITHUB_TOKEN, or by logging in via the Copilot CLI (writes ~/.copilot/config.json).
2325
#
2426
# Auth docs: https://github.com/github/copilot-sdk/blob/main/docs/auth/index.md
2527

26-
# Auth
27-
build:copilot --action_env=HOME
28-
build:copilot --action_env=COPILOT_GITHUB_TOKEN
29-
build:copilot --action_env=GH_TOKEN
30-
build:copilot --action_env=GITHUB_TOKEN
31-
32-
# Proxy (Node.js checks both upper and lowercase)
33-
build:copilot --action_env=HTTP_PROXY
34-
build:copilot --action_env=HTTPS_PROXY
35-
build:copilot --action_env=NO_PROXY
36-
build:copilot --action_env=http_proxy
37-
build:copilot --action_env=https_proxy
38-
build:copilot --action_env=no_proxy
28+
###############################################################################
29+
## Project-specific guidelines (optional)
30+
###############################################################################
31+
# General + element-type guidelines are built in. Project-specific details
32+
# (e.g. requirement levels, architecture levels) are injected as graded rules
33+
# via label flags, set once here instead of on every AI test target.
34+
#
35+
# Point them at your own filegroup of .md files, or reuse the bundled SCORE
36+
# examples shown below.
37+
#
38+
# build --//validation/ai_checker:project_guidelines=//validation/ai_checker:score_project_guidelines
39+
# build --//validation/ai_checker:project_architecture_guidelines=//validation/ai_checker:score_project_architecture_guidelines

bazel/rules/rules_score/docs/user_guide/requirements.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ The `tags = ["manual"]` attribute is strongly recommended to prevent the rule fr
199199
Run the check explicitly with:
200200

201201
```bash
202-
bazel test //my/package:feature_requirements_ai_check --config=copilot
202+
bazel test //my/package:feature_requirements_ai_check
203203
```
204204

205205
| Attribute | Type | Required | Description |
@@ -210,7 +210,9 @@ bazel test //my/package:feature_requirements_ai_check --config=copilot
210210
| `score_threshold` | string | no | Minimum average quality score from 0 to 10 to pass the test (default: `"0.0"`) |
211211
| `guidelines` | label | no | Filegroup of guideline Markdown files to override the built-in guidelines |
212212

213-
**Output files** (written to `bazel-bin/`):
213+
**Output files** (the AI analysis runs at test time; reports are written to the
214+
test's undeclared-outputs archive at
215+
`bazel-testlogs/<package>/<name>/test.outputs/outputs.zip`):
214216

215217
| File | Content |
216218
|---|---|

bazel/rules/rules_score/examples/seooc/design/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ load(
1414
"//bazel/rules/rules_score:rules_score.bzl",
1515
"architectural_design",
1616
)
17+
load("//validation/ai_checker:ai_checker.bzl", "architecture_ai_test")
1718

1819
architectural_design(
1920
name = "sample_seooc_design",
@@ -29,3 +30,16 @@ architectural_design(
2930
],
3031
visibility = ["//visibility:public"],
3132
)
33+
34+
# Background context (read-only) for the AI architecture review.
35+
filegroup(
36+
name = "design_context",
37+
srcs = ["design_context.md"],
38+
)
39+
40+
architecture_ai_test(
41+
name = "sample_seooc_design_ai_test",
42+
context = ":design_context",
43+
designs = [":sample_seooc_design"],
44+
tags = ["manual"],
45+
)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!-- ----------------------------------------------------------------------------
2+
Copyright (c) 2025 Contributors to the Eclipse Foundation
3+
4+
See the NOTICE file(s) distributed with this work for additional
5+
information regarding copyright ownership.
6+
7+
This program and the accompanying materials are made available under the
8+
terms of the Apache License Version 2.0 which is available at
9+
https://www.apache.org/licenses/LICENSE-2.0
10+
11+
SPDX-License-Identifier: Apache-2.0
12+
----------------------------------------------------------------------------- -->
13+
14+
# Design Context: Sample SEooC
15+
16+
Background material provided to the AI reviewer as read-only reference. It is
17+
**not** graded; it only helps the reviewer interpret the architecture under
18+
review.
19+
20+
## Scope
21+
22+
This is a Safety Element out of Context (SEooC). The component is developed
23+
without a concrete vehicle-level item, so assumptions of use (AoU) stand in for
24+
the missing system context.
25+
26+
## Components
27+
28+
- The static design (`static_design.puml`) describes the component structure and
29+
its public interfaces.
30+
- The dynamic design (`dynamic_design.puml`) describes the runtime interaction
31+
between the component and its environment.
32+
- The public API (`public_api.puml`) defines the interfaces exposed to
33+
integrators.
34+
35+
## Assumptions of Use
36+
37+
- Integrators are responsible for satisfying the documented assumptions of use
38+
before relying on the component's safety claims.
39+
- The execution environment provides the resources declared in the static
40+
design.

validation/ai_checker/BUILD

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,47 +28,127 @@ filegroup(
2828
# Default requirements engineering guidelines
2929
filegroup(
3030
name = "default_guidelines",
31-
srcs = glob(["guidelines/*.md"]),
31+
srcs = ["guidelines/general.md"] + glob(["guidelines/requirements/*.md"]),
3232
visibility = ["//visibility:public"],
3333
)
3434

35-
# Core AI checker library (analysis framework)
35+
# Default architecture design guidelines
36+
filegroup(
37+
name = "default_architecture_guidelines",
38+
srcs = ["guidelines/general.md"] + glob(["guidelines/architecture/*.md"]),
39+
visibility = ["//visibility:public"],
40+
)
41+
42+
# Empty default for the project-guideline flags below. Consumer repos override
43+
# the flags in their .bazelrc to inject project-specific guidelines once,
44+
# instead of setting an attribute on every AI test target.
45+
filegroup(
46+
name = "empty_guidelines",
47+
srcs = [],
48+
visibility = ["//visibility:public"],
49+
)
50+
51+
# Project-specific requirement guidelines (graded). Override once via:
52+
# build --//validation/ai_checker:project_guidelines=//path/to:my_guidelines
53+
label_flag(
54+
name = "project_guidelines",
55+
build_setting_default = ":empty_guidelines",
56+
visibility = ["//visibility:public"],
57+
)
58+
59+
# Project-specific architecture guidelines (graded). Override once via:
60+
# build --//validation/ai_checker:project_architecture_guidelines=//path/to:my_guidelines
61+
label_flag(
62+
name = "project_architecture_guidelines",
63+
build_setting_default = ":empty_guidelines",
64+
visibility = ["//visibility:public"],
65+
)
66+
67+
# Example SCORE project guidelines, referenced by the flags above when a repo
68+
# opts into the SCORE process levels.
69+
filegroup(
70+
name = "score_project_guidelines",
71+
srcs = ["guidelines/project/score_requirement_levels.md"],
72+
visibility = ["//visibility:public"],
73+
)
74+
75+
filegroup(
76+
name = "score_project_architecture_guidelines",
77+
srcs = ["guidelines/project/score_architecture_levels.md"],
78+
visibility = ["//visibility:public"],
79+
)
80+
81+
# Core AI checker library (analysis framework).
82+
# Deliberately free of any AI-SDK / LangChain dependency: it depends only on
83+
# the AnalysisAgent interface, which concrete agents implement.
84+
# Core analysis framework + extractors + the AnalysisAgent interface.
85+
# No AI-SDK / LangChain dependency. The agents/ subpackage (concrete backends)
86+
# is intentionally excluded — those are separate libraries below.
3687
py_library(
3788
name = "ai_checker_core",
38-
srcs = glob(["src/ai_checker/*.py"]),
89+
srcs = glob([
90+
"src/ai_checker/*.py",
91+
"src/ai_checker/extractors/*.py",
92+
"src/ai_checker/reports/*.py",
93+
]),
94+
# Jinja2 report templates are loaded at runtime relative to the package,
95+
# so they must travel in the library's runfiles.
96+
data = glob(["src/ai_checker/reports/*.j2"]),
3997
imports = ["src"],
4098
visibility = ["//visibility:public"],
4199
deps = [
42100
"@trlc//trlc",
43101
requirement("bigtree"),
102+
requirement("jinja2"),
103+
requirement("markupsafe"),
44104
requirement("pydantic"),
45105
requirement("pydot"),
46106
requirement("pyyaml"),
47107
],
48108
)
49109

50-
# LangChain adapter for GitHub Copilot SDK
110+
# Default AI backend: GitHub Copilot SDK agent (no LangChain).
51111
py_library(
52-
name = "copilot_langchain",
112+
name = "copilot_agent",
53113
srcs = [
54-
"src/copilot_adapter/__init__.py",
55-
"src/copilot_adapter/_client_manager.py",
56-
"src/copilot_adapter/_errors.py",
57-
"src/copilot_adapter/_message_converter.py",
58-
"src/copilot_adapter/_preflight.py",
59-
"src/copilot_adapter/_tool_converter.py",
60-
"src/copilot_adapter/copilot_langchain.py",
114+
"src/ai_checker/agents/__init__.py",
115+
"src/ai_checker/agents/_client_manager.py",
116+
"src/ai_checker/agents/_errors.py",
117+
"src/ai_checker/agents/_preflight.py",
118+
"src/ai_checker/agents/copilot_agent.py",
61119
],
62120
imports = ["src"],
63121
visibility = ["//visibility:public"],
64122
deps = [
65-
requirement("langchain-core"),
123+
":ai_checker_core",
66124
requirement("github-copilot-sdk"),
67125
requirement("pydantic"),
68126
],
69127
)
70128

71-
# Default orchestrator (uses GitHub Copilot SDK as default AI backend)
129+
# Optional LangChain adapter: wraps any LangChain BaseChatModel (e.g. ChatOpenAI)
130+
# as an AnalysisAgent. Used only when a custom langchain model is supplied via a
131+
# custom ai_model target's create_agent().
132+
py_library(
133+
name = "langchain_agent",
134+
srcs = [
135+
"src/ai_checker/agents/__init__.py",
136+
"src/ai_checker/agents/_errors.py",
137+
"src/ai_checker/agents/langchain_agent.py",
138+
],
139+
imports = ["src"],
140+
visibility = ["//visibility:public"],
141+
deps = [
142+
":ai_checker_core",
143+
requirement("langchain-core"),
144+
],
145+
)
146+
147+
# Default orchestrator (uses the Copilot SDK agent as default AI backend).
148+
# Intentionally does NOT depend on :langchain_agent — the default path is
149+
# LangChain-free. A consumer wanting the LangChain path supplies a custom
150+
# ai_model target whose create_agent() returns a LangChainAgent and which
151+
# depends on :langchain_agent itself.
72152
py_binary(
73153
name = "orchestrator",
74154
srcs = ["src/ai_checker/orchestrator.py"],
@@ -77,8 +157,7 @@ py_binary(
77157
visibility = ["//visibility:public"],
78158
deps = [
79159
":ai_checker_core",
80-
":copilot_langchain",
81-
requirement("langchain-core"),
160+
":copilot_agent",
82161
],
83162
)
84163

0 commit comments

Comments
 (0)