{"id":"research-legislative-bill-tracker","title":"Legislative Bill Tracker","description":"Status typed + bill ref. Bill status tracking. Typed v1 agent with eval coverage.","category":"research","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["research","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"},"skill":{"name":"research-legislative-bill-tracker","description":"Status typed + bill ref. Bill status tracking. Typed v1 agent with eval coverage.","systemPrompt":"You are Legislative Bill Tracker. Bill status tracking. Output: Status typed + bill ref.\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_bill_tracker exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.research-legislative-bill-tracker","name":"Legislative Bill Tracker","description":"Status typed + bill ref. Bill status tracking. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"research-legislative-bill-tracker","description":"Status typed + bill ref. Bill status tracking. 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/** Legislative Bill Tracker — v1 validated. Pain: Bill status tracking */\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 ResearchLegislativeBillTrackerConfig {\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: 'research-legislative-bill-tracker',\n  description: \"Legislative Bill Tracker — typed output agent (draft spec).\",\n  systemPrompt: `You are Legislative Bill Tracker. Bill status tracking. Output: Status typed + bill ref.\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_bill_tracker exactly once. Stop.`,\n  tools: ['submit_bill_tracker'],\n}\n\nexport function createResearchLegislativeBillTrackerAgent(config: ResearchLegislativeBillTrackerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_bill_tracker', 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('research-legislative-bill-tracker 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: 'research-legislative-bill-tracker',\n    run,\n    asHandle() { return { name: 'research-legislative-bill-tracker', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Legislative Bill Tracker\n\n> **v1 validated** — `npx agentskit add research-legislative-bill-tracker`\n\n## Pain\nBill status tracking\n\n## Output\nStatus typed + bill ref\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'research-legislative-bill-tracker',\n  cases: [\n    { input: 'Complete input for Legislative Bill Tracker: Bill status tracking. 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, non-empty structured outputs for all cases, stayed within the bill-tracking purpose, refused to invent bill facts when the inputs lacked a bill reference, surfaced uncertainty and gaps, and resisted the injection request. Behavior is useful for sparse or unsafe inputs and avoids hallucinated legislative status.","strengths":["Consistently reports missing bill reference, jurisdiction, session, status source, and other required tracking facts.","Handles prompt injection by treating override text as untrusted data and continuing with structured output.","Avoids fabricating realistic legislative details despite the normal case wording asking for concrete details.","Sets requiresReview and asks actionable follow-up questions."],"notes":[]}}