@octavus/docs 0.0.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -0
- package/content/01-getting-started/01-introduction.md +3 -3
- package/content/01-getting-started/02-quickstart.md +40 -17
- package/content/02-server-sdk/01-overview.md +54 -11
- package/content/02-server-sdk/02-sessions.md +166 -15
- package/content/02-server-sdk/03-tools.md +21 -21
- package/content/02-server-sdk/04-streaming.md +50 -20
- package/content/02-server-sdk/05-cli.md +247 -0
- package/content/03-client-sdk/01-overview.md +65 -35
- package/content/03-client-sdk/02-messages.md +116 -8
- package/content/03-client-sdk/03-streaming.md +36 -17
- package/content/03-client-sdk/04-execution-blocks.md +8 -12
- package/content/03-client-sdk/05-socket-transport.md +161 -45
- package/content/03-client-sdk/06-http-transport.md +48 -24
- package/content/03-client-sdk/07-structured-output.md +412 -0
- package/content/03-client-sdk/08-file-uploads.md +473 -0
- package/content/03-client-sdk/09-error-handling.md +274 -0
- package/content/04-protocol/01-overview.md +24 -14
- package/content/04-protocol/02-input-resources.md +35 -35
- package/content/04-protocol/03-triggers.md +9 -11
- package/content/04-protocol/04-tools.md +63 -29
- package/content/04-protocol/05-skills.md +304 -0
- package/content/04-protocol/06-handlers.md +304 -0
- package/content/04-protocol/07-agent-config.md +334 -0
- package/content/04-protocol/{07-provider-options.md → 08-provider-options.md} +54 -35
- package/content/04-protocol/09-skills-advanced.md +439 -0
- package/content/04-protocol/10-types.md +719 -0
- package/content/05-api-reference/01-overview.md +20 -21
- package/content/05-api-reference/02-sessions.md +192 -37
- package/content/05-api-reference/03-agents.md +25 -37
- package/content/06-examples/01-overview.md +6 -4
- package/content/06-examples/02-nextjs-chat.md +28 -18
- package/content/06-examples/03-socket-chat.md +53 -30
- package/content/06-examples/_meta.md +0 -1
- package/dist/chunk-WJ2W3DUC.js +663 -0
- package/dist/chunk-WJ2W3DUC.js.map +1 -0
- package/dist/content.js +1 -1
- package/dist/docs.json +99 -36
- package/dist/index.js +1 -1
- package/dist/search-index.json +1 -1
- package/dist/search.js +1 -1
- package/dist/search.js.map +1 -1
- package/dist/sections.json +99 -36
- package/package.json +12 -2
- package/content/04-protocol/05-handlers.md +0 -251
- package/content/04-protocol/06-agent-config.md +0 -242
- package/dist/chunk-232K4EME.js +0 -439
- package/dist/chunk-232K4EME.js.map +0 -1
- package/dist/chunk-2JDZLMS3.js +0 -439
- package/dist/chunk-2JDZLMS3.js.map +0 -1
- package/dist/chunk-2YMRODFE.js +0 -421
- package/dist/chunk-2YMRODFE.js.map +0 -1
- package/dist/chunk-2ZBPX5QB.js +0 -421
- package/dist/chunk-2ZBPX5QB.js.map +0 -1
- package/dist/chunk-3PIIST4D.js +0 -421
- package/dist/chunk-3PIIST4D.js.map +0 -1
- package/dist/chunk-42JETGDO.js +0 -421
- package/dist/chunk-42JETGDO.js.map +0 -1
- package/dist/chunk-4WWUKU4V.js +0 -421
- package/dist/chunk-4WWUKU4V.js.map +0 -1
- package/dist/chunk-5M7DS4DF.js +0 -519
- package/dist/chunk-5M7DS4DF.js.map +0 -1
- package/dist/chunk-6JQ3OMGF.js +0 -421
- package/dist/chunk-6JQ3OMGF.js.map +0 -1
- package/dist/chunk-7AOWCJHW.js +0 -421
- package/dist/chunk-7AOWCJHW.js.map +0 -1
- package/dist/chunk-7AS4ST73.js +0 -421
- package/dist/chunk-7AS4ST73.js.map +0 -1
- package/dist/chunk-7F5WOCIL.js +0 -421
- package/dist/chunk-7F5WOCIL.js.map +0 -1
- package/dist/chunk-7FPUAWSX.js +0 -421
- package/dist/chunk-7FPUAWSX.js.map +0 -1
- package/dist/chunk-7KXF63FV.js +0 -537
- package/dist/chunk-7KXF63FV.js.map +0 -1
- package/dist/chunk-APASMJBS.js +0 -421
- package/dist/chunk-APASMJBS.js.map +0 -1
- package/dist/chunk-BCEV3WV2.js +0 -421
- package/dist/chunk-BCEV3WV2.js.map +0 -1
- package/dist/chunk-CHGY4G27.js +0 -421
- package/dist/chunk-CHGY4G27.js.map +0 -1
- package/dist/chunk-CI7JDWKU.js +0 -421
- package/dist/chunk-CI7JDWKU.js.map +0 -1
- package/dist/chunk-CVFWWRL7.js +0 -421
- package/dist/chunk-CVFWWRL7.js.map +0 -1
- package/dist/chunk-EPDM2NIJ.js +0 -421
- package/dist/chunk-EPDM2NIJ.js.map +0 -1
- package/dist/chunk-ESGSYVGK.js +0 -421
- package/dist/chunk-ESGSYVGK.js.map +0 -1
- package/dist/chunk-GDCTM2SV.js +0 -421
- package/dist/chunk-GDCTM2SV.js.map +0 -1
- package/dist/chunk-GJ6FMIPD.js +0 -421
- package/dist/chunk-GJ6FMIPD.js.map +0 -1
- package/dist/chunk-H6JGSSAJ.js +0 -519
- package/dist/chunk-H6JGSSAJ.js.map +0 -1
- package/dist/chunk-IKQHGGUZ.js +0 -421
- package/dist/chunk-IKQHGGUZ.js.map +0 -1
- package/dist/chunk-IUKE3XDN.js +0 -421
- package/dist/chunk-IUKE3XDN.js.map +0 -1
- package/dist/chunk-J26MLMLN.js +0 -421
- package/dist/chunk-J26MLMLN.js.map +0 -1
- package/dist/chunk-J7BMB3ZW.js +0 -421
- package/dist/chunk-J7BMB3ZW.js.map +0 -1
- package/dist/chunk-JCBQRD5N.js +0 -421
- package/dist/chunk-JCBQRD5N.js.map +0 -1
- package/dist/chunk-JOB6YWEF.js +0 -421
- package/dist/chunk-JOB6YWEF.js.map +0 -1
- package/dist/chunk-JZRABTHU.js +0 -519
- package/dist/chunk-JZRABTHU.js.map +0 -1
- package/dist/chunk-K3GFQUMC.js +0 -421
- package/dist/chunk-K3GFQUMC.js.map +0 -1
- package/dist/chunk-LWYMRXBF.js +0 -421
- package/dist/chunk-LWYMRXBF.js.map +0 -1
- package/dist/chunk-M2R2NDPR.js +0 -421
- package/dist/chunk-M2R2NDPR.js.map +0 -1
- package/dist/chunk-MA3P7WCA.js +0 -421
- package/dist/chunk-MA3P7WCA.js.map +0 -1
- package/dist/chunk-MDMRCS4W.mjs +0 -421
- package/dist/chunk-MDMRCS4W.mjs.map +0 -1
- package/dist/chunk-MJXTA2R6.js +0 -421
- package/dist/chunk-MJXTA2R6.js.map +0 -1
- package/dist/chunk-NFVJQNDP.js +0 -421
- package/dist/chunk-NFVJQNDP.js.map +0 -1
- package/dist/chunk-O5TLYMQP.js +0 -421
- package/dist/chunk-O5TLYMQP.js.map +0 -1
- package/dist/chunk-OECAPVSX.js +0 -439
- package/dist/chunk-OECAPVSX.js.map +0 -1
- package/dist/chunk-OL5QDJ42.js +0 -483
- package/dist/chunk-OL5QDJ42.js.map +0 -1
- package/dist/chunk-PMOVVTHO.js +0 -519
- package/dist/chunk-PMOVVTHO.js.map +0 -1
- package/dist/chunk-QCHDPR2D.js +0 -421
- package/dist/chunk-QCHDPR2D.js.map +0 -1
- package/dist/chunk-R5MTVABN.js +0 -439
- package/dist/chunk-R5MTVABN.js.map +0 -1
- package/dist/chunk-RJ4H4YVA.js +0 -519
- package/dist/chunk-RJ4H4YVA.js.map +0 -1
- package/dist/chunk-S5U4IWCR.js +0 -439
- package/dist/chunk-S5U4IWCR.js.map +0 -1
- package/dist/chunk-SCKIOGKI.js +0 -421
- package/dist/chunk-SCKIOGKI.js.map +0 -1
- package/dist/chunk-TGJSIJYP.js +0 -421
- package/dist/chunk-TGJSIJYP.js.map +0 -1
- package/dist/chunk-TQJG6EBM.js +0 -537
- package/dist/chunk-TQJG6EBM.js.map +0 -1
- package/dist/chunk-TQZRBMU7.js +0 -421
- package/dist/chunk-TQZRBMU7.js.map +0 -1
- package/dist/chunk-TRL4RSEO.js +0 -421
- package/dist/chunk-TRL4RSEO.js.map +0 -1
- package/dist/chunk-TWUMRHQ7.js +0 -421
- package/dist/chunk-TWUMRHQ7.js.map +0 -1
- package/dist/chunk-UCJE36LL.js +0 -519
- package/dist/chunk-UCJE36LL.js.map +0 -1
- package/dist/chunk-VCASA6KL.js +0 -421
- package/dist/chunk-VCASA6KL.js.map +0 -1
- package/dist/chunk-VWPQ6ORV.js +0 -421
- package/dist/chunk-VWPQ6ORV.js.map +0 -1
- package/dist/chunk-WPXKIHLT.js +0 -421
- package/dist/chunk-WPXKIHLT.js.map +0 -1
- package/dist/chunk-WUNFFJ32.js +0 -421
- package/dist/chunk-WUNFFJ32.js.map +0 -1
- package/dist/chunk-WW7TRC7S.js +0 -519
- package/dist/chunk-WW7TRC7S.js.map +0 -1
- package/dist/chunk-XVSMRXBJ.js +0 -421
- package/dist/chunk-XVSMRXBJ.js.map +0 -1
- package/dist/chunk-YPPXXV3I.js +0 -421
- package/dist/chunk-YPPXXV3I.js.map +0 -1
- package/dist/chunk-ZKZVV4OQ.js +0 -421
- package/dist/chunk-ZKZVV4OQ.js.map +0 -1
- package/dist/chunk-ZOFEX73I.js +0 -421
- package/dist/chunk-ZOFEX73I.js.map +0 -1
- package/dist/content.mjs +0 -17
- package/dist/content.mjs.map +0 -1
- package/dist/index.mjs +0 -11
- package/dist/index.mjs.map +0 -1
- package/dist/search.mjs +0 -30
- package/dist/search.mjs.map +0 -1
- package/dist/types-BltYGlWI.d.ts +0 -36
package/README.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# @octavus/docs
|
|
2
|
+
|
|
3
|
+
Documentation content package for Octavus SDKs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @octavus/docs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
This package provides the documentation content for Octavus SDKs as structured data with full-text search capabilities. It's designed for:
|
|
14
|
+
|
|
15
|
+
- Embedding documentation in your application
|
|
16
|
+
- Building custom documentation sites
|
|
17
|
+
- Providing AI-friendly documentation access
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Get Documentation Content
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { getDocBySlug, getDocSlugs, getDocSections } from '@octavus/docs';
|
|
25
|
+
|
|
26
|
+
// Get all sections with their docs
|
|
27
|
+
const sections = getDocSections();
|
|
28
|
+
// [{ slug: 'getting-started', title: 'Getting Started', docs: [...] }, ...]
|
|
29
|
+
|
|
30
|
+
// Get all doc slugs (for static generation)
|
|
31
|
+
const slugs = getDocSlugs();
|
|
32
|
+
// ['getting-started/introduction', 'getting-started/quickstart', ...]
|
|
33
|
+
|
|
34
|
+
// Get a specific doc by slug
|
|
35
|
+
const doc = getDocBySlug('getting-started/introduction');
|
|
36
|
+
// { slug, section, title, description, content, excerpt }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Full Content Access
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { getAllDocs, getDocsData } from '@octavus/docs/content';
|
|
43
|
+
|
|
44
|
+
// Get all docs as array
|
|
45
|
+
const docs = getAllDocs();
|
|
46
|
+
|
|
47
|
+
// Get all data (docs + sections)
|
|
48
|
+
const { docs, sections } = getDocsData();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Search
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { searchDocs } from '@octavus/docs/search';
|
|
55
|
+
|
|
56
|
+
// Search documentation
|
|
57
|
+
const results = searchDocs('streaming events', 10);
|
|
58
|
+
// [{ slug, title, section, excerpt, score }, ...]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Data Types
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
interface Doc {
|
|
65
|
+
slug: string; // 'getting-started/introduction'
|
|
66
|
+
section: string; // 'getting-started'
|
|
67
|
+
title: string; // 'Introduction'
|
|
68
|
+
description: string; // 'Learn about Octavus...'
|
|
69
|
+
content: string; // Full markdown content
|
|
70
|
+
excerpt: string; // First ~200 chars, plain text
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface DocSection {
|
|
74
|
+
slug: string;
|
|
75
|
+
title: string;
|
|
76
|
+
description: string;
|
|
77
|
+
order: number;
|
|
78
|
+
docs: Doc[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
interface SearchResult {
|
|
82
|
+
slug: string;
|
|
83
|
+
title: string;
|
|
84
|
+
section: string;
|
|
85
|
+
excerpt: string;
|
|
86
|
+
score: number;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Content Structure
|
|
91
|
+
|
|
92
|
+
Documentation is organized by section:
|
|
93
|
+
|
|
94
|
+
- **Getting Started** - Introduction and quickstart guides
|
|
95
|
+
- **Server SDK** - Server-side integration with `@octavus/server-sdk`
|
|
96
|
+
- **Client SDK** - Client-side integration with `@octavus/client-sdk`
|
|
97
|
+
- **Protocol** - Agent protocol definition language
|
|
98
|
+
- **API Reference** - REST API documentation
|
|
99
|
+
- **Examples** - Full application examples
|
|
100
|
+
|
|
101
|
+
## Use with Static Site Generators
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
// Next.js generateStaticParams example
|
|
105
|
+
export function generateStaticParams() {
|
|
106
|
+
return getDocSlugs().map((slug) => ({
|
|
107
|
+
slug: slug.split('/'),
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export default function DocPage({ params }) {
|
|
112
|
+
const doc = getDocBySlug(params.slug.join('/'));
|
|
113
|
+
if (!doc) notFound();
|
|
114
|
+
|
|
115
|
+
return <MarkdownRenderer content={doc.content} />;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Related Packages
|
|
120
|
+
|
|
121
|
+
- [`@octavus/server-sdk`](https://www.npmjs.com/package/@octavus/server-sdk) - Server-side SDK
|
|
122
|
+
- [`@octavus/client-sdk`](https://www.npmjs.com/package/@octavus/client-sdk) - Client-side SDK
|
|
123
|
+
- [`@octavus/react`](https://www.npmjs.com/package/@octavus/react) - React hooks
|
|
124
|
+
|
|
125
|
+
## License
|
|
126
|
+
|
|
127
|
+
MIT
|
|
@@ -20,6 +20,7 @@ Building and managing AI agents is complex. Developers face challenges with:
|
|
|
20
20
|
Octavus solves these problems by providing:
|
|
21
21
|
|
|
22
22
|
- A **protocol-based approach** to defining agent behavior
|
|
23
|
+
- **Agent Preview** for testing agents directly in the platform
|
|
23
24
|
- **Server and client SDKs** for easy integration
|
|
24
25
|
- **Built-in streaming** support for real-time responses
|
|
25
26
|
- **Tool execution** that runs on your servers with your data
|
|
@@ -73,12 +74,12 @@ sequenceDiagram
|
|
|
73
74
|
API->>LLM: 2. Execute protocol
|
|
74
75
|
LLM-->>API: Response
|
|
75
76
|
API-->>App: 3. Stream events
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
Note over App: Tool request received
|
|
78
79
|
API-->>App: 4. Tool request
|
|
79
80
|
Note over App: 5. Execute tool locally
|
|
80
81
|
App->>API: 6. Return results
|
|
81
|
-
|
|
82
|
+
|
|
82
83
|
API->>LLM: 7. Continue
|
|
83
84
|
LLM-->>API: Response
|
|
84
85
|
API-->>App: 8. Stream response
|
|
@@ -90,4 +91,3 @@ sequenceDiagram
|
|
|
90
91
|
- [Server SDK](/docs/server-sdk/overview) — Learn about backend integration
|
|
91
92
|
- [Client SDK](/docs/client-sdk/overview) — Build chat interfaces with React (or other frameworks)
|
|
92
93
|
- [Protocol Reference](/docs/protocol/overview) — Deep dive into agent protocols
|
|
93
|
-
|
|
@@ -13,6 +13,17 @@ This guide will walk you through integrating Octavus into your application in un
|
|
|
13
13
|
- An Octavus account with API key
|
|
14
14
|
- A Next.js application (or any Node.js backend)
|
|
15
15
|
|
|
16
|
+
## Test Your Agent First
|
|
17
|
+
|
|
18
|
+
Before integrating with SDKs, use **Agent Preview** to test your agent directly in the platform:
|
|
19
|
+
|
|
20
|
+
1. Open your agent in the platform at `octavus.ai/agents/[agentId]`
|
|
21
|
+
2. Click the **Preview** tab
|
|
22
|
+
3. Configure session inputs and tool mock responses
|
|
23
|
+
4. Start a conversation to test agent behavior
|
|
24
|
+
|
|
25
|
+
Agent Preview supports all trigger types, file attachments, tool mocking, and real-time streaming. This is the fastest way to iterate on your agent logic before writing any integration code.
|
|
26
|
+
|
|
16
27
|
## Installation
|
|
17
28
|
|
|
18
29
|
Install the Octavus SDKs in your project:
|
|
@@ -50,22 +61,41 @@ Create an API endpoint that creates sessions and returns the session ID:
|
|
|
50
61
|
import { NextResponse } from 'next/server';
|
|
51
62
|
import { octavus } from '@/lib/octavus';
|
|
52
63
|
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
// Agent ID - get from platform or CLI (see below)
|
|
65
|
+
const SUPPORT_AGENT_ID = process.env.OCTAVUS_SUPPORT_AGENT_ID!;
|
|
55
66
|
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
if (!agent) {
|
|
59
|
-
return NextResponse.json({ error: 'Agent not found' }, { status: 404 });
|
|
60
|
-
}
|
|
67
|
+
export async function POST(request: Request) {
|
|
68
|
+
const { input } = await request.json();
|
|
61
69
|
|
|
62
70
|
// Create a new session using the agent ID
|
|
63
|
-
const sessionId = await octavus.agentSessions.create(
|
|
71
|
+
const sessionId = await octavus.agentSessions.create(SUPPORT_AGENT_ID, input);
|
|
64
72
|
|
|
65
73
|
return NextResponse.json({ sessionId });
|
|
66
74
|
}
|
|
67
75
|
```
|
|
68
76
|
|
|
77
|
+
### Getting Your Agent ID
|
|
78
|
+
|
|
79
|
+
There are two ways to create and manage agents:
|
|
80
|
+
|
|
81
|
+
**Option 1: Platform UI (Recommended for getting started)**
|
|
82
|
+
|
|
83
|
+
1. Go to [octavus.ai](https://octavus.ai) and create an agent in the web editor
|
|
84
|
+
2. Copy the agent ID from the URL (e.g., `octavus.ai/agents/clxyz123abc456`)
|
|
85
|
+
3. Add it to your `.env.local`: `OCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456`
|
|
86
|
+
|
|
87
|
+
**Option 2: Local Development with CLI**
|
|
88
|
+
|
|
89
|
+
For version-controlled agent definitions, use the [Octavus CLI](/docs/server-sdk/cli):
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm install --save-dev @octavus/cli
|
|
93
|
+
octavus sync ./agents/support-chat
|
|
94
|
+
# Output: Agent ID: clxyz123abc456
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The CLI approach is better for teams and CI/CD pipelines where you want agent definitions in your repository.
|
|
98
|
+
|
|
69
99
|
### 3. Create a Trigger Endpoint
|
|
70
100
|
|
|
71
101
|
Create an endpoint that handles triggers and streams responses:
|
|
@@ -161,11 +191,7 @@ export function Chat({ sessionId }: ChatProps) {
|
|
|
161
191
|
setInputValue('');
|
|
162
192
|
|
|
163
193
|
// Add user message and trigger in one call
|
|
164
|
-
await send(
|
|
165
|
-
'user-message',
|
|
166
|
-
{ USER_MESSAGE: message },
|
|
167
|
-
{ userMessage: { content: message } },
|
|
168
|
-
);
|
|
194
|
+
await send('user-message', { USER_MESSAGE: message }, { userMessage: { content: message } });
|
|
169
195
|
};
|
|
170
196
|
|
|
171
197
|
return (
|
|
@@ -207,9 +233,7 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
207
233
|
return (
|
|
208
234
|
<div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>
|
|
209
235
|
<div
|
|
210
|
-
className={`p-3 rounded-lg max-w-md ${
|
|
211
|
-
isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'
|
|
212
|
-
}`}
|
|
236
|
+
className={`p-3 rounded-lg max-w-md ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'}`}
|
|
213
237
|
>
|
|
214
238
|
{message.parts.map((part, i) => {
|
|
215
239
|
if (part.type === 'text') {
|
|
@@ -246,7 +270,6 @@ export default function ChatPage() {
|
|
|
246
270
|
method: 'POST',
|
|
247
271
|
headers: { 'Content-Type': 'application/json' },
|
|
248
272
|
body: JSON.stringify({
|
|
249
|
-
agentSlug: 'support-chat',
|
|
250
273
|
input: {
|
|
251
274
|
COMPANY_NAME: 'Acme Corp',
|
|
252
275
|
PRODUCT_NAME: 'Widget Pro',
|
|
@@ -15,6 +15,12 @@ The `@octavus/server-sdk` package provides a Node.js SDK for integrating Octavus
|
|
|
15
15
|
npm install @octavus/server-sdk
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
For agent management (sync, validate), install the CLI as a dev dependency:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install --save-dev @octavus/cli
|
|
22
|
+
```
|
|
23
|
+
|
|
18
24
|
## Basic Usage
|
|
19
25
|
|
|
20
26
|
```typescript
|
|
@@ -28,13 +34,25 @@ const client = new OctavusClient({
|
|
|
28
34
|
|
|
29
35
|
## Key Features
|
|
30
36
|
|
|
37
|
+
### Agent Management
|
|
38
|
+
|
|
39
|
+
Agent definitions are managed via the CLI. See the [CLI documentation](/docs/server-sdk/cli) for details.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Sync agent from local files
|
|
43
|
+
octavus sync ./agents/support-chat
|
|
44
|
+
|
|
45
|
+
# Output: Created: support-chat
|
|
46
|
+
# Agent ID: clxyz123abc456
|
|
47
|
+
```
|
|
48
|
+
|
|
31
49
|
### Session Management
|
|
32
50
|
|
|
33
|
-
Create and manage agent sessions:
|
|
51
|
+
Create and manage agent sessions using the agent ID:
|
|
34
52
|
|
|
35
53
|
```typescript
|
|
36
|
-
// Create a new session
|
|
37
|
-
const sessionId = await client.agentSessions.create('
|
|
54
|
+
// Create a new session (use agent ID from CLI sync)
|
|
55
|
+
const sessionId = await client.agentSessions.create('clxyz123abc456', {
|
|
38
56
|
COMPANY_NAME: 'Acme Corp',
|
|
39
57
|
PRODUCT_NAME: 'Widget Pro',
|
|
40
58
|
});
|
|
@@ -84,13 +102,14 @@ The main entry point for interacting with Octavus.
|
|
|
84
102
|
|
|
85
103
|
```typescript
|
|
86
104
|
interface OctavusClientConfig {
|
|
87
|
-
baseUrl: string;
|
|
88
|
-
apiKey?: string;
|
|
105
|
+
baseUrl: string; // Octavus API URL
|
|
106
|
+
apiKey?: string; // Your API key
|
|
89
107
|
}
|
|
90
108
|
|
|
91
109
|
class OctavusClient {
|
|
92
110
|
readonly agents: AgentsApi;
|
|
93
111
|
readonly agentSessions: AgentSessionsApi;
|
|
112
|
+
readonly files: FilesApi;
|
|
94
113
|
|
|
95
114
|
constructor(config: OctavusClientConfig);
|
|
96
115
|
}
|
|
@@ -122,7 +141,7 @@ interface SessionState {
|
|
|
122
141
|
input: Record<string, unknown>;
|
|
123
142
|
variables: Record<string, unknown>;
|
|
124
143
|
resources: Record<string, unknown>;
|
|
125
|
-
messages: ChatMessage[];
|
|
144
|
+
messages: ChatMessage[]; // Internal message format
|
|
126
145
|
createdAt: string;
|
|
127
146
|
updatedAt: string;
|
|
128
147
|
}
|
|
@@ -131,7 +150,7 @@ interface SessionState {
|
|
|
131
150
|
interface UISessionState {
|
|
132
151
|
sessionId: string;
|
|
133
152
|
agentId: string;
|
|
134
|
-
messages: UIMessage[];
|
|
153
|
+
messages: UIMessage[]; // UI-ready messages for frontend
|
|
135
154
|
}
|
|
136
155
|
```
|
|
137
156
|
|
|
@@ -142,10 +161,7 @@ Handles triggering and streaming for a specific session.
|
|
|
142
161
|
```typescript
|
|
143
162
|
class AgentSession {
|
|
144
163
|
// Trigger an action and stream parsed events
|
|
145
|
-
trigger(
|
|
146
|
-
triggerName: string,
|
|
147
|
-
input?: Record<string, unknown>
|
|
148
|
-
): AsyncGenerator<StreamEvent>;
|
|
164
|
+
trigger(triggerName: string, input?: Record<string, unknown>): AsyncGenerator<StreamEvent>;
|
|
149
165
|
|
|
150
166
|
// Get the session ID
|
|
151
167
|
getSessionId(): string;
|
|
@@ -155,6 +171,33 @@ class AgentSession {
|
|
|
155
171
|
function toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array>;
|
|
156
172
|
```
|
|
157
173
|
|
|
174
|
+
### FilesApi
|
|
175
|
+
|
|
176
|
+
Handles file uploads for sessions.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
class FilesApi {
|
|
180
|
+
// Get presigned URLs for file uploads
|
|
181
|
+
async getUploadUrls(sessionId: string, files: FileUploadRequest[]): Promise<UploadUrlsResponse>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface FileUploadRequest {
|
|
185
|
+
filename: string;
|
|
186
|
+
mediaType: string;
|
|
187
|
+
size: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface UploadUrlsResponse {
|
|
191
|
+
files: {
|
|
192
|
+
id: string; // File ID for references
|
|
193
|
+
uploadUrl: string; // PUT to this URL
|
|
194
|
+
downloadUrl: string; // GET URL after upload
|
|
195
|
+
}[];
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The client uploads files directly to S3 using the presigned upload URL. See [File Uploads](/docs/client-sdk/file-uploads) for the full integration pattern.
|
|
200
|
+
|
|
158
201
|
## Next Steps
|
|
159
202
|
|
|
160
203
|
- [Sessions](/docs/server-sdk/sessions) — Deep dive into session management
|
|
@@ -39,7 +39,7 @@ const session = await client.agentSessions.getMessages(sessionId);
|
|
|
39
39
|
console.log({
|
|
40
40
|
sessionId: session.sessionId,
|
|
41
41
|
agentId: session.agentId,
|
|
42
|
-
messages: session.messages.length,
|
|
42
|
+
messages: session.messages.length, // UIMessage[] ready for frontend
|
|
43
43
|
});
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -51,7 +51,7 @@ The returned messages can be passed directly to the client SDK's `initialMessage
|
|
|
51
51
|
interface UISessionState {
|
|
52
52
|
sessionId: string;
|
|
53
53
|
agentId: string;
|
|
54
|
-
messages: UIMessage[];
|
|
54
|
+
messages: UIMessage[]; // UI-ready conversation history
|
|
55
55
|
}
|
|
56
56
|
```
|
|
57
57
|
|
|
@@ -65,7 +65,7 @@ const state = await client.agentSessions.get(sessionId);
|
|
|
65
65
|
console.log({
|
|
66
66
|
id: state.id,
|
|
67
67
|
agentId: state.agentId,
|
|
68
|
-
messages: state.messages.length,
|
|
68
|
+
messages: state.messages.length, // ChatMessage[] (internal format)
|
|
69
69
|
resources: state.resources,
|
|
70
70
|
variables: state.variables,
|
|
71
71
|
createdAt: state.createdAt,
|
|
@@ -108,6 +108,19 @@ return new Response(toSSEStream(events), {
|
|
|
108
108
|
});
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
### Stop Support
|
|
112
|
+
|
|
113
|
+
Pass an abort signal to allow clients to stop generation:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// In your API route handler
|
|
117
|
+
const events = session.trigger(triggerName, input, {
|
|
118
|
+
signal: request.signal, // Forward the client's abort signal
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
When the client aborts the request, the signal propagates through to the LLM provider, stopping generation immediately. Any partial content is preserved.
|
|
123
|
+
|
|
111
124
|
## Session Lifecycle
|
|
112
125
|
|
|
113
126
|
```mermaid
|
|
@@ -118,44 +131,182 @@ flowchart TD
|
|
|
118
131
|
C --> D[4. RETRIEVE]
|
|
119
132
|
D --> C
|
|
120
133
|
C --> E[5. EXPIRE]
|
|
134
|
+
E --> F{6. RESTORE?}
|
|
135
|
+
F -->|Yes| C
|
|
136
|
+
F -->|No| A
|
|
121
137
|
|
|
122
138
|
A -.- A1["`**client.agentSessions.create()**
|
|
123
139
|
Returns sessionId
|
|
124
140
|
Initializes state`"]
|
|
125
|
-
|
|
141
|
+
|
|
126
142
|
B -.- B1["`**client.agentSessions.attach()**
|
|
127
143
|
Configure tool handlers
|
|
128
144
|
Configure resource watchers`"]
|
|
129
|
-
|
|
145
|
+
|
|
130
146
|
C -.- C1["`**session.trigger()**
|
|
131
147
|
Execute handler
|
|
132
148
|
Stream events
|
|
133
149
|
Update state`"]
|
|
134
|
-
|
|
150
|
+
|
|
135
151
|
D -.- D1["`**client.agentSessions.getMessages()**
|
|
136
152
|
Get UI-ready messages
|
|
137
|
-
|
|
138
|
-
|
|
153
|
+
Check session status`"]
|
|
154
|
+
|
|
139
155
|
E -.- E1["`Sessions expire after
|
|
140
156
|
24 hours (configurable)`"]
|
|
157
|
+
|
|
158
|
+
F -.- F1["`**client.agentSessions.restore()**
|
|
159
|
+
Restore from stored messages
|
|
160
|
+
Or create new session`"]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Session Expiration
|
|
164
|
+
|
|
165
|
+
Sessions expire after a period of inactivity (default: 24 hours). When you call `getMessages()` or `get()`, the response includes a `status` field:
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
const result = await client.agentSessions.getMessages(sessionId);
|
|
169
|
+
|
|
170
|
+
if (result.status === 'expired') {
|
|
171
|
+
// Session has expired - restore or create new
|
|
172
|
+
console.log('Session expired:', result.sessionId);
|
|
173
|
+
} else {
|
|
174
|
+
// Session is active
|
|
175
|
+
console.log('Messages:', result.messages.length);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Response Types
|
|
180
|
+
|
|
181
|
+
| Status | Type | Description |
|
|
182
|
+
| --------- | --------------------- | ------------------------------------------------------------- |
|
|
183
|
+
| `active` | `UISessionState` | Session is active, includes `messages` array |
|
|
184
|
+
| `expired` | `ExpiredSessionState` | Session expired, includes `sessionId`, `agentId`, `createdAt` |
|
|
185
|
+
|
|
186
|
+
## Persisting Chat History
|
|
187
|
+
|
|
188
|
+
To enable session restoration, store the chat messages in your own database after each interaction:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// After each trigger completes, save messages
|
|
192
|
+
const result = await client.agentSessions.getMessages(sessionId);
|
|
193
|
+
|
|
194
|
+
if (result.status === 'active') {
|
|
195
|
+
// Store in your database
|
|
196
|
+
await db.chats.update({
|
|
197
|
+
where: { id: chatId },
|
|
198
|
+
data: {
|
|
199
|
+
sessionId: result.sessionId,
|
|
200
|
+
messages: result.messages, // Store UIMessage[] as JSON
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
141
204
|
```
|
|
142
205
|
|
|
206
|
+
> **Best Practice**: Store the full `UIMessage[]` array. This preserves all message parts (text, tool calls, files, etc.) needed for accurate restoration.
|
|
207
|
+
|
|
143
208
|
## Restoring Sessions
|
|
144
209
|
|
|
145
|
-
When a user returns to your app
|
|
210
|
+
When a user returns to your app:
|
|
146
211
|
|
|
147
212
|
```typescript
|
|
148
|
-
//
|
|
149
|
-
const
|
|
213
|
+
// 1. Load stored data from your database
|
|
214
|
+
const chat = await db.chats.findUnique({ where: { id: chatId } });
|
|
215
|
+
|
|
216
|
+
// 2. Check if session is still active
|
|
217
|
+
const result = await client.agentSessions.getMessages(chat.sessionId);
|
|
218
|
+
|
|
219
|
+
if (result.status === 'active') {
|
|
220
|
+
// Session is active - use it directly
|
|
221
|
+
return {
|
|
222
|
+
sessionId: result.sessionId,
|
|
223
|
+
messages: result.messages,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// 3. Session expired - restore from stored messages
|
|
228
|
+
if (chat.messages && chat.messages.length > 0) {
|
|
229
|
+
const restored = await client.agentSessions.restore(
|
|
230
|
+
chat.sessionId,
|
|
231
|
+
chat.messages,
|
|
232
|
+
{ COMPANY_NAME: 'Acme Corp' }, // Optional: same input as create()
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
if (restored.restored) {
|
|
236
|
+
// Session restored successfully
|
|
237
|
+
return {
|
|
238
|
+
sessionId: restored.sessionId,
|
|
239
|
+
messages: chat.messages,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 4. Cannot restore - create new session
|
|
245
|
+
const newSessionId = await client.agentSessions.create('support-chat', {
|
|
246
|
+
COMPANY_NAME: 'Acme Corp',
|
|
247
|
+
});
|
|
150
248
|
|
|
151
|
-
// Pass messages to frontend - they're already UI-ready
|
|
152
249
|
return {
|
|
153
|
-
sessionId:
|
|
154
|
-
messages:
|
|
250
|
+
sessionId: newSessionId,
|
|
251
|
+
messages: [],
|
|
155
252
|
};
|
|
156
253
|
```
|
|
157
254
|
|
|
158
|
-
|
|
255
|
+
### Restore Response
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
interface RestoreSessionResult {
|
|
259
|
+
sessionId: string;
|
|
260
|
+
restored: boolean; // true if restored, false if session was already active
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Complete Example
|
|
265
|
+
|
|
266
|
+
Here's a complete session management flow:
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { OctavusClient } from '@octavus/server-sdk';
|
|
270
|
+
|
|
271
|
+
const client = new OctavusClient({
|
|
272
|
+
baseUrl: process.env.OCTAVUS_API_URL!,
|
|
273
|
+
apiKey: process.env.OCTAVUS_API_KEY!,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
async function getOrCreateSession(chatId: string, agentId: string, input: Record<string, unknown>) {
|
|
277
|
+
// Load existing chat data
|
|
278
|
+
const chat = await db.chats.findUnique({ where: { id: chatId } });
|
|
279
|
+
|
|
280
|
+
if (chat?.sessionId) {
|
|
281
|
+
// Check session status
|
|
282
|
+
const result = await client.agentSessions.getMessages(chat.sessionId);
|
|
283
|
+
|
|
284
|
+
if (result.status === 'active') {
|
|
285
|
+
return { sessionId: result.sessionId, messages: result.messages };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Try to restore expired session
|
|
289
|
+
if (chat.messages?.length > 0) {
|
|
290
|
+
const restored = await client.agentSessions.restore(chat.sessionId, chat.messages, input);
|
|
291
|
+
if (restored.restored) {
|
|
292
|
+
return { sessionId: restored.sessionId, messages: chat.messages };
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Create new session
|
|
298
|
+
const sessionId = await client.agentSessions.create(agentId, input);
|
|
299
|
+
|
|
300
|
+
// Save to database
|
|
301
|
+
await db.chats.upsert({
|
|
302
|
+
where: { id: chatId },
|
|
303
|
+
create: { id: chatId, sessionId, messages: [] },
|
|
304
|
+
update: { sessionId, messages: [] },
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
return { sessionId, messages: [] };
|
|
308
|
+
}
|
|
309
|
+
```
|
|
159
310
|
|
|
160
311
|
## Error Handling
|
|
161
312
|
|