@wmaurer/effect-ai-amazon-bedrock 0.1.0 → 0.3.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 +24 -0
- package/README.md +97 -16
- package/dist/AmazonBedrockClient.d.ts +135 -23
- package/dist/AmazonBedrockClient.d.ts.map +1 -1
- package/dist/AmazonBedrockClient.js +36 -92
- package/dist/AmazonBedrockClient.js.map +1 -1
- package/dist/AmazonBedrockConfig.d.ts +6 -6
- package/dist/AmazonBedrockConfig.js +4 -4
- package/dist/AmazonBedrockEventStream.d.ts +2 -2
- package/dist/AmazonBedrockEventStream.js +3 -3
- package/dist/AmazonBedrockLanguageModel.d.ts +22 -22
- package/dist/AmazonBedrockLanguageModel.d.ts.map +1 -1
- package/dist/AmazonBedrockLanguageModel.js +77 -28
- package/dist/AmazonBedrockLanguageModel.js.map +1 -1
- package/dist/AmazonBedrockSchema.d.ts +76 -55
- package/dist/AmazonBedrockSchema.d.ts.map +1 -1
- package/dist/AmazonBedrockSchema.js +63 -50
- package/dist/AmazonBedrockSchema.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -6
- package/dist/internal/credentials.d.ts +79 -0
- package/dist/internal/credentials.d.ts.map +1 -0
- package/dist/internal/credentials.js +241 -0
- package/dist/internal/credentials.js.map +1 -0
- package/dist/internal/errors.d.ts +2 -0
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +6 -0
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/utilities.d.ts +1 -1
- package/dist/internal/utilities.d.ts.map +1 -1
- package/dist/internal/utilities.js +4 -5
- package/dist/internal/utilities.js.map +1 -1
- package/package.json +1 -1
- package/src/AmazonBedrockClient.ts +184 -95
- package/src/AmazonBedrockConfig.ts +6 -6
- package/src/AmazonBedrockEventStream.ts +3 -3
- package/src/AmazonBedrockLanguageModel.ts +136 -62
- package/src/AmazonBedrockSchema.ts +77 -54
- package/src/index.ts +6 -6
- package/src/internal/credentials.ts +319 -0
- package/src/internal/errors.ts +5 -0
- package/src/internal/utilities.ts +7 -7
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* deltas Converse returns are surfaced as document source parts.
|
|
24
24
|
*
|
|
25
25
|
* @stability unstable
|
|
26
|
-
* @since
|
|
26
|
+
* @since 0.1.0
|
|
27
27
|
*/
|
|
28
28
|
import * as AiError from "effect/ai/AiError"
|
|
29
29
|
import { toCodecAnthropic } from "effect/ai/AnthropicStructuredOutput"
|
|
@@ -73,7 +73,7 @@ import * as InternalUtilities from "./internal/utilities.ts"
|
|
|
73
73
|
*
|
|
74
74
|
* @stability unstable
|
|
75
75
|
* @category models
|
|
76
|
-
* @since
|
|
76
|
+
* @since 0.1.0
|
|
77
77
|
*/
|
|
78
78
|
export type Model = string & {}
|
|
79
79
|
|
|
@@ -92,7 +92,7 @@ export type Model = string & {}
|
|
|
92
92
|
*
|
|
93
93
|
* @stability unstable
|
|
94
94
|
* @category models
|
|
95
|
-
* @since
|
|
95
|
+
* @since 0.1.0
|
|
96
96
|
*/
|
|
97
97
|
export type CachePoint = typeof CachePointBlock.Encoded
|
|
98
98
|
|
|
@@ -123,7 +123,7 @@ export type CachePoint = typeof CachePointBlock.Encoded
|
|
|
123
123
|
*
|
|
124
124
|
* @stability unstable
|
|
125
125
|
* @category services
|
|
126
|
-
* @since
|
|
126
|
+
* @since 0.1.0
|
|
127
127
|
*/
|
|
128
128
|
export const ToolCachePoint = Context.Reference<CachePoint | undefined>(
|
|
129
129
|
"@wmaurer/effect-ai-amazon-bedrock/AmazonBedrockLanguageModel/ToolCachePoint",
|
|
@@ -154,7 +154,7 @@ declare module "effect/ai/Prompt" {
|
|
|
154
154
|
*
|
|
155
155
|
* @stability unstable
|
|
156
156
|
* @category models
|
|
157
|
-
* @since
|
|
157
|
+
* @since 0.1.0
|
|
158
158
|
*/
|
|
159
159
|
export interface SystemMessageOptions extends CachePointOptions {}
|
|
160
160
|
|
|
@@ -163,7 +163,7 @@ declare module "effect/ai/Prompt" {
|
|
|
163
163
|
*
|
|
164
164
|
* @stability unstable
|
|
165
165
|
* @category models
|
|
166
|
-
* @since
|
|
166
|
+
* @since 0.1.0
|
|
167
167
|
*/
|
|
168
168
|
export interface UserMessageOptions extends CachePointOptions {}
|
|
169
169
|
|
|
@@ -172,7 +172,7 @@ declare module "effect/ai/Prompt" {
|
|
|
172
172
|
*
|
|
173
173
|
* @stability unstable
|
|
174
174
|
* @category models
|
|
175
|
-
* @since
|
|
175
|
+
* @since 0.1.0
|
|
176
176
|
*/
|
|
177
177
|
export interface AssistantMessageOptions extends CachePointOptions {}
|
|
178
178
|
|
|
@@ -181,7 +181,7 @@ declare module "effect/ai/Prompt" {
|
|
|
181
181
|
*
|
|
182
182
|
* @stability unstable
|
|
183
183
|
* @category models
|
|
184
|
-
* @since
|
|
184
|
+
* @since 0.1.0
|
|
185
185
|
*/
|
|
186
186
|
export interface ToolMessageOptions extends CachePointOptions {}
|
|
187
187
|
|
|
@@ -190,7 +190,7 @@ declare module "effect/ai/Prompt" {
|
|
|
190
190
|
*
|
|
191
191
|
* @stability unstable
|
|
192
192
|
* @category models
|
|
193
|
-
* @since
|
|
193
|
+
* @since 0.1.0
|
|
194
194
|
*/
|
|
195
195
|
export interface TextPartOptions extends CachePointOptions {}
|
|
196
196
|
|
|
@@ -199,7 +199,7 @@ declare module "effect/ai/Prompt" {
|
|
|
199
199
|
*
|
|
200
200
|
* @stability unstable
|
|
201
201
|
* @category models
|
|
202
|
-
* @since
|
|
202
|
+
* @since 0.1.0
|
|
203
203
|
*/
|
|
204
204
|
export interface ToolCallPartOptions extends CachePointOptions {}
|
|
205
205
|
|
|
@@ -208,7 +208,7 @@ declare module "effect/ai/Prompt" {
|
|
|
208
208
|
*
|
|
209
209
|
* @stability unstable
|
|
210
210
|
* @category models
|
|
211
|
-
* @since
|
|
211
|
+
* @since 0.1.0
|
|
212
212
|
*/
|
|
213
213
|
export interface ToolResultPartOptions extends CachePointOptions {}
|
|
214
214
|
}
|
|
@@ -242,7 +242,7 @@ const pushCachePoint = (
|
|
|
242
242
|
*
|
|
243
243
|
* @stability unstable
|
|
244
244
|
* @category models
|
|
245
|
-
* @since
|
|
245
|
+
* @since 0.1.0
|
|
246
246
|
*/
|
|
247
247
|
export type Citations = typeof CitationsConfig.Encoded
|
|
248
248
|
|
|
@@ -283,7 +283,7 @@ declare module "effect/ai/Prompt" {
|
|
|
283
283
|
*
|
|
284
284
|
* @stability unstable
|
|
285
285
|
* @category models
|
|
286
|
-
* @since
|
|
286
|
+
* @since 0.1.0
|
|
287
287
|
*/
|
|
288
288
|
export interface FilePartOptions extends FileOptions {}
|
|
289
289
|
}
|
|
@@ -299,7 +299,7 @@ declare module "effect/ai/Response" {
|
|
|
299
299
|
*
|
|
300
300
|
* @stability unstable
|
|
301
301
|
* @category models
|
|
302
|
-
* @since
|
|
302
|
+
* @since 0.1.0
|
|
303
303
|
*/
|
|
304
304
|
export interface DocumentSourcePartMetadata extends ProviderMetadata {
|
|
305
305
|
readonly amazonBedrock?: {
|
|
@@ -403,7 +403,7 @@ const citationSource: (
|
|
|
403
403
|
*
|
|
404
404
|
* @stability unstable
|
|
405
405
|
* @category models
|
|
406
|
-
* @since
|
|
406
|
+
* @since 0.1.0
|
|
407
407
|
*/
|
|
408
408
|
export type ReasoningInfo = {
|
|
409
409
|
readonly type: "reasoningText"
|
|
@@ -433,7 +433,7 @@ declare module "effect/ai/Prompt" {
|
|
|
433
433
|
*
|
|
434
434
|
* @stability unstable
|
|
435
435
|
* @category models
|
|
436
|
-
* @since
|
|
436
|
+
* @since 0.1.0
|
|
437
437
|
*/
|
|
438
438
|
export interface ReasoningPartOptions extends ProviderOptions {
|
|
439
439
|
readonly amazonBedrock?: {
|
|
@@ -448,7 +448,7 @@ declare module "effect/ai/Response" {
|
|
|
448
448
|
*
|
|
449
449
|
* @stability unstable
|
|
450
450
|
* @category models
|
|
451
|
-
* @since
|
|
451
|
+
* @since 0.1.0
|
|
452
452
|
*/
|
|
453
453
|
export interface ReasoningPartMetadata extends ProviderMetadata {
|
|
454
454
|
readonly amazonBedrock?: {
|
|
@@ -467,7 +467,7 @@ declare module "effect/ai/Response" {
|
|
|
467
467
|
*
|
|
468
468
|
* @stability unstable
|
|
469
469
|
* @category models
|
|
470
|
-
* @since
|
|
470
|
+
* @since 0.1.0
|
|
471
471
|
*/
|
|
472
472
|
export interface ReasoningDeltaPartMetadata extends ProviderMetadata {
|
|
473
473
|
readonly amazonBedrock?: {
|
|
@@ -525,7 +525,7 @@ const reasoningTextInfo = (signature: string | undefined): ReasoningInfo => ({
|
|
|
525
525
|
*
|
|
526
526
|
* @stability unstable
|
|
527
527
|
* @category configuration
|
|
528
|
-
* @since
|
|
528
|
+
* @since 0.1.0
|
|
529
529
|
*/
|
|
530
530
|
export class Config extends Context.Service<
|
|
531
531
|
Config,
|
|
@@ -554,11 +554,15 @@ export class Config extends Context.Service<
|
|
|
554
554
|
*
|
|
555
555
|
* **Details**
|
|
556
556
|
*
|
|
557
|
-
* Overrides
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
557
|
+
* Overrides the default for the provider that the model identifier
|
|
558
|
+
* names. By default only Claude models, and ARNs that do not name their
|
|
559
|
+
* model, get native structured output. In probes on 2026-10-17 in
|
|
560
|
+
* eu-west-1 and us-east-1, Nova, Mistral Large 2402, Pixtral Large,
|
|
561
|
+
* Llama, and Palmyra answered `outputConfig` with a 400. When `false`,
|
|
562
|
+
* `generateObject` asks for the object through a tool instead, which is
|
|
563
|
+
* forced on models that accept a forced `toolChoice` and left unforced,
|
|
564
|
+
* with an instruction to call it, on models that do not. Never sent to
|
|
565
|
+
* Bedrock.
|
|
562
566
|
*
|
|
563
567
|
* When the prompt holds tool calls or tool results and the request
|
|
564
568
|
* offers no tools, `generateObject` uses the tool even when this is
|
|
@@ -571,12 +575,19 @@ export class Config extends Context.Service<
|
|
|
571
575
|
*
|
|
572
576
|
* **Details**
|
|
573
577
|
*
|
|
574
|
-
* Overrides
|
|
575
|
-
*
|
|
576
|
-
* without native structured output is forced
|
|
577
|
-
* `structuredOutputs: false` it selects between
|
|
578
|
-
* unforced tool, for example for an application
|
|
579
|
-
* which does not name its model. Never sent to
|
|
578
|
+
* Overrides the default for the provider that the model identifier
|
|
579
|
+
* names. It decides whether the tool that `generateObject` uses
|
|
580
|
+
* without native structured output is forced with `toolChoice`
|
|
581
|
+
* `{ any: {} }`, so with `structuredOutputs: false` it selects between
|
|
582
|
+
* the forced and the unforced tool, for example for an application
|
|
583
|
+
* inference profile ARN, which does not name its model. Never sent to
|
|
584
|
+
* Bedrock.
|
|
585
|
+
*
|
|
586
|
+
* By default Meta and Writer models, and Claude Opus 5.5, Sonnet 5.5,
|
|
587
|
+
* Fable 5.1, and Mythos 5.1, get the unforced tool. In probes on
|
|
588
|
+
* 2026-10-17 in us-east-1, Llama 3.1, 3.3, and 4 and Palmyra X4 and X5
|
|
589
|
+
* answered `any` with a 400, and in eu-west-1 Opus 5.5 and Sonnet 5.5
|
|
590
|
+
* rejected both `any` and a named `tool`.
|
|
580
591
|
*
|
|
581
592
|
* It steers only that tool. A `toolChoice` passed with the caller's own
|
|
582
593
|
* tools, such as `"required"` or a named tool, goes to Bedrock
|
|
@@ -598,7 +609,7 @@ export class Config extends Context.Service<
|
|
|
598
609
|
*
|
|
599
610
|
* @stability unstable
|
|
600
611
|
* @category constructors
|
|
601
|
-
* @since
|
|
612
|
+
* @since 0.1.0
|
|
602
613
|
*/
|
|
603
614
|
export const model = (
|
|
604
615
|
model: (string & {}) | Model,
|
|
@@ -612,7 +623,7 @@ export const model = (
|
|
|
612
623
|
*
|
|
613
624
|
* @stability unstable
|
|
614
625
|
* @category constructors
|
|
615
|
-
* @since
|
|
626
|
+
* @since 0.1.0
|
|
616
627
|
*/
|
|
617
628
|
export const make = Effect.fnUntraced(function*({ config: providerConfig, model }: {
|
|
618
629
|
readonly model: (string & {}) | Model
|
|
@@ -674,9 +685,9 @@ export const make = Effect.fnUntraced(function*({ config: providerConfig, model
|
|
|
674
685
|
}
|
|
675
686
|
}
|
|
676
687
|
} else {
|
|
677
|
-
// The object is
|
|
678
|
-
//
|
|
679
|
-
//
|
|
688
|
+
// The object tool is the only tool, so `any` forces it, and
|
|
689
|
+
// Mistral Large 2402 and Pixtral Large accept `any` but reject a
|
|
690
|
+
// named `tool`.
|
|
680
691
|
const forced = forcedToolChoice ?? capabilities.supportsForcedToolChoice
|
|
681
692
|
nameMapper = new Tool.NameMapper([])
|
|
682
693
|
toolConfig = {
|
|
@@ -687,7 +698,7 @@ export const make = Effect.fnUntraced(function*({ config: providerConfig, model
|
|
|
687
698
|
inputSchema: { json: json as Record<string, unknown> }
|
|
688
699
|
}
|
|
689
700
|
}],
|
|
690
|
-
toolChoice: forced ? {
|
|
701
|
+
toolChoice: forced ? { any: {} } : { auto: {} }
|
|
691
702
|
}
|
|
692
703
|
if (!forced) {
|
|
693
704
|
system = [...(system ?? []), {
|
|
@@ -742,7 +753,7 @@ export const make = Effect.fnUntraced(function*({ config: providerConfig, model
|
|
|
742
753
|
*
|
|
743
754
|
* @stability unstable
|
|
744
755
|
* @category layers
|
|
745
|
-
* @since
|
|
756
|
+
* @since 0.1.0
|
|
746
757
|
*/
|
|
747
758
|
export const layer = (options: {
|
|
748
759
|
readonly model: (string & {}) | Model
|
|
@@ -755,7 +766,7 @@ export const layer = (options: {
|
|
|
755
766
|
*
|
|
756
767
|
* @stability unstable
|
|
757
768
|
* @category configuration
|
|
758
|
-
* @since
|
|
769
|
+
* @since 0.1.0
|
|
759
770
|
*/
|
|
760
771
|
export const withConfigOverride: {
|
|
761
772
|
(overrides: typeof Config.Service): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Config>>
|
|
@@ -1124,16 +1135,36 @@ interface ModelCapabilities {
|
|
|
1124
1135
|
}
|
|
1125
1136
|
|
|
1126
1137
|
/**
|
|
1127
|
-
* Returns what a model accepts for structured output,
|
|
1128
|
-
*
|
|
1129
|
-
*
|
|
1138
|
+
* Returns what a model accepts for structured output, looked up by the
|
|
1139
|
+
* provider that the model ID names: `anthropic` in
|
|
1140
|
+
* `eu.anthropic.claude-opus-4-8`, `amazon` in `amazon.nova-pro-v1:0`. A
|
|
1141
|
+
* foundation model or inference profile ARN names its model at the end. Other
|
|
1142
|
+
* ARNs, such as an application inference profile or a provisioned model, do
|
|
1143
|
+
* not. They get the Claude rules, which give them the native structured output
|
|
1144
|
+
* and forced tool of 0.2.0, on the unmeasured assumption that most of them
|
|
1145
|
+
* wrap a Claude model.
|
|
1146
|
+
*
|
|
1147
|
+
* Probes on 2026-10-17, one run per model and call unless noted:
|
|
1130
1148
|
*
|
|
1149
|
+
* - Only Claude gets native structured output. Nova, Mistral Large 2402 and
|
|
1150
|
+
* Pixtral Large in eu-west-1, and Llama, Palmyra, DeepSeek R1, Mistral 7B
|
|
1151
|
+
* and Mixtral in us-east-1, answer `outputConfig` with a 400. gpt-oss-120b
|
|
1152
|
+
* accepts it but wrote text before the JSON in 3 of 4 runs.
|
|
1153
|
+
* - The forced object tool, sent as `{ any: {} }`, returned the object on 15
|
|
1154
|
+
* of 16 models in eu-west-1, Claude Haiku 4.5 and Opus 4.8 included, and
|
|
1155
|
+
* on all 17 models in us-east-1 that accept a forced tool. Magistral Small
|
|
1156
|
+
* fails every object path.
|
|
1157
|
+
* - Llama 3.1, 3.3 and 4 and Palmyra X4 and X5 (`meta`, `writer`) answer
|
|
1158
|
+
* `any` with a 400 in us-east-1, and so does each of them that the probe
|
|
1159
|
+
* sent a named `tool`, all but Llama 3.1 8B. They get the unforced tool. It
|
|
1160
|
+
* returned the object on Llama 3.1 8B, Llama 4 Scout and Maverick and
|
|
1161
|
+
* Palmyra X5, and a wrong object on Llama 3.1 70B and 3.3 70B.
|
|
1131
1162
|
* - Claude models before Opus 4.1 / Sonnet 4.5 predate structured output, as
|
|
1132
1163
|
* in the Anthropic provider. This is not checked on Bedrock: a probe of 17
|
|
1133
|
-
* Claude inference profiles in eu-west-1
|
|
1134
|
-
*
|
|
1135
|
-
* 3
|
|
1136
|
-
* - Every Claude profile that served
|
|
1164
|
+
* Claude inference profiles in eu-west-1 found Claude 3 Haiku, Claude 3
|
|
1165
|
+
* Sonnet and Sonnet 4 at end of life there, and did not try Claude 3 Opus,
|
|
1166
|
+
* 3.5 Haiku, 3.5 Sonnet, 3.7 Sonnet, Opus 4 or Opus 4.1.
|
|
1167
|
+
* - Every Claude profile that served that probe's requests (12 of 17)
|
|
1137
1168
|
* accepted `outputConfig.textFormat`: Haiku 4.5 and 5.5, Opus 4.5 to 4.8, 5
|
|
1138
1169
|
* and 5.5, and Sonnet 4.5, 4.6, 5 and 5.5. Fable 5 and 5.1 rejected every
|
|
1139
1170
|
* request, with or without `textFormat`, with a data-retention
|
|
@@ -1146,23 +1177,51 @@ interface ModelCapabilities {
|
|
|
1146
1177
|
* @see https://platform.claude.com/docs/en/build-with-claude/structured-outputs
|
|
1147
1178
|
*/
|
|
1148
1179
|
const getModelCapabilities = (modelId: string): ModelCapabilities => {
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
modelId
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
)
|
|
1155
|
-
const
|
|
1156
|
-
|
|
1157
|
-
modelId.includes("claude-sonnet-4-20250514") ||
|
|
1158
|
-
modelId.includes("claude-3-7-sonnet") ||
|
|
1159
|
-
modelId.includes("claude-opus-4-0") ||
|
|
1160
|
-
modelId.includes("claude-opus-4-20250514") ||
|
|
1161
|
-
modelId.includes("claude-3-")
|
|
1162
|
-
)
|
|
1163
|
-
return { supportsStructuredOutput, supportsForcedToolChoice }
|
|
1180
|
+
const named = modelId.startsWith("arn:") ? namingArn.exec(modelId)?.[1] : modelId
|
|
1181
|
+
if (Predicate.isUndefined(named)) {
|
|
1182
|
+
return claudeCapabilities(modelId)
|
|
1183
|
+
}
|
|
1184
|
+
// `provider.model`, or `geo.provider.model` for an inference profile.
|
|
1185
|
+
const [first = "", second = ""] = named.split(".")
|
|
1186
|
+
const byProvider = capabilitiesByProvider.get(first) ?? capabilitiesByProvider.get(second)
|
|
1187
|
+
return Predicate.isUndefined(byProvider) ? otherProvider : byProvider(named)
|
|
1164
1188
|
}
|
|
1165
1189
|
|
|
1190
|
+
// Of the ARNs Converse accepts, only these two end in the ID of the model
|
|
1191
|
+
// they invoke.
|
|
1192
|
+
const namingArn = /^arn:[^:]+:bedrock:[^:]*:[^:]*:(?:foundation-model|inference-profile)\/(.+)$/
|
|
1193
|
+
|
|
1194
|
+
const otherProvider: ModelCapabilities = { supportsStructuredOutput: false, supportsForcedToolChoice: true }
|
|
1195
|
+
|
|
1196
|
+
const unforcedTool: ModelCapabilities = { supportsStructuredOutput: false, supportsForcedToolChoice: false }
|
|
1197
|
+
|
|
1198
|
+
const claudeWithoutStructuredOutput = [
|
|
1199
|
+
"claude-sonnet-4-0",
|
|
1200
|
+
"claude-sonnet-4-20250514",
|
|
1201
|
+
"claude-3-7-sonnet",
|
|
1202
|
+
"claude-opus-4-0",
|
|
1203
|
+
"claude-opus-4-20250514",
|
|
1204
|
+
"claude-3-"
|
|
1205
|
+
]
|
|
1206
|
+
|
|
1207
|
+
const claudeWithoutForcedToolChoice = [
|
|
1208
|
+
"claude-opus-5-5",
|
|
1209
|
+
"claude-sonnet-5-5",
|
|
1210
|
+
"claude-fable-5-1",
|
|
1211
|
+
"claude-mythos-5-1"
|
|
1212
|
+
]
|
|
1213
|
+
|
|
1214
|
+
const claudeCapabilities = (modelId: string): ModelCapabilities => ({
|
|
1215
|
+
supportsStructuredOutput: !claudeWithoutStructuredOutput.some((id) => modelId.includes(id)),
|
|
1216
|
+
supportsForcedToolChoice: !claudeWithoutForcedToolChoice.some((id) => modelId.includes(id))
|
|
1217
|
+
})
|
|
1218
|
+
|
|
1219
|
+
const capabilitiesByProvider = new Map<string, (modelId: string) => ModelCapabilities>([
|
|
1220
|
+
["anthropic", claudeCapabilities],
|
|
1221
|
+
["meta", () => unforcedTool],
|
|
1222
|
+
["writer", () => unforcedTool]
|
|
1223
|
+
])
|
|
1224
|
+
|
|
1166
1225
|
const tryJsonSchema = (schema: Schema.Top, method: string) =>
|
|
1167
1226
|
Effect.try({
|
|
1168
1227
|
try: () => Tool.getJsonSchemaFromSchema(schema, { transformer: toCodecAnthropic }),
|
|
@@ -1591,6 +1650,19 @@ const makeStreamResponse: (
|
|
|
1591
1650
|
const block = toolBlocks.get(index)
|
|
1592
1651
|
if (Predicate.isNotUndefined(block)) {
|
|
1593
1652
|
toolBlocks.delete(index)
|
|
1653
|
+
const params = yield* Effect.try({
|
|
1654
|
+
// A tool taking no arguments streams no deltas at all.
|
|
1655
|
+
try: () => Tool.unsafeSecureJsonParse(block.params.length === 0 ? "{}" : block.params),
|
|
1656
|
+
catch: () =>
|
|
1657
|
+
AiError.make({
|
|
1658
|
+
module: "AmazonBedrockLanguageModel",
|
|
1659
|
+
method: "makeStreamResponse",
|
|
1660
|
+
reason: new AiError.InvalidOutputError({
|
|
1661
|
+
description: `Bedrock streamed input for the \`${block.name}\` tool that is not valid JSON: ` +
|
|
1662
|
+
truncate(block.params, 500)
|
|
1663
|
+
})
|
|
1664
|
+
})
|
|
1665
|
+
})
|
|
1594
1666
|
parts.push({
|
|
1595
1667
|
type: "tool-params-end",
|
|
1596
1668
|
id: block.id
|
|
@@ -1599,8 +1671,7 @@ const makeStreamResponse: (
|
|
|
1599
1671
|
type: "tool-call",
|
|
1600
1672
|
id: block.id,
|
|
1601
1673
|
name: block.name,
|
|
1602
|
-
|
|
1603
|
-
params: Tool.unsafeSecureJsonParse(block.params.length === 0 ? "{}" : block.params),
|
|
1674
|
+
params,
|
|
1604
1675
|
providerExecuted: false
|
|
1605
1676
|
})
|
|
1606
1677
|
}
|
|
@@ -1744,3 +1815,6 @@ const trimIfLast = (
|
|
|
1744
1815
|
isLastPart: boolean,
|
|
1745
1816
|
text: string
|
|
1746
1817
|
) => isLastGroup && isLastMessage && isLastPart ? text.trim() : text
|
|
1818
|
+
|
|
1819
|
+
const truncate = (text: string, maxLength: number): string =>
|
|
1820
|
+
text.length > maxLength ? `${text.slice(0, maxLength)}...` : text
|