sammy-sdk-client 0.1.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 +82 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +66 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/stream.d.ts +3 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +130 -0
- package/dist/stream.js.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# sammy-sdk-client
|
|
2
|
+
|
|
3
|
+
Zero-dependency JavaScript client for the [Sammy](https://sammy.dev) AI agent runtime. Works in any framework — React, Vue, Svelte, vanilla — and in any modern JavaScript runtime (browser, Node 18+, edge).
|
|
4
|
+
|
|
5
|
+
`sammy-sdk-client` is the framework-agnostic transport layer. It speaks to the chat endpoint your server exposes (typically backed by [`sammy-sdk`](https://www.npmjs.com/package/sammy-sdk)'s `createSammyRouteHandler`) and handles JSON requests, conversation IDs, and SSE streaming.
|
|
6
|
+
|
|
7
|
+
For React-specific helpers see [`sammy-sdk-react`](https://www.npmjs.com/package/sammy-sdk-react). For a drop-in chat widget see [`sammy-sdk-ui`](https://www.npmjs.com/package/sammy-sdk-ui).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install sammy-sdk-client
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
You'll also need a chat endpoint on your backend. The fastest way is `createSammyRouteHandler` from `sammy-sdk`:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// app/api/chat/route.ts (Next.js App Router)
|
|
19
|
+
import { Sammy, createSammyRouteHandler } from "sammy-sdk";
|
|
20
|
+
const sammy = new Sammy();
|
|
21
|
+
export const POST = createSammyRouteHandler(sammy);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { SammyClient } from "sammy-sdk-client";
|
|
28
|
+
|
|
29
|
+
const client = new SammyClient({
|
|
30
|
+
endpoint: "/api/chat",
|
|
31
|
+
// Optional: custom headers (object or async function)
|
|
32
|
+
headers: async () => ({ Authorization: `Bearer ${await getToken()}` }),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// One-shot request/response (returns the full ChatResponse)
|
|
36
|
+
const reply = await client.chat("List all open deals");
|
|
37
|
+
console.log(reply.message);
|
|
38
|
+
|
|
39
|
+
// Streaming
|
|
40
|
+
const stream = client.stream("Summarise this week's pipeline");
|
|
41
|
+
stream
|
|
42
|
+
.on("text", (chunk) => process.stdout.write(chunk))
|
|
43
|
+
.on("tool_call", (call) => console.log("calling tool:", call.name))
|
|
44
|
+
.on("tool_result", (r) => console.log("tool", r.name, "->", r.result.success))
|
|
45
|
+
.on("agent_handoff", (h) => console.log("handed off to:", h.targetAgent))
|
|
46
|
+
.on("done", (final) => console.log("\ntools used:", final.toolsUsed.length))
|
|
47
|
+
.on("error", (err) => console.error(err));
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Conversations
|
|
51
|
+
|
|
52
|
+
`client.conversation(id?)` gives you a scoped object that re-uses the same `conversationId` across calls — useful for chat threads.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const thread = client.conversation();
|
|
56
|
+
await thread.send("hi");
|
|
57
|
+
await thread.send("what did I just say?");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## API surface
|
|
61
|
+
|
|
62
|
+
- `new SammyClient(config)`
|
|
63
|
+
- `client.chat(message, options?)` — `Promise<ChatResponse>` (one-shot JSON; the server must speak JSON for this path — `createSammyRouteHandler` does)
|
|
64
|
+
- `client.stream(message, options?)` — `SammyStream` (event emitter)
|
|
65
|
+
- `client.conversation(id?)` — convenience scope for a single conversation
|
|
66
|
+
|
|
67
|
+
`SammyStream` events:
|
|
68
|
+
|
|
69
|
+
| Event | Handler argument |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `text` | `string` chunk to append to the assistant message |
|
|
72
|
+
| `tool_call` | `ToolCallEvent` — `{ id, name, params }` |
|
|
73
|
+
| `tool_result` | `ToolResultEvent` — `{ id, name, result: { success, data?, error? } }` |
|
|
74
|
+
| `agent_handoff` | `AgentHandoffEvent` — `{ fromAgent, targetAgent, reason }` (multi-agent only) |
|
|
75
|
+
| `done` | the full `ChatResponse` |
|
|
76
|
+
| `error` | a real `Error` instance |
|
|
77
|
+
|
|
78
|
+
All exported types — `SammyClientConfig`, `ChatOptions`, `ChatResponse`, `SammyStream`, `ToolCallEvent`, `ToolResultEvent`, `ToolResult`, `ToolCallResult`, `AgentHandoffEvent`, `Attachment` — are exported from the package root.
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SammyClientConfig, ChatOptions, ChatResponse, SammyStream } from "./types";
|
|
2
|
+
export declare class SammyClient {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: SammyClientConfig);
|
|
5
|
+
chat(message: string, options?: ChatOptions): Promise<ChatResponse>;
|
|
6
|
+
stream(message: string, options?: ChatOptions): SammyStream;
|
|
7
|
+
conversation(id?: string): {
|
|
8
|
+
id: string;
|
|
9
|
+
send: (message: string) => Promise<ChatResponse>;
|
|
10
|
+
stream: (message: string) => SammyStream;
|
|
11
|
+
};
|
|
12
|
+
private resolveHeaders;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGzF,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAoB;gBAEtB,MAAM,EAAE,iBAAiB;IAQ/B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAwCzE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW;IAI3D,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM;;wBAIJ,MAAM;0BACJ,MAAM;;YAId,cAAc;CAK7B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SammyClient = void 0;
|
|
4
|
+
const stream_1 = require("./stream");
|
|
5
|
+
class SammyClient {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = {
|
|
9
|
+
retries: 3,
|
|
10
|
+
timeout: 30000,
|
|
11
|
+
...config,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async chat(message, options) {
|
|
15
|
+
const headers = await this.resolveHeaders();
|
|
16
|
+
const response = await fetch(this.config.endpoint, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
Accept: "application/json",
|
|
21
|
+
...headers,
|
|
22
|
+
},
|
|
23
|
+
body: JSON.stringify({
|
|
24
|
+
message,
|
|
25
|
+
conversationId: options?.conversationId || this.config.conversationId,
|
|
26
|
+
metadata: options?.metadata,
|
|
27
|
+
attachments: options?.attachments,
|
|
28
|
+
}),
|
|
29
|
+
signal: AbortSignal.timeout(this.config.timeout),
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const text = await response.text().catch(() => "");
|
|
33
|
+
throw new Error(`Sammy request failed: ${response.status} ${response.statusText}${text ? ` - ${text}` : ""}`);
|
|
34
|
+
}
|
|
35
|
+
const contentType = response.headers.get("content-type") || "";
|
|
36
|
+
if (!contentType.includes("application/json")) {
|
|
37
|
+
const text = await response.text().catch(() => "");
|
|
38
|
+
throw new Error(`Expected JSON from chat endpoint but got "${contentType}". ` +
|
|
39
|
+
`If you're using the Sammy SDK route handler, this should not happen — ` +
|
|
40
|
+
`make sure your /api/chat route uses createSammyRouteHandler() from sammy-sdk, ` +
|
|
41
|
+
`or use client.stream() instead of client.chat() for SSE-only endpoints. ` +
|
|
42
|
+
`Body preview: ${text.slice(0, 200)}`);
|
|
43
|
+
}
|
|
44
|
+
return response.json();
|
|
45
|
+
}
|
|
46
|
+
stream(message, options) {
|
|
47
|
+
return (0, stream_1.createStream)(this.config, message, options);
|
|
48
|
+
}
|
|
49
|
+
conversation(id) {
|
|
50
|
+
const conversationId = id || crypto.randomUUID();
|
|
51
|
+
return {
|
|
52
|
+
id: conversationId,
|
|
53
|
+
send: (message) => this.chat(message, { conversationId }),
|
|
54
|
+
stream: (message) => this.stream(message, { conversationId }),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async resolveHeaders() {
|
|
58
|
+
if (!this.config.headers)
|
|
59
|
+
return {};
|
|
60
|
+
if (typeof this.config.headers === "function")
|
|
61
|
+
return this.config.headers();
|
|
62
|
+
return this.config.headers;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.SammyClient = SammyClient;
|
|
66
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,YAAY,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,WAAW,EACX,aAAa,EACb,eAAe,EACf,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,UAAU,GACX,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SammyClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "SammyClient", { enumerable: true, get: function () { return client_1.SammyClient; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAuC;AAA9B,qGAAA,WAAW,OAAA"}
|
package/dist/stream.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAgB,WAAW,EAAqD,MAAM,SAAS,CAAC;AAmB5I,wBAAgB,YAAY,CAC1B,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,WAAW,GACpB,WAAW,CA8Gb"}
|
package/dist/stream.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createStream = createStream;
|
|
4
|
+
function coerceError(payload) {
|
|
5
|
+
if (payload instanceof Error)
|
|
6
|
+
return payload;
|
|
7
|
+
if (typeof payload === "string")
|
|
8
|
+
return new Error(payload);
|
|
9
|
+
if (payload && typeof payload === "object") {
|
|
10
|
+
const message = payload.message;
|
|
11
|
+
if (typeof message === "string")
|
|
12
|
+
return new Error(message);
|
|
13
|
+
try {
|
|
14
|
+
return new Error(JSON.stringify(payload));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return new Error("Unknown error");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return new Error("Unknown error");
|
|
21
|
+
}
|
|
22
|
+
function createStream(config, message, options) {
|
|
23
|
+
const handlers = {};
|
|
24
|
+
let abortController = new AbortController();
|
|
25
|
+
let finalResponse = null;
|
|
26
|
+
const emit = (event, payload) => {
|
|
27
|
+
const list = handlers[event];
|
|
28
|
+
if (!list)
|
|
29
|
+
return;
|
|
30
|
+
for (const handler of list) {
|
|
31
|
+
try {
|
|
32
|
+
handler(payload);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Swallow handler errors so one bad listener doesn't kill the stream.
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const stream = {
|
|
40
|
+
on(event, handler) {
|
|
41
|
+
if (!handlers[event])
|
|
42
|
+
handlers[event] = [];
|
|
43
|
+
handlers[event].push(handler);
|
|
44
|
+
return stream;
|
|
45
|
+
},
|
|
46
|
+
abort() {
|
|
47
|
+
abortController?.abort();
|
|
48
|
+
abortController = null;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
(async () => {
|
|
52
|
+
try {
|
|
53
|
+
const headersFn = config.headers;
|
|
54
|
+
const resolvedHeaders = headersFn
|
|
55
|
+
? typeof headersFn === "function" ? await headersFn() : headersFn
|
|
56
|
+
: {};
|
|
57
|
+
const response = await fetch(config.endpoint, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { "Content-Type": "application/json", Accept: "text/event-stream", ...resolvedHeaders },
|
|
60
|
+
body: JSON.stringify({
|
|
61
|
+
message,
|
|
62
|
+
conversationId: options?.conversationId || config.conversationId,
|
|
63
|
+
stream: true,
|
|
64
|
+
metadata: options?.metadata,
|
|
65
|
+
}),
|
|
66
|
+
signal: abortController?.signal,
|
|
67
|
+
});
|
|
68
|
+
if (!response.ok || !response.body) {
|
|
69
|
+
throw new Error(`Stream failed: ${response.status} ${response.statusText}`);
|
|
70
|
+
}
|
|
71
|
+
const reader = response.body.getReader();
|
|
72
|
+
const decoder = new TextDecoder();
|
|
73
|
+
let buffer = "";
|
|
74
|
+
while (true) {
|
|
75
|
+
const { done, value } = await reader.read();
|
|
76
|
+
if (done)
|
|
77
|
+
break;
|
|
78
|
+
buffer += decoder.decode(value, { stream: true });
|
|
79
|
+
const lines = buffer.split("\n");
|
|
80
|
+
buffer = lines.pop() || "";
|
|
81
|
+
for (const line of lines) {
|
|
82
|
+
if (!line.startsWith("data: "))
|
|
83
|
+
continue;
|
|
84
|
+
const data = line.slice(6);
|
|
85
|
+
if (data === "[DONE]")
|
|
86
|
+
continue;
|
|
87
|
+
let event;
|
|
88
|
+
try {
|
|
89
|
+
event = JSON.parse(data);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
switch (event.type) {
|
|
95
|
+
case "text":
|
|
96
|
+
if (typeof event.data === "string")
|
|
97
|
+
emit("text", event.data);
|
|
98
|
+
break;
|
|
99
|
+
case "tool_call":
|
|
100
|
+
emit("tool_call", event.data);
|
|
101
|
+
break;
|
|
102
|
+
case "tool_result":
|
|
103
|
+
emit("tool_result", event.data);
|
|
104
|
+
break;
|
|
105
|
+
case "agent_handoff":
|
|
106
|
+
emit("agent_handoff", event.data);
|
|
107
|
+
break;
|
|
108
|
+
case "done":
|
|
109
|
+
finalResponse = event.data;
|
|
110
|
+
break;
|
|
111
|
+
case "error":
|
|
112
|
+
emit("error", coerceError(event.data));
|
|
113
|
+
break;
|
|
114
|
+
default:
|
|
115
|
+
// Forward-compatible: ignore unknown event types.
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
emit("done", finalResponse ?? {});
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.name === "AbortError")
|
|
124
|
+
return;
|
|
125
|
+
emit("error", coerceError(error));
|
|
126
|
+
}
|
|
127
|
+
})();
|
|
128
|
+
return stream;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface SammyClientConfig {
|
|
2
|
+
endpoint: string;
|
|
3
|
+
headers?: Record<string, string> | (() => Promise<Record<string, string>>);
|
|
4
|
+
conversationId?: string;
|
|
5
|
+
retries?: number;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ChatOptions {
|
|
9
|
+
conversationId?: string;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
attachments?: Attachment[];
|
|
12
|
+
}
|
|
13
|
+
export interface Attachment {
|
|
14
|
+
type: "image" | "document";
|
|
15
|
+
mimeType: string;
|
|
16
|
+
name: string;
|
|
17
|
+
data?: string;
|
|
18
|
+
url?: string;
|
|
19
|
+
extractedText?: string;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface ToolCallEvent {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
params: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
export interface ToolResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
data?: unknown;
|
|
30
|
+
error?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ToolResultEvent {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
result: ToolResult;
|
|
36
|
+
}
|
|
37
|
+
export interface AgentHandoffEvent {
|
|
38
|
+
fromAgent: string;
|
|
39
|
+
targetAgent: string;
|
|
40
|
+
reason: string;
|
|
41
|
+
}
|
|
42
|
+
export interface ToolCallResult {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
params: Record<string, unknown>;
|
|
46
|
+
success: boolean;
|
|
47
|
+
result?: unknown;
|
|
48
|
+
error?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ChatResponse {
|
|
51
|
+
message: string;
|
|
52
|
+
conversationId: string;
|
|
53
|
+
toolsUsed: ToolCallResult[];
|
|
54
|
+
agentUsed: string;
|
|
55
|
+
suggestedFollowUps: string[];
|
|
56
|
+
agentHandoff?: AgentHandoffEvent;
|
|
57
|
+
}
|
|
58
|
+
export interface SammyStream {
|
|
59
|
+
on(event: "text", handler: (chunk: string) => void): SammyStream;
|
|
60
|
+
on(event: "tool_call", handler: (call: ToolCallEvent) => void): SammyStream;
|
|
61
|
+
on(event: "tool_result", handler: (result: ToolResultEvent) => void): SammyStream;
|
|
62
|
+
on(event: "agent_handoff", handler: (handoff: AgentHandoffEvent) => void): SammyStream;
|
|
63
|
+
on(event: "done", handler: (response: ChatResponse) => void): SammyStream;
|
|
64
|
+
on(event: "error", handler: (error: Error) => void): SammyStream;
|
|
65
|
+
abort(): void;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sammy-sdk-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Zero-dependency JavaScript client for the Sammy AI agent runtime (SSE streaming, conversations, attachments).",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [
|
|
21
|
+
"sammy",
|
|
22
|
+
"sammy-sdk",
|
|
23
|
+
"ai",
|
|
24
|
+
"agent",
|
|
25
|
+
"chat",
|
|
26
|
+
"client",
|
|
27
|
+
"sse",
|
|
28
|
+
"streaming"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/sammymitch0071/sammy.git",
|
|
37
|
+
"directory": "packages/client"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/sammymitch0071/sammy/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://sammy.dev",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"rimraf": "^6.0.1",
|
|
45
|
+
"typescript": "^5.7.0"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsc",
|
|
52
|
+
"dev": "tsc --watch",
|
|
53
|
+
"clean": "rimraf dist tsconfig.tsbuildinfo"
|
|
54
|
+
}
|
|
55
|
+
}
|