onipin-js 0.2.0 → 0.2.1
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 +63 -23
- package/dist/index.d.ts +55 -2
- package/dist/index.js +26 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# onipin-js
|
|
2
2
|
|
|
3
|
-
SDK oficial de [OniPin](https://onnivers.store) — protocolo
|
|
3
|
+
SDK oficial de [OniPin](https://onnivers.store) — protocolo `onipin/0.2`, discovery, handshake, chat, catálogo, reservas y pedidos.
|
|
4
|
+
|
|
5
|
+
**npm:** https://www.npmjs.com/package/onipin-js
|
|
6
|
+
**Intent Spec:** https://onnivers.store/docs/intent-spec/
|
|
7
|
+
**Docs:** https://onnivers.store/docs#sdk
|
|
4
8
|
|
|
5
9
|
## Instalación
|
|
6
10
|
|
|
@@ -8,7 +12,7 @@ SDK oficial de [OniPin](https://onnivers.store) — protocolo `/v1`, chat, catá
|
|
|
8
12
|
npm install onipin-js
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
##
|
|
15
|
+
## Inicio rápido (OniPin 0.2)
|
|
12
16
|
|
|
13
17
|
```javascript
|
|
14
18
|
import { OniPinClient } from "onipin-js";
|
|
@@ -17,40 +21,76 @@ const oni = new OniPinClient({
|
|
|
17
21
|
baseUrl: "https://onnivers.store",
|
|
18
22
|
pin: "onp_tu_pin",
|
|
19
23
|
callerType: "ai-agent",
|
|
20
|
-
|
|
24
|
+
agent: { name: "MiBot", version: "1.0" },
|
|
21
25
|
});
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
// 1. Descubrir desde URL (opcional si ya tienes el pin)
|
|
28
|
+
const found = await oni.discoverFromUrl("https://sitio-del-negocio.com");
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
// 2. Handshake — anuncia agente e intención
|
|
31
|
+
await oni.handshake("appointment.create");
|
|
32
|
+
|
|
33
|
+
// 3. Chatear con intent
|
|
34
|
+
const chat = await oni.chat("Quiero cita mañana 10:00", {
|
|
35
|
+
intent: "appointment.create",
|
|
36
|
+
});
|
|
27
37
|
console.log(chat.reply?.text);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
| Método | Descripción |
|
|
43
|
+
|--------|-------------|
|
|
44
|
+
| `ping()` | Discovery del negocio (`GET /v1/ping/:pin`) |
|
|
45
|
+
| `discoverFromUrl(url)` | Resuelve pin desde sitio web (`GET /v1/discover?url=`) |
|
|
46
|
+
| `handshake(intent?, agent?)` | Handshake OniPin 0.2 (`POST /v1/handshake/:pin`) |
|
|
47
|
+
| `catalog()` | Productos/servicios activos |
|
|
48
|
+
| `chat(message, opts?)` | Envía mensaje; `opts`: `{ conversationId, intent, agent }` |
|
|
49
|
+
| `messages({ conversationId, after, limit })` | Lee el hilo |
|
|
50
|
+
| `createBooking({ service, scheduledLabel, clientName, ... })` | Reserva real en BD |
|
|
51
|
+
| `createOrder({ productName, quantity, clientName, ... })` | Pedido real en BD |
|
|
52
|
+
| `reset()` | Nueva conversación local |
|
|
53
|
+
|
|
54
|
+
## Intents soportados
|
|
55
|
+
|
|
56
|
+
- `business.chat` — conversación general
|
|
57
|
+
- `appointment.create` — agendar cita/demo
|
|
58
|
+
- `order.create` — crear pedido
|
|
59
|
+
- `product.price` / `product.info` — consultar producto
|
|
60
|
+
- `catalog.browse` — ver catálogo
|
|
61
|
+
- `payment.info` — datos de pago
|
|
62
|
+
|
|
63
|
+
## Ejemplo completo
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
import { OniPinClient } from "onipin-js";
|
|
67
|
+
|
|
68
|
+
const oni = new OniPinClient({
|
|
69
|
+
baseUrl: "https://onnivers.store",
|
|
70
|
+
pin: "onp_tu_pin",
|
|
71
|
+
agent: { name: "CursorAgent", version: "1.0" },
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await oni.ping();
|
|
75
|
+
await oni.handshake("business.chat");
|
|
76
|
+
await oni.catalog();
|
|
77
|
+
|
|
78
|
+
const chat = await oni.chat("Hola, ¿qué servicios ofrecen?");
|
|
79
|
+
await oni.messages({ limit: 10 });
|
|
28
80
|
|
|
29
|
-
|
|
81
|
+
await oni.createBooking({
|
|
30
82
|
service: "Consulta",
|
|
31
83
|
scheduledLabel: "2026-07-20 15:00",
|
|
32
84
|
clientName: "Ana",
|
|
33
85
|
clientContact: "ana@email.com",
|
|
34
86
|
});
|
|
35
|
-
|
|
36
|
-
const order = await oni.createOrder({
|
|
37
|
-
productName: "Plan Pro",
|
|
38
|
-
quantity: 1,
|
|
39
|
-
clientName: "Ana",
|
|
40
|
-
});
|
|
41
87
|
```
|
|
42
88
|
|
|
43
|
-
##
|
|
89
|
+
## Alternativas
|
|
44
90
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
| `catalog()` | Productos/servicios activos |
|
|
49
|
-
| `chat(message)` | Envía mensaje y mantiene `conversationId` |
|
|
50
|
-
| `messages({ after, limit })` | Lee el hilo |
|
|
51
|
-
| `createBooking(...)` | Reserva real en BD |
|
|
52
|
-
| `createOrder(...)` | Pedido real en BD |
|
|
53
|
-
| `reset()` | Nueva conversación |
|
|
91
|
+
- **MCP (IAs):** `https://onnivers.store/mcp` — herramientas `descubrir_url`, `handshake`, `enviar_mensaje`
|
|
92
|
+
- **HTTP directo:** `GET/POST https://onnivers.store/v1/...`
|
|
93
|
+
- **Well-known:** `GET https://onnivers.store/.well-known/onipin`
|
|
54
94
|
|
|
55
95
|
## Licencia
|
|
56
96
|
|
package/dist/index.d.ts
CHANGED
|
@@ -15,9 +15,23 @@ export type OniPinClientOptions = {
|
|
|
15
15
|
callerType?: "human" | "ai-agent";
|
|
16
16
|
/** Nombre visible del llamador */
|
|
17
17
|
callerName?: string;
|
|
18
|
+
/** Agente externo (handshake OniPin 0.2) */
|
|
19
|
+
agent?: {
|
|
20
|
+
name: string;
|
|
21
|
+
version?: string;
|
|
22
|
+
};
|
|
18
23
|
/** fetch personalizado (p. ej. undici, timeout wrappers) */
|
|
19
24
|
fetch?: typeof globalThis.fetch;
|
|
20
25
|
};
|
|
26
|
+
export type OniIntent = "business.chat" | "appointment.create" | "appointment.status" | "order.create" | "product.price" | "product.info" | "catalog.browse" | "payment.info" | string;
|
|
27
|
+
export type ChatOptions = {
|
|
28
|
+
conversationId?: string | null;
|
|
29
|
+
intent?: OniIntent;
|
|
30
|
+
agent?: {
|
|
31
|
+
name: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
21
35
|
export type PingResult = {
|
|
22
36
|
ok: true;
|
|
23
37
|
protocol: string;
|
|
@@ -25,8 +39,31 @@ export type PingResult = {
|
|
|
25
39
|
name: string;
|
|
26
40
|
description?: string;
|
|
27
41
|
language?: string;
|
|
28
|
-
capabilities
|
|
42
|
+
capabilities?: string[];
|
|
43
|
+
supports?: string[];
|
|
29
44
|
mcp?: string;
|
|
45
|
+
handshake_endpoint?: string;
|
|
46
|
+
};
|
|
47
|
+
export type DiscoverResult = {
|
|
48
|
+
ok: boolean;
|
|
49
|
+
found: boolean;
|
|
50
|
+
pin?: string;
|
|
51
|
+
source?: string;
|
|
52
|
+
url?: string;
|
|
53
|
+
discovery?: Record<string, unknown>;
|
|
54
|
+
handshake_url?: string;
|
|
55
|
+
};
|
|
56
|
+
export type HandshakeResult = {
|
|
57
|
+
ok: true;
|
|
58
|
+
protocol: string;
|
|
59
|
+
handshake: string;
|
|
60
|
+
agent?: {
|
|
61
|
+
name: string;
|
|
62
|
+
version?: string | null;
|
|
63
|
+
} | null;
|
|
64
|
+
intent?: string | null;
|
|
65
|
+
supports?: string[];
|
|
66
|
+
endpoint?: string;
|
|
30
67
|
};
|
|
31
68
|
export type CatalogItem = {
|
|
32
69
|
id: string;
|
|
@@ -47,6 +84,11 @@ export type ChatResult = {
|
|
|
47
84
|
ok: true;
|
|
48
85
|
protocol: string;
|
|
49
86
|
conversationId: string;
|
|
87
|
+
handshake?: {
|
|
88
|
+
accepted: boolean;
|
|
89
|
+
agent?: unknown;
|
|
90
|
+
intent?: string | null;
|
|
91
|
+
};
|
|
50
92
|
reply: {
|
|
51
93
|
id?: string;
|
|
52
94
|
text: string;
|
|
@@ -65,12 +107,23 @@ export declare class OniPinClient {
|
|
|
65
107
|
readonly pin: string;
|
|
66
108
|
readonly callerType: "human" | "ai-agent";
|
|
67
109
|
readonly callerName?: string;
|
|
110
|
+
readonly agent?: {
|
|
111
|
+
name: string;
|
|
112
|
+
version?: string;
|
|
113
|
+
};
|
|
68
114
|
conversationId: string | null;
|
|
69
115
|
private readonly _fetch;
|
|
70
116
|
constructor(opts: OniPinClientOptions);
|
|
71
117
|
private request;
|
|
72
118
|
/** Discovery del negocio (GET /v1/ping/:pin). */
|
|
73
119
|
ping(): Promise<PingResult>;
|
|
120
|
+
/** Descubrir pin desde URL de un sitio (GET /v1/discover?url=). */
|
|
121
|
+
discoverFromUrl(url: string): Promise<DiscoverResult>;
|
|
122
|
+
/** Handshake OniPin 0.2 — anuncia agente e intención. */
|
|
123
|
+
handshake(intent?: OniIntent, agent?: {
|
|
124
|
+
name: string;
|
|
125
|
+
version?: string;
|
|
126
|
+
}): Promise<HandshakeResult>;
|
|
74
127
|
/** Catálogo público de productos/servicios. */
|
|
75
128
|
catalog(): Promise<{
|
|
76
129
|
ok: true;
|
|
@@ -78,7 +131,7 @@ export declare class OniPinClient {
|
|
|
78
131
|
business?: string;
|
|
79
132
|
}>;
|
|
80
133
|
/** Envía un mensaje y mantiene conversationId entre llamadas. */
|
|
81
|
-
chat(message: string,
|
|
134
|
+
chat(message: string, opts?: ChatOptions): Promise<ChatResult>;
|
|
82
135
|
/** Lee mensajes del hilo (con cursor `after` y `limit` opcionales). */
|
|
83
136
|
messages(opts?: {
|
|
84
137
|
conversationId?: string;
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ export class OniPinClient {
|
|
|
21
21
|
pin;
|
|
22
22
|
callerType;
|
|
23
23
|
callerName;
|
|
24
|
+
agent;
|
|
24
25
|
conversationId = null;
|
|
25
26
|
_fetch;
|
|
26
27
|
constructor(opts) {
|
|
@@ -30,6 +31,7 @@ export class OniPinClient {
|
|
|
30
31
|
this.pin = opts.pin;
|
|
31
32
|
this.callerType = opts.callerType || "ai-agent";
|
|
32
33
|
this.callerName = opts.callerName;
|
|
34
|
+
this.agent = opts.agent || (opts.callerName ? { name: opts.callerName } : undefined);
|
|
33
35
|
this._fetch = opts.fetch || globalThis.fetch.bind(globalThis);
|
|
34
36
|
}
|
|
35
37
|
async request(path, init) {
|
|
@@ -50,19 +52,39 @@ export class OniPinClient {
|
|
|
50
52
|
ping() {
|
|
51
53
|
return this.request(`/v1/ping/${encodeURIComponent(this.pin)}`);
|
|
52
54
|
}
|
|
55
|
+
/** Descubrir pin desde URL de un sitio (GET /v1/discover?url=). */
|
|
56
|
+
discoverFromUrl(url) {
|
|
57
|
+
return this.request(`/v1/discover?url=${encodeURIComponent(url)}`);
|
|
58
|
+
}
|
|
59
|
+
/** Handshake OniPin 0.2 — anuncia agente e intención. */
|
|
60
|
+
handshake(intent, agent) {
|
|
61
|
+
const a = agent || this.agent;
|
|
62
|
+
return this.request(`/v1/handshake/${encodeURIComponent(this.pin)}`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: { "X-Caller-Type": this.callerType },
|
|
65
|
+
body: JSON.stringify({ agent: a, intent: intent || "business.chat" }),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
53
68
|
/** Catálogo público de productos/servicios. */
|
|
54
69
|
async catalog() {
|
|
55
70
|
return this.request(`/v1/catalog/${encodeURIComponent(this.pin)}`);
|
|
56
71
|
}
|
|
57
72
|
/** Envía un mensaje y mantiene conversationId entre llamadas. */
|
|
58
|
-
async chat(message,
|
|
73
|
+
async chat(message, opts = {}) {
|
|
74
|
+
const agent = opts.agent || this.agent;
|
|
59
75
|
const result = await this.request(`/v1/chat/${encodeURIComponent(this.pin)}`, {
|
|
60
76
|
method: "POST",
|
|
61
|
-
headers: {
|
|
77
|
+
headers: {
|
|
78
|
+
"X-Caller-Type": this.callerType,
|
|
79
|
+
...(opts.intent ? { "X-Oni-Intent": String(opts.intent) } : {}),
|
|
80
|
+
...(agent?.name ? { "X-Oni-Agent": agent.name } : {}),
|
|
81
|
+
},
|
|
62
82
|
body: JSON.stringify({
|
|
63
83
|
message,
|
|
64
|
-
conversationId: conversationId ?? this.conversationId,
|
|
65
|
-
callerName: this.callerName,
|
|
84
|
+
conversationId: opts.conversationId ?? this.conversationId,
|
|
85
|
+
callerName: agent?.name || this.callerName,
|
|
86
|
+
agent,
|
|
87
|
+
intent: opts.intent,
|
|
66
88
|
}),
|
|
67
89
|
});
|
|
68
90
|
this.conversationId = result.conversationId;
|