effect-cf 0.13.1 → 0.15.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/CHANGELOG.md +18 -0
- package/README.md +28 -1
- package/dist/{Hyperdrive-L6ldMlRF.d.mts → Hyperdrive-C0vfrPeG.d.mts} +1 -1
- package/dist/HyperdrivePg.d.mts +1 -1
- package/dist/index.d.mts +551 -311
- package/dist/index.mjs +460 -316
- package/package.json +8 -8
- package/src/AiGateway.ts +284 -0
- package/src/BrowserRendering.ts +286 -0
- package/src/CloudflareOtlp.ts +90 -386
- package/src/DurableObject.ts +3 -2
- package/src/Email.ts +134 -0
- package/src/Environment.ts +1 -1
- package/src/Images.ts +42 -24
- package/src/Kv.ts +6 -2
- package/src/QueueBinding.ts +19 -10
- package/src/R2.ts +47 -33
- package/src/Vectorize.ts +213 -0
- package/src/WorkersAi.ts +239 -0
- package/src/Workflow.ts +2 -0
- package/src/WorkflowBinding.ts +15 -9
- package/src/index.ts +5 -0
package/src/Vectorize.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { Context, Data, Effect, type Layer } from "effect";
|
|
2
|
+
import type {
|
|
3
|
+
Vectorize as CloudflareVectorize,
|
|
4
|
+
VectorizeAsyncMutation as CloudflareVectorizeAsyncMutation,
|
|
5
|
+
VectorizeIndex as CloudflareVectorizeIndex,
|
|
6
|
+
VectorizeIndexDetails as CloudflareVectorizeIndexDetails,
|
|
7
|
+
VectorizeIndexInfo as CloudflareVectorizeIndexInfo,
|
|
8
|
+
VectorizeMatch as CloudflareVectorizeMatch,
|
|
9
|
+
VectorizeMatches as CloudflareVectorizeMatches,
|
|
10
|
+
VectorizeQueryOptions as CloudflareVectorizeQueryOptions,
|
|
11
|
+
VectorizeVector as CloudflareVectorizeVector,
|
|
12
|
+
VectorizeVectorMetadata as CloudflareVectorizeVectorMetadata,
|
|
13
|
+
VectorizeVectorMetadataFilter as CloudflareVectorizeVectorMetadataFilter,
|
|
14
|
+
VectorizeVectorMetadataValue as CloudflareVectorizeVectorMetadataValue,
|
|
15
|
+
VectorizeVectorMutation as CloudflareVectorizeVectorMutation,
|
|
16
|
+
} from "@cloudflare/workers-types";
|
|
17
|
+
|
|
18
|
+
import * as Binding from "./Binding";
|
|
19
|
+
import type { WorkerEnvironment } from "./Environment";
|
|
20
|
+
|
|
21
|
+
const expectedVectorizeBinding =
|
|
22
|
+
"Vectorize index binding with describe(), query(), insert(), upsert(), deleteByIds(), and getByIds()";
|
|
23
|
+
|
|
24
|
+
/** Error raised when a Vectorize operation fails. */
|
|
25
|
+
export class VectorizeOperationError extends Data.TaggedError("VectorizeOperationError")<{
|
|
26
|
+
readonly binding: string;
|
|
27
|
+
readonly operation: string;
|
|
28
|
+
readonly cause: unknown;
|
|
29
|
+
}> {}
|
|
30
|
+
|
|
31
|
+
/** Typed Vectorize binding definition. */
|
|
32
|
+
export interface VectorizeDefinition {
|
|
33
|
+
/** Binding name as configured in `wrangler.jsonc`. */
|
|
34
|
+
readonly binding: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type VectorizeBinding = CloudflareVectorize | CloudflareVectorizeIndex;
|
|
38
|
+
export type VectorizeVector = CloudflareVectorizeVector;
|
|
39
|
+
export type VectorizeVectorMetadata = CloudflareVectorizeVectorMetadata;
|
|
40
|
+
export type VectorizeVectorMetadataValue = CloudflareVectorizeVectorMetadataValue;
|
|
41
|
+
export type VectorizeVectorMetadataFilter = CloudflareVectorizeVectorMetadataFilter;
|
|
42
|
+
export type VectorizeQueryOptions = CloudflareVectorizeQueryOptions;
|
|
43
|
+
export type VectorizeMatches = CloudflareVectorizeMatches;
|
|
44
|
+
export type VectorizeMatch = CloudflareVectorizeMatch;
|
|
45
|
+
export type VectorizeIndexInfo = CloudflareVectorizeIndexInfo;
|
|
46
|
+
export type VectorizeIndexDetails = CloudflareVectorizeIndexDetails;
|
|
47
|
+
export type VectorizeMutation =
|
|
48
|
+
| CloudflareVectorizeAsyncMutation
|
|
49
|
+
| CloudflareVectorizeVectorMutation;
|
|
50
|
+
export type VectorizeValues = Float32Array | Float64Array | ReadonlyArray<number>;
|
|
51
|
+
|
|
52
|
+
interface VectorizeRuntimeBinding {
|
|
53
|
+
readonly describe: () => Promise<VectorizeIndexInfo | VectorizeIndexDetails>;
|
|
54
|
+
readonly query: (
|
|
55
|
+
vector: Float32Array | Float64Array | number[],
|
|
56
|
+
options?: VectorizeQueryOptions,
|
|
57
|
+
) => Promise<VectorizeMatches>;
|
|
58
|
+
readonly queryById?: (
|
|
59
|
+
vectorId: string,
|
|
60
|
+
options?: VectorizeQueryOptions,
|
|
61
|
+
) => Promise<VectorizeMatches>;
|
|
62
|
+
readonly insert: (vectors: Array<VectorizeVector>) => Promise<VectorizeMutation>;
|
|
63
|
+
readonly upsert: (vectors: Array<VectorizeVector>) => Promise<VectorizeMutation>;
|
|
64
|
+
readonly deleteByIds: (ids: Array<string>) => Promise<VectorizeMutation>;
|
|
65
|
+
readonly getByIds: (ids: Array<string>) => Promise<Array<VectorizeVector>>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface VectorizeClient {
|
|
69
|
+
readonly describe: Effect.Effect<
|
|
70
|
+
VectorizeIndexInfo | VectorizeIndexDetails,
|
|
71
|
+
VectorizeOperationError
|
|
72
|
+
>;
|
|
73
|
+
readonly query: (
|
|
74
|
+
vector: VectorizeValues,
|
|
75
|
+
options?: VectorizeQueryOptions,
|
|
76
|
+
) => Effect.Effect<VectorizeMatches, VectorizeOperationError>;
|
|
77
|
+
readonly queryById: (
|
|
78
|
+
vectorId: string,
|
|
79
|
+
options?: VectorizeQueryOptions,
|
|
80
|
+
) => Effect.Effect<VectorizeMatches, VectorizeOperationError>;
|
|
81
|
+
readonly insert: (
|
|
82
|
+
vectors: ReadonlyArray<VectorizeVector>,
|
|
83
|
+
) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
|
|
84
|
+
readonly upsert: (
|
|
85
|
+
vectors: ReadonlyArray<VectorizeVector>,
|
|
86
|
+
) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
|
|
87
|
+
readonly deleteByIds: (
|
|
88
|
+
ids: ReadonlyArray<string>,
|
|
89
|
+
) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
|
|
90
|
+
readonly delete: (
|
|
91
|
+
ids: ReadonlyArray<string>,
|
|
92
|
+
) => Effect.Effect<VectorizeMutation, VectorizeOperationError>;
|
|
93
|
+
readonly getByIds: (
|
|
94
|
+
ids: ReadonlyArray<string>,
|
|
95
|
+
) => Effect.Effect<ReadonlyArray<VectorizeVector>, VectorizeOperationError>;
|
|
96
|
+
readonly unsafeRaw: Effect.Effect<VectorizeBinding>;
|
|
97
|
+
readonly definition: VectorizeDefinition;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
declare const VectorizeServiceTypeId: unique symbol;
|
|
101
|
+
|
|
102
|
+
/** Nominal service marker for Vectorize services created with {@link make}. */
|
|
103
|
+
export interface VectorizeService<Id extends string> {
|
|
104
|
+
readonly [VectorizeServiceTypeId]: {
|
|
105
|
+
readonly id: Id;
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type LayerOptions = {
|
|
110
|
+
readonly binding: string;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export interface TagClass<Self, Id extends string> extends Context.ServiceClass<
|
|
114
|
+
Self,
|
|
115
|
+
Id,
|
|
116
|
+
VectorizeClient
|
|
117
|
+
> {
|
|
118
|
+
readonly id: Id;
|
|
119
|
+
readonly layer: (
|
|
120
|
+
options: LayerOptions,
|
|
121
|
+
) => Layer.Layer<
|
|
122
|
+
Self,
|
|
123
|
+
Binding.BindingNotFoundError | Binding.BindingValidationError,
|
|
124
|
+
WorkerEnvironment
|
|
125
|
+
>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const vectorizeError = (binding: string, operation: string, cause: unknown) =>
|
|
129
|
+
new VectorizeOperationError({ binding, operation, cause });
|
|
130
|
+
|
|
131
|
+
const tryVectorizePromise = <A>(
|
|
132
|
+
binding: string,
|
|
133
|
+
operation: string,
|
|
134
|
+
evaluate: () => Promise<A>,
|
|
135
|
+
): Effect.Effect<A, VectorizeOperationError> =>
|
|
136
|
+
Effect.tryPromise({
|
|
137
|
+
try: evaluate,
|
|
138
|
+
catch: (cause) => vectorizeError(binding, operation, cause),
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const hasFunction = (value: object, key: string): boolean =>
|
|
142
|
+
typeof Reflect.get(value, key) === "function";
|
|
143
|
+
|
|
144
|
+
export const isVectorizeBinding = (value: unknown): value is VectorizeBinding =>
|
|
145
|
+
typeof value === "object" &&
|
|
146
|
+
value !== null &&
|
|
147
|
+
hasFunction(value, "describe") &&
|
|
148
|
+
hasFunction(value, "query") &&
|
|
149
|
+
hasFunction(value, "insert") &&
|
|
150
|
+
hasFunction(value, "upsert") &&
|
|
151
|
+
hasFunction(value, "deleteByIds") &&
|
|
152
|
+
hasFunction(value, "getByIds");
|
|
153
|
+
|
|
154
|
+
export const makeClient =
|
|
155
|
+
(definition: VectorizeDefinition) =>
|
|
156
|
+
(index: VectorizeBinding): VectorizeClient => {
|
|
157
|
+
const runtime = index as VectorizeRuntimeBinding;
|
|
158
|
+
const deleteByIds = (ids: ReadonlyArray<string>) =>
|
|
159
|
+
tryVectorizePromise(definition.binding, "deleteByIds", () => runtime.deleteByIds([...ids]));
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
definition,
|
|
163
|
+
describe: tryVectorizePromise(definition.binding, "describe", () => runtime.describe()),
|
|
164
|
+
query: (vector, options) =>
|
|
165
|
+
tryVectorizePromise(definition.binding, "query", () =>
|
|
166
|
+
runtime.query(vector as Float32Array | Float64Array | number[], options),
|
|
167
|
+
),
|
|
168
|
+
queryById: (vectorId, options) =>
|
|
169
|
+
runtime.queryById !== undefined
|
|
170
|
+
? tryVectorizePromise(definition.binding, "queryById", () =>
|
|
171
|
+
runtime.queryById!(vectorId, options),
|
|
172
|
+
)
|
|
173
|
+
: Effect.fail(
|
|
174
|
+
vectorizeError(
|
|
175
|
+
definition.binding,
|
|
176
|
+
"queryById",
|
|
177
|
+
new TypeError("Vectorize binding does not expose queryById()"),
|
|
178
|
+
),
|
|
179
|
+
),
|
|
180
|
+
insert: (vectors) =>
|
|
181
|
+
tryVectorizePromise(definition.binding, "insert", () => runtime.insert([...vectors])),
|
|
182
|
+
upsert: (vectors) =>
|
|
183
|
+
tryVectorizePromise(definition.binding, "upsert", () => runtime.upsert([...vectors])),
|
|
184
|
+
deleteByIds,
|
|
185
|
+
delete: deleteByIds,
|
|
186
|
+
getByIds: (ids) =>
|
|
187
|
+
tryVectorizePromise(definition.binding, "getByIds", () => runtime.getByIds([...ids])),
|
|
188
|
+
unsafeRaw: Effect.succeed(index),
|
|
189
|
+
};
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export const layer = <Self>(
|
|
193
|
+
tag: Context.Service<Self, VectorizeClient>,
|
|
194
|
+
definition: VectorizeDefinition,
|
|
195
|
+
) =>
|
|
196
|
+
Binding.layer(tag, definition.binding, isVectorizeBinding, makeClient(definition), {
|
|
197
|
+
expected: expectedVectorizeBinding,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
export const make = <Id extends string>(id: Id) => Tag<VectorizeService<Id>>()<Id>(id);
|
|
201
|
+
|
|
202
|
+
export const Tag =
|
|
203
|
+
<Self>() =>
|
|
204
|
+
<Id extends string>(id: Id) => {
|
|
205
|
+
const tag = Context.Service<Self, VectorizeClient>()(id);
|
|
206
|
+
|
|
207
|
+
const makeLayer = (definition: LayerOptions) => layer(tag, definition);
|
|
208
|
+
|
|
209
|
+
return Object.assign(tag, {
|
|
210
|
+
id,
|
|
211
|
+
layer: makeLayer,
|
|
212
|
+
}) as TagClass<Self, Id>;
|
|
213
|
+
};
|
package/src/WorkersAi.ts
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { Context, Data, Effect, type Layer } from "effect";
|
|
2
|
+
import type {
|
|
3
|
+
Ai as CloudflareAi,
|
|
4
|
+
AiAsyncBatchResponse,
|
|
5
|
+
AiGateway as CloudflareAiGateway,
|
|
6
|
+
AiModelListType,
|
|
7
|
+
AiModels,
|
|
8
|
+
AiModelsSearchObject,
|
|
9
|
+
AiModelsSearchParams,
|
|
10
|
+
AiOptions,
|
|
11
|
+
AiTextEmbeddingsInput,
|
|
12
|
+
Ai_Cf_Qwen_Qwen3_Embedding_0_6B_Input,
|
|
13
|
+
} from "@cloudflare/workers-types";
|
|
14
|
+
|
|
15
|
+
import * as Binding from "./Binding";
|
|
16
|
+
import type { WorkerEnvironment } from "./Environment";
|
|
17
|
+
|
|
18
|
+
const expectedWorkersAiBinding = "Workers AI binding with run(), gateway(), and models()";
|
|
19
|
+
|
|
20
|
+
/** Error raised when a Workers AI operation fails. */
|
|
21
|
+
export class WorkersAiOperationError extends Data.TaggedError("WorkersAiOperationError")<{
|
|
22
|
+
readonly binding: string;
|
|
23
|
+
readonly operation: string;
|
|
24
|
+
readonly cause: unknown;
|
|
25
|
+
}> {}
|
|
26
|
+
|
|
27
|
+
/** Typed Workers AI binding definition. */
|
|
28
|
+
export interface WorkersAiDefinition {
|
|
29
|
+
/** Binding name as configured in `wrangler.jsonc`. */
|
|
30
|
+
readonly binding: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type WorkersAiBinding<ModelList extends AiModelListType = AiModels> =
|
|
34
|
+
CloudflareAi<ModelList>;
|
|
35
|
+
export type WorkersAiOptions = AiOptions;
|
|
36
|
+
export type WorkersAiModelsSearchParams = AiModelsSearchParams;
|
|
37
|
+
export type WorkersAiModelsSearchObject = AiModelsSearchObject;
|
|
38
|
+
export type WorkersAiAsyncBatchResponse = AiAsyncBatchResponse;
|
|
39
|
+
export type WorkersAiEmbeddingInput =
|
|
40
|
+
| AiTextEmbeddingsInput
|
|
41
|
+
| Ai_Cf_Qwen_Qwen3_Embedding_0_6B_Input
|
|
42
|
+
| Record<string, unknown>;
|
|
43
|
+
|
|
44
|
+
export interface WorkersAiEmbeddingResponse {
|
|
45
|
+
readonly data: ReadonlyArray<ReadonlyArray<number>>;
|
|
46
|
+
readonly shape: ReadonlyArray<number>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface WorkersAiClient<ModelList extends AiModelListType = AiModels> {
|
|
50
|
+
readonly aiGatewayLogId: Effect.Effect<string | null, WorkersAiOperationError>;
|
|
51
|
+
readonly run: {
|
|
52
|
+
<Name extends keyof ModelList>(
|
|
53
|
+
model: Name,
|
|
54
|
+
input: {
|
|
55
|
+
readonly requests: ReadonlyArray<ModelList[Name]["inputs"]>;
|
|
56
|
+
},
|
|
57
|
+
options: WorkersAiOptions & {
|
|
58
|
+
readonly queueRequest: true;
|
|
59
|
+
},
|
|
60
|
+
): Effect.Effect<WorkersAiAsyncBatchResponse, WorkersAiOperationError>;
|
|
61
|
+
<Name extends keyof ModelList>(
|
|
62
|
+
model: Name,
|
|
63
|
+
input: ModelList[Name]["inputs"],
|
|
64
|
+
options: WorkersAiOptions & {
|
|
65
|
+
readonly returnRawResponse: true;
|
|
66
|
+
},
|
|
67
|
+
): Effect.Effect<Response, WorkersAiOperationError>;
|
|
68
|
+
<Name extends keyof ModelList>(
|
|
69
|
+
model: Name,
|
|
70
|
+
input: ModelList[Name]["inputs"],
|
|
71
|
+
options: WorkersAiOptions & {
|
|
72
|
+
readonly websocket: true;
|
|
73
|
+
},
|
|
74
|
+
): Effect.Effect<Response, WorkersAiOperationError>;
|
|
75
|
+
<Name extends keyof ModelList>(
|
|
76
|
+
model: Name,
|
|
77
|
+
input: ModelList[Name]["inputs"] & {
|
|
78
|
+
readonly stream: true;
|
|
79
|
+
},
|
|
80
|
+
options?: WorkersAiOptions,
|
|
81
|
+
): Effect.Effect<ReadableStream, WorkersAiOperationError>;
|
|
82
|
+
<Name extends keyof ModelList>(
|
|
83
|
+
model: Name,
|
|
84
|
+
input: ModelList[Name]["inputs"],
|
|
85
|
+
options?: WorkersAiOptions,
|
|
86
|
+
): Effect.Effect<ModelList[Name]["postProcessedOutputs"], WorkersAiOperationError>;
|
|
87
|
+
<Input extends Record<string, unknown>, Output = Record<string, unknown>>(
|
|
88
|
+
model: string,
|
|
89
|
+
input: Input,
|
|
90
|
+
options?: WorkersAiOptions,
|
|
91
|
+
): Effect.Effect<Output, WorkersAiOperationError>;
|
|
92
|
+
};
|
|
93
|
+
readonly runEmbedding: <Input extends WorkersAiEmbeddingInput>(
|
|
94
|
+
model: string,
|
|
95
|
+
input: Input,
|
|
96
|
+
options?: WorkersAiOptions,
|
|
97
|
+
) => Effect.Effect<WorkersAiEmbeddingResponse, WorkersAiOperationError>;
|
|
98
|
+
readonly models: (
|
|
99
|
+
params?: WorkersAiModelsSearchParams,
|
|
100
|
+
) => Effect.Effect<ReadonlyArray<WorkersAiModelsSearchObject>, WorkersAiOperationError>;
|
|
101
|
+
readonly gateway: (
|
|
102
|
+
gatewayId: string,
|
|
103
|
+
) => Effect.Effect<CloudflareAiGateway, WorkersAiOperationError>;
|
|
104
|
+
readonly unsafeRaw: Effect.Effect<WorkersAiBinding<ModelList>>;
|
|
105
|
+
readonly definition: WorkersAiDefinition;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
declare const WorkersAiServiceTypeId: unique symbol;
|
|
109
|
+
|
|
110
|
+
/** Nominal service marker for Workers AI services created with {@link make}. */
|
|
111
|
+
export interface WorkersAiService<Id extends string> {
|
|
112
|
+
readonly [WorkersAiServiceTypeId]: {
|
|
113
|
+
readonly id: Id;
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export type LayerOptions = {
|
|
118
|
+
readonly binding: string;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export interface TagClass<
|
|
122
|
+
Self,
|
|
123
|
+
Id extends string,
|
|
124
|
+
ModelList extends AiModelListType = AiModels,
|
|
125
|
+
> extends Context.ServiceClass<Self, Id, WorkersAiClient<ModelList>> {
|
|
126
|
+
readonly id: Id;
|
|
127
|
+
readonly layer: (
|
|
128
|
+
options: LayerOptions,
|
|
129
|
+
) => Layer.Layer<
|
|
130
|
+
Self,
|
|
131
|
+
Binding.BindingNotFoundError | Binding.BindingValidationError,
|
|
132
|
+
WorkerEnvironment
|
|
133
|
+
>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const workersAiError = (binding: string, operation: string, cause: unknown) =>
|
|
137
|
+
new WorkersAiOperationError({ binding, operation, cause });
|
|
138
|
+
|
|
139
|
+
const tryWorkersAiPromise = <A>(
|
|
140
|
+
binding: string,
|
|
141
|
+
operation: string,
|
|
142
|
+
evaluate: () => Promise<A>,
|
|
143
|
+
): Effect.Effect<A, WorkersAiOperationError> =>
|
|
144
|
+
Effect.tryPromise({
|
|
145
|
+
try: evaluate,
|
|
146
|
+
catch: (cause) => workersAiError(binding, operation, cause),
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const tryWorkersAiSync = <A>(
|
|
150
|
+
binding: string,
|
|
151
|
+
operation: string,
|
|
152
|
+
evaluate: () => A,
|
|
153
|
+
): Effect.Effect<A, WorkersAiOperationError> =>
|
|
154
|
+
Effect.try({
|
|
155
|
+
try: evaluate,
|
|
156
|
+
catch: (cause) => workersAiError(binding, operation, cause),
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const hasFunction = (value: object, key: string): boolean =>
|
|
160
|
+
typeof Reflect.get(value, key) === "function";
|
|
161
|
+
|
|
162
|
+
export const isWorkersAiBinding = (value: unknown): value is WorkersAiBinding =>
|
|
163
|
+
typeof value === "object" &&
|
|
164
|
+
value !== null &&
|
|
165
|
+
hasFunction(value, "run") &&
|
|
166
|
+
hasFunction(value, "gateway") &&
|
|
167
|
+
hasFunction(value, "models");
|
|
168
|
+
|
|
169
|
+
export const embeddingResponse = (value: {
|
|
170
|
+
readonly data?: ReadonlyArray<ReadonlyArray<number>>;
|
|
171
|
+
readonly shape?: ReadonlyArray<number>;
|
|
172
|
+
}): WorkersAiEmbeddingResponse => ({
|
|
173
|
+
data: value.data ?? [],
|
|
174
|
+
shape: value.shape ?? [],
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
export const makeClient =
|
|
178
|
+
<ModelList extends AiModelListType = AiModels>(definition: WorkersAiDefinition) =>
|
|
179
|
+
(ai: WorkersAiBinding<ModelList>): WorkersAiClient<ModelList> => {
|
|
180
|
+
const run = ((model: string, input: Record<string, unknown>, options?: WorkersAiOptions) =>
|
|
181
|
+
tryWorkersAiPromise(definition.binding, "run", () =>
|
|
182
|
+
ai.run(model as string & {}, input, options),
|
|
183
|
+
)) as WorkersAiClient<ModelList>["run"];
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
definition,
|
|
187
|
+
aiGatewayLogId: tryWorkersAiSync(
|
|
188
|
+
definition.binding,
|
|
189
|
+
"aiGatewayLogId",
|
|
190
|
+
() => ai.aiGatewayLogId,
|
|
191
|
+
),
|
|
192
|
+
run,
|
|
193
|
+
runEmbedding: (model, input, options) =>
|
|
194
|
+
run(model, input, options).pipe(
|
|
195
|
+
Effect.map((response) =>
|
|
196
|
+
embeddingResponse(
|
|
197
|
+
response as {
|
|
198
|
+
readonly data?: ReadonlyArray<ReadonlyArray<number>>;
|
|
199
|
+
readonly shape?: ReadonlyArray<number>;
|
|
200
|
+
},
|
|
201
|
+
),
|
|
202
|
+
),
|
|
203
|
+
),
|
|
204
|
+
models: (params) =>
|
|
205
|
+
tryWorkersAiPromise(definition.binding, "models", () => ai.models(params)),
|
|
206
|
+
gateway: (gatewayId) =>
|
|
207
|
+
tryWorkersAiSync(definition.binding, "gateway", () => ai.gateway(gatewayId)),
|
|
208
|
+
unsafeRaw: Effect.succeed(ai),
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export const layer = <Self, ModelList extends AiModelListType = AiModels>(
|
|
213
|
+
tag: Context.Service<Self, WorkersAiClient<ModelList>>,
|
|
214
|
+
definition: WorkersAiDefinition,
|
|
215
|
+
) =>
|
|
216
|
+
Binding.layer(
|
|
217
|
+
tag,
|
|
218
|
+
definition.binding,
|
|
219
|
+
(value): value is WorkersAiBinding<ModelList> => isWorkersAiBinding(value),
|
|
220
|
+
makeClient<ModelList>(definition),
|
|
221
|
+
{
|
|
222
|
+
expected: expectedWorkersAiBinding,
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
export const make = <Id extends string>(id: Id) => Tag<WorkersAiService<Id>>()<Id, AiModels>(id);
|
|
227
|
+
|
|
228
|
+
export const Tag =
|
|
229
|
+
<Self>() =>
|
|
230
|
+
<Id extends string, ModelList extends AiModelListType = AiModels>(id: Id) => {
|
|
231
|
+
const tag = Context.Service<Self, WorkersAiClient<ModelList>>()(id);
|
|
232
|
+
|
|
233
|
+
const makeLayer = (definition: LayerOptions) => layer(tag, definition);
|
|
234
|
+
|
|
235
|
+
return Object.assign(tag, {
|
|
236
|
+
id,
|
|
237
|
+
layer: makeLayer,
|
|
238
|
+
}) as TagClass<Self, Id, ModelList>;
|
|
239
|
+
};
|
package/src/Workflow.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface WorkflowEventService<Payload = unknown> {
|
|
|
21
21
|
readonly payload: Payload;
|
|
22
22
|
readonly timestamp: Date;
|
|
23
23
|
readonly instanceId: string;
|
|
24
|
+
readonly workflowName: string;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
export class WorkflowEvent extends Context.Service<WorkflowEvent, WorkflowEventService>()(
|
|
@@ -63,6 +64,7 @@ const fromWorkflowEvent = <Payload>(
|
|
|
63
64
|
payload: event.payload,
|
|
64
65
|
timestamp: event.timestamp,
|
|
65
66
|
instanceId: event.instanceId,
|
|
67
|
+
workflowName: event.workflowName,
|
|
66
68
|
});
|
|
67
69
|
|
|
68
70
|
const fromWorkflowStep = (
|
package/src/WorkflowBinding.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
InstanceStatus as CloudflareInstanceStatus,
|
|
3
|
+
Workflow as CloudflareWorkflow,
|
|
4
|
+
WorkflowInstance as CloudflareWorkflowInstance,
|
|
5
|
+
WorkflowInstanceCreateOptions as CloudflareWorkflowInstanceCreateOptions,
|
|
6
|
+
} from "@cloudflare/workers-types";
|
|
1
7
|
import { Context, Data, Effect, Option, Schema as S } from "effect";
|
|
2
8
|
|
|
3
9
|
import * as Binding from "./Binding";
|
|
@@ -6,7 +12,7 @@ import type * as RpcDefinition from "./RpcDefinition";
|
|
|
6
12
|
const expectedWorkflow = "Workflow binding with create(), createBatch(), and get()";
|
|
7
13
|
|
|
8
14
|
export type WorkflowInstanceCreateOptions<Payload> = Omit<
|
|
9
|
-
|
|
15
|
+
CloudflareWorkflowInstanceCreateOptions<Payload>,
|
|
10
16
|
"params"
|
|
11
17
|
>;
|
|
12
18
|
|
|
@@ -22,7 +28,7 @@ export interface WorkflowInstanceRestartOptions {
|
|
|
22
28
|
};
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
export type WorkflowInstanceStatusName =
|
|
31
|
+
export type WorkflowInstanceStatusName = CloudflareInstanceStatus["status"];
|
|
26
32
|
|
|
27
33
|
export interface WorkflowInstanceStatus<Result> {
|
|
28
34
|
readonly status: WorkflowInstanceStatusName;
|
|
@@ -34,7 +40,7 @@ export interface WorkflowInstanceStatus<Result> {
|
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
export interface WorkflowInstance<Result> {
|
|
37
|
-
readonly raw:
|
|
43
|
+
readonly raw: CloudflareWorkflowInstance;
|
|
38
44
|
readonly id: string;
|
|
39
45
|
readonly pause: Effect.Effect<void, WorkflowOperationError>;
|
|
40
46
|
readonly resume: Effect.Effect<void, WorkflowOperationError>;
|
|
@@ -86,7 +92,7 @@ export interface WorkflowBindingClient<
|
|
|
86
92
|
readonly get: (
|
|
87
93
|
instanceId: string,
|
|
88
94
|
) => Effect.Effect<WorkflowInstance<S.Schema.Type<Result>>, WorkflowOperationError>;
|
|
89
|
-
readonly unsafeRaw: Effect.Effect<
|
|
95
|
+
readonly unsafeRaw: Effect.Effect<CloudflareWorkflow<S.Codec.Encoded<Payload>>>;
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
export class WorkflowOperationError extends Data.TaggedError("WorkflowOperationError")<{
|
|
@@ -114,7 +120,7 @@ const tryWorkflowPromise = <A>(
|
|
|
114
120
|
catch: (cause) => workflowError(binding, operation, cause),
|
|
115
121
|
});
|
|
116
122
|
|
|
117
|
-
export const isWorkflow = <Payload>(value: unknown): value is
|
|
123
|
+
export const isWorkflow = <Payload>(value: unknown): value is CloudflareWorkflow<Payload> => {
|
|
118
124
|
if (typeof value !== "object" || value === null) {
|
|
119
125
|
return false;
|
|
120
126
|
}
|
|
@@ -134,7 +140,7 @@ export const makeClient = <
|
|
|
134
140
|
>(
|
|
135
141
|
definition: WorkflowBindingDefinition<Payload, Result>,
|
|
136
142
|
): ((
|
|
137
|
-
workflow:
|
|
143
|
+
workflow: CloudflareWorkflow<S.Codec.Encoded<Payload>>,
|
|
138
144
|
) => WorkflowBindingClient<Payload, Result>) => {
|
|
139
145
|
type PayloadValue = S.Schema.Type<Payload>;
|
|
140
146
|
type EncodedPayload = S.Codec.Encoded<Payload>;
|
|
@@ -143,7 +149,7 @@ export const makeClient = <
|
|
|
143
149
|
const encodePayload = S.encodeEffect(definition.payload);
|
|
144
150
|
const decodeResult = S.decodeUnknownEffect(definition.result);
|
|
145
151
|
|
|
146
|
-
const wrapInstance = (raw:
|
|
152
|
+
const wrapInstance = (raw: CloudflareWorkflowInstance): WorkflowInstance<ResultValue> => {
|
|
147
153
|
const operation = <A>(name: string, evaluate: () => Promise<A>) =>
|
|
148
154
|
tryWorkflowPromise(definition.binding, name, evaluate);
|
|
149
155
|
|
|
@@ -205,7 +211,7 @@ export const makeClient = <
|
|
|
205
211
|
createBatch: Effect.fnUntraced(function* (
|
|
206
212
|
batch: WorkflowInstanceCreateBatchOptions<PayloadValue, EncodedPayload>,
|
|
207
213
|
) {
|
|
208
|
-
const encodedBatch: Array<
|
|
214
|
+
const encodedBatch: Array<CloudflareWorkflowInstanceCreateOptions<EncodedPayload>> = [];
|
|
209
215
|
|
|
210
216
|
for (const item of batch) {
|
|
211
217
|
const { payload, ...options } = item;
|
|
@@ -241,7 +247,7 @@ export const layer = <
|
|
|
241
247
|
Binding.layer(
|
|
242
248
|
tag,
|
|
243
249
|
definition.binding,
|
|
244
|
-
(value): value is
|
|
250
|
+
(value): value is CloudflareWorkflow<S.Codec.Encoded<Payload>> =>
|
|
245
251
|
isWorkflow<S.Codec.Encoded<Payload>>(value),
|
|
246
252
|
makeClient(definition),
|
|
247
253
|
{ expected: expectedWorkflow },
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
export * as AiGateway from "./AiGateway";
|
|
1
2
|
export * as Binding from "./Binding";
|
|
3
|
+
export * as BrowserRendering from "./BrowserRendering";
|
|
2
4
|
export * as CloudflareOtlp from "./CloudflareOtlp";
|
|
3
5
|
export * as D1 from "./D1";
|
|
4
6
|
export * as DurableObject from "./DurableObject";
|
|
@@ -10,6 +12,7 @@ export * as DurableObjectSqlite from "./DurableObjectSqlite";
|
|
|
10
12
|
export * as DurableObjectState from "./DurableObjectState";
|
|
11
13
|
export * as DurableObjectWebSocket from "./DurableObjectWebSocket";
|
|
12
14
|
export * as DurableObjectStorage from "./DurableObjectStorage";
|
|
15
|
+
export * as Email from "./Email";
|
|
13
16
|
export * as Hyperdrive from "./Hyperdrive";
|
|
14
17
|
export * as Images from "./Images";
|
|
15
18
|
export * as Kv from "./Kv";
|
|
@@ -25,4 +28,6 @@ export * as WorkerDefinition from "./WorkerDefinition";
|
|
|
25
28
|
export * as Workflow from "./Workflow";
|
|
26
29
|
export * as WorkflowBinding from "./WorkflowBinding";
|
|
27
30
|
export * as WorkflowDefinition from "./WorkflowDefinition";
|
|
31
|
+
export * as Vectorize from "./Vectorize";
|
|
32
|
+
export * as WorkersAi from "./WorkersAi";
|
|
28
33
|
export { WorkerConfig, WorkerEnvironment, type WorkerEnv } from "./Environment";
|