openpond-sdk 0.12.26 → 0.12.27
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/PRODUCT_INTEGRATION.md +13 -6
- package/README.md +2 -10
- package/SERVERLESS_SERVING.md +52 -35
- package/TASK_INGESTION.md +0 -4
- package/dist/advanced-refiner-evaluations.js +7 -7
- package/dist/ai-sdk.js +20 -83
- package/dist/ai-sdk.js.map +1 -1
- package/dist/candidate-evaluations.js +6 -6
- package/dist/{chunk-UZAVG2WK.js → chunk-3HOGOWKU.js} +8 -6
- package/dist/chunk-3HOGOWKU.js.map +1 -0
- package/dist/{chunk-YV6PPDXZ.js → chunk-3Z5IK2UK.js} +27 -2
- package/dist/chunk-3Z5IK2UK.js.map +1 -0
- package/dist/{chunk-4REK5TTE.js → chunk-4D4QSQC3.js} +2 -2
- package/dist/{chunk-AMZ2SWHR.js → chunk-534W2O2S.js} +2 -2
- package/dist/{chunk-6LVLWRBJ.js → chunk-54BJJL7G.js} +2 -2
- package/dist/{chunk-XWUTYFOU.js → chunk-5KJY44FB.js} +3 -3
- package/dist/{chunk-QKLZZOZD.js → chunk-7MLFWVDI.js} +29 -10
- package/dist/chunk-7MLFWVDI.js.map +1 -0
- package/dist/{chunk-4A4FNG4R.js → chunk-7ZV626YS.js} +2 -2
- package/dist/{chunk-57ROW3XF.js → chunk-ABOZV47D.js} +2 -2
- package/dist/{chunk-3BILL33A.js → chunk-BIQ5TG3T.js} +4 -4
- package/dist/{chunk-JINWKUKR.js → chunk-BT6CC6QB.js} +3 -3
- package/dist/{chunk-4PEK3YOW.js → chunk-CNFN6GHY.js} +2 -2
- package/dist/{chunk-X5AT253K.js → chunk-CVYGJUWM.js} +2 -2
- package/dist/{chunk-D26RJQU7.js → chunk-CX7ETU2F.js} +2 -2
- package/dist/{chunk-4CDLPMJK.js → chunk-D7LV3USE.js} +2 -2
- package/dist/{chunk-WZKKQNYY.js → chunk-GA7OSSEA.js} +2 -2
- package/dist/{chunk-EL6KZO43.js → chunk-GFWXDWEE.js} +3 -3
- package/dist/{chunk-XYK3MAIC.js → chunk-JYWIKBGD.js} +122 -112
- package/dist/chunk-JYWIKBGD.js.map +1 -0
- package/dist/{chunk-AQV7RQZH.js → chunk-K4WU4JOP.js} +2 -2
- package/dist/{chunk-CAOMKM55.js → chunk-L7MVGGBH.js} +2 -2
- package/dist/{chunk-P56JWQYV.js → chunk-LRFVISLA.js} +3 -3
- package/dist/{chunk-2U6BQ5C4.js → chunk-MJHQMQEW.js} +3 -3
- package/dist/chunk-ON3KSXWR.js +639 -0
- package/dist/chunk-ON3KSXWR.js.map +1 -0
- package/dist/{chunk-PMVSO23F.js → chunk-RMXZISHK.js} +10 -1
- package/dist/chunk-RMXZISHK.js.map +1 -0
- package/dist/{chunk-JWEIAEQ6.js → chunk-TMNEDWA7.js} +10 -3
- package/dist/chunk-TMNEDWA7.js.map +1 -0
- package/dist/{chunk-C7I4ZG6Q.js → chunk-TX552FQG.js} +3 -3
- package/dist/{chunk-4CRLQMJ2.js → chunk-VIDRZCPQ.js} +6 -6
- package/dist/{chunk-MN4FE52A.js → chunk-VRUAIMM3.js} +7 -7
- package/dist/chunk-VRUAIMM3.js.map +1 -0
- package/dist/{chunk-H5KHLBC5.js → chunk-WJZHSIGD.js} +6 -8
- package/dist/{chunk-H5KHLBC5.js.map → chunk-WJZHSIGD.js.map} +1 -1
- package/dist/{chunk-HCUZYGUK.js → chunk-WPTFJZ4L.js} +3 -3
- package/dist/connected-evidence.js +7 -7
- package/dist/dataset-workspaces.js +10 -10
- package/dist/errors.js +1 -1
- package/dist/experiment-evaluation-schedules.js +16 -16
- package/dist/experiment-improvements.js +7 -7
- package/dist/experiments.js +15 -15
- package/dist/index.js +23 -23
- package/dist/learning.js +15 -4
- package/dist/learning.js.map +1 -1
- package/dist/model-projects.js +1 -1
- package/dist/model-starter-attempts.js +2 -2
- package/dist/model-starter-catalog.js +4 -4
- package/dist/model-starters.js +4 -4
- package/dist/model-taskset-runs.js +3 -3
- package/dist/post-training.js +6 -6
- package/dist/taskset-drafts.js +6 -6
- package/dist/taskset-packages.js +12 -10
- package/dist/training-bundle.js +46 -20
- package/dist/training-bundle.js.map +1 -1
- package/dist/training-hardware.js +2 -2
- package/dist/training.js +5620 -4342
- package/dist/training.js.map +1 -1
- package/dist/types/packages/sdk/src/ai-sdk.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/alphaedit-model-serving.d.ts +8 -4
- package/dist/types/packages/sdk/src/alphaedit-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/candidate-evaluation-client.d.ts +162 -162
- package/dist/types/packages/sdk/src/decision-model-serving.d.ts +4 -2
- package/dist/types/packages/sdk/src/decision-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/engram-model-serving.d.ts +3 -1
- package/dist/types/packages/sdk/src/engram-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/experiment-client.d.ts +699 -691
- package/dist/types/packages/sdk/src/experiment-client.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/experiment-draft-storage.d.ts +34 -28
- package/dist/types/packages/sdk/src/experiment-draft-storage.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/experiment-improvement-client.d.ts +1889 -1889
- package/dist/types/packages/sdk/src/experiment-run-details.d.ts +7 -7
- package/dist/types/packages/sdk/src/experiment-scoring-contracts.d.ts +21 -3
- package/dist/types/packages/sdk/src/experiment-scoring-contracts.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/learning.d.ts +1 -0
- package/dist/types/packages/sdk/src/learning.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-alphaedit-executions.d.ts +272 -16
- package/dist/types/packages/sdk/src/managed-alphaedit-executions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-compute-price.d.ts +53 -1
- package/dist/types/packages/sdk/src/managed-compute-price.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-decision-executions.d.ts +612 -356
- package/dist/types/packages/sdk/src/managed-decision-executions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-engram-executions.d.ts +272 -16
- package/dist/types/packages/sdk/src/managed-engram-executions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-modification-executions.d.ts +208 -16
- package/dist/types/packages/sdk/src/managed-modification-executions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-neuron-training-executions.d.ts +272 -16
- package/dist/types/packages/sdk/src/managed-neuron-training-executions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-serving-usage.d.ts +3 -0
- package/dist/types/packages/sdk/src/managed-serving-usage.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/managed-training-preparation.d.ts +25 -25
- package/dist/types/packages/sdk/src/managed-training-preparation.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-learning-capabilities.d.ts +4 -0
- package/dist/types/packages/sdk/src/model-learning-capabilities.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/model-learning-policy.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-supervised-training-defaults.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/model-training-defaults.d.ts +5 -2
- package/dist/types/packages/sdk/src/model-training-defaults.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/neuron-training-model-serving.d.ts +8 -4
- package/dist/types/packages/sdk/src/neuron-training-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/post-training.d.ts +7 -7
- package/dist/types/packages/sdk/src/product-model-response.d.ts +6 -2
- package/dist/types/packages/sdk/src/product-model-response.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/product-model-transport.d.ts +99 -0
- package/dist/types/packages/sdk/src/product-model-transport.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/product-model-wire.d.ts +104 -0
- package/dist/types/packages/sdk/src/product-model-wire.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/product-models.d.ts +18 -15
- package/dist/types/packages/sdk/src/product-models.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/serverless-serving.d.ts +416 -9
- package/dist/types/packages/sdk/src/serverless-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/steering-model-serving.d.ts +2144 -703
- package/dist/types/packages/sdk/src/steering-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/steering-profile-publication.d.ts +631 -0
- package/dist/types/packages/sdk/src/steering-profile-publication.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/taskset-draft-client.d.ts +120 -120
- package/dist/types/packages/sdk/src/taskset-package-projection.d.ts +20 -20
- package/dist/types/packages/sdk/src/taskset-packages.d.ts +1 -0
- package/dist/types/packages/sdk/src/taskset-packages.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/taskset-text-policy.d.ts +11 -0
- package/dist/types/packages/sdk/src/taskset-text-policy.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/training-compute-selection.d.ts +6 -19
- package/dist/types/packages/sdk/src/training-compute-selection.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training-estimates.d.ts +1 -1
- package/dist/types/packages/sdk/src/training-experiment-setup.d.ts +4 -1
- package/dist/types/packages/sdk/src/training-experiment-setup.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training-harness-sources.d.ts +2 -2
- package/dist/types/packages/sdk/src/training-learning-batch.d.ts +40 -40
- package/dist/types/packages/sdk/src/training-model-serving-control.d.ts +406 -8
- package/dist/types/packages/sdk/src/training-model-serving-control.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training-model-serving.d.ts +1136 -30
- package/dist/types/packages/sdk/src/training-model-serving.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training-operations.d.ts +11197 -0
- package/dist/types/packages/sdk/src/training-operations.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/training-qualification-preparation.d.ts +25 -25
- package/dist/types/packages/sdk/src/training-supervised.d.ts +13 -0
- package/dist/types/packages/sdk/src/training-supervised.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training-transport.d.ts +4 -1
- package/dist/types/packages/sdk/src/training-transport.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/training.d.ts +15885 -4662
- package/dist/types/packages/sdk/src/training.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/weight-inference.d.ts +8 -5
- package/dist/types/packages/sdk/src/weight-inference.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/weight-model-versions.d.ts +2089 -398
- package/dist/types/packages/sdk/src/weight-model-versions.d.ts.map +1 -1
- package/dist/types/packages/sdk/src/weight-space-artifact.d.ts +433 -0
- package/dist/types/packages/sdk/src/weight-space-artifact.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/weight-space-evaluation.d.ts +1437 -0
- package/dist/types/packages/sdk/src/weight-space-evaluation.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/weight-space-model-serving.d.ts +2910 -0
- package/dist/types/packages/sdk/src/weight-space-model-serving.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/weight-space-programming.d.ts +845 -0
- package/dist/types/packages/sdk/src/weight-space-programming.d.ts.map +1 -0
- package/dist/types/packages/sdk/src/weight-space-sessions.d.ts +4600 -0
- package/dist/types/packages/sdk/src/weight-space-sessions.d.ts.map +1 -0
- package/fixtures/python-foundation/operation-matrix.json +369 -0
- package/fixtures/python-foundation/schemas.json +34304 -27905
- package/fixtures/python-foundation/training-estimate-http-workflow.json +1 -1
- package/package.json +2 -2
- package/dist/chunk-JWEIAEQ6.js.map +0 -1
- package/dist/chunk-MN4FE52A.js.map +0 -1
- package/dist/chunk-PMVSO23F.js.map +0 -1
- package/dist/chunk-QKLZZOZD.js.map +0 -1
- package/dist/chunk-UZAVG2WK.js.map +0 -1
- package/dist/chunk-XYK3MAIC.js.map +0 -1
- package/dist/chunk-YV6PPDXZ.js.map +0 -1
- package/dist/chunk-ZG4HVCJB.js +0 -248
- package/dist/chunk-ZG4HVCJB.js.map +0 -1
- /package/dist/{chunk-4REK5TTE.js.map → chunk-4D4QSQC3.js.map} +0 -0
- /package/dist/{chunk-AMZ2SWHR.js.map → chunk-534W2O2S.js.map} +0 -0
- /package/dist/{chunk-6LVLWRBJ.js.map → chunk-54BJJL7G.js.map} +0 -0
- /package/dist/{chunk-XWUTYFOU.js.map → chunk-5KJY44FB.js.map} +0 -0
- /package/dist/{chunk-4A4FNG4R.js.map → chunk-7ZV626YS.js.map} +0 -0
- /package/dist/{chunk-57ROW3XF.js.map → chunk-ABOZV47D.js.map} +0 -0
- /package/dist/{chunk-3BILL33A.js.map → chunk-BIQ5TG3T.js.map} +0 -0
- /package/dist/{chunk-JINWKUKR.js.map → chunk-BT6CC6QB.js.map} +0 -0
- /package/dist/{chunk-4PEK3YOW.js.map → chunk-CNFN6GHY.js.map} +0 -0
- /package/dist/{chunk-X5AT253K.js.map → chunk-CVYGJUWM.js.map} +0 -0
- /package/dist/{chunk-D26RJQU7.js.map → chunk-CX7ETU2F.js.map} +0 -0
- /package/dist/{chunk-4CDLPMJK.js.map → chunk-D7LV3USE.js.map} +0 -0
- /package/dist/{chunk-WZKKQNYY.js.map → chunk-GA7OSSEA.js.map} +0 -0
- /package/dist/{chunk-EL6KZO43.js.map → chunk-GFWXDWEE.js.map} +0 -0
- /package/dist/{chunk-AQV7RQZH.js.map → chunk-K4WU4JOP.js.map} +0 -0
- /package/dist/{chunk-CAOMKM55.js.map → chunk-L7MVGGBH.js.map} +0 -0
- /package/dist/{chunk-P56JWQYV.js.map → chunk-LRFVISLA.js.map} +0 -0
- /package/dist/{chunk-2U6BQ5C4.js.map → chunk-MJHQMQEW.js.map} +0 -0
- /package/dist/{chunk-C7I4ZG6Q.js.map → chunk-TX552FQG.js.map} +0 -0
- /package/dist/{chunk-4CRLQMJ2.js.map → chunk-VIDRZCPQ.js.map} +0 -0
- /package/dist/{chunk-HCUZYGUK.js.map → chunk-WPTFJZ4L.js.map} +0 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readBoundedJsonResponse
|
|
3
|
+
} from "./chunk-B3ZHJ2KK.js";
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_MODEL_BASE_URL
|
|
6
|
+
} from "./chunk-QYWPNNP3.js";
|
|
7
|
+
|
|
8
|
+
// src/product-model-wire.ts
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
var ProductModelError = class extends Error {
|
|
11
|
+
constructor(code, status, outcomeUnknown, requestId, clientRequestId) {
|
|
12
|
+
super(`OpenPond model request failed (${code}).`);
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.outcomeUnknown = outcomeUnknown;
|
|
16
|
+
this.requestId = requestId;
|
|
17
|
+
this.clientRequestId = clientRequestId;
|
|
18
|
+
this.name = "ProductModelError";
|
|
19
|
+
}
|
|
20
|
+
code;
|
|
21
|
+
status;
|
|
22
|
+
outcomeUnknown;
|
|
23
|
+
requestId;
|
|
24
|
+
clientRequestId;
|
|
25
|
+
};
|
|
26
|
+
var ProductModelToolCallSchema = z.object({
|
|
27
|
+
id: z.string(),
|
|
28
|
+
type: z.literal("function").default("function"),
|
|
29
|
+
function: z.object({ name: z.string(), arguments: z.string() })
|
|
30
|
+
}).passthrough();
|
|
31
|
+
var ProductModelUsageSchema = z.object({
|
|
32
|
+
prompt_tokens: z.number().int().nonnegative(),
|
|
33
|
+
completion_tokens: z.number().int().nonnegative(),
|
|
34
|
+
total_tokens: z.number().int().nonnegative()
|
|
35
|
+
});
|
|
36
|
+
var ProductModelChunkSchema = z.object({
|
|
37
|
+
id: z.string(),
|
|
38
|
+
model: z.string(),
|
|
39
|
+
system_fingerprint: z.string().nullable().optional(),
|
|
40
|
+
openpond: z.record(z.string(), z.json()).optional(),
|
|
41
|
+
usage: ProductModelUsageSchema.nullable().optional(),
|
|
42
|
+
choices: z.array(
|
|
43
|
+
z.object({
|
|
44
|
+
index: z.number().int(),
|
|
45
|
+
finish_reason: z.string().nullable().optional(),
|
|
46
|
+
delta: z.object({
|
|
47
|
+
content: z.string().nullable().optional(),
|
|
48
|
+
tool_calls: z.unknown().optional()
|
|
49
|
+
}).passthrough().optional(),
|
|
50
|
+
message: z.object({
|
|
51
|
+
content: z.string().nullable(),
|
|
52
|
+
tool_calls: z.unknown().optional()
|
|
53
|
+
}).passthrough().optional()
|
|
54
|
+
})
|
|
55
|
+
).max(1)
|
|
56
|
+
}).passthrough();
|
|
57
|
+
var ProductModelRequestStatusSchema = z.object({
|
|
58
|
+
schemaVersion: z.literal("openpond.modelRequestStatus.v1"),
|
|
59
|
+
requestId: z.string().regex(/^pinf_[A-Za-z0-9-]{8,191}$/),
|
|
60
|
+
clientRequestId: z.uuid().nullable(),
|
|
61
|
+
modelId: z.string(),
|
|
62
|
+
state: z.enum([
|
|
63
|
+
"pending",
|
|
64
|
+
"running",
|
|
65
|
+
"stopping",
|
|
66
|
+
"completed",
|
|
67
|
+
"failed",
|
|
68
|
+
"cancelled"
|
|
69
|
+
]),
|
|
70
|
+
deadlineAt: z.iso.datetime(),
|
|
71
|
+
retryAt: z.iso.datetime().nullable(),
|
|
72
|
+
result: ProductModelChunkSchema.nullable(),
|
|
73
|
+
failureCode: z.string().nullable()
|
|
74
|
+
}).strict();
|
|
75
|
+
function canonicalResponseModelId(modelId) {
|
|
76
|
+
const name = modelId.startsWith("personalized:") ? modelId.slice("personalized:".length) : null;
|
|
77
|
+
return name && /^[a-z0-9][a-z0-9._:-]{2,127}$/.test(name) ? name : modelId;
|
|
78
|
+
}
|
|
79
|
+
function productModelEndpoint(value) {
|
|
80
|
+
const url = new URL(value);
|
|
81
|
+
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash)
|
|
82
|
+
throw new Error("A clean serving base URL is required.");
|
|
83
|
+
return url.href.replace(/\/$/, "");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/product-model-transport.ts
|
|
87
|
+
import { z as z2 } from "zod";
|
|
88
|
+
|
|
89
|
+
// src/product-model-response.ts
|
|
90
|
+
function boundProductModelResponse(response, context = {}) {
|
|
91
|
+
const headers = new Headers(response.headers);
|
|
92
|
+
if (context.clientRequestId) headers.set("x-openpond-client-request-id", context.clientRequestId);
|
|
93
|
+
if (!response.body) return new Response(null, { status: response.status, statusText: response.statusText, headers });
|
|
94
|
+
const streaming = response.headers.get("content-type")?.includes("text/event-stream") ?? false;
|
|
95
|
+
const reader = response.body.getReader();
|
|
96
|
+
const decoder = new TextDecoder();
|
|
97
|
+
let total = 0, pending = "", terminal = false;
|
|
98
|
+
let identity;
|
|
99
|
+
const fail = () => new ProductModelError(
|
|
100
|
+
streaming ? "model_stream_interrupted" : "model_response_invalid",
|
|
101
|
+
response.status,
|
|
102
|
+
true,
|
|
103
|
+
context.requestId ?? response.headers.get("x-openpond-request-id") ?? response.headers.get("x-request-id") ?? void 0,
|
|
104
|
+
context.clientRequestId
|
|
105
|
+
);
|
|
106
|
+
let closed = false;
|
|
107
|
+
let cancellation;
|
|
108
|
+
const cancelReader = (reason) => cancellation ??= reader.cancel(reason).finally(() => reader.releaseLock());
|
|
109
|
+
let abort;
|
|
110
|
+
const cleanup = () => {
|
|
111
|
+
if (abort) context.signal?.removeEventListener("abort", abort);
|
|
112
|
+
};
|
|
113
|
+
const body = new ReadableStream({
|
|
114
|
+
start(controller) {
|
|
115
|
+
abort = () => {
|
|
116
|
+
if (closed) return;
|
|
117
|
+
closed = true;
|
|
118
|
+
cleanup();
|
|
119
|
+
void cancelReader().catch(() => {
|
|
120
|
+
});
|
|
121
|
+
controller.error(fail());
|
|
122
|
+
};
|
|
123
|
+
context.signal?.addEventListener("abort", abort, { once: true });
|
|
124
|
+
if (context.signal?.aborted) abort();
|
|
125
|
+
},
|
|
126
|
+
async pull(controller) {
|
|
127
|
+
if (closed) return;
|
|
128
|
+
try {
|
|
129
|
+
const { done, value } = await reader.read();
|
|
130
|
+
if (closed) return;
|
|
131
|
+
if (done) {
|
|
132
|
+
if (streaming && !terminal) throw fail();
|
|
133
|
+
closed = true;
|
|
134
|
+
cleanup();
|
|
135
|
+
controller.close();
|
|
136
|
+
reader.releaseLock();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
total += value.byteLength;
|
|
140
|
+
if (total > 8 * 1024 * 1024) throw fail();
|
|
141
|
+
if (streaming) {
|
|
142
|
+
pending = (pending + decoder.decode(value, { stream: true })).replace(/\r\n/g, "\n");
|
|
143
|
+
let boundary;
|
|
144
|
+
while ((boundary = pending.indexOf("\n\n")) >= 0) {
|
|
145
|
+
const frame = pending.slice(0, boundary);
|
|
146
|
+
pending = pending.slice(boundary + 2);
|
|
147
|
+
if (new TextEncoder().encode(frame).length > 1024 * 1024) throw fail();
|
|
148
|
+
const data = frame.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
149
|
+
if (data === "[DONE]") terminal = true;
|
|
150
|
+
else if (data) {
|
|
151
|
+
const chunk = JSON.parse(data);
|
|
152
|
+
if (typeof chunk.id === "string" && typeof chunk.model === "string") {
|
|
153
|
+
if (identity && (chunk.id !== identity.id || chunk.model !== identity.model))
|
|
154
|
+
throw fail();
|
|
155
|
+
identity = { id: chunk.id, model: chunk.model };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (new TextEncoder().encode(pending).length > 1024 * 1024) throw fail();
|
|
160
|
+
}
|
|
161
|
+
controller.enqueue(value);
|
|
162
|
+
} catch {
|
|
163
|
+
if (closed) return;
|
|
164
|
+
closed = true;
|
|
165
|
+
cleanup();
|
|
166
|
+
await cancelReader().catch(() => {
|
|
167
|
+
});
|
|
168
|
+
controller.error(fail());
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
async cancel(reason) {
|
|
172
|
+
closed = true;
|
|
173
|
+
cleanup();
|
|
174
|
+
await cancelReader(reason);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return new Response(body, {
|
|
178
|
+
status: response.status,
|
|
179
|
+
statusText: response.statusText,
|
|
180
|
+
headers
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// src/product-model-transport.ts
|
|
185
|
+
var MAX_BODY_BYTES = 8 * 1024 * 1024;
|
|
186
|
+
var RequestId = ProductModelRequestStatusSchema.shape.requestId;
|
|
187
|
+
var unknown = (identity, status = 0) => new ProductModelError("model_outcome_unknown", status, true, identity.requestId, identity.clientRequestId);
|
|
188
|
+
var ProductModelTransport = class {
|
|
189
|
+
constructor(modelId, connection) {
|
|
190
|
+
this.modelId = modelId;
|
|
191
|
+
this.connection = connection;
|
|
192
|
+
this.endpoint = `${productModelEndpoint(connection.baseUrl)}/chat/completions`;
|
|
193
|
+
}
|
|
194
|
+
modelId;
|
|
195
|
+
connection;
|
|
196
|
+
identities = /* @__PURE__ */ new WeakMap();
|
|
197
|
+
endpoint;
|
|
198
|
+
identity(response) {
|
|
199
|
+
return this.identities.get(response) ?? {};
|
|
200
|
+
}
|
|
201
|
+
budget(timeoutMs, signal) {
|
|
202
|
+
const timeout = AbortSignal.timeout(timeoutMs);
|
|
203
|
+
return { until: Date.now() + timeoutMs, signal: signal ? AbortSignal.any([signal, timeout]) : timeout };
|
|
204
|
+
}
|
|
205
|
+
headers(extra) {
|
|
206
|
+
const headers = new Headers(extra);
|
|
207
|
+
headers.delete("openpond-api-key");
|
|
208
|
+
headers.set("Authorization", `Bearer ${this.connection.apiKey}`);
|
|
209
|
+
headers.delete("X-OpenPond-Team-Id");
|
|
210
|
+
if (this.connection.teamId) headers.set("X-OpenPond-Team-Id", this.connection.teamId);
|
|
211
|
+
return headers;
|
|
212
|
+
}
|
|
213
|
+
async fetchResponse(url, init, budget, identity) {
|
|
214
|
+
if (budget.signal.aborted || Date.now() >= budget.until) throw unknown(identity);
|
|
215
|
+
let response;
|
|
216
|
+
try {
|
|
217
|
+
response = await (this.connection.fetch ?? fetch)(url, {
|
|
218
|
+
...init,
|
|
219
|
+
redirect: "error",
|
|
220
|
+
signal: budget.signal
|
|
221
|
+
});
|
|
222
|
+
} catch {
|
|
223
|
+
throw unknown(identity);
|
|
224
|
+
}
|
|
225
|
+
const observedId = response.headers.get("x-openpond-request-id") ?? response.headers.get("x-request-id");
|
|
226
|
+
if (!identity.requestId && observedId && (init.method !== "GET" && response.status !== 202 || RequestId.safeParse(observedId).success)) identity.requestId = observedId;
|
|
227
|
+
if (!response.ok) {
|
|
228
|
+
await response.body?.cancel().catch(() => {
|
|
229
|
+
});
|
|
230
|
+
throw new ProductModelError(
|
|
231
|
+
init.method === "GET" ? "model_status_unavailable" : "model_request_rejected",
|
|
232
|
+
response.status,
|
|
233
|
+
response.status === 408 || response.status >= 500,
|
|
234
|
+
identity.requestId,
|
|
235
|
+
identity.clientRequestId
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
const bounded = boundProductModelResponse(response, { signal: budget.signal, ...identity });
|
|
239
|
+
this.identities.set(bounded, { ...identity });
|
|
240
|
+
return bounded;
|
|
241
|
+
}
|
|
242
|
+
async request(body, options) {
|
|
243
|
+
if (new TextEncoder().encode(body).length > 1024 * 1024)
|
|
244
|
+
throw new ProductModelError("payload_too_large", 0, false);
|
|
245
|
+
const headers = this.headers(options.headers);
|
|
246
|
+
const parsedId = z2.uuid().safeParse(options.clientRequestId ?? headers.get("X-OpenPond-Client-Request-Id") ?? crypto.randomUUID());
|
|
247
|
+
if (!parsedId.success) throw new ProductModelError("client_request_id_invalid", 0, false);
|
|
248
|
+
const identity = { clientRequestId: parsedId.data };
|
|
249
|
+
headers.set("X-OpenPond-Client-Request-Id", parsedId.data);
|
|
250
|
+
headers.delete("idempotency-key");
|
|
251
|
+
headers.delete("x-request-id");
|
|
252
|
+
headers.set("Content-Type", "application/json");
|
|
253
|
+
headers.set("Accept", options.stream ? "text/event-stream" : "application/json");
|
|
254
|
+
const budget = this.budget(this.connection.timeoutMs ?? 63e4, options.signal);
|
|
255
|
+
const response = await this.fetchResponse(this.endpoint, { method: "POST", headers, body }, budget, identity);
|
|
256
|
+
if (response.status !== 202) return response;
|
|
257
|
+
const completion = await this.observePending(response, identity, budget);
|
|
258
|
+
let terminal;
|
|
259
|
+
try {
|
|
260
|
+
terminal = terminalResponse(completion, options.stream);
|
|
261
|
+
} catch {
|
|
262
|
+
throw new ProductModelError("model_response_invalid", 200, true, identity.requestId, identity.clientRequestId);
|
|
263
|
+
}
|
|
264
|
+
const bounded = boundProductModelResponse(terminal, { signal: budget.signal, ...identity });
|
|
265
|
+
this.identities.set(bounded, { ...identity });
|
|
266
|
+
return bounded;
|
|
267
|
+
}
|
|
268
|
+
async parseStatus(response, expected, deadlineAt) {
|
|
269
|
+
let status;
|
|
270
|
+
try {
|
|
271
|
+
status = ProductModelRequestStatusSchema.parse(await readBoundedJsonResponse(response, MAX_BODY_BYTES, "Model status"));
|
|
272
|
+
} catch {
|
|
273
|
+
throw new ProductModelError("model_response_invalid", response.status, true, expected.requestId, expected.clientRequestId);
|
|
274
|
+
}
|
|
275
|
+
if (status.modelId !== canonicalResponseModelId(this.modelId) || expected.requestId !== void 0 && status.requestId !== expected.requestId || expected.clientRequestId !== void 0 && status.clientRequestId !== expected.clientRequestId || deadlineAt !== void 0 && status.deadlineAt !== deadlineAt)
|
|
276
|
+
throw new ProductModelError("model_recovery_identity_changed", 409, true, expected.requestId, expected.clientRequestId);
|
|
277
|
+
if (status.result && (status.state !== "completed" || status.failureCode !== null || status.result.id !== status.requestId || status.result.model !== status.modelId || status.result.choices.length !== 1 || status.result.choices[0]?.index !== 0 || !status.result.choices[0]?.message || !status.result.choices[0]?.finish_reason))
|
|
278
|
+
throw new ProductModelError("model_response_invalid", response.status, true, status.requestId, expected.clientRequestId);
|
|
279
|
+
return status;
|
|
280
|
+
}
|
|
281
|
+
async readStatus(suffix, expected, budget, deadlineAt) {
|
|
282
|
+
const headers = this.headers();
|
|
283
|
+
headers.set("Accept", "application/json");
|
|
284
|
+
const response = await this.fetchResponse(`${this.endpoint}${suffix}`, { method: "GET", headers }, budget, expected);
|
|
285
|
+
return this.parseStatus(response, expected, deadlineAt);
|
|
286
|
+
}
|
|
287
|
+
async inspectRequest(requestId) {
|
|
288
|
+
const id = RequestId.parse(requestId);
|
|
289
|
+
return this.readStatus(`/${encodeURIComponent(id)}`, { requestId: id }, this.budget(3e4));
|
|
290
|
+
}
|
|
291
|
+
async recover(clientRequestId) {
|
|
292
|
+
const id = z2.uuid().parse(clientRequestId);
|
|
293
|
+
return this.readStatus(`?clientRequestId=${encodeURIComponent(id)}`, { clientRequestId: id }, this.budget(3e4));
|
|
294
|
+
}
|
|
295
|
+
async observePending(response, identity, budget) {
|
|
296
|
+
let status = await this.parseStatus(response, identity);
|
|
297
|
+
identity.requestId = status.requestId;
|
|
298
|
+
const deadlineAt = status.deadlineAt;
|
|
299
|
+
const remaining = Math.min(budget.until, Date.parse(deadlineAt) + 3e4) - Date.now();
|
|
300
|
+
if (remaining <= 0) throw unknown(identity, 202);
|
|
301
|
+
const observation = this.budget(remaining, budget.signal);
|
|
302
|
+
budget.until = observation.until;
|
|
303
|
+
budget.signal = observation.signal;
|
|
304
|
+
for (; ; ) {
|
|
305
|
+
if (observation.signal.aborted) throw unknown(identity, 202);
|
|
306
|
+
if (status.state === "completed" && status.result) return status.result;
|
|
307
|
+
if (status.state === "completed" || status.state === "failed" || status.state === "cancelled")
|
|
308
|
+
throw new ProductModelError(
|
|
309
|
+
status.state === "completed" ? "model_result_not_retained" : "model_request_failed",
|
|
310
|
+
200,
|
|
311
|
+
false,
|
|
312
|
+
identity.requestId,
|
|
313
|
+
identity.clientRequestId
|
|
314
|
+
);
|
|
315
|
+
const delay = Math.min(observation.until - Date.now(), Math.max(
|
|
316
|
+
500,
|
|
317
|
+
Math.min(15e3, status.retryAt ? Date.parse(status.retryAt) - Date.now() : 2e3)
|
|
318
|
+
));
|
|
319
|
+
await waitForObservation(delay, observation.signal, identity);
|
|
320
|
+
try {
|
|
321
|
+
status = await this.readStatus(
|
|
322
|
+
`/${encodeURIComponent(identity.requestId)}`,
|
|
323
|
+
identity,
|
|
324
|
+
this.budget(Math.max(1, Math.min(3e4, observation.until - Date.now())), observation.signal),
|
|
325
|
+
deadlineAt
|
|
326
|
+
);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
if (error instanceof ProductModelError && ["model_recovery_identity_changed", "model_response_invalid"].includes(error.code)) throw error;
|
|
329
|
+
throw unknown(identity, 202);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async cancelRequest(requestId) {
|
|
334
|
+
const id = RequestId.parse(requestId);
|
|
335
|
+
try {
|
|
336
|
+
const response = await this.fetchResponse(
|
|
337
|
+
`${this.endpoint}/${encodeURIComponent(id)}/cancel`,
|
|
338
|
+
{ method: "POST", headers: this.headers() },
|
|
339
|
+
this.budget(3e4),
|
|
340
|
+
{ requestId: id }
|
|
341
|
+
);
|
|
342
|
+
await response.body?.cancel();
|
|
343
|
+
} catch {
|
|
344
|
+
throw new ProductModelError("model_cancel_pending", 0, true, id);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
async function waitForObservation(delay, signal, identity) {
|
|
349
|
+
if (signal.aborted || delay <= 0) throw unknown(identity, 202);
|
|
350
|
+
await new Promise((resolve, reject) => {
|
|
351
|
+
const abort = () => {
|
|
352
|
+
clearTimeout(timer);
|
|
353
|
+
signal.removeEventListener("abort", abort);
|
|
354
|
+
reject(unknown(identity, 202));
|
|
355
|
+
};
|
|
356
|
+
const timer = setTimeout(() => {
|
|
357
|
+
signal.removeEventListener("abort", abort);
|
|
358
|
+
resolve();
|
|
359
|
+
}, delay);
|
|
360
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
361
|
+
if (signal.aborted) abort();
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
var ToolCalls = z2.array(ProductModelToolCallSchema);
|
|
365
|
+
function terminalResponse(completion, stream) {
|
|
366
|
+
const headers = { "x-openpond-request-id": completion.id, "cache-control": "private, no-store" };
|
|
367
|
+
if (!stream) return Response.json(completion, { headers });
|
|
368
|
+
const choice = completion.choices[0], message = choice.message;
|
|
369
|
+
const identity = {
|
|
370
|
+
id: completion.id,
|
|
371
|
+
model: completion.model,
|
|
372
|
+
created: completion.created,
|
|
373
|
+
system_fingerprint: completion.system_fingerprint
|
|
374
|
+
};
|
|
375
|
+
const frames = [];
|
|
376
|
+
const emit = (delta) => frames.push(`data: ${JSON.stringify({
|
|
377
|
+
...identity,
|
|
378
|
+
choices: [{ index: 0, delta, finish_reason: null }]
|
|
379
|
+
})}
|
|
380
|
+
|
|
381
|
+
`);
|
|
382
|
+
emit({ role: "assistant" });
|
|
383
|
+
if (message.content) for (let offset = 0; offset < message.content.length; offset += 16384)
|
|
384
|
+
emit({ content: message.content.slice(offset, offset + 16384) });
|
|
385
|
+
if (message.tool_calls !== void 0 && message.tool_calls !== null) {
|
|
386
|
+
const tools = ToolCalls.parse(message.tool_calls);
|
|
387
|
+
for (const [index, tool] of tools.entries()) {
|
|
388
|
+
emit({ tool_calls: [{ ...tool, index, type: "function", function: { name: tool.function.name, arguments: "" } }] });
|
|
389
|
+
for (let offset = 0; offset < tool.function.arguments.length; offset += 16384)
|
|
390
|
+
emit({ tool_calls: [{ index, function: { arguments: tool.function.arguments.slice(offset, offset + 16384) } }] });
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
frames.push(`data: ${JSON.stringify({
|
|
394
|
+
...identity,
|
|
395
|
+
openpond: completion.openpond,
|
|
396
|
+
usage: completion.usage,
|
|
397
|
+
choices: [{ index: 0, delta: {}, finish_reason: choice.finish_reason }]
|
|
398
|
+
})}
|
|
399
|
+
|
|
400
|
+
`, "data: [DONE]\n\n");
|
|
401
|
+
return new Response(frames.join(""), { headers: { ...headers, "content-type": "text/event-stream" } });
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// src/product-models.ts
|
|
405
|
+
import { z as z3 } from "zod";
|
|
406
|
+
var Message = z3.object({
|
|
407
|
+
role: z3.enum(["system", "user", "assistant"]),
|
|
408
|
+
content: z3.string().max(2e5)
|
|
409
|
+
}).strict();
|
|
410
|
+
var Input = z3.object({
|
|
411
|
+
prompt: z3.string().max(2e5).optional(),
|
|
412
|
+
messages: z3.array(Message).min(1).max(128).optional(),
|
|
413
|
+
temperature: z3.number().min(0).max(2).optional(),
|
|
414
|
+
maxTokens: z3.number().int().min(1).max(4096).optional()
|
|
415
|
+
}).strict().refine(
|
|
416
|
+
(v) => v.prompt !== void 0 !== (v.messages !== void 0),
|
|
417
|
+
"Supply prompt or messages, exclusively."
|
|
418
|
+
);
|
|
419
|
+
var ProductModel = class {
|
|
420
|
+
constructor(binding, connection) {
|
|
421
|
+
this.connection = connection;
|
|
422
|
+
this.id = z3.string().trim().regex(/^[a-z0-9][a-z0-9._:-]{2,127}$/).parse(typeof binding === "string" ? binding : binding.id);
|
|
423
|
+
this.capabilities = {
|
|
424
|
+
streaming: true,
|
|
425
|
+
tools: false,
|
|
426
|
+
structuredOutput: false,
|
|
427
|
+
...typeof binding === "string" ? {} : binding.capabilities
|
|
428
|
+
};
|
|
429
|
+
if (!connection.apiKey.trim())
|
|
430
|
+
throw new Error("Named models require an API key.");
|
|
431
|
+
this.connection = {
|
|
432
|
+
...connection,
|
|
433
|
+
baseUrl: productModelEndpoint(
|
|
434
|
+
connection.baseUrl ?? DEFAULT_MODEL_BASE_URL
|
|
435
|
+
)
|
|
436
|
+
};
|
|
437
|
+
if (connection.timeoutMs !== void 0 && (!Number.isFinite(connection.timeoutMs) || connection.timeoutMs <= 0 || connection.timeoutMs > 63e4))
|
|
438
|
+
throw new Error(
|
|
439
|
+
"Serving timeoutMs must be greater than zero and at most 630000."
|
|
440
|
+
);
|
|
441
|
+
this.transport = new ProductModelTransport(this.id, this.connection);
|
|
442
|
+
}
|
|
443
|
+
connection;
|
|
444
|
+
id;
|
|
445
|
+
capabilities;
|
|
446
|
+
transport;
|
|
447
|
+
/** Provider integrations use the same exact destination and transport. */
|
|
448
|
+
providerConnection() {
|
|
449
|
+
return { ...this.connection };
|
|
450
|
+
}
|
|
451
|
+
async request(input, stream) {
|
|
452
|
+
if (stream && !this.capabilities.streaming)
|
|
453
|
+
throw new ProductModelError("streaming_unsupported", 0, false);
|
|
454
|
+
const { signal, clientRequestId: suppliedClientId, ...raw } = input;
|
|
455
|
+
const parsed = Input.parse(raw);
|
|
456
|
+
const body = JSON.stringify({
|
|
457
|
+
model: this.id,
|
|
458
|
+
messages: parsed.messages ?? [{ role: "user", content: parsed.prompt }],
|
|
459
|
+
...parsed.temperature === void 0 ? {} : { temperature: parsed.temperature },
|
|
460
|
+
...parsed.maxTokens === void 0 ? {} : { max_tokens: parsed.maxTokens },
|
|
461
|
+
stream
|
|
462
|
+
});
|
|
463
|
+
return this.transport.request(body, { stream, signal, clientRequestId: suppliedClientId });
|
|
464
|
+
}
|
|
465
|
+
async generate(input) {
|
|
466
|
+
const response = await this.request(input, false);
|
|
467
|
+
try {
|
|
468
|
+
const chunk = ProductModelChunkSchema.parse(
|
|
469
|
+
await readBoundedJsonResponse(
|
|
470
|
+
response,
|
|
471
|
+
8 * 1024 * 1024,
|
|
472
|
+
"Model result"
|
|
473
|
+
)
|
|
474
|
+
);
|
|
475
|
+
if (chunk.choices.length !== 1 || !chunk.choices[0].message || chunk.choices[0].message.tool_calls)
|
|
476
|
+
throw new Error("Unsupported response");
|
|
477
|
+
return this.result(
|
|
478
|
+
chunk,
|
|
479
|
+
chunk.choices[0].message.content ?? "",
|
|
480
|
+
chunk.choices[0].finish_reason ?? null,
|
|
481
|
+
response
|
|
482
|
+
);
|
|
483
|
+
} catch {
|
|
484
|
+
throw new ProductModelError(
|
|
485
|
+
"model_response_invalid",
|
|
486
|
+
response.status,
|
|
487
|
+
true,
|
|
488
|
+
response.headers.get("x-openpond-request-id") ?? response.headers.get("x-request-id") ?? void 0,
|
|
489
|
+
this.transport.identity(response).clientRequestId
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
/** Read only: a timeout never submits another paid operation. */
|
|
494
|
+
async inspectRequest(requestId) {
|
|
495
|
+
return this.projectStatus(await this.transport.inspectRequest(requestId));
|
|
496
|
+
}
|
|
497
|
+
async recover(clientRequestId) {
|
|
498
|
+
return this.projectStatus(await this.transport.recover(clientRequestId));
|
|
499
|
+
}
|
|
500
|
+
projectStatus(status) {
|
|
501
|
+
if (!status.result) return { ...status, result: null };
|
|
502
|
+
const message = status.result.choices[0].message;
|
|
503
|
+
let toolCalls;
|
|
504
|
+
if (message.tool_calls !== void 0 && message.tool_calls !== null) {
|
|
505
|
+
const parsed = z3.array(ProductModelToolCallSchema).safeParse(message.tool_calls);
|
|
506
|
+
if (!this.capabilities.tools || !parsed.success)
|
|
507
|
+
throw new ProductModelError(
|
|
508
|
+
"model_response_invalid",
|
|
509
|
+
200,
|
|
510
|
+
true,
|
|
511
|
+
status.requestId,
|
|
512
|
+
status.clientRequestId ?? void 0
|
|
513
|
+
);
|
|
514
|
+
toolCalls = parsed.data;
|
|
515
|
+
}
|
|
516
|
+
return { ...status, result: {
|
|
517
|
+
...this.result(
|
|
518
|
+
status.result,
|
|
519
|
+
message.content ?? "",
|
|
520
|
+
status.result.choices[0].finish_reason ?? null,
|
|
521
|
+
new Response(null)
|
|
522
|
+
),
|
|
523
|
+
...toolCalls === void 0 ? {} : { toolCalls }
|
|
524
|
+
} };
|
|
525
|
+
}
|
|
526
|
+
/** Explicit cancellation retains the original request's cleanup owner. */
|
|
527
|
+
async cancelRequest(requestId) {
|
|
528
|
+
await this.transport.cancelRequest(requestId);
|
|
529
|
+
}
|
|
530
|
+
result(chunk, text, finishReason, response) {
|
|
531
|
+
return {
|
|
532
|
+
text,
|
|
533
|
+
requestId: response.headers.get("x-openpond-request-id") ?? response.headers.get("x-request-id") ?? chunk.id,
|
|
534
|
+
modelId: this.id,
|
|
535
|
+
resolvedModelId: chunk.model,
|
|
536
|
+
finishReason,
|
|
537
|
+
usage: chunk.usage ? {
|
|
538
|
+
inputTokens: chunk.usage.prompt_tokens,
|
|
539
|
+
outputTokens: chunk.usage.completion_tokens,
|
|
540
|
+
totalTokens: chunk.usage.total_tokens
|
|
541
|
+
} : null,
|
|
542
|
+
systemFingerprint: chunk.system_fingerprint ?? null,
|
|
543
|
+
evidence: chunk.openpond ?? null
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/** Breaking iteration cancels the HTTP body. A truncated stream never produces finish. */
|
|
547
|
+
async *stream(input) {
|
|
548
|
+
const response = await this.request(input, true);
|
|
549
|
+
if (!response.headers.get("content-type")?.includes("text/event-stream") || !response.body) {
|
|
550
|
+
await response.body?.cancel();
|
|
551
|
+
throw new ProductModelError(
|
|
552
|
+
"model_stream_invalid",
|
|
553
|
+
response.status,
|
|
554
|
+
true,
|
|
555
|
+
response.headers.get("x-openpond-request-id") ?? void 0,
|
|
556
|
+
this.transport.identity(response).clientRequestId
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
const reader = response.body.getReader();
|
|
560
|
+
const decoder = new TextDecoder();
|
|
561
|
+
let buffer = "", text = "", finish = null, last;
|
|
562
|
+
let usage = null;
|
|
563
|
+
let outputBytes = 0;
|
|
564
|
+
try {
|
|
565
|
+
for (; ; ) {
|
|
566
|
+
const { done, value } = await reader.read();
|
|
567
|
+
buffer = (buffer + decoder.decode(value, { stream: !done })).replace(
|
|
568
|
+
/\r\n/g,
|
|
569
|
+
"\n"
|
|
570
|
+
);
|
|
571
|
+
if (new TextEncoder().encode(buffer).length > 1024 * 1024)
|
|
572
|
+
throw new Error("Stream frame too large");
|
|
573
|
+
let boundary;
|
|
574
|
+
while ((boundary = buffer.indexOf("\n\n")) >= 0) {
|
|
575
|
+
const frame = buffer.slice(0, boundary);
|
|
576
|
+
buffer = buffer.slice(boundary + 2);
|
|
577
|
+
const data = frame.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join("\n");
|
|
578
|
+
if (!data) continue;
|
|
579
|
+
if (data === "[DONE]") {
|
|
580
|
+
if (!last || !finish) throw new Error("Incomplete stream");
|
|
581
|
+
yield {
|
|
582
|
+
type: "finish",
|
|
583
|
+
result: this.result({ ...last, usage }, text, finish, response)
|
|
584
|
+
};
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
const chunk = ProductModelChunkSchema.parse(JSON.parse(data));
|
|
588
|
+
if (last && (last.id !== chunk.id || last.model !== chunk.model))
|
|
589
|
+
throw new Error("Stream identity changed");
|
|
590
|
+
last = chunk;
|
|
591
|
+
if (chunk.usage) usage = chunk.usage;
|
|
592
|
+
const choice = chunk.choices[0];
|
|
593
|
+
if (choice?.delta?.tool_calls)
|
|
594
|
+
throw new Error("Tool output unsupported by text API");
|
|
595
|
+
if (choice?.finish_reason) finish = choice.finish_reason;
|
|
596
|
+
const delta = choice?.delta?.content;
|
|
597
|
+
if (delta) {
|
|
598
|
+
text += delta;
|
|
599
|
+
outputBytes += new TextEncoder().encode(delta).length;
|
|
600
|
+
if (outputBytes > 8 * 1024 * 1024)
|
|
601
|
+
throw new Error("Model output too large");
|
|
602
|
+
yield { type: "text", text: delta };
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
if (done) throw new Error("Stream ended before DONE");
|
|
606
|
+
}
|
|
607
|
+
} catch (error) {
|
|
608
|
+
if (error instanceof ProductModelError) throw error;
|
|
609
|
+
throw new ProductModelError(
|
|
610
|
+
"model_stream_interrupted",
|
|
611
|
+
response.status,
|
|
612
|
+
true,
|
|
613
|
+
response.headers.get("x-openpond-request-id") ?? response.headers.get("x-request-id") ?? void 0,
|
|
614
|
+
this.transport.identity(response).clientRequestId
|
|
615
|
+
);
|
|
616
|
+
} finally {
|
|
617
|
+
await reader.cancel().catch(() => {
|
|
618
|
+
});
|
|
619
|
+
reader.releaseLock();
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
function createProductModels(bindings, connection) {
|
|
624
|
+
return Object.fromEntries(
|
|
625
|
+
Object.entries(bindings).map(([name, binding]) => [
|
|
626
|
+
name,
|
|
627
|
+
new ProductModel(binding, connection)
|
|
628
|
+
])
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
export {
|
|
633
|
+
ProductModelError,
|
|
634
|
+
productModelEndpoint,
|
|
635
|
+
ProductModelTransport,
|
|
636
|
+
ProductModel,
|
|
637
|
+
createProductModels
|
|
638
|
+
};
|
|
639
|
+
//# sourceMappingURL=chunk-ON3KSXWR.js.map
|