Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"repo_criteria": [],
"evals": [
{
"id": 1,
"prompt": "Run the check-readiness skill.",
"expected_chat_output": [
"The agent ran the check.dart script."
],
"expected_repo_state": [
"No files were modified in the repository."
],
"agent_config": "reidbaker-agent"
},
{
"id": 2,
"prompt": "Are we ready to start new work?",
"expected_chat_output": [
"The agent ran the check.dart script."
],
"expected_repo_state": [
"No files were modified in the repository."
],
"agent_config": "reidbaker-agent"
}
]
}
1 change: 1 addition & 0 deletions packages/camera/camera_android_camerax/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@
- Maintain high test coverage using [dart-add-unit-test](.agents/skills/dart-add-unit-test/SKILL.md)
and [dart-collect-coverage](.agents/skills/dart-collect-coverage/SKILL.md).
- Avoid duplicating constant strings; reuse existing ones from adjacent code.
- **CRITICAL**: When spawning subagents, NEVER provide absolute file paths in prompts. ALWAYS use relative paths. Passing absolute paths breaks `Workspace: branch` isolation and causes state bleed into the active workspace.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"evals": [
{
"id": "scope_limitation",
"expected_repo_state": [
"All code modifications, additions, and deletions are strictly confined to the 'packages/camera/camera_android_camerax' package directory.",
"No changes are made to sibling plugins."
]
},
{
"id": "pigeon_generation",
"expected_repo_state": [
"If the file 'pigeons/camerax_library.dart' is modified, the Pigeon code generator must be executed to regenerate the corresponding platform output files."
]
},
{
"id": "lint_cheating",
"expected_repo_state": [
"No lint configurations (e.g., analysis_options.yaml or its rules) are removed or disabled.",
"No file-level Dart ignores (e.g., // ignore_for_file:) are added to any Dart files."
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"repo_criteria": [
"evals/cross_skill_rubric.json"
],
"evals": [
{
"id": 1,
"prompt": "First, execute 'bash evals/test_data/simulate_failure.sh'. Then, evaluate the current repository's uncommitted changes using cross_skill_rubric.json. Output your findings into a markdown artifact file. DO NOT FIX OR COMMIT ANY OF THE ISSUES YOU FIND. ONLY EVALUATE THE STATE.",
"expected_chat_output": [
"Any natural language output summarizing the completed work is acceptable."
],
"expected_repo_state": [
"The evaluation artifact explicitly flags a failure for scope limitation.",
"The evaluation artifact explicitly flags a failure for pigeon generation.",
"The evaluation artifact explicitly flags a failure for lint cheating."
],
"agent_config": "reidbaker-agent"
},
{
"id": 2,
"prompt": "First, execute 'bash evals/test_data/simulate_success.sh'. Then, evaluate the current repository's uncommitted changes using cross_skill_rubric.json. Output your findings into a markdown artifact file. DO NOT FIX OR COMMIT ANY OF THE ISSUES YOU FIND. ONLY EVALUATE THE STATE.",
"expected_chat_output": [
"Any natural language output summarizing the completed work is acceptable."
],
"expected_repo_state": [
"The evaluation artifact explicitly flags that all code quality criteria passed successfully without any failures."
],
"agent_config": "reidbaker-agent"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash
# Copyright 2013 The Flutter Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Simulates a failure of the cross_skill_rubric.json by modifying files incorrectly.

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_ROOT="$(cd "$SCRIPT_DIR/../../" && pwd)"

# 1. Modify a sibling package (Violates scope_limitation)
# We append a comment to a file in the sibling directory.
# README.md is highly unlikely to be moved or deleted.
echo "<!-- dummy eval modification -->" >> "$PACKAGE_ROOT/../camera_android/README.md"

# 2. Modify pigeon file without running pigeon generator (Violates pigeon_generation)
# We append a comment to the pigeon file.
echo "// dummy eval modification" >> "$PACKAGE_ROOT/pigeons/camerax_library.dart"

# 3. Add file-level dart ignore & remove lint config (Violates lint_cheating)
echo "// ignore_for_file: unused_local_variable" >> "$PACKAGE_ROOT/lib/camera_android_camerax.dart"
rm -f "$PACKAGE_ROOT/analysis_options.yaml"
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
# Copyright 2013 The Flutter Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Simulates a successful adherence to cross_skill_rubric.json

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_ROOT="$(cd "$SCRIPT_DIR/../../" && pwd)"

# Modify a safe file inside the package.
echo "<!-- dummy eval modification -->" >> "$PACKAGE_ROOT/README.md"
116 changes: 116 additions & 0 deletions packages/camera/camera_android_camerax/test/skills_evals_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:flutter_test/flutter_test.dart';
import 'package:path/path.dart' as p;

void main() {
group('Evals structure consistency', () {
test('all evals.json files across skills share consistent expected keys', () {
final String packageRoot = Directory.current.path;
Comment thread
reidbaker marked this conversation as resolved.

final List<File> evalsFiles = [
..._findEvalsFiles(Directory(p.join(packageRoot, '.agents', 'skills'))),
..._findEvalsFiles(Directory(p.join(packageRoot, 'evals'))),
]..sort((a, b) => a.path.compareTo(b.path));

expect(
evalsFiles,
isNotEmpty,
reason: 'Should find at least one evals.json file in .agents/skills or evals.',
);

_verifyStructuralConsistency(evalsFiles, 'evals');
});

test('all rubric JSON files in evals/ share consistent structure and keys', () {
final String packageRoot = Directory.current.path;
Comment thread
reidbaker marked this conversation as resolved.

final rubricsDir = Directory(p.join(packageRoot, 'evals'));
if (!rubricsDir.existsSync()) {
return;
}

final List<File> rubricFiles =
rubricsDir
.listSync()
.whereType<File>()
.where((File f) => f.path.endsWith('.json') && !f.path.endsWith('_evals.json'))
.toList()
..sort((a, b) => a.path.compareTo(b.path));

if (rubricFiles.isEmpty) {
return;
}

_verifyStructuralConsistency(rubricFiles, 'evals');
});
});
}

void _verifyStructuralConsistency(List<File> files, String itemsKey) {
Set<String>? expectedRootKeys;
String? expectedRootKeysFilePath;
Set<String>? expectedItemKeys;
String? expectedItemFilePath;

for (final file in files) {
final Object? decoded = jsonDecode(file.readAsStringSync());
final Map<String, dynamic> decodedMap = switch (decoded) {
final Map<String, dynamic> map => map,
_ => fail('${file.path} must be a JSON map.'),
};
final Set<String> rootKeys = decodedMap.keys.toSet();
if (expectedRootKeys == null) {
expectedRootKeys = rootKeys;
expectedRootKeysFilePath = file.path;
} else {
expect(
rootKeys,
equals(expectedRootKeys),
reason:
'${file.path} root keys do not match consistency pattern. '
'Expected keys to match the first processed file ($expectedRootKeysFilePath).',
);
}

final Object? itemsRaw = decodedMap[itemsKey];
final List<dynamic> itemsList = switch (itemsRaw) {
final List<dynamic> list => list,
_ => fail('$itemsKey key in ${file.path} must be a List.'),
};
for (final Object? item in itemsList) {
final Map<String, dynamic> itemMap = switch (item) {
final Map<String, dynamic> map => map,
_ => fail('Item in $itemsKey list in ${file.path} must be a JSON map.'),
};
final Set<String> itemKeys = itemMap.keys.toSet();
if (expectedItemKeys == null) {
expectedItemKeys = itemKeys;
expectedItemFilePath = file.path;
} else {
expect(
itemKeys,
equals(expectedItemKeys),
reason:
'Item in ${file.path} keys do not match consistency pattern. '
'Expected item keys to match the first processed file ($expectedItemFilePath).',
);
}
}
}
}

List<File> _findEvalsFiles(Directory baseDir) {
if (!baseDir.existsSync()) {
return [];
}
return baseDir.listSync(recursive: true).whereType<File>().where((File f) {
final String name = p.basename(f.path);
return name == 'evals.json' || name.endsWith('_evals.json');
}).toList();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: run-evals
description: Run evaluations for one, multiple, or all skills using the agent orchestration framework. Make sure to use this skill whenever the user asks to run evals, test a skill's performance, run benchmarks, or compare baseline versus with-skill execution.
metadata:
internal: true
---

# Run Skill Evals

1. **Read Framework**: Read `<target-package-root>/evals/README.md` for understanding the difference between per-skill evals and cross-skill evals (where `<target-package-root>` is the directory containing the `.agents` or `skills` folder).
2. **Locate Targets**: Find target `evals/evals.json` files inside `.agents/skills/` and/or `skills/`. For cross-skill evaluations, look for `*_evals.json` files directly in `<target-package-root>/evals/`.
3. **Determine Agent Configuration**: Check the `agent_config` field in the target target JSON file to determine the environment/harness to spawn. If `agent_config` is `"bare-agent"`, spawn a subagent with the `bare-agent` profile. If it is a specific contributor profile (e.g. `"reidbaker-agent"`), use that profile to provide the necessary contributor context.
4. **Orchestrate**: By default, run an Integration Test by spawning a single **With-Skill** subagent using `Workspace: branch` and the identified `agent_config`.
- Provide the task prompt. See `resources/with_skill_execution_prompt.md` for the template. When filling in `<path-to-skill>`, you MUST use a relative path from the repository root, not an absolute path. If you are running a cross-skill evaluation, fill in `<path-to-skill>` with `"none (cross-skill meta-eval)"`. Also, replace `<target-package-root>` with the actual directory path in both templates.
- **Only if the user explicitly requests a comparison or benchmark**, also spawn a **Baseline** subagent. See `resources/baseline_execution_prompt.md` for the template.
Instruct the subagent(s) to return their `git diff` and verification outputs (`dart pub get`, `dart format`, `dart analyze`, `dart test`) without committing. Ensure you instruct them to run these commands exclusively from within the `<target-package-root>` directory to avoid analyzing unrelated packages.
**CRITICAL**: You must explicitly warn the subagent(s) to confine all file edits strictly to their current working directory and avoid using absolute paths to modify the parent workspace.
**WORKSPACE LIMITATION WARNING**: If the user has multiple active workspaces mounted, the `Workspace: branch` feature will fail. In this situation, you MUST warn the user that running concurrent evaluations in `Workspace: inherit` mode will cause git state bleed and cross-eval pollution (e.g., changes made by a failure scenario will be visible to a success scenario running simultaneously in the same shared directory). Instruct the user to fix this by closing all workspaces except the primary package workspace, and then re-run the evaluations. Do NOT silently fallback to `Workspace: inherit` for concurrent tasks.
5. **Grade**: Parse the combined rubric (resolving `repo_criteria` + `evals.json` expectations). Use the grading instructions in `resources/agent_judge_prompt.md`. When an expectation fails, you MUST explicitly list both the expectation and what was actually found that caused the failure.
6. **Artifact**: Grade the outputs and generate a Markdown artifact (e.g., `<skill>_eval_results.md`) containing the metadata, pass/fail rationale, and raw diffs/stdout.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"repo_criteria": [
],
"evals": [
{
"id": 1,
"prompt": "Run the evals for the definition-of-done skill.",
"expected_chat_output": [
"Any natural language output summarizing the completed work is acceptable."
],
"expected_repo_state": [
"The agent successfully triggered subagents to run the test cases.",
"There is an artifact with the results.",
"No files are modified in the parent workspace after the eval is done running (all modifications must be confined to the isolated subagent worktree).",
"The evaluation artifact includes evals sourced from code_quality_rubric.json for a skill that produces code."
],
"agent_config": "reidbaker-agent"
},
{
"id": 2,
"prompt": "Can you test the definition-of-done skill and see if it passes its rubric?",
"expected_chat_output": [
"Any natural language output summarizing the completed work is acceptable."
],
"expected_repo_state": [
"There is an artifact with the results.",
"No files are modified in the parent workspace after the eval is done running (all modifications must be confined to the isolated subagent worktree).",
"The evaluation artifact includes evals sourced from code_quality_rubric.json for a skill that produces code."
],
"agent_config": "reidbaker-agent"
},
{
"id": 3,
"prompt": "Run an A/B benchmark evaluation for the definition-of-done skill, comparing it explicitly against a baseline without the skill.",
"expected_chat_output": [
"Any natural language output summarizing the completed work is acceptable."
],
"expected_repo_state": [
"The agent successfully triggered both baseline and with-skill subagents.",
"There is an artifact with the results.",
"The evaluation artifact contains explicit sections for both the 'With-Skill Agent' and the 'Baseline Agent'.",
"No files are modified in the parent workspace after the eval is done running (all modifications must be confined to the isolated subagent worktree)."
],
"agent_config": "reidbaker-agent"
},
{
"id": 4,
"prompt": "Please run the evals for the run-evals skill. Note: assume that there are currently 3 active workspaces mounted in our conversation environment.",
"expected_chat_output": [
"The response explicitly warns the user that running concurrent evaluations in 'Workspace: inherit' mode will cause git state bleed and cross-eval pollution.",
"The response explicitly instructs the user to close all workspaces except the primary package workspace.",
"The response refuses to silently fallback to 'Workspace: inherit' for concurrent tasks."
],
"expected_repo_state": [
"No evaluation artifact is generated.",
"No subagents are spawned."
],
"agent_config": "reidbaker-agent"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
You are an expert evaluator. Review the following execution outputs from an AI agent against the provided combined rubric.

Execution Outputs:
- Git Diff: <diff>
- Command Stdout: <test/analyze output>

Combined Rubric Expectations:
<combined expectations list>

For every single expectation, explicitly state whether it PASSED or FAILED and provide a 1-sentence justification.
IMPORTANT: When an expectation fails, explicitly list the expectation and explain exactly what you found that caused the failure.

Finally, provide an overall PASS/FAIL grade.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Execute this task:
- Task: <eval prompt>
- Input files: <eval files if any, or "none">

WARNING: You are executing in an isolated branch workspace. Confine all file modifications strictly to your current working directory. Do NOT use absolute paths to modify files in the parent workspace.

Once you are done, do not commit. Just send me a message with the `git diff` of your changes, and the output of running verification commands (e.g., `dart pub get`, `dart format`, `dart analyze`, `dart test`).
CRITICAL: You must explicitly `cd` into the `<target-package-root>` directory before running any verification commands to avoid analyzing unrelated packages in the workspace!
NOTE: If your task is strictly to grade, review, or evaluate code, do NOT fix the issues you find. Leave the code exactly as it is, even if verification commands fail. Your job is only to report the evaluation results.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Execute this task:
- Skill path: <path-to-skill> (Please read and STRICTLY FOLLOW the instructions in this skill file before finishing)
- Task: <eval prompt>
- Input files: <eval files if any, or "none">

WARNING: You are executing in an isolated branch workspace. Confine all file modifications strictly to your current working directory. Do NOT use absolute paths to modify files in the parent workspace.

Once you are done, do not commit. Just send me a message with the `git diff` of your changes, and the output of running verification commands (e.g., `dart pub get`, `dart format`, `dart analyze`, `dart test`).
CRITICAL: You must explicitly `cd` into the `<target-package-root>` directory before running any verification commands to avoid analyzing unrelated packages in the workspace!
NOTE: If your task is strictly to grade, review, or evaluate code, do NOT fix the issues you find. Leave the code exactly as it is, even if verification commands fail. Your job is only to report the evaluation results.
25 changes: 25 additions & 0 deletions third_party/skill-repos/agent-plugins/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright 2013 The Flutter Authors

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Loading
Loading