Skip to content

Commit bbcf1a5

Browse files
Merge branch 'main' into feat/context-relevance-check
2 parents 2f92341 + 978a481 commit bbcf1a5

170 files changed

Lines changed: 13812 additions & 1486 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.

.claude/CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@AGENTS.md

.claude/settings.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"enabledPlugins": {
3+
"pyright-lsp@claude-plugins-official": true,
4+
"superpowers@claude-plugins-official": true
5+
},
6+
"hooks": {
7+
"SessionStart": [
8+
{
9+
"matcher": "startup",
10+
"hooks": [
11+
{
12+
"type": "command",
13+
"command": "bash -c '[[ ! -d \"$PWD/.venv\" ]] && make -C \"$PWD\" setup >&2 || true'",
14+
"async": true,
15+
"statusMessage": "Running make setup..."
16+
}
17+
]
18+
}
19+
]
20+
}
21+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: giskard-oss-quality-gate
3+
description: Run the full code quality gate for the giskard-oss monorepo—format, lint, typecheck, and unit tests across all packages. Use when finishing a feature, before opening a PR, or when the user asks to check quality or run the gate.
4+
disable-model-invocation: true
5+
allowed-tools: Bash(make *)
6+
---
7+
8+
# giskard-oss — quality gate
9+
10+
## Results
11+
12+
```!
13+
echo "=== make format ===" && make format 2>&1 | tail -5
14+
echo "=== make check ===" && make check 2>&1 | tail -10
15+
echo "=== make test-unit PACKAGE=giskard-core ===" && make test-unit PACKAGE=giskard-core 2>&1 | tail -5
16+
echo "=== make test-unit PACKAGE=giskard-checks ===" && make test-unit PACKAGE=giskard-checks 2>&1 | tail -5
17+
echo "=== make test-unit PACKAGE=giskard-agents ===" && make test-unit PACKAGE=giskard-agents 2>&1 | tail -5
18+
```
19+
20+
Report pass/fail for each step. Fix root causes on failure — no `# type: ignore`, no skips. Re-run after fixing.

.claude/skills/setup-env/SKILL.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
description: Set up the full workspace dev environment. Use when the user wants to install dependencies, sync libs, or prepare the environment.
3+
disable-model-invocation: true
4+
allowed-tools: Bash(make *) Bash(uv *)
5+
---
6+
7+
## Setup dev env
8+
9+
!`make setup 2>&1 | tail -20`
10+
11+
## Validate installation and notify user
12+
13+
Check the output above for errors. If any errors occurred, try to fix them and re-run the failed step. Report whether installation was successful.

.cursor/rules/guidelines.mdc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ Do not remove unrelated code, functionalities, or comments without explicit reas
1515
## No CODEMAP
1616

1717
Never generate architecture maps, codemap files, or similar high-maintenance documentation that duplicates what is already in cursor rules, docstrings, and README. These files go stale fast and create maintenance burden.
18+
19+
## Root Causes, No Temporary Fixes
20+
21+
Trace failures to their source before making a change. Do not:
22+
- Add `# type: ignore` / `# pyright: ignore` without first confirming no structural fix is possible.
23+
- Modify test assertions to force a pass — if a test reveals a real bug, fix the bug.
24+
- Add `try/except` to suppress exceptions that should be fixed.
25+
26+
If the root cause is in a different library than where the symptom appears, say so before proposing a fix.
27+
28+
## Minimal Scope
29+
30+
Only touch files directly required by the task. Do not reformat untouched lines, rename unrelated variables, or add type annotations to code you didn't otherwise change. Propose nearby improvements separately and wait for approval.

.cursor/skills/giskard-oss-pr-ready/SKILL.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ If checks fail from missing tools, run **`make install`** and **`make install-to
4848

4949
Use valid shell assignments in `.env` (e.g. `GEMINI_API_KEY=...`). If you point `TEST_MODEL` / `TEST_EMBEDDING_MODEL` at another provider, add whatever API keys that provider expects (LiteLLM / the underlying SDK).
5050

51+
## Verification gate
52+
53+
Before declaring a branch merge-ready, include the following evidence in your response:
54+
55+
1. Last line(s) of `make check` output — must show no errors.
56+
2. Pytest summary from `make test-unit` — e.g. `52 passed, 0 failed`.
57+
3. If any step was skipped or failed, state it explicitly.
58+
59+
"It should pass" is not evidence. Show actual output.
60+
5161
## Library-specific rules
5262

5363
For package conventions (API patterns, tests layout), read `libs/<package>/.cursor/rules/`. Makefile targets are always invoked from the repository root as listed above.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919

2020
## Coding agents
2121

22-
If this PR was opened by or with a coding agent, read **[AGENTS.md](https://github.com/Giskard-AI/giskard-oss/blob/main/AGENTS.md)** at the repository root first — **it is required** (setup, `make` commands, expedited agent PR workflow, etc.).
22+
Autonomous agents with no human in the loop must read **[AUTONOMOUS.md](https://github.com/Giskard-AI/giskard-oss/blob/main/AUTONOMOUS.md)** before opening a PR.
2323

2424
**PR title:** agent-opened PRs **must** end the title with **`🤖🤖🤖🤖`** (exactly four robot emojis). Do not omit — that suffix is how the expedited agent PR workflow picks up the PR.
2525

2626
## Checklist
2727

2828
<!-- Mark with an `x` all the checkboxes that apply (like `[x]`) -->
2929

30-
- [ ] I've read the [`CODE_OF_CONDUCT.md`](https://github.com/Giskard-AI/ai-inspector/blob/master/CODE_OF_CONDUCT.md) document.
31-
- [ ] I've read the [`CONTRIBUTING.md`](https://github.com/Giskard-AI/ai-inspector/blob/master/CONTRIBUTING.md) guide.
30+
- [ ] I've read the [`CODE_OF_CONDUCT.md`](../CODE_OF_CONDUCT.md) document.
31+
- [ ] I've read the [`CONTRIBUTING.md`](../CONTRIBUTING.md) guide.
3232
- [ ] I've written tests for all new methods and classes that I created.
3333
- [ ] I've written the docstring in NumPy format for all the methods and classes that I created or modified.
3434
- [ ] I've updated the `uv.lock` running `uv lock` (only applicable when `pyproject.toml` has been

.github/labeler.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
- any-glob-to-any-file:
44
- "libs/giskard-core/**"
55

6+
"Scope: LLM":
7+
- changed-files:
8+
- any-glob-to-any-file:
9+
- "libs/giskard-llm/**"
10+
611
"Scope: Agents":
712
- changed-files:
813
- any-glob-to-any-file:

.github/workflows/ci.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2424
with:
2525
persist-credentials: false
26-
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
26+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
2727
with:
2828
enable-cache: true
2929
python-version: "3.12"
@@ -41,16 +41,34 @@ jobs:
4141
fail-fast: false
4242
matrix:
4343
python-version: ["3.12", "3.13", "3.14"]
44-
package: [giskard-core, giskard-agents, giskard-checks]
44+
package: [giskard-core, giskard-llm, giskard-agents, giskard-checks]
4545
env:
4646
PACKAGE: ${{ matrix.package }}
4747
steps:
4848
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
4949
with:
5050
persist-credentials: false
51-
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
51+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
5252
with:
5353
enable-cache: true
5454
python-version: ${{ matrix.python-version }}
5555
- run: make install
5656
- run: make test-unit PACKAGE=$PACKAGE
57+
58+
test-no-providers:
59+
name: test-no-providers / giskard-llm
60+
needs: lint
61+
runs-on: ubuntu-latest
62+
permissions:
63+
contents: read # checkout repository
64+
timeout-minutes: 10
65+
steps:
66+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
67+
with:
68+
persist-credentials: false
69+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
70+
with:
71+
enable-cache: true
72+
python-version: "3.12"
73+
- run: make install-no-providers
74+
- run: make test-no-providers

.github/workflows/integration-tests.yml

Lines changed: 124 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ name: Integration Tests
33
on:
44
pull_request_target: # zizmor: ignore[dangerous-triggers] guarded by authorize job, label gate for external PRs, and immutable head.sha checkout
55
types: [opened, synchronize, reopened, labeled]
6+
workflow_dispatch:
67

78
permissions: {}
89

910
concurrency:
10-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
11+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
1112
cancel-in-progress: true
1213

1314
jobs:
@@ -17,10 +18,23 @@ jobs:
1718
steps:
1819
- name: Check authorization
1920
env:
21+
GH_TOKEN: ${{ github.token }}
22+
EVENT_NAME: ${{ github.event_name }}
23+
ACTOR: ${{ github.actor }}
2024
AUTHOR_ASSOC: ${{ github.event.pull_request.author_association }}
2125
EVENT_ACTION: ${{ github.event.action }}
2226
LABEL_NAME: ${{ github.event.label.name }}
2327
run: |
28+
# Manual dispatch: verify the actor belongs to the org
29+
if [[ "$EVENT_NAME" == "workflow_dispatch" ]]; then
30+
if gh api "orgs/Giskard-AI/members/$ACTOR" --silent 2>/dev/null; then
31+
echo "Org member $ACTOR — authorized."
32+
exit 0
33+
fi
34+
echo "::error::$ACTOR is not a member of the Giskard-AI organization."
35+
exit 1
36+
fi
37+
2438
# Internal contributors are always authorized
2539
if [[ "$AUTHOR_ASSOC" =~ ^(MEMBER|COLLABORATOR|OWNER)$ ]]; then
2640
echo "Internal contributor — authorized."
@@ -36,7 +50,7 @@ jobs:
3650
echo "::error::External contributors require a maintainer to add the 'safe for build' label."
3751
exit 1
3852
39-
test-functional:
53+
test-agents-functional:
4054
needs: authorize
4155
runs-on: ubuntu-latest
4256
permissions:
@@ -47,26 +61,122 @@ jobs:
4761
fail-fast: false
4862
matrix:
4963
python-version: ["3.12", "3.13", "3.14"]
50-
package: [giskard-core, giskard-agents, giskard-checks]
51-
name: test-functional / ${{ matrix.package }} / ${{ matrix.python-version }}
52-
env:
53-
PACKAGE: ${{ matrix.package }}
64+
backend:
65+
# Each backend exercises a different install combination so we
66+
# catch dependency regressions in the three supported layouts:
67+
# giskard-llm only, litellm only, and both installed together.
68+
# Using the top-level giskard-agents extras (not giskard-llm
69+
# directly) so the pass-through extras declared in
70+
# libs/giskard-agents/pyproject.toml are covered.
71+
- name: giskard-llm
72+
extras: "giskard-agents[google]"
73+
pytest_mark: "functional and google"
74+
- name: litellm
75+
extras: "giskard-agents[litellm]"
76+
pytest_mark: "functional and litellm"
77+
- name: both
78+
extras: "giskard-agents[google,litellm]"
79+
pytest_mark: "functional and (google or litellm)"
80+
name: agents / ${{ matrix.backend.name }} / ${{ matrix.python-version }}
5481
steps:
5582
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
5683
with:
57-
# Use the SHA from the event to ensure we're using the correct commit
58-
# for the `labeled` event. For external contributors, we want to use
59-
# the SHA corresponding to the time the label was added.
60-
ref: ${{ github.event.pull_request.head.sha }}
84+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
6185
persist-credentials: false
62-
- uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
86+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
6387
with:
6488
enable-cache: true
6589
python-version: ${{ matrix.python-version }}
6690
- run: make install
91+
- name: Install backend extras
92+
env:
93+
BACKEND_EXTRAS: ${{ matrix.backend.extras }}
94+
run: uv pip install "$BACKEND_EXTRAS"
6795
- name: Run functional tests
6896
env:
97+
GOOGLE_API_KEY: ${{ secrets.GEMINI_API_KEY }}
6998
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
70-
TEST_MODEL: "gemini/gemini-2.0-flash"
71-
TEST_EMBEDDING_MODEL: "gemini/gemini-embedding-001"
72-
run: make test-functional PACKAGE=$PACKAGE
99+
TEST_MODEL: "google/gemini-2.0-flash"
100+
TEST_LITELLM_MODEL: "gemini/gemini-2.0-flash"
101+
TEST_EMBEDDING_MODEL: "google/gemini-embedding-001"
102+
PYTEST_MARK: ${{ matrix.backend.pytest_mark }}
103+
run: uv run pytest libs/giskard-agents -m "$PYTEST_MARK"
104+
105+
test-llm-functional:
106+
needs: authorize
107+
runs-on: ubuntu-latest
108+
environment: ci
109+
timeout-minutes: 30
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
# One cell per routing prefix we want to exercise end-to-end.
114+
# `extras` is the giskard-llm optional-dependency group to install;
115+
# aliases share an install (bare/azure_ai reuse openai/azure, gemini reuses google).
116+
include:
117+
- { python-version: "3.12", provider: openai, extras: openai }
118+
- { python-version: "3.12", provider: bare, extras: openai }
119+
- { python-version: "3.12", provider: google, extras: google }
120+
- { python-version: "3.12", provider: gemini, extras: google }
121+
- { python-version: "3.12", provider: anthropic, extras: anthropic }
122+
- { python-version: "3.12", provider: azure, extras: azure }
123+
- { python-version: "3.12", provider: azure_ai, extras: azure }
124+
name: llm / ${{ matrix.provider }} / ${{ matrix.python-version }}
125+
env:
126+
PROVIDER: ${{ matrix.provider }}
127+
EXTRAS: ${{ matrix.extras }}
128+
steps:
129+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
130+
with:
131+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
132+
persist-credentials: false
133+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
134+
with:
135+
enable-cache: true
136+
python-version: ${{ matrix.python-version }}
137+
- run: make install
138+
- name: Install provider SDK
139+
run: uv pip install "giskard-llm[$EXTRAS]"
140+
- name: Run functional tests
141+
env:
142+
OPENAI_API_KEY: ${{ (matrix.provider == 'openai' || matrix.provider == 'bare') && secrets.OPENAI_API_KEY || '' }}
143+
GOOGLE_API_KEY: ${{ (matrix.provider == 'google' || matrix.provider == 'gemini') && secrets.GEMINI_API_KEY || '' }}
144+
ANTHROPIC_API_KEY: ${{ matrix.provider == 'anthropic' && secrets.ANTHROPIC_API_KEY || '' }}
145+
AZURE_API_KEY: ${{ matrix.provider == 'azure' && secrets.AZURE_API_KEY || '' }}
146+
AZURE_API_BASE: ${{ matrix.provider == 'azure' && secrets.AZURE_API_BASE || '' }}
147+
AZURE_API_VERSION: ${{ matrix.provider == 'azure' && secrets.AZURE_API_VERSION || '' }}
148+
AZURE_AI_API_KEY: ${{ matrix.provider == 'azure_ai' && secrets.AZURE_AI_API_KEY || '' }}
149+
AZURE_AI_ENDPOINT: ${{ matrix.provider == 'azure_ai' && secrets.AZURE_AI_ENDPOINT || '' }}
150+
run: make test-functional PACKAGE=giskard-llm PROVIDER=$PROVIDER
151+
152+
test-checks-functional:
153+
needs: authorize
154+
runs-on: ubuntu-latest
155+
environment: ci
156+
timeout-minutes: 30
157+
strategy:
158+
fail-fast: false
159+
matrix:
160+
python-version: ["3.12", "3.13", "3.14"]
161+
provider: [google]
162+
name: checks / ${{ matrix.provider }} / ${{ matrix.python-version }}
163+
env:
164+
PROVIDER: ${{ matrix.provider }}
165+
steps:
166+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
167+
with:
168+
ref: ${{ github.event.pull_request.head.sha || github.ref }}
169+
persist-credentials: false
170+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
171+
with:
172+
enable-cache: true
173+
python-version: ${{ matrix.python-version }}
174+
- run: make install
175+
- name: Install provider SDK
176+
run: uv pip install "giskard-llm[$PROVIDER]"
177+
- name: Run functional tests
178+
env:
179+
GOOGLE_API_KEY: ${{ matrix.provider == 'google' && secrets.GEMINI_API_KEY || '' }}
180+
TEST_MODEL: "google/gemini-2.0-flash"
181+
TEST_EMBEDDING_MODEL: "google/gemini-embedding-001"
182+
run: make test-functional PACKAGE=giskard-checks PROVIDER=$PROVIDER

0 commit comments

Comments
 (0)