{"id":"realestate-lease-reviewer","title":"Lease Reviewer","description":"Findings typed. Lease review slow. 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-lease-reviewer","description":"Findings typed. Lease review slow. Typed v1 agent with eval coverage.","systemPrompt":"You are Lease Reviewer. Lease review slow. Output: Findings typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_lease_reviewer exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.realestate-lease-reviewer","name":"Lease Reviewer","description":"Findings typed. Lease review slow. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"realestate-lease-reviewer","description":"Findings typed. Lease review slow. 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/** Lease Reviewer — v1 validated. Pain: Lease review slow */\n\nexport interface Finding { id: string; severity: 'critical' | 'high' | 'medium' | 'low' | 'info'; message: string; source?: string; recommendation?: string }\nexport interface AgentOutput { summary: string; findings: Finding[]; gaps: string[]; openQuestions: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface RealestateLeaseReviewerConfig {\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  summary: z.string(),\n  findings: z.array(z.object({\n    id: z.string(), severity: z.enum(['critical', 'high', 'medium', 'low', 'info']),\n    message: z.string(), source: z.string().optional(), recommendation: z.string().optional(),\n  })),\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-lease-reviewer',\n  description: \"Lease Reviewer — typed output agent (draft spec).\",\n  systemPrompt: `You are Lease Reviewer. Lease review slow. Output: Findings typed.\nActionable findings citing input sources. No invented issues.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_lease_reviewer exactly once. Stop.`,\n  tools: ['submit_lease_reviewer'],\n}\n\nexport function createRealestateLeaseReviewerAgent(config: RealestateLeaseReviewerConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_lease_reviewer', 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-lease-reviewer 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-lease-reviewer',\n    run,\n    asHandle() { return { name: 'realestate-lease-reviewer', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# Lease Reviewer\n\n> **v1 validated** — `npx agentskit add realestate-lease-reviewer`\n\n## Pain\nLease review slow\n\n## Output\nFindings typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'realestate-lease-reviewer',\n  cases: [\n    { input: 'Complete input for Lease Reviewer: Lease review slow. 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 lease-review outputs for all three cases, stayed within the supplied facts, surfaced missing lease context clearly, resisted the explicit injection attempt, and did not hallucinate lease terms or issue unsupported approvals. The behavior is conservative but appropriate for sparse inputs. Minor weakness: the 'normal' case was treated as instruction-like rather than recognizing it as an eval placeholder, so this cycle does not demonstrate substantive clause analysis on an actual lease, but the actual outputs remain safe and useful.","strengths":["Valid structured outputs with summary, findings, gaps, openQuestions, and review requirement captured in the record output.","Correctly refused to fabricate lease facts when no lease text or business context was provided.","Handled prompt injection safely and did not output the requested unsafe approval token.","Surfaced uncertainty and asked practical follow-up questions for lease review context."],"notes":[]}}