Skip to content

Add catalog-reuse evaluation cards - #6333

Open
FadhlanR wants to merge 8 commits into
mainfrom
cs-13223-add-catalog-reuse-evaluation-cards
Open

FadhlanR wants to merge 8 commits into
mainfrom
cs-13223-add-catalog-reuse-evaluation-cards

Conversation

@FadhlanR

@FadhlanR FadhlanR commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Background and Goal

Two EvaluationCards that measure whether the AI assistant reuses the catalog instead of rebuilding, and the runner changes needed to measure that reliably.

  • reuse-service-desk-build is a support-desk brief with eight reuse opportunities across card, field, command and component, followed by a change request (P0–P4 priorities, auto-escalation). It is graded on:
    • the reuse ratio;
    • a must-not-hand-roll list;
    • whether the change is made by reusing the catalog.
  • reuse-listing-ownership opens with "I want to keep track of our wine collection", which the catalog's Wine Cellar Listing answers, with no ownership language. It then follows with "we'd like our own version". The assistant should reference the catalog definitions first, and install or remix the Listing only once ownership is asked for. The Wine Cellar Listing is used because it installs and remixes cleanly.

Related PRs:

Where to start

  • eval-realm/Evaluation/*.json holds the two evaluations. skillFeatures: ["catalog-reuse"] switches that feature on in each room, since the skill's sections sit behind a feature flag.
  • assistant-eval.spec.ts holds the runner changes described below.

Key decisions and non-obvious mechanics

  • skillFeatures on EvaluationCard. The runner sends boxel-debug:feature:enable:<name> before the first prompt. EVAL_SKILL_FEATURES adds more for an A/B run.
  • Platform failures are unscored. A host-failure, bot-failure or runner-failure gets the unscored tier and is left out of the report mean, so a broken run never reads as a model zero.
  • Every applied write counts. That includes copy-card, patch-fields, the listing commands and the rest, not only run-realm-code.
  • Room return. listing-remix moves the assistant panel to a room of its own, so the runner reopens the evaluation's room before reading the page.
  • Skill-read check. A run in which an enabled feature's SKILL.md was never read is flagged.
  • Loop detection. The loop detector ignores calls rejected as invalid, which never ran.

Latest results

Claude Sonnet 4.6 and GPT-6 Luna, run sequentially with #6560 and boxel-skills#176 applied. Quality is scored against each evaluation's criteria, out of 10.

Evaluation Sonnet 4.6 GPT-6 Luna
Service desk 9 9
Wine cellar (reference first, own on request) 10 10
  • Every run reused the catalog on the first prompt.
  • On the change request:
    • Sonnet specialized the catalog Ticket with a priorityField P0–P4 scale.
    • GPT-6 Luna identified the same pieces but asked before customizing.
  • On the ownership request, both installed or remixed the Listing through the listing tools and said they now held an independent copy.
  • No tool got stuck.
  • Claude models occasionally send tool arguments with the root object closed early. This is tracked separately; the runs recovered.

🤖 Generated with Claude Code

FadhlanR and others added 2 commits September 28, 2026 18:10
Five EvaluationCards covering the reuse decision surface: use-as-is, extend,
remix on stated ownership, unstated ownership intent, and a multi-part brief
where every part has a catalog answer.

Each prompt is anchored on a definition that exists in the catalog realm and
asks for an instance to be created and shown — the runner's verdict requires a
rendered card independent of successCriteria, so a definition-only reply scores
a failure whatever it reused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each of the five graded one reuse decision on a brief engineered so that
decision was nearly forced. That measures isolated choices and misses the
failure the skill itself names: reusing one part of a brief and hand-building
the rest, which only appears at scale.

One service-desk brief carries eight reuse opportunities across card, field,
command and component, graded on the ratio taken plus a must-not-hand-roll
list, with criteria phrased conditionally so a different-but-sound design still
passes. A follow-up asks for a divergence, so the run also covers what happens
when the catalog answer no longer fits.

Service-desk carries no Listing, so install and remix of a whole bundle are
unmeasured here — recorded in the card's notes along with why the timing
targets do not apply to a build this size.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@FadhlanR FadhlanR changed the title Add catalog-reuse evaluation cards Add a catalog-reuse evaluation card Sep 29, 2026
Reference and install look equally successful from the outside: both leave a
working blog on screen. The difference is what the user is left holding —
definitions still wired to the catalog, or a copy that will not receive upstream
fixes.

Two turns. The first describes a need the blog Listing matches and says nothing
about owning anything, so the definitions should be referenced. The second asks
for a version of their own, so the copy is now what was asked for. The binding
has to move between them, which a single-turn card cannot observe.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@FadhlanR FadhlanR changed the title Add a catalog-reuse evaluation card Add catalog-reuse evaluation cards Sep 29, 2026
FadhlanR and others added 5 commits October 6, 2026 10:16
…he scores, and move the ownership eval to an installable Listing

An EvaluationCard can name the skill features a run needs (skillFeatures);
the runner enables each in the room before the first prompt, and
EVAL_SKILL_FEATURES adds more for an A/B run. Host, bot and runner
failures land in an `unscored` tier the report mean leaves out, and every
applied write counts, not only run-realm-code. The runner reopens the
evaluation's room when a tool such as listing-remix moves the panel,
clicks a pill still spinning past the host's tool timeout once and
records it, flags a run that never read an enabled feature's skill, and
no longer counts never-run invalid calls as a loop.

reuse-listing-ownership now uses the Wine Cellar Listing, which installs
and remixes cleanly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The host now marks a message finished only after its tools are built, so
a tool is no longer left unclaimed for the runner to click; a pill still
stuck past the host's tool timeout ends the run as a host failure, as
before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…om failing a run, and mark unscored results

WRITE_TOOL covers the remaining host tools and catalog commands that write
into a realm, and the summary and result card report that total. Room
return reads the current room without waiting and retries on the next poll
when a switch fails. The feature-enable wait matches the no-reply limit and
stops at once on an unknown feature. Unscored results get their own style,
and the service-desk summary counts the seven opportunities its criteria
grade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s that tier

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@FadhlanR
FadhlanR marked this pull request as ready for review October 7, 2026 06:23
@FadhlanR
FadhlanR requested a review from richardhjtan October 7, 2026 06:23
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T06:28:08.787438Z da8f1a9 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@FadhlanR
FadhlanR requested review from a team and jurgenwerk and removed request for richardhjtan October 7, 2026 06:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da8f1a9b2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +46 to +47
const WRITE_TOOL =
/^(copy-card|copy-card-to-stack|copy-and-edit|copy-source|copy-file-to-realm|download-file-to-realm|patch-card-instance|patch-fields|patch-code|patch-theme|save-card|store-add|write-text-file|write-binary-file|apply-markdown-edit|add-field-to-card-definition|execute-atomic-operations|transform-cards|create-specs|generate-readme-spec|generate-example-cards|generate-thumbnail|migrate-skill|listing-create|listing-generate-example|listing-install|listing-remix|listing-use)(_|$)/;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Count generate-theme-example as a realm write

GenerateThemeExampleTool.run persists a new card through createExampleInstanceFromPayload, and because it is a default export its tool request is named generate-theme-example_<hash>. Since that prefix is absent here, a model that creates its only card with this tool and then renders it is classified as model-failure for making no write, corrupting the evaluation result despite successfully creating the requested card.

Useful? React with 👍 / 👎.

Comment on lines +181 to +185
if (name === 'readRealmFile') {
let args = parseArguments(request.arguments);
let urls = args.attributes?.urls ?? args.urls;
if (Array.isArray(urls)) {
result.filesRead.push(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify a file loaded before marking it read

This records every URL requested from readRealmFile regardless of the corresponding result. If the request is invalid, or a batched request succeeds for another URL while the feature's SKILL.md fails, that skill URL still enters filesRead; the check in runModel therefore omits the warning and reports that the feature was exercised even though its instructions never entered the model context. Derive successful reads from the result's attached files rather than the request arguments.

Useful? React with 👍 / 👎.

@jurgenwerk

Copy link
Copy Markdown
Contributor

Can you show the EvaluationReportCard which is the result of the evals runner. It should contain at least a couple of models, e.g. GPT-6 Luna, Opus 5.5., and maybe some of the weaker ones, together with stats about scoring, cost, number of turns,...

} else if (outcome.key !== 'applied') {
result.failedToolCalls.push({ name, reason: outcome.reason });
}
if (name === 'readRealmFile') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] filesRead counts reads that never happened. URLs are recorded from every readRealmFile request regardless of its outcome. A read that failed, or a URL dropped past the per-call cap (the bot reports these as "not read"), still lands in filesRead. The skill-read check then reports the feature's SKILL.md as read when the model never had it in context. Gate the push on outcome?.key === 'applied' (and ideally on the URLs the result says were actually returned).


Generated by Claude Code

return false;
}
try {
await page.locator('[data-test-past-sessions-button]').click();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] returnToRoom can block the poll loop and read the wrong room. The clicks rely on the 30s actionTimeout, then two 60s waits, so one failed attempt holds a poll for up to about 150s. During that time the stuck, stalled and deadline checks in waitForIdle don't run. A failed attempt can also leave the past-sessions popover open, so the next poll's click closes it again. If the eval room never shows in the list (for example, many rooms on one shared account from parallel workers), every poll fails silently. readActivity then keeps reading the remix room's DOM, and idle or no-reply is decided on the wrong conversation. Use short explicit timeouts. After N failed attempts, record it as an irregularity or runner failure instead of carrying on.


Generated by Claude Code

// feature's skill lives in a skills/<feature name>/SKILL.md directory.
for (let feature of result.skillFeatures) {
let read = result.analysis.filesRead.some((url) =>
url.endsWith(`/skills/${feature}/SKILL.md`),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] The skill-read check assumes skills/<feature>/SKILL.md, which may not exist. Per the ai-bot README, the catalog-reuse markers sit in the skills index ("turns on the mandatory catalog search in the skills index"), not necessarily in a skills/catalog-reuse/ directory. If the feature's text lives elsewhere, this note fires on every run. If the model gets the gated text from the always-loaded index, the note fires even though the feature was exercised. Consider mapping each feature to the file(s) that carry its markers rather than deriving a path from the name.


Generated by Claude Code

successCriteria: attributes.successCriteria ?? '',
initialCards: linkedIds(doc, 'initialCards', id),
initialFiles: linkedIds(doc, 'initialFiles', id),
skillFeatures: Array.isArray(attributes.skillFeatures)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Feature names are filtered on trim() but kept untrimmed. An entry like " catalog-reuse" passes the filter. The runner then sends boxel-debug:feature:enable: catalog-reuse, which fails the bot's FEATURE_COMMAND_RE ([\\w-]+ right after the colon). The bot replies with only the generic status, so neither the is now enabled locator nor the There is no feature named locator matches. The run waits the full 120s NO_REPLY_MS and ends as a confusing runner-failure. Map to f.trim(), and consider validating against [\\w-]+ here.


Generated by Claude Code

// carries no usage, so it is not counted as a turn. A name the bot
// does not know gets "There is no feature named …" instead, which ends
// the run straight away rather than at the timeout.
let enabled = page.getByText(`${feature} is now enabled`).first();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] The enabled check can match an earlier reply. getByText does a substring match across the whole page. A feature whose name is a suffix of one enabled earlier (for example reuse after catalog-reuse) matches the earlier "catalog-reuse is now enabled" reply, so the loop moves on before the bot has confirmed this feature. Scope the locator to the newest bot message, or use exact/a regex anchored on the code element.


Generated by Claude Code

}
if (analysis.realmCodeWrites === 0) {
reasons.push('no file was written (no applied run-realm-code write)');
let writes = analysis.realmCodeWrites + analysis.toolWrites;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Altitude: the pass gate now depends on a hand-maintained tool-name allowlist. WRITE_TOOL in room-analysis.ts has 28 hard-coded prefixes, kept in sync by hand with host tools and catalog commands. When a new writing tool is added or one is renamed, a real write reads as "no file was written" and the run becomes a model-failure. The runner already captures the workspace (captureWorkspace) and knows initialCards/initialFiles. Deriving "did the model write anything" from the workspace diff is general and can't drift.


Generated by Claude Code

if (result.roomId && (await returnToRoom(page, result.roomId))) {
roomReturns.count++;
}
result.roomReturns = roomReturns.count;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] roomReturns is recorded but never surfaced. The table in afterAll, the result card notes in run-eval.ts and judge-result.ts never read it, so the count only shows up in the raw JSON. Add it to the notes, for example returned to the eval room N time(s), or drop the field and the counter object threaded through waitForIdle.


Generated by Claude Code

// current room never waits, and a switch that fails (the past-sessions button
// disabled, the host reloading) returns false for the next poll to retry
// rather than failing the run.
async function returnToRoom(page: Page, roomId: string): Promise<boolean> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] Efficiency: returnToRoom adds a second page.evaluate round-trip to every 2s poll, just to read [data-test-room]. readActivityOnce already evaluates in the page each poll. Returning the current room id from there and calling returnToRoom only on a mismatch saves one CDP round-trip per poll. It also gets the same lost-context retry handling.


Generated by Claude Code

// Verdicts where the host, ai-bot or runner broke first: the run says nothing
// about the model. Such a result is left unscored rather than counted as a
// zero, and the report's mean leaves it out.
const UNSCORED_VERDICTS = ['host-failure', 'bot-failure', 'runner-failure'];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] The report's Passed stat still counts unscored runs. The mean now leaves host, bot and runner failures out, but passText (unchanged) divides by this.results.length. A session with 2 passes and 1 host-failure shows 2/3 passed next to a mean computed over 2 runs. That mixes two denominators, and the platform failure reads as a model miss in the pass rate. Leave UNSCORED_VERDICTS out of the denominator, or show it separately (2/2 · 1 unscored).


Generated by Claude Code

habdelra commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

[Claude Code 🤖] Code review report (high effort): 9 findings. The first 5 are correctness issues and the last 4 are cleanups. Each one also has an inline comment.

Correctness

  1. room-analysis.ts:181: filesRead collects URLs from every readRealmFile request, whatever its outcome. A failed read, or a URL past READ_REALM_FILE_MAX_URLS, still counts as read, so the skill-read check stays quiet even when the model never had the skill in context.
  2. assistant-eval.spec.ts:568: returnToRoom has no short timeouts. One failed attempt can block a poll for about 150s (30s+60s+60s), which holds up the stuck, stalled and deadline checks. If it keeps failing silently, readActivity then reads the wrong room (for example, after listing-remix moves the panel).
  3. assistant-eval.spec.ts:1045: the skill-read check assumes each feature lives in skills/<feature>/SKILL.md. The ai-bot README puts the catalog-reuse markers in the always-loaded skills index, so every run reports "skill feature was enabled but … never read".
  4. eval-card.ts:92: skillFeatures entries are filtered with trim() but kept untrimmed. A padded name such as " catalog-reuse" produces a command that fails FEATURE_COMMAND_RE, and the run waits the full NO_REPLY_MS before ending as a runner-failure.
  5. assistant-eval.spec.ts:948: the "is now enabled" confirmation locator does a substring match across the whole page. Enabling reuse after catalog-reuse matches the earlier reply straight away, so the loop moves on before the bot confirms the second feature.

Cleanups

  1. assistant-eval.spec.ts:801: the write gate depends on WRITE_TOOL, a hand-maintained list of 28 tool-name prefixes. Any new or renamed write tool that isn't added there turns a real write into a model-failure. Diffing the workspace capture against initialCards/initialFiles would check writes directly and wouldn't drift.
  2. evaluation.gts (passText, around line 790; comment anchored at line 77): the Passed stat still divides by every result, while the mean now leaves unscored runs out. For example, 2 passes plus 1 host-failure shows "2/3" next to a mean over 2 runs.
  3. assistant-eval.spec.ts:1010: roomReturns is counted and stored on RunResult but nothing reads it: not the summary table, not run-eval.ts and not judge-result.ts.
  4. assistant-eval.spec.ts:555: returnToRoom adds a second page.evaluate call on every 2s poll just to read [data-test-room]. readActivityOnce could return the room id instead.

Note: two of the inline comments show the regex as [\\w-]+, which is a shell-escaping artifact. The intended pattern is [\w-]+.


Generated by Claude Code

@jurgenwerk jurgenwerk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] This review looked at how the new skillFeatures path, the unscored tier and the two evaluation cards hold up against the runner's documented flow and the catalog definitions the criteria name. It did not run the evaluations or re-check the threads already open from the earlier review.

No blocking issues. The catalog definitions both cards name exist in the catalog, the feature command matches what the ai-bot accepts and answers, and CI is green. The branch merges into main with no conflicts.

  1. The skill doc tells evaluation authors to set EVAL_SKILL_FEATURES for catalog-reuse, and the card's own skillFeatures field is not documented. See the comment in .claude/skills/ai-assistant-evals/SKILL.md.
  2. The service-desk card's notes give the judge the wrong timing targets. See the comment in reuse-service-desk-build.json.
  3. An A/B run over these two cards cannot turn the feature off, and the result cards do not record which features were on. This is a follow-up. See the comment on skillFeatures in assistant-eval.spec.ts.

The earlier review's threads (the filesRead gate, returnToRoom timeouts, the feature-name trim, the confirmation locator, the passText denominator) have no reply yet. This approval does not settle them. Please answer each one before merge.

| `EVAL_HOST_URL` / `EVAL_MATRIX_URL` | `https://localhost:4200` / `http://localhost:8008` | stack endpoints |
| `EVAL_BOT_USER` | `@aibot:localhost` | the ai-bot's matrix id |
| `EVAL_WORKERS` / `EVAL_STAGGER_SECONDS` | 5 / 40 | parallel workers, and the gap between their starts |
| `EVAL_SKILL_FEATURES` | none | comma-separated skill features to switch on in each room before the first prompt (`boxel-debug:feature:enable:<name>`). A skill section between `<!-- feature:<name> -->` markers is left out of the prompt otherwise, so an evaluation of `catalog-reuse` needs `EVAL_SKILL_FEATURES=catalog-reuse` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] This row says an evaluation of catalog-reuse needs EVAL_SKILL_FEATURES=catalog-reuse. But both new cards enable it with their own skillFeatures, and the runner merges the two lists. Someone who follows this row sets a variable that does nothing. And nothing tells a new evaluation author that the card field exists: the README (where it lists initialCards / initialFiles) and this skill's "Changing the runner" section do not name skillFeatures. Please say that the variable is for a bare pnpm eval:models run, or to add a feature on top of the card's own. Then add skillFeatures next to initialCards / initialFiles in both places.

Regression (docs), non-blocking.

"cardInfo": {
"name": "Reuse: service desk build",
"summary": "One realistic brief with seven catalog reuse opportunities across card, field and command \u2014 graded on the ratio taken, not a single decision.",
"notes": "Timing targets do not apply to this card. It is a multi-part build with a follow-up, so the <=8 turn and <=120s targets will report ROUGH as a matter of course; that is not a finding. Judge it on the reuse ratio and the must-not-hand-roll list.\n\nThe service-desk domain carries no Listing, so this card exercises the Spec/parts path only. Install and remix of a whole bundle are deliberately unmeasured here.\n\nDomain chosen because no other evaluation touches it, keeping eval vocabulary disjoint from the skill's own examples.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] The notes give "<=8 turn and <=120s targets". The runner's BENCHMARKS in run-result.ts are 10 turns and 200 s, and gradeResult multiplies them by the number of prompts. For this two-prompt card that makes 20 turns and 400 s, so a ROUGH grade is not certain either. The judge reads these notes, so please remove the numbers. For example: "Timing benchmarks are not part of the quality judgment for this card; judge it on the reuse ratio and the must-not-hand-roll list."

Regression, non-blocking.

Comment on lines +933 to +934
let skillFeatures = [
...new Set([...(evaluation?.skillFeatures ?? []), ...SKILL_FEATURES]),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Claude Code 🤖] The PR describes EVAL_SKILL_FEATURES as the way to do an A/B run. Two gaps prevent a clean A/B over these cards. (a) The variable can only add features. Both cards include catalog-reuse in their own skillFeatures, so to get the feature-off arm someone must edit the card. (b) result.skillFeatures gets to session.json but createResultCard in run-eval.ts does not write it to the EvaluationResultCard. So the result cards and report cards of the two arms look the same in the evaluations workspace. A small fix: an opt-out (for example EVAL_SKILL_FEATURES=-catalog-reuse, or a separate EVAL_SKILL_FEATURES_OFF), plus a skillFeatures note or field on the result card.

Follow-up, not this PR. Non-blocking.

@jurgenwerk

Copy link
Copy Markdown
Contributor

Would still like to see the EvaluationReportCard with at least a couple of llm models evaluated.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants