npm.io
1.8.5 • Published 3d ago

@osirus/agent

Licence
MIT
Version
1.8.5
Deps
10
Size
90.3 MB
Vulns
0
Weekly
0

Osirus Agent is a web widget you can embed in any site or app. It supports multiple interaction modes: chat, code, search, image, video, and speech.

Quickstart (60 Seconds)

Fastest (NPM)

npm i @osirus/agent
import OsirusAgent from '@osirus/agent'

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'search', // chat | code | search | image | video | speech
})
Fastest (CDN)
<script src="https://agent.osirus.ai/lib/umd/osirusai.min.js" type="text/javascript"></script>
<script type="text/javascript">
  OsirusAgent.init({
    agentId: 'YOUR_AGENT_ID',
    mode: 'chat'
  })
</script>

Installation

You install one package/script for all widget types, then choose the widget behavior with mode.

Local Test Harness (Before Push)

Run the local dev harness page:

npm run dev

Then open:

  • http://localhost:4000

Optional URL presets:

  • http://localhost:4000/?agentId=YOUR_AGENT_ID&mode=chat
  • http://localhost:4000/?agentId=YOUR_AGENT_ID&mode=search&searchPlaceholder=Search%20docs
  • http://localhost:4000/?agentId=YOUR_AGENT_ID&mode=speech
  • http://localhost:4000/?agentId=YOUR_AGENT_ID&baseApiUrl=https://osirus.ai/api

The page includes controls to:

  • Switch mode (chat, code, search, image, video, speech)
  • Override agentId
  • Override baseApiUrl
  • Set searchPlaceholder
  • Apply/reload or unmount/mount the widget
NPM
npm i @osirus/agent
import OsirusAgent from '@osirus/agent'

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
})
CDN
<script src="https://agent.osirus.ai/lib/umd/osirusai.min.js" type="text/javascript"></script>
<script type="text/javascript">
  OsirusAgent.init({
    agentId: 'YOUR_AGENT_ID'
  })
</script>

Multi-Agent Init (One Call)

You can mount many agents at once by passing an array to init.

import OsirusAgent from '@osirus/agent'

OsirusAgent.init([
  { agentId: 'AGENT_CHAT_ID', mode: 'chat' },
  { agentId: 'AGENT_CODE_ID', mode: 'code' },
  { agentId: 'AGENT_IMAGE_ID', mode: 'image' },
])

instanceId is optional in array mode. If omitted, it is auto-generated from agentId/name.

Mount Into Tab/Div Containers

Use mountTo to render inside a specific host element (for CMS tab systems, side panels, modals, etc.).

<div id="tab-code"></div>
<div id="tab-media"></div>
OsirusAgent.init([
  {
    agentId: 'AGENT_CODE_ID',
    mode: 'code',
    mountTo: '#tab-code',
    placement: { position: 'absolute', top: '0', right: '0', left: '0', bottom: '0' },
  },
  {
    agentId: 'AGENT_IMAGE_ID',
    mode: 'image',
    mountTo: '#tab-media',
    placement: { position: 'absolute', top: '0', right: '0', left: '0', bottom: '0' },
  },
])

mountTo accepts either a CSS selector string or an HTMLElement.

Host Callbacks (onOutput, onClose)

Use callbacks to receive generated output in the host app and react when users close the widget.

import type { AgentOutputEvent, AgentCloseEvent } from '@osirus/agent'

OsirusAgent.init({
  agentId: 'AGENT_IMAGE_ID',
  mode: 'image',
  mountTo: '#tab-media',
  onOutput: (event: AgentOutputEvent) => {
    // event.type: 'code' | 'image' | 'video' | ...
    // event.output contains payload from the mode panel
    // Example image payload: { urls, primaryUrl, generationId, prompt, source }
    console.log('output', event)
  },
  onClose: (event: AgentCloseEvent) => {
    // Example: hide active tab or persist draft state
    console.log('closed', event.reason, event.instanceId)
  },
})

agentId is always included in onOutput/onClose payloads for app-backed widgets and should be used as the host-side auth token when handling callback actions.

Current mode outputs:

  • code: emits updated HTML after apply.
  • image: emits generated media URLs when create/status returns outputs.
  • video: emits generated media URLs when create/status returns outputs.

React Host Tab Example

import { useEffect } from 'react'
import OsirusAgent from '@osirus/agent'

export function CmsAiTabs() {
  useEffect(() => {
    OsirusAgent.init([
      {
        agentId: 'AGENT_CODE_ID',
        mode: 'code',
        mountTo: '#tab-code',
        onOutput: (event) => console.log('code output', event.output),
      },
      {
        agentId: 'AGENT_IMAGE_ID',
        mode: 'image',
        mountTo: '#tab-media-generate',
        onOutput: (event) => console.log('media output', event.output),
      },
    ])

    return () => {
      OsirusAgent.destroy()
    }
  }, [])

  return (
    <>
      <div id="tab-code" />
      <div id="tab-media-generate" />
    </>
  )
}

Lifecycle Methods

Use these methods when your host controls tab lifecycle explicitly.

// Update an existing mounted widget instance
OsirusAgent.update({
  instanceId: 'AGENT_CODE_ID',
  searchPlaceholder: 'Search CMS docs...',
})

// Destroy one instance
OsirusAgent.destroy('AGENT_CODE_ID')

// Destroy all instances
OsirusAgent.destroy()

Install Each Widget Type

Use mode in your init config to force widget behavior per embed.

If your agent already has a type configured in the app, you can omit mode. If both are present, mode in OsirusAgent.init(...) overrides the agent default.

Supported values:

  • chat
  • code
  • search
  • image
  • video
  • speech

Legacy alias:

  • voice is normalized to speech
1. Chat Widget
OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'chat',
})
2. Code Widget

code mode provides an HTML/code editor panel with prompt + attachment apply flow.

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'code',
})
3. Search Widget

search mode replaces the floating chat icon with a floating search bar launcher.

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'search',
  searchPlaceholder: 'Search docs, API, pricing...',
})
4. Image Widget

image mode includes a Generate tab with a canvas preview and prompt input.

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'image',
})
5. Video Widget

video mode includes a Generate tab with video-focused prompting and preview.

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'video',
})
6. Speech Widget

speech runs inside chat and supports a fullscreen speech view.

OsirusAgent.init({
  agentId: 'YOUR_AGENT_ID',
  mode: 'speech',
})

Local Configuration Example

Use local configuration when you are not loading agent settings by agentId.

OsirusAgent.init({
  name: 'OsirusAgent',
  mode: 'chat',
  searchPlaceholder: 'Search...',
  companyName: 'Osirus',
  companyIconUrl: 'https://agent.osirus.ai/images/Osirus-Icon.svg',
  customColor: '#006FE5',
  description: 'Embedded support and AI agent widget.',
  phoneNumber: '123-456-7890',
  email: 'info@osirus.ai',
  docUrl: 'https://osirus.ai/docs',
  apiDocUrl: 'https://osirus.ai/docs/api',
  support: {
    type: 'page',
    value: 'https://osirus.ai/support',
  },
  schedule: 'M - F, 8:30AM - 5:30PM EDT',
  address: {
    streetAddress: '123 Orange Ave',
    city: 'Orlando',
    state: 'FL',
    postalCode: '38235',
    country: 'USA',
  },
  showMap: true,
  googleMapApiKey: 'AIzaS...x2E_k',
  greeting: 'Hi, how can I help you today?',
  customOptions: [
    {
      icon: 'people',
      label: 'Careers',
      link: 'https://www.solodev.com/careers',
      openNewTab: true,
    },
  ],
})

React Export (@osirus/agent/react)

For React apps, you can import reusable UI components directly (in addition to OsirusAgentProvider).

import {
  CodeHtmlEditor,
  FieldAssistantBar,
  HTMLEditor,
  MediaGeneratePanel,
} from '@osirus/agent/react'
import { useRef, useState } from 'react'

export function Example() {
  const inputRef = useRef<HTMLInputElement | null>(null)
  const [visible, setVisible] = useState(true)

  return (
    <>
      <CodeHtmlEditor
        value="<p>Hello</p>"
        onApply={async ({ prompt, html }) => {
          // Call your API here and return updated HTML.
          return html
        }}
      />

      <HTMLEditor
        name="content"
        value="<p>Hello world</p>"
        onChange={(nextHtml) => console.log(nextHtml)}
        onApplyPrompt={async ({ prompt, html, files }) => {
          // Call your API and return updated html.
          return { html }
        }}
      />

      <div style={{ position: 'relative', marginTop: 24 }}>
        <input
          ref={inputRef}
          onFocus={() => setVisible(true)}
          placeholder="Edit this text with AI"
        />
        <FieldAssistantBar
          targetRef={inputRef}
          visible={visible}
          onAssist={async ({ mode, text, prompt }) => {
            // Call your API here and return updated text.
            return { text: mode === 'prompt' ? `${text} ${prompt || ''}` : text }
          }}
        />
      </div>

      <MediaGeneratePanel
        agentId="YOUR_IMAGE_AGENT_ID"
        prompt="cinematic sunset mountain"
        onPromptChange={(value) => console.log(value)}
        onGenerate={({ prompt, aspectRatio, agentId }) => {
          console.log('generate', prompt, aspectRatio, agentId)
        }}
        onAddToLibrary={({ url, agentId }) => {
          console.log('add-to-library', url, agentId)
        }}
        generatedUrls={['https://example.com/generated.png']}
      />
    </>
  )
}

MediaGeneratePanel callback payloads always include agentId so host systems can enforce agent-scoped authorization. For HTMLEditor and FieldAssistantBar, pass aiContext/context.agentId so callback requests include the same token.

Configuration Reference

App-Backed Config (agentId)
Property Type Required Description Example
agentId string Yes Agent ID created in the Osirus app. "abc123"
baseApiUrl string No API base URL override. "https://osirus.ai/api"
mode 'chat' | 'code' | 'search' | 'image' | 'video' | 'speech' No Overrides widget mode for this embed. "search"
searchPlaceholder string No Search input placeholder for search mode. "Search docs..."
instanceId string No Unique widget instance key used by update/destroy. "cms-code-tab"
mountTo string | HTMLElement No Mount target selector or element instead of default floating root. "#tab-code"
placement object No Inline placement style for widget overlay. { position: 'absolute', top: '0', left: '0' }
onOutput (event) => void No Receives generated outputs (code, image, video, etc.). (e) => console.log(e.output)
onClose (event) => void No Called when widget closes. (e) => console.log(e.reason)
Local Config
Property Type Required Description Example
name string Yes Agent display name. "OsirusAgent"
mode 'chat' | 'code' | 'search' | 'image' | 'video' | 'speech' No Widget mode. "speech"
searchPlaceholder string No Search input placeholder for search mode. "Search..."
instanceId string No Unique widget instance key used by update/destroy. "cms-local-widget"
mountTo string | HTMLElement No Mount target selector or element instead of default floating root. "#assistant-tab"
placement object No Inline placement style for widget overlay. { position: 'absolute', top: '0', left: '0' }
onOutput (event) => void No Receives generated outputs (code, image, video, etc.). (e) => console.log(e.output)
onClose (event) => void No Called when widget closes. (e) => console.log(e.reason)
companyName string No Replaces agent name in UI. "Osirus"
companyIconUrl string No Company logo URL shown in widget header. "https://agent.osirus.ai/images/Osirus-Icon.svg"
customColor string No Hex color for widget actions. "#006FE5"
description string No Company/agent description text. "Embedded support and AI agent widget."
phoneNumber string No Enables call button. "123-456-7890"
email string No Support email. "info@osirus.ai"
docUrl string No Enables docs panel button. "https://osirus.ai/docs"
apiDocUrl string No Enables API docs panel button. "https://osirus.ai/docs/api"
support { type: 'page' | 'email', value: string } No Support button behavior and target. { type: 'page', value: 'https://osirus.ai/support' }
schedule string No Operating hours. "M - F, 8:30AM - 5:30PM EDT"
address object No Business address object. { streetAddress, city, state, postalCode, country }
showMap boolean No Shows map preview (requires googleMapApiKey). true
googleMapApiKey string No Google Maps API key for map rendering. "AIzaS...x2E_k"
greeting string No Initial greeting and popup message text. "Hi, how can I help you today?"
customOptions Array<{ icon, label, link, openNewTab }> No Custom action buttons. [{ icon: 'telephone-plus', label: 'Sales', link: 'https://example.com', openNewTab: true }]
Callback Event Shapes

onOutput(event):

  • event.type: 'chat' | 'code' | 'image' | 'video' | 'speech' | 'search'
  • event.output: mode-specific payload (for example html for code, urls for image/video)
  • event.agentId, event.instanceId, event.mode, event.timestamp

onClose(event):

  • event.reason: close reason string (for example 'widget-close')
  • event.agentId, event.instanceId, event.mode, event.timestamp

Icon Notes

customOptions[].icon uses Bootstrap Icons names (without the bi- prefix). Example: "telephone-plus" renders bi bi-telephone-plus.

Keywords