@ragpipe/plugin-cloudflare 0.0.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/dist/index.cjs +166 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +138 -0
- package/package.json +61 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
cloudflareEmbedding: () => cloudflareEmbedding,
|
|
24
|
+
cloudflareGeneration: () => cloudflareGeneration
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/embedding.ts
|
|
29
|
+
var DIMENSION_MAP = {
|
|
30
|
+
"@cf/baai/bge-base-en-v1.5": 768,
|
|
31
|
+
"@cf/baai/bge-large-en-v1.5": 1024,
|
|
32
|
+
"@cf/baai/bge-small-en-v1.5": 384
|
|
33
|
+
};
|
|
34
|
+
var DEFAULT_MODEL = "@cf/baai/bge-base-en-v1.5";
|
|
35
|
+
function cloudflareEmbedding(options) {
|
|
36
|
+
const model = options.model ?? DEFAULT_MODEL;
|
|
37
|
+
const dimensions = DIMENSION_MAP[model] ?? 768;
|
|
38
|
+
const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/ai/run/${model}`;
|
|
39
|
+
async function callApi(text) {
|
|
40
|
+
const res = await fetch(baseUrl, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
44
|
+
"Content-Type": "application/json"
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify({ text })
|
|
47
|
+
});
|
|
48
|
+
if (!res.ok) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Cloudflare embedding error: ${res.status} ${await res.text()}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const data = await res.json();
|
|
54
|
+
if (!data.success) {
|
|
55
|
+
throw new Error("Cloudflare embedding error: API returned success=false");
|
|
56
|
+
}
|
|
57
|
+
return data.result.data;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
name: "cloudflare",
|
|
61
|
+
dimensions,
|
|
62
|
+
async embed(text) {
|
|
63
|
+
const vectors = await callApi([text]);
|
|
64
|
+
return vectors[0];
|
|
65
|
+
},
|
|
66
|
+
async embedMany(texts) {
|
|
67
|
+
return callApi(texts);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/generation.ts
|
|
73
|
+
var DEFAULT_MODEL2 = "@cf/meta/llama-3.1-8b-instruct";
|
|
74
|
+
function cloudflareGeneration(options) {
|
|
75
|
+
const model = options.model ?? DEFAULT_MODEL2;
|
|
76
|
+
const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/ai/run/${model}`;
|
|
77
|
+
function buildMessages(question, context, opts) {
|
|
78
|
+
const systemPrompt = opts?.systemPrompt ?? options.systemPrompt ?? "Answer based on the provided context.";
|
|
79
|
+
let userPrompt = `Context:
|
|
80
|
+
${context}
|
|
81
|
+
|
|
82
|
+
Question: ${question}`;
|
|
83
|
+
if (opts?.history) {
|
|
84
|
+
userPrompt = `Conversation history:
|
|
85
|
+
${opts.history}
|
|
86
|
+
|
|
87
|
+
${userPrompt}`;
|
|
88
|
+
}
|
|
89
|
+
return [
|
|
90
|
+
{ role: "system", content: systemPrompt },
|
|
91
|
+
{ role: "user", content: userPrompt }
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
name: "cloudflare",
|
|
96
|
+
async generate(question, context, opts) {
|
|
97
|
+
const messages = buildMessages(question, context, opts);
|
|
98
|
+
const res = await fetch(baseUrl, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers: {
|
|
101
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
102
|
+
"Content-Type": "application/json"
|
|
103
|
+
},
|
|
104
|
+
body: JSON.stringify({ messages, stream: false })
|
|
105
|
+
});
|
|
106
|
+
if (!res.ok) {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Cloudflare generation error: ${res.status} ${await res.text()}`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const data = await res.json();
|
|
112
|
+
if (!data.success) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
"Cloudflare generation error: API returned success=false"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
return data.result.response;
|
|
118
|
+
},
|
|
119
|
+
async *generateStream(question, context, opts) {
|
|
120
|
+
const messages = buildMessages(question, context, opts);
|
|
121
|
+
const res = await fetch(baseUrl, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: {
|
|
124
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
125
|
+
"Content-Type": "application/json"
|
|
126
|
+
},
|
|
127
|
+
body: JSON.stringify({ messages, stream: true })
|
|
128
|
+
});
|
|
129
|
+
if (!res.ok) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Cloudflare generation stream error: ${res.status} ${await res.text()}`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const reader = res.body?.getReader();
|
|
135
|
+
if (!reader) throw new Error("No response body");
|
|
136
|
+
const decoder = new TextDecoder();
|
|
137
|
+
let buffer = "";
|
|
138
|
+
try {
|
|
139
|
+
for (; ; ) {
|
|
140
|
+
const { done, value } = await reader.read();
|
|
141
|
+
if (done) break;
|
|
142
|
+
buffer += decoder.decode(value, { stream: true });
|
|
143
|
+
const lines = buffer.split("\n");
|
|
144
|
+
buffer = lines.pop() ?? "";
|
|
145
|
+
for (const line of lines) {
|
|
146
|
+
if (!line.startsWith("data: ")) continue;
|
|
147
|
+
const payload = line.slice(6).trim();
|
|
148
|
+
if (payload === "[DONE]") return;
|
|
149
|
+
try {
|
|
150
|
+
const data = JSON.parse(payload);
|
|
151
|
+
if (data.response) yield data.response;
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} finally {
|
|
157
|
+
reader.releaseLock();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
163
|
+
0 && (module.exports = {
|
|
164
|
+
cloudflareEmbedding,
|
|
165
|
+
cloudflareGeneration
|
|
166
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EmbeddingPlugin, GenerationPlugin } from 'ragpipe';
|
|
2
|
+
|
|
3
|
+
interface CloudflareEmbeddingOptions {
|
|
4
|
+
accountId: string;
|
|
5
|
+
apiToken: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function cloudflareEmbedding(options: CloudflareEmbeddingOptions): EmbeddingPlugin;
|
|
9
|
+
|
|
10
|
+
interface CloudflareGenerationOptions {
|
|
11
|
+
accountId: string;
|
|
12
|
+
apiToken: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
systemPrompt?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function cloudflareGeneration(options: CloudflareGenerationOptions): GenerationPlugin;
|
|
17
|
+
|
|
18
|
+
export { type CloudflareEmbeddingOptions, type CloudflareGenerationOptions, cloudflareEmbedding, cloudflareGeneration };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { EmbeddingPlugin, GenerationPlugin } from 'ragpipe';
|
|
2
|
+
|
|
3
|
+
interface CloudflareEmbeddingOptions {
|
|
4
|
+
accountId: string;
|
|
5
|
+
apiToken: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function cloudflareEmbedding(options: CloudflareEmbeddingOptions): EmbeddingPlugin;
|
|
9
|
+
|
|
10
|
+
interface CloudflareGenerationOptions {
|
|
11
|
+
accountId: string;
|
|
12
|
+
apiToken: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
systemPrompt?: string;
|
|
15
|
+
}
|
|
16
|
+
declare function cloudflareGeneration(options: CloudflareGenerationOptions): GenerationPlugin;
|
|
17
|
+
|
|
18
|
+
export { type CloudflareEmbeddingOptions, type CloudflareGenerationOptions, cloudflareEmbedding, cloudflareGeneration };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// src/embedding.ts
|
|
2
|
+
var DIMENSION_MAP = {
|
|
3
|
+
"@cf/baai/bge-base-en-v1.5": 768,
|
|
4
|
+
"@cf/baai/bge-large-en-v1.5": 1024,
|
|
5
|
+
"@cf/baai/bge-small-en-v1.5": 384
|
|
6
|
+
};
|
|
7
|
+
var DEFAULT_MODEL = "@cf/baai/bge-base-en-v1.5";
|
|
8
|
+
function cloudflareEmbedding(options) {
|
|
9
|
+
const model = options.model ?? DEFAULT_MODEL;
|
|
10
|
+
const dimensions = DIMENSION_MAP[model] ?? 768;
|
|
11
|
+
const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/ai/run/${model}`;
|
|
12
|
+
async function callApi(text) {
|
|
13
|
+
const res = await fetch(baseUrl, {
|
|
14
|
+
method: "POST",
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
17
|
+
"Content-Type": "application/json"
|
|
18
|
+
},
|
|
19
|
+
body: JSON.stringify({ text })
|
|
20
|
+
});
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Cloudflare embedding error: ${res.status} ${await res.text()}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const data = await res.json();
|
|
27
|
+
if (!data.success) {
|
|
28
|
+
throw new Error("Cloudflare embedding error: API returned success=false");
|
|
29
|
+
}
|
|
30
|
+
return data.result.data;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
name: "cloudflare",
|
|
34
|
+
dimensions,
|
|
35
|
+
async embed(text) {
|
|
36
|
+
const vectors = await callApi([text]);
|
|
37
|
+
return vectors[0];
|
|
38
|
+
},
|
|
39
|
+
async embedMany(texts) {
|
|
40
|
+
return callApi(texts);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/generation.ts
|
|
46
|
+
var DEFAULT_MODEL2 = "@cf/meta/llama-3.1-8b-instruct";
|
|
47
|
+
function cloudflareGeneration(options) {
|
|
48
|
+
const model = options.model ?? DEFAULT_MODEL2;
|
|
49
|
+
const baseUrl = `https://api.cloudflare.com/client/v4/accounts/${options.accountId}/ai/run/${model}`;
|
|
50
|
+
function buildMessages(question, context, opts) {
|
|
51
|
+
const systemPrompt = opts?.systemPrompt ?? options.systemPrompt ?? "Answer based on the provided context.";
|
|
52
|
+
let userPrompt = `Context:
|
|
53
|
+
${context}
|
|
54
|
+
|
|
55
|
+
Question: ${question}`;
|
|
56
|
+
if (opts?.history) {
|
|
57
|
+
userPrompt = `Conversation history:
|
|
58
|
+
${opts.history}
|
|
59
|
+
|
|
60
|
+
${userPrompt}`;
|
|
61
|
+
}
|
|
62
|
+
return [
|
|
63
|
+
{ role: "system", content: systemPrompt },
|
|
64
|
+
{ role: "user", content: userPrompt }
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
name: "cloudflare",
|
|
69
|
+
async generate(question, context, opts) {
|
|
70
|
+
const messages = buildMessages(question, context, opts);
|
|
71
|
+
const res = await fetch(baseUrl, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
75
|
+
"Content-Type": "application/json"
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify({ messages, stream: false })
|
|
78
|
+
});
|
|
79
|
+
if (!res.ok) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Cloudflare generation error: ${res.status} ${await res.text()}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const data = await res.json();
|
|
85
|
+
if (!data.success) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
"Cloudflare generation error: API returned success=false"
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return data.result.response;
|
|
91
|
+
},
|
|
92
|
+
async *generateStream(question, context, opts) {
|
|
93
|
+
const messages = buildMessages(question, context, opts);
|
|
94
|
+
const res = await fetch(baseUrl, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
Authorization: `Bearer ${options.apiToken}`,
|
|
98
|
+
"Content-Type": "application/json"
|
|
99
|
+
},
|
|
100
|
+
body: JSON.stringify({ messages, stream: true })
|
|
101
|
+
});
|
|
102
|
+
if (!res.ok) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
`Cloudflare generation stream error: ${res.status} ${await res.text()}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const reader = res.body?.getReader();
|
|
108
|
+
if (!reader) throw new Error("No response body");
|
|
109
|
+
const decoder = new TextDecoder();
|
|
110
|
+
let buffer = "";
|
|
111
|
+
try {
|
|
112
|
+
for (; ; ) {
|
|
113
|
+
const { done, value } = await reader.read();
|
|
114
|
+
if (done) break;
|
|
115
|
+
buffer += decoder.decode(value, { stream: true });
|
|
116
|
+
const lines = buffer.split("\n");
|
|
117
|
+
buffer = lines.pop() ?? "";
|
|
118
|
+
for (const line of lines) {
|
|
119
|
+
if (!line.startsWith("data: ")) continue;
|
|
120
|
+
const payload = line.slice(6).trim();
|
|
121
|
+
if (payload === "[DONE]") return;
|
|
122
|
+
try {
|
|
123
|
+
const data = JSON.parse(payload);
|
|
124
|
+
if (data.response) yield data.response;
|
|
125
|
+
} catch {
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
} finally {
|
|
130
|
+
reader.releaseLock();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export {
|
|
136
|
+
cloudflareEmbedding,
|
|
137
|
+
cloudflareGeneration
|
|
138
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ragpipe/plugin-cloudflare",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Cloudflare Workers AI embedding and generation plugin for ragpipe",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "yungblud",
|
|
9
|
+
"url": "https://github.com/yungblud"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/yungblud/ragpipe",
|
|
14
|
+
"directory": "packages/plugin-cloudflare"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/yungblud/ragpipe/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/yungblud/ragpipe#readme",
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"registry": "https://registry.npmjs.org/",
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"require": "./dist/index.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"main": "./dist/index.cjs",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"files": ["dist", "README.md"],
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"dev": "tsup --watch",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"test:coverage": "vitest run --coverage"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"ragpipe",
|
|
45
|
+
"rag",
|
|
46
|
+
"cloudflare",
|
|
47
|
+
"workers-ai",
|
|
48
|
+
"embedding",
|
|
49
|
+
"generation",
|
|
50
|
+
"plugin"
|
|
51
|
+
],
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"ragpipe": ">=0.1.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"ragpipe": "workspace:*",
|
|
57
|
+
"tsup": "^8.4.0",
|
|
58
|
+
"typescript": "^5.8.3",
|
|
59
|
+
"vitest": "^3.1.1"
|
|
60
|
+
}
|
|
61
|
+
}
|