@gakr-gakr/amazon-bedrock-provider 0.1.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/api.ts +6 -0
- package/autobot.plugin.json +80 -0
- package/aws-credential-refresh.ts +42 -0
- package/config-api.ts +4 -0
- package/config-compat.ts +107 -0
- package/discovery-shared.ts +28 -0
- package/discovery.ts +616 -0
- package/embedding-provider.ts +470 -0
- package/index.ts +11 -0
- package/memory-embedding-adapter.ts +47 -0
- package/package.json +41 -0
- package/provider-policy-api.ts +9 -0
- package/register.sync.runtime.ts +659 -0
- package/setup-api.ts +18 -0
- package/thinking-policy.ts +32 -0
- package/tsconfig.json +16 -0
package/api.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "amazon-bedrock",
|
|
3
|
+
"activation": {
|
|
4
|
+
"onStartup": false
|
|
5
|
+
},
|
|
6
|
+
"enabledByDefault": true,
|
|
7
|
+
"providers": ["amazon-bedrock"],
|
|
8
|
+
"contracts": {
|
|
9
|
+
"memoryEmbeddingProviders": ["bedrock"]
|
|
10
|
+
},
|
|
11
|
+
"configSchema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"discovery": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"properties": {
|
|
19
|
+
"enabled": { "type": "boolean" },
|
|
20
|
+
"region": { "type": "string" },
|
|
21
|
+
"providerFilter": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"items": { "type": "string" }
|
|
24
|
+
},
|
|
25
|
+
"refreshInterval": { "type": "integer", "minimum": 0 },
|
|
26
|
+
"defaultContextWindow": { "type": "integer", "minimum": 1 },
|
|
27
|
+
"defaultMaxTokens": { "type": "integer", "minimum": 1 }
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"guardrail": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"additionalProperties": false,
|
|
33
|
+
"properties": {
|
|
34
|
+
"guardrailIdentifier": { "type": "string" },
|
|
35
|
+
"guardrailVersion": { "type": "string" },
|
|
36
|
+
"streamProcessingMode": { "type": "string", "enum": ["sync", "async"] },
|
|
37
|
+
"trace": { "type": "string", "enum": ["enabled", "disabled", "enabled_full"] }
|
|
38
|
+
},
|
|
39
|
+
"required": ["guardrailIdentifier", "guardrailVersion"]
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"configContracts": {
|
|
44
|
+
"compatibilityMigrationPaths": ["models.bedrockDiscovery"]
|
|
45
|
+
},
|
|
46
|
+
"uiHints": {
|
|
47
|
+
"discovery": {
|
|
48
|
+
"label": "Model Discovery",
|
|
49
|
+
"help": "Plugin-owned controls for Amazon Bedrock model auto-discovery."
|
|
50
|
+
},
|
|
51
|
+
"discovery.enabled": {
|
|
52
|
+
"label": "Enable Discovery",
|
|
53
|
+
"help": "When false, AutoBot keeps the Amazon Bedrock plugin available but skips implicit startup discovery. When true, discovery can run even without AWS auth env markers."
|
|
54
|
+
},
|
|
55
|
+
"discovery.region": {
|
|
56
|
+
"label": "Discovery Region",
|
|
57
|
+
"help": "AWS region to use for Bedrock model discovery. Defaults to AWS_REGION, AWS_DEFAULT_REGION, then us-east-1."
|
|
58
|
+
},
|
|
59
|
+
"discovery.providerFilter": {
|
|
60
|
+
"label": "Provider Filter",
|
|
61
|
+
"help": "Optional Bedrock provider-name allowlist for discovery, such as anthropic or amazon."
|
|
62
|
+
},
|
|
63
|
+
"discovery.refreshInterval": {
|
|
64
|
+
"label": "Discovery Refresh Interval (s)",
|
|
65
|
+
"help": "How long to cache Bedrock discovery results in seconds. Set to 0 to disable caching."
|
|
66
|
+
},
|
|
67
|
+
"discovery.defaultContextWindow": {
|
|
68
|
+
"label": "Default Context Window",
|
|
69
|
+
"help": "Fallback context window to assign to discovered Bedrock models."
|
|
70
|
+
},
|
|
71
|
+
"discovery.defaultMaxTokens": {
|
|
72
|
+
"label": "Default Max Tokens",
|
|
73
|
+
"help": "Fallback max output tokens to assign to discovered Bedrock models."
|
|
74
|
+
},
|
|
75
|
+
"guardrail": {
|
|
76
|
+
"label": "Guardrail",
|
|
77
|
+
"help": "Amazon Bedrock Guardrails settings applied to Bedrock model invocations."
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
type SharedIniFileLoader = {
|
|
2
|
+
loadSharedConfigFiles(init?: { ignoreCache?: boolean }): Promise<unknown>;
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
let sharedIniFileLoaderForTest: SharedIniFileLoader | null | undefined;
|
|
6
|
+
|
|
7
|
+
function hasStaticAwsCredentialEnv(env: NodeJS.ProcessEnv): boolean {
|
|
8
|
+
return Boolean(env.AWS_ACCESS_KEY_ID && env.AWS_SECRET_ACCESS_KEY);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function shouldRefreshAwsSharedConfigCacheForBedrock(env: NodeJS.ProcessEnv): boolean {
|
|
12
|
+
if (env.AWS_BEDROCK_SKIP_AUTH === "1" || env.AWS_BEARER_TOKEN_BEDROCK) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return !hasStaticAwsCredentialEnv(env);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async function loadSharedIniFileLoader(): Promise<SharedIniFileLoader> {
|
|
19
|
+
if (sharedIniFileLoaderForTest !== undefined) {
|
|
20
|
+
if (!sharedIniFileLoaderForTest) {
|
|
21
|
+
throw new Error("AWS shared INI file loader unavailable");
|
|
22
|
+
}
|
|
23
|
+
return sharedIniFileLoaderForTest;
|
|
24
|
+
}
|
|
25
|
+
return (await import("@smithy/shared-ini-file-loader")) as SharedIniFileLoader;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function refreshAwsSharedConfigCacheForBedrock(
|
|
29
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
30
|
+
): Promise<void> {
|
|
31
|
+
if (!shouldRefreshAwsSharedConfigCacheForBedrock(env)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const loader = await loadSharedIniFileLoader();
|
|
35
|
+
await loader.loadSharedConfigFiles({ ignoreCache: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function setAwsSharedIniFileLoaderForTest(
|
|
39
|
+
loader: SharedIniFileLoader | null | undefined,
|
|
40
|
+
): void {
|
|
41
|
+
sharedIniFileLoaderForTest = loader;
|
|
42
|
+
}
|
package/config-api.ts
ADDED
package/config-compat.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { isRecord } from "autobot/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
|
|
3
|
+
type JsonRecord = Record<string, unknown>;
|
|
4
|
+
|
|
5
|
+
const LEGACY_PATH = "models.bedrockDiscovery";
|
|
6
|
+
const TARGET_PATH = "plugins.entries.amazon-bedrock.config.discovery";
|
|
7
|
+
const BLOCKED_OBJECT_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
8
|
+
|
|
9
|
+
function isBlockedObjectKey(key: string): boolean {
|
|
10
|
+
return BLOCKED_OBJECT_KEYS.has(key);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getRecord(value: unknown): JsonRecord | null {
|
|
14
|
+
return isRecord(value) ? value : null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function ensureRecord(root: JsonRecord, key: string): JsonRecord {
|
|
18
|
+
const existing = root[key];
|
|
19
|
+
if (isRecord(existing)) {
|
|
20
|
+
return existing;
|
|
21
|
+
}
|
|
22
|
+
const next: JsonRecord = {};
|
|
23
|
+
root[key] = next;
|
|
24
|
+
return next;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function mergeMissing(target: JsonRecord, source: JsonRecord): void {
|
|
28
|
+
for (const [key, value] of Object.entries(source)) {
|
|
29
|
+
if (value === undefined || isBlockedObjectKey(key)) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const existing = target[key];
|
|
33
|
+
if (existing === undefined) {
|
|
34
|
+
target[key] = value;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (isRecord(existing) && isRecord(value)) {
|
|
38
|
+
mergeMissing(existing, value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function cloneRecord<T extends JsonRecord>(value: T | undefined): T {
|
|
44
|
+
return { ...value } as T;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function resolveLegacyBedrockDiscoveryConfig(raw: unknown): JsonRecord | undefined {
|
|
48
|
+
if (!isRecord(raw)) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const models = getRecord(raw.models);
|
|
52
|
+
return getRecord(models?.bedrockDiscovery) ?? undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function pruneEmptyModelsRoot(root: JsonRecord): void {
|
|
56
|
+
const models = getRecord(root.models);
|
|
57
|
+
if (models && Object.keys(models).length === 0) {
|
|
58
|
+
delete root.models;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function migrateAmazonBedrockLegacyConfig<T>(raw: T): { config: T; changes: string[] } {
|
|
63
|
+
if (!isRecord(raw)) {
|
|
64
|
+
return { config: raw, changes: [] };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const legacy = resolveLegacyBedrockDiscoveryConfig(raw);
|
|
68
|
+
if (!legacy) {
|
|
69
|
+
return { config: raw, changes: [] };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const nextRoot = structuredClone(raw) as JsonRecord;
|
|
73
|
+
const models = ensureRecord(nextRoot, "models");
|
|
74
|
+
delete models.bedrockDiscovery;
|
|
75
|
+
pruneEmptyModelsRoot(nextRoot);
|
|
76
|
+
|
|
77
|
+
const changes: string[] = [];
|
|
78
|
+
if (Object.keys(legacy).length === 0) {
|
|
79
|
+
changes.push(`Removed empty ${LEGACY_PATH}.`);
|
|
80
|
+
return { config: nextRoot as T, changes };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const plugins = ensureRecord(nextRoot, "plugins");
|
|
84
|
+
const entries = ensureRecord(plugins, "entries");
|
|
85
|
+
const entry = ensureRecord(entries, "amazon-bedrock");
|
|
86
|
+
const config = ensureRecord(entry, "config");
|
|
87
|
+
const existing = getRecord(config.discovery) ?? undefined;
|
|
88
|
+
|
|
89
|
+
if (!existing) {
|
|
90
|
+
config.discovery = cloneRecord(legacy);
|
|
91
|
+
changes.push(`Moved ${LEGACY_PATH} → ${TARGET_PATH}.`);
|
|
92
|
+
return { config: nextRoot as T, changes };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const merged = cloneRecord(existing);
|
|
96
|
+
mergeMissing(merged, legacy);
|
|
97
|
+
config.discovery = merged;
|
|
98
|
+
if (JSON.stringify(merged) !== JSON.stringify(existing)) {
|
|
99
|
+
changes.push(
|
|
100
|
+
`Merged ${LEGACY_PATH} → ${TARGET_PATH} (filled missing fields from legacy; kept explicit plugin config values).`,
|
|
101
|
+
);
|
|
102
|
+
return { config: nextRoot as T, changes };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
changes.push(`Removed ${LEGACY_PATH} (${TARGET_PATH} already set).`);
|
|
106
|
+
return { config: nextRoot as T, changes };
|
|
107
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { resolveAwsSdkEnvVarName } from "autobot/plugin-sdk/provider-auth-runtime";
|
|
2
|
+
import type { ModelProviderConfig } from "autobot/plugin-sdk/provider-model-shared";
|
|
3
|
+
|
|
4
|
+
export function resolveBedrockConfigApiKey(
|
|
5
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
6
|
+
): string | undefined {
|
|
7
|
+
// When no AWS auth env marker is present, Bedrock should fall back to the
|
|
8
|
+
// AWS SDK default credential chain instead of persisting a fake apiKey marker.
|
|
9
|
+
return resolveAwsSdkEnvVarName(env);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function mergeImplicitBedrockProvider(params: {
|
|
13
|
+
existing: ModelProviderConfig | undefined;
|
|
14
|
+
implicit: ModelProviderConfig;
|
|
15
|
+
}): ModelProviderConfig {
|
|
16
|
+
const { existing, implicit } = params;
|
|
17
|
+
if (!existing) {
|
|
18
|
+
return implicit;
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
...implicit,
|
|
22
|
+
...existing,
|
|
23
|
+
models:
|
|
24
|
+
Array.isArray(existing.models) && existing.models.length > 0
|
|
25
|
+
? existing.models
|
|
26
|
+
: implicit.models,
|
|
27
|
+
};
|
|
28
|
+
}
|