Skip to content

Commit f292a59

Browse files
committed
build(studio): sync sample agent configs with a script
The Studio copy of the example agent config has to match the plugin example it came from, and a test enforces that, but reproducing it was a manual cp nobody would remember the source path for. Add sync-sample-agents alongside fetch-styles, which follows the same pattern in this package: a tsx script that writes a generated file which stays committed, so dev, build, and test need no extra step. The source-to-target map is a list, so a second sample is a two-line change. The drift test now names the command to run when it fails. Signed-off-by: mschwab <mschwab@nvidia.com>
1 parent ddf44c7 commit f292a59

3 files changed

Lines changed: 45 additions & 2 deletions

File tree

web/packages/studio/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"update-warning-count": "pnpm tsx ../common/scripts/update-max-warnings.ts",
3737
"screenshots": "tsx screenshots/capture.ts",
3838
"feature-flags": "tsx scripts/feature-flag-matrix.ts",
39-
"fetch-styles": "tsx scripts/fetch-styles.ts"
39+
"fetch-styles": "tsx scripts/fetch-styles.ts",
40+
"sync-sample-agents": "tsx scripts/sync-sample-agents.ts"
4041
},
4142
"dependencies": {
4243
"@assistant-ui/react": "^0.12.28",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env node
2+
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
/* eslint-disable no-console -- CLI script */
6+
/**
7+
* Copies the agent configs behind Create Example Agent from the plugin examples
8+
* that own them into public/sample-agents/, so Studio serves the same bytes the
9+
* platform ships rather than an edited fork. Run after changing a source config;
10+
* src/constants/sampleAgents.test.ts fails when the two drift.
11+
*/
12+
import { copyFile, mkdir } from 'node:fs/promises';
13+
import { dirname, resolve } from 'node:path';
14+
import { fileURLToPath } from 'node:url';
15+
16+
const __dirname = dirname(fileURLToPath(import.meta.url));
17+
const STUDIO_ROOT = resolve(__dirname, '..');
18+
const REPO_ROOT = resolve(STUDIO_ROOT, '../../..');
19+
20+
/** source: repo-relative. target: studio-package-relative. */
21+
const SAMPLE_AGENT_CONFIGS = [
22+
{
23+
source: 'plugins/nemo-agents/examples/nemo-agent-config/email-phishing-agent/agent.yaml',
24+
target: 'public/sample-agents/email-phishing-agent/agent.yaml',
25+
},
26+
];
27+
28+
async function main() {
29+
for (const { source, target } of SAMPLE_AGENT_CONFIGS) {
30+
const from = resolve(REPO_ROOT, source);
31+
const to = resolve(STUDIO_ROOT, target);
32+
await mkdir(dirname(to), { recursive: true });
33+
await copyFile(from, to);
34+
console.log(`${source} -> ${target}`);
35+
}
36+
}
37+
38+
main().catch((error: unknown) => {
39+
console.error(error);
40+
process.exitCode = 1;
41+
});

web/packages/studio/src/constants/sampleAgents.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ describe('SAMPLE_AGENTS', () => {
2727
expect(config.models?.default).toBeDefined();
2828
});
2929

30-
it('the shipped asset stays identical to the plugin example it was copied from', () => {
30+
it('the shipped asset stays identical to the plugin example it is copied from', () => {
3131
const shipped = readFileSync(
3232
join(PUBLIC_DIR, 'sample-agents/email-phishing-agent/agent.yaml'),
3333
'utf8'
3434
);
3535
const source = readFileSync(join(PLUGIN_EXAMPLES, 'email-phishing-agent/agent.yaml'), 'utf8');
3636

37+
// Regenerate with `pnpm --filter nemo-studio-ui sync-sample-agents`.
3738
expect(shipped).toBe(source);
3839
});
3940

0 commit comments

Comments
 (0)