hammerSkills

Skills let you extend Intelligence Nodes with custom context or custom code that runs when the AI decides to use it.

circle-check

What is a Skill?

A Skill is a custom tool you can attach to an Intelligence Node. When the AI decides the Skill is relevant to the conversation, it "calls" the Skill and incorporates the result into its reply.

Skills come in two flavors:

  • Content Skills return a block of markdown to the AI — think of these as reference material the AI can pull in on demand.

  • Code Skills run a short piece of TypeScript that can call an external API, transform data, and return a structured result to the AI.

You add Skills to a Flow the same way you add built-in tools: open the Intelligence Node, type @ in the Instructions box, and pick your Skill from the list.

When to use a Skill

Use a Content Skill when the AI needs access to a body of information that is too long or too nuanced to put directly in the Intelligence Node instructions — for example, a position paper, a list of FAQs, or a set of talking points. Keeping this content in a Skill lets the AI pull it in only when needed, which keeps prompts focused and makes the content reusable across Flows.

Use a Code Skill when the AI needs to do something dynamic — look up data in an external service, find nearby events for a supporter, check a supporter's donation history, or any other operation that can't be answered from static text.

Creating a Skill

  1. Naviate to the Flows section of Daisychain and click the "Customize" link in the top-right. Then, click "Skills."

  2. Click "New Skill" and give it a name. The name becomes the Skill's tool name (for example, "Healthcare Talking Points" → skill_healthcare_talking_points).

  3. Write a description. The description is shown to the AI, so write it for the AI, not for humans. For example: "Returns the campaign's current talking points about healthcare policy."

  4. Fill in the content or code depending on the Skill type. A Skill can be content-only, code-only, or both — if both are present, the AI sees the code; the markdown content is available as documentation.

  5. Save. Then go to any Intelligence Node and add your Skill as a tool.

Content Skills

A Content Skill is just a markdown document. When the AI calls the Skill, the full content is returned as the tool result and the AI uses it to inform its reply.

circle-info

Example: "Talking Points About Healthcare"

Description: Returns the campaign's current talking points on healthcare policy. Use this when the supporter asks about the candidate's healthcare stance or raises healthcare concerns.

Content:

In the Intelligence Node instructions, reference the Skill by name so the AI knows when to use it:

"If the supporter asks about healthcare policy, use the @Healthcare Talking Points Skill to ground your reply."

That's it — no code, no schema, no configuration. Content Skills are the fastest way to make long-form context available to a Flow.

Code Skills

A Code Skill runs a single TypeScript function when the AI calls it. The function receives arguments (chosen by the AI based on an input schema you define), a context object with information about the current person and conversation, and any secrets you've configured.

The run function

Every Code Skill exports a run function:

The returned object is serialized to JSON and handed back to the AI as the tool result. Return any shape you like — just keep it JSON-serializable.

circle-info

Example: "Dictionary Lookup"

Description: Looks up the definition of a word using the free Dictionary API. Use this when the supporter asks what a word means or when defining a term would help the conversation.

Input Schema:

Code (skill.ts):

When the AI decides to call this Skill, it will pass an argument like {"word": "gerrymandering"}, your code fetches the definition, and the AI uses the returned object to compose its reply.

Input Schema — how the AI chooses arguments

The Input Schema is a JSON Schemaarrow-up-right document that describes the arguments your Skill accepts. The AI uses it to decide whether and how to call your Skill, so write it like you're teaching the AI a new API.

A minimal schema looks like this:

Tips for writing schemas that the AI uses well:

  • Describe every property. The AI reads the description field and uses it to figure out what value to pass.

  • Use enum for fixed choices. If an argument must be one of a known set of values, enum makes the AI pick from the list instead of guessing.

  • Mark truly required fields as required. Required fields make the AI ask follow-up questions if it doesn't have the information yet.

  • Keep it small. Skills with 1–3 well-described arguments work better than kitchen-sink schemas with ten optional knobs.

The properties you define here show up as the typed SkillArgs parameter in your code. The editor gives you TypeScript autocomplete based on the schema.

The context argument

The second argument to run is the SkillContext — a snapshot of who the AI is talking to. You don't have to use it, but it's there when you do.

All fields use snake_case to match how they come through the API. The editor autocompletes the full shape — you don't need to memorize it.

Common uses:

  • Personalize the result: context.person.first_name

  • Look up a custom field: context.person.custom_fields['supporter_priority']

  • Read the most recent message: context.conversation.messages.at(-1)?.body

  • Find the primary ZIP code: context.person.addresses.find(a => a.primary)?.postal_code

Environment variables — secrets and API keys

Never commit API keys or other secrets into Skill code. Instead, configure them in the Environment panel on the Skill edit screen.

  1. Open your Skill, click Environment in the sidebar.

  2. Click Add Variable, enter a name (uppercase with underscores — e.g. STRIPE_API_KEY), and paste the value.

  3. Click the checkmark to save. Values are encrypted at rest and never shown in the UI again.

Read them in your code through the third argument:

Environment variables are the only way secrets should reach a Skill — they're scoped to the Skill, encrypted, and rotated without code changes.

The Execution Environment

Code Skills run in an isolated Denoarrow-up-right 2.x runtime. If you've written JavaScript or TypeScript for the browser, most of what you know transfers: fetch, URL, Response, async/await, JSON, Math, Date, Intl, and the rest of the web-standard APIs are available.

A few things are deliberately not available:

  • Only fetch over https:// is allowed for network access. Plain http:// is blocked. Deno.connect, WebSocket, and the Node.js modules node:net, node:http, node:https, node:tls, node:dgram, and node:dns all throw if you try to use them. This prevents Skills from reaching internal infrastructure or bypassing the egress proxy.

  • No remote imports. You cannot import code from https://, npm:, or jsr: specifiers. Everything you need should be written inline in skill.ts.

  • No file system access, no subprocesses, no FFI.

  • 30-second timeout. A single Skill execution must complete within 30 seconds or it is killed.

  • 64KB stdout limit. The return value must serialize to under 64KB of JSON.

Logging

console.log, console.warn, console.error, console.debug, and console.info all work and are captured in the execution log. Log liberally — it's the easiest way to understand what the AI and your Skill are doing.

Structured logs are supported too. If you pass a single object with message and meta fields, the meta is stored separately so you can filter on it later:

Errors

If your function throws or the return value can't be serialized, the execution is recorded with status: error and the error message is shown in the Test/Debug panel and the Logs list. The AI is also told the Skill failed, so it can adjust its reply rather than hallucinating data.

Testing a Skill

The Test / Debug panel on the Skill edit screen lets you run your Skill against real arguments and real person context without having to trigger a full conversation:

  1. Pick a person from the selector (this fills in context.person).

  2. Enter arguments as JSON (e.g. {"word": "gerrymandering"}).

  3. Click Run.

The panel shows the returned value, console output, and how long the execution took. If the arguments don't match your input schema, you'll get a validation error before the Skill runs — the same validation the AI is subject to.

The Logs panel shows every execution of the Skill, including production runs inside Flows. Click an execution to see its input, output, and console output.

Frequently Asked Questions

chevron-rightCan one Skill combine content and code?hashtag

Yes. If a Skill has both code and markdown content, the code runs when the AI calls the Skill, and the markdown content is kept alongside as documentation. In practice, most Skills are one or the other.

chevron-rightCan a Skill write data back into Daisychain?hashtag

Not directly — Skills are read-only outbound today. To capture data onto a Person or tag them, use the built-in Collect Custom Field, Collect Email, or Collect Name tools. You can also write a Code Skill that calls the Daisychain API itself, using an API key stored as an environment variable. Let us know if you have a use case that needs write-back from a Skill.

chevron-rightCan I import an npm package or a library from deno.land?hashtag

No. Skills run in a locked-down environment with remote and npm imports disabled. Everything you need should fit in the single skill.ts file. If you find yourself wanting a big library, reach out — we'd rather understand the use case than watch you work around the sandbox.

chevron-rightCan a Skill call our internal API?hashtag

Only if the API is reachable on the public internet over HTTPS. The egress proxy blocks private IP ranges, so Skills cannot reach services that are only reachable from inside your VPC or corporate network.

chevron-rightHow do I share a Skill between accounts?hashtag

Each Skill has an Export button on the Settings panel that produces a .zip containing the Skill's markdown, code, and input schema. You can re-import that .zip in another account by clicking Import from the Skills list.

Last updated