1import * as bedrock from "@distilled.cloud/aws/bedrock-agent-runtime";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as Binding from "../../Binding.ts";
5import { AWSEnvironment } from "../Environment.ts";
6import { isBindingHost } from "../Lambda/Function.ts";
7import { bedrockModelArns } from "./ModelArns.ts";
8import { Rerank, type RerankRequest } from "./Rerank.ts";
9
10// Bespoke (not the shared model-scoped scaffold): Rerank authorizes the
11// `bedrock:Rerank` action only against `*`, alongside model-scoped
12// `bedrock:InvokeModel`, and the model is referenced inside
13// `rerankingConfiguration` rather than a top-level `modelId`.
14export const RerankHttp = Layer.effect(
15 Rerank,
16 Effect.gen(function* () {
17 const rerank = yield* bedrock.rerank;
18
19 return Effect.fn(function* (model: string, ...additionalModels: string[]) {
20 if (!globalThis.__ALCHEMY_RUNTIME__) {
21 const host = yield* Binding.Host;
22 if (isBindingHost(host)) {
23 const { accountId, region } =
24 yield* AWSEnvironment.current as unknown as Effect.Effect<{
25 accountId: string;
26 region: string;
27 }>;
28 // Sort so the binding identity (SID + ARN list) is deterministic
29 // regardless of argument order.
30 const sorted = [...new Set([model, ...additionalModels])].sort();
31 yield* host.bind`Allow(${host}, AWS.Bedrock.Rerank(${sorted.join(",")}))`(
32 {
33 policyStatements: [
34 {
35 // bedrock:Rerank does not support resource-level scoping.
36 Effect: "Allow",
37 Action: ["bedrock:Rerank"],
38 Resource: ["*"],
39 },
40 {
41 Effect: "Allow",
42 Action: ["bedrock:InvokeModel"],
43 Resource: [
44 ...new Set(
45 sorted.flatMap((id) =>
46 bedrockModelArns(region, accountId, id),
47 ),
48 ),
49 ],
50 },
51 ],
52 },
53 );
54 }
55 }
56 return Effect.fn(`AWS.Bedrock.Rerank(${model})`)(function* (
57 request: RerankRequest,
58 ) {
59 return yield* rerank(request);
60 });
61 });
62 }),
63);