API Reference

AI Actions

Empower your agent with custom, AI-powered actions that automate workflows and deliver smarter, context-aware responses.

Prerequisite

This page assumes you’ve already initiate your Agent Embedded | Overlay.

AI Actions Reference

Eucera agents can call out to your backend or third-party APIs via two action types:

  1. Execute-Only
    Runs an async task (GET/POST/PUT/DELETE/etc.) and returns the raw or parsed data back to the agent so it can craft a chat response.

  2. Execute + Render
    Runs an async task and then renders a custom UI component in the conversation, letting users interact with the results while still returning data back to the agent.


Execute-Only Action

When the agent invokes an execute-only action, it awaits your execute(params) function, takes whatever you return, and feeds it into its next chat message.

eucera("when", "ready", () => {
  eucera.agent({ /* …common setup… */ })
    .addActionHandlers({
      create_task: {
        execute: async (params) => {
					const {title, body} = params;
          const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
            method: 'POST',
            body: JSON.stringify({
              title,
              body,
              userId: 'playground',
            }),
            headers: {
              'Content-type': 'application/json; charset=UTF-8',
            },
          });
          const data = await response.json()

          // Return all relevant fields so the agent can reference them later
          return {
            id: data.id,
            title: data.title,
            body: data.body,
            userId: data.userId,
            // Include a link property—if the user asks "What's the link?", the agent can supply this
            link: `https://jsonplaceholder.typicode.com/posts/${data.id}`
          };
        }
      }
    });
});

Execute + Render Action

After your execute(params) resolves, you also implement render(data) to return a DOM node (or HTML string) that the agent will embed directly in the chat stream. Users can interact with that component, and you still return data back to the agent.

eucera("when", "ready", () => {
  eucera.agent({ /* …common setup… */ })
  .addActionHandlers({
    show_task: {
      // 1. Fetch the task by ID
      execute: async (params) => {
        const { taskId } = params;
        const response = await fetch(
          `https://jsonplaceholder.typicode.com/posts/${taskId}`
        );
        const data = await response.json();
        // Return the task object to both agent and renderer
        return data;
      },

      // 2. Tell the agent to wait for user input before continuing
      awaitUserInput: true,

      // 3. Render an editable card UI
      render: (task, host, header, callback, cancel) => {
        const style = document.createElement('style');
        style.textContent = `
          .task-card {
            border: 1px solid #e3e3e3;
            border-radius: 8px;
            margin-top: 8px;
            font-family: sans-serif;
            overflow: hidden;
          }
          .task-card-header {
            background-color: #f5f5f5;
            padding: 12px 16px;
            font-weight: bold;
          }
          .task-card-body {
            padding: 16px;
          }
          .task-card-body label {
            display: block;
            margin-bottom: 4px;
            font-size: 14px;
          }
          .task-card-body input,
          .task-card-body textarea {
            width: 100%;
            margin-bottom: 12px;
            padding: 8px;
            box-sizing: border-box;
            font-size: 14px;
          }
          .task-card-footer {
            padding: 12px 16px;
            text-align: right;
            background-color: #fafafa;
          }
          .task-card-footer button {
            margin-left: 8px;
            padding: 8px 16px;
            cursor: pointer;
          }
        `;
        header.appendChild(style);

        // 2. Build the card container
        const card = document.createElement('div');
        card.className = 'task-card';

        // Header section (title)
        const cardHeader = document.createElement('div');
        cardHeader.className = 'task-card-header';
        cardHeader.textContent = `Edit Task #${task.id}`;

        // Body section (form fields)
        const body = document.createElement('div');
        body.className = 'task-card-body';

        const titleLabel = document.createElement('label');
        titleLabel.textContent = 'Title:';
        const titleInput = document.createElement('input');
        titleInput.type = 'text';
        titleInput.value = task.title;

        const bodyLabel = document.createElement('label');
        bodyLabel.textContent = 'Body:';
        const bodyInput = document.createElement('textarea');
        bodyInput.rows = 4;
        bodyInput.value = task.body;

        body.append(titleLabel, titleInput, bodyLabel, bodyInput);

        // Footer section (buttons)
        const footer = document.createElement('div');
        footer.className = 'task-card-footer';

        const saveBtn = document.createElement('button');
        saveBtn.textContent = 'Save';
        saveBtn.onclick = () => {
          callback({
            id: task.id,
            title: titleInput.value,
            body: bodyInput.value,
          });
        };

        const cancelBtn = document.createElement('button');
        cancelBtn.textContent = 'Cancel';
        cancelBtn.onclick = cancel;

        footer.append(cancelBtn, saveBtn);

        // 3. Assemble and mount
        card.append(cardHeader, body, footer);
        host.appendChild(card);
      }
    }
  });
});

Tip: Make sure the object you return from execute or in the callbac() includes every piece of data the agent may need later (IDs, URLs, timestamps, etc.). The agent caches this data so that if a user follows up—“What’s the link to that new task?”—it can pull from the stored properties and respond correctly.


Configuration

PropertyTypeRequiredDescription
timeoutnumberNoMilliseconds to abort the execute call (default 5000).
execute(params: any) => Promise<any>YesHandler for your async task; must return a Promise with data.
render<see Render Options below>NoOptional UI: either a built-in component key or a custom render function to inject interactive UI.
awaitUserInputbooleanNoWhen true, the agent will pause and wait for user interaction before continuing.

Render Options

ParameterTypeDescription
dataanyThe value returned by your execute handler (e.g. an object or array of results).
hostHTMLElementThe container element where you should append your custom UI nodes (forms, cards, lists, etc.).
headerHTMLElementA header element you can style or populate with a title, instructions, or status messages.
callback(value: string, disableOnSubmit?: boolean) => voidCall this when the user submits. Pass the return value to the agent. By default, disableOnSubmit is true (the SDK auto-disable your UI after submit). Set it to false to not disable the UI component after submit.
cancel() => voidCall this if the user aborts, so the agent resumes without new data. A default “Cancel” control is also rendered in the chat UI.