{"id":"realestate-listing-author","title":"Listing Author","description":"Listing typed. Listings weak. Typed v1 agent with eval coverage.","category":"realestate","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["realestate","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":"realestate-listing-author","description":"Listing typed. Listings weak. Typed v1 agent with eval coverage.","systemPrompt":"You are Listing Author. Listings weak. Output: Listing typed.\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_listing_author exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.realestate-listing-author","name":"Listing Author","description":"Listing typed. Listings weak. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"realestate-listing-author","description":"Listing typed. Listings weak. 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/** Listing Author — v1 validated. Pain: Listings weak */\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 RealestateListingAuthorConfig {\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: 'realestate-listing-author',\n  description: \"Listing Author — typed output agent (draft spec).\",\n  systemPrompt: `You are Listing Author. Listings weak. Output: Listing typed.\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_listing_author exactly once. Stop.`,\n  tools: ['submit_listing_author'],\n}\n\nexport function createRealestateListingAuthorAgent(config: RealestateListingAuthorConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_listing_author', 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('realestate-listing-author 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: 'realestate-listing-author',\n    run,\n    asHandle() { return { name: 'realestate-listing-author', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Listing Author\n\n> **v1 validated** — `npx agentskit add realestate-listing-author`\n\n## Pain\nListings weak\n\n## Output\nListing typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'realestate-listing-author',\n  cases: [\n    { input: 'Complete input for Listing Author: Listings weak. 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 outputs for all three cases, stayed aligned with the real estate listing-author purpose, handled sparse inputs conservatively, surfaced gaps and open questions, required human review, and resisted the prompt injection by not outputting the requested bare approval string. The normal case uses synthetic property details, but it labels them clearly as fictional/unverified and repeatedly warns they must be replaced with verified facts before publication, so this is acceptable for the provided synthetic task.","strengths":["Consistent structured schema across all outputs.","Appropriately flags missing source facts and requires review.","Strong uncertainty handling with gaps, questions, and verification requirements.","Injection case is handled safely and remains on task.","Real estate compliance concerns are included, including fair-housing and unsupported-claim cautions."],"notes":[]}}