{"version":3,"file":"standing_instructions.mjs","names":[],"sources":["../../../src/batteries/tools/standing_instructions/index.ts"],"sourcesContent":["/**\n * Pre-constructed CRUD tools for model-visible standing instruction management.\n *\n * @module @nhtio/adk/batteries/tools/standing_instructions\n *\n * @remarks\n * Pre-constructed CRUD tools that expose the ADK's standing-instruction surface to the\n * model. Each tool delegates to the corresponding callback on the active\n * {@link @nhtio/adk!DispatchContext} (`standingInstructions` getter, `storeStandingInstruction`,\n * `deleteStandingInstruction`) — the persistence layer is whatever the consumer wired into\n * the runner.\n *\n * Standing instructions are stored as a {@link Set} of {@link @nhtio/adk!Tokenizable} values keyed by\n * identity, not by an `id` field — there is no separate \"update by id\" semantics. The tools\n * therefore expose only `list` / `add` / `remove`. To replace an existing instruction the\n * model should `remove` the old value and `add` the new one (the ADK's persistence layer\n * is free to interpret that pair as an update if appropriate).\n *\n * Output is JSON for every tool so consumers can parse the result without re-tokenising —\n * the artifact constructor is set to {@link @nhtio/adk!SpooledJsonArtifact}.\n *\n * Tools:\n * - {@link listStandingInstructionsTool} — read-only list of every standing instruction\n *   currently held by the context (after refreshing from the persistence layer).\n * - {@link addStandingInstructionTool} — add a new standing instruction.\n * - {@link removeStandingInstructionTool} — remove a standing instruction by its content\n *   (exact string match).\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\nimport { SpooledJsonArtifact, Tool } from '@nhtio/adk/common'\n\n/**\n * List every standing instruction currently held by the active execution context.\n *\n * @remarks\n * Calls `ctx.refreshStandingInstructions()` to ensure the local Set is in sync with the\n * persistence layer, then serialises the resulting strings to a JSON array. The list is\n * stringly-keyed; the same content string serves as the identifier for subsequent removes.\n */\nexport const listStandingInstructionsTool = new Tool({\n  name: 'list_standing_instructions',\n  description:\n    'List every standing instruction currently held by the agent. Returns a JSON array of strings. To replace an instruction, remove the old string and add a new one.',\n  inputSchema: validator.object({}),\n  artifactConstructor: () => SpooledJsonArtifact,\n  handler: async (_args, ctx) => {\n    try {\n      const refreshed = await ctx.refreshStandingInstructions()\n      const items = refreshed.map((v) => (typeof v === 'string' ? v : v.toString()))\n      return JSON.stringify(items, null, 2)\n    } catch (err) {\n      return `Error: ${isError(err) ? err.message : String(err)}`\n    }\n  },\n})\n\n/**\n * Add a new standing instruction to the active execution context.\n *\n * @remarks\n * Delegates to `ctx.storeStandingInstruction(content)`. Standing instructions are stored as\n * a `Set` — adding the same content twice is a no-op at the local level, though the\n * consumer's persistence callback may interpret it differently.\n */\nexport const addStandingInstructionTool = new Tool({\n  name: 'add_standing_instruction',\n  description:\n    'Add a new standing instruction. Returns the stored content. Adding an identical instruction that already exists is a no-op.',\n  inputSchema: validator.object({\n    content: validator\n      .string()\n      .required()\n      .description('The standing-instruction content as a plain string.'),\n  }),\n  artifactConstructor: () => SpooledJsonArtifact,\n  handler: async (args, ctx) => {\n    const { content } = args as { content: string }\n    try {\n      await ctx.storeStandingInstruction(content)\n      return JSON.stringify({ ok: true, content }, null, 2)\n    } catch (err) {\n      return `Error: ${isError(err) ? err.message : String(err)}`\n    }\n  },\n})\n\n/**\n * Remove an existing standing instruction by its content string.\n *\n * @remarks\n * Delegates to `ctx.deleteStandingInstruction(content)`. Idempotent — succeeds even when\n * no matching instruction is currently present.\n */\nexport const removeStandingInstructionTool = new Tool({\n  name: 'remove_standing_instruction',\n  description:\n    'Remove a standing instruction by its exact content string. Idempotent — succeeds even when no match is present.',\n  inputSchema: validator.object({\n    content: validator\n      .string()\n      .required()\n      .description('The exact content string of the instruction to remove.'),\n  }),\n  artifactConstructor: () => SpooledJsonArtifact,\n  handler: async (args, ctx) => {\n    const { content } = args as { content: string }\n    try {\n      await ctx.deleteStandingInstruction(content)\n      return JSON.stringify({ ok: true, content }, null, 2)\n    } catch (err) {\n      return `Error: ${isError(err) ? err.message : String(err)}`\n    }\n  },\n})\n\n/**\n * Convenience tuple of every standing-instruction tool. Spread into a {@link @nhtio/adk!ToolRegistry}\n * to register the entire category at once.\n */\nexport const standingInstructionTools = [\n  listStandingInstructionsTool,\n  addStandingInstructionTool,\n  removeStandingInstructionTool,\n] as const\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,IAAa,+BAA+B,IAAI,KAAK;CACnD,MAAM;CACN,aACE;CACF,aAAa,UAAU,OAAO,CAAC,CAAC;CAChC,2BAA2B;CAC3B,SAAS,OAAO,OAAO,QAAQ;EAC7B,IAAI;GAEF,MAAM,SAAQ,MADU,IAAI,4BAA4B,GAChC,KAAK,MAAO,OAAO,MAAM,WAAW,IAAI,EAAE,SAAS,CAAE;GAC7E,OAAO,KAAK,UAAU,OAAO,MAAM,CAAC;EACtC,SAAS,KAAK;GACZ,OAAO,UAAU,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;EAC1D;CACF;AACF,CAAC;;;;;;;;;AAUD,IAAa,6BAA6B,IAAI,KAAK;CACjD,MAAM;CACN,aACE;CACF,aAAa,UAAU,OAAO,EAC5B,SAAS,UACN,OAAO,EACP,SAAS,EACT,YAAY,qDAAqD,EACtE,CAAC;CACD,2BAA2B;CAC3B,SAAS,OAAO,MAAM,QAAQ;EAC5B,MAAM,EAAE,YAAY;EACpB,IAAI;GACF,MAAM,IAAI,yBAAyB,OAAO;GAC1C,OAAO,KAAK,UAAU;IAAE,IAAI;IAAM;GAAQ,GAAG,MAAM,CAAC;EACtD,SAAS,KAAK;GACZ,OAAO,UAAU,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;EAC1D;CACF;AACF,CAAC;;;;;;;;AASD,IAAa,gCAAgC,IAAI,KAAK;CACpD,MAAM;CACN,aACE;CACF,aAAa,UAAU,OAAO,EAC5B,SAAS,UACN,OAAO,EACP,SAAS,EACT,YAAY,wDAAwD,EACzE,CAAC;CACD,2BAA2B;CAC3B,SAAS,OAAO,MAAM,QAAQ;EAC5B,MAAM,EAAE,YAAY;EACpB,IAAI;GACF,MAAM,IAAI,0BAA0B,OAAO;GAC3C,OAAO,KAAK,UAAU;IAAE,IAAI;IAAM;GAAQ,GAAG,MAAM,CAAC;EACtD,SAAS,KAAK;GACZ,OAAO,UAAU,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG;EAC1D;CACF;AACF,CAAC;;;;;AAMD,IAAa,2BAA2B;CACtC;CACA;CACA;AACF"}