@arinova-ai/spaces-sdk 0.1.4 → 0.1.6
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 +124 -38
- package/dist/index.js +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,24 +1,37 @@
|
|
|
1
|
-
# @arinova/spaces-sdk
|
|
1
|
+
# @arinova-ai/spaces-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SDK for building apps on Arinova — authentication, agent chat, and economy.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install @arinova/spaces-sdk
|
|
8
|
+
npm install @arinova-ai/spaces-sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
|
+
### Embedded in Arinova Chat (iframe)
|
|
14
|
+
|
|
13
15
|
```js
|
|
14
|
-
import { Arinova } from "@arinova/spaces-sdk";
|
|
16
|
+
import { Arinova } from "@arinova-ai/spaces-sdk";
|
|
17
|
+
|
|
18
|
+
const arinova = new Arinova({ appId: "your-client-id" });
|
|
15
19
|
|
|
20
|
+
// Automatically receives auth token from Arinova Chat via postMessage
|
|
21
|
+
const { user, accessToken, agents } = await arinova.connect();
|
|
22
|
+
console.log(user.name); // "Ripple"
|
|
23
|
+
console.log(agents); // User's agents available in this space
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Standalone (external website)
|
|
27
|
+
|
|
28
|
+
```js
|
|
16
29
|
const arinova = new Arinova({ appId: "your-client-id" });
|
|
17
30
|
|
|
18
|
-
//
|
|
31
|
+
// Opens popup for OAuth PKCE login
|
|
19
32
|
const token = await arinova.login();
|
|
20
|
-
console.log(token.user.name);
|
|
21
|
-
console.log(token.access_token);
|
|
33
|
+
console.log(token.user.name);
|
|
34
|
+
console.log(token.access_token);
|
|
22
35
|
```
|
|
23
36
|
|
|
24
37
|
## Setup
|
|
@@ -27,7 +40,7 @@ console.log(token.access_token); // Bearer token for API calls
|
|
|
27
40
|
2. Copy the `Client ID` from the output
|
|
28
41
|
3. No `client_secret` needed — all apps use PKCE
|
|
29
42
|
|
|
30
|
-
## API
|
|
43
|
+
## API Reference
|
|
31
44
|
|
|
32
45
|
### `new Arinova(config)`
|
|
33
46
|
|
|
@@ -38,23 +51,116 @@ console.log(token.access_token); // Bearer token for API calls
|
|
|
38
51
|
| `redirectUri` | `string` | `{origin}/callback` | OAuth callback URL |
|
|
39
52
|
| `scope` | `string` | `"profile"` | OAuth scope |
|
|
40
53
|
|
|
41
|
-
|
|
54
|
+
---
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
### Authentication
|
|
44
57
|
|
|
45
|
-
|
|
58
|
+
#### `arinova.connect(options?): Promise<ConnectResult>`
|
|
59
|
+
|
|
60
|
+
**Recommended for Spaces.** Auto-detects environment:
|
|
61
|
+
- **Inside iframe** (Arinova Chat): receives auth via postMessage from parent window
|
|
62
|
+
- **Outside iframe** (standalone): falls back to `login()` popup flow
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const { user, accessToken, agents } = await arinova.connect({ timeout: 10000 });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| Option | Type | Default | Description |
|
|
69
|
+
|--------|------|---------|-------------|
|
|
70
|
+
| `timeout` | `number` | `5000` | Timeout in ms for postMessage (iframe mode) |
|
|
71
|
+
|
|
72
|
+
Returns: `{ user: { id, name, email, image }, accessToken: string, agents: Agent[] }`
|
|
73
|
+
|
|
74
|
+
#### `arinova.login(): Promise<TokenResponse>`
|
|
75
|
+
|
|
76
|
+
Opens a popup for OAuth PKCE authorization. Falls back to redirect if popup is blocked.
|
|
77
|
+
|
|
78
|
+
#### `arinova.handleCallback(): Promise<TokenResponse>`
|
|
79
|
+
|
|
80
|
+
Call on your redirect_uri page to complete the OAuth flow (redirect mode).
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### Agent Chat
|
|
85
|
+
|
|
86
|
+
Chat with the user's AI agents. Supports streaming (SSE).
|
|
87
|
+
|
|
88
|
+
#### `POST /api/v1/agents/{agentId}/chat`
|
|
89
|
+
|
|
90
|
+
**Auth:** Bearer token (requires `agents` scope)
|
|
91
|
+
|
|
92
|
+
**Request Body:**
|
|
93
|
+
|
|
94
|
+
```json
|
|
46
95
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
96
|
+
"agentId": "uuid",
|
|
97
|
+
"prompt": "Hello!",
|
|
98
|
+
"systemPrompt": "You are a brave adventurer's companion...",
|
|
99
|
+
"messages": [
|
|
100
|
+
{ "role": "user", "content": "Let's go north" },
|
|
101
|
+
{ "role": "assistant", "content": "We arrived at the dark forest..." }
|
|
102
|
+
],
|
|
103
|
+
"context": {
|
|
104
|
+
"player": { "name": "Ripple", "level": 5, "hp": 120 },
|
|
105
|
+
"location": { "name": "Village Square", "exits": ["north", "south"] },
|
|
106
|
+
"inventory": ["Wooden Sword", "Health Potion x3"]
|
|
107
|
+
}
|
|
52
108
|
}
|
|
53
109
|
```
|
|
54
110
|
|
|
55
|
-
|
|
111
|
+
| Field | Type | Required | Description |
|
|
112
|
+
|-------|------|----------|-------------|
|
|
113
|
+
| `agentId` | `string` | Yes | The agent's UUID |
|
|
114
|
+
| `prompt` | `string` | No* | Single user message |
|
|
115
|
+
| `systemPrompt` | `string` | No | Overrides agent's default system prompt |
|
|
116
|
+
| `messages` | `Array<{role, content}>` | No* | Multi-turn conversation history |
|
|
117
|
+
| `context` | `object` | No | Game/app state, injected into system prompt as `[Context]` block |
|
|
118
|
+
|
|
119
|
+
*Either `prompt` or `messages` must be provided.
|
|
120
|
+
|
|
121
|
+
**Response:** Server-Sent Events (SSE)
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
data: {"type":"chunk","content":"Hello"}
|
|
125
|
+
data: {"type":"chunk","content":" there!"}
|
|
126
|
+
data: {"type":"done"}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Usage Tips:**
|
|
130
|
+
- `systemPrompt` = stable character/role definition (doesn't change often)
|
|
131
|
+
- `context` = real-time app state (updated every request)
|
|
132
|
+
- `messages` = conversation history (accumulated by your app)
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Economy
|
|
137
|
+
|
|
138
|
+
#### `arinova.balance(): Promise<{ balance: number }>`
|
|
139
|
+
|
|
140
|
+
Get the current user's coin balance.
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
const { balance } = await arinova.balance();
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### `arinova.purchase(productId, amount, description?): Promise<PurchaseResponse>`
|
|
56
147
|
|
|
57
|
-
|
|
148
|
+
Charge coins from the user's balance. Requires `economy` scope (via OAuth consent).
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
const result = await arinova.purchase("health-potion", 50, "Bought Health Potion");
|
|
152
|
+
console.log(result.transactionId, result.newBalance);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### `arinova.transactions(limit?, offset?): Promise<TransactionsResponse>`
|
|
156
|
+
|
|
157
|
+
Get the user's transaction history.
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
const { transactions, total } = await arinova.transactions(20, 0);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
58
164
|
|
|
59
165
|
## PKCE Flow
|
|
60
166
|
|
|
@@ -69,23 +175,3 @@ Call on your redirect_uri page to complete the flow (for redirect mode instead o
|
|
|
69
175
|
- Path can differ (SDK uses `window.location.origin + /callback` by default)
|
|
70
176
|
- Must use HTTPS in production
|
|
71
177
|
- `http://localhost` is allowed for development
|
|
72
|
-
|
|
73
|
-
## Example: Redirect Mode
|
|
74
|
-
|
|
75
|
-
If popups are blocked, use redirect mode:
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
// On login page:
|
|
79
|
-
const arinova = new Arinova({
|
|
80
|
-
appId: "your-client-id",
|
|
81
|
-
redirectUri: "https://myapp.com/auth/callback",
|
|
82
|
-
});
|
|
83
|
-
arinova.login(); // Will redirect if popup is blocked
|
|
84
|
-
|
|
85
|
-
// On callback page (/auth/callback):
|
|
86
|
-
const arinova = new Arinova({
|
|
87
|
-
appId: "your-client-id",
|
|
88
|
-
redirectUri: "https://myapp.com/auth/callback",
|
|
89
|
-
});
|
|
90
|
-
const token = await arinova.handleCallback();
|
|
91
|
-
```
|
package/dist/index.js
CHANGED
|
@@ -111,10 +111,12 @@ export class Arinova {
|
|
|
111
111
|
}
|
|
112
112
|
}, timeout);
|
|
113
113
|
const handler = (event) => {
|
|
114
|
+
console.log("[ARINOVA-SDK] message received", event.data?.type, { settled, hasPayload: !!event.data?.payload });
|
|
114
115
|
if (event.data?.type !== "arinova:auth")
|
|
115
116
|
return;
|
|
116
117
|
if (settled)
|
|
117
118
|
return;
|
|
119
|
+
console.log("[ARINOVA-SDK] arinova:auth matched, resolving connect()");
|
|
118
120
|
settled = true;
|
|
119
121
|
clearTimeout(timer);
|
|
120
122
|
window.removeEventListener("message", handler);
|
|
@@ -123,6 +125,7 @@ export class Arinova {
|
|
|
123
125
|
resolve(payload);
|
|
124
126
|
};
|
|
125
127
|
window.addEventListener("message", handler);
|
|
128
|
+
console.log("[ARINOVA-SDK] connect() listener registered, waiting for arinova:auth...");
|
|
126
129
|
});
|
|
127
130
|
}
|
|
128
131
|
/**
|