@composurecdk/bedrock 0.10.1

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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/dist/commonjs/grants.d.ts +27 -0
  4. package/dist/commonjs/grants.d.ts.map +1 -0
  5. package/dist/commonjs/grants.js +42 -0
  6. package/dist/commonjs/grants.js.map +1 -0
  7. package/dist/commonjs/index.d.ts +8 -0
  8. package/dist/commonjs/index.d.ts.map +1 -0
  9. package/dist/commonjs/index.js +18 -0
  10. package/dist/commonjs/index.js.map +1 -0
  11. package/dist/commonjs/inference-profile.d.ts +88 -0
  12. package/dist/commonjs/inference-profile.d.ts.map +1 -0
  13. package/dist/commonjs/inference-profile.js +125 -0
  14. package/dist/commonjs/inference-profile.js.map +1 -0
  15. package/dist/commonjs/inference-target.d.ts +41 -0
  16. package/dist/commonjs/inference-target.d.ts.map +1 -0
  17. package/dist/commonjs/inference-target.js +104 -0
  18. package/dist/commonjs/inference-target.js.map +1 -0
  19. package/dist/commonjs/model-alarm-builder.d.ts +67 -0
  20. package/dist/commonjs/model-alarm-builder.d.ts.map +1 -0
  21. package/dist/commonjs/model-alarm-builder.js +58 -0
  22. package/dist/commonjs/model-alarm-builder.js.map +1 -0
  23. package/dist/commonjs/model-alarm-config.d.ts +83 -0
  24. package/dist/commonjs/model-alarm-config.d.ts.map +1 -0
  25. package/dist/commonjs/model-alarm-config.js +3 -0
  26. package/dist/commonjs/model-alarm-config.js.map +1 -0
  27. package/dist/commonjs/model-alarm-defaults.d.ts +22 -0
  28. package/dist/commonjs/model-alarm-defaults.d.ts.map +1 -0
  29. package/dist/commonjs/model-alarm-defaults.js +30 -0
  30. package/dist/commonjs/model-alarm-defaults.js.map +1 -0
  31. package/dist/commonjs/model-alarms.d.ts +20 -0
  32. package/dist/commonjs/model-alarms.d.ts.map +1 -0
  33. package/dist/commonjs/model-alarms.js +115 -0
  34. package/dist/commonjs/model-alarms.js.map +1 -0
  35. package/dist/commonjs/package.json +3 -0
  36. package/dist/esm/grants.d.ts +27 -0
  37. package/dist/esm/grants.d.ts.map +1 -0
  38. package/dist/esm/grants.js +39 -0
  39. package/dist/esm/grants.js.map +1 -0
  40. package/dist/esm/index.d.ts +8 -0
  41. package/dist/esm/index.d.ts.map +1 -0
  42. package/dist/esm/index.js +7 -0
  43. package/dist/esm/index.js.map +1 -0
  44. package/dist/esm/inference-profile.d.ts +88 -0
  45. package/dist/esm/inference-profile.d.ts.map +1 -0
  46. package/dist/esm/inference-profile.js +121 -0
  47. package/dist/esm/inference-profile.js.map +1 -0
  48. package/dist/esm/inference-target.d.ts +41 -0
  49. package/dist/esm/inference-target.d.ts.map +1 -0
  50. package/dist/esm/inference-target.js +98 -0
  51. package/dist/esm/inference-target.js.map +1 -0
  52. package/dist/esm/model-alarm-builder.d.ts +67 -0
  53. package/dist/esm/model-alarm-builder.d.ts.map +1 -0
  54. package/dist/esm/model-alarm-builder.js +55 -0
  55. package/dist/esm/model-alarm-builder.js.map +1 -0
  56. package/dist/esm/model-alarm-config.d.ts +83 -0
  57. package/dist/esm/model-alarm-config.d.ts.map +1 -0
  58. package/dist/esm/model-alarm-config.js +2 -0
  59. package/dist/esm/model-alarm-config.js.map +1 -0
  60. package/dist/esm/model-alarm-defaults.d.ts +22 -0
  61. package/dist/esm/model-alarm-defaults.d.ts.map +1 -0
  62. package/dist/esm/model-alarm-defaults.js +27 -0
  63. package/dist/esm/model-alarm-defaults.js.map +1 -0
  64. package/dist/esm/model-alarms.d.ts +20 -0
  65. package/dist/esm/model-alarms.d.ts.map +1 -0
  66. package/dist/esm/model-alarms.js +111 -0
  67. package/dist/esm/model-alarms.js.map +1 -0
  68. package/dist/esm/package.json +3 -0
  69. package/package.json +87 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-profile.d.ts","sourceRoot":"","sources":["../../src/inference-profile.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,qDAAsD,CAAC;AAEjG,2EAA2E;AAC3E,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAIvF;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,yBAAyB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAC9D,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC1C,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC1C,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,uDAAuD;AACvD,MAAM,MAAM,gBAAgB,GAAG,0BAA0B,GAAG,sBAAsB,CAAC;AAEnF,uDAAuD;AACvD,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,0BAA0B,EAC1B,OAAO,GAAG,WAAW,GAAG,gBAAgB,CACzC,CAAC;AA4CF,iBAAS,UAAU,CAAC,OAAO,EAAE,iCAAiC,GAAG,0BAA0B,CAiB1F;AAED,iBAAS,MAAM,CAAC,KAAK,EAAE,yBAAyB,GAAG,sBAAsB,CAGxE;AAaD,iBAAS,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,CAAC;AAC1D,iBAAS,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAAC;AAkBvF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB;IAC3B,8CAA8C;;IAE9C,4DAA4D;;IAE5D;;;;OAIG;;CAEJ,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,yBAAyB,CAE/E"}
@@ -0,0 +1,121 @@
1
+ import { Token } from "aws-cdk-lib";
2
+ import { FoundationModelIdentifier } from "aws-cdk-lib/aws-bedrock";
3
+ /**
4
+ * Geography prefixes of Amazon Bedrock's system-defined cross-Region inference
5
+ * profiles, e.g. the `eu` in `eu.anthropic.claude-haiku-4-5-20251001-v1:0`.
6
+ *
7
+ * {@link inferenceProfile.parse} recognises a profile id by one of these
8
+ * prefixes. {@link inferenceProfile.geographic} also accepts a geography not
9
+ * yet listed here.
10
+ *
11
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/geographic-cross-region-inference.html
12
+ */
13
+ export const INFERENCE_PROFILE_GEOGRAPHIES = ["us", "eu", "apac", "jp", "au", "us-gov"];
14
+ const GLOBAL_PREFIX = "global";
15
+ const GEOGRAPHY_PATTERN = /^[a-z]+(-[a-z]+)*$/;
16
+ const REGION_PATTERN = /^[a-z]{2}(-[a-z]+)+-\d+$/;
17
+ function isProfilePrefix(prefix) {
18
+ return (prefix === GLOBAL_PREFIX ||
19
+ INFERENCE_PROFILE_GEOGRAPHIES.includes(prefix));
20
+ }
21
+ function prefixOf(id) {
22
+ const dot = id.indexOf(".");
23
+ return dot > 0 ? id.slice(0, dot) : undefined;
24
+ }
25
+ function assertModel(model) {
26
+ const { modelId } = model;
27
+ if (Token.isUnresolved(modelId) || modelId === "") {
28
+ throw new Error("Inference profile model id must be a non-empty literal string.");
29
+ }
30
+ const prefix = prefixOf(modelId);
31
+ if (prefix !== undefined && isProfilePrefix(prefix)) {
32
+ throw new Error(`"${modelId}" is an inference profile id, not a foundation model id. ` +
33
+ `Use inferenceProfile.parse("${modelId}", …) instead.`);
34
+ }
35
+ }
36
+ function assertRoutingRegions(profileId, regions) {
37
+ if (regions.length === 0) {
38
+ throw new Error(`Inference profile "${profileId}": routingRegions must not be empty.`);
39
+ }
40
+ for (const region of regions) {
41
+ if (Token.isUnresolved(region) || !REGION_PATTERN.test(region)) {
42
+ throw new Error(`Inference profile "${profileId}": "${region}" is not a literal AWS Region code.`);
43
+ }
44
+ }
45
+ }
46
+ function geographic(options) {
47
+ const { model, geography } = options;
48
+ assertModel(model);
49
+ if (geography === GLOBAL_PREFIX || !GEOGRAPHY_PATTERN.test(geography)) {
50
+ throw new Error(`"${geography}" is not a geography prefix. Use inferenceProfile.global() for a global profile.`);
51
+ }
52
+ const profileId = `${geography}.${model.modelId}`;
53
+ assertRoutingRegions(profileId, options.routingRegions);
54
+ return Object.freeze({
55
+ kind: "geographic",
56
+ geography,
57
+ model,
58
+ profileId,
59
+ routingRegions: Object.freeze([...new Set(options.routingRegions)]),
60
+ });
61
+ }
62
+ function global(model) {
63
+ assertModel(model);
64
+ return Object.freeze({ kind: "global", model, profileId: `${GLOBAL_PREFIX}.${model.modelId}` });
65
+ }
66
+ function splitProfileId(profileId) {
67
+ const prefix = prefixOf(profileId);
68
+ if (prefix === undefined || !isProfilePrefix(prefix)) {
69
+ throw new Error(`"${profileId}" is not a system-defined inference profile id. Expected one of the ` +
70
+ `prefixes: ${[GLOBAL_PREFIX, ...INFERENCE_PROFILE_GEOGRAPHIES].join(", ")}.`);
71
+ }
72
+ return { prefix, modelId: profileId.slice(prefix.length + 1) };
73
+ }
74
+ function parse(profileId, routingRegions) {
75
+ const { prefix, modelId } = splitProfileId(profileId);
76
+ const model = new FoundationModelIdentifier(modelId);
77
+ if (prefix === GLOBAL_PREFIX) {
78
+ if (routingRegions !== undefined) {
79
+ throw new Error(`Inference profile "${profileId}" is global and routes to every supported Region; omit routingRegions.`);
80
+ }
81
+ return global(model);
82
+ }
83
+ if (routingRegions === undefined) {
84
+ throw new Error(`Inference profile "${profileId}" is geographic and needs its routingRegions.`);
85
+ }
86
+ return geographic({ model, geography: prefix, routingRegions });
87
+ }
88
+ /**
89
+ * Factories for {@link InferenceProfile} values.
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * const haiku = inferenceProfile.geographic({
94
+ * model: FoundationModelIdentifier.ANTHROPIC_CLAUDE_HAIKU_4_5_20251001_V1_0,
95
+ * geography: "eu",
96
+ * routingRegions: ["eu-central-1", "eu-north-1", "eu-south-1", "eu-south-2", "eu-west-1", "eu-west-3"],
97
+ * });
98
+ * haiku.profileId; // "eu.anthropic.claude-haiku-4-5-20251001-v1:0"
99
+ * ```
100
+ */
101
+ export const inferenceProfile = {
102
+ /** A profile routing within one geography. */
103
+ geographic,
104
+ /** A profile routing to any supported commercial Region. */
105
+ global,
106
+ /**
107
+ * Reads a profile id such as `eu.anthropic.claude-haiku-4-5-20251001-v1:0`.
108
+ * Throws unless the id starts with a known geography or `global`. A
109
+ * geographic id needs its `routingRegions`; a global id takes none.
110
+ */
111
+ parse,
112
+ };
113
+ /**
114
+ * The foundation model a system-defined inference profile serves:
115
+ * `eu.anthropic.x` → `anthropic.x`. Throws unless the id starts with a known
116
+ * geography or `global`.
117
+ */
118
+ export function foundationModelFor(profileId) {
119
+ return new FoundationModelIdentifier(splitProfileId(profileId).modelId);
120
+ }
121
+ //# sourceMappingURL=inference-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-profile.js","sourceRoot":"","sources":["../../src/inference-profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { FoundationModelIdentifier, IModel } from "aws-cdk-lib/aws-bedrock";
2
+ import { type IConstruct } from "constructs";
3
+ import type { InferenceProfile } from "./inference-profile.js";
4
+ /**
5
+ * Anything a caller can invoke: an in-Region foundation model, a
6
+ * system-defined inference profile, or any {@link IModel} (a provisioned
7
+ * model, or `{ modelArn }` for a model ARN from elsewhere).
8
+ */
9
+ export type InferenceTarget = FoundationModelIdentifier | InferenceProfile | IModel;
10
+ /** @internal */
11
+ export declare function isInferenceProfile(target: InferenceTarget): target is InferenceProfile;
12
+ /** One IAM statement's resources and conditions for invoking a target. @internal */
13
+ export interface InvocationStatement {
14
+ readonly resourceArns: string[];
15
+ readonly conditions?: Record<string, Record<string, unknown>>;
16
+ }
17
+ /**
18
+ * The statements the Bedrock user guide prescribes for invoking `target` from
19
+ * the Region `scope` deploys to.
20
+ *
21
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/geographic-cross-region-inference.html#geographic-cris-iam-setup
22
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/global-cross-region-inference.html#global-cris-iam-setup
23
+ * @internal
24
+ */
25
+ export declare function invocationStatements(target: InferenceTarget, scope?: IConstruct): InvocationStatement[];
26
+ /**
27
+ * Every resource ARN a caller in `scope`'s Region must be allowed to invoke to
28
+ * use `target`. For a cross-Region profile that is the profile plus the
29
+ * foundation model in the source Region and in each Region it routes to.
30
+ *
31
+ * {@link modelGrants.invoke} applies these with the conditions the Bedrock
32
+ * user guide prescribes; use this list where you write a policy yourself,
33
+ * such as a service control policy.
34
+ *
35
+ * @param scope - Resolves partition, Region and account from its stack. Omit
36
+ * for the `AWS::` pseudo-parameters.
37
+ */
38
+ export declare function invocationArns(target: InferenceTarget, scope?: IConstruct): string[];
39
+ /** @internal */
40
+ export declare function scopeOf(principal: unknown): IConstruct | undefined;
41
+ //# sourceMappingURL=inference-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-target.d.ts","sourceRoot":"","sources":["../../src/inference-target.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,yBAAyB,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAEpF,gBAAgB;AAChB,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI,gBAAgB,CAEtF;AAMD,oFAAoF;AACpF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC/D;AA4BD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EACvB,KAAK,CAAC,EAAE,UAAU,GACjB,mBAAmB,EAAE,CAuDvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,CAEpF;AAED,gBAAgB;AAChB,wBAAgB,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAElE"}
@@ -0,0 +1,98 @@
1
+ import { Arn, ArnFormat, Aws, Stack } from "aws-cdk-lib";
2
+ import { Construct } from "constructs";
3
+ /** @internal */
4
+ export function isInferenceProfile(target) {
5
+ return "kind" in target;
6
+ }
7
+ function isModel(target) {
8
+ return "modelArn" in target;
9
+ }
10
+ function environmentOf(scope) {
11
+ return scope === undefined
12
+ ? { partition: Aws.PARTITION, region: Aws.REGION, account: Aws.ACCOUNT_ID }
13
+ : Stack.of(scope);
14
+ }
15
+ function bedrockArn(partition, resource, resourceName, region, account = "") {
16
+ return Arn.format({
17
+ partition,
18
+ service: "bedrock",
19
+ region,
20
+ account,
21
+ resource,
22
+ resourceName,
23
+ arnFormat: ArnFormat.SLASH_RESOURCE_NAME,
24
+ });
25
+ }
26
+ /**
27
+ * The statements the Bedrock user guide prescribes for invoking `target` from
28
+ * the Region `scope` deploys to.
29
+ *
30
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/geographic-cross-region-inference.html#geographic-cris-iam-setup
31
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/global-cross-region-inference.html#global-cris-iam-setup
32
+ * @internal
33
+ */
34
+ export function invocationStatements(target, scope) {
35
+ if (isModel(target))
36
+ return [{ resourceArns: [target.modelArn] }];
37
+ const { partition, region: sourceRegion, account } = environmentOf(scope);
38
+ const modelArn = (modelId, region) => bedrockArn(partition, "foundation-model", modelId, region);
39
+ if (!isInferenceProfile(target)) {
40
+ return [{ resourceArns: [modelArn(target.modelId, sourceRegion)] }];
41
+ }
42
+ const profileArn = bedrockArn(partition, "inference-profile", target.profileId, sourceRegion, account);
43
+ const { modelId } = target.model;
44
+ if (target.kind === "geographic") {
45
+ const regions = [...new Set([sourceRegion, ...target.routingRegions])];
46
+ return [
47
+ { resourceArns: [profileArn] },
48
+ {
49
+ resourceArns: regions.map((region) => modelArn(modelId, region)),
50
+ conditions: { StringEquals: { "bedrock:InferenceProfileArn": profileArn } },
51
+ },
52
+ ];
53
+ }
54
+ return [
55
+ {
56
+ resourceArns: [profileArn],
57
+ conditions: { StringEquals: { "aws:RequestedRegion": sourceRegion } },
58
+ },
59
+ {
60
+ resourceArns: [modelArn(modelId, sourceRegion)],
61
+ conditions: {
62
+ StringEquals: {
63
+ "aws:RequestedRegion": sourceRegion,
64
+ "bedrock:InferenceProfileArn": profileArn,
65
+ },
66
+ },
67
+ },
68
+ {
69
+ resourceArns: [modelArn(modelId, "")],
70
+ conditions: {
71
+ StringEquals: {
72
+ "aws:RequestedRegion": "unspecified",
73
+ "bedrock:InferenceProfileArn": profileArn,
74
+ },
75
+ },
76
+ },
77
+ ];
78
+ }
79
+ /**
80
+ * Every resource ARN a caller in `scope`'s Region must be allowed to invoke to
81
+ * use `target`. For a cross-Region profile that is the profile plus the
82
+ * foundation model in the source Region and in each Region it routes to.
83
+ *
84
+ * {@link modelGrants.invoke} applies these with the conditions the Bedrock
85
+ * user guide prescribes; use this list where you write a policy yourself,
86
+ * such as a service control policy.
87
+ *
88
+ * @param scope - Resolves partition, Region and account from its stack. Omit
89
+ * for the `AWS::` pseudo-parameters.
90
+ */
91
+ export function invocationArns(target, scope) {
92
+ return invocationStatements(target, scope).flatMap((s) => s.resourceArns);
93
+ }
94
+ /** @internal */
95
+ export function scopeOf(principal) {
96
+ return Construct.isConstruct(principal) ? principal : undefined;
97
+ }
98
+ //# sourceMappingURL=inference-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference-target.js","sourceRoot":"","sources":["../../src/inference-target.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { Alarm } from "aws-cdk-lib/aws-cloudwatch";
2
+ import type { IConstruct } from "constructs";
3
+ import { COPY_STATE, type Lifecycle, type Resolvable } from "@composurecdk/core";
4
+ import { type ITaggedBuilder } from "@composurecdk/cloudformation";
5
+ import { AlarmDefinitionBuilder } from "@composurecdk/cloudwatch";
6
+ import type { ModelAlarmConfig } from "./model-alarm-config.js";
7
+ import { type ModelAlarmTarget, type ModelMetrics } from "./model-alarms.js";
8
+ /** Configuration properties for {@link createModelAlarmBuilder}. */
9
+ export interface ModelAlarmBuilderProps {
10
+ /** The foundation model or inference profile to alarm on. Required. */
11
+ model: Resolvable<ModelAlarmTarget>;
12
+ /**
13
+ * Configuration for the recommended alarms. Throttle, server-error and
14
+ * client-error alarms are created by default; latency, time-to-first-token
15
+ * and quota alarms are opt-in. Set to `false` to disable them; alarms added
16
+ * with `addAlarm()` are unaffected.
17
+ *
18
+ * No alarm actions are configured. Use `alarmActionsPolicy` or an
19
+ * `afterBuild` hook to route them.
20
+ */
21
+ recommendedAlarms?: ModelAlarmConfig | false;
22
+ }
23
+ /** The build output of an {@link IModelAlarmBuilder}. */
24
+ export interface ModelAlarmBuilderResult {
25
+ /** The CloudWatch alarms created, keyed by alarm key. */
26
+ alarms: Record<string, Alarm>;
27
+ }
28
+ /**
29
+ * A fluent builder for CloudWatch alarms on an Amazon Bedrock model.
30
+ *
31
+ * @see {@link createModelAlarmBuilder}
32
+ */
33
+ export type IModelAlarmBuilder = ITaggedBuilder<ModelAlarmBuilderProps, ModelAlarmBuilder>;
34
+ declare class ModelAlarmBuilder implements Lifecycle<ModelAlarmBuilderResult> {
35
+ #private;
36
+ props: Partial<ModelAlarmBuilderProps>;
37
+ /**
38
+ * Adds a custom alarm. The metric factory receives the model's
39
+ * {@link ModelMetrics}, e.g.
40
+ * `(a) => a.metric((m) => m.metric("OutputTokenCount", { statistic: "Sum" })).threshold(1e6)`.
41
+ */
42
+ addAlarm(key: string, configure: (alarm: AlarmDefinitionBuilder<ModelMetrics>) => AlarmDefinitionBuilder<ModelMetrics>): this;
43
+ /** @internal — see ADR-0005. */
44
+ [COPY_STATE](target: ModelAlarmBuilder): void;
45
+ build(scope: IConstruct, id: string, context?: Record<string, object>): ModelAlarmBuilderResult;
46
+ }
47
+ /**
48
+ * Creates CloudWatch alarms on an Amazon Bedrock model's `AWS/Bedrock`
49
+ * metrics.
50
+ *
51
+ * The metrics are per model per account and Region, whichever principal
52
+ * invokes it, so build one per model in each Region that invokes it rather
53
+ * than one per caller. For a cross-Region profile, the metrics are emitted
54
+ * in the source Region.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * createModelAlarmBuilder()
59
+ * .model(haiku)
60
+ * .recommendedAlarms({ invocationLatency: { threshold: 10_000 } });
61
+ * ```
62
+ *
63
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp02.html
64
+ */
65
+ export declare function createModelAlarmBuilder(): IModelAlarmBuilder;
66
+ export {};
67
+ //# sourceMappingURL=model-alarm-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-builder.d.ts","sourceRoot":"","sources":["../../src/model-alarm-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAW,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,KAAK,cAAc,EAAiB,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAgB,MAAM,0BAA0B,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAGlB,MAAM,mBAAmB,CAAC;AAE3B,oEAAoE;AACpE,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,KAAK,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAEpC;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;CAC9C;AAED,yDAAyD;AACzD,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,cAAc,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC;AAE3F,cAAM,iBAAkB,YAAW,SAAS,CAAC,uBAAuB,CAAC;;IACnE,KAAK,EAAE,OAAO,CAAC,sBAAsB,CAAC,CAAM;IAG5C;;;;OAIG;IACH,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,CACT,KAAK,EAAE,sBAAsB,CAAC,YAAY,CAAC,KACxC,sBAAsB,CAAC,YAAY,CAAC,GACxC,IAAI;IAKP,gCAAgC;IAChC,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAI7C,KAAK,CACH,KAAK,EAAE,UAAU,EACjB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,uBAAuB;CAa3B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,IAAI,kBAAkB,CAE5D"}
@@ -0,0 +1,55 @@
1
+ import { COPY_STATE, resolve } from "@composurecdk/core";
2
+ import { taggedBuilder } from "@composurecdk/cloudformation";
3
+ import { AlarmDefinitionBuilder, createAlarms } from "@composurecdk/cloudwatch";
4
+ import { modelMetrics, resolveModelAlarmDefinitions, } from "./model-alarms.js";
5
+ class ModelAlarmBuilder {
6
+ props = {};
7
+ #customAlarms = [];
8
+ /**
9
+ * Adds a custom alarm. The metric factory receives the model's
10
+ * {@link ModelMetrics}, e.g.
11
+ * `(a) => a.metric((m) => m.metric("OutputTokenCount", { statistic: "Sum" })).threshold(1e6)`.
12
+ */
13
+ addAlarm(key, configure) {
14
+ this.#customAlarms.push(configure(new AlarmDefinitionBuilder(key)));
15
+ return this;
16
+ }
17
+ /** @internal — see ADR-0005. */
18
+ [COPY_STATE](target) {
19
+ target.#customAlarms.push(...this.#customAlarms);
20
+ }
21
+ build(scope, id, context = {}) {
22
+ if (this.props.model === undefined) {
23
+ throw new Error(`ModelAlarmBuilder "${id}" requires a model. Call .model().`);
24
+ }
25
+ const metrics = modelMetrics(resolve(this.props.model, context));
26
+ const { recommendedAlarms } = this.props;
27
+ const recommended = recommendedAlarms === false
28
+ ? []
29
+ : resolveModelAlarmDefinitions(scope, metrics, recommendedAlarms);
30
+ const custom = this.#customAlarms.map((b) => b.resolve(metrics));
31
+ return { alarms: createAlarms(scope, id, [...recommended, ...custom]) };
32
+ }
33
+ }
34
+ /**
35
+ * Creates CloudWatch alarms on an Amazon Bedrock model's `AWS/Bedrock`
36
+ * metrics.
37
+ *
38
+ * The metrics are per model per account and Region, whichever principal
39
+ * invokes it, so build one per model in each Region that invokes it rather
40
+ * than one per caller. For a cross-Region profile, the metrics are emitted
41
+ * in the source Region.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * createModelAlarmBuilder()
46
+ * .model(haiku)
47
+ * .recommendedAlarms({ invocationLatency: { threshold: 10_000 } });
48
+ * ```
49
+ *
50
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp02.html
51
+ */
52
+ export function createModelAlarmBuilder() {
53
+ return taggedBuilder(ModelAlarmBuilder);
54
+ }
55
+ //# sourceMappingURL=model-alarm-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-builder.js","sourceRoot":"","sources":["../../src/model-alarm-builder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAkB,OAAO,EAAmB,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAuB,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,OAAO,EAGL,YAAY,EACZ,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAgC3B,MAAM,iBAAiB;IACrB,KAAK,GAAoC,EAAE,CAAC;IACnC,aAAa,GAA2C,EAAE,CAAC;IAEpE;;;;OAIG;IACH,QAAQ,CACN,GAAW,EACX,SAEyC;QAEzC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,sBAAsB,CAAe,GAAG,CAAC,CAAC,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gCAAgC;IAChC,CAAC,UAAU,CAAC,CAAC,MAAyB;QACpC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CACH,KAAiB,EACjB,EAAU,EACV,UAAkC,EAAE;QAEpC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,sBAAsB,EAAE,oCAAoC,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;QACjE,MAAM,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACzC,MAAM,WAAW,GACf,iBAAiB,KAAK,KAAK;YACzB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,4BAA4B,CAAC,KAAK,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,GAAG,WAAW,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC;IAC1E,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,aAAa,CAA4C,iBAAiB,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,83 @@
1
+ import type { AlarmConfig } from "@composurecdk/cloudwatch";
2
+ /**
3
+ * Configuration for an alarm whose threshold is a fraction of a quota the
4
+ * caller supplies.
5
+ */
6
+ export type QuotaAlarmConfig = Omit<AlarmConfig, "threshold"> & {
7
+ /** The applied quota, in the metric's unit. Required when enabling the alarm. */
8
+ quota: number;
9
+ /** Threshold as a fraction of {@link quota}, in (0, 1]. */
10
+ thresholdPercent?: number;
11
+ };
12
+ /**
13
+ * Controls which recommended alarms are created for a model. Set an alarm to
14
+ * `false` to disable it, or provide a config to enable it (if opt-in) or tune
15
+ * it.
16
+ *
17
+ * Every alarm uses the `AWS/Bedrock` namespace, the `ModelId` dimension and a
18
+ * 1-minute period. Bedrock metrics aggregate every caller of the model in the
19
+ * account and Region.
20
+ *
21
+ * AWS publishes no recommended thresholds for Bedrock. The Well-Architected
22
+ * Generative AI Lens names which signals to alarm on; the thresholds are this
23
+ * library's.
24
+ *
25
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp02.html
26
+ * @see https://docs.aws.amazon.com/bedrock/latest/userguide/monitoring-runtime-metrics.html
27
+ */
28
+ export interface ModelAlarmConfig {
29
+ /**
30
+ * Master switch: set to `false` to disable all recommended alarms.
31
+ * @default true
32
+ */
33
+ enabled?: boolean;
34
+ /**
35
+ * Alarm when requests are throttled. Throttled requests are not counted in
36
+ * `Invocations`, and SDK retries mean a count here was already retried.
37
+ *
38
+ * Metric: `InvocationThrottles`, statistic Sum. On by default.
39
+ *
40
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp03.html
41
+ */
42
+ invocationThrottles?: AlarmConfig | false;
43
+ /**
44
+ * Alarm on server-side (5xx) invocation errors.
45
+ *
46
+ * Metric: `InvocationServerErrors`, statistic Sum. On by default.
47
+ */
48
+ invocationServerErrors?: AlarmConfig | false;
49
+ /**
50
+ * Alarm on client-side (4xx) invocation errors, including `AccessDenied`
51
+ * from a Region missing from a cross-Region grant and validation errors
52
+ * such as a prompt over the context window.
53
+ *
54
+ * Metric: `InvocationClientErrors`, statistic Sum. On by default.
55
+ */
56
+ invocationClientErrors?: AlarmConfig | false;
57
+ /**
58
+ * Alarm when invocation latency, in milliseconds to the last token, exceeds
59
+ * the threshold. Latency depends on the model and output length, so there
60
+ * is no default threshold.
61
+ *
62
+ * Metric: `InvocationLatency`, statistic p90. Opt-in; threshold required.
63
+ */
64
+ invocationLatency?: AlarmConfig | false;
65
+ /**
66
+ * Alarm when time to first token, in milliseconds, exceeds the threshold.
67
+ * Emitted for streaming APIs only.
68
+ *
69
+ * Metric: `TimeToFirstToken`, statistic p90. Opt-in; threshold required.
70
+ */
71
+ timeToFirstToken?: AlarmConfig | false;
72
+ /**
73
+ * Alarm when estimated tokens-per-minute usage approaches the applied
74
+ * quota. AWS advises against relying on this metric alone for quota use.
75
+ *
76
+ * Metric: `EstimatedTPMQuotaUsage`, statistic Maximum. Opt-in; `quota`
77
+ * required.
78
+ *
79
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genrel01-bp01.html
80
+ */
81
+ estimatedTpmQuotaUsage?: QuotaAlarmConfig | false;
82
+ }
83
+ //# sourceMappingURL=model-alarm-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-config.d.ts","sourceRoot":"","sources":["../../src/model-alarm-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG;IAC9D,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAE1C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAE7C;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAE7C;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAExC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC;IAEvC;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,gBAAgB,GAAG,KAAK,CAAC;CACnD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=model-alarm-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-config.js","sourceRoot":"","sources":["../../src/model-alarm-config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ import type { AlarmConfigDefaults } from "@composurecdk/cloudwatch";
2
+ interface ModelAlarmDefaults {
3
+ enabled: true;
4
+ invocationThrottles: AlarmConfigDefaults;
5
+ invocationServerErrors: AlarmConfigDefaults;
6
+ invocationClientErrors: AlarmConfigDefaults;
7
+ /** Applied to the opt-in alarms; their threshold comes from the caller. */
8
+ optIn: Omit<AlarmConfigDefaults, "threshold">;
9
+ estimatedTpmQuotaUsage: {
10
+ thresholdPercent: number;
11
+ };
12
+ }
13
+ /**
14
+ * Default alarm configuration for a Bedrock model. AWS publishes no Bedrock
15
+ * thresholds; these follow the shape of AWS's recommended Lambda `Errors` and
16
+ * `Throttles` alarms.
17
+ *
18
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp02.html
19
+ */
20
+ export declare const MODEL_ALARM_DEFAULTS: ModelAlarmDefaults;
21
+ export {};
22
+ //# sourceMappingURL=model-alarm-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-defaults.d.ts","sourceRoot":"","sources":["../../src/model-alarm-defaults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAYpE,UAAU,kBAAkB;IAC1B,OAAO,EAAE,IAAI,CAAC;IACd,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,sBAAsB,EAAE,mBAAmB,CAAC;IAC5C,sBAAsB,EAAE,mBAAmB,CAAC;IAC5C,2EAA2E;IAC3E,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;IAC9C,sBAAsB,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,kBAQlC,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
2
+ /**
3
+ * 3 breaching minutes out of 5: SDK retries absorb isolated throttles and
4
+ * transient errors, so a single datapoint is noise. No traffic emits no data.
5
+ */
6
+ const SUSTAINED = {
7
+ evaluationPeriods: 5,
8
+ datapointsToAlarm: 3,
9
+ treatMissingData: TreatMissingData.NOT_BREACHING,
10
+ };
11
+ /**
12
+ * Default alarm configuration for a Bedrock model. AWS publishes no Bedrock
13
+ * thresholds; these follow the shape of AWS's recommended Lambda `Errors` and
14
+ * `Throttles` alarms.
15
+ *
16
+ * @see https://docs.aws.amazon.com/wellarchitected/latest/generative-ai-lens/genops02-bp02.html
17
+ */
18
+ export const MODEL_ALARM_DEFAULTS = {
19
+ enabled: true,
20
+ invocationThrottles: { threshold: 0, ...SUSTAINED },
21
+ invocationServerErrors: { threshold: 0, ...SUSTAINED },
22
+ invocationClientErrors: { threshold: 0, ...SUSTAINED },
23
+ optIn: SUSTAINED,
24
+ /** Leaves 20% headroom to act before requests are throttled. */
25
+ estimatedTpmQuotaUsage: { thresholdPercent: 0.8 },
26
+ };
27
+ //# sourceMappingURL=model-alarm-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarm-defaults.js","sourceRoot":"","sources":["../../src/model-alarm-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG9D;;;GAGG;AACH,MAAM,SAAS,GAAG;IAChB,iBAAiB,EAAE,CAAC;IACpB,iBAAiB,EAAE,CAAC;IACpB,gBAAgB,EAAE,gBAAgB,CAAC,aAAa;CACjD,CAAC;AAYF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAuB;IACtD,OAAO,EAAE,IAAI;IACb,mBAAmB,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE;IACnD,sBAAsB,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE;IACtD,sBAAsB,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE;IACtD,KAAK,EAAE,SAAS;IAChB,gEAAgE;IAChE,sBAAsB,EAAE,EAAE,gBAAgB,EAAE,GAAG,EAAE;CAClD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { FoundationModelIdentifier } from "aws-cdk-lib/aws-bedrock";
2
+ import { Metric, type MetricOptions } from "aws-cdk-lib/aws-cloudwatch";
3
+ import type { IConstruct } from "constructs";
4
+ import type { AlarmDefinition } from "@composurecdk/cloudwatch";
5
+ import type { InferenceProfile } from "./inference-profile.js";
6
+ import type { ModelAlarmConfig } from "./model-alarm-config.js";
7
+ /** A model whose `AWS/Bedrock` metrics an alarm can read. */
8
+ export type ModelAlarmTarget = FoundationModelIdentifier | InferenceProfile;
9
+ /** `AWS/Bedrock` metrics for one model, for alarms added with `addAlarm()`. */
10
+ export interface ModelMetrics {
11
+ /** The `ModelId` dimension value: the model or inference profile id invoked. */
12
+ readonly modelId: string;
13
+ /** An `AWS/Bedrock` metric dimensioned by {@link modelId}. */
14
+ metric(metricName: string, options?: MetricOptions): Metric;
15
+ }
16
+ /** Returns the `AWS/Bedrock` metrics for `target`. */
17
+ export declare function modelMetrics(target: ModelAlarmTarget): ModelMetrics;
18
+ /** Resolves the recommended alarm configuration for a model's metrics. */
19
+ export declare function resolveModelAlarmDefinitions(scope: IConstruct, metrics: ModelMetrics, config: ModelAlarmConfig | undefined): AlarmDefinition[];
20
+ //# sourceMappingURL=model-alarms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-alarms.d.ts","sourceRoot":"","sources":["../../src/model-alarms.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAsB,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC5F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAEV,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG,yBAAyB,GAAG,gBAAgB,CAAC;AAE5E,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC;CAC7D;AAID,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAanE;AA6GD,0EAA0E;AAC1E,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,gBAAgB,GAAG,SAAS,GACnC,eAAe,EAAE,CA6BnB"}