Skip to content

Commit 0080409

Browse files
committed
chore: wip
1 parent 7053316 commit 0080409

File tree

9 files changed

+175
-18
lines changed

9 files changed

+175
-18
lines changed

bun.lockb

1.7 KB
Binary file not shown.

storage/framework/.stacks/core/ai/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@
4747
"typecheck": "bun --bun tsc --noEmit",
4848
"prepublishOnly": "bun --bun run build"
4949
},
50+
"peerDependencies": {
51+
"@aws-sdk/client-bedrock-runtime": "^3.470.0"
52+
},
53+
"dependencies": {
54+
"@aws-sdk/client-bedrock-runtime": "^3.470.0"
55+
},
5056
"devDependencies": {
5157
"@stacksjs/development": "workspace:*"
5258
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
export * from './drivers'
1+
export * from './utils/client-bedrock'
2+
export * from './utils/client-bedrock-runtime'
3+
4+
// export * from './chatbots'
5+
// export * from './image-generation'
6+
// export * from './search'
7+
// export * from './text-generation'
8+
// export * from './text-summary'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import type { InvokeModelCommandInput, InvokeModelCommandOutput, InvokeModelWithResponseStreamCommandInput, InvokeModelWithResponseStreamCommandOutput } from '@aws-sdk/client-bedrock-runtime'
2+
import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelWithResponseStreamCommand } from '@aws-sdk/client-bedrock-runtime'
3+
4+
// eslint-disable-next-line node/prefer-global/process
5+
const client = new BedrockRuntimeClient({ region: process.env.REGION || 'us-east-1' })
6+
const logger = console // import your own logger
7+
8+
/*
9+
* Invoke Model
10+
* @param {InvokeModelCommandInput} params
11+
* @returns {Promise<InvokeModelCommandOutput>}
12+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/BedrockRuntime.html#invokeModel-property
13+
*/
14+
export async function invokeModel(params: InvokeModelCommandInput): Promise<InvokeModelCommandOutput> {
15+
logger.debug(params)
16+
const command = new InvokeModelCommand(params)
17+
const res = await client.send(command)
18+
logger.debug('Successfully invoke model')
19+
logger.debug(res)
20+
return res
21+
}
22+
23+
/*
24+
* Invoke Model With Response Stream
25+
* @param {InvokeModelWithResponseStreamCommandInput} params
26+
* @returns {Promise<InvokeModelWithResponseStreamCommandOutput>}
27+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/BedrockRuntime.html#invokeModelWithResponseStream-property
28+
*/
29+
export async function invokeModelWithResponseStream(params: InvokeModelWithResponseStreamCommandInput): Promise<InvokeModelWithResponseStreamCommandOutput> {
30+
logger.debug(params)
31+
const command = new InvokeModelWithResponseStreamCommand(params)
32+
const res = await client.send(command)
33+
logger.debug('Successfully invoke model with response stream')
34+
logger.debug(res)
35+
return res
36+
}
37+
38+
export type { InvokeModelCommandInput, InvokeModelWithResponseStreamCommandInput }
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { CreateModelCustomizationJobCommandInput, CreateModelCustomizationJobCommandOutput, GetModelCustomizationJobCommandInput, GetModelCustomizationJobCommandOutput, ListFoundationModelsCommandInput, ListFoundationModelsCommandOutput } from '@aws-sdk/client-bedrock'
2+
import { BedrockClient, CreateModelCustomizationJobCommand, GetModelCustomizationJobCommand, ListFoundationModelsCommand } from '@aws-sdk/client-bedrock'
3+
4+
// eslint-disable-next-line node/prefer-global/process
5+
const client = new BedrockClient({ region: process.env.REGION || 'us-east-1' })
6+
const logger = console // import your own logger
7+
8+
/*
9+
* Create Model Customization Job
10+
* @param {CreateModelCustomizationJobCommandInput} params
11+
* @returns {Promise<CreateModelCustomizationJobCommandOutput>}
12+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Bedrock.html#CreateModelCustomizationJob-property
13+
*/
14+
export async function createModelCustomizationJob(param: CreateModelCustomizationJobCommandInput): Promise<CreateModelCustomizationJobCommandOutput> {
15+
logger.debug(param)
16+
const command = new CreateModelCustomizationJobCommand(param)
17+
const res = await client.send(command)
18+
logger.debug('Successfully create model customization job')
19+
logger.debug(res)
20+
return res
21+
}
22+
23+
/*
24+
* Get Model Customization Job
25+
* @param {GetModelCustomizationJobCommandInput} params
26+
* @returns {Promise<GetModelCustomizationJobCommandOutput>}
27+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Bedrock.html#getModelCustomizationJob-property
28+
*/
29+
export async function getModelCustomizationJob(params: GetModelCustomizationJobCommandInput): Promise<GetModelCustomizationJobCommandOutput> {
30+
logger.debug(params)
31+
const command = new GetModelCustomizationJobCommand(params)
32+
const res = await client.send(command)
33+
logger.debug('Successfully get model customization job')
34+
logger.debug(res)
35+
return res
36+
}
37+
38+
/*
39+
* List Foundation Models
40+
* @param {ListFoundationModelsCommandInput} params
41+
* @returns {Promise<ListFoundationModelsCommandOutput>}
42+
* @see https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Bedrock.html#listFoundationModels-property
43+
*/
44+
export async function listFoundationModels(params: ListFoundationModelsCommandInput): Promise<ListFoundationModelsCommandOutput> {
45+
logger.debug(params)
46+
const command = new ListFoundationModelsCommand(params)
47+
const res = await client.send(command)
48+
logger.debug('Successfully list foundation models')
49+
logger.debug(res)
50+
return res
51+
}
52+
53+
export type { CreateModelCustomizationJobCommandInput, GetModelCustomizationJobCommandInput, ListFoundationModelsCommandInput }

storage/framework/.stacks/core/cloud/src/cloud/ai.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable no-new */
22
import {
3+
Duration,
34
CfnOutput as Output,
45
aws_iam as iam,
56
aws_lambda as lambda,
@@ -20,27 +21,38 @@ export class AiStack {
2021
description: 'Layer with aws-sdk',
2122
})
2223

23-
const aiRole = new iam.Role(scope, 'AiRole', {
24+
const bedrockAccessPolicy = new iam.PolicyStatement({
25+
effect: iam.Effect.ALLOW,
26+
actions: ['bedrock:InvokeModel'], // See: https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonbedrock.html
27+
resources: ['*'],
28+
})
29+
30+
const bedrockAccessRole = new iam.Role(scope, 'BedrockAccessRole', {
2431
assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
32+
managedPolicies: [
33+
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
34+
],
2535
})
2636

27-
// Granting the Lambda permission to invoke the AI model
28-
aiRole.addToPolicy(
29-
new iam.PolicyStatement({
30-
actions: ['bedrock:InvokeModel'],
31-
resources: config.ai.models?.map(model => `arn:aws:bedrock:us-east-1:${props.env.account}:foundation-model/${model}`),
32-
effect: iam.Effect.ALLOW,
33-
}),
34-
)
37+
bedrockAccessRole.addToPolicy(bedrockAccessPolicy)
38+
39+
// aiRole.addToPolicy(
40+
// new iam.PolicyStatement({
41+
// actions: ['bedrock:InvokeModel'],
42+
// resources: config.ai.models?.map(model => `arn:aws:bedrock:us-east-1:${props.env.account}:foundation-model/${model}`),
43+
// effect: iam.Effect.ALLOW,
44+
// }),
45+
// )
3546

36-
const aiLambda = new lambda.Function(scope, 'LambdaFunction', {
47+
const aiLambda = new lambda.Function(scope, 'AiFunction', {
3748
functionName: `${props.slug}-${props.appEnv}-ai`,
3849
description: 'Lambda function to invoke the AI model',
3950
runtime: lambda.Runtime.NODEJS_20_X,
4051
handler: 'index.handler',
4152
code: lambda.Code.fromAsset('src/cloud/lambda'), // path relative to the cloud root package dir
4253
layers: [awsSdkLayer],
43-
role: aiRole,
54+
role: bedrockAccessRole,
55+
timeout: Duration.seconds(30),
4456
})
4557

4658
const api = new lambda.FunctionUrl(scope, 'AiLambdaUrl', {

storage/framework/.stacks/core/cloud/src/cloud/lambda/index.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ async function handler(event) {
1212
const res = await bedrockRuntime.invokeModel({
1313
modelId: 'amazon.titan-text-express-v1',
1414
contentType: 'application/json',
15-
accept: '*/*',
16-
body: `{"prompt": "${question}","maxTokens":200,"temperature":0.7,"topP":1,"stopSequences":[],"countPenalty":{"scale":0},"presencePenalty":{"scale":0},"frequencyPenalty":{"scale":0}}`,
15+
accept: 'application/json',
16+
body: JSON.stringify({
17+
inputText: question,
18+
textGenerationConfig: {
19+
maxTokenCount: 300,
20+
stopSequences: [],
21+
temperature: 0,
22+
topP: 0.9,
23+
},
24+
}),
1725
}).promise()
1826

1927
return {

storage/framework/.stacks/core/cloud/src/helpers.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,28 @@ export async function deleteIamUsers() {
198198
if (!users || users.length === 0)
199199
return ok(`No Stacks IAM users found for team ${teamName}`)
200200

201-
const promises = users.map((user) => {
202-
// eslint-disable-next-line no-console
203-
console.log(`Deleting IAM user: ${user.UserName}`)
204-
return iam.deleteUser({ UserName: user.UserName || '' })
201+
const promises = users.map(async (user) => {
202+
const userName = user.UserName || '';
203+
console.log(`Deleting IAM user: ${userName}`)
204+
205+
// Get the list of policies attached to the user
206+
const policies = await iam.listAttachedUserPolicies({ UserName: userName });
207+
208+
// Detach each policy
209+
await Promise.all(policies.AttachedPolicies?.map(policy =>
210+
iam.detachUserPolicy({ UserName: userName, PolicyArn: policy.PolicyArn || '' })
211+
) || []);
212+
213+
// Get the list of access keys for the user
214+
const accessKeys = await iam.listAccessKeys({ UserName: userName });
215+
216+
// Delete each access key
217+
await Promise.all(accessKeys.AccessKeyMetadata?.map(key =>
218+
iam.deleteAccessKey({ UserName: userName, AccessKeyId: key.AccessKeyId || '' })
219+
) || []);
220+
221+
// Now delete the user
222+
return iam.deleteUser({ UserName: userName })
205223
})
206224

207225
await Promise.all(promises).catch((error: Error) => {

storage/framework/types/auto-imports.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ declare global {
150150
const createLocalTunnel: typeof import('../.stacks/core/tunnel/src/index')['createLocalTunnel']
151151
const createMigration: typeof import('../.stacks/core/actions/src/index')['createMigration']
152152
const createModel: typeof import('../.stacks/core/actions/src/index')['createModel']
153+
const createModelCustomizationJob: typeof import('../.stacks/core/ai/src/utils/client-bedrock')['createModelCustomizationJob']
153154
const createMysqlPool: typeof import('../.stacks/core/query-builder/src/kysely')['createMysqlPool']
154155
const createNotification: typeof import('../.stacks/core/actions/src/index')['createNotification']
155156
const createPage: typeof import('../.stacks/core/actions/src/index')['createPage']
@@ -306,6 +307,7 @@ declare global {
306307
const getExportsSize: typeof import('../.stacks/core/utils/src/export-size')['getExportsSize']
307308
const getFiles: typeof import('../.stacks/core/storage/src/files')['getFiles']
308309
const getFolders: typeof import('../.stacks/core/storage/src/folders')['getFolders']
310+
const getModelCustomizationJob: typeof import('../.stacks/core/ai/src/utils/client-bedrock')['getModelCustomizationJob']
309311
const getNameservers: typeof import('../.stacks/core/dns/src/drivers/aws')['getNameservers']
310312
const getSSRHandler: typeof import('../.stacks/core/utils/src/vendors')['getSSRHandler']
311313
const getTypeName: typeof import('../.stacks/core/types/src/helpers')['getTypeName']
@@ -349,6 +351,8 @@ declare global {
349351
const injectLocal: typeof import('../.stacks/core/utils/src/vendors')['injectLocal']
350352
const installIfVersionMismatch: typeof import('../.stacks/core/utils/src/helpers')['installIfVersionMismatch']
351353
const invoke: typeof import('../.stacks/core/actions/src/generate/index')['invoke']
354+
const invokeModel: typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModel']
355+
const invokeModelWithResponseStream: typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModelWithResponseStream']
352356
const isAbsolute: typeof import('../.stacks/core/path/src/index')['isAbsolute']
353357
const isAppKeySet: typeof import('../.stacks/core/utils/src/helpers')['isAppKeySet']
354358
const isArray: typeof import('../.stacks/core/validation/src/is')['isArray']
@@ -410,6 +414,7 @@ declare global {
410414
const libsEntriesPath: typeof import('../.stacks/core/path/src/index')['libsEntriesPath']
411415
const libsPath: typeof import('../.stacks/core/path/src/index')['libsPath']
412416
const lintPath: typeof import('../.stacks/core/path/src/index')['lintPath']
417+
const listFoundationModels: typeof import('../.stacks/core/ai/src/utils/client-bedrock')['listFoundationModels']
413418
const listen: typeof import('../.stacks/core/events/src/index')['listen']
414419
const loadYaml: typeof import('../.stacks/core/utils/src/helpers')['loadYaml']
415420
const log: typeof import('../.stacks/core/logging/src/index')['log']
@@ -1048,6 +1053,7 @@ declare module 'vue' {
10481053
readonly createLocalTunnel: UnwrapRef<typeof import('../.stacks/core/tunnel/src/index')['createLocalTunnel']>
10491054
readonly createMigration: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createMigration']>
10501055
readonly createModel: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createModel']>
1056+
readonly createModelCustomizationJob: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['createModelCustomizationJob']>
10511057
readonly createMysqlPool: UnwrapRef<typeof import('../.stacks/core/query-builder/src/kysely')['createMysqlPool']>
10521058
readonly createNotification: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createNotification']>
10531059
readonly createPage: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createPage']>
@@ -1204,6 +1210,7 @@ declare module 'vue' {
12041210
readonly getExportsSize: UnwrapRef<typeof import('../.stacks/core/utils/src/export-size')['getExportsSize']>
12051211
readonly getFiles: UnwrapRef<typeof import('../.stacks/core/storage/src/files')['getFiles']>
12061212
readonly getFolders: UnwrapRef<typeof import('../.stacks/core/storage/src/folders')['getFolders']>
1213+
readonly getModelCustomizationJob: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['getModelCustomizationJob']>
12071214
readonly getNameservers: UnwrapRef<typeof import('../.stacks/core/dns/src/drivers/aws')['getNameservers']>
12081215
readonly getSSRHandler: UnwrapRef<typeof import('../.stacks/core/utils/src/vendors')['getSSRHandler']>
12091216
readonly getTypeName: UnwrapRef<typeof import('../.stacks/core/types/src/helpers')['getTypeName']>
@@ -1247,6 +1254,8 @@ declare module 'vue' {
12471254
readonly injectLocal: UnwrapRef<typeof import('../.stacks/core/utils/src/vendors')['injectLocal']>
12481255
readonly installIfVersionMismatch: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['installIfVersionMismatch']>
12491256
readonly invoke: UnwrapRef<typeof import('../.stacks/core/actions/src/generate/index')['invoke']>
1257+
readonly invokeModel: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModel']>
1258+
readonly invokeModelWithResponseStream: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModelWithResponseStream']>
12501259
readonly isAbsolute: UnwrapRef<typeof import('../.stacks/core/path/src/index')['isAbsolute']>
12511260
readonly isAppKeySet: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['isAppKeySet']>
12521261
readonly isArray: UnwrapRef<typeof import('../.stacks/core/validation/src/is')['isArray']>
@@ -1308,6 +1317,7 @@ declare module 'vue' {
13081317
readonly libsEntriesPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['libsEntriesPath']>
13091318
readonly libsPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['libsPath']>
13101319
readonly lintPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['lintPath']>
1320+
readonly listFoundationModels: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['listFoundationModels']>
13111321
readonly listen: UnwrapRef<typeof import('../.stacks/core/events/src/index')['listen']>
13121322
readonly loadYaml: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['loadYaml']>
13131323
readonly log: UnwrapRef<typeof import('../.stacks/core/logging/src/index')['log']>
@@ -1931,6 +1941,7 @@ declare module '@vue/runtime-core' {
19311941
readonly createLocalTunnel: UnwrapRef<typeof import('../.stacks/core/tunnel/src/index')['createLocalTunnel']>
19321942
readonly createMigration: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createMigration']>
19331943
readonly createModel: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createModel']>
1944+
readonly createModelCustomizationJob: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['createModelCustomizationJob']>
19341945
readonly createMysqlPool: UnwrapRef<typeof import('../.stacks/core/query-builder/src/kysely')['createMysqlPool']>
19351946
readonly createNotification: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createNotification']>
19361947
readonly createPage: UnwrapRef<typeof import('../.stacks/core/actions/src/index')['createPage']>
@@ -2087,6 +2098,7 @@ declare module '@vue/runtime-core' {
20872098
readonly getExportsSize: UnwrapRef<typeof import('../.stacks/core/utils/src/export-size')['getExportsSize']>
20882099
readonly getFiles: UnwrapRef<typeof import('../.stacks/core/storage/src/files')['getFiles']>
20892100
readonly getFolders: UnwrapRef<typeof import('../.stacks/core/storage/src/folders')['getFolders']>
2101+
readonly getModelCustomizationJob: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['getModelCustomizationJob']>
20902102
readonly getNameservers: UnwrapRef<typeof import('../.stacks/core/dns/src/drivers/aws')['getNameservers']>
20912103
readonly getSSRHandler: UnwrapRef<typeof import('../.stacks/core/utils/src/vendors')['getSSRHandler']>
20922104
readonly getTypeName: UnwrapRef<typeof import('../.stacks/core/types/src/helpers')['getTypeName']>
@@ -2130,6 +2142,8 @@ declare module '@vue/runtime-core' {
21302142
readonly injectLocal: UnwrapRef<typeof import('../.stacks/core/utils/src/vendors')['injectLocal']>
21312143
readonly installIfVersionMismatch: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['installIfVersionMismatch']>
21322144
readonly invoke: UnwrapRef<typeof import('../.stacks/core/actions/src/generate/index')['invoke']>
2145+
readonly invokeModel: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModel']>
2146+
readonly invokeModelWithResponseStream: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock-runtime')['invokeModelWithResponseStream']>
21332147
readonly isAbsolute: UnwrapRef<typeof import('../.stacks/core/path/src/index')['isAbsolute']>
21342148
readonly isAppKeySet: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['isAppKeySet']>
21352149
readonly isArray: UnwrapRef<typeof import('../.stacks/core/validation/src/is')['isArray']>
@@ -2191,6 +2205,7 @@ declare module '@vue/runtime-core' {
21912205
readonly libsEntriesPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['libsEntriesPath']>
21922206
readonly libsPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['libsPath']>
21932207
readonly lintPath: UnwrapRef<typeof import('../.stacks/core/path/src/index')['lintPath']>
2208+
readonly listFoundationModels: UnwrapRef<typeof import('../.stacks/core/ai/src/utils/client-bedrock')['listFoundationModels']>
21942209
readonly listen: UnwrapRef<typeof import('../.stacks/core/events/src/index')['listen']>
21952210
readonly loadYaml: UnwrapRef<typeof import('../.stacks/core/utils/src/helpers')['loadYaml']>
21962211
readonly log: UnwrapRef<typeof import('../.stacks/core/logging/src/index')['log']>

0 commit comments

Comments
 (0)