diff --git a/.agentworkforce/agents/relay-feature-guardian/agent.test.ts b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts new file mode 100644 index 000000000..4269cc33c --- /dev/null +++ b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts @@ -0,0 +1,19 @@ +import { readFileSync } from 'node:fs'; +import { describe, expect, it } from 'vitest'; +import { resolveManifestPath } from './agent.ts'; + +const persona = JSON.parse(readFileSync(new URL('./persona.json', import.meta.url), 'utf8')) as { + inputs: { SLACK_CHANNEL: { default: string } }; +}; + +describe('relay-feature-guardian runtime paths', () => { + it('reads the manifest from the cloned relay repository', () => { + expect(resolveManifestPath('/home/daytona/workspace')).toBe( + '/home/daytona/workspace/github/repos/AgentWorkforce/relay/.agentworkforce/features/manifest.yaml' + ); + }); + + it('defaults delivery to the relay feature-check channel', () => { + expect(persona.inputs.SLACK_CHANNEL.default).toBe('C0AEKNLDNKW'); + }); +}); diff --git a/.agentworkforce/agents/relay-feature-guardian/agent.ts b/.agentworkforce/agents/relay-feature-guardian/agent.ts index 9e53b7a22..cfb9f893a 100644 --- a/.agentworkforce/agents/relay-feature-guardian/agent.ts +++ b/.agentworkforce/agents/relay-feature-guardian/agent.ts @@ -2,7 +2,7 @@ * relay-feature-guardian handler. * * Hourly cron tick: - * 1. Read the feature list from .agentworkforce/features/manifest.yaml + * 1. Read the feature list from the cloned relay repository * 2. Load feature progress from memory * 3. Pick the next unchecked feature (ordered by criticality then tier) * 4. Generate a concise quiz question via ctx.llm @@ -55,9 +55,20 @@ interface Feature { } const MANIFEST_RELPATH = '.agentworkforce/features/manifest.yaml'; +const RELAY_REPO_RELPATH = 'github/repos/AgentWorkforce/relay'; + +/** + * GitHub-scoped repositories are cloned beneath the proactive workspace root. + * WorkforceCtx currently exposes that workspace root (`sandbox.cwd`), but not + * an integration-specific repository directory, so derive the clone path from + * the documented `/github/repos/{owner}/{repo}` layout. + */ +export function resolveManifestPath(workspaceDir: string): string { + return `${workspaceDir}/${RELAY_REPO_RELPATH}/${MANIFEST_RELPATH}`; +} async function loadFeatures(ctx: WorkforceCtx): Promise { - const absPath = `${ctx.sandbox.cwd}/${MANIFEST_RELPATH}`; + const absPath = resolveManifestPath(ctx.sandbox.cwd); const raw = await ctx.sandbox.readFile(absPath); const manifest = parse(raw) as Manifest; const features: Feature[] = []; @@ -191,17 +202,21 @@ export default defineAgent({ try { features = await loadFeatures(ctx); } catch (err) { - const absPath = `${ctx.sandbox.cwd}/${MANIFEST_RELPATH}`; + const absPath = resolveManifestPath(ctx.sandbox.cwd); ctx.log('error', 'relay-feature-guardian.manifest-load-failed', { path: absPath, err: String(err) }); const isNotFound = String(err).includes('ENOENT'); const errMsg = isNotFound - ? `⚠️ *relay-feature-guardian* can't find the feature manifest at \`${MANIFEST_RELPATH}\`.\n\nThe \`feature/verify-features-workflow\` branch hasn't been merged to main yet — the sandbox runs on main, so the manifest doesn't exist. Merge PR #1283 to fix this.` + ? `⚠️ *relay-feature-guardian* can't find the feature manifest in the cloned relay repository at \`${RELAY_REPO_RELPATH}/${MANIFEST_RELPATH}\`.` : `⚠️ *relay-feature-guardian* failed to load the feature manifest: \`${String(err)}\``; await slackClient() .post(channel, errMsg) .catch(() => undefined); return; } + ctx.log('info', 'relay-feature-guardian.manifest-loaded', { + path: resolveManifestPath(ctx.sandbox.cwd), + features: features.length, + }); if (features.length === 0) { ctx.log('error', 'relay-feature-guardian.no-features', { reason: 'manifest parsed but empty' }); await slackClient() diff --git a/.agentworkforce/agents/relay-feature-guardian/persona.json b/.agentworkforce/agents/relay-feature-guardian/persona.json index 0bc45fbed..f5c4b1e8e 100644 --- a/.agentworkforce/agents/relay-feature-guardian/persona.json +++ b/.agentworkforce/agents/relay-feature-guardian/persona.json @@ -10,6 +10,11 @@ "timeoutSeconds": 300 }, "integrations": { + "github": { + "scope": { + "repo": "AgentWorkforce/relay" + } + }, "slack": { "scope": { "paths": "/slack/channels/**" @@ -20,7 +25,7 @@ "SLACK_CHANNEL": { "description": "Slack channel to post feature checks to (e.g. relay-health or general).", "env": "SLACK_CHANNEL", - "default": "C0BHWJSF309", + "default": "C0AEKNLDNKW", "picker": { "provider": "slack", "resource": "channels" diff --git a/vitest.config.ts b/vitest.config.ts index 9d39f6eef..271b84a07 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -62,6 +62,7 @@ export default defineConfig({ environment: 'node', setupFiles: [path.resolve(__dirname, './vitest.setup.ts')], include: [ + '.agentworkforce/agents/**/*.test.ts', 'tests/fixtures/**/*.test.ts', 'tests/integration/broker/evals/**/*.unit.test.ts', 'packages/**/src/**/*.test.ts',