edgee 0.1.0 → 0.1.2
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 +56 -65
- package/dist/index.d.ts +38 -2
- package/dist/index.js +124 -6
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
# Edgee
|
|
1
|
+
# Edgee TypeScript SDK
|
|
2
2
|
|
|
3
|
-
Lightweight TypeScript SDK for Edgee AI Gateway.
|
|
3
|
+
Lightweight, type-safe TypeScript SDK for the [Edgee AI Gateway](https://www.edgee.cloud).
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/edgee)
|
|
6
|
+
[](LICENSE)
|
|
4
7
|
|
|
5
8
|
## Installation
|
|
6
9
|
|
|
@@ -8,88 +11,76 @@ Lightweight TypeScript SDK for Edgee AI Gateway.
|
|
|
8
11
|
npm install edgee
|
|
9
12
|
```
|
|
10
13
|
|
|
11
|
-
##
|
|
14
|
+
## Quick Start
|
|
12
15
|
|
|
13
16
|
```typescript
|
|
14
|
-
import Edgee from
|
|
15
|
-
|
|
16
|
-
const edgee = new Edgee(process.env.EDGEE_API_KEY);
|
|
17
|
-
```
|
|
17
|
+
import Edgee from 'edgee';
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const edgee = new Edgee("your-api-key");
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Send a simple request
|
|
22
22
|
const response = await edgee.send({
|
|
23
|
-
model:
|
|
24
|
-
input:
|
|
23
|
+
model: 'gpt-4o',
|
|
24
|
+
input: 'What is the capital of France?',
|
|
25
25
|
});
|
|
26
26
|
|
|
27
|
-
console.log(response.
|
|
27
|
+
console.log(response.text);
|
|
28
|
+
// "The capital of France is Paris."
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
const response = await edgee.send({
|
|
34
|
-
model: "gpt-4o",
|
|
35
|
-
input: {
|
|
36
|
-
messages: [
|
|
37
|
-
{ role: "system", content: "You are a helpful assistant." },
|
|
38
|
-
{ role: "user", content: "Hello!" },
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
```
|
|
31
|
+
## Send Method
|
|
43
32
|
|
|
44
|
-
|
|
33
|
+
The `send()` method makes non-streaming chat completion requests:
|
|
45
34
|
|
|
46
35
|
```typescript
|
|
47
36
|
const response = await edgee.send({
|
|
48
|
-
model:
|
|
49
|
-
input:
|
|
50
|
-
messages: [{ role: "user", content: "What's the weather in Paris?" }],
|
|
51
|
-
tools: [
|
|
52
|
-
{
|
|
53
|
-
type: "function",
|
|
54
|
-
function: {
|
|
55
|
-
name: "get_weather",
|
|
56
|
-
description: "Get weather for a location",
|
|
57
|
-
parameters: {
|
|
58
|
-
type: "object",
|
|
59
|
-
properties: {
|
|
60
|
-
location: { type: "string" },
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
tool_choice: "auto",
|
|
67
|
-
},
|
|
37
|
+
model: 'gpt-4o',
|
|
38
|
+
input: 'Hello, world!',
|
|
68
39
|
});
|
|
69
40
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
41
|
+
// Access response
|
|
42
|
+
console.log(response.text); // Text content
|
|
43
|
+
console.log(response.finishReason); // Finish reason
|
|
44
|
+
console.log(response.toolCalls); // Tool calls (if any)
|
|
73
45
|
```
|
|
74
46
|
|
|
75
|
-
##
|
|
47
|
+
## Stream Method
|
|
48
|
+
|
|
49
|
+
The `stream()` method enables real-time streaming responses:
|
|
76
50
|
|
|
77
51
|
```typescript
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
finish_reason: string | null;
|
|
87
|
-
}[];
|
|
88
|
-
usage?: {
|
|
89
|
-
prompt_tokens: number;
|
|
90
|
-
completion_tokens: number;
|
|
91
|
-
total_tokens: number;
|
|
92
|
-
};
|
|
52
|
+
for await (const chunk of edgee.stream('gpt-4o', 'Tell me a story')) {
|
|
53
|
+
if (chunk.text) {
|
|
54
|
+
process.stdout.write(chunk.text);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (chunk.finishReason) {
|
|
58
|
+
console.log(`\nFinished: ${chunk.finishReason}`);
|
|
59
|
+
}
|
|
93
60
|
}
|
|
94
61
|
```
|
|
95
62
|
|
|
63
|
+
## Features
|
|
64
|
+
|
|
65
|
+
- ✅ **Type-safe** - Full TypeScript support with comprehensive types
|
|
66
|
+
- ✅ **OpenAI-compatible** - Works with any model supported by Edgee
|
|
67
|
+
- ✅ **Streaming** - Real-time response streaming
|
|
68
|
+
- ✅ **Tool calling** - Full support for function calling
|
|
69
|
+
- ✅ **Flexible input** - Accept strings or structured objects
|
|
70
|
+
- ✅ **Zero dependencies** - Lightweight and fast
|
|
71
|
+
|
|
72
|
+
## Documentation
|
|
73
|
+
|
|
74
|
+
For complete documentation, examples, and API reference, visit:
|
|
75
|
+
|
|
76
|
+
**👉 [Official TypeScript SDK Documentation](https://www.edgee.cloud/docs/sdk/typescript)**
|
|
77
|
+
|
|
78
|
+
The documentation includes:
|
|
79
|
+
- [Configuration guide](https://www.edgee.cloud/docs/sdk/typescript/configuration) - Multiple ways to configure the SDK
|
|
80
|
+
- [Send method](https://www.edgee.cloud/docs/sdk/typescript/send) - Complete guide to non-streaming requests
|
|
81
|
+
- [Stream method](https://www.edgee.cloud/docs/sdk/typescript/stream) - Streaming responses guide
|
|
82
|
+
- [Tools](https://www.edgee.cloud/docs/sdk/typescript/tools) - Function calling guide
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
|
package/dist/index.d.ts
CHANGED
|
@@ -47,17 +47,53 @@ export interface Choice {
|
|
|
47
47
|
};
|
|
48
48
|
finish_reason: string | null;
|
|
49
49
|
}
|
|
50
|
-
export
|
|
50
|
+
export declare class SendResponse {
|
|
51
51
|
choices: Choice[];
|
|
52
52
|
usage?: {
|
|
53
53
|
prompt_tokens: number;
|
|
54
54
|
completion_tokens: number;
|
|
55
55
|
total_tokens: number;
|
|
56
56
|
};
|
|
57
|
+
constructor(choices: Choice[], usage?: {
|
|
58
|
+
prompt_tokens: number;
|
|
59
|
+
completion_tokens: number;
|
|
60
|
+
total_tokens: number;
|
|
61
|
+
});
|
|
62
|
+
get text(): string | null;
|
|
63
|
+
get message(): {
|
|
64
|
+
role: string;
|
|
65
|
+
content: string | null;
|
|
66
|
+
tool_calls?: ToolCall[];
|
|
67
|
+
};
|
|
68
|
+
get finishReason(): string | null;
|
|
69
|
+
get toolCalls(): ToolCall[] | null;
|
|
70
|
+
}
|
|
71
|
+
export interface StreamDelta {
|
|
72
|
+
role?: string;
|
|
73
|
+
content?: string;
|
|
74
|
+
tool_calls?: ToolCall[];
|
|
75
|
+
}
|
|
76
|
+
export interface StreamChoice {
|
|
77
|
+
index: number;
|
|
78
|
+
delta: StreamDelta;
|
|
79
|
+
finish_reason?: string | null;
|
|
80
|
+
}
|
|
81
|
+
export declare class StreamChunk {
|
|
82
|
+
choices: StreamChoice[];
|
|
83
|
+
constructor(choices: StreamChoice[]);
|
|
84
|
+
get text(): string | null;
|
|
85
|
+
get role(): string | null;
|
|
86
|
+
get finishReason(): string | null;
|
|
87
|
+
}
|
|
88
|
+
export interface EdgeeConfig {
|
|
89
|
+
apiKey?: string;
|
|
90
|
+
baseUrl?: string;
|
|
57
91
|
}
|
|
58
92
|
export default class Edgee {
|
|
59
93
|
private apiKey;
|
|
60
94
|
private baseUrl;
|
|
61
|
-
constructor(
|
|
95
|
+
constructor(config?: string | EdgeeConfig);
|
|
62
96
|
send(options: SendOptions): Promise<SendResponse>;
|
|
97
|
+
private _handleStreamingResponse;
|
|
98
|
+
stream(model: string, input: string | InputObject): AsyncGenerator<StreamChunk>;
|
|
63
99
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,65 @@
|
|
|
1
|
+
export class SendResponse {
|
|
2
|
+
constructor(choices, usage) {
|
|
3
|
+
this.choices = choices;
|
|
4
|
+
this.usage = usage;
|
|
5
|
+
}
|
|
6
|
+
get text() {
|
|
7
|
+
if (this.choices[0]?.message?.content) {
|
|
8
|
+
return this.choices[0].message.content;
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
get message() {
|
|
13
|
+
return this.choices[0]?.message ?? null;
|
|
14
|
+
}
|
|
15
|
+
get finishReason() {
|
|
16
|
+
return this.choices[0]?.finish_reason ?? null;
|
|
17
|
+
}
|
|
18
|
+
get toolCalls() {
|
|
19
|
+
return this.choices[0]?.message?.tool_calls ?? null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class StreamChunk {
|
|
23
|
+
constructor(choices) {
|
|
24
|
+
this.choices = choices;
|
|
25
|
+
}
|
|
26
|
+
get text() {
|
|
27
|
+
if (this.choices[0]?.delta?.content) {
|
|
28
|
+
return this.choices[0].delta.content;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
get role() {
|
|
33
|
+
if (this.choices[0]?.delta?.role) {
|
|
34
|
+
return this.choices[0].delta.role;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
get finishReason() {
|
|
39
|
+
if (this.choices[0]?.finish_reason) {
|
|
40
|
+
return this.choices[0].finish_reason;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
1
45
|
export default class Edgee {
|
|
2
|
-
constructor(
|
|
3
|
-
|
|
46
|
+
constructor(config) {
|
|
47
|
+
let apiKey;
|
|
48
|
+
let baseUrl;
|
|
49
|
+
if (typeof config === "string") {
|
|
50
|
+
// Backward compatibility: accept apiKey as string
|
|
51
|
+
apiKey = config;
|
|
52
|
+
}
|
|
53
|
+
else if (config) {
|
|
54
|
+
// New format: accept config object
|
|
55
|
+
apiKey = config.apiKey;
|
|
56
|
+
baseUrl = config.baseUrl;
|
|
57
|
+
}
|
|
4
58
|
this.apiKey = apiKey || process.env.EDGEE_API_KEY || "";
|
|
5
59
|
if (!this.apiKey) {
|
|
6
60
|
throw new Error("EDGEE_API_KEY is not set");
|
|
7
61
|
}
|
|
62
|
+
this.baseUrl = baseUrl || process.env.EDGEE_BASE_URL || "https://api.edgee.ai";
|
|
8
63
|
}
|
|
9
64
|
async send(options) {
|
|
10
65
|
const { input } = options;
|
|
@@ -28,10 +83,73 @@ export default class Edgee {
|
|
|
28
83
|
},
|
|
29
84
|
body: JSON.stringify(body),
|
|
30
85
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
86
|
+
if (!res.ok) {
|
|
87
|
+
const errorBody = await res.text();
|
|
88
|
+
throw new Error(`API error ${res.status}: ${errorBody}`);
|
|
89
|
+
}
|
|
90
|
+
const data = await res.json();
|
|
91
|
+
return new SendResponse(data.choices, data.usage);
|
|
92
|
+
}
|
|
93
|
+
async *_handleStreamingResponse(url, body) {
|
|
94
|
+
const res = await fetch(url, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json",
|
|
98
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify(body),
|
|
101
|
+
});
|
|
102
|
+
if (!res.ok) {
|
|
103
|
+
const errorBody = await res.text();
|
|
104
|
+
throw new Error(`API error ${res.status}: ${errorBody}`);
|
|
105
|
+
}
|
|
106
|
+
if (!res.body) {
|
|
107
|
+
throw new Error("Response body is null");
|
|
108
|
+
}
|
|
109
|
+
const reader = res.body.getReader();
|
|
110
|
+
const decoder = new TextDecoder();
|
|
111
|
+
let buffer = "";
|
|
112
|
+
while (true) {
|
|
113
|
+
const { done, value } = await reader.read();
|
|
114
|
+
if (done)
|
|
115
|
+
break;
|
|
116
|
+
buffer += decoder.decode(value, { stream: true });
|
|
117
|
+
const lines = buffer.split("\n");
|
|
118
|
+
buffer = lines.pop() || "";
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
const trimmed = line.trim();
|
|
121
|
+
if (trimmed === "" || !trimmed.startsWith("data: ")) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const data = trimmed.slice(6);
|
|
125
|
+
if (data === "[DONE]") {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(data);
|
|
130
|
+
yield new StreamChunk(parsed.choices);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Skip malformed JSON
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async *stream(model, input) {
|
|
140
|
+
const body = {
|
|
141
|
+
model,
|
|
142
|
+
messages: typeof input === "string"
|
|
143
|
+
? [{ role: "user", content: input }]
|
|
144
|
+
: input.messages,
|
|
145
|
+
stream: true,
|
|
35
146
|
};
|
|
147
|
+
if (typeof input !== "string") {
|
|
148
|
+
if (input.tools)
|
|
149
|
+
body.tools = input.tools;
|
|
150
|
+
if (input.tool_choice)
|
|
151
|
+
body.tool_choice = input.tool_choice;
|
|
152
|
+
}
|
|
153
|
+
yield* this._handleStreamingResponse(`${this.baseUrl}/v1/chat/completions`, body);
|
|
36
154
|
}
|
|
37
155
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edgee",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/edgee-cloud/typescript-sdk"
|
|
10
|
+
},
|
|
7
11
|
"exports": {
|
|
8
12
|
".": {
|
|
9
13
|
"types": "./dist/index.d.ts",
|