{"id":"research-vendor-evaluation","title":"Vendor Evaluation","description":"Scorecard typed + evidence. Vendor selection subjective. 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-vendor-evaluation","description":"Scorecard typed + evidence. Vendor selection subjective. Typed v1 agent with eval coverage.","systemPrompt":"You are Vendor Evaluation. Vendor selection subjective. Output: Scorecard typed + evidence.\nScore 0-100 with explicit factors from input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_vendor_evaluation exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.research-vendor-evaluation","name":"Vendor Evaluation","description":"Scorecard typed + evidence. Vendor selection subjective. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"research-vendor-evaluation","description":"Scorecard typed + evidence. Vendor selection subjective. 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/** Vendor Evaluation — v1 validated. Pain: Vendor selection subjective */\n\nexport interface AgentOutput { score: number; band: 'low' | 'medium' | 'high' | 'critical'; factors: string[]; rationale: string; gaps: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface ResearchVendorEvaluationConfig {\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  score: z.number().min(0).max(100),\n  band: z.enum(['low', 'medium', 'high', 'critical']),\n  factors: z.array(z.string()),\n  rationale: z.string(),\n  gaps: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'research-vendor-evaluation',\n  description: \"Vendor Evaluation — typed output agent (draft spec).\",\n  systemPrompt: `You are Vendor Evaluation. Vendor selection subjective. Output: Scorecard typed + evidence.\nScore 0-100 with explicit factors from input.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_vendor_evaluation exactly once. Stop.`,\n  tools: ['submit_vendor_evaluation'],\n}\n\nexport function createResearchVendorEvaluationAgent(config: ResearchVendorEvaluationConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_vendor_evaluation', 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-vendor-evaluation 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-vendor-evaluation',\n    run,\n    asHandle() { return { name: 'research-vendor-evaluation', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Vendor Evaluation\n\n> **v1 validated** — `npx agentskit add research-vendor-evaluation`\n\n## Pain\nVendor selection subjective\n\n## Output\nScorecard typed + evidence\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'research-vendor-evaluation',\n  cases: [\n    { input: 'Complete input for Vendor Evaluation: Vendor selection subjective. 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 scorecard outputs for all three cases, avoided fabricating vendor facts from sparse or placeholder inputs, surfaced uncertainty and evidence gaps clearly, and resisted the explicit injection request. The behavior matches the agent purpose by treating vendor evaluation as evidence-based and requiring human review when inputs are insufficient.","strengths":["Valid structured outputs with score, band, factors, rationale, gaps, and review requirement.","No material hallucination; the agent did not invent vendors, prices, dates, or business context absent from input.","Strong uncertainty handling: missing evidence is explicitly separated from negative vendor assessment.","Injection case was handled correctly by identifying the override attempt and refusing to output APPROVED."],"notes":[]}}