-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(generation-transformer): add generation transformer #2820
Conversation
}; | ||
const solveEquationResult = await doAppSyncGraphqlQuery({ ...args, query: solveEquation, variables }); | ||
const solution = solveEquationResult.body.data.solveEquation; | ||
expect(solution).toBeDefined(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're asserting that we get an answer here, not the correct answer because LLMs are not good (being generous) at math.
// TODO: This currently doesn't work because LLMs are not great at following regex pattern requirements, they'll sometimes return "<UNKNOWN>" | ||
// which fails GraphQL type validation for implicitly generated required model values like id, createdAt, updatedAt. | ||
xtest('should generate a model', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is currently disabled because we throw in the transformer when the return type contains required fields typed as certain AppSync scalars.
We're exploring options, including prompt improvements, better regex pattern in JSON Schema tool definitions, and special case handling for models (omitting createdAt, updatedAt, and id in tool definition, and populating them in the resolver).
For now, this is an accepted current limitation.
resolverResourceId, | ||
invokeBedrockFunction.req, | ||
invokeBedrockFunction.res, | ||
['auth'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows existing VTL @auth
generated resolver functions to be inserted into the pipeline resolver.
['auth'], | ||
[], | ||
dataSource as any, | ||
{ name: 'APPSYNC_JS', runtimeVersion: '1.0.0' }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should eventually be a constant defined in amplify-graphql-transformer-core, but it's only being used here for now. Will add one in a follow up if / when it becomes necessary.
* @returns {MappingTemplateProvider} A MappingTemplateProvider for the response function. | ||
*/ | ||
const createInvokeBedrockResponseFunction = (): MappingTemplateProvider => { | ||
// TODO: add stopReason: max_tokens error handling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Planned followup to improve the error message.
packages/amplify-graphql-transformer-interfaces/src/transform-host-provider.ts
Show resolved
Hide resolved
----- MARK REVIEW ----- |
...lify-graphql-api-construct-tests/src/__tests__/generations/graphql/schema-generation.graphql
Outdated
Show resolved
Hide resolved
...-graphql-generation-transformer/src/__tests__/amplify-graphql-generation-transformer.test.ts
Show resolved
Hide resolved
packages/amplify-graphql-api-construct-tests/src/__tests__/generations/generation.test.ts
Show resolved
Hide resolved
...-graphql-generation-transformer/src/__tests__/amplify-graphql-generation-transformer.test.ts
Outdated
Show resolved
Hide resolved
packages/amplify-graphql-generation-transformer/src/grapqhl-generation-transformer.ts
Show resolved
Hide resolved
packages/amplify-graphql-transformer-interfaces/src/transform-host-provider.ts
Show resolved
Hide resolved
...s/amplify-graphql-generation-transformer/src/utils/graphql-scalar-json-schema-definitions.ts
Show resolved
Hide resolved
|
||
export type GenerationDirectiveConfiguration = { | ||
parent: ObjectTypeDefinitionNode; | ||
directive: DirectiveNode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to store the directive definition when the actual directive arguments are already listed out separately below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, we don't! I'll remove this in a follow up. Thanks!
}; | ||
|
||
const stackName = `Generation${this.capitalizeFirstLetter(fieldName)}BedrockDataSourceStack`; | ||
const stack = this.createStack(ctx, stackName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think Tim has a good point here and might be worth discussing the trade offs with team before we release. I couldn't find any AppSync imposed limit on number of datasources, but feel like re-use will save us from trouble in the future.
toolSpec: ToolSpec; | ||
}; | ||
|
||
export type Tools = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you use this type elsewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't, and your comment made me realize that we only actually need to export ToolConfig
. The extra export
s and Tools
type definition are relics from previous structure. Will remove in a follow up. Thanks for the callout!
exports[`generation route all scalar types 2`] = ` | ||
"export function request(ctx) { | ||
const toolConfig = {\\"tools\\":[{\\"toolSpec\\":{\\"name\\":\\"responseType\\",\\"description\\":\\"Generate a response type for the given field\\",\\"inputSchema\\":{\\"json\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"value\\":{\\"type\\":\\"object\\",\\"properties\\":{\\"int\\":{\\"type\\":\\"number\\",\\"description\\":\\"A signed 32-bit integer value.\\"},\\"float\\":{\\"type\\":\\"number\\",\\"description\\":\\"An IEEE 754 floating point value.\\"},\\"string\\":{\\"type\\":\\"string\\",\\"description\\":\\"A UTF-8 character sequence.\\"},\\"id\\":{\\"type\\":\\"string\\",\\"description\\":\\"A unique identifier for an object. This scalar is serialized like a String but isn't meant to be human-readable.\\"},\\"boolean\\":{\\"type\\":\\"boolean\\",\\"description\\":\\"A boolean value.\\"},\\"awsjson\\":{\\"type\\":\\"string\\",\\"description\\":\\"A JSON string. Any valid JSON construct is automatically parsed and loaded in the resolver code as maps, lists, or scalar values rather than as the literal input strings. Unquoted strings or otherwise invalid JSON result in a GraphQL validation error.\\"},\\"awsemail\\":{\\"type\\":\\"string\\",\\"description\\":\\"An email address in the format local-part@domain-part as defined by RFC 822.\\",\\"pattern\\":\\"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,}$\\"},\\"awsdate\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date string in the format YYYY-MM-DD.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-d{2}-d{2}$\\"},\\"awstime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 time string in the format hh:mm:ss.sss.\\",\\"pattern\\":\\"^\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}$\\"},\\"awsdatetime\\":{\\"type\\":\\"string\\",\\"description\\":\\"An extended ISO 8601 date and time string in the format YYYY-MM-DDThh:mm:ss.sssZ.\\",\\"pattern\\":\\"^\\\\\\\\d{4}-\\\\\\\\d{2}-\\\\\\\\d{2}T\\\\\\\\d{2}:\\\\\\\\d{2}:\\\\\\\\d{2}\\\\\\\\.\\\\\\\\d{3}Z$\\"},\\"awstimestamp\\":{\\"type\\":\\"string\\",\\"description\\":\\"An integer value representing the number of seconds before or after 1970-01-01-T00:00Z.\\",\\"pattern\\":\\"^\\\\\\\\d+$\\"},\\"awsphone\\":{\\"type\\":\\"string\\",\\"description\\":\\"A phone number. This value is stored as a string. Phone numbers can contain either spaces or hyphens to separate digit groups. Phone numbers without a country code are assumed to be US/North American numbers adhering to the North American Numbering Plan (NANP).\\",\\"pattern\\":\\"^\\\\\\\\d{3}-d{3}-d{4}$\\"},\\"awsurl\\":{\\"type\\":\\"string\\",\\"description\\":\\"A URL as defined by RFC 1738. For example, https://www.amazon.com/dp/B000NZW3KC/ or mailto:[email protected]. URLs must contain a schema (http, mailto) and can't contain two forward slashes (//) in the path part.\\",\\"pattern\\":\\"^(https?|mailto)://[^s/$.?#].[^s]*$\\"},\\"awsipaddress\\":{\\"type\\":\\"string\\",\\"description\\":\\"A valid IPv4 or IPv6 address. IPv4 addresses are expected in quad-dotted notation (123.12.34.56). IPv6 addresses are expected in non-bracketed, colon-separated format (1a2b:3c4b::1234:4567). You can include an optional CIDR suffix (123.45.67.89/16) to indicate subnet mask.\\"}},\\"required\\":[]}},\\"required\\":[\\"value\\"]}}}}],\\"toolChoice\\":{\\"tool\\":{\\"name\\":\\"responseType\\"}}}; | ||
const prompt = \\"\\"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We give so much information and it still returns a response with wrong format? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea 😞
We haven't found a generic solution yet, but we've seen some promising results with various techniques, and are cautiously optimistic that we can get there.
Description of changes
Amplify GraphQL Generation Transformer
The Amplify GraphQL Generation Transformer is a tool that enables the quick and easy creation of AI-powered Generation routes within your AWS AppSync API. This transformer can be leveraged by using the
@generation
directive to configure AI models and system prompts for generating content.Directive Definition
The
@generation
directive is defined as follows:Features
@auth
Directive: Supports existing auth modes like IAM, API key, and Amazon Cognito User Pools.Examples
Basic Usage
Scalar Type Generation
Complex Type Generation
Advanced Configuration
Limitations
@generation
directive can only be used on Query fields.CDK / CloudFormation Parameters Changed
N/A
Issue #, if available
N/A
Description of how you validated changes
Checklist
yarn test
passesRelevant documentation is changed or added (and PR referenced)Docs PRs are WIPBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.