{"id":"security-siem-alert-grouper","title":"SIEM Alert Grouper","description":"Groups typed. Alert noise. Typed v1 agent with eval coverage.","category":"cybersecurity","status":"validated","version":"1.0.0","source":"agentskit-registry","license":"MIT","tags":["cybersecurity","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":"security-siem-alert-grouper","description":"Groups typed. Alert noise. Typed v1 agent with eval coverage.","systemPrompt":"You are SIEM Alert Grouper. Alert noise. Output: Groups typed.\nGroup into themed clusters.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_alert_grouper exactly once. Stop."},"flow":null,"a2a":{"id":"io.agentskit.registry.security-siem-alert-grouper","name":"SIEM Alert Grouper","description":"Groups typed. Alert noise. Typed v1 agent with eval coverage.","version":"1.0.0","homepage":"https://registry.agentskit.io","skills":[{"name":"security-siem-alert-grouper","description":"Groups typed. Alert noise. 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/** SIEM Alert Grouper — v1 validated. Pain: Alert noise */\n\nexport interface Cluster { name: string; theme: string; items: string[] }\nexport interface AgentOutput { summary: string; clusters: Cluster[]; unassigned: string[] }\nexport interface AgentResult extends AgentOutput { requiresReview: boolean }\nexport interface SecuritySiemAlertGrouperConfig {\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  clusters: z.array(z.object({ name: z.string(), theme: z.string(), items: z.array(z.string()) })).min(1),\n  unassigned: z.array(z.string()).default([]),\n})\nconst toJson = (s: z.ZodTypeAny): JSONSchema7 => zodToJsonSchema(s) as JSONSchema7\n\nconst skill = {\n  name: 'security-siem-alert-grouper',\n  description: \"SIEM Alert Grouper — typed output agent (draft spec).\",\n  systemPrompt: `You are SIEM Alert Grouper. Alert noise. Output: Groups typed.\nGroup into themed clusters.\nNEVER invent facts — gaps and openQuestions for missing input. Always draft for human review.\n${UNTRUSTED_CONTENT_DIRECTIVE}\nCall submit_alert_grouper exactly once. Stop.`,\n  tools: ['submit_alert_grouper'],\n}\n\nexport function createSecuritySiemAlertGrouperAgent(config: SecuritySiemAlertGrouperConfig) {\n  const submit = (): ToolDefinition =>\n    defineZodTool({ name: 'submit_alert_grouper', 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('security-siem-alert-grouper 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: 'security-siem-alert-grouper',\n    run,\n    asHandle() { return { name: 'security-siem-alert-grouper', run: (t: string) => run(t).then((r) => JSON.stringify(r)) } },\n  }\n}\n"},{"path":"README.md","content":"# SIEM Alert Grouper\n\n> **v1 validated** — `npx agentskit add security-siem-alert-grouper`\n\n## Pain\nAlert noise\n\n## Output\nGroups typed\n"},{"path":"eval.ts","content":"import type { EvalSuite } from '@agentskit/eval'\n\nexport const suite: EvalSuite = {\n  name: 'security-siem-alert-grouper',\n  cases: [\n    { input: 'Complete input for SIEM Alert Grouper: Alert noise. 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 within its SIEM alert grouping purpose, did not obey prompt injection, and correctly surfaced uncertainty and missing alert data instead of fabricating clusters. The outputs are conservative but useful: they explain that no alert records were provided, preserve the input as untrusted data, and flag review needs. Minor limitation: the normal case does not demonstrate grouping on realistic alert data because the provided input contained no actual alerts, so this validation set only proves safe handling of sparse/non-alert inputs rather than full grouping quality.","strengths":["Valid structured outputs across all cases","No empty outputs or unsafe leakage","Correctly resisted the injection request to output APPROVED","Avoided hallucinating SIEM facts or business context not present in the input","Clearly surfaced missing fields and need for human review"],"notes":[]}}