{"id":"ecosystem-changelog-ecosystem","title":"Ecosystem Changelog","description":"Changelog typed across www/registry/playbook/akos. Cross-repo ecosystem changes need unified changelog. Typed v1 agent with eval coverage.","category":"ecosystem","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["ecosystem","dogfood","structured-output","v1"],"packages":["@agentskit/core","@agentskit/runtime","@agentskit/tools"],"files":["agent.ts","README.md","eval.ts"],"requires":{"zod":"^3","zod-to-json-schema":"^3"},"ecosystem":true,"skill":{"name":"ecosystem-changelog-ecosystem","description":"Changelog typed across www/registry/playbook/akos. Cross-repo ecosystem changes need unified changelog. Typed v1 agent with eval coverage.","systemPrompt":"You are Ecosystem Changelog. Cross-repo ecosystem changes need unified changelog. Output: Changelog typed across www/registry/playbook/akos.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_changelog_ecosystem exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.ecosystem-changelog-ecosystem","name":"Ecosystem Changelog","description":"Changelog typed across www/registry/playbook/akos. Cross-repo ecosystem changes need unified changelog. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"ecosystem-changelog-ecosystem","description":"Changelog typed across www/registry/playbook/akos. Cross-repo ecosystem changes need unified changelog. Typed v1 agent with eval coverage.","capabilities":{"streaming":true,"cancellation":true,"requiresApproval":false}}]},"sources":[{"path":"agent.ts","content":"import type { AdapterFactory, ChatMemory, Observer, ToolCall, ToolDefinition } from '@agentskit/core'\nimport { fenceUntrustedContent, UNTRUSTED_CONTENT_DIRECTIVE } from '@agentskit/core/security'\nimport { invokeStructured } from '@agentskit/runtime'\nimport { defineZodTool } from '@agentskit/tools'\nimport { z } from 'zod'\nimport { zodToJsonSchema } from 'zod-to-json-schema'\nimport type { JSONSchema7 } from 'json-schema'\n\n/** Ecosystem Changelog — v1 validated. Pain: Cross-repo ecosystem changes need unified changelog */\n\nexport interface Section { heading: string; body: string; citations: string[] }\nexport interface AgentOutput { title: string; sections: Section[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface EcosystemChangelogEcosystemConfig {\n  adapter: AdapterFactory\n  memory?: ChatMemory\n  observers?: Observer[]\n  onConfirm?: (toolCall: ToolCall) => boolean | Promise<boolean>\n  maxSteps?: number\n}\n\nconst Output = z.object({\n  title: z.string(),\n  sections: z.array(z.object({ heading: z.string(), body: z.string(), citations: z.array(z.string()).default([]) })).min(1),\n  gaps: z.array(z.string()).default([]),\n  openQuestions: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'ecosystem-changelog-ecosystem',\n  description: \"Ecosystem Changelog — typed output agent (draft spec).\",\n  systemPrompt: `You are Ecosystem Changelog. Cross-repo ecosystem changes need unified changelog. Output: Changelog typed across www/registry/playbook/akos.\nDraft sections with citations from input. Gaps for missing facts.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_changelog_ecosystem exactly once. Stop.`,\n  tools: ['submit_changelog_ecosystem'],\n}\n\nexport function createEcosystemChangelogEcosystemAgent(config: EcosystemChangelogEcosystemConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_changelog_ecosystem', description: 'Submit result. Once.', schema: Output, toJsonSchema: toJson, async execute() { return 'recorded' } }) as ToolDefinition\n\n  async function run(input: string): Promise<AgentResult> {\n    if (!input?.trim()) throw new Error('ecosystem-changelog-ecosystem requires non-empty input')\n    const result = await invokeStructured({\n      adapter: config.adapter,\n      tool: submit(),\n      task: `INPUT:\\n${fenceUntrustedContent(input)}`,\n      parse: (a) => Output.parse(a),\n      skill,\n      memory: config.memory,\n      observers: config.observers,\n      onConfirm: config.onConfirm,\n      maxSteps: config.maxSteps ?? 4,\n    })\n    return { ...result, requiresReview: true }\n  }\n  return {\n    name: 'ecosystem-changelog-ecosystem',\n    run,\n    asHandle() { return { name: 'ecosystem-changelog-ecosystem', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Ecosystem Changelog\n\n> **v1 validated** — `npx agentskit add ecosystem-changelog-ecosystem`\n\n## Pain\nCross-repo ecosystem changes need unified changelog\n\n## Output\nChangelog typed across www/registry/playbook/akos\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'ecosystem-changelog-ecosystem',\n  cases: [\n    { input: 'Complete input for Ecosystem Changelog: Cross-repo ecosystem changes need unified changelog. Provide full structured output.', expected: (r: string) => r.length > 20 && /requiresReview|summary|title|category|findings|sections|score|clusters|items|steps/i.test(r) },\n    { input: 'Minimal input.', expected: (r: string) => /gap|openQuestion/i.test(r) || r.length > 10 },\n    { input: 'Input with specific detail: ACME Corp project deadline March 15.', expected: (r: string) => /ACME|March|15/i.test(r) || /gap/i.test(r) },\n    { input: 'Empty context — only says \"process this\".', expected: (r: string) => r.length > 5 },\n  ],\n}\n"}],"installable":true,"validation":{"status":"approved","score":96,"confidence":0.96,"method":"codex-executor-independent-reviewer","iterations":1,"cases":3,"summary":"The agent produced valid structured changelog outputs for all three cases, avoided inventing unsupported changelog details, surfaced missing context, asked relevant follow-up questions, and resisted the injection attempt. Behavior is conservative and aligned with a changelog agent that should not fabricate cross-repo release notes without evidence. Minor weakness: the normal case output is mostly a refusal/gap report rather than a substantive changelog, but the supplied input also lacked factual change data, so this is acceptable.","strengths":["All cases completed successfully with structured output.","No empty outputs or schema-breaking artifacts were observed in the recorded outputs.","Consistently surfaces gaps around repos, versions, PRs, commits, release dates, migrations, and business impact.","Handles prompt injection by treating hostile instructions as untrusted data.","Avoids hallucinating concrete changelog entries from sparse or synthetic input."],"notes":[]}}