@pagelines/sdk 1.0.148
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 +542 -0
- package/dist/AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js +42 -0
- package/dist/AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js.map +1 -0
- package/dist/AgentWidgetInline-pTCUPNqY.js +35 -0
- package/dist/AgentWidgetInline-pTCUPNqY.js.map +1 -0
- package/dist/AgentWidgetModal-BA74AH8E.js +66 -0
- package/dist/AgentWidgetModal-BA74AH8E.js.map +1 -0
- package/dist/AgentWidgetPopup-pe5CmJfa.js +117 -0
- package/dist/AgentWidgetPopup-pe5CmJfa.js.map +1 -0
- package/dist/AgentWrap.vue_vue_type_script_setup_true_lang-Bvik7Wdb.js +5139 -0
- package/dist/AgentWrap.vue_vue_type_script_setup_true_lang-Bvik7Wdb.js.map +1 -0
- package/dist/FModal.vue_vue_type_script_setup_true_lang-cL0BFEkZ.js +172 -0
- package/dist/FModal.vue_vue_type_script_setup_true_lang-cL0BFEkZ.js.map +1 -0
- package/dist/agent/AgentController.d.ts +81 -0
- package/dist/agent/ClientAudio.d.ts +102 -0
- package/dist/agent/constants.d.ts +16 -0
- package/dist/agent/index.d.ts +10 -0
- package/dist/agent/schema.d.ts +46 -0
- package/dist/agent/test/AgentController.test.d.ts +1 -0
- package/dist/agent/test/utils.test.d.ts +1 -0
- package/dist/agent/ui/AgentChat.vue.d.ts +27 -0
- package/dist/agent/ui/AgentInputEmail.vue.d.ts +9 -0
- package/dist/agent/ui/AgentInputOneTimeCode.vue.d.ts +13 -0
- package/dist/agent/ui/AgentModal.vue.d.ts +16 -0
- package/dist/agent/ui/AgentProvider.vue.d.ts +22 -0
- package/dist/agent/ui/AgentSidebarClose.vue.d.ts +6 -0
- package/dist/agent/ui/AgentWidget.vue.d.ts +17 -0
- package/dist/agent/ui/AgentWrap.vue.d.ts +128 -0
- package/dist/agent/ui/ElAgentAbout.vue.d.ts +6 -0
- package/dist/agent/ui/ElAgentButton.vue.d.ts +26 -0
- package/dist/agent/ui/ElAgentChat.vue.d.ts +11 -0
- package/dist/agent/ui/ElAgentHeader.vue.d.ts +6 -0
- package/dist/agent/ui/ElAgentModeSidebar.vue.d.ts +11 -0
- package/dist/agent/ui/ElAgentSidebar.vue.d.ts +14 -0
- package/dist/agent/ui/ElAuthGate.vue.d.ts +6 -0
- package/dist/agent/ui/ElModeHeader.vue.d.ts +9 -0
- package/dist/agent/ui/ElSidebar.vue.d.ts +30 -0
- package/dist/agent/utils.d.ts +34 -0
- package/dist/agent.js +162 -0
- package/dist/agent.js.map +1 -0
- package/dist/api.d.ts +23 -0
- package/dist/constants/socialPlatforms.d.ts +10 -0
- package/dist/demo/index.d.ts +105 -0
- package/dist/demo.js +264 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/sdk.css +1 -0
- package/dist/sdk.js +9 -0
- package/dist/sdk.js.map +1 -0
- package/dist/sdkClient-BmWhfelO.js +939 -0
- package/dist/sdkClient-BmWhfelO.js.map +1 -0
- package/dist/sdkClient.d.ts +762 -0
- package/dist/sdkStorage.d.ts +39 -0
- package/dist/socialPlatforms-Ck-b3SnQ.js +82 -0
- package/dist/socialPlatforms-Ck-b3SnQ.js.map +1 -0
- package/dist/test/api.test.d.ts +1 -0
- package/dist/test/build.test.d.ts +1 -0
- package/dist/types/SDKAppType.stub.d.ts +6 -0
- package/dist/vite-env.d.ts +13 -0
- package/dist/vite.config.sdk.d.ts +2 -0
- package/dist/vitest.config.d.ts +2 -0
- package/dist/widget/PLWidget.d.ts +55 -0
- package/dist/widget/composables/usePLWidget.d.ts +57 -0
- package/dist/widget/index.d.ts +4 -0
- package/dist/widget/ui/AgentWidgetInline.vue.d.ts +17 -0
- package/dist/widget/ui/AgentWidgetModal.vue.d.ts +22 -0
- package/dist/widget/ui/AgentWidgetPopup.vue.d.ts +24 -0
- package/dist/widget.js +188 -0
- package/dist/widget.js.map +1 -0
- package/package.json +94 -0
package/README.md
ADDED
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
# PageLines SDK
|
|
2
|
+
|
|
3
|
+
Lightweight client library for PageLines agent integration. Built for PageLines-owned properties (app, www, widget).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pagelines/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { PageLinesSDK } from '@pagelines/sdk'
|
|
15
|
+
|
|
16
|
+
// Singleton pattern - shares state across your app
|
|
17
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
18
|
+
|
|
19
|
+
// Get public agent
|
|
20
|
+
const agent = await sdk.getPublicAgent({ handle: 'andrew' })
|
|
21
|
+
|
|
22
|
+
// Authenticate user
|
|
23
|
+
await sdk.requestAuthCode({ email: 'user@example.com' })
|
|
24
|
+
await sdk.loginWithCode({ email: 'user@example.com', code: '123456' })
|
|
25
|
+
|
|
26
|
+
// Access reactive state
|
|
27
|
+
console.log(sdk.activeUser.value)
|
|
28
|
+
console.log(sdk.currentAgent.value)
|
|
29
|
+
console.log(sdk.currentOrg.value)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Core Philosophy
|
|
33
|
+
|
|
34
|
+
**Minimal API Surface**: Clean wrapper methods hide internal complexity. No direct `apiClient` exposure prevents type generation issues.
|
|
35
|
+
|
|
36
|
+
**Agent-First Architecture**: Agents are primary entities. Organization context derived from agent, not passed redundantly.
|
|
37
|
+
|
|
38
|
+
**Singleton by Default**: Browser-only singleton prevents duplicate API calls and separate reactive state. Multiple `getInstance()` calls return same instance.
|
|
39
|
+
|
|
40
|
+
**SSR-Safe**: No singleton in Node.js—each request gets new instance to prevent request bleeding.
|
|
41
|
+
|
|
42
|
+
## Public API
|
|
43
|
+
|
|
44
|
+
### Authentication
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Request email verification code
|
|
48
|
+
await sdk.requestAuthCode({ email: 'user@example.com' })
|
|
49
|
+
|
|
50
|
+
// Login with code
|
|
51
|
+
await sdk.loginWithCode({
|
|
52
|
+
email: 'user@example.com',
|
|
53
|
+
code: '123456'
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
// Google OAuth popup
|
|
57
|
+
await sdk.loginWithGoogle()
|
|
58
|
+
|
|
59
|
+
// Get current user
|
|
60
|
+
const user = await sdk.getCurrentUser()
|
|
61
|
+
|
|
62
|
+
// Logout
|
|
63
|
+
await sdk.logout()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Agent Access
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Public agent by handle (no auth)
|
|
70
|
+
const agent = await sdk.getPublicAgent({ handle: 'andrew' })
|
|
71
|
+
|
|
72
|
+
// Public agent by email (no auth)
|
|
73
|
+
const agent = await sdk.getAgentByEmail({ email: 'andrew@pagelines.com' })
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Usage Tracking
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// Unified tracking method
|
|
80
|
+
await sdk.trackUsage({
|
|
81
|
+
agentId: 'agt_456', // Agent contains orgId
|
|
82
|
+
type: 'voice', // 'voice' | 'chat'
|
|
83
|
+
quantity: 45, // Seconds for voice, characters for chat
|
|
84
|
+
participantId: 'usr_123' // Optional: conversation participant
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Reactive State
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
// Core state
|
|
92
|
+
sdk.activeUser.value // EnrichedUser | undefined
|
|
93
|
+
sdk.token.value // string | null
|
|
94
|
+
sdk.loading.value // boolean
|
|
95
|
+
sdk.error.value // string | null
|
|
96
|
+
|
|
97
|
+
// Computed properties (auto-derived from activeUser)
|
|
98
|
+
sdk.currentAgent.value // Agent | undefined
|
|
99
|
+
sdk.currentOrg.value // OrgInfo | undefined
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Singleton Pattern
|
|
103
|
+
|
|
104
|
+
**Why Singleton**: Prevents duplicate API requests and maintains shared reactive state across your application.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Both return same instance
|
|
108
|
+
const sdk1 = PageLinesSDK.getInstance({ isDev: true })
|
|
109
|
+
const sdk2 = PageLinesSDK.getInstance({ isDev: true })
|
|
110
|
+
|
|
111
|
+
console.log(sdk1 === sdk2) // true
|
|
112
|
+
|
|
113
|
+
// Reactive state shared
|
|
114
|
+
sdk1.token.value = 'test-token'
|
|
115
|
+
console.log(sdk2.token.value) // 'test-token'
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Cross-Bundle Singleton**: Uses `globalThis` to share instance between separate bundles (www + widget).
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
// Global SDK (www.pagelines.com)
|
|
122
|
+
window.pagelinesSDK = PageLinesSDK.getInstance({ isDev: true })
|
|
123
|
+
|
|
124
|
+
// Widget automatically uses singleton
|
|
125
|
+
const widget = new PLWidget({ handle: 'andrew' })
|
|
126
|
+
console.log(window.pagelinesSDK === widget.sdk) // true
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Testing Pattern**: Use `clear()` to reset singleton between tests.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { afterEach, it, expect } from 'vitest'
|
|
133
|
+
|
|
134
|
+
afterEach(() => {
|
|
135
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
136
|
+
sdk.clear() // Clears session + state + destroys singleton
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('should test singleton behavior', () => {
|
|
140
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
141
|
+
// Test runs with clean state
|
|
142
|
+
})
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Environment Detection**: `apiBase` auto-detected from environment. Only override for testing.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// ✅ Normal usage (95%+ cases) - apiBase omitted
|
|
149
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
150
|
+
// Dev: http://localhost:5555 (auto)
|
|
151
|
+
// Prod: https://app.pagelines.com (auto)
|
|
152
|
+
|
|
153
|
+
// ✅ Testing only - custom apiBase
|
|
154
|
+
const testSDK = PageLinesSDK.getInstance({
|
|
155
|
+
isDev: true,
|
|
156
|
+
apiBase: 'http://localhost:9999'
|
|
157
|
+
})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Usage Patterns
|
|
161
|
+
|
|
162
|
+
### Blog Author Attribution
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Astro component (www.pagelines.com)
|
|
166
|
+
import { PageLinesSDK } from '@pagelines/sdk'
|
|
167
|
+
|
|
168
|
+
const sdk = PageLinesSDK.getInstance({ isDev: import.meta.env.DEV })
|
|
169
|
+
const authorAgent = await sdk.getAgentByEmail({ email: 'andrew@pagelines.com' })
|
|
170
|
+
|
|
171
|
+
// Use agent data instead of static strings
|
|
172
|
+
const authorAvatar = authorAgent?.avatar?.url
|
|
173
|
+
const authorName = authorAgent?.name
|
|
174
|
+
const authorBio = authorAgent?.summary
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Widget Integration
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
import { PLWidget } from '@pagelines/sdk/widget'
|
|
181
|
+
|
|
182
|
+
const widget = new PLWidget({
|
|
183
|
+
mode: 'modal', // 'inline' | 'popup' | 'modal'
|
|
184
|
+
handle: 'andrew', // Or provide agent object directly
|
|
185
|
+
context: 'support', // Optional: agent context override
|
|
186
|
+
firstMessage: 'Hi!' // Optional: custom greeting
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
// Update without re-mount
|
|
190
|
+
widget.update({
|
|
191
|
+
agent: newAgent,
|
|
192
|
+
context: 'sales'
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
// Cleanup
|
|
196
|
+
widget.destroy()
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Profile Page
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { AgentChat } from '@pagelines/sdk/agent'
|
|
203
|
+
|
|
204
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
205
|
+
const agent = await sdk.getPublicAgent({ handle: 'andrew' })
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
```vue
|
|
209
|
+
<template>
|
|
210
|
+
<AgentChat
|
|
211
|
+
:sdk="sdk"
|
|
212
|
+
:agent="agent"
|
|
213
|
+
theme-color="#3b82f6"
|
|
214
|
+
/>
|
|
215
|
+
</template>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Error Handling
|
|
219
|
+
|
|
220
|
+
All wrapper methods return `undefined` on error (no exceptions thrown). Check reactive error state for details.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const agent = await sdk.getPublicAgent({ handle: 'nonexistent' })
|
|
224
|
+
|
|
225
|
+
if (!agent) {
|
|
226
|
+
console.error(sdk.error.value) // 'Agent not found'
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## Build Strategy
|
|
231
|
+
|
|
232
|
+
**SDK Build**: ES modules, tree-shakeable, externals (Vue)
|
|
233
|
+
- Format: ES modules
|
|
234
|
+
- Bundle size: < 256KB
|
|
235
|
+
- Build time: 5 seconds
|
|
236
|
+
|
|
237
|
+
**Widget Build**: IIFE, single-file CDN bundle
|
|
238
|
+
- Format: IIFE (global `window.PLWidget`)
|
|
239
|
+
- Bundle size: < 1MB
|
|
240
|
+
- Includes all dependencies
|
|
241
|
+
|
|
242
|
+
## Import Patterns
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// ✅ Correct - Use bundled entry points
|
|
246
|
+
import { PageLinesSDK } from '@pagelines/sdk'
|
|
247
|
+
import { AgentChat, AgentProvider } from '@pagelines/sdk/agent'
|
|
248
|
+
import { PLWidget } from '@pagelines/sdk/widget'
|
|
249
|
+
import { getDemoAgents } from '@pagelines/sdk/demo'
|
|
250
|
+
|
|
251
|
+
// ❌ Wrong - Deep imports don't work
|
|
252
|
+
import { PageLinesSDK } from '@pagelines/sdk/PageLinesSDK'
|
|
253
|
+
import AgentChat from '@pagelines/sdk/agent/ui/AgentChat.vue'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Package Exports
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"exports": {
|
|
261
|
+
".": {
|
|
262
|
+
"import": "./dist/sdk.js",
|
|
263
|
+
"types": "./dist/sdk.d.ts"
|
|
264
|
+
},
|
|
265
|
+
"./agent": {
|
|
266
|
+
"import": "./dist/agent.js",
|
|
267
|
+
"types": "./dist/agent.d.ts"
|
|
268
|
+
},
|
|
269
|
+
"./widget": {
|
|
270
|
+
"import": "./dist/widget.js",
|
|
271
|
+
"types": "./dist/widget.d.ts"
|
|
272
|
+
},
|
|
273
|
+
"./demo": {
|
|
274
|
+
"import": "./dist/demo.js",
|
|
275
|
+
"types": "./dist/demo/index.d.ts"
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Agent-First Architecture
|
|
282
|
+
|
|
283
|
+
Agents are primary entities that determine organizational context.
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// ✅ Agent contains all context
|
|
287
|
+
await sdk.trackUsage({
|
|
288
|
+
agentId: 'agt_456', // Includes orgId internally
|
|
289
|
+
type: 'voice',
|
|
290
|
+
quantity: 45
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
// ❌ Don't pass redundant orgId
|
|
294
|
+
await sdk.trackUsage({
|
|
295
|
+
orgId: 'org_123', // Redundant - derived from agentId
|
|
296
|
+
agentId: 'agt_456',
|
|
297
|
+
type: 'voice',
|
|
298
|
+
quantity: 45
|
|
299
|
+
})
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Benefits**:
|
|
303
|
+
- Simpler APIs (fewer parameters)
|
|
304
|
+
- Single source of truth (agent determines org)
|
|
305
|
+
- Automatic context resolution
|
|
306
|
+
- Consistent across all SDK methods
|
|
307
|
+
|
|
308
|
+
## Reactive State Pattern
|
|
309
|
+
|
|
310
|
+
SDK maintains reactive state that auto-updates components.
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
314
|
+
|
|
315
|
+
// Core refs (direct state)
|
|
316
|
+
sdk.activeUser.value // Updated by auth operations
|
|
317
|
+
sdk.token.value // Updated by login/logout
|
|
318
|
+
sdk.loading.value // Updated during API calls
|
|
319
|
+
sdk.error.value // Updated on errors
|
|
320
|
+
|
|
321
|
+
// Computed properties (auto-derived)
|
|
322
|
+
sdk.currentAgent.value = computed(() => {
|
|
323
|
+
const user = sdk.activeUser.value
|
|
324
|
+
if (!user?.agents) return undefined
|
|
325
|
+
|
|
326
|
+
const agentId = user.primaryAgentId || user.agents[0]?.agentId
|
|
327
|
+
return user.agents.find(a => a.agentId === agentId)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
sdk.currentOrg.value = computed(() => {
|
|
331
|
+
const agent = sdk.currentAgent.value
|
|
332
|
+
if (!agent?.orgId) return undefined
|
|
333
|
+
|
|
334
|
+
return sdk.activeUser.value?.orgs.find(org =>
|
|
335
|
+
org.orgId === agent.orgId
|
|
336
|
+
)
|
|
337
|
+
})
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Benefits**:
|
|
341
|
+
- Components auto-update when user changes
|
|
342
|
+
- No manual state management needed
|
|
343
|
+
- Consistent with PageLines app patterns
|
|
344
|
+
- Agent-first architecture (org derived from agent)
|
|
345
|
+
|
|
346
|
+
## Component Integration
|
|
347
|
+
|
|
348
|
+
### Prop-Based Dependency Injection
|
|
349
|
+
|
|
350
|
+
SDK components accept `sdk` prop instead of using global services.
|
|
351
|
+
|
|
352
|
+
```vue
|
|
353
|
+
<script setup>
|
|
354
|
+
import { PageLinesSDK } from '@pagelines/sdk'
|
|
355
|
+
import { AgentChat } from '@pagelines/sdk/agent'
|
|
356
|
+
|
|
357
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
358
|
+
const agent = await sdk.getPublicAgent({ handle: 'andrew' })
|
|
359
|
+
</script>
|
|
360
|
+
|
|
361
|
+
<template>
|
|
362
|
+
<AgentChat
|
|
363
|
+
:sdk="sdk"
|
|
364
|
+
:agent="agent"
|
|
365
|
+
theme-color="#3b82f6"
|
|
366
|
+
/>
|
|
367
|
+
</template>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Available Components
|
|
371
|
+
|
|
372
|
+
**AgentChat** - Main agent interface (chat/voice)
|
|
373
|
+
**AgentProvider** - Handle → agent resolver wrapper
|
|
374
|
+
**ElAgentAbout** - Profile information display
|
|
375
|
+
**ElAgentChat** - Text chat interface
|
|
376
|
+
**ElAgentVoice** - Voice call interface
|
|
377
|
+
**ElAgentSidebar** - Navigation sidebar
|
|
378
|
+
|
|
379
|
+
## Demo Data
|
|
380
|
+
|
|
381
|
+
Static demo agents for marketing/showcase.
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
import { getDemoAgents, getDemoAgentByHandle } from '@pagelines/sdk/demo'
|
|
385
|
+
|
|
386
|
+
// All demo agents
|
|
387
|
+
const demoAgents = getDemoAgents()
|
|
388
|
+
|
|
389
|
+
// Specific demo agent
|
|
390
|
+
const andrew = getDemoAgentByHandle('andrew')
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
**Single Source of Truth**: Demo data maintained in PageLines app at `src/modules/agent/static/data.ts`, bundled into SDK at build time.
|
|
394
|
+
|
|
395
|
+
## Security Model
|
|
396
|
+
|
|
397
|
+
**Public-Only Access**: `getPublicAgent()` and `getAgentByEmail()` only return agents with `visibility: 'public'`.
|
|
398
|
+
|
|
399
|
+
**Authentication Required**: User operations require valid JWT token in `sdk.token.value`.
|
|
400
|
+
|
|
401
|
+
**Rate Limiting**: Widget includes 10 comments/hour per agent, 100 likes/hour (future).
|
|
402
|
+
|
|
403
|
+
## Performance Optimization
|
|
404
|
+
|
|
405
|
+
**Single Query Pattern**: Public endpoints use single SQL query with LEFT JOINs for media.
|
|
406
|
+
|
|
407
|
+
**Voice Recordings Excluded**: Public endpoints exclude voice recordings (performance).
|
|
408
|
+
|
|
409
|
+
**Build Time Bundling**: App dependencies (`@/` imports) bundled during SDK build.
|
|
410
|
+
|
|
411
|
+
**Ultra-Fast Builds**: 5-second builds via custom tsconfig + esbuild optimization.
|
|
412
|
+
|
|
413
|
+
## Type Safety
|
|
414
|
+
|
|
415
|
+
**Full TypeScript Inference**: From API routes to SDK methods to component props.
|
|
416
|
+
|
|
417
|
+
**Wrapper Method Pattern**: Clean function signatures serialize perfectly to `.d.ts` files.
|
|
418
|
+
|
|
419
|
+
**No Complex Types**: Simple `Promise<Agent | undefined>` instead of Hono RPC types.
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
// Clean wrapper method
|
|
423
|
+
async getPublicAgent(args: {
|
|
424
|
+
handle: string
|
|
425
|
+
}): Promise<Agent | undefined>
|
|
426
|
+
|
|
427
|
+
// Internal complexity hidden
|
|
428
|
+
const response = await this.api.agent.public[':handle'].$get({
|
|
429
|
+
param: { handle: args.handle }
|
|
430
|
+
})
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Best Practices
|
|
434
|
+
|
|
435
|
+
**1. Use Singleton**: Always use `getInstance()` instead of `new PageLinesSDK()`.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
// ✅ Recommended
|
|
439
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
440
|
+
|
|
441
|
+
// ⚠️ Works but creates singleton anyway
|
|
442
|
+
const sdk = new PageLinesSDK({ isDev: true })
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**2. Don't Override apiBase**: Let SDK auto-detect environment.
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
// ✅ Normal usage
|
|
449
|
+
const sdk = PageLinesSDK.getInstance({ isDev: true })
|
|
450
|
+
|
|
451
|
+
// ❌ Only for testing
|
|
452
|
+
const sdk = PageLinesSDK.getInstance({
|
|
453
|
+
isDev: true,
|
|
454
|
+
apiBase: 'http://localhost:9999'
|
|
455
|
+
})
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**3. Clear Between Tests**: Use `clear()` for test isolation.
|
|
459
|
+
|
|
460
|
+
```typescript
|
|
461
|
+
afterEach(() => {
|
|
462
|
+
PageLinesSDK.getInstance({ isDev: true }).clear()
|
|
463
|
+
})
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
**4. Check Error State**: Methods return `undefined` on error.
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
const agent = await sdk.getPublicAgent({ handle: 'test' })
|
|
470
|
+
if (!agent) {
|
|
471
|
+
console.error(sdk.error.value)
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
**5. Agent-First APIs**: Pass `agentId`, let SDK resolve `orgId`.
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
// ✅ Minimal args
|
|
479
|
+
await sdk.trackUsage({ agentId, type, quantity })
|
|
480
|
+
|
|
481
|
+
// ❌ Redundant args
|
|
482
|
+
await sdk.trackUsage({ orgId, agentId, type, quantity })
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
## Architecture Principles
|
|
486
|
+
|
|
487
|
+
**Minimal Case First**: Start with simplest implementation, add complexity only when needed.
|
|
488
|
+
|
|
489
|
+
**No Globals**: All state via dependency injection (SDK prop pattern).
|
|
490
|
+
|
|
491
|
+
**Bundle Safety**: Server code never reaches client (strict separation).
|
|
492
|
+
|
|
493
|
+
**Validated Environment**: Auto-detected `apiBase` based on environment.
|
|
494
|
+
|
|
495
|
+
**Static Chaining**: Preserves Hono type inference for internal operations.
|
|
496
|
+
|
|
497
|
+
## Browser Compatibility
|
|
498
|
+
|
|
499
|
+
**Singleton Scope**: `globalThis` for cross-bundle state sharing.
|
|
500
|
+
|
|
501
|
+
**SSR Detection**: `typeof window === 'undefined'` prevents Node.js singleton.
|
|
502
|
+
|
|
503
|
+
**Storage**: localStorage for user data, cookies for auth tokens.
|
|
504
|
+
|
|
505
|
+
**Vue 3.6+**: Required for reactive refs and computed properties.
|
|
506
|
+
|
|
507
|
+
## Development
|
|
508
|
+
|
|
509
|
+
```bash
|
|
510
|
+
# Watch mode - rebuilds on change
|
|
511
|
+
pnpm dev
|
|
512
|
+
|
|
513
|
+
# Production build (ES modules + types)
|
|
514
|
+
pnpm build
|
|
515
|
+
|
|
516
|
+
# Run tests
|
|
517
|
+
pnpm test
|
|
518
|
+
|
|
519
|
+
# Typecheck
|
|
520
|
+
pnpm typecheck
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Build required before typecheck** - Widget/www import from `dist/`, not source.
|
|
524
|
+
|
|
525
|
+
## Contributing
|
|
526
|
+
|
|
527
|
+
This SDK is for PageLines-owned projects only. For internal development:
|
|
528
|
+
|
|
529
|
+
1. Make changes in `packages/sdk/`
|
|
530
|
+
2. Build: `pnpm run sdk:build`
|
|
531
|
+
3. Test: `pnpm test packages/sdk/test/`
|
|
532
|
+
4. Update this README if public API changes
|
|
533
|
+
|
|
534
|
+
## License
|
|
535
|
+
|
|
536
|
+
Proprietary - PageLines
|
|
537
|
+
|
|
538
|
+
## Support
|
|
539
|
+
|
|
540
|
+
Internal developers: See `plans/architecture/sdk.md` for complete architecture documentation.
|
|
541
|
+
|
|
542
|
+
External users: Contact support@pagelines.com
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { defineComponent as i, createBlock as c, openBlock as l, mergeProps as u, withCtx as m, createVNode as f } from "vue";
|
|
2
|
+
import { _ as g, a as p } from "./AgentWrap.vue_vue_type_script_setup_true_lang-Bvik7Wdb.js";
|
|
3
|
+
const b = /* @__PURE__ */ i({
|
|
4
|
+
__name: "AgentProvider",
|
|
5
|
+
props: {
|
|
6
|
+
sdk: {},
|
|
7
|
+
agent: {},
|
|
8
|
+
handle: {},
|
|
9
|
+
context: {},
|
|
10
|
+
firstMessage: {},
|
|
11
|
+
buttonText: {},
|
|
12
|
+
buttonIcon: {},
|
|
13
|
+
hasClose: { type: Boolean },
|
|
14
|
+
apiBase: {}
|
|
15
|
+
},
|
|
16
|
+
emits: ["close", "error"],
|
|
17
|
+
setup(r, { emit: a }) {
|
|
18
|
+
const e = r, n = a;
|
|
19
|
+
return (x, t) => (l(), c(g, u(e, { class: "agent-provider size-full relative" }), {
|
|
20
|
+
default: m((o) => [
|
|
21
|
+
f(p, {
|
|
22
|
+
sdk: o.sdk,
|
|
23
|
+
agent: o.agent,
|
|
24
|
+
context: o.context,
|
|
25
|
+
"first-message": o.firstMessage,
|
|
26
|
+
"button-text": e.buttonText,
|
|
27
|
+
"button-icon": e.buttonIcon,
|
|
28
|
+
"has-close": e.hasClose,
|
|
29
|
+
"is-active": !0,
|
|
30
|
+
class: "size-full",
|
|
31
|
+
onClose: t[0] || (t[0] = (s) => n("close", s)),
|
|
32
|
+
onError: t[1] || (t[1] = (s) => n("error", s))
|
|
33
|
+
}, null, 8, ["sdk", "agent", "context", "first-message", "button-text", "button-icon", "has-close"])
|
|
34
|
+
]),
|
|
35
|
+
_: 1
|
|
36
|
+
}, 16));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
export {
|
|
40
|
+
b as _
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js","sources":["../agent/ui/AgentProvider.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { PageLinesSDK } from '../../sdkClient'\nimport type { ButtonIconPreset } from '../../widget/PLWidget'\nimport type { Agent } from '../schema'\nimport AgentChat from './AgentChat.vue'\nimport AgentWrap from './AgentWrap.vue'\n\nconst props = defineProps<{\n sdk?: PageLinesSDK\n agent?: Agent\n handle?: string\n context?: string\n firstMessage?: string\n buttonText?: string\n buttonIcon?: ButtonIconPreset\n hasClose?: boolean\n apiBase?: string\n}>()\n\nconst emit = defineEmits<{\n close: [value: string]\n error: [message: string]\n}>()\n\n</script>\n\n<template>\n <AgentWrap\n v-slot=\"slotProps\"\n v-bind=\"props\"\n class=\"agent-provider size-full relative\"\n >\n <AgentChat\n :sdk=\"slotProps.sdk\"\n :agent=\"slotProps.agent\"\n :context=\"slotProps.context\"\n :first-message=\"slotProps.firstMessage\"\n :button-text=\"props.buttonText\"\n :button-icon=\"props.buttonIcon\"\n :has-close=\"props.hasClose\"\n :is-active=\"true\"\n class=\"size-full\"\n @close=\"emit('close', $event)\"\n @error=\"emit('error', $event)\"\n />\n </AgentWrap>\n</template>\n"],"names":["props","__props","emit","__emit","_openBlock","_createBlock","AgentWrap","_mergeProps","_withCtx","slotProps","_createVNode","AgentChat","_cache","$event"],"mappings":";;;;;;;;;;;;;;;;;AAOA,UAAMA,IAAQC,GAYRC,IAAOC;sBAQXC,EAAA,GAAAC,EAkBYC,GAlBZC,EAkBYP,GAhBG,EACb,OAAM,oCAAA,CAAmC,GAAA;AAAA,MAEzC,SAAAQ,EAAA,CAJQC,MAAS;AAAA,QAIjBC,EAYEC,GAAA;AAAA,UAXC,KAAKF,EAAU;AAAA,UACf,OAAOA,EAAU;AAAA,UACjB,SAASA,EAAU;AAAA,UACnB,iBAAeA,EAAU;AAAA,UACzB,eAAaT,EAAM;AAAA,UACnB,eAAaA,EAAM;AAAA,UACnB,aAAWA,EAAM;AAAA,UACjB,aAAW;AAAA,UACZ,OAAM;AAAA,UACL,SAAKY,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEX,EAAI,SAAUW,CAAM;AAAA,UAC3B,SAAKD,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAC,MAAEX,EAAI,SAAUW,CAAM;AAAA,QAAA;;;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
var x = Object.defineProperty;
|
|
2
|
+
var l = (n, c) => x(n, "name", { value: c, configurable: !0 });
|
|
3
|
+
import { defineComponent as g, ref as o, createBlock as v, openBlock as b } from "vue";
|
|
4
|
+
import { _ as m } from "./AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js";
|
|
5
|
+
const M = /* @__PURE__ */ g({
|
|
6
|
+
__name: "AgentWidgetInline",
|
|
7
|
+
props: {
|
|
8
|
+
sdk: {},
|
|
9
|
+
handle: {},
|
|
10
|
+
agent: {},
|
|
11
|
+
context: {},
|
|
12
|
+
firstMessage: {},
|
|
13
|
+
buttonText: {},
|
|
14
|
+
buttonIcon: {}
|
|
15
|
+
},
|
|
16
|
+
setup(n, { expose: c }) {
|
|
17
|
+
const e = n, s = o(e.agent), r = o(e.context), a = o(e.firstMessage), i = o(e.buttonText), u = o(e.buttonIcon);
|
|
18
|
+
function f(t) {
|
|
19
|
+
t.agent !== void 0 && (s.value = t.agent), t.context !== void 0 && (r.value = t.context), t.firstMessage !== void 0 && (a.value = t.firstMessage), t.buttonText !== void 0 && (i.value = t.buttonText), t.buttonIcon !== void 0 && (u.value = t.buttonIcon);
|
|
20
|
+
}
|
|
21
|
+
return l(f, "update"), c({ update: f }), (t, d) => (b(), v(m, {
|
|
22
|
+
sdk: n.sdk,
|
|
23
|
+
handle: n.handle,
|
|
24
|
+
agent: s.value,
|
|
25
|
+
context: r.value,
|
|
26
|
+
"first-message": a.value,
|
|
27
|
+
"button-text": i.value,
|
|
28
|
+
"button-icon": u.value
|
|
29
|
+
}, null, 8, ["sdk", "handle", "agent", "context", "first-message", "button-text", "button-icon"]));
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
export {
|
|
33
|
+
M as default
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=AgentWidgetInline-pTCUPNqY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentWidgetInline-pTCUPNqY.js","sources":["../widget/ui/AgentWidgetInline.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { PageLinesSDK } from '../../sdkClient'\nimport type { Agent } from '@pagelines/types'\nimport type { ButtonIconPreset, WidgetUpdate } from '../PLWidget'\nimport { ref } from 'vue'\nimport AgentProvider from '../../agent/ui/AgentProvider.vue'\n\nconst props = defineProps<{\n sdk?: PageLinesSDK\n handle?: string\n agent?: Agent\n context?: string\n firstMessage?: string\n buttonText?: string\n buttonIcon?: ButtonIconPreset\n}>()\n\n// Local state for updateable props\nconst currentAgent = ref<Agent | undefined>(props.agent)\nconst currentContext = ref<string | undefined>(props.context)\nconst currentFirstMessage = ref<string | undefined>(props.firstMessage)\nconst currentButtonText = ref<string | undefined>(props.buttonText)\nconst currentButtonIcon = ref<ButtonIconPreset | undefined>(props.buttonIcon)\n\nfunction update(updates: WidgetUpdate) {\n if (updates.agent !== undefined)\n currentAgent.value = updates.agent\n if (updates.context !== undefined)\n currentContext.value = updates.context\n if (updates.firstMessage !== undefined)\n currentFirstMessage.value = updates.firstMessage\n if (updates.buttonText !== undefined)\n currentButtonText.value = updates.buttonText\n if (updates.buttonIcon !== undefined)\n currentButtonIcon.value = updates.buttonIcon\n}\n\ndefineExpose({ update })\n</script>\n\n<template>\n <AgentProvider\n :sdk=\"sdk\"\n :handle=\"handle\"\n :agent=\"currentAgent\"\n :context=\"currentContext\"\n :first-message=\"currentFirstMessage\"\n :button-text=\"currentButtonText\"\n :button-icon=\"currentButtonIcon\"\n />\n</template>\n"],"names":["props","__props","currentAgent","ref","currentContext","currentFirstMessage","currentButtonText","currentButtonIcon","update","updates","__name","__expose","_createBlock","AgentProvider"],"mappings":";;;;;;;;;;;;;;;;AAOA,UAAMA,IAAQC,GAWRC,IAAeC,EAAuBH,EAAM,KAAK,GACjDI,IAAiBD,EAAwBH,EAAM,OAAO,GACtDK,IAAsBF,EAAwBH,EAAM,YAAY,GAChEM,IAAoBH,EAAwBH,EAAM,UAAU,GAC5DO,IAAoBJ,EAAkCH,EAAM,UAAU;AAE5E,aAASQ,EAAOC,GAAuB;AACrC,MAAIA,EAAQ,UAAU,WACpBP,EAAa,QAAQO,EAAQ,QAC3BA,EAAQ,YAAY,WACtBL,EAAe,QAAQK,EAAQ,UAC7BA,EAAQ,iBAAiB,WAC3BJ,EAAoB,QAAQI,EAAQ,eAClCA,EAAQ,eAAe,WACzBH,EAAkB,QAAQG,EAAQ,aAChCA,EAAQ,eAAe,WACzBF,EAAkB,QAAQE,EAAQ;AAAA,IACtC;AAXS,WAAAC,EAAAF,GAAA,WAaTG,EAAa,EAAE,QAAAH,GAAQ,mBAIrBI,EAQEC,GAAA;AAAA,MAPC,KAAKZ,EAAA;AAAA,MACL,QAAQA,EAAA;AAAA,MACR,OAAOC,EAAA;AAAA,MACP,SAASE,EAAA;AAAA,MACT,iBAAeC,EAAA;AAAA,MACf,eAAaC,EAAA;AAAA,MACb,eAAaC,EAAA;AAAA,IAAA;;;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var b = Object.defineProperty;
|
|
2
|
+
var a = (o, i) => b(o, "name", { value: i, configurable: !0 });
|
|
3
|
+
import { defineComponent as h, ref as n, onMounted as C, nextTick as T, createBlock as k, openBlock as M, withCtx as _, createVNode as p } from "vue";
|
|
4
|
+
import { _ as I } from "./FModal.vue_vue_type_script_setup_true_lang-cL0BFEkZ.js";
|
|
5
|
+
import { _ as B } from "./AgentProvider.vue_vue_type_script_setup_true_lang-BGCgpGEW.js";
|
|
6
|
+
const V = /* @__PURE__ */ h({
|
|
7
|
+
__name: "AgentWidgetModal",
|
|
8
|
+
props: {
|
|
9
|
+
sdk: {},
|
|
10
|
+
handle: {},
|
|
11
|
+
agent: {},
|
|
12
|
+
context: {},
|
|
13
|
+
firstMessage: {},
|
|
14
|
+
buttonText: {},
|
|
15
|
+
buttonIcon: {},
|
|
16
|
+
onClose: { type: Function }
|
|
17
|
+
},
|
|
18
|
+
setup(o, { expose: i }) {
|
|
19
|
+
const e = o, u = n(e.agent), c = n(e.context), r = n(e.firstMessage), f = n(e.buttonText), v = n(e.buttonIcon), s = n(!1);
|
|
20
|
+
C(async () => {
|
|
21
|
+
await T(), setTimeout(() => {
|
|
22
|
+
s.value = !0;
|
|
23
|
+
}, 10);
|
|
24
|
+
});
|
|
25
|
+
function m(t) {
|
|
26
|
+
t.agent !== void 0 && (u.value = t.agent), t.context !== void 0 && (c.value = t.context), t.firstMessage !== void 0 && (r.value = t.firstMessage), t.buttonText !== void 0 && (f.value = t.buttonText), t.buttonIcon !== void 0 && (v.value = t.buttonIcon);
|
|
27
|
+
}
|
|
28
|
+
a(m, "update");
|
|
29
|
+
function l() {
|
|
30
|
+
s.value = !1, setTimeout(() => {
|
|
31
|
+
e.onClose && e.onClose();
|
|
32
|
+
}, 300);
|
|
33
|
+
}
|
|
34
|
+
a(l, "close");
|
|
35
|
+
function d() {
|
|
36
|
+
s.value = !0;
|
|
37
|
+
}
|
|
38
|
+
return a(d, "open"), i({ update: m, close: l, open: d }), (t, x) => (M(), k(I, {
|
|
39
|
+
vis: s.value,
|
|
40
|
+
"disable-teleport": !0,
|
|
41
|
+
"modal-class": "max-w-4xl h-[80vh] md:h-[600px]",
|
|
42
|
+
"has-close": !1,
|
|
43
|
+
"onUpdate:vis": x[0] || (x[0] = (g) => s.value = g),
|
|
44
|
+
onClose: l
|
|
45
|
+
}, {
|
|
46
|
+
default: _(() => [
|
|
47
|
+
p(B, {
|
|
48
|
+
sdk: o.sdk,
|
|
49
|
+
handle: o.handle,
|
|
50
|
+
agent: u.value,
|
|
51
|
+
context: c.value,
|
|
52
|
+
"first-message": r.value,
|
|
53
|
+
"button-text": f.value,
|
|
54
|
+
"button-icon": v.value,
|
|
55
|
+
"has-close": !0,
|
|
56
|
+
onClose: l
|
|
57
|
+
}, null, 8, ["sdk", "handle", "agent", "context", "first-message", "button-text", "button-icon"])
|
|
58
|
+
]),
|
|
59
|
+
_: 1
|
|
60
|
+
}, 8, ["vis"]));
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
export {
|
|
64
|
+
V as default
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=AgentWidgetModal-BA74AH8E.js.map
|