@absolutejs/ai 0.0.41 → 0.0.42
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 +8 -0
- package/dist/ai/index.js +165 -2
- package/dist/ai/index.js.map +5 -4
- package/dist/ai/providers/anthropic.js +3 -2
- package/dist/ai/providers/anthropic.js.map +3 -3
- package/dist/src/ai/index.d.ts +2 -0
- package/dist/src/ai/providerProxy.d.ts +16 -0
- package/dist/types/anthropic.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,3 +4,11 @@ Standalone AI runtime and provider package extracted from AbsoluteJS.
|
|
|
4
4
|
|
|
5
5
|
This package currently focuses on generic AI/chat/provider functionality.
|
|
6
6
|
RAG remains a separate package.
|
|
7
|
+
|
|
8
|
+
Provider traffic can cross a trusted control plane without reimplementing a
|
|
9
|
+
vendor protocol. `remoteProvider()` carries normalized provider parameters and
|
|
10
|
+
chunks over SSE, while `createProviderProxyResponse()` hosts any
|
|
11
|
+
`AIProviderConfig` with pre-first-token and inter-token heartbeats. Provider
|
|
12
|
+
callbacks and abort objects never cross the wire. The Anthropic provider also
|
|
13
|
+
accepts an injectable `fetch`, allowing hosts to retain egress policy, tracing,
|
|
14
|
+
and test transports.
|
package/dist/ai/index.js
CHANGED
|
@@ -1956,7 +1956,8 @@ async function* parseSSEStream4(body, signal) {
|
|
|
1956
1956
|
var fetchAndStream = async function* (baseUrl, config2, params, configuredMax, promptCaching) {
|
|
1957
1957
|
const body = buildRequestBody4(params, configuredMax, promptCaching);
|
|
1958
1958
|
const target = `${baseUrl}/v1/messages`;
|
|
1959
|
-
const
|
|
1959
|
+
const fetchImpl = config2.fetch ?? fetch;
|
|
1960
|
+
const response = await fetchImpl(target, {
|
|
1960
1961
|
...h2IfHttps4(target),
|
|
1961
1962
|
body: JSON.stringify(body),
|
|
1962
1963
|
headers: {
|
|
@@ -3654,6 +3655,165 @@ var streamAIWithTools = async function* (options) {
|
|
|
3654
3655
|
yield { ...summary, type: "done" };
|
|
3655
3656
|
return summary;
|
|
3656
3657
|
};
|
|
3658
|
+
// src/ai/providerProxy.ts
|
|
3659
|
+
var DEFAULT_HEARTBEAT_MS2 = 5000;
|
|
3660
|
+
var encoder = new TextEncoder;
|
|
3661
|
+
var wireParams = (params) => ({
|
|
3662
|
+
...params.cacheSystemPrompt === undefined ? {} : { cacheSystemPrompt: params.cacheSystemPrompt },
|
|
3663
|
+
...params.frequencyPenalty === undefined ? {} : { frequencyPenalty: params.frequencyPenalty },
|
|
3664
|
+
...params.maxTokens === undefined ? {} : { maxTokens: params.maxTokens },
|
|
3665
|
+
messages: params.messages,
|
|
3666
|
+
model: params.model,
|
|
3667
|
+
...params.parallelToolCalls === undefined ? {} : { parallelToolCalls: params.parallelToolCalls },
|
|
3668
|
+
...params.presencePenalty === undefined ? {} : { presencePenalty: params.presencePenalty },
|
|
3669
|
+
...params.promptCaching === undefined ? {} : { promptCaching: params.promptCaching },
|
|
3670
|
+
...params.reasoning === undefined ? {} : { reasoning: params.reasoning },
|
|
3671
|
+
...params.responseFormat === undefined ? {} : { responseFormat: params.responseFormat },
|
|
3672
|
+
...params.seed === undefined ? {} : { seed: params.seed },
|
|
3673
|
+
...params.stopSequences === undefined ? {} : { stopSequences: params.stopSequences },
|
|
3674
|
+
...params.systemPrompt === undefined ? {} : { systemPrompt: params.systemPrompt },
|
|
3675
|
+
...params.temperature === undefined ? {} : { temperature: params.temperature },
|
|
3676
|
+
...params.toolChoice === undefined ? {} : { toolChoice: params.toolChoice },
|
|
3677
|
+
...params.tools === undefined ? {} : { tools: params.tools },
|
|
3678
|
+
...params.topP === undefined ? {} : { topP: params.topP }
|
|
3679
|
+
});
|
|
3680
|
+
var parseProviderProxyParams = (value) => {
|
|
3681
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3682
|
+
return null;
|
|
3683
|
+
const input = value;
|
|
3684
|
+
if (typeof input.model !== "string" || input.model.trim() === "")
|
|
3685
|
+
return null;
|
|
3686
|
+
if (!Array.isArray(input.messages))
|
|
3687
|
+
return null;
|
|
3688
|
+
return wireParams(input);
|
|
3689
|
+
};
|
|
3690
|
+
var encodeEvent = (event, data) => encoder.encode(`event: ${event}
|
|
3691
|
+
data: ${JSON.stringify(data)}
|
|
3692
|
+
|
|
3693
|
+
`);
|
|
3694
|
+
var errorPayload = (error) => {
|
|
3695
|
+
const providerError = error instanceof ProviderError ? error : ProviderError.from(error, "remote");
|
|
3696
|
+
return {
|
|
3697
|
+
message: providerError.message,
|
|
3698
|
+
provider: providerError.provider,
|
|
3699
|
+
retryable: providerError.retryable,
|
|
3700
|
+
status: providerError.status,
|
|
3701
|
+
type: providerError.type
|
|
3702
|
+
};
|
|
3703
|
+
};
|
|
3704
|
+
var streamResponseBody = (iterator, heartbeatMs, onError) => new ReadableStream({
|
|
3705
|
+
async start(controller) {
|
|
3706
|
+
try {
|
|
3707
|
+
for (;; ) {
|
|
3708
|
+
const pending = iterator.next();
|
|
3709
|
+
let next;
|
|
3710
|
+
for (;; ) {
|
|
3711
|
+
let timer;
|
|
3712
|
+
const heartbeat = new Promise((resolve) => {
|
|
3713
|
+
timer = setTimeout(() => resolve("heartbeat"), heartbeatMs);
|
|
3714
|
+
});
|
|
3715
|
+
const winner = heartbeatMs > 0 ? await Promise.race([pending, heartbeat]) : await pending;
|
|
3716
|
+
if (timer)
|
|
3717
|
+
clearTimeout(timer);
|
|
3718
|
+
if (winner === "heartbeat") {
|
|
3719
|
+
controller.enqueue(encoder.encode(`: ping
|
|
3720
|
+
|
|
3721
|
+
`));
|
|
3722
|
+
continue;
|
|
3723
|
+
}
|
|
3724
|
+
next = winner;
|
|
3725
|
+
break;
|
|
3726
|
+
}
|
|
3727
|
+
if (next.done)
|
|
3728
|
+
break;
|
|
3729
|
+
controller.enqueue(encodeEvent("chunk", next.value));
|
|
3730
|
+
}
|
|
3731
|
+
} catch (error) {
|
|
3732
|
+
await onError?.(error);
|
|
3733
|
+
controller.enqueue(encodeEvent("error", errorPayload(error)));
|
|
3734
|
+
} finally {
|
|
3735
|
+
await iterator.return?.();
|
|
3736
|
+
controller.close();
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
});
|
|
3740
|
+
var createProviderProxyResponse = async (provider, value, options = {}) => {
|
|
3741
|
+
const params = parseProviderProxyParams(value);
|
|
3742
|
+
if (!params) {
|
|
3743
|
+
return Response.json({ error: "invalid provider stream request" }, { status: 400 });
|
|
3744
|
+
}
|
|
3745
|
+
const iterator = provider.stream({ ...params, signal: options.signal })[Symbol.asyncIterator]();
|
|
3746
|
+
return new Response(streamResponseBody(iterator, options.heartbeatMs ?? DEFAULT_HEARTBEAT_MS2, options.onError), {
|
|
3747
|
+
headers: {
|
|
3748
|
+
"cache-control": "no-cache",
|
|
3749
|
+
"content-type": "text/event-stream; charset=utf-8",
|
|
3750
|
+
"x-accel-buffering": "no",
|
|
3751
|
+
...Object.fromEntries(new Headers(options.headers))
|
|
3752
|
+
}
|
|
3753
|
+
});
|
|
3754
|
+
};
|
|
3755
|
+
var parseRemoteStream = async function* (response) {
|
|
3756
|
+
if (!response.ok) {
|
|
3757
|
+
throw ProviderError.fromResponse("remote", response.status, await response.text());
|
|
3758
|
+
}
|
|
3759
|
+
if (!response.body)
|
|
3760
|
+
throw new ProviderError({
|
|
3761
|
+
message: "Remote provider returned no response body",
|
|
3762
|
+
provider: "remote",
|
|
3763
|
+
retryable: true
|
|
3764
|
+
});
|
|
3765
|
+
const reader = response.body.getReader();
|
|
3766
|
+
const decoder = new TextDecoder;
|
|
3767
|
+
let buffer = "";
|
|
3768
|
+
try {
|
|
3769
|
+
for (;; ) {
|
|
3770
|
+
const { done, value } = await reader.read();
|
|
3771
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
3772
|
+
const frames = buffer.split(/\r?\n\r?\n/);
|
|
3773
|
+
buffer = frames.pop() ?? "";
|
|
3774
|
+
for (const frame of frames) {
|
|
3775
|
+
if (frame.startsWith(":"))
|
|
3776
|
+
continue;
|
|
3777
|
+
const event = /^event:\s*(.+)$/m.exec(frame)?.[1];
|
|
3778
|
+
const data = frame.split(/\r?\n/).filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trimStart()).join(`
|
|
3779
|
+
`);
|
|
3780
|
+
if (!data)
|
|
3781
|
+
continue;
|
|
3782
|
+
const parsed = JSON.parse(data);
|
|
3783
|
+
if (event === "error") {
|
|
3784
|
+
throw new ProviderError({
|
|
3785
|
+
message: "message" in parsed && typeof parsed.message === "string" ? parsed.message : "Remote provider stream failed",
|
|
3786
|
+
provider: "provider" in parsed && typeof parsed.provider === "string" ? parsed.provider : "remote",
|
|
3787
|
+
retryable: "retryable" in parsed && typeof parsed.retryable === "boolean" ? parsed.retryable : true,
|
|
3788
|
+
status: "status" in parsed && (typeof parsed.status === "number" || parsed.status === null) ? parsed.status : null,
|
|
3789
|
+
type: "type" in parsed && (typeof parsed.type === "string" || parsed.type === null) ? parsed.type : null
|
|
3790
|
+
});
|
|
3791
|
+
}
|
|
3792
|
+
if (event === "chunk")
|
|
3793
|
+
yield parsed;
|
|
3794
|
+
}
|
|
3795
|
+
if (done)
|
|
3796
|
+
break;
|
|
3797
|
+
}
|
|
3798
|
+
} finally {
|
|
3799
|
+
reader.releaseLock();
|
|
3800
|
+
}
|
|
3801
|
+
};
|
|
3802
|
+
var remoteProvider = (config2) => ({
|
|
3803
|
+
stream: async function* (params) {
|
|
3804
|
+
const headers = typeof config2.headers === "function" ? await config2.headers() : config2.headers;
|
|
3805
|
+
const response = await (config2.fetch ?? fetch)(config2.url, {
|
|
3806
|
+
body: JSON.stringify(wireParams(params)),
|
|
3807
|
+
headers: {
|
|
3808
|
+
"content-type": "application/json",
|
|
3809
|
+
...Object.fromEntries(new Headers(headers))
|
|
3810
|
+
},
|
|
3811
|
+
method: "POST",
|
|
3812
|
+
signal: params.signal
|
|
3813
|
+
});
|
|
3814
|
+
yield* parseRemoteStream(response);
|
|
3815
|
+
}
|
|
3816
|
+
});
|
|
3657
3817
|
// src/ai/ui/uiCards.ts
|
|
3658
3818
|
var createUiCards = (definitions) => {
|
|
3659
3819
|
const byName = new Map(definitions.map((definition) => [definition.name, definition]));
|
|
@@ -5680,11 +5840,13 @@ export {
|
|
|
5680
5840
|
serializeAIMessage,
|
|
5681
5841
|
resolveRenderers,
|
|
5682
5842
|
renderChartSvg,
|
|
5843
|
+
remoteProvider,
|
|
5683
5844
|
providerStatusPage,
|
|
5684
5845
|
planCard,
|
|
5685
5846
|
parseUiActions,
|
|
5686
5847
|
parseTableSpec,
|
|
5687
5848
|
parseStatTilesSpec,
|
|
5849
|
+
parseProviderProxyParams,
|
|
5688
5850
|
parsePlanSpec,
|
|
5689
5851
|
parseFormSpec,
|
|
5690
5852
|
parseDiffSpec,
|
|
@@ -5714,6 +5876,7 @@ export {
|
|
|
5714
5876
|
credentialCard,
|
|
5715
5877
|
createUiCards,
|
|
5716
5878
|
createSyncConversationStore,
|
|
5879
|
+
createProviderProxyResponse,
|
|
5717
5880
|
createOAuth2ClientCredentialsTokenSource,
|
|
5718
5881
|
createMemoryStore,
|
|
5719
5882
|
createConversationManager,
|
|
@@ -5751,5 +5914,5 @@ export {
|
|
|
5751
5914
|
BUILTIN_UI_CARDS
|
|
5752
5915
|
};
|
|
5753
5916
|
|
|
5754
|
-
//# debugId=
|
|
5917
|
+
//# debugId=31B8793E47976E7B64756E2164756E21
|
|
5755
5918
|
//# sourceMappingURL=index.js.map
|