From c5660e69c90b4c24fef90d119ab484da7dc0057b Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Mon, 10 Apr 2023 15:30:06 -0500 Subject: [PATCH 01/62] Add autorest.md file --- sdk/cognitiveservices/azopenai/autorest.md | 112 +++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/autorest.md diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md new file mode 100644 index 000000000000..e846b55f60c3 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -0,0 +1,112 @@ +# Go + +These settings apply only when `--go` is specified on the command line. + +``` yaml +input-file: +- https://github.com/mikekistler/azure-rest-api-specs/blob/baed660fd853b4a387ca9f0b9491fd1414b66e9e/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2023-03-15-preview/inference.json +output-folder: ../azopenai +clear-output-folder: false +module: github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai +license-header: MICROSOFT_MIT_NO_VERSION +openapi-type: data-plane +go: true +use: "@autorest/go@4.0.0-preview.48" +``` + +## Transformations + +``` yaml +directive: + # Add x-ms-parameter-location to parameters in x-ms-parameterized-host + - from: openapi-document + where: $.servers.0.variables.endpoint + debug: true + transform: $["x-ms-parameter-location"] = "client"; + + # Make deploymentId a client parameter + # This must be done in each operation as the parameter is not defined in the components section + - from: openapi-document + where: $.paths..parameters..[?(@.name=='deploymentId')] + transform: $["x-ms-parameter-location"] = "client"; + + # Update operationIds to combine all operations into a single client + - rename-operation: + from: getCompletions + to: OpenAI_GetCompletions + - rename-operation: + from: getEmbeddings + to: OpenAI_GetEmbeddings + - rename-operation: + from: getChatCompletions + to: OpenAI_GetChatCompletions + + # Mark request bodies as required (TypeSpec issue #1838) + - from: openapi-document + where: $.paths["/deployments/{deploymentId}/completions"].post.requestBody + transform: $["required"] = true; + - from: openapi-document + where: $.paths["/deployments/{deploymentId}/embeddings"].post.requestBody + transform: $["required"] = true; + + # Remove stream property from CompletionsOptions and ChatCompletionsOptions + - from: openapi-document + where: $.components.schemas["CompletionsOptions"] + transform: delete $.properties.stream; + - from: openapi-document + where: $.components.schemas["ChatCompletionsOptions"] + transform: delete $.properties.stream; + + # Replace anyOf schemas with an empty schema (no type) to get an "any" type generated + - from: openapi-document + where: '$.components.schemas["EmbeddingsOptions"].properties["input"]' + transform: delete $.anyOf; + + # Fix autorest bug + - from: openapi-document + where: $.components.schemas["ChatMessage"].properties.role + transform: > + delete $.allOf; + $["$ref"] = "#/components/schemas/ChatRole"; + + # Fix another autorest bug + - from: openapi-document + where: $.components.schemas["Choice"].properties.finish_reason + transform: > + delete $.oneOf; + $["$ref"] = "#/components/schemas/CompletionsFinishReason"; + - from: openapi-document + where: $.components.schemas["ChatChoice"].properties.finish_reason + transform: > + delete $.oneOf; + $["$ref"] = "#/components/schemas/CompletionsFinishReason"; + + # Fix "AutoGenerated" models + - from: openapi-document + where: $.components.schemas["ChatCompletions"].properties.usage + transform: > + delete $.allOf; + $["$ref"] = "#/components/schemas/CompletionsUsage"; + - from: openapi-document + where: $.components.schemas["Completions"].properties.usage + transform: > + delete $.allOf; + $["$ref"] = "#/components/schemas/CompletionsUsage"; + + # Remove deploymentId from path when not set + - from: client.go + where: $ + transform: return $.replace(/\sreturn.*parameter client.deploymentID cannot be empty"\)\s/g, "urlPath = strings.ReplaceAll(urlPath, \"/deployments/{deploymentId}/\", \"/v1/\")"); + # Drop error import + - from: client.go + where: $ + transform: return $.replace(/(import \(\n(\s\"\w+\"\n)+)\s\"errors\"\n/g, "$1"); + + # delete unused error models + - from: models.go + where: $ + transform: return $.replace(/(?:\/\/.*\s)?type (?:ErrorResponse|ErrorResponseError).+\{(?:\s.+\s)+\}\s/g, ""); + - from: models_serde.go + where: $ + transform: return $.replace(/(?:\/\/.*\s)?func \(\w \*?(?:ErrorResponse|ErrorResponseError)\).*\{\s(?:.+\s)+\}\s/g, ""); +``` From 182a3b9e65f8c1de143ce6369bcc29ab9d92e808 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Mon, 10 Apr 2023 15:45:57 -0500 Subject: [PATCH 02/62] Add build.go --- sdk/cognitiveservices/azopenai/build.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/build.go diff --git a/sdk/cognitiveservices/azopenai/build.go b/sdk/cognitiveservices/azopenai/build.go new file mode 100644 index 000000000000..ac79e21f95c3 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/build.go @@ -0,0 +1,11 @@ +//go:build go1.18 +// +build go1.18 + +//go:generate autorest ./autorest.md +//go:generate go mod tidy +//go:generate gofmt -w . + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai From 216b15c9517df029833a23c0c63157ae37ee3359 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Mon, 10 Apr 2023 15:55:32 -0500 Subject: [PATCH 03/62] Generated client --- sdk/cognitiveservices/azopenai/client.go | 171 ++++ sdk/cognitiveservices/azopenai/constants.go | 61 ++ sdk/cognitiveservices/azopenai/go.mod | 11 + sdk/cognitiveservices/azopenai/go.sum | 12 + sdk/cognitiveservices/azopenai/models.go | 426 ++++++++ .../azopenai/models_serde.go | 947 ++++++++++++++++++ .../azopenai/response_types.go | 25 + 7 files changed, 1653 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/client.go create mode 100644 sdk/cognitiveservices/azopenai/constants.go create mode 100644 sdk/cognitiveservices/azopenai/go.mod create mode 100644 sdk/cognitiveservices/azopenai/go.sum create mode 100644 sdk/cognitiveservices/azopenai/models.go create mode 100644 sdk/cognitiveservices/azopenai/models_serde.go create mode 100644 sdk/cognitiveservices/azopenai/response_types.go diff --git a/sdk/cognitiveservices/azopenai/client.go b/sdk/cognitiveservices/azopenai/client.go new file mode 100644 index 000000000000..f9949caf4318 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/client.go @@ -0,0 +1,171 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package azopenai + +import ( + "context" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + "net/http" + "net/url" + "strings" +) + +// Client contains the methods for the OpenAI group. +// Don't use this type directly, use a constructor function instead. +type Client struct { + internal *azcore.Client + endpoint string + deploymentID string +} + +// GetChatCompletions - Gets chat completions for the provided chat messages. Completions support a wide variety of tasks +// and generate text that continues from or "completes" provided prompt data. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2023-03-15-preview +// - options - ClientGetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. +func (client *Client) GetChatCompletions(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (ClientGetChatCompletionsResponse, error) { + req, err := client.getChatCompletionsCreateRequest(ctx, body, options) + if err != nil { + return ClientGetChatCompletionsResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetChatCompletionsResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientGetChatCompletionsResponse{}, runtime.NewResponseError(resp) + } + return client.getChatCompletionsHandleResponse(resp) +} + +// getChatCompletionsCreateRequest creates the GetChatCompletions request. +func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (*policy.Request, error) { + urlPath := "/deployments/{deploymentId}/chat/completions" + if client.deploymentID == "" { + urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2023-03-15-preview") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, runtime.MarshalAsJSON(req, body) +} + +// getChatCompletionsHandleResponse handles the GetChatCompletions response. +func (client *Client) getChatCompletionsHandleResponse(resp *http.Response) (ClientGetChatCompletionsResponse, error) { + result := ClientGetChatCompletionsResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.ChatCompletions); err != nil { + return ClientGetChatCompletionsResponse{}, err + } + return result, nil +} + +// GetCompletions - Gets completions for the provided input prompts. Completions support a wide variety of tasks and generate +// text that continues from or "completes" provided prompt data. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2023-03-15-preview +// - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +func (client *Client) GetCompletions(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (ClientGetCompletionsResponse, error) { + req, err := client.getCompletionsCreateRequest(ctx, body, options) + if err != nil { + return ClientGetCompletionsResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetCompletionsResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientGetCompletionsResponse{}, runtime.NewResponseError(resp) + } + return client.getCompletionsHandleResponse(resp) +} + +// getCompletionsCreateRequest creates the GetCompletions request. +func (client *Client) getCompletionsCreateRequest(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (*policy.Request, error) { + urlPath := "/deployments/{deploymentId}/completions" + if client.deploymentID == "" { + urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2023-03-15-preview") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, runtime.MarshalAsJSON(req, body) +} + +// getCompletionsHandleResponse handles the GetCompletions response. +func (client *Client) getCompletionsHandleResponse(resp *http.Response) (ClientGetCompletionsResponse, error) { + result := ClientGetCompletionsResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Completions); err != nil { + return ClientGetCompletionsResponse{}, err + } + return result, nil +} + +// GetEmbeddings - Return the embeddings for a given prompt. +// If the operation fails it returns an *azcore.ResponseError type. +// +// Generated from API version 2023-03-15-preview +// - options - ClientGetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. +func (client *Client) GetEmbeddings(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (ClientGetEmbeddingsResponse, error) { + req, err := client.getEmbeddingsCreateRequest(ctx, body, options) + if err != nil { + return ClientGetEmbeddingsResponse{}, err + } + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return ClientGetEmbeddingsResponse{}, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return ClientGetEmbeddingsResponse{}, runtime.NewResponseError(resp) + } + return client.getEmbeddingsHandleResponse(resp) +} + +// getEmbeddingsCreateRequest creates the GetEmbeddings request. +func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (*policy.Request, error) { + urlPath := "/deployments/{deploymentId}/embeddings" + if client.deploymentID == "" { + urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") + } + urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) + if err != nil { + return nil, err + } + reqQP := req.Raw().URL.Query() + reqQP.Set("api-version", "2023-03-15-preview") + req.Raw().URL.RawQuery = reqQP.Encode() + req.Raw().Header["Accept"] = []string{"application/json"} + return req, runtime.MarshalAsJSON(req, body) +} + +// getEmbeddingsHandleResponse handles the GetEmbeddings response. +func (client *Client) getEmbeddingsHandleResponse(resp *http.Response) (ClientGetEmbeddingsResponse, error) { + result := ClientGetEmbeddingsResponse{} + if err := runtime.UnmarshalAsJSON(resp, &result.Embeddings); err != nil { + return ClientGetEmbeddingsResponse{}, err + } + return result, nil +} diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go new file mode 100644 index 000000000000..e9517274b03e --- /dev/null +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -0,0 +1,61 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package azopenai + +// ChatRole - A description of the intended purpose of a message within a chat completions interaction. +type ChatRole string + +const ( + ChatRoleAssistant ChatRole = "assistant" + ChatRoleSystem ChatRole = "system" + ChatRoleUser ChatRole = "user" +) + +// PossibleChatRoleValues returns the possible values for the ChatRole const type. +func PossibleChatRoleValues() []ChatRole { + return []ChatRole{ + ChatRoleAssistant, + ChatRoleSystem, + ChatRoleUser, + } +} + +// CompletionsFinishReason - Representation of the manner in which a completions response concluded. +type CompletionsFinishReason string + +const ( + CompletionsFinishReasonContentFilter CompletionsFinishReason = "content_filter" + CompletionsFinishReasonLength CompletionsFinishReason = "length" + CompletionsFinishReasonStop CompletionsFinishReason = "stop" +) + +// PossibleCompletionsFinishReasonValues returns the possible values for the CompletionsFinishReason const type. +func PossibleCompletionsFinishReasonValues() []CompletionsFinishReason { + return []CompletionsFinishReason{ + CompletionsFinishReasonContentFilter, + CompletionsFinishReasonLength, + CompletionsFinishReasonStop, + } +} + +type ServiceAPIVersions string + +const ( + ServiceAPIVersionsTwoThousandTwentyThree0315Preview ServiceAPIVersions = "2023-03-15-preview" + ServiceAPIVersionsTwoThousandTwentyTwo1201 ServiceAPIVersions = "2022-12-01" +) + +// PossibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. +func PossibleServiceAPIVersionsValues() []ServiceAPIVersions { + return []ServiceAPIVersions{ + ServiceAPIVersionsTwoThousandTwentyThree0315Preview, + ServiceAPIVersionsTwoThousandTwentyTwo1201, + } +} diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod new file mode 100644 index 000000000000..e051c62950e0 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -0,0 +1,11 @@ +module github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai + +go 1.18 + +require github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 + +require ( + github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/text v0.7.0 // indirect +) diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum new file mode 100644 index 000000000000..d39a720dafd8 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -0,0 +1,12 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJVR2cMC8lvZcimipiEY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/sdk/cognitiveservices/azopenai/models.go b/sdk/cognitiveservices/azopenai/models.go new file mode 100644 index 000000000000..b385329dae68 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/models.go @@ -0,0 +1,426 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package azopenai + +// AzureCoreFoundationsError - The error object. +type AzureCoreFoundationsError struct { + // REQUIRED; One of a server-defined set of error codes. + Code *string + + // REQUIRED; An array of details about specific errors that led to this reported error. + Details []*AzureCoreFoundationsError + + // REQUIRED; A human-readable representation of the error. + Message *string + + // An object containing more specific information than the current object about the error. + Innererror *AzureCoreFoundationsErrorInnererror + + // The target of the error. + Target *string +} + +// AzureCoreFoundationsErrorInnererror - An object containing more specific information than the current object about the +// error. +type AzureCoreFoundationsErrorInnererror struct { + // REQUIRED; One of a server-defined set of error codes. + Code *string + + // Inner error. + Innererror *AzureCoreFoundationsInnerErrorInnererror +} + +// AzureCoreFoundationsErrorResponse - A response containing error details. +type AzureCoreFoundationsErrorResponse struct { + // REQUIRED; The error object. + Error *AzureCoreFoundationsErrorResponseError +} + +// AzureCoreFoundationsErrorResponseError - The error object. +type AzureCoreFoundationsErrorResponseError struct { + // REQUIRED; One of a server-defined set of error codes. + Code *string + + // REQUIRED; An array of details about specific errors that led to this reported error. + Details []*AzureCoreFoundationsError + + // REQUIRED; A human-readable representation of the error. + Message *string + + // An object containing more specific information than the current object about the error. + Innererror *AzureCoreFoundationsErrorInnererror + + // The target of the error. + Target *string +} + +// AzureCoreFoundationsInnerError - An object containing more specific information about the error. As per Microsoft One API +// guidelines - +// https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses. +type AzureCoreFoundationsInnerError struct { + // REQUIRED; One of a server-defined set of error codes. + Code *string + + // Inner error. + Innererror *AzureCoreFoundationsInnerErrorInnererror +} + +// AzureCoreFoundationsInnerErrorInnererror - Inner error. +type AzureCoreFoundationsInnerErrorInnererror struct { + // REQUIRED; One of a server-defined set of error codes. + Code *string + + // Inner error. + Innererror *AzureCoreFoundationsInnerErrorInnererror +} + +// ChatChoice - The representation of a single prompt completion as part of an overall chat completions request. Generally, +// n choices are generated per provided prompt with a default value of 1. Token limits and +// other settings may limit the number of choices generated. +type ChatChoice struct { + // REQUIRED; The reason that this chat completions choice completed its generated. + FinishReason *CompletionsFinishReason + + // REQUIRED; The ordered index associated with this chat completions choice. + Index *int32 + + // The delta message content for a streaming response. + Delta *ChatChoiceDelta + + // The chat message for a given chat completions prompt. + Message *ChatChoiceMessage +} + +// ChatChoiceDelta - The delta message content for a streaming response. +type ChatChoiceDelta struct { + // REQUIRED; The role associated with this message payload. + Role *ChatRole + + // The text associated with this message payload. + Content *string +} + +// ChatChoiceMessage - The chat message for a given chat completions prompt. +type ChatChoiceMessage struct { + // REQUIRED; The role associated with this message payload. + Role *ChatRole + + // The text associated with this message payload. + Content *string +} + +// ChatCompletions - Representation of the response data from a chat completions request. Completions support a wide variety +// of tasks and generate text that continues from or "completes" provided prompt data. +type ChatCompletions struct { + // REQUIRED; The collection of completions choices associated with this completions response. Generally, n choices are generated + // per provided prompt with a default value of 1. Token limits and other settings may + // limit the number of choices generated. + Choices []*ChatChoice + + // REQUIRED; The first timestamp associated with generation activity for this completions response, represented as seconds + // since the beginning of the Unix epoch of 00:00 on 1 Jan 1970. + Created *int32 + + // REQUIRED; A unique identifier associated with this chat completions response. + ID *string + + // REQUIRED; Usage information for tokens processed and generated as part of this completions operation. + Usage *CompletionsUsage +} + +// ChatCompletionsOptions - The configuration information for a chat completions request. Completions support a wide variety +// of tasks and generate text that continues from or "completes" provided prompt data. +type ChatCompletionsOptions struct { + // REQUIRED; The collection of context messages associated with this chat completions request. Typical usage begins with a + // chat message for the System role that provides instructions for the behavior of the + // assistant, followed by alternating messages between the User and Assistant roles. + Messages []*ChatMessage + + // A value that influences the probability of generated tokens appearing based on their cumulative frequency in generated + // text. Positive values will make tokens less likely to appear as their frequency + // increases and decrease the likelihood of the model repeating the same statements verbatim. + FrequencyPenalty *float32 + + // A map between GPT token IDs and bias scores that influences the probability of specific tokens appearing in a completions + // response. Token IDs are computed via external tokenizer tools, while bias + // scores reside in the range of -100 to 100 with minimum and maximum values corresponding to a full ban or exclusive selection + // of a token, respectively. The exact behavior of a given bias score varies + // by model. + LogitBias map[string]*int32 + + // The maximum number of tokens to generate. + MaxTokens *int32 + + // The model name to provide as part of this completions request. Not applicable to Azure OpenAI, where deployment information + // should be included in the Azure resource URI that's connected to. + Model *string + + // The number of chat completions choices that should be generated for a chat completions response. Because this setting can + // generate many completions, it may quickly consume your token quota. Use + // carefully and ensure reasonable settings for max_tokens and stop. + N *int32 + + // A value that influences the probability of generated tokens appearing based on their existing presence in generated text. + // Positive values will make tokens less likely to appear when they already exist + // and increase the model's likelihood to output new topics. + PresencePenalty *float32 + + // A collection of textual sequences that will end completions generation. + Stop []*string + + // The sampling temperature to use that controls the apparent creativity of generated completions. Higher values will make + // output more random while lower values will make results more focused and + // deterministic. It is not recommended to modify temperature and top_p for the same completions request as the interaction + // of these two settings is difficult to predict. + Temperature *float32 + + // An alternative to sampling with temperature called nucleus sampling. This value causes the model to consider the results + // of tokens with the provided probability mass. As an example, a value of 0.15 + // will cause only the tokens comprising the top 15% of probability mass to be considered. It is not recommended to modify + // temperature and top_p for the same completions request as the interaction of + // these two settings is difficult to predict. + TopP *float32 + + // An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. + User *string +} + +// ChatMessage - A single, role-attributed message within a chat completion interaction. +type ChatMessage struct { + // REQUIRED; The role associated with this message payload. + Role *ChatRole + + // The text associated with this message payload. + Content *string +} + +// Choice - The representation of a single prompt completion as part of an overall completions request. Generally, n choices +// are generated per provided prompt with a default value of 1. Token limits and other +// settings may limit the number of choices generated. +type Choice struct { + // REQUIRED; Reason for finishing + FinishReason *CompletionsFinishReason + + // REQUIRED; The ordered index associated with this completions choice. + Index *int32 + + // REQUIRED; The log probabilities model for tokens associated with this completions choice. + Logprobs *ChoiceLogprobs + + // REQUIRED; The generated text for a given completions prompt. + Text *string +} + +// ChoiceLogprobs - The log probabilities model for tokens associated with this completions choice. +type ChoiceLogprobs struct { + // REQUIRED; The text offsets associated with tokens in this completions data. + TextOffset []*int32 + + // REQUIRED; A collection of log probability values for the tokens in this completions data. + TokenLogprobs []*float32 + + // REQUIRED; The textual forms of tokens evaluated in this probability model. + Tokens []*string + + // REQUIRED; A mapping of tokens to maximum log probability values in this completions data. + TopLogprobs []any +} + +// ClientGetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. +type ClientGetChatCompletionsOptions struct { + // placeholder for future optional parameters +} + +// ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +type ClientGetCompletionsOptions struct { + // placeholder for future optional parameters +} + +// ClientGetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. +type ClientGetEmbeddingsOptions struct { + // placeholder for future optional parameters +} + +// Completions - Representation of the response data from a completions request. Completions support a wide variety of tasks +// and generate text that continues from or "completes" provided prompt data. +type Completions struct { + // REQUIRED; The collection of completions choices associated with this completions response. Generally, n choices are generated + // per provided prompt with a default value of 1. Token limits and other settings may + // limit the number of choices generated. + Choices []*Choice + + // REQUIRED; The first timestamp associated with generation activity for this completions response, represented as seconds + // since the beginning of the Unix epoch of 00:00 on 1 Jan 1970. + Created *int32 + + // REQUIRED; A unique identifier associated with this completions response. + ID *string + + // REQUIRED; Usage information for tokens processed and generated as part of this completions operation. + Usage *CompletionsUsage +} + +// CompletionsLogProbabilityModel - Representation of a log probabilities model for a completions generation. +type CompletionsLogProbabilityModel struct { + // REQUIRED; The text offsets associated with tokens in this completions data. + TextOffset []*int32 + + // REQUIRED; A collection of log probability values for the tokens in this completions data. + TokenLogprobs []*float32 + + // REQUIRED; The textual forms of tokens evaluated in this probability model. + Tokens []*string + + // REQUIRED; A mapping of tokens to maximum log probability values in this completions data. + TopLogprobs []any +} + +// CompletionsOptions - The configuration information for a completions request. Completions support a wide variety of tasks +// and generate text that continues from or "completes" provided prompt data. +type CompletionsOptions struct { + // REQUIRED; The prompts to generate completions from. + Prompt []*string + + // A value that controls how many completions will be internally generated prior to response formulation. When used together + // with n, bestof controls the number of candidate completions and must be + // greater than n. Because this setting can generate many completions, it may quickly consume your token quota. Use carefully + // and ensure reasonable settings for maxtokens and stop. + BestOf *int32 + + // A value specifying whether completions responses should include input prompts as prefixes to their generated output. + Echo *bool + + // A value that influences the probability of generated tokens appearing based on their cumulative frequency in generated + // text. Positive values will make tokens less likely to appear as their frequency + // increases and decrease the likelihood of the model repeating the same statements verbatim. + FrequencyPenalty *float32 + + // A map between GPT token IDs and bias scores that influences the probability of specific tokens appearing in a completions + // response. Token IDs are computed via external tokenizer tools, while bias + // scores reside in the range of -100 to 100 with minimum and maximum values corresponding to a full ban or exclusive selection + // of a token, respectively. The exact behavior of a given bias score varies + // by model. + LogitBias map[string]*int32 + + // A value that controls the emission of log probabilities for the provided number of most likely tokens within a completions + // response. + Logprobs *int32 + + // The maximum number of tokens to generate. + MaxTokens *int32 + + // The model name to provide as part of this completions request. Not applicable to Azure OpenAI, where deployment information + // should be included in the Azure resource URI that's connected to. + Model *string + + // The number of completions choices that should be generated per provided prompt as part of an overall completions response. + // Because this setting can generate many completions, it may quickly consume + // your token quota. Use carefully and ensure reasonable settings for max_tokens and stop. + N *int32 + + // A value that influences the probability of generated tokens appearing based on their existing presence in generated text. + // Positive values will make tokens less likely to appear when they already exist + // and increase the model's likelihood to output new topics. + PresencePenalty *float32 + + // A collection of textual sequences that will end completions generation. + Stop []*string + + // The sampling temperature to use that controls the apparent creativity of generated completions. Higher values will make + // output more random while lower values will make results more focused and + // deterministic. It is not recommended to modify temperature and top_p for the same completions request as the interaction + // of these two settings is difficult to predict. + Temperature *float32 + + // An alternative to sampling with temperature called nucleus sampling. This value causes the model to consider the results + // of tokens with the provided probability mass. As an example, a value of 0.15 + // will cause only the tokens comprising the top 15% of probability mass to be considered. It is not recommended to modify + // temperature and top_p for the same completions request as the interaction of + // these two settings is difficult to predict. + TopP *float32 + + // An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. + User *string +} + +// CompletionsUsage - Representation of the token counts processed for a completions request. Counts consider all tokens across +// prompts, choices, choice alternates, best_of generations, and other consumers. +type CompletionsUsage struct { + // REQUIRED; The number of tokens generated across all completions emissions. + CompletionTokens *int32 + + // REQUIRED; The number of tokens in the provided prompts for the completions request. + PromptTokens *int32 + + // REQUIRED; The total number of tokens processed for the completions request and response. + TotalTokens *int32 +} + +// Deployment - A specific deployment +type Deployment struct { + // READ-ONLY; deployment id of the deployed model + DeploymentID *string +} + +// EmbeddingItem - Representation of a single embeddings relatedness comparison. +type EmbeddingItem struct { + // REQUIRED; List of embeddings value for the input prompt. These represent a measurement of the vector-based relatedness + // of the provided input. + Embedding []*float32 + + // REQUIRED; Index of the prompt to which the EmbeddingItem corresponds. + Index *int32 +} + +// Embeddings - Representation of the response data from an embeddings request. Embeddings measure the relatedness of text +// strings and are commonly used for search, clustering, recommendations, and other similar +// scenarios. +type Embeddings struct { + // REQUIRED; Embedding values for the prompts submitted in the request. + Data []*EmbeddingItem + + // REQUIRED; Usage counts for tokens input using the embeddings API. + Usage *EmbeddingsUsage +} + +// EmbeddingsOptions - The configuration information for an embeddings request. Embeddings measure the relatedness of text +// strings and are commonly used for search, clustering, recommendations, and other similar scenarios. +type EmbeddingsOptions struct { + // REQUIRED; Input text to get embeddings for, encoded as a string. To get embeddings for multiple inputs in a single request, + // pass an array of strings. Each input must not exceed 2048 tokens in length. + // Unless you are embedding code, we suggest replacing newlines (\n) in your input with a single space, as we have observed + // inferior results when newlines are present. + Input any + + // The model name to provide as part of this embeddings request. Not applicable to Azure OpenAI, where deployment information + // should be included in the Azure resource URI that's connected to. + Model *string + + // An identifier for the caller or end user of the operation. This may be used for tracking or rate-limiting purposes. + User *string +} + +// EmbeddingsUsage - Usage counts for tokens input using the embeddings API. +type EmbeddingsUsage struct { + // REQUIRED; Number of tokens sent in the original request. + PromptTokens *int32 + + // REQUIRED; Total number of tokens transacted in this request/response. + TotalTokens *int32 +} + +// EmbeddingsUsageAutoGenerated - Measurement of the amount of tokens used in this request and response. +type EmbeddingsUsageAutoGenerated struct { + // REQUIRED; Number of tokens sent in the original request. + PromptTokens *int32 + + // REQUIRED; Total number of tokens transacted in this request/response. + TotalTokens *int32 +} diff --git a/sdk/cognitiveservices/azopenai/models_serde.go b/sdk/cognitiveservices/azopenai/models_serde.go new file mode 100644 index 000000000000..582d49c6feb0 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/models_serde.go @@ -0,0 +1,947 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package azopenai + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "reflect" +) + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsError. +func (a AzureCoreFoundationsError) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", a.Code) + populate(objectMap, "details", a.Details) + populate(objectMap, "innererror", a.Innererror) + populate(objectMap, "message", a.Message) + populate(objectMap, "target", a.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsError. +func (a *AzureCoreFoundationsError) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &a.Code) + delete(rawMsg, key) + case "details": + err = unpopulate(val, "Details", &a.Details) + delete(rawMsg, key) + case "innererror": + err = unpopulate(val, "Innererror", &a.Innererror) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &a.Message) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &a.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorInnererror. +func (a AzureCoreFoundationsErrorInnererror) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", a.Code) + populate(objectMap, "innererror", a.Innererror) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorInnererror. +func (a *AzureCoreFoundationsErrorInnererror) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &a.Code) + delete(rawMsg, key) + case "innererror": + err = unpopulate(val, "Innererror", &a.Innererror) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorResponse. +func (a AzureCoreFoundationsErrorResponse) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "error", a.Error) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorResponse. +func (a *AzureCoreFoundationsErrorResponse) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "error": + err = unpopulate(val, "Error", &a.Error) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorResponseError. +func (a AzureCoreFoundationsErrorResponseError) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", a.Code) + populate(objectMap, "details", a.Details) + populate(objectMap, "innererror", a.Innererror) + populate(objectMap, "message", a.Message) + populate(objectMap, "target", a.Target) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorResponseError. +func (a *AzureCoreFoundationsErrorResponseError) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &a.Code) + delete(rawMsg, key) + case "details": + err = unpopulate(val, "Details", &a.Details) + delete(rawMsg, key) + case "innererror": + err = unpopulate(val, "Innererror", &a.Innererror) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &a.Message) + delete(rawMsg, key) + case "target": + err = unpopulate(val, "Target", &a.Target) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsInnerError. +func (a AzureCoreFoundationsInnerError) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", a.Code) + populate(objectMap, "innererror", a.Innererror) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsInnerError. +func (a *AzureCoreFoundationsInnerError) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &a.Code) + delete(rawMsg, key) + case "innererror": + err = unpopulate(val, "Innererror", &a.Innererror) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsInnerErrorInnererror. +func (a AzureCoreFoundationsInnerErrorInnererror) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "code", a.Code) + populate(objectMap, "innererror", a.Innererror) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsInnerErrorInnererror. +func (a *AzureCoreFoundationsInnerErrorInnererror) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "code": + err = unpopulate(val, "Code", &a.Code) + delete(rawMsg, key) + case "innererror": + err = unpopulate(val, "Innererror", &a.Innererror) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", a, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatChoice. +func (c ChatChoice) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "delta", c.Delta) + populate(objectMap, "finish_reason", c.FinishReason) + populate(objectMap, "index", c.Index) + populate(objectMap, "message", c.Message) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatChoice. +func (c *ChatChoice) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "delta": + err = unpopulate(val, "Delta", &c.Delta) + delete(rawMsg, key) + case "finish_reason": + err = unpopulate(val, "FinishReason", &c.FinishReason) + delete(rawMsg, key) + case "index": + err = unpopulate(val, "Index", &c.Index) + delete(rawMsg, key) + case "message": + err = unpopulate(val, "Message", &c.Message) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatChoiceDelta. +func (c ChatChoiceDelta) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "content", c.Content) + populate(objectMap, "role", c.Role) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatChoiceDelta. +func (c *ChatChoiceDelta) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "content": + err = unpopulate(val, "Content", &c.Content) + delete(rawMsg, key) + case "role": + err = unpopulate(val, "Role", &c.Role) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatChoiceMessage. +func (c ChatChoiceMessage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "content", c.Content) + populate(objectMap, "role", c.Role) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatChoiceMessage. +func (c *ChatChoiceMessage) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "content": + err = unpopulate(val, "Content", &c.Content) + delete(rawMsg, key) + case "role": + err = unpopulate(val, "Role", &c.Role) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatCompletions. +func (c ChatCompletions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "choices", c.Choices) + populate(objectMap, "created", c.Created) + populate(objectMap, "id", c.ID) + populate(objectMap, "usage", c.Usage) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatCompletions. +func (c *ChatCompletions) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "choices": + err = unpopulate(val, "Choices", &c.Choices) + delete(rawMsg, key) + case "created": + err = unpopulate(val, "Created", &c.Created) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &c.ID) + delete(rawMsg, key) + case "usage": + err = unpopulate(val, "Usage", &c.Usage) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatCompletionsOptions. +func (c ChatCompletionsOptions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "frequency_penalty", c.FrequencyPenalty) + populate(objectMap, "logit_bias", c.LogitBias) + populate(objectMap, "max_tokens", c.MaxTokens) + populate(objectMap, "messages", c.Messages) + populate(objectMap, "model", c.Model) + populate(objectMap, "n", c.N) + populate(objectMap, "presence_penalty", c.PresencePenalty) + populate(objectMap, "stop", c.Stop) + populate(objectMap, "temperature", c.Temperature) + populate(objectMap, "top_p", c.TopP) + populate(objectMap, "user", c.User) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatCompletionsOptions. +func (c *ChatCompletionsOptions) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "frequency_penalty": + err = unpopulate(val, "FrequencyPenalty", &c.FrequencyPenalty) + delete(rawMsg, key) + case "logit_bias": + err = unpopulate(val, "LogitBias", &c.LogitBias) + delete(rawMsg, key) + case "max_tokens": + err = unpopulate(val, "MaxTokens", &c.MaxTokens) + delete(rawMsg, key) + case "messages": + err = unpopulate(val, "Messages", &c.Messages) + delete(rawMsg, key) + case "model": + err = unpopulate(val, "Model", &c.Model) + delete(rawMsg, key) + case "n": + err = unpopulate(val, "N", &c.N) + delete(rawMsg, key) + case "presence_penalty": + err = unpopulate(val, "PresencePenalty", &c.PresencePenalty) + delete(rawMsg, key) + case "stop": + err = unpopulate(val, "Stop", &c.Stop) + delete(rawMsg, key) + case "temperature": + err = unpopulate(val, "Temperature", &c.Temperature) + delete(rawMsg, key) + case "top_p": + err = unpopulate(val, "TopP", &c.TopP) + delete(rawMsg, key) + case "user": + err = unpopulate(val, "User", &c.User) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChatMessage. +func (c ChatMessage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "content", c.Content) + populate(objectMap, "role", c.Role) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChatMessage. +func (c *ChatMessage) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "content": + err = unpopulate(val, "Content", &c.Content) + delete(rawMsg, key) + case "role": + err = unpopulate(val, "Role", &c.Role) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Choice. +func (c Choice) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "finish_reason", c.FinishReason) + populate(objectMap, "index", c.Index) + populate(objectMap, "logprobs", c.Logprobs) + populate(objectMap, "text", c.Text) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Choice. +func (c *Choice) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "finish_reason": + err = unpopulate(val, "FinishReason", &c.FinishReason) + delete(rawMsg, key) + case "index": + err = unpopulate(val, "Index", &c.Index) + delete(rawMsg, key) + case "logprobs": + err = unpopulate(val, "Logprobs", &c.Logprobs) + delete(rawMsg, key) + case "text": + err = unpopulate(val, "Text", &c.Text) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type ChoiceLogprobs. +func (c ChoiceLogprobs) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "text_offset", c.TextOffset) + populate(objectMap, "token_logprobs", c.TokenLogprobs) + populate(objectMap, "tokens", c.Tokens) + populate(objectMap, "top_logprobs", c.TopLogprobs) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type ChoiceLogprobs. +func (c *ChoiceLogprobs) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "text_offset": + err = unpopulate(val, "TextOffset", &c.TextOffset) + delete(rawMsg, key) + case "token_logprobs": + err = unpopulate(val, "TokenLogprobs", &c.TokenLogprobs) + delete(rawMsg, key) + case "tokens": + err = unpopulate(val, "Tokens", &c.Tokens) + delete(rawMsg, key) + case "top_logprobs": + err = unpopulate(val, "TopLogprobs", &c.TopLogprobs) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Completions. +func (c Completions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "choices", c.Choices) + populate(objectMap, "created", c.Created) + populate(objectMap, "id", c.ID) + populate(objectMap, "usage", c.Usage) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Completions. +func (c *Completions) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "choices": + err = unpopulate(val, "Choices", &c.Choices) + delete(rawMsg, key) + case "created": + err = unpopulate(val, "Created", &c.Created) + delete(rawMsg, key) + case "id": + err = unpopulate(val, "ID", &c.ID) + delete(rawMsg, key) + case "usage": + err = unpopulate(val, "Usage", &c.Usage) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type CompletionsLogProbabilityModel. +func (c CompletionsLogProbabilityModel) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "text_offset", c.TextOffset) + populate(objectMap, "token_logprobs", c.TokenLogprobs) + populate(objectMap, "tokens", c.Tokens) + populate(objectMap, "top_logprobs", c.TopLogprobs) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type CompletionsLogProbabilityModel. +func (c *CompletionsLogProbabilityModel) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "text_offset": + err = unpopulate(val, "TextOffset", &c.TextOffset) + delete(rawMsg, key) + case "token_logprobs": + err = unpopulate(val, "TokenLogprobs", &c.TokenLogprobs) + delete(rawMsg, key) + case "tokens": + err = unpopulate(val, "Tokens", &c.Tokens) + delete(rawMsg, key) + case "top_logprobs": + err = unpopulate(val, "TopLogprobs", &c.TopLogprobs) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type CompletionsOptions. +func (c CompletionsOptions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "best_of", c.BestOf) + populate(objectMap, "echo", c.Echo) + populate(objectMap, "frequency_penalty", c.FrequencyPenalty) + populate(objectMap, "logit_bias", c.LogitBias) + populate(objectMap, "logprobs", c.Logprobs) + populate(objectMap, "max_tokens", c.MaxTokens) + populate(objectMap, "model", c.Model) + populate(objectMap, "n", c.N) + populate(objectMap, "presence_penalty", c.PresencePenalty) + populate(objectMap, "prompt", c.Prompt) + populate(objectMap, "stop", c.Stop) + populate(objectMap, "temperature", c.Temperature) + populate(objectMap, "top_p", c.TopP) + populate(objectMap, "user", c.User) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type CompletionsOptions. +func (c *CompletionsOptions) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "best_of": + err = unpopulate(val, "BestOf", &c.BestOf) + delete(rawMsg, key) + case "echo": + err = unpopulate(val, "Echo", &c.Echo) + delete(rawMsg, key) + case "frequency_penalty": + err = unpopulate(val, "FrequencyPenalty", &c.FrequencyPenalty) + delete(rawMsg, key) + case "logit_bias": + err = unpopulate(val, "LogitBias", &c.LogitBias) + delete(rawMsg, key) + case "logprobs": + err = unpopulate(val, "Logprobs", &c.Logprobs) + delete(rawMsg, key) + case "max_tokens": + err = unpopulate(val, "MaxTokens", &c.MaxTokens) + delete(rawMsg, key) + case "model": + err = unpopulate(val, "Model", &c.Model) + delete(rawMsg, key) + case "n": + err = unpopulate(val, "N", &c.N) + delete(rawMsg, key) + case "presence_penalty": + err = unpopulate(val, "PresencePenalty", &c.PresencePenalty) + delete(rawMsg, key) + case "prompt": + err = unpopulate(val, "Prompt", &c.Prompt) + delete(rawMsg, key) + case "stop": + err = unpopulate(val, "Stop", &c.Stop) + delete(rawMsg, key) + case "temperature": + err = unpopulate(val, "Temperature", &c.Temperature) + delete(rawMsg, key) + case "top_p": + err = unpopulate(val, "TopP", &c.TopP) + delete(rawMsg, key) + case "user": + err = unpopulate(val, "User", &c.User) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type CompletionsUsage. +func (c CompletionsUsage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "completion_tokens", c.CompletionTokens) + populate(objectMap, "prompt_tokens", c.PromptTokens) + populate(objectMap, "total_tokens", c.TotalTokens) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type CompletionsUsage. +func (c *CompletionsUsage) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "completion_tokens": + err = unpopulate(val, "CompletionTokens", &c.CompletionTokens) + delete(rawMsg, key) + case "prompt_tokens": + err = unpopulate(val, "PromptTokens", &c.PromptTokens) + delete(rawMsg, key) + case "total_tokens": + err = unpopulate(val, "TotalTokens", &c.TotalTokens) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", c, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Deployment. +func (d Deployment) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "deploymentId", d.DeploymentID) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Deployment. +func (d *Deployment) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", d, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "deploymentId": + err = unpopulate(val, "DeploymentID", &d.DeploymentID) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", d, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type EmbeddingItem. +func (e EmbeddingItem) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "embedding", e.Embedding) + populate(objectMap, "index", e.Index) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EmbeddingItem. +func (e *EmbeddingItem) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "embedding": + err = unpopulate(val, "Embedding", &e.Embedding) + delete(rawMsg, key) + case "index": + err = unpopulate(val, "Index", &e.Index) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type Embeddings. +func (e Embeddings) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "data", e.Data) + populate(objectMap, "usage", e.Usage) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type Embeddings. +func (e *Embeddings) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "data": + err = unpopulate(val, "Data", &e.Data) + delete(rawMsg, key) + case "usage": + err = unpopulate(val, "Usage", &e.Usage) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type EmbeddingsOptions. +func (e EmbeddingsOptions) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populateAny(objectMap, "input", e.Input) + populate(objectMap, "model", e.Model) + populate(objectMap, "user", e.User) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EmbeddingsOptions. +func (e *EmbeddingsOptions) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "input": + err = unpopulate(val, "Input", &e.Input) + delete(rawMsg, key) + case "model": + err = unpopulate(val, "Model", &e.Model) + delete(rawMsg, key) + case "user": + err = unpopulate(val, "User", &e.User) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type EmbeddingsUsage. +func (e EmbeddingsUsage) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "prompt_tokens", e.PromptTokens) + populate(objectMap, "total_tokens", e.TotalTokens) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EmbeddingsUsage. +func (e *EmbeddingsUsage) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "prompt_tokens": + err = unpopulate(val, "PromptTokens", &e.PromptTokens) + delete(rawMsg, key) + case "total_tokens": + err = unpopulate(val, "TotalTokens", &e.TotalTokens) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +// MarshalJSON implements the json.Marshaller interface for type EmbeddingsUsageAutoGenerated. +func (e EmbeddingsUsageAutoGenerated) MarshalJSON() ([]byte, error) { + objectMap := make(map[string]any) + populate(objectMap, "prompt_tokens", e.PromptTokens) + populate(objectMap, "total_tokens", e.TotalTokens) + return json.Marshal(objectMap) +} + +// UnmarshalJSON implements the json.Unmarshaller interface for type EmbeddingsUsageAutoGenerated. +func (e *EmbeddingsUsageAutoGenerated) UnmarshalJSON(data []byte) error { + var rawMsg map[string]json.RawMessage + if err := json.Unmarshal(data, &rawMsg); err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + for key, val := range rawMsg { + var err error + switch key { + case "prompt_tokens": + err = unpopulate(val, "PromptTokens", &e.PromptTokens) + delete(rawMsg, key) + case "total_tokens": + err = unpopulate(val, "TotalTokens", &e.TotalTokens) + delete(rawMsg, key) + } + if err != nil { + return fmt.Errorf("unmarshalling type %T: %v", e, err) + } + } + return nil +} + +func populate(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else if !reflect.ValueOf(v).IsNil() { + m[k] = v + } +} + +func populateAny(m map[string]any, k string, v any) { + if v == nil { + return + } else if azcore.IsNullValue(v) { + m[k] = nil + } else { + m[k] = v + } +} + +func unpopulate(data json.RawMessage, fn string, v any) error { + if data == nil { + return nil + } + if err := json.Unmarshal(data, v); err != nil { + return fmt.Errorf("struct field %s: %v", fn, err) + } + return nil +} diff --git a/sdk/cognitiveservices/azopenai/response_types.go b/sdk/cognitiveservices/azopenai/response_types.go new file mode 100644 index 000000000000..83d2b8d8be1e --- /dev/null +++ b/sdk/cognitiveservices/azopenai/response_types.go @@ -0,0 +1,25 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. +// DO NOT EDIT. + +package azopenai + +// ClientGetChatCompletionsResponse contains the response from method Client.GetChatCompletions. +type ClientGetChatCompletionsResponse struct { + ChatCompletions +} + +// ClientGetCompletionsResponse contains the response from method Client.GetCompletions. +type ClientGetCompletionsResponse struct { + Completions +} + +// ClientGetEmbeddingsResponse contains the response from method Client.GetEmbeddings. +type ClientGetEmbeddingsResponse struct { + Embeddings +} From a8d3e713accf9f9fbea1926aaed15bca18ae4e0a Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Tue, 11 Apr 2023 13:31:35 -0500 Subject: [PATCH 04/62] Add custom_client.go and supporting files --- .../azopenai/custom_client.go | 155 ++++++++++++++++++ .../azopenai/custom_models.go | 21 +++ .../azopenai/event_reader.go | 61 +++++++ .../azopenai/policy_apikey.go | 40 +++++ sdk/cognitiveservices/azopenai/version.go | 11 ++ 5 files changed, 288 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/custom_client.go create mode 100644 sdk/cognitiveservices/azopenai/custom_models.go create mode 100644 sdk/cognitiveservices/azopenai/event_reader.go create mode 100644 sdk/cognitiveservices/azopenai/policy_apikey.go create mode 100644 sdk/cognitiveservices/azopenai/version.go diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go new file mode 100644 index 000000000000..602aebbc1e5a --- /dev/null +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -0,0 +1,155 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +// this file contains handwritten additions to the generated code + +import ( + "context" + "encoding/json" + "errors" + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" +) + +const ( + clientName = "azopenai.Client" + apiVersion = "2023-03-15-preview" + tokenScope = "https://cognitiveservices.azure.com/.default" +) + +// Clients + +// ClientOptions contains optional settings for Client. +type ClientOptions struct { + azcore.ClientOptions +} + +// NewClient creates a new instance of Client with the specified values. +// - endpoint - Azure OpenAI service endpoint +// - credential - used to authorize requests. Usually a credential from azidentity. +// - deploymentID - the deployment ID of the model to query +// - options - client options, pass nil to accept the default values. +func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID string, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + if deploymentID == "" { + return nil, errors.New("parameter client.deploymentID cannot be empty") + } + authPolicy := runtime.NewBearerTokenPolicy(credential, []string{tokenScope}, nil) + azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) + if err != nil { + return nil, err + } + return &Client{endpoint: endpoint + "/openai", deploymentID: deploymentID, internal: azcoreClient}, nil +} + +// NewClientWithKeyCredential creates a new instance of Client with the specified values. +// - endpoint - Azure OpenAI service endpoint +// - credential - used to authorize requests with an API Key credential +// - deploymentID - the deployment ID of the model to query +// - options - client options, pass nil to accept the default values. +func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deploymentID string, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + if deploymentID == "" { + return nil, errors.New("parameter client.deploymentID cannot be empty") + } + authPolicy := NewAPIKeyPolicy(credential, "api-key") + azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) + if err != nil { + return nil, err + } + return &Client{endpoint: endpoint + "/openai", deploymentID: deploymentID, internal: azcoreClient}, nil +} + +// NewClientForOpenAI creates a new instance of Client with the specified values. +// - endpoint - OpenAI service endpoint +// - credential - used to authorize requests with an API Key credential +// - options - client options, pass nil to accept the default values. +func NewClientForOpenAI(endpoint string, credential KeyCredential, options *ClientOptions) (*Client, error) { + if options == nil { + options = &ClientOptions{} + } + openAIPolicy := newOpenAIPolicy(credential) + azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{openAIPolicy}}, &options.ClientOptions) + if err != nil { + return nil, err + } + return &Client{endpoint: endpoint, internal: azcoreClient}, nil +} + +// openAIPolicy is an internal pipeline policy to remove the api-version query parameter +type openAIPolicy struct { + cred KeyCredential +} + +// newOpenAIPolicy creates a new instance of openAIPolicy. +// cred: a KeyCredential implementation. +func newOpenAIPolicy(cred KeyCredential) *openAIPolicy { + return &openAIPolicy{cred: cred} +} + +// Do returns a function which adapts a request to target OpenAI. +// Specifically, it removes the api-version query parameter. +func (b *openAIPolicy) Do(req *policy.Request) (*http.Response, error) { + q := req.Raw().URL.Query() + q.Del("api-version") + req.Raw().Header.Set("authorization", "Bearer "+b.cred.APIKey) + return req.Next() +} + +// Methods that return streaming response + +type streamCompletionsOptions struct { + CompletionsOptions + Stream bool `json:"stream"` +} + +func (o streamCompletionsOptions) MarshalJSON() ([]byte, error) { + bytes, err := o.CompletionsOptions.MarshalJSON() + if err != nil { + return nil, err + } + objectMap := make(map[string]any) + err = json.Unmarshal(bytes, &objectMap) + if err != nil { + return nil, err + } + objectMap["stream"] = o.Stream + return json.Marshal(objectMap) +} + +// GetCompletionsStream - Return the completions for a given prompt as a sequence of events. +// If the operation fails it returns an *azcore.ResponseError type. +// - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsStreamOptions) (CompletionEventsResponse, error) { + req, err := client.getCompletionsCreateRequest(ctx, CompletionsOptions{}, &ClientGetCompletionsOptions{}) + var cer CompletionEventsResponse + if err != nil { + return cer, err + } + err = runtime.MarshalAsJSON(req, streamCompletionsOptions{body, true}) + if err != nil { + return cer, err + } + runtime.SkipBodyDownload(req) + resp, err := client.internal.Pipeline().Do(req) + if err != nil { + return cer, err + } + if !runtime.HasStatusCode(resp, http.StatusOK) { + return cer, runtime.NewResponseError(resp) + } + cer.Events = newEventReader[Completions](resp.Body) + return cer, nil +} diff --git a/sdk/cognitiveservices/azopenai/custom_models.go b/sdk/cognitiveservices/azopenai/custom_models.go new file mode 100644 index 000000000000..14af0fb283c5 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/custom_models.go @@ -0,0 +1,21 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +// Models for methods that return streaming response + +// ClientGetCompletionsStreamOptions contains the optional parameters for the Client.GetCompletions method. +type ClientGetCompletionsStreamOptions struct { + // placeholder for future optional parameters +} + +type CompletionEventsResponse struct { + // REQUIRED; An EventReader to obtain the streaming completions choices associated with this completions response. + // Generally, n choices are generated per provided prompt with a default value of 1. Token limits and other settings + // may limit the number of choices generated. + Events *EventReader[Completions] +} diff --git a/sdk/cognitiveservices/azopenai/event_reader.go b/sdk/cognitiveservices/azopenai/event_reader.go new file mode 100644 index 000000000000..8febabec4bcf --- /dev/null +++ b/sdk/cognitiveservices/azopenai/event_reader.go @@ -0,0 +1,61 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "bufio" + "encoding/json" + "errors" + "io" + "strings" +) + +type EventReader[T any] struct { + reader io.Reader // Required for Closing + scanner *bufio.Scanner +} + +func newEventReader[T any](r io.Reader) *EventReader[T] { + return &EventReader[T]{reader: r, scanner: bufio.NewScanner(r)} +} + +func (er *EventReader[T]) Read() (T, error) { + // https://html.spec.whatwg.org/multipage/server-sent-events.html + for er.scanner.Scan() { // Scan while no error + line := er.scanner.Text() // Get the line & interpret the event stream: + + if line == "" || line[0] == ':' { // If the line is blank or is a comment, skip it + continue + } + + if strings.Contains(line, ":") { // If the line contains a U+003A COLON character (:), process the field + tokens := strings.SplitN(line, ":", 2) + tokens[0], tokens[1] = strings.TrimSpace(tokens[0]), strings.TrimSpace(tokens[1]) + var data T + switch tokens[0] { + case "data": // return the deserialized JSON object + if tokens[1] == "[DONE]" { // If data is [DONE], end of stream was reached + return data, io.EOF + } + //fmt.Println(tokens[1]) + err := json.Unmarshal([]byte(tokens[1]), &data) + return data, err + + default: // Any other event type is an unexpected + return data, errors.New("Unexpected event type: " + tokens[0]) + } + // Unreachable + } + } + return *new(T), er.scanner.Err() +} + +func (er *EventReader[T]) Close() { + if closer, ok := er.reader.(io.Closer); ok { + closer.Close() + } +} diff --git a/sdk/cognitiveservices/azopenai/policy_apikey.go b/sdk/cognitiveservices/azopenai/policy_apikey.go new file mode 100644 index 000000000000..1d57d1c9296d --- /dev/null +++ b/sdk/cognitiveservices/azopenai/policy_apikey.go @@ -0,0 +1,40 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "net/http" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" +) + +// KeyCredential + +type KeyCredential struct { + APIKey string +} + +// APIKeyPolicy authorizes requests with an API key acquired from a KeyCredential. +type APIKeyPolicy struct { + header string + cred KeyCredential +} + +// NewAPIKeyPolicy creates a policy object that authorizes requests with an API Key. +// cred: a KeyCredential implementation. +func NewAPIKeyPolicy(cred KeyCredential, header string) *APIKeyPolicy { + return &APIKeyPolicy{ + header: header, + cred: cred, + } +} + +// Do returns a function which authorizes req with a token from the policy's credential +func (b *APIKeyPolicy) Do(req *policy.Request) (*http.Response, error) { + req.Raw().Header.Set(b.header, b.cred.APIKey) + return req.Next() +} diff --git a/sdk/cognitiveservices/azopenai/version.go b/sdk/cognitiveservices/azopenai/version.go new file mode 100644 index 000000000000..cecc80db67a5 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/version.go @@ -0,0 +1,11 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +const ( + version = "v0.1.0" +) From 3db25b0740cfe229fdaf05f82e2daba549663915 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Wed, 19 Apr 2023 08:36:10 -0500 Subject: [PATCH 05/62] Add LICENSE.txt, README.md, CHANGELOG.md. --- sdk/cognitiveservices/azopenai/CHANGELOG.md | 5 + sdk/cognitiveservices/azopenai/LICENSE.txt | 21 ++++ sdk/cognitiveservices/azopenai/README.md | 101 ++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/CHANGELOG.md create mode 100644 sdk/cognitiveservices/azopenai/LICENSE.txt create mode 100644 sdk/cognitiveservices/azopenai/README.md diff --git a/sdk/cognitiveservices/azopenai/CHANGELOG.md b/sdk/cognitiveservices/azopenai/CHANGELOG.md new file mode 100644 index 000000000000..077c60d77c60 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/CHANGELOG.md @@ -0,0 +1,5 @@ +# Release History + +## 0.1.0 (unreleased) + +* This is the initial release of the `azopenai` library diff --git a/sdk/cognitiveservices/azopenai/LICENSE.txt b/sdk/cognitiveservices/azopenai/LICENSE.txt new file mode 100644 index 000000000000..ec703274aadd --- /dev/null +++ b/sdk/cognitiveservices/azopenai/LICENSE.txt @@ -0,0 +1,21 @@ + MIT License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE \ No newline at end of file diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md new file mode 100644 index 000000000000..2a1721791fb2 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/README.md @@ -0,0 +1,101 @@ +# Azure OpenAI client module for Go + +The Azure OpenAI client module is used to ... + +[Source code][azopenai_repo] | [Package (pkg.go.dev)][azopenai_pkg_go] | [REST API documentation][openai_rest_docs] | [Product documentation][openai_docs] + +## Getting started + +### Prerequisites + +* Go, version 1.18 or higher - [Install Go](https://go.dev/doc/install) +* Azure subscription - [Create a free account][azure_sub] + +### Install the packages + +Install the `azopenai` and `azidentity` modules with `go get`: + +```bash +go get github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai +go get github.com/Azure/azure-sdk-for-go/sdk/azidentity +``` + +The [azidentity][azure_identity] module is used for authentication during client construction. + +### Authentication + + + +#### Create a client + +Constructing the client requires your vault's URL, which you can get from the Azure CLI or the Azure Portal. + +```go +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" +) + +func main() { + endpoint := "https://" + apiKey := "" + + var err error + cred := azopenai.KeyCredential{APIKey: apiKey} + client, err := azopenai.NewClientWithKeyCredential(endpoint, cred, &options) + if err != nil { + // TODO: handle error + } +} +``` + +## Key concepts + +See [Key concepts][openai_key_concepts] in the product documentation for more details about general concepts. + +## Troubleshooting + +### Error Handling + +All methods that send HTTP requests return `*azcore.ResponseError` when these requests fail. `ResponseError` has error details and the raw response from the service. + +### Logging + +This module uses the logging implementation in `azcore`. To turn on logging for all Azure SDK modules, set `AZURE_SDK_GO_LOGGING` to `all`. By default, the logger writes to stderr. Use the `azcore/log` package to control log output. For example, logging only HTTP request and response events, and printing them to stdout: + +```go +import azlog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log" + +// Print log events to stdout +azlog.SetListener(func(cls azlog.Event, msg string) { + fmt.Println(msg) +}) + +// Includes only requests and responses in credential logs +azlog.SetEvents(azlog.EventRequest, azlog.EventResponse) +``` + +## Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a [Contributor License Agreement (CLA)][cla] declaring that you have the right to, and actually do, grant us the rights to use your contribution. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate +the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to +do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct][coc]. For more information, see +the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_contact] with any additional questions or +comments. + + +[azopenai_repo]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/cognitiveservices/azopenai +[azopenai_pkg_go]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai +[azure_identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity +[azure_sub]: https://azure.microsoft.com/free/ +[openai_docs]: https://learn.microsoft.com/azure/cognitive-services/openai +[openai_key_concepts]: https://learn.microsoft.com/en-us/azure/cognitive-services/openai/overview#key-concepts +[openai_rest_docs]: https://learn.microsoft.com/azure/cognitive-services/openai/reference +[cla]: https://cla.microsoft.com +[coc]: https://opensource.microsoft.com/codeofconduct/ +[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/ +[coc_contact]: mailto:opencode@microsoft.com \ No newline at end of file From e90a2783df000066b1748c141a55d6e4b864a1d3 Mon Sep 17 00:00:00 2001 From: Mike Kistler Date: Sun, 4 Jun 2023 11:07:36 -0500 Subject: [PATCH 06/62] Add tests -- WIP --- sdk/cognitiveservices/azopenai/client_test.go | 222 ++++++++++++++++++ .../azopenai/custom_client_test.go | 125 ++++++++++ sdk/cognitiveservices/azopenai/go.mod | 11 +- sdk/cognitiveservices/azopenai/go.sum | 18 +- .../azopenai/policy_apikey_test.go | 80 +++++++ 5 files changed, 444 insertions(+), 12 deletions(-) create mode 100644 sdk/cognitiveservices/azopenai/client_test.go create mode 100644 sdk/cognitiveservices/azopenai/custom_client_test.go create mode 100644 sdk/cognitiveservices/azopenai/policy_apikey_test.go diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go new file mode 100644 index 000000000000..c1dbdce0387e --- /dev/null +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -0,0 +1,222 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "context" + "log" + "os" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" +) + +var ( + endpoint = os.Getenv("AOAI_ENDPOINT") + apiKey = os.Getenv("AOAI_API_KEY") +) + +func TestClient_GetChatCompletions(t *testing.T) { + type args struct { + ctx context.Context + deploymentID string + body ChatCompletionsOptions + options *ClientGetChatCompletionsOptions + } + cred := KeyCredential{APIKey: apiKey} + deploymentID := "gpt-35-turbo" + chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + if err != nil { + log.Fatalf("%v", err) + } + tests := []struct { + name string + client *Client + args args + want ClientGetChatCompletionsResponse + wantErr bool + }{ + { + name: "ChatCompletions", + client: chatClient, + args: args{ + ctx: context.TODO(), + deploymentID: "gpt-35-turbo", + body: ChatCompletionsOptions{ + Messages: []*ChatMessage{ + { + Role: to.Ptr(ChatRole("user")), + Content: to.Ptr("Count to 100, with a comma between each number and no newlines. E.g., 1, 2, 3, ..."), + }, + }, + MaxTokens: to.Ptr(int32(1024)), + Temperature: to.Ptr(float32(0.0)), + }, + options: nil, + }, + want: ClientGetChatCompletionsResponse{ + ChatCompletions: ChatCompletions{ + Choices: []*ChatChoice{ + { + Message: &ChatChoiceMessage{ + Role: to.Ptr(ChatRole("assistant")), + Content: to.Ptr("1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100."), + }, + Index: to.Ptr(int32(0)), + FinishReason: to.Ptr(CompletionsFinishReason("stop")), + }, + }, + Usage: &CompletionsUsage{ + CompletionTokens: to.Ptr(int32(299)), + PromptTokens: to.Ptr(int32(37)), + TotalTokens: to.Ptr(int32(336)), + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.client.GetChatCompletions(tt.args.ctx, tt.args.body, tt.args.options) + if (err != nil) != tt.wantErr { + t.Errorf("Client.GetChatCompletions() error = %v, wantErr %v", err, tt.wantErr) + return + } + opts := cmpopts.IgnoreFields(ChatCompletions{}, "Created", "ID") + if diff := cmp.Diff(tt.want.ChatCompletions, got.ChatCompletions, opts); diff != "" { + t.Errorf("Client.GetCompletions(): -want, +got:\n%s", diff) + } + }) + } +} + +func TestClient_GetCompletions(t *testing.T) { + type args struct { + ctx context.Context + deploymentID string + body CompletionsOptions + options *ClientGetCompletionsOptions + } + cred := KeyCredential{APIKey: apiKey} + deploymentID := "text-davinci-003" + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + if err != nil { + log.Fatalf("%v", err) + } + tests := []struct { + name string + client *Client + args args + want ClientGetCompletionsResponse + wantErr bool + }{ + { + name: "chatbot", + client: client, + args: args{ + ctx: context.TODO(), + deploymentID: deploymentID, + body: CompletionsOptions{ + Prompt: []*string{to.Ptr("What is Azure OpenAI?")}, + MaxTokens: to.Ptr(int32(2048 - 127)), + Temperature: to.Ptr(float32(0.0)), + }, + options: nil, + }, + want: ClientGetCompletionsResponse{ + Completions: Completions{ + Choices: []*Choice{ + { + Text: to.Ptr("\n\nAzure OpenAI is a platform from Microsoft that provides access to OpenAI's artificial intelligence (AI) technologies. It enables developers to build, train, and deploy AI models in the cloud. Azure OpenAI provides access to OpenAI's powerful AI technologies, such as GPT-3, which can be used to create natural language processing (NLP) applications, computer vision models, and reinforcement learning models."), + Index: to.Ptr(int32(0)), + FinishReason: to.Ptr(CompletionsFinishReason("stop")), + Logprobs: nil, + }, + }, + Usage: &CompletionsUsage{ + CompletionTokens: to.Ptr(int32(85)), + PromptTokens: to.Ptr(int32(6)), + TotalTokens: to.Ptr(int32(91)), + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.client.GetCompletions(tt.args.ctx, tt.args.body, tt.args.options) + if (err != nil) != tt.wantErr { + t.Errorf("Client.GetCompletions() error = %v, wantErr %v", err, tt.wantErr) + return + } + opts := cmpopts.IgnoreFields(Completions{}, "Created", "ID") + if diff := cmp.Diff(tt.want.Completions, got.Completions, opts); diff != "" { + t.Errorf("Client.GetCompletions(): -want, +got:\n%s", diff) + } + }) + } +} + +func TestClient_GetEmbeddings(t *testing.T) { + type args struct { + ctx context.Context + deploymentID string + body EmbeddingsOptions + options *ClientGetEmbeddingsOptions + } + deploymentID := "embedding" + cred := KeyCredential{APIKey: apiKey} + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + if err != nil { + log.Fatalf("%v", err) + } + tests := []struct { + name string + client *Client + args args + want ClientGetEmbeddingsResponse + wantErr bool + }{ + { + name: "Embeddings", + client: client, + args: args{ + ctx: context.TODO(), + deploymentID: "embedding", + body: EmbeddingsOptions{ + Input: "Your text string goes here", + Model: to.Ptr("text-similarity-curie-001"), + }, + options: nil, + }, + want: ClientGetEmbeddingsResponse{ + Embeddings{ + Data: []*EmbeddingItem{}, + Usage: &EmbeddingsUsage{}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.client.GetEmbeddings(tt.args.ctx, tt.args.body, tt.args.options) + if (err != nil) != tt.wantErr { + t.Errorf("Client.GetEmbeddings() error = %v, wantErr %v", err, tt.wantErr) + return + } + if len(got.Embeddings.Data[0].Embedding) != 4096 { + t.Errorf("Client.GetEmbeddings() len(Data) want 4096, got %d", len(got.Embeddings.Data)) + return + } + }) + } +} diff --git a/sdk/cognitiveservices/azopenai/custom_client_test.go b/sdk/cognitiveservices/azopenai/custom_client_test.go new file mode 100644 index 000000000000..ba0496799e95 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/custom_client_test.go @@ -0,0 +1,125 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "context" + "io" + "reflect" + "strings" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" +) + +func TestNewClient(t *testing.T) { + type args struct { + endpoint string + credential azcore.TokenCredential + deploymentID string + options *ClientOptions + } + tests := []struct { + name string + args args + want *Client + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewClient(tt.args.endpoint, tt.args.credential, tt.args.deploymentID, tt.args.options) + if (err != nil) != tt.wantErr { + t.Errorf("NewClient() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewClient() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestNewClientWithKeyCredential(t *testing.T) { + type args struct { + endpoint string + credential KeyCredential + deploymentID string + options *ClientOptions + } + tests := []struct { + name string + args args + want *Client + wantErr bool + }{ + // TODO: Add test cases. + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewClientWithKeyCredential(tt.args.endpoint, tt.args.credential, tt.args.deploymentID, tt.args.options) + if (err != nil) != tt.wantErr { + t.Errorf("NewClientWithKeyCredential() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewClientWithKeyCredential() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestClient_GetCompletionsStream(t *testing.T) { + body := CompletionsOptions{ + Prompt: []*string{to.Ptr("What is Azure OpenAI?")}, + MaxTokens: to.Ptr(int32(2048 - 127)), + Temperature: to.Ptr(float32(0.0)), + } + cred := KeyCredential{APIKey: apiKey} + deploymentID := "text-davinci-003" + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + if err != nil { + t.Errorf("NewClientWithKeyCredential() error = %v", err) + return + } + response, err := client.GetCompletionsStream(context.TODO(), body, nil) + if err != nil { + t.Errorf("Client.GetCompletionsStream() error = %v", err) + return + } + reader := response.Events + defer reader.Close() + + var sb strings.Builder + var eventCount int + for { + event, err := reader.Read() + if err == io.EOF { + break + } + eventCount++ + if err != nil { + t.Errorf("reader.Read() error = %v", err) + return + } + sb.WriteString(*event.Choices[0].Text) + } + got := sb.String() + const want = "\n\nAzure OpenAI is a platform from Microsoft that provides access to OpenAI's artificial intelligence (AI) technologies. It enables developers to build, train, and deploy AI models in the cloud. Azure OpenAI provides access to OpenAI's powerful AI technologies, such as GPT-3, which can be used to create natural language processing (NLP) applications, computer vision models, and reinforcement learning models." + if got != want { + i := 0 + for i < len(got) && i < len(want) && got[i] == want[i] { + i++ + } + t.Errorf("Client.GetCompletionsStream() text[%d] = %c, want %c", i, got[i], want[i]) + } + if eventCount != 86 { + t.Errorf("Client.GetCompletionsStream() got = %v, want %v", eventCount, 1) + } +} diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod index e051c62950e0..6f3ac167661e 100644 --- a/sdk/cognitiveservices/azopenai/go.mod +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -2,10 +2,13 @@ module github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai go 1.18 -require github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 + github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 + github.com/google/go-cmp v0.5.9 +) require ( - github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/text v0.8.0 // indirect ) diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum index d39a720dafd8..fb24a34f3b79 100644 --- a/sdk/cognitiveservices/azopenai/go.sum +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -1,12 +1,14 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0 h1:rTnT/Jrcm+figWlYz4Ixzt0SJVR2cMC8lvZcimipiEY= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2 h1:+5VZ72z0Qan5Bog5C+ZkgSqUbeVUd9wgtHOrIKuc5b8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/sdk/cognitiveservices/azopenai/policy_apikey_test.go b/sdk/cognitiveservices/azopenai/policy_apikey_test.go new file mode 100644 index 000000000000..d688530dd896 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/policy_apikey_test.go @@ -0,0 +1,80 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "context" + "net/http" + "reflect" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" + + "github.com/Azure/azure-sdk-for-go/sdk/internal/mock" +) + +func TestNewAPIKeyPolicy(t *testing.T) { + type args struct { + header string + cred KeyCredential + } + simpleCred := KeyCredential{APIKey: "apiKey"} + simpleHeader := "headerName" + tests := []struct { + name string + args args + want *APIKeyPolicy + }{ + { + name: "simple", + args: args{ + cred: simpleCred, + header: simpleHeader, + }, + want: &APIKeyPolicy{ + header: simpleHeader, + cred: simpleCred, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := NewAPIKeyPolicy(tt.args.cred, tt.args.header); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewAPIKeyPolicy() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestAPIKeyPolicy_Success(t *testing.T) { + srv, close := mock.NewTLSServer() + defer close() + srv.AppendResponse(mock.WithStatusCode(http.StatusOK)) + cred := KeyCredential{ + APIKey: "secret", + } + authPolicy := NewAPIKeyPolicy(cred, "api-key") + pipeline := runtime.NewPipeline( + "testmodule", + "v0.1.0", + runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, + &policy.ClientOptions{ + Transport: srv, + }) + req, err := runtime.NewRequest(context.Background(), http.MethodGet, srv.URL()) + if err != nil { + t.Fatal(err) + } + resp, err := pipeline.Do(req) + if err != nil { + t.Fatalf("Expected nil error but received one") + } + if hdrValue := resp.Request.Header.Get("api-key"); hdrValue != "secret" { + t.Fatalf("expected api-key '%s', got '%s'", "secret", hdrValue) + } +} From 8b446adb1f16161b3ae739a2f5dbaabdb282d724 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 12 Jun 2023 17:10:59 -0700 Subject: [PATCH 07/62] Load an env file for the key and endpoint --- sdk/cognitiveservices/azopenai/client_test.go | 15 +++++++++++++-- sdk/cognitiveservices/azopenai/go.mod | 1 + sdk/cognitiveservices/azopenai/go.sum | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index c1dbdce0387e..334e4a03be38 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -8,6 +8,7 @@ package azopenai import ( "context" + "fmt" "log" "os" "testing" @@ -15,13 +16,23 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/joho/godotenv" ) var ( - endpoint = os.Getenv("AOAI_ENDPOINT") - apiKey = os.Getenv("AOAI_API_KEY") + endpoint string + apiKey string ) +func init() { + if err := godotenv.Load(); err != nil { + fmt.Printf("Failed to load .env file: %s\n", err) + os.Exit(1) + } + endpoint = os.Getenv("AOAI_ENDPOINT") + apiKey = os.Getenv("AOAI_API_KEY") +} + func TestClient_GetChatCompletions(t *testing.T) { type args struct { ctx context.Context diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod index 6f3ac167661e..54d610a2918c 100644 --- a/sdk/cognitiveservices/azopenai/go.mod +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -6,6 +6,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 github.com/google/go-cmp v0.5.9 + github.com/joho/godotenv v1.3.0 ) require ( diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum index fb24a34f3b79..2cce6a0a78de 100644 --- a/sdk/cognitiveservices/azopenai/go.sum +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -5,6 +5,8 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aov github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= From 2f8401c2a599ee941d6e0e965bcc707faf3f3a24 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 12 Jun 2023 19:45:07 -0700 Subject: [PATCH 08/62] starting to add in recordings --- .../azopenai/client_shared_test.go | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/client_shared_test.go diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go new file mode 100644 index 000000000000..b57413fe89e7 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai + +import ( + "fmt" + "os" + "testing" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" + "github.com/Azure/azure-sdk-for-go/sdk/internal/recording" + "github.com/joho/godotenv" + "github.com/stretchr/testify/require" +) + +var ( + endpoint string + apiKey string +) + +func init() { + if err := godotenv.Load(); err != nil { + fmt.Printf("Failed to load .env file: %s\n", err) + os.Exit(1) + } + endpoint = os.Getenv("AOAI_ENDPOINT") + apiKey = os.Getenv("AOAI_API_KEY") +} + +func newRecordingTransporter(t *testing.T) policy.Transporter { + transport, err := recording.NewRecordingHTTPClient(t, nil) + require.NoError(t, err) + + err = recording.Start(t, "sdk/cognitive/azopenai/testdata", nil) + require.NoError(t, err) + + err = recording.AddHeaderRegexSanitizer("Api-Key", `redacted`, "", nil) + require.NoError(t, err) + + err = recording.AddURISanitizer("https://aoai", "https://[^/]+", nil) + require.NoError(t, err) + + t.Cleanup(func() { + err := recording.Stop(t, nil) + require.NoError(t, err) + }) + + return transport +} + +func newClientOptionsForTest(t *testing.T) *ClientOptions { + co := &ClientOptions{} + co.Transport = newRecordingTransporter(t) + return co +} From 8314e074de243de7ee75c847a2a9ef761892169d Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 12 Jun 2023 19:51:15 -0700 Subject: [PATCH 09/62] Adding in recordings --- sdk/cognitiveservices/azopenai/assets.json | 6 +++ sdk/cognitiveservices/azopenai/autorest.md | 9 ++++ sdk/cognitiveservices/azopenai/client_test.go | 26 ++-------- sdk/cognitiveservices/azopenai/go.mod | 6 +++ sdk/cognitiveservices/azopenai/go.sum | 13 +++++ sdk/cognitiveservices/azopenai/models.go | 40 ++++++++-------- .../azopenai/models_serde.go | 48 +++++++++---------- 7 files changed, 83 insertions(+), 65 deletions(-) create mode 100644 sdk/cognitiveservices/azopenai/assets.json diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json new file mode 100644 index 000000000000..c076b55f7aaa --- /dev/null +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -0,0 +1,6 @@ +{ + "AssetsRepo": "Azure/azure-sdk-assets", + "AssetsRepoPrefixPath": "go", + "TagPrefix": "go/cognitiveservices/azopenai", + "Tag": "go/cognitiveservices/azopenai_e2a2d2dbef" +} diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index e846b55f60c3..84bce54e83aa 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -109,4 +109,13 @@ directive: - from: models_serde.go where: $ transform: return $.replace(/(?:\/\/.*\s)?func \(\w \*?(?:ErrorResponse|ErrorResponseError)\).*\{\s(?:.+\s)+\}\s/g, ""); + + # rename the "AzureCoreFoundation" prefix from models + - from: + - client.go + - models.go + - models_serde.go + - response_types.go + where: $ + transform: return $.replace(/AzureCoreFoundations/g, ""); ``` diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 334e4a03be38..a134f8de50a6 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -8,31 +8,14 @@ package azopenai import ( "context" - "fmt" "log" - "os" "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/joho/godotenv" ) -var ( - endpoint string - apiKey string -) - -func init() { - if err := godotenv.Load(); err != nil { - fmt.Printf("Failed to load .env file: %s\n", err) - os.Exit(1) - } - endpoint = os.Getenv("AOAI_ENDPOINT") - apiKey = os.Getenv("AOAI_API_KEY") -} - func TestClient_GetChatCompletions(t *testing.T) { type args struct { ctx context.Context @@ -42,7 +25,7 @@ func TestClient_GetChatCompletions(t *testing.T) { } cred := KeyCredential{APIKey: apiKey} deploymentID := "gpt-35-turbo" - chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) if err != nil { log.Fatalf("%v", err) } @@ -117,7 +100,7 @@ func TestClient_GetCompletions(t *testing.T) { } cred := KeyCredential{APIKey: apiKey} deploymentID := "text-davinci-003" - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) if err != nil { log.Fatalf("%v", err) } @@ -185,10 +168,11 @@ func TestClient_GetEmbeddings(t *testing.T) { } deploymentID := "embedding" cred := KeyCredential{APIKey: apiKey} - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) if err != nil { log.Fatalf("%v", err) } + tests := []struct { name string client *Client @@ -203,7 +187,7 @@ func TestClient_GetEmbeddings(t *testing.T) { ctx: context.TODO(), deploymentID: "embedding", body: EmbeddingsOptions{ - Input: "Your text string goes here", + Input: []byte("\"Your text string goes here\""), Model: to.Ptr("text-similarity-curie-001"), }, options: nil, diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod index 54d610a2918c..0ad97e44d36a 100644 --- a/sdk/cognitiveservices/azopenai/go.mod +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -7,9 +7,15 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.3.0 + github.com/stretchr/testify v1.7.0 ) require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/dnaeon/go-vcr v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/text v0.8.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum index 2cce6a0a78de..c505048ba64e 100644 --- a/sdk/cognitiveservices/azopenai/go.sum +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -3,14 +3,27 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQ github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sdk/cognitiveservices/azopenai/models.go b/sdk/cognitiveservices/azopenai/models.go index b385329dae68..0b7bd024db02 100644 --- a/sdk/cognitiveservices/azopenai/models.go +++ b/sdk/cognitiveservices/azopenai/models.go @@ -9,76 +9,76 @@ package azopenai -// AzureCoreFoundationsError - The error object. -type AzureCoreFoundationsError struct { +// Error - The error object. +type Error struct { // REQUIRED; One of a server-defined set of error codes. Code *string // REQUIRED; An array of details about specific errors that led to this reported error. - Details []*AzureCoreFoundationsError + Details []*Error // REQUIRED; A human-readable representation of the error. Message *string // An object containing more specific information than the current object about the error. - Innererror *AzureCoreFoundationsErrorInnererror + Innererror *ErrorInnererror // The target of the error. Target *string } -// AzureCoreFoundationsErrorInnererror - An object containing more specific information than the current object about the +// ErrorInnererror - An object containing more specific information than the current object about the // error. -type AzureCoreFoundationsErrorInnererror struct { +type ErrorInnererror struct { // REQUIRED; One of a server-defined set of error codes. Code *string // Inner error. - Innererror *AzureCoreFoundationsInnerErrorInnererror + Innererror *InnerErrorInnererror } -// AzureCoreFoundationsErrorResponse - A response containing error details. -type AzureCoreFoundationsErrorResponse struct { +// ErrorResponse - A response containing error details. +type ErrorResponse struct { // REQUIRED; The error object. - Error *AzureCoreFoundationsErrorResponseError + Error *ErrorResponseError } -// AzureCoreFoundationsErrorResponseError - The error object. -type AzureCoreFoundationsErrorResponseError struct { +// ErrorResponseError - The error object. +type ErrorResponseError struct { // REQUIRED; One of a server-defined set of error codes. Code *string // REQUIRED; An array of details about specific errors that led to this reported error. - Details []*AzureCoreFoundationsError + Details []*Error // REQUIRED; A human-readable representation of the error. Message *string // An object containing more specific information than the current object about the error. - Innererror *AzureCoreFoundationsErrorInnererror + Innererror *ErrorInnererror // The target of the error. Target *string } -// AzureCoreFoundationsInnerError - An object containing more specific information about the error. As per Microsoft One API +// InnerError - An object containing more specific information about the error. As per Microsoft One API // guidelines - // https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses. -type AzureCoreFoundationsInnerError struct { +type InnerError struct { // REQUIRED; One of a server-defined set of error codes. Code *string // Inner error. - Innererror *AzureCoreFoundationsInnerErrorInnererror + Innererror *InnerErrorInnererror } -// AzureCoreFoundationsInnerErrorInnererror - Inner error. -type AzureCoreFoundationsInnerErrorInnererror struct { +// InnerErrorInnererror - Inner error. +type InnerErrorInnererror struct { // REQUIRED; One of a server-defined set of error codes. Code *string // Inner error. - Innererror *AzureCoreFoundationsInnerErrorInnererror + Innererror *InnerErrorInnererror } // ChatChoice - The representation of a single prompt completion as part of an overall chat completions request. Generally, diff --git a/sdk/cognitiveservices/azopenai/models_serde.go b/sdk/cognitiveservices/azopenai/models_serde.go index 582d49c6feb0..ba31e0bfbb5a 100644 --- a/sdk/cognitiveservices/azopenai/models_serde.go +++ b/sdk/cognitiveservices/azopenai/models_serde.go @@ -16,8 +16,8 @@ import ( "reflect" ) -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsError. -func (a AzureCoreFoundationsError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type Error. +func (a Error) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "details", a.Details) @@ -27,8 +27,8 @@ func (a AzureCoreFoundationsError) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsError. -func (a *AzureCoreFoundationsError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type Error. +func (a *Error) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -59,16 +59,16 @@ func (a *AzureCoreFoundationsError) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorInnererror. -func (a AzureCoreFoundationsErrorInnererror) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ErrorInnererror. +func (a ErrorInnererror) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "innererror", a.Innererror) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorInnererror. -func (a *AzureCoreFoundationsErrorInnererror) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorInnererror. +func (a *ErrorInnererror) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -90,15 +90,15 @@ func (a *AzureCoreFoundationsErrorInnererror) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorResponse. -func (a AzureCoreFoundationsErrorResponse) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ErrorResponse. +func (a ErrorResponse) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "error", a.Error) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorResponse. -func (a *AzureCoreFoundationsErrorResponse) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponse. +func (a *ErrorResponse) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -117,8 +117,8 @@ func (a *AzureCoreFoundationsErrorResponse) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsErrorResponseError. -func (a AzureCoreFoundationsErrorResponseError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type ErrorResponseError. +func (a ErrorResponseError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "details", a.Details) @@ -128,8 +128,8 @@ func (a AzureCoreFoundationsErrorResponseError) MarshalJSON() ([]byte, error) { return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsErrorResponseError. -func (a *AzureCoreFoundationsErrorResponseError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponseError. +func (a *ErrorResponseError) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -160,16 +160,16 @@ func (a *AzureCoreFoundationsErrorResponseError) UnmarshalJSON(data []byte) erro return nil } -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsInnerError. -func (a AzureCoreFoundationsInnerError) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type InnerError. +func (a InnerError) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "innererror", a.Innererror) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsInnerError. -func (a *AzureCoreFoundationsInnerError) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type InnerError. +func (a *InnerError) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) @@ -191,16 +191,16 @@ func (a *AzureCoreFoundationsInnerError) UnmarshalJSON(data []byte) error { return nil } -// MarshalJSON implements the json.Marshaller interface for type AzureCoreFoundationsInnerErrorInnererror. -func (a AzureCoreFoundationsInnerErrorInnererror) MarshalJSON() ([]byte, error) { +// MarshalJSON implements the json.Marshaller interface for type InnerErrorInnererror. +func (a InnerErrorInnererror) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) populate(objectMap, "code", a.Code) populate(objectMap, "innererror", a.Innererror) return json.Marshal(objectMap) } -// UnmarshalJSON implements the json.Unmarshaller interface for type AzureCoreFoundationsInnerErrorInnererror. -func (a *AzureCoreFoundationsInnerErrorInnererror) UnmarshalJSON(data []byte) error { +// UnmarshalJSON implements the json.Unmarshaller interface for type InnerErrorInnererror. +func (a *InnerErrorInnererror) UnmarshalJSON(data []byte) error { var rawMsg map[string]json.RawMessage if err := json.Unmarshal(data, &rawMsg); err != nil { return fmt.Errorf("unmarshalling type %T: %v", a, err) From 3bd833c3dcc4645532ac15cbe18b289cde3a6ec8 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 12 Jun 2023 19:52:17 -0700 Subject: [PATCH 10/62] ci.yml --- sdk/cognitiveservices/azopenai/ci.yml | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/ci.yml diff --git a/sdk/cognitiveservices/azopenai/ci.yml b/sdk/cognitiveservices/azopenai/ci.yml new file mode 100644 index 000000000000..90db9512357e --- /dev/null +++ b/sdk/cognitiveservices/azopenai/ci.yml @@ -0,0 +1,28 @@ +# NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. +trigger: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/cognitiveservices/azopenai + - eng/ + +pr: + branches: + include: + - main + - feature/* + - hotfix/* + - release/* + paths: + include: + - sdk/cognitiveservices/azopenai + +stages: + - template: /eng/pipelines/templates/jobs/archetype-sdk-client.yml + parameters: + ServiceDirectory: "cognitiveservices/azopenai" From 9c97e7f0063307b44054cfe3ef0d2f3895d29c7c Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 12 Jun 2023 22:29:04 -0700 Subject: [PATCH 11/62] Use latest autorest-go --- sdk/cognitiveservices/azopenai/autorest.md | 2 +- sdk/cognitiveservices/azopenai/client.go | 51 ++++++++++++------- sdk/cognitiveservices/azopenai/constants.go | 3 +- sdk/cognitiveservices/azopenai/go.mod | 2 +- sdk/cognitiveservices/azopenai/go.sum | 4 +- sdk/cognitiveservices/azopenai/models.go | 3 +- .../azopenai/models_serde.go | 3 +- .../azopenai/response_types.go | 3 +- 8 files changed, 42 insertions(+), 29 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index 84bce54e83aa..9151c4ccccfc 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -11,7 +11,7 @@ module: github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai license-header: MICROSOFT_MIT_NO_VERSION openapi-type: data-plane go: true -use: "@autorest/go@4.0.0-preview.48" +use: "@autorest/go@4.0.0-preview.50" ``` ## Transformations diff --git a/sdk/cognitiveservices/azopenai/client.go b/sdk/cognitiveservices/azopenai/client.go index f9949caf4318..9b8ad911b0d6 100644 --- a/sdk/cognitiveservices/azopenai/client.go +++ b/sdk/cognitiveservices/azopenai/client.go @@ -3,9 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// Code generated by Microsoft (R) AutoRest Code Generator. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -// DO NOT EDIT. package azopenai @@ -34,18 +33,21 @@ type Client struct { // Generated from API version 2023-03-15-preview // - options - ClientGetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. func (client *Client) GetChatCompletions(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (ClientGetChatCompletionsResponse, error) { + var err error req, err := client.getChatCompletionsCreateRequest(ctx, body, options) if err != nil { return ClientGetChatCompletionsResponse{}, err } - resp, err := client.internal.Pipeline().Do(req) + httpResp, err := client.internal.Pipeline().Do(req) if err != nil { return ClientGetChatCompletionsResponse{}, err } - if !runtime.HasStatusCode(resp, http.StatusOK) { - return ClientGetChatCompletionsResponse{}, runtime.NewResponseError(resp) + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetChatCompletionsResponse{}, err } - return client.getChatCompletionsHandleResponse(resp) + resp, err := client.getChatCompletionsHandleResponse(httpResp) + return resp, err } // getChatCompletionsCreateRequest creates the GetChatCompletions request. @@ -63,7 +65,10 @@ func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body reqQP.Set("api-version", "2023-03-15-preview") req.Raw().URL.RawQuery = reqQP.Encode() req.Raw().Header["Accept"] = []string{"application/json"} - return req, runtime.MarshalAsJSON(req, body) + if err := runtime.MarshalAsJSON(req, body); err != nil { + return nil, err + } + return req, nil } // getChatCompletionsHandleResponse handles the GetChatCompletions response. @@ -82,18 +87,21 @@ func (client *Client) getChatCompletionsHandleResponse(resp *http.Response) (Cli // Generated from API version 2023-03-15-preview // - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. func (client *Client) GetCompletions(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (ClientGetCompletionsResponse, error) { + var err error req, err := client.getCompletionsCreateRequest(ctx, body, options) if err != nil { return ClientGetCompletionsResponse{}, err } - resp, err := client.internal.Pipeline().Do(req) + httpResp, err := client.internal.Pipeline().Do(req) if err != nil { return ClientGetCompletionsResponse{}, err } - if !runtime.HasStatusCode(resp, http.StatusOK) { - return ClientGetCompletionsResponse{}, runtime.NewResponseError(resp) + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetCompletionsResponse{}, err } - return client.getCompletionsHandleResponse(resp) + resp, err := client.getCompletionsHandleResponse(httpResp) + return resp, err } // getCompletionsCreateRequest creates the GetCompletions request. @@ -111,7 +119,10 @@ func (client *Client) getCompletionsCreateRequest(ctx context.Context, body Comp reqQP.Set("api-version", "2023-03-15-preview") req.Raw().URL.RawQuery = reqQP.Encode() req.Raw().Header["Accept"] = []string{"application/json"} - return req, runtime.MarshalAsJSON(req, body) + if err := runtime.MarshalAsJSON(req, body); err != nil { + return nil, err + } + return req, nil } // getCompletionsHandleResponse handles the GetCompletions response. @@ -129,18 +140,21 @@ func (client *Client) getCompletionsHandleResponse(resp *http.Response) (ClientG // Generated from API version 2023-03-15-preview // - options - ClientGetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. func (client *Client) GetEmbeddings(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (ClientGetEmbeddingsResponse, error) { + var err error req, err := client.getEmbeddingsCreateRequest(ctx, body, options) if err != nil { return ClientGetEmbeddingsResponse{}, err } - resp, err := client.internal.Pipeline().Do(req) + httpResp, err := client.internal.Pipeline().Do(req) if err != nil { return ClientGetEmbeddingsResponse{}, err } - if !runtime.HasStatusCode(resp, http.StatusOK) { - return ClientGetEmbeddingsResponse{}, runtime.NewResponseError(resp) + if !runtime.HasStatusCode(httpResp, http.StatusOK) { + err = runtime.NewResponseError(httpResp) + return ClientGetEmbeddingsResponse{}, err } - return client.getEmbeddingsHandleResponse(resp) + resp, err := client.getEmbeddingsHandleResponse(httpResp) + return resp, err } // getEmbeddingsCreateRequest creates the GetEmbeddings request. @@ -158,7 +172,10 @@ func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body Embed reqQP.Set("api-version", "2023-03-15-preview") req.Raw().URL.RawQuery = reqQP.Encode() req.Raw().Header["Accept"] = []string{"application/json"} - return req, runtime.MarshalAsJSON(req, body) + if err := runtime.MarshalAsJSON(req, body); err != nil { + return nil, err + } + return req, nil } // getEmbeddingsHandleResponse handles the GetEmbeddings response. diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go index e9517274b03e..a54c966c3d37 100644 --- a/sdk/cognitiveservices/azopenai/constants.go +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -3,9 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// Code generated by Microsoft (R) AutoRest Code Generator. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -// DO NOT EDIT. package azopenai diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod index 0ad97e44d36a..4573fc73272c 100644 --- a/sdk/cognitiveservices/azopenai/go.mod +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -3,7 +3,7 @@ module github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai go 1.18 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.3.0 diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum index c505048ba64e..80d64785f771 100644 --- a/sdk/cognitiveservices/azopenai/go.sum +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -1,5 +1,5 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 h1:SEy2xmstIphdPwNBUi7uhvjyjhVKISfwjfOJmuy7kg4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= diff --git a/sdk/cognitiveservices/azopenai/models.go b/sdk/cognitiveservices/azopenai/models.go index 0b7bd024db02..4ad6a4d007b9 100644 --- a/sdk/cognitiveservices/azopenai/models.go +++ b/sdk/cognitiveservices/azopenai/models.go @@ -3,9 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// Code generated by Microsoft (R) AutoRest Code Generator. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -// DO NOT EDIT. package azopenai diff --git a/sdk/cognitiveservices/azopenai/models_serde.go b/sdk/cognitiveservices/azopenai/models_serde.go index ba31e0bfbb5a..b88c28b4e32d 100644 --- a/sdk/cognitiveservices/azopenai/models_serde.go +++ b/sdk/cognitiveservices/azopenai/models_serde.go @@ -3,9 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// Code generated by Microsoft (R) AutoRest Code Generator. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -// DO NOT EDIT. package azopenai diff --git a/sdk/cognitiveservices/azopenai/response_types.go b/sdk/cognitiveservices/azopenai/response_types.go index 83d2b8d8be1e..a7127ec3f522 100644 --- a/sdk/cognitiveservices/azopenai/response_types.go +++ b/sdk/cognitiveservices/azopenai/response_types.go @@ -3,9 +3,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. -// Code generated by Microsoft (R) AutoRest Code Generator. +// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT. // Changes may cause incorrect behavior and will be lost if the code is regenerated. -// DO NOT EDIT. package azopenai From 797fdd14949dbf9d1e88d41e859cffb9ac528d48 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:16:08 -0700 Subject: [PATCH 12/62] Update sdk/cognitiveservices/azopenai/custom_client.go Co-authored-by: Jeffrey Richter --- sdk/cognitiveservices/azopenai/custom_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 602aebbc1e5a..57ba8336a5b5 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -53,7 +53,7 @@ func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID } // NewClientWithKeyCredential creates a new instance of Client with the specified values. -// - endpoint - Azure OpenAI service endpoint +// - endpoint - Azure OpenAI service endpoint, for example: https://{your-resource-name}.openai.azure.com // - credential - used to authorize requests with an API Key credential // - deploymentID - the deployment ID of the model to query // - options - client options, pass nil to accept the default values. From 2fb1feae5898e35e47e91c6094de78e8b1d5f49f Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:16:19 -0700 Subject: [PATCH 13/62] Update sdk/cognitiveservices/azopenai/custom_client.go Co-authored-by: Jeffrey Richter --- sdk/cognitiveservices/azopenai/custom_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 57ba8336a5b5..0340d80cc47e 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -73,7 +73,7 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo } // NewClientForOpenAI creates a new instance of Client with the specified values. -// - endpoint - OpenAI service endpoint +// - endpoint - OpenAI service endpoint, for example: https://api.openai.com/v1 // - credential - used to authorize requests with an API Key credential // - options - client options, pass nil to accept the default values. func NewClientForOpenAI(endpoint string, credential KeyCredential, options *ClientOptions) (*Client, error) { From 9e5c6aa2e6664c4dc48bafcc91a5f02c9ce9b38b Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:17:36 -0700 Subject: [PATCH 14/62] Update sdk/cognitiveservices/azopenai/custom_client.go Co-authored-by: Jeffrey Richter --- sdk/cognitiveservices/azopenai/custom_client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 0340d80cc47e..d3a6575249b5 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -33,7 +33,7 @@ type ClientOptions struct { } // NewClient creates a new instance of Client with the specified values. -// - endpoint - Azure OpenAI service endpoint +// - endpoint - Azure OpenAI service endpoint, for example: https://{your-resource-name}.openai.azure.com // - credential - used to authorize requests. Usually a credential from azidentity. // - deploymentID - the deployment ID of the model to query // - options - client options, pass nil to accept the default values. From 2c10176413488fe44f24d0e3c9a7c70c49b6e20e Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 15:29:49 -0700 Subject: [PATCH 15/62] Strip out deploymentID formatting from the individual client functions. We just incorporate it into the endpoint now. --- sdk/cognitiveservices/azopenai/autorest.md | 18 ++++++++---- sdk/cognitiveservices/azopenai/build.go | 2 +- sdk/cognitiveservices/azopenai/client.go | 23 ++++----------- .../azopenai/client_shared_test.go | 2 +- .../azopenai/custom_client.go | 28 +++++++++++++++---- .../azopenai/models_serde.go | 3 +- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index 9151c4ccccfc..0f8c864cabb2 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -93,14 +93,20 @@ directive: delete $.allOf; $["$ref"] = "#/components/schemas/CompletionsUsage"; - # Remove deploymentId from path when not set + # + # strip out the deploymentID validation code - we absorbed this into the endpoint. + # + # urlPath := "/deployments/{deploymentId}/embeddings" + # if client.deploymentID == "" { + # return nil, errors.New("parameter client.deploymentID cannot be empty") + # } + # urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) - from: client.go where: $ - transform: return $.replace(/\sreturn.*parameter client.deploymentID cannot be empty"\)\s/g, "urlPath = strings.ReplaceAll(urlPath, \"/deployments/{deploymentId}/\", \"/v1/\")"); - # Drop error import - - from: client.go - where: $ - transform: return $.replace(/(import \(\n(\s\"\w+\"\n)+)\s\"errors\"\n/g, "$1"); + transform: >- + return $.replace( + /(\s+)urlPath\s*:=\s*"\/deployments\/\{deploymentId\}\/([^"]+)".+?url\.PathEscape.+?\n/gs, + "$1urlPath := \"$2\"\n") # delete unused error models - from: models.go diff --git a/sdk/cognitiveservices/azopenai/build.go b/sdk/cognitiveservices/azopenai/build.go index ac79e21f95c3..12924d856949 100644 --- a/sdk/cognitiveservices/azopenai/build.go +++ b/sdk/cognitiveservices/azopenai/build.go @@ -3,7 +3,7 @@ //go:generate autorest ./autorest.md //go:generate go mod tidy -//go:generate gofmt -w . +//go:generate goimports -w . // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. diff --git a/sdk/cognitiveservices/azopenai/client.go b/sdk/cognitiveservices/azopenai/client.go index 9b8ad911b0d6..b9b80cf629d5 100644 --- a/sdk/cognitiveservices/azopenai/client.go +++ b/sdk/cognitiveservices/azopenai/client.go @@ -10,12 +10,11 @@ package azopenai import ( "context" + "net/http" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime" - "net/http" - "net/url" - "strings" ) // Client contains the methods for the OpenAI group. @@ -52,11 +51,7 @@ func (client *Client) GetChatCompletions(ctx context.Context, body ChatCompletio // getChatCompletionsCreateRequest creates the GetChatCompletions request. func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (*policy.Request, error) { - urlPath := "/deployments/{deploymentId}/chat/completions" - if client.deploymentID == "" { - urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") - } - urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + urlPath := "chat/completions" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { return nil, err @@ -106,11 +101,7 @@ func (client *Client) GetCompletions(ctx context.Context, body CompletionsOption // getCompletionsCreateRequest creates the GetCompletions request. func (client *Client) getCompletionsCreateRequest(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (*policy.Request, error) { - urlPath := "/deployments/{deploymentId}/completions" - if client.deploymentID == "" { - urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") - } - urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + urlPath := "completions" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { return nil, err @@ -159,11 +150,7 @@ func (client *Client) GetEmbeddings(ctx context.Context, body EmbeddingsOptions, // getEmbeddingsCreateRequest creates the GetEmbeddings request. func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (*policy.Request, error) { - urlPath := "/deployments/{deploymentId}/embeddings" - if client.deploymentID == "" { - urlPath = strings.ReplaceAll(urlPath, "/deployments/{deploymentId}/", "/v1/") - } - urlPath = strings.ReplaceAll(urlPath, "{deploymentId}", url.PathEscape(client.deploymentID)) + urlPath := "embeddings" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { return nil, err diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index b57413fe89e7..3259149a14fa 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -38,7 +38,7 @@ func newRecordingTransporter(t *testing.T) policy.Transporter { err = recording.AddHeaderRegexSanitizer("Api-Key", `redacted`, "", nil) require.NoError(t, err) - err = recording.AddURISanitizer("https://aoai", "https://[^/]+", nil) + err = recording.AddURISanitizer("https://aoai", endpoint, nil) require.NoError(t, err) t.Cleanup(func() { diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index d3a6575249b5..58db38e768ac 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -13,6 +13,7 @@ import ( "encoding/json" "errors" "net/http" + "net/url" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" @@ -41,15 +42,25 @@ func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID if options == nil { options = &ClientOptions{} } - if deploymentID == "" { - return nil, errors.New("parameter client.deploymentID cannot be empty") - } + authPolicy := runtime.NewBearerTokenPolicy(credential, []string{tokenScope}, nil) azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) if err != nil { return nil, err } - return &Client{endpoint: endpoint + "/openai", deploymentID: deploymentID, internal: azcoreClient}, nil + + fullEndpoint, err := formatAzureOpenAIURL(endpoint, deploymentID) + + if err != nil { + return nil, err + } + + return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil +} + +func formatAzureOpenAIURL(endpoint, deploymentID string) (string, error) { + escapedDeplID := url.PathEscape(deploymentID) + return url.JoinPath(endpoint, "openai", "deployments", escapedDeplID) } // NewClientWithKeyCredential creates a new instance of Client with the specified values. @@ -69,7 +80,14 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo if err != nil { return nil, err } - return &Client{endpoint: endpoint + "/openai", deploymentID: deploymentID, internal: azcoreClient}, nil + + fullEndpoint, err := formatAzureOpenAIURL(endpoint, deploymentID) + + if err != nil { + return nil, err + } + + return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil } // NewClientForOpenAI creates a new instance of Client with the specified values. diff --git a/sdk/cognitiveservices/azopenai/models_serde.go b/sdk/cognitiveservices/azopenai/models_serde.go index b88c28b4e32d..dda9817c1894 100644 --- a/sdk/cognitiveservices/azopenai/models_serde.go +++ b/sdk/cognitiveservices/azopenai/models_serde.go @@ -11,8 +11,9 @@ package azopenai import ( "encoding/json" "fmt" - "github.com/Azure/azure-sdk-for-go/sdk/azcore" "reflect" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore" ) // MarshalJSON implements the json.Marshaller interface for type Error. From 5938ac500d1dcc8db5c396166cc9041af0cad7e1 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 15:38:30 -0700 Subject: [PATCH 16/62] splice out the auto-generated `deploymentID` field from the client --- sdk/cognitiveservices/azopenai/autorest.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index 0f8c864cabb2..9ab6d2c33dc0 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -108,6 +108,14 @@ directive: /(\s+)urlPath\s*:=\s*"\/deployments\/\{deploymentId\}\/([^"]+)".+?url\.PathEscape.+?\n/gs, "$1urlPath := \"$2\"\n") + # splice out the auto-generated `deploymentID` field from the client + - from: client.go + where: $ + transform: >- + return $.replace( + /(type Client struct.+?)deploymentID string([^}]+})/s, + "$1$2") + # delete unused error models - from: models.go where: $ From 6535eca1f952f6c24d948ce64897642c5e3ef38b Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 15:39:38 -0700 Subject: [PATCH 17/62] splice out the auto-generated `deploymentID` field from the client --- sdk/cognitiveservices/azopenai/client.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client.go b/sdk/cognitiveservices/azopenai/client.go index b9b80cf629d5..7bde66a202d0 100644 --- a/sdk/cognitiveservices/azopenai/client.go +++ b/sdk/cognitiveservices/azopenai/client.go @@ -20,9 +20,8 @@ import ( // Client contains the methods for the OpenAI group. // Don't use this type directly, use a constructor function instead. type Client struct { - internal *azcore.Client - endpoint string - deploymentID string + internal *azcore.Client + endpoint string } // GetChatCompletions - Gets chat completions for the provided chat messages. Completions support a wide variety of tasks From b3df143ef42b8154eb6ee55b0be405da5a7fdd90 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 15:48:29 -0700 Subject: [PATCH 18/62] No en-us links --- sdk/cognitiveservices/azopenai/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index 2a1721791fb2..b673c1d0cac4 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -93,7 +93,7 @@ comments. [azure_identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity [azure_sub]: https://azure.microsoft.com/free/ [openai_docs]: https://learn.microsoft.com/azure/cognitive-services/openai -[openai_key_concepts]: https://learn.microsoft.com/en-us/azure/cognitive-services/openai/overview#key-concepts +[openai_key_concepts]: https://learn.microsoft.com/azure/cognitive-services/openai/overview#key-concepts [openai_rest_docs]: https://learn.microsoft.com/azure/cognitive-services/openai/reference [cla]: https://cla.microsoft.com [coc]: https://opensource.microsoft.com/codeofconduct/ From afcf5213bd03306a6ea9328380ebb1c17e0416e3 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:09:56 -0700 Subject: [PATCH 19/62] Added in another recorded test --- .../azopenai/client_shared_test.go | 30 +++++++++++++------ .../azopenai/custom_client_test.go | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index 3259149a14fa..b332b37a87b8 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -19,13 +19,22 @@ var ( apiKey string ) +const fakeEndpoint = "https://recordedhost/" +const fakeAPIKey = "redacted" + func init() { - if err := godotenv.Load(); err != nil { - fmt.Printf("Failed to load .env file: %s\n", err) - os.Exit(1) + if recording.GetRecordMode() == recording.PlaybackMode { + endpoint = fakeEndpoint + apiKey = fakeAPIKey + } else { + if err := godotenv.Load(); err != nil { + fmt.Printf("Failed to load .env file: %s\n", err) + os.Exit(1) + } + + endpoint = os.Getenv("AOAI_ENDPOINT") + apiKey = os.Getenv("AOAI_API_KEY") } - endpoint = os.Getenv("AOAI_ENDPOINT") - apiKey = os.Getenv("AOAI_API_KEY") } func newRecordingTransporter(t *testing.T) policy.Transporter { @@ -35,11 +44,14 @@ func newRecordingTransporter(t *testing.T) policy.Transporter { err = recording.Start(t, "sdk/cognitive/azopenai/testdata", nil) require.NoError(t, err) - err = recording.AddHeaderRegexSanitizer("Api-Key", `redacted`, "", nil) - require.NoError(t, err) + if recording.GetRecordMode() != recording.PlaybackMode { + err = recording.AddHeaderRegexSanitizer("Api-Key", fakeAPIKey, "", nil) + require.NoError(t, err) - err = recording.AddURISanitizer("https://aoai", endpoint, nil) - require.NoError(t, err) + // "RequestUri": "https://openai-shared.openai.azure.com/openai/deployments/text-davinci-003/completions?api-version=2023-03-15-preview", + err = recording.AddURISanitizer(fakeEndpoint, endpoint, nil) + require.NoError(t, err) + } t.Cleanup(func() { err := recording.Stop(t, nil) diff --git a/sdk/cognitiveservices/azopenai/custom_client_test.go b/sdk/cognitiveservices/azopenai/custom_client_test.go index ba0496799e95..50915cfc9d57 100644 --- a/sdk/cognitiveservices/azopenai/custom_client_test.go +++ b/sdk/cognitiveservices/azopenai/custom_client_test.go @@ -83,7 +83,7 @@ func TestClient_GetCompletionsStream(t *testing.T) { } cred := KeyCredential{APIKey: apiKey} deploymentID := "text-davinci-003" - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, nil) + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) if err != nil { t.Errorf("NewClientWithKeyCredential() error = %v", err) return From a4f5a23af052eac1b4ef907658cf02cd4ef34f05 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:11:48 -0700 Subject: [PATCH 20/62] Remove check, we'll let the service handle it. --- sdk/cognitiveservices/azopenai/custom_client.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 58db38e768ac..fbbb7d920811 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -11,7 +11,6 @@ package azopenai import ( "context" "encoding/json" - "errors" "net/http" "net/url" @@ -72,9 +71,7 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo if options == nil { options = &ClientOptions{} } - if deploymentID == "" { - return nil, errors.New("parameter client.deploymentID cannot be empty") - } + authPolicy := NewAPIKeyPolicy(credential, "api-key") azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) if err != nil { From ec5978c3a2dcc6fce015b062629bd9b005b3b399 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:25:35 -0700 Subject: [PATCH 21/62] Package isn't published yet, temp link for now. --- sdk/cognitiveservices/azopenai/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index b673c1d0cac4..2f9308a4b0fe 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -89,7 +89,8 @@ comments. [azopenai_repo]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/cognitiveservices/azopenai -[azopenai_pkg_go]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai + +[azopenai_pkg_go]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk [azure_identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity [azure_sub]: https://azure.microsoft.com/free/ [openai_docs]: https://learn.microsoft.com/azure/cognitive-services/openai From 6131717cf6ce3b041ed9ca5ea2db2de4d103ce64 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:27:17 -0700 Subject: [PATCH 22/62] Whoops, uri.JoinPaths is a new API. --- .../azopenai/custom_client.go | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index fbbb7d920811..1f3ecd42f025 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -48,18 +48,13 @@ func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID return nil, err } - fullEndpoint, err := formatAzureOpenAIURL(endpoint, deploymentID) - - if err != nil { - return nil, err - } - + fullEndpoint := formatAzureOpenAIURL(endpoint, deploymentID) return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil } -func formatAzureOpenAIURL(endpoint, deploymentID string) (string, error) { +func formatAzureOpenAIURL(endpoint, deploymentID string) string { escapedDeplID := url.PathEscape(deploymentID) - return url.JoinPath(endpoint, "openai", "deployments", escapedDeplID) + return runtime.JoinPaths(endpoint, "openai", "deployments", escapedDeplID) } // NewClientWithKeyCredential creates a new instance of Client with the specified values. @@ -78,12 +73,7 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo return nil, err } - fullEndpoint, err := formatAzureOpenAIURL(endpoint, deploymentID) - - if err != nil { - return nil, err - } - + fullEndpoint := formatAzureOpenAIURL(endpoint, deploymentID) return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil } From 8f64745af07d0ab193c5bbcc16ed8c4bb3a1fb70 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:41:21 -0700 Subject: [PATCH 23/62] Missed another dead link. --- sdk/cognitiveservices/azopenai/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index 2f9308a4b0fe..99578d6e7ce1 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -88,8 +88,9 @@ the [Code of Conduct FAQ][coc_faq] or contact [opencode@microsoft.com][coc_conta comments. -[azopenai_repo]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/cognitiveservices/azopenai + +[azopenai_repo]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk [azopenai_pkg_go]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk [azure_identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity [azure_sub]: https://azure.microsoft.com/free/ From 3d97237ca3d266e7614481c099a64ee0317b7586 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 16:58:22 -0700 Subject: [PATCH 24/62] Missing doc comment and rename suggested by Jeff. --- sdk/cognitiveservices/azopenai/custom_client.go | 4 ++-- sdk/cognitiveservices/azopenai/custom_models.go | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 1f3ecd42f025..40eea7217016 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -137,9 +137,9 @@ func (o streamCompletionsOptions) MarshalJSON() ([]byte, error) { // GetCompletionsStream - Return the completions for a given prompt as a sequence of events. // If the operation fails it returns an *azcore.ResponseError type. // - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. -func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsStreamOptions) (CompletionEventsResponse, error) { +func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsStreamOptions) (GetCompletionsStreamResponse, error) { req, err := client.getCompletionsCreateRequest(ctx, CompletionsOptions{}, &ClientGetCompletionsOptions{}) - var cer CompletionEventsResponse + var cer GetCompletionsStreamResponse if err != nil { return cer, err } diff --git a/sdk/cognitiveservices/azopenai/custom_models.go b/sdk/cognitiveservices/azopenai/custom_models.go index 14af0fb283c5..afe028d6a9f8 100644 --- a/sdk/cognitiveservices/azopenai/custom_models.go +++ b/sdk/cognitiveservices/azopenai/custom_models.go @@ -13,7 +13,8 @@ type ClientGetCompletionsStreamOptions struct { // placeholder for future optional parameters } -type CompletionEventsResponse struct { +// GetCompletionsStreamResponse is the response from [GetCompletionsStream]. +type GetCompletionsStreamResponse struct { // REQUIRED; An EventReader to obtain the streaming completions choices associated with this completions response. // Generally, n choices are generated per provided prompt with a default value of 1. Token limits and other settings // may limit the number of choices generated. From e30c767c17fdc6647193af90bb1b3045c1658848 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:02:54 -0700 Subject: [PATCH 25/62] Docs for EventReader --- sdk/cognitiveservices/azopenai/event_reader.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/event_reader.go b/sdk/cognitiveservices/azopenai/event_reader.go index 8febabec4bcf..c98b74ddd6af 100644 --- a/sdk/cognitiveservices/azopenai/event_reader.go +++ b/sdk/cognitiveservices/azopenai/event_reader.go @@ -14,6 +14,7 @@ import ( "strings" ) +// EventReader streams events dynamically from an OpenAI endpoint. type EventReader[T any] struct { reader io.Reader // Required for Closing scanner *bufio.Scanner @@ -23,6 +24,8 @@ func newEventReader[T any](r io.Reader) *EventReader[T] { return &EventReader[T]{reader: r, scanner: bufio.NewScanner(r)} } +// Read reads the next event from the stream. +// Returns io.EOF when there are no further events. func (er *EventReader[T]) Read() (T, error) { // https://html.spec.whatwg.org/multipage/server-sent-events.html for er.scanner.Scan() { // Scan while no error @@ -41,7 +44,6 @@ func (er *EventReader[T]) Read() (T, error) { if tokens[1] == "[DONE]" { // If data is [DONE], end of stream was reached return data, io.EOF } - //fmt.Println(tokens[1]) err := json.Unmarshal([]byte(tokens[1]), &data) return data, err @@ -54,6 +56,7 @@ func (er *EventReader[T]) Read() (T, error) { return *new(T), er.scanner.Err() } +// Close closes the EventReader and any applicable inner stream state. func (er *EventReader[T]) Close() { if closer, ok := er.reader.(io.Closer); ok { closer.Close() From 2d42c9f9b5c7acb47647b5bd5d13440105f5c5d5 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:06:07 -0700 Subject: [PATCH 26/62] Adding more docs, unexporting most of policy --- sdk/cognitiveservices/azopenai/custom_client.go | 2 +- sdk/cognitiveservices/azopenai/policy_apikey.go | 16 ++++++++-------- .../azopenai/policy_apikey_test.go | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 40eea7217016..435e9e0f2616 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -67,7 +67,7 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo options = &ClientOptions{} } - authPolicy := NewAPIKeyPolicy(credential, "api-key") + authPolicy := newAPIKeyPolicy(credential, "api-key") azcoreClient, err := azcore.NewClient(clientName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions) if err != nil { return nil, err diff --git a/sdk/cognitiveservices/azopenai/policy_apikey.go b/sdk/cognitiveservices/azopenai/policy_apikey.go index 1d57d1c9296d..ad353946801b 100644 --- a/sdk/cognitiveservices/azopenai/policy_apikey.go +++ b/sdk/cognitiveservices/azopenai/policy_apikey.go @@ -12,29 +12,29 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" ) -// KeyCredential - +// KeyCredential is used when doing APIKey-based authentication. type KeyCredential struct { + // APIKey is the api key for the client. APIKey string } -// APIKeyPolicy authorizes requests with an API key acquired from a KeyCredential. -type APIKeyPolicy struct { +// apiKeyPolicy authorizes requests with an API key acquired from a KeyCredential. +type apiKeyPolicy struct { header string cred KeyCredential } -// NewAPIKeyPolicy creates a policy object that authorizes requests with an API Key. +// newAPIKeyPolicy creates a policy object that authorizes requests with an API Key. // cred: a KeyCredential implementation. -func NewAPIKeyPolicy(cred KeyCredential, header string) *APIKeyPolicy { - return &APIKeyPolicy{ +func newAPIKeyPolicy(cred KeyCredential, header string) *apiKeyPolicy { + return &apiKeyPolicy{ header: header, cred: cred, } } // Do returns a function which authorizes req with a token from the policy's credential -func (b *APIKeyPolicy) Do(req *policy.Request) (*http.Response, error) { +func (b *apiKeyPolicy) Do(req *policy.Request) (*http.Response, error) { req.Raw().Header.Set(b.header, b.cred.APIKey) return req.Next() } diff --git a/sdk/cognitiveservices/azopenai/policy_apikey_test.go b/sdk/cognitiveservices/azopenai/policy_apikey_test.go index d688530dd896..b5945449c503 100644 --- a/sdk/cognitiveservices/azopenai/policy_apikey_test.go +++ b/sdk/cognitiveservices/azopenai/policy_apikey_test.go @@ -28,7 +28,7 @@ func TestNewAPIKeyPolicy(t *testing.T) { tests := []struct { name string args args - want *APIKeyPolicy + want *apiKeyPolicy }{ { name: "simple", @@ -36,7 +36,7 @@ func TestNewAPIKeyPolicy(t *testing.T) { cred: simpleCred, header: simpleHeader, }, - want: &APIKeyPolicy{ + want: &apiKeyPolicy{ header: simpleHeader, cred: simpleCred, }, @@ -44,7 +44,7 @@ func TestNewAPIKeyPolicy(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewAPIKeyPolicy(tt.args.cred, tt.args.header); !reflect.DeepEqual(got, tt.want) { + if got := newAPIKeyPolicy(tt.args.cred, tt.args.header); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewAPIKeyPolicy() = %v, want %v", got, tt.want) } }) @@ -58,7 +58,7 @@ func TestAPIKeyPolicy_Success(t *testing.T) { cred := KeyCredential{ APIKey: "secret", } - authPolicy := NewAPIKeyPolicy(cred, "api-key") + authPolicy := newAPIKeyPolicy(cred, "api-key") pipeline := runtime.NewPipeline( "testmodule", "v0.1.0", From 90e12c8284ce95b3ba14ce96e4468ed0c8e9361b Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:07:13 -0700 Subject: [PATCH 27/62] Unexport serviceAPIVersions --- sdk/cognitiveservices/azopenai/constants.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go index a54c966c3d37..8518be913db7 100644 --- a/sdk/cognitiveservices/azopenai/constants.go +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -44,16 +44,16 @@ func PossibleCompletionsFinishReasonValues() []CompletionsFinishReason { } } -type ServiceAPIVersions string +type serviceAPIVersions string const ( - ServiceAPIVersionsTwoThousandTwentyThree0315Preview ServiceAPIVersions = "2023-03-15-preview" - ServiceAPIVersionsTwoThousandTwentyTwo1201 ServiceAPIVersions = "2022-12-01" + ServiceAPIVersionsTwoThousandTwentyThree0315Preview serviceAPIVersions = "2023-03-15-preview" + ServiceAPIVersionsTwoThousandTwentyTwo1201 serviceAPIVersions = "2022-12-01" ) // PossibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. -func PossibleServiceAPIVersionsValues() []ServiceAPIVersions { - return []ServiceAPIVersions{ +func PossibleServiceAPIVersionsValues() []serviceAPIVersions { + return []serviceAPIVersions{ ServiceAPIVersionsTwoThousandTwentyThree0315Preview, ServiceAPIVersionsTwoThousandTwentyTwo1201, } From 518e9b061bed9fbdf8ed35f851c58fb6bdca4fe7 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:07:58 -0700 Subject: [PATCH 28/62] Unexport serviceAPIVersions --- sdk/cognitiveservices/azopenai/constants.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go index 8518be913db7..a9d1de76c8a9 100644 --- a/sdk/cognitiveservices/azopenai/constants.go +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -47,14 +47,14 @@ func PossibleCompletionsFinishReasonValues() []CompletionsFinishReason { type serviceAPIVersions string const ( - ServiceAPIVersionsTwoThousandTwentyThree0315Preview serviceAPIVersions = "2023-03-15-preview" - ServiceAPIVersionsTwoThousandTwentyTwo1201 serviceAPIVersions = "2022-12-01" + serviceAPIVersionsTwoThousandTwentyThree0315Preview serviceAPIVersions = "2023-03-15-preview" + serviceAPIVersionsTwoThousandTwentyTwo1201 serviceAPIVersions = "2022-12-01" ) -// PossibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. -func PossibleServiceAPIVersionsValues() []serviceAPIVersions { +// possibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. +func possibleServiceAPIVersionsValues() []serviceAPIVersions { return []serviceAPIVersions{ - ServiceAPIVersionsTwoThousandTwentyThree0315Preview, - ServiceAPIVersionsTwoThousandTwentyTwo1201, + serviceAPIVersionsTwoThousandTwentyThree0315Preview, + serviceAPIVersionsTwoThousandTwentyTwo1201, } } From 88fcc73012b3076e834090a91114fc817711b26e Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:09:54 -0700 Subject: [PATCH 29/62] Update recordings and tag --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index c076b55f7aaa..9a97a8fe9c41 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_e2a2d2dbef" + "Tag": "go/cognitiveservices/azopenai_974bad8076" } From dd70e9d8ef684d256291694fcbc9bb4c80964a89 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 17:42:58 -0700 Subject: [PATCH 30/62] Hm... --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index 9a97a8fe9c41..2c03f252a6f9 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_974bad8076" + "Tag": "go/cognitiveservices/azopenai_5492653858" } From a029a809a23552a158c49f0ebc03fdf4c9ad29ab Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 18:22:22 -0700 Subject: [PATCH 31/62] Oops, wrong path --- sdk/cognitiveservices/azopenai/client_shared_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index b332b37a87b8..631f692a2906 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -41,7 +41,7 @@ func newRecordingTransporter(t *testing.T) policy.Transporter { transport, err := recording.NewRecordingHTTPClient(t, nil) require.NoError(t, err) - err = recording.Start(t, "sdk/cognitive/azopenai/testdata", nil) + err = recording.Start(t, "sdk/cognitiveservices/azopenai/testdata", nil) require.NoError(t, err) if recording.GetRecordMode() != recording.PlaybackMode { From 569131994df89f31093eb767925e40d054b13180 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 18:23:59 -0700 Subject: [PATCH 32/62] Fixed generation issue --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index 2c03f252a6f9..ba78d3aaa3c0 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_5492653858" + "Tag": "go/cognitiveservices/azopenai_fdb14d8605" } From a8d9d2324b0a0906d5bafa586de4d12ca5146c8b Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 19:11:05 -0700 Subject: [PATCH 33/62] Adding in a test that shows error parsing. --- sdk/cognitiveservices/azopenai/client_test.go | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index a134f8de50a6..ce5866853c65 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -11,9 +11,11 @@ import ( "log" "testing" + "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/require" ) func TestClient_GetChatCompletions(t *testing.T) { @@ -91,6 +93,35 @@ func TestClient_GetChatCompletions(t *testing.T) { } } +func TestClient_GetChatCompletions_InvalidModel(t *testing.T) { + type args struct { + ctx context.Context + deploymentID string + body ChatCompletionsOptions + options *ClientGetChatCompletionsOptions + } + cred := KeyCredential{APIKey: apiKey} + chatClient, err := NewClientWithKeyCredential(endpoint, cred, "thisdoesntexist", newClientOptionsForTest(t)) + if err != nil { + log.Fatalf("%v", err) + } + + _, err = chatClient.GetChatCompletions(context.Background(), ChatCompletionsOptions{ + Messages: []*ChatMessage{ + { + Role: to.Ptr(ChatRole("user")), + Content: to.Ptr("Count to 100, with a comma between each number and no newlines. E.g., 1, 2, 3, ..."), + }, + }, + MaxTokens: to.Ptr(int32(1024)), + Temperature: to.Ptr(float32(0.0)), + }, nil) + + var respErr *azcore.ResponseError + require.ErrorAs(t, err, &respErr) + require.Equal(t, "DeploymentNotFound", respErr.ErrorCode) +} + func TestClient_GetCompletions(t *testing.T) { type args struct { ctx context.Context From c5c1bb683f4ea2e0bc4299873bfb888528bb0dbc Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 19:11:45 -0700 Subject: [PATCH 34/62] Updated to use require --- sdk/cognitiveservices/azopenai/client_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index ce5866853c65..53abc4a93d09 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -102,9 +102,7 @@ func TestClient_GetChatCompletions_InvalidModel(t *testing.T) { } cred := KeyCredential{APIKey: apiKey} chatClient, err := NewClientWithKeyCredential(endpoint, cred, "thisdoesntexist", newClientOptionsForTest(t)) - if err != nil { - log.Fatalf("%v", err) - } + require.NoError(t, err) _, err = chatClient.GetChatCompletions(context.Background(), ChatCompletionsOptions{ Messages: []*ChatMessage{ From ac088e1279a08acb054caa0b178e8946904f9896 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 19:12:22 -0700 Subject: [PATCH 35/62] New function test --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index ba78d3aaa3c0..dfb41c004208 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_fdb14d8605" + "Tag": "go/cognitiveservices/azopenai_1e480fcad7" } From 8c1403bb7f4570ef10c9a4bf2ddd3dcc950381aa Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 20:25:50 -0700 Subject: [PATCH 36/62] Scrub the unused error types (error, innnerror, blah) --- sdk/cognitiveservices/azopenai/autorest.md | 20 +- sdk/cognitiveservices/azopenai/client_test.go | 18 +- sdk/cognitiveservices/azopenai/constants.go | 16 +- sdk/cognitiveservices/azopenai/models.go | 72 ------ .../azopenai/models_serde.go | 206 ------------------ 5 files changed, 30 insertions(+), 302 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index 9ab6d2c33dc0..e1eb8472edd4 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -119,17 +119,17 @@ directive: # delete unused error models - from: models.go where: $ - transform: return $.replace(/(?:\/\/.*\s)?type (?:ErrorResponse|ErrorResponseError).+\{(?:\s.+\s)+\}\s/g, ""); + transform: >- + return $.replace( + /\/\/ AzureCoreFoundations.*?type AzureCoreFoundations(Error|ErrorResponse|ErrorResponseError|InnerError|InnerErrorInnererror|ErrorInnererror) struct \{[^}]+\}/gs, + "") - from: models_serde.go where: $ - transform: return $.replace(/(?:\/\/.*\s)?func \(\w \*?(?:ErrorResponse|ErrorResponseError)\).*\{\s(?:.+\s)+\}\s/g, ""); - - # rename the "AzureCoreFoundation" prefix from models - - from: - - client.go - - models.go - - models_serde.go - - response_types.go + transform: >- + return $.replace( + /\/\/ (UnmarshalJSON|MarshalJSON) implements.*?AzureCoreFoundations.*?func.+?\n}/gs, + "") + - from: models_serde.go where: $ - transform: return $.replace(/AzureCoreFoundations/g, ""); + transform: return $.replace(/(?:\/\/.*\s)?func \(\w \*?(?:ErrorResponse|ErrorResponseError|InnerError|InnerErrorInnererror)\).*\{\s(?:.+\s)+\}\s/g, ""); ``` diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 53abc4a93d09..ed5dba978b93 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -94,12 +94,6 @@ func TestClient_GetChatCompletions(t *testing.T) { } func TestClient_GetChatCompletions_InvalidModel(t *testing.T) { - type args struct { - ctx context.Context - deploymentID string - body ChatCompletionsOptions - options *ClientGetChatCompletionsOptions - } cred := KeyCredential{APIKey: apiKey} chatClient, err := NewClientWithKeyCredential(endpoint, cred, "thisdoesntexist", newClientOptionsForTest(t)) require.NoError(t, err) @@ -120,6 +114,18 @@ func TestClient_GetChatCompletions_InvalidModel(t *testing.T) { require.Equal(t, "DeploymentNotFound", respErr.ErrorCode) } +func TestClient_GetEmbeddings_InvalidModel(t *testing.T) { + cred := KeyCredential{APIKey: apiKey} + chatClient, err := NewClientWithKeyCredential(endpoint, cred, "thisdoesntexist", newClientOptionsForTest(t)) + require.NoError(t, err) + + _, err = chatClient.GetEmbeddings(context.Background(), EmbeddingsOptions{}, nil) + + var respErr *azcore.ResponseError + require.ErrorAs(t, err, &respErr) + require.Equal(t, "DeploymentNotFound", respErr.ErrorCode) +} + func TestClient_GetCompletions(t *testing.T) { type args struct { ctx context.Context diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go index a9d1de76c8a9..a54c966c3d37 100644 --- a/sdk/cognitiveservices/azopenai/constants.go +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -44,17 +44,17 @@ func PossibleCompletionsFinishReasonValues() []CompletionsFinishReason { } } -type serviceAPIVersions string +type ServiceAPIVersions string const ( - serviceAPIVersionsTwoThousandTwentyThree0315Preview serviceAPIVersions = "2023-03-15-preview" - serviceAPIVersionsTwoThousandTwentyTwo1201 serviceAPIVersions = "2022-12-01" + ServiceAPIVersionsTwoThousandTwentyThree0315Preview ServiceAPIVersions = "2023-03-15-preview" + ServiceAPIVersionsTwoThousandTwentyTwo1201 ServiceAPIVersions = "2022-12-01" ) -// possibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. -func possibleServiceAPIVersionsValues() []serviceAPIVersions { - return []serviceAPIVersions{ - serviceAPIVersionsTwoThousandTwentyThree0315Preview, - serviceAPIVersionsTwoThousandTwentyTwo1201, +// PossibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. +func PossibleServiceAPIVersionsValues() []ServiceAPIVersions { + return []ServiceAPIVersions{ + ServiceAPIVersionsTwoThousandTwentyThree0315Preview, + ServiceAPIVersionsTwoThousandTwentyTwo1201, } } diff --git a/sdk/cognitiveservices/azopenai/models.go b/sdk/cognitiveservices/azopenai/models.go index 4ad6a4d007b9..5275f85ae42e 100644 --- a/sdk/cognitiveservices/azopenai/models.go +++ b/sdk/cognitiveservices/azopenai/models.go @@ -8,78 +8,6 @@ package azopenai -// Error - The error object. -type Error struct { - // REQUIRED; One of a server-defined set of error codes. - Code *string - - // REQUIRED; An array of details about specific errors that led to this reported error. - Details []*Error - - // REQUIRED; A human-readable representation of the error. - Message *string - - // An object containing more specific information than the current object about the error. - Innererror *ErrorInnererror - - // The target of the error. - Target *string -} - -// ErrorInnererror - An object containing more specific information than the current object about the -// error. -type ErrorInnererror struct { - // REQUIRED; One of a server-defined set of error codes. - Code *string - - // Inner error. - Innererror *InnerErrorInnererror -} - -// ErrorResponse - A response containing error details. -type ErrorResponse struct { - // REQUIRED; The error object. - Error *ErrorResponseError -} - -// ErrorResponseError - The error object. -type ErrorResponseError struct { - // REQUIRED; One of a server-defined set of error codes. - Code *string - - // REQUIRED; An array of details about specific errors that led to this reported error. - Details []*Error - - // REQUIRED; A human-readable representation of the error. - Message *string - - // An object containing more specific information than the current object about the error. - Innererror *ErrorInnererror - - // The target of the error. - Target *string -} - -// InnerError - An object containing more specific information about the error. As per Microsoft One API -// guidelines - -// https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses. -type InnerError struct { - // REQUIRED; One of a server-defined set of error codes. - Code *string - - // Inner error. - Innererror *InnerErrorInnererror -} - -// InnerErrorInnererror - Inner error. -type InnerErrorInnererror struct { - // REQUIRED; One of a server-defined set of error codes. - Code *string - - // Inner error. - Innererror *InnerErrorInnererror -} - // ChatChoice - The representation of a single prompt completion as part of an overall chat completions request. Generally, // n choices are generated per provided prompt with a default value of 1. Token limits and // other settings may limit the number of choices generated. diff --git a/sdk/cognitiveservices/azopenai/models_serde.go b/sdk/cognitiveservices/azopenai/models_serde.go index dda9817c1894..a757d9b7f13c 100644 --- a/sdk/cognitiveservices/azopenai/models_serde.go +++ b/sdk/cognitiveservices/azopenai/models_serde.go @@ -16,212 +16,6 @@ import ( "github.com/Azure/azure-sdk-for-go/sdk/azcore" ) -// MarshalJSON implements the json.Marshaller interface for type Error. -func (a Error) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "code", a.Code) - populate(objectMap, "details", a.Details) - populate(objectMap, "innererror", a.Innererror) - populate(objectMap, "message", a.Message) - populate(objectMap, "target", a.Target) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type Error. -func (a *Error) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "code": - err = unpopulate(val, "Code", &a.Code) - delete(rawMsg, key) - case "details": - err = unpopulate(val, "Details", &a.Details) - delete(rawMsg, key) - case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) - delete(rawMsg, key) - case "message": - err = unpopulate(val, "Message", &a.Message) - delete(rawMsg, key) - case "target": - err = unpopulate(val, "Target", &a.Target) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - -// MarshalJSON implements the json.Marshaller interface for type ErrorInnererror. -func (a ErrorInnererror) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "code", a.Code) - populate(objectMap, "innererror", a.Innererror) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorInnererror. -func (a *ErrorInnererror) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "code": - err = unpopulate(val, "Code", &a.Code) - delete(rawMsg, key) - case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - -// MarshalJSON implements the json.Marshaller interface for type ErrorResponse. -func (a ErrorResponse) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "error", a.Error) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponse. -func (a *ErrorResponse) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "error": - err = unpopulate(val, "Error", &a.Error) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - -// MarshalJSON implements the json.Marshaller interface for type ErrorResponseError. -func (a ErrorResponseError) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "code", a.Code) - populate(objectMap, "details", a.Details) - populate(objectMap, "innererror", a.Innererror) - populate(objectMap, "message", a.Message) - populate(objectMap, "target", a.Target) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type ErrorResponseError. -func (a *ErrorResponseError) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "code": - err = unpopulate(val, "Code", &a.Code) - delete(rawMsg, key) - case "details": - err = unpopulate(val, "Details", &a.Details) - delete(rawMsg, key) - case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) - delete(rawMsg, key) - case "message": - err = unpopulate(val, "Message", &a.Message) - delete(rawMsg, key) - case "target": - err = unpopulate(val, "Target", &a.Target) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - -// MarshalJSON implements the json.Marshaller interface for type InnerError. -func (a InnerError) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "code", a.Code) - populate(objectMap, "innererror", a.Innererror) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type InnerError. -func (a *InnerError) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "code": - err = unpopulate(val, "Code", &a.Code) - delete(rawMsg, key) - case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - -// MarshalJSON implements the json.Marshaller interface for type InnerErrorInnererror. -func (a InnerErrorInnererror) MarshalJSON() ([]byte, error) { - objectMap := make(map[string]any) - populate(objectMap, "code", a.Code) - populate(objectMap, "innererror", a.Innererror) - return json.Marshal(objectMap) -} - -// UnmarshalJSON implements the json.Unmarshaller interface for type InnerErrorInnererror. -func (a *InnerErrorInnererror) UnmarshalJSON(data []byte) error { - var rawMsg map[string]json.RawMessage - if err := json.Unmarshal(data, &rawMsg); err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - for key, val := range rawMsg { - var err error - switch key { - case "code": - err = unpopulate(val, "Code", &a.Code) - delete(rawMsg, key) - case "innererror": - err = unpopulate(val, "Innererror", &a.Innererror) - delete(rawMsg, key) - } - if err != nil { - return fmt.Errorf("unmarshalling type %T: %v", a, err) - } - } - return nil -} - // MarshalJSON implements the json.Marshaller interface for type ChatChoice. func (c ChatChoice) MarshalJSON() ([]byte, error) { objectMap := make(map[string]any) From 5b886e76c5fb1958a1ff62da410b3462d962855d Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 21:03:32 -0700 Subject: [PATCH 37/62] New functions, new problems. --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index dfb41c004208..951f028e331c 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_1e480fcad7" + "Tag": "go/cognitiveservices/azopenai_e8e86269da" } From 5e05b7f624391267d3ebbec62399874f6d6dc62e Mon Sep 17 00:00:00 2001 From: Richard Park Date: Tue, 13 Jun 2023 23:24:08 -0700 Subject: [PATCH 38/62] Add in a token credential test as well. --- sdk/cognitiveservices/azopenai/client_test.go | 37 ++++++++++++++++--- sdk/cognitiveservices/azopenai/go.mod | 14 +++++-- sdk/cognitiveservices/azopenai/go.sum | 29 ++++++++++++--- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index ed5dba978b93..ca2005c92325 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -9,28 +9,53 @@ package azopenai import ( "context" "log" + "os" "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/internal/recording" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/require" ) func TestClient_GetChatCompletions(t *testing.T) { + deploymentID := "gpt-35-turbo" + + t.Run("WithKeyCredential", func(t *testing.T) { + cred := KeyCredential{APIKey: apiKey} + chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) + require.NoError(t, err) + + testGetChatCompletions(t, chatClient) + }) + + t.Run("WithTokenCredential", func(t *testing.T) { + if os.Getenv("USE_TOKEN_CREDS") != "true" && recording.GetRecordMode() != recording.PlaybackMode { + t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") + t.SkipNow() + } + + dac, err := azidentity.NewDefaultAzureCredential(nil) + require.NoError(t, err) + + chatClient, err := NewClient(endpoint, dac, deploymentID, newClientOptionsForTest(t)) + require.NoError(t, err) + + testGetChatCompletions(t, chatClient) + }) +} + +func testGetChatCompletions(t *testing.T, chatClient *Client) { type args struct { ctx context.Context deploymentID string body ChatCompletionsOptions options *ClientGetChatCompletionsOptions } - cred := KeyCredential{APIKey: apiKey} - deploymentID := "gpt-35-turbo" - chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) - if err != nil { - log.Fatalf("%v", err) - } + tests := []struct { name string client *Client diff --git a/sdk/cognitiveservices/azopenai/go.mod b/sdk/cognitiveservices/azopenai/go.mod index 4573fc73272c..710379f09aa8 100644 --- a/sdk/cognitiveservices/azopenai/go.mod +++ b/sdk/cognitiveservices/azopenai/go.mod @@ -4,6 +4,7 @@ go 1.18 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 github.com/google/go-cmp v0.5.9 github.com/joho/godotenv v1.3.0 @@ -11,11 +12,18 @@ require ( ) require ( - github.com/davecgh/go-spew v1.1.0 // indirect - github.com/dnaeon/go-vcr v1.1.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dnaeon/go-vcr v1.2.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/crypto v0.7.0 // indirect golang.org/x/net v0.8.0 // indirect + golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/sdk/cognitiveservices/azopenai/go.sum b/sdk/cognitiveservices/azopenai/go.sum index 80d64785f771..d3d94d1ae54a 100644 --- a/sdk/cognitiveservices/azopenai/go.sum +++ b/sdk/cognitiveservices/azopenai/go.sum @@ -1,29 +1,48 @@ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1 h1:SEy2xmstIphdPwNBUi7uhvjyjhVKISfwjfOJmuy7kg4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d94ce3b05fee7d67f6454b5d632b929dc51b9cdf Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 10:14:45 -0700 Subject: [PATCH 39/62] Remove unused serviceversions enum. --- sdk/cognitiveservices/azopenai/autorest.md | 7 +++++++ sdk/cognitiveservices/azopenai/constants.go | 15 --------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index e1eb8472edd4..3373332529e1 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -132,4 +132,11 @@ directive: - from: models_serde.go where: $ transform: return $.replace(/(?:\/\/.*\s)?func \(\w \*?(?:ErrorResponse|ErrorResponseError|InnerError|InnerErrorInnererror)\).*\{\s(?:.+\s)+\}\s/g, ""); + + - from: constants.go + where: $ + transform: >- + return $.replace( + /type ServiceAPIVersions string.+PossibleServiceAPIVersionsValues.+?\n}/gs, + "") ``` diff --git a/sdk/cognitiveservices/azopenai/constants.go b/sdk/cognitiveservices/azopenai/constants.go index a54c966c3d37..b35f00d25a9a 100644 --- a/sdk/cognitiveservices/azopenai/constants.go +++ b/sdk/cognitiveservices/azopenai/constants.go @@ -43,18 +43,3 @@ func PossibleCompletionsFinishReasonValues() []CompletionsFinishReason { CompletionsFinishReasonStop, } } - -type ServiceAPIVersions string - -const ( - ServiceAPIVersionsTwoThousandTwentyThree0315Preview ServiceAPIVersions = "2023-03-15-preview" - ServiceAPIVersionsTwoThousandTwentyTwo1201 ServiceAPIVersions = "2022-12-01" -) - -// PossibleServiceAPIVersionsValues returns the possible values for the ServiceAPIVersions const type. -func PossibleServiceAPIVersionsValues() []ServiceAPIVersions { - return []ServiceAPIVersions{ - ServiceAPIVersionsTwoThousandTwentyThree0315Preview, - ServiceAPIVersionsTwoThousandTwentyTwo1201, - } -} From 0c445863ec739b732c5301cb36d918de39555a74 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 10:28:23 -0700 Subject: [PATCH 40/62] Remove the entire "Client" prefix. WE ARE THE CLIENT. --- sdk/cognitiveservices/azopenai/autorest.md | 8 +++ sdk/cognitiveservices/azopenai/client.go | 54 +++++++++---------- sdk/cognitiveservices/azopenai/client_test.go | 18 +++---- .../azopenai/custom_client.go | 2 +- sdk/cognitiveservices/azopenai/models.go | 12 ++--- .../azopenai/response_types.go | 12 ++--- 6 files changed, 57 insertions(+), 49 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/autorest.md b/sdk/cognitiveservices/azopenai/autorest.md index 3373332529e1..fff153b3f8c2 100644 --- a/sdk/cognitiveservices/azopenai/autorest.md +++ b/sdk/cognitiveservices/azopenai/autorest.md @@ -139,4 +139,12 @@ directive: return $.replace( /type ServiceAPIVersions string.+PossibleServiceAPIVersionsValues.+?\n}/gs, "") + + # delete client name prefix from method options and response types + - from: + - client.go + - models.go + - response_types.go + where: $ + transform: return $.replace(/Client(\w+)((?:Options|Response))/g, "$1$2"); ``` diff --git a/sdk/cognitiveservices/azopenai/client.go b/sdk/cognitiveservices/azopenai/client.go index 7bde66a202d0..cd7237df5032 100644 --- a/sdk/cognitiveservices/azopenai/client.go +++ b/sdk/cognitiveservices/azopenai/client.go @@ -29,27 +29,27 @@ type Client struct { // If the operation fails it returns an *azcore.ResponseError type. // // Generated from API version 2023-03-15-preview -// - options - ClientGetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. -func (client *Client) GetChatCompletions(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (ClientGetChatCompletionsResponse, error) { +// - options - GetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. +func (client *Client) GetChatCompletions(ctx context.Context, body ChatCompletionsOptions, options *GetChatCompletionsOptions) (GetChatCompletionsResponse, error) { var err error req, err := client.getChatCompletionsCreateRequest(ctx, body, options) if err != nil { - return ClientGetChatCompletionsResponse{}, err + return GetChatCompletionsResponse{}, err } httpResp, err := client.internal.Pipeline().Do(req) if err != nil { - return ClientGetChatCompletionsResponse{}, err + return GetChatCompletionsResponse{}, err } if !runtime.HasStatusCode(httpResp, http.StatusOK) { err = runtime.NewResponseError(httpResp) - return ClientGetChatCompletionsResponse{}, err + return GetChatCompletionsResponse{}, err } resp, err := client.getChatCompletionsHandleResponse(httpResp) return resp, err } // getChatCompletionsCreateRequest creates the GetChatCompletions request. -func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body ChatCompletionsOptions, options *ClientGetChatCompletionsOptions) (*policy.Request, error) { +func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body ChatCompletionsOptions, options *GetChatCompletionsOptions) (*policy.Request, error) { urlPath := "chat/completions" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { @@ -66,10 +66,10 @@ func (client *Client) getChatCompletionsCreateRequest(ctx context.Context, body } // getChatCompletionsHandleResponse handles the GetChatCompletions response. -func (client *Client) getChatCompletionsHandleResponse(resp *http.Response) (ClientGetChatCompletionsResponse, error) { - result := ClientGetChatCompletionsResponse{} +func (client *Client) getChatCompletionsHandleResponse(resp *http.Response) (GetChatCompletionsResponse, error) { + result := GetChatCompletionsResponse{} if err := runtime.UnmarshalAsJSON(resp, &result.ChatCompletions); err != nil { - return ClientGetChatCompletionsResponse{}, err + return GetChatCompletionsResponse{}, err } return result, nil } @@ -79,27 +79,27 @@ func (client *Client) getChatCompletionsHandleResponse(resp *http.Response) (Cli // If the operation fails it returns an *azcore.ResponseError type. // // Generated from API version 2023-03-15-preview -// - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. -func (client *Client) GetCompletions(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (ClientGetCompletionsResponse, error) { +// - options - GetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +func (client *Client) GetCompletions(ctx context.Context, body CompletionsOptions, options *GetCompletionsOptions) (GetCompletionsResponse, error) { var err error req, err := client.getCompletionsCreateRequest(ctx, body, options) if err != nil { - return ClientGetCompletionsResponse{}, err + return GetCompletionsResponse{}, err } httpResp, err := client.internal.Pipeline().Do(req) if err != nil { - return ClientGetCompletionsResponse{}, err + return GetCompletionsResponse{}, err } if !runtime.HasStatusCode(httpResp, http.StatusOK) { err = runtime.NewResponseError(httpResp) - return ClientGetCompletionsResponse{}, err + return GetCompletionsResponse{}, err } resp, err := client.getCompletionsHandleResponse(httpResp) return resp, err } // getCompletionsCreateRequest creates the GetCompletions request. -func (client *Client) getCompletionsCreateRequest(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsOptions) (*policy.Request, error) { +func (client *Client) getCompletionsCreateRequest(ctx context.Context, body CompletionsOptions, options *GetCompletionsOptions) (*policy.Request, error) { urlPath := "completions" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { @@ -116,10 +116,10 @@ func (client *Client) getCompletionsCreateRequest(ctx context.Context, body Comp } // getCompletionsHandleResponse handles the GetCompletions response. -func (client *Client) getCompletionsHandleResponse(resp *http.Response) (ClientGetCompletionsResponse, error) { - result := ClientGetCompletionsResponse{} +func (client *Client) getCompletionsHandleResponse(resp *http.Response) (GetCompletionsResponse, error) { + result := GetCompletionsResponse{} if err := runtime.UnmarshalAsJSON(resp, &result.Completions); err != nil { - return ClientGetCompletionsResponse{}, err + return GetCompletionsResponse{}, err } return result, nil } @@ -128,27 +128,27 @@ func (client *Client) getCompletionsHandleResponse(resp *http.Response) (ClientG // If the operation fails it returns an *azcore.ResponseError type. // // Generated from API version 2023-03-15-preview -// - options - ClientGetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. -func (client *Client) GetEmbeddings(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (ClientGetEmbeddingsResponse, error) { +// - options - GetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. +func (client *Client) GetEmbeddings(ctx context.Context, body EmbeddingsOptions, options *GetEmbeddingsOptions) (GetEmbeddingsResponse, error) { var err error req, err := client.getEmbeddingsCreateRequest(ctx, body, options) if err != nil { - return ClientGetEmbeddingsResponse{}, err + return GetEmbeddingsResponse{}, err } httpResp, err := client.internal.Pipeline().Do(req) if err != nil { - return ClientGetEmbeddingsResponse{}, err + return GetEmbeddingsResponse{}, err } if !runtime.HasStatusCode(httpResp, http.StatusOK) { err = runtime.NewResponseError(httpResp) - return ClientGetEmbeddingsResponse{}, err + return GetEmbeddingsResponse{}, err } resp, err := client.getEmbeddingsHandleResponse(httpResp) return resp, err } // getEmbeddingsCreateRequest creates the GetEmbeddings request. -func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body EmbeddingsOptions, options *ClientGetEmbeddingsOptions) (*policy.Request, error) { +func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body EmbeddingsOptions, options *GetEmbeddingsOptions) (*policy.Request, error) { urlPath := "embeddings" req, err := runtime.NewRequest(ctx, http.MethodPost, runtime.JoinPaths(client.endpoint, urlPath)) if err != nil { @@ -165,10 +165,10 @@ func (client *Client) getEmbeddingsCreateRequest(ctx context.Context, body Embed } // getEmbeddingsHandleResponse handles the GetEmbeddings response. -func (client *Client) getEmbeddingsHandleResponse(resp *http.Response) (ClientGetEmbeddingsResponse, error) { - result := ClientGetEmbeddingsResponse{} +func (client *Client) getEmbeddingsHandleResponse(resp *http.Response) (GetEmbeddingsResponse, error) { + result := GetEmbeddingsResponse{} if err := runtime.UnmarshalAsJSON(resp, &result.Embeddings); err != nil { - return ClientGetEmbeddingsResponse{}, err + return GetEmbeddingsResponse{}, err } return result, nil } diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index ca2005c92325..e8393823697a 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -53,14 +53,14 @@ func testGetChatCompletions(t *testing.T, chatClient *Client) { ctx context.Context deploymentID string body ChatCompletionsOptions - options *ClientGetChatCompletionsOptions + options *GetChatCompletionsOptions } tests := []struct { name string client *Client args args - want ClientGetChatCompletionsResponse + want GetChatCompletionsResponse wantErr bool }{ { @@ -81,7 +81,7 @@ func testGetChatCompletions(t *testing.T, chatClient *Client) { }, options: nil, }, - want: ClientGetChatCompletionsResponse{ + want: GetChatCompletionsResponse{ ChatCompletions: ChatCompletions{ Choices: []*ChatChoice{ { @@ -156,7 +156,7 @@ func TestClient_GetCompletions(t *testing.T) { ctx context.Context deploymentID string body CompletionsOptions - options *ClientGetCompletionsOptions + options *GetCompletionsOptions } cred := KeyCredential{APIKey: apiKey} deploymentID := "text-davinci-003" @@ -168,7 +168,7 @@ func TestClient_GetCompletions(t *testing.T) { name string client *Client args args - want ClientGetCompletionsResponse + want GetCompletionsResponse wantErr bool }{ { @@ -184,7 +184,7 @@ func TestClient_GetCompletions(t *testing.T) { }, options: nil, }, - want: ClientGetCompletionsResponse{ + want: GetCompletionsResponse{ Completions: Completions{ Choices: []*Choice{ { @@ -224,7 +224,7 @@ func TestClient_GetEmbeddings(t *testing.T) { ctx context.Context deploymentID string body EmbeddingsOptions - options *ClientGetEmbeddingsOptions + options *GetEmbeddingsOptions } deploymentID := "embedding" cred := KeyCredential{APIKey: apiKey} @@ -237,7 +237,7 @@ func TestClient_GetEmbeddings(t *testing.T) { name string client *Client args args - want ClientGetEmbeddingsResponse + want GetEmbeddingsResponse wantErr bool }{ { @@ -252,7 +252,7 @@ func TestClient_GetEmbeddings(t *testing.T) { }, options: nil, }, - want: ClientGetEmbeddingsResponse{ + want: GetEmbeddingsResponse{ Embeddings{ Data: []*EmbeddingItem{}, Usage: &EmbeddingsUsage{}, diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 435e9e0f2616..55418896c007 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -138,7 +138,7 @@ func (o streamCompletionsOptions) MarshalJSON() ([]byte, error) { // If the operation fails it returns an *azcore.ResponseError type. // - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsStreamOptions) (GetCompletionsStreamResponse, error) { - req, err := client.getCompletionsCreateRequest(ctx, CompletionsOptions{}, &ClientGetCompletionsOptions{}) + req, err := client.getCompletionsCreateRequest(ctx, CompletionsOptions{}, &GetCompletionsOptions{}) var cer GetCompletionsStreamResponse if err != nil { return cer, err diff --git a/sdk/cognitiveservices/azopenai/models.go b/sdk/cognitiveservices/azopenai/models.go index 5275f85ae42e..42c0ddb088b3 100644 --- a/sdk/cognitiveservices/azopenai/models.go +++ b/sdk/cognitiveservices/azopenai/models.go @@ -160,18 +160,18 @@ type ChoiceLogprobs struct { TopLogprobs []any } -// ClientGetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. -type ClientGetChatCompletionsOptions struct { +// GetChatCompletionsOptions contains the optional parameters for the Client.GetChatCompletions method. +type GetChatCompletionsOptions struct { // placeholder for future optional parameters } -// ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. -type ClientGetCompletionsOptions struct { +// GetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +type GetCompletionsOptions struct { // placeholder for future optional parameters } -// ClientGetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. -type ClientGetEmbeddingsOptions struct { +// GetEmbeddingsOptions contains the optional parameters for the Client.GetEmbeddings method. +type GetEmbeddingsOptions struct { // placeholder for future optional parameters } diff --git a/sdk/cognitiveservices/azopenai/response_types.go b/sdk/cognitiveservices/azopenai/response_types.go index a7127ec3f522..8847d0af3da3 100644 --- a/sdk/cognitiveservices/azopenai/response_types.go +++ b/sdk/cognitiveservices/azopenai/response_types.go @@ -8,17 +8,17 @@ package azopenai -// ClientGetChatCompletionsResponse contains the response from method Client.GetChatCompletions. -type ClientGetChatCompletionsResponse struct { +// GetChatCompletionsResponse contains the response from method Client.GetChatCompletions. +type GetChatCompletionsResponse struct { ChatCompletions } -// ClientGetCompletionsResponse contains the response from method Client.GetCompletions. -type ClientGetCompletionsResponse struct { +// GetCompletionsResponse contains the response from method Client.GetCompletions. +type GetCompletionsResponse struct { Completions } -// ClientGetEmbeddingsResponse contains the response from method Client.GetEmbeddings. -type ClientGetEmbeddingsResponse struct { +// GetEmbeddingsResponse contains the response from method Client.GetEmbeddings. +type GetEmbeddingsResponse struct { Embeddings } From 94a3fd10478d928bd8b3f364ff0729853a1aa88e Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 11:41:21 -0700 Subject: [PATCH 41/62] Dang it, boolean logic. --- sdk/cognitiveservices/azopenai/client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index e8393823697a..de3f185f6d3e 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -33,7 +33,7 @@ func TestClient_GetChatCompletions(t *testing.T) { }) t.Run("WithTokenCredential", func(t *testing.T) { - if os.Getenv("USE_TOKEN_CREDS") != "true" && recording.GetRecordMode() != recording.PlaybackMode { + if os.Getenv("USE_TOKEN_CREDS") != "true" || recording.GetRecordMode() != recording.PlaybackMode { t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") t.SkipNow() } From b54d9b29e0020b5aee917a50e58f6826feba5ea7 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 14:32:57 -0700 Subject: [PATCH 42/62] Updating tests. --- sdk/cognitiveservices/azopenai/assets.json | 2 +- sdk/cognitiveservices/azopenai/client_test.go | 27 ++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index 951f028e331c..b0fb7b144c43 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_e8e86269da" + "Tag": "go/cognitiveservices/azopenai_5d4bf2a85d" } diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index de3f185f6d3e..10e878571827 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -13,6 +13,7 @@ import ( "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore" + "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/internal/recording" @@ -31,21 +32,33 @@ func TestClient_GetChatCompletions(t *testing.T) { testGetChatCompletions(t, chatClient) }) +} - t.Run("WithTokenCredential", func(t *testing.T) { - if os.Getenv("USE_TOKEN_CREDS") != "true" || recording.GetRecordMode() != recording.PlaybackMode { +func TestClient_GetChatCompletions_DefaultAzureCredential(t *testing.T) { + if recording.GetRecordMode() != recording.PlaybackMode { + if os.Getenv("USE_TOKEN_CREDS") != "true" { t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") t.SkipNow() } + } - dac, err := azidentity.NewDefaultAzureCredential(nil) - require.NoError(t, err) + deploymentID := "gpt-35-turbo" - chatClient, err := NewClient(endpoint, dac, deploymentID, newClientOptionsForTest(t)) - require.NoError(t, err) + recordingTransporter := newRecordingTransporter(t) - testGetChatCompletions(t, chatClient) + dac, err := azidentity.NewDefaultAzureCredential(&azidentity.DefaultAzureCredentialOptions{ + ClientOptions: policy.ClientOptions{ + Transport: recordingTransporter, + }, + }) + require.NoError(t, err) + + chatClient, err := NewClient(endpoint, dac, deploymentID, &ClientOptions{ + ClientOptions: policy.ClientOptions{Transport: recordingTransporter}, }) + require.NoError(t, err) + + testGetChatCompletions(t, chatClient) } func testGetChatCompletions(t *testing.T, chatClient *Client) { From a8f319a0177ceebe168767a13c582df7df24b1c2 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 14:35:57 -0700 Subject: [PATCH 43/62] Adding current coverage --- eng/config.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/config.json b/eng/config.json index 18dbd410be92..25fd0c91d5ff 100644 --- a/eng/config.json +++ b/eng/config.json @@ -36,6 +36,10 @@ "Name": "azfile", "CoverageGoal": 0.75 }, + { + "Name": "azopenai", + "CoverageGoal": 0.47 + }, { "Name": "aztemplate", "CoverageGoal": 0.50 @@ -98,4 +102,4 @@ "CoverageGoal": 0.80 } ] -} +} \ No newline at end of file From 0e26d921f8b7308a79894a2c8b2bbb07527a1820 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 16:58:54 -0700 Subject: [PATCH 44/62] Updated test, skip in playback for now. --- eng/config.json | 2 +- sdk/cognitiveservices/azopenai/client_test.go | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/eng/config.json b/eng/config.json index 25fd0c91d5ff..dc6ba5ecdeea 100644 --- a/eng/config.json +++ b/eng/config.json @@ -38,7 +38,7 @@ }, { "Name": "azopenai", - "CoverageGoal": 0.47 + "CoverageGoal": 0.45 }, { "Name": "aztemplate", diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 10e878571827..3a364178882c 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -35,11 +35,14 @@ func TestClient_GetChatCompletions(t *testing.T) { } func TestClient_GetChatCompletions_DefaultAzureCredential(t *testing.T) { - if recording.GetRecordMode() != recording.PlaybackMode { - if os.Getenv("USE_TOKEN_CREDS") != "true" { - t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") - t.SkipNow() - } + if recording.GetRecordMode() == recording.PlaybackMode { + t.Logf("Not running this test in playback (for now)") + t.SkipNow() + } + + if os.Getenv("USE_TOKEN_CREDS") != "true" { + t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") + t.SkipNow() } deploymentID := "gpt-35-turbo" @@ -70,10 +73,11 @@ func testGetChatCompletions(t *testing.T, chatClient *Client) { } tests := []struct { - name string - client *Client - args args - want GetChatCompletionsResponse + name string + client *Client + args args + want GetChatCompletionsResponse + wantErr bool }{ { From 15ed993832fae85a7158006a3b0c4a3f4e17d035 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 19:15:29 -0700 Subject: [PATCH 45/62] Hit the OpenAI endpoint for chat completions. (for recordings and, optionally, for use with live tests) --- sdk/cognitiveservices/azopenai/assets.json | 2 +- .../azopenai/client_shared_test.go | 28 +++++++++++++-- sdk/cognitiveservices/azopenai/client_test.go | 34 ++++++++++++------- .../azopenai/custom_client.go | 28 +++++++++------ .../azopenai/custom_models.go | 4 +-- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index b0fb7b144c43..8ab0c5f15e42 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_5d4bf2a85d" + "Tag": "go/cognitiveservices/azopenai_d15b530c4b" } diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index 631f692a2906..c353a2500757 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -6,6 +6,7 @@ package azopenai import ( "fmt" "os" + "strings" "testing" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" @@ -15,8 +16,10 @@ import ( ) var ( - endpoint string - apiKey string + endpoint string + apiKey string + openAIKey string + openAIEndpoint string ) const fakeEndpoint = "https://recordedhost/" @@ -26,6 +29,8 @@ func init() { if recording.GetRecordMode() == recording.PlaybackMode { endpoint = fakeEndpoint apiKey = fakeAPIKey + openAIKey = fakeAPIKey + openAIEndpoint = fakeEndpoint } else { if err := godotenv.Load(); err != nil { fmt.Printf("Failed to load .env file: %s\n", err) @@ -33,7 +38,21 @@ func init() { } endpoint = os.Getenv("AOAI_ENDPOINT") + + if !strings.HasSuffix(endpoint, "/") { + // (this just makes recording replacement easier) + endpoint += "/" + } + apiKey = os.Getenv("AOAI_API_KEY") + openAIKey = os.Getenv("OPENAI_API_KEY") + + openAIEndpoint = os.Getenv("OPENAI_ENDPOINT") + + if !strings.HasSuffix(openAIEndpoint, "/") { + // (this just makes recording replacement easier) + openAIEndpoint += "/" + } } } @@ -51,6 +70,11 @@ func newRecordingTransporter(t *testing.T) policy.Transporter { // "RequestUri": "https://openai-shared.openai.azure.com/openai/deployments/text-davinci-003/completions?api-version=2023-03-15-preview", err = recording.AddURISanitizer(fakeEndpoint, endpoint, nil) require.NoError(t, err) + + if openAIEndpoint != "" { + err = recording.AddURISanitizer(fakeEndpoint, openAIEndpoint, nil) + require.NoError(t, err) + } } t.Cleanup(func() { diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 3a364178882c..7d5998c560b2 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -25,24 +25,20 @@ import ( func TestClient_GetChatCompletions(t *testing.T) { deploymentID := "gpt-35-turbo" - t.Run("WithKeyCredential", func(t *testing.T) { - cred := KeyCredential{APIKey: apiKey} - chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) - require.NoError(t, err) + cred := KeyCredential{APIKey: apiKey} + chatClient, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) + require.NoError(t, err) - testGetChatCompletions(t, chatClient) - }) + testGetChatCompletions(t, chatClient, deploymentID) } func TestClient_GetChatCompletions_DefaultAzureCredential(t *testing.T) { if recording.GetRecordMode() == recording.PlaybackMode { - t.Logf("Not running this test in playback (for now)") - t.SkipNow() + t.Skipf("Not running this test in playback (for now)") } if os.Getenv("USE_TOKEN_CREDS") != "true" { - t.Logf("USE_TOKEN_CREDS is not true, disabling token credential tests") - t.SkipNow() + t.Skipf("USE_TOKEN_CREDS is not true, disabling token credential tests") } deploymentID := "gpt-35-turbo" @@ -61,10 +57,21 @@ func TestClient_GetChatCompletions_DefaultAzureCredential(t *testing.T) { }) require.NoError(t, err) - testGetChatCompletions(t, chatClient) + testGetChatCompletions(t, chatClient, deploymentID) +} + +func TestClient_OpenAI(t *testing.T) { + if openAIKey == "" { + t.Skipf("OPENAI_API_KEY not defined, skipping OpenAI public endpoint test") + } + + chatClient, err := NewClientForOpenAI(openAIEndpoint, KeyCredential{APIKey: openAIKey}, newClientOptionsForTest(t)) + require.NoError(t, err) + + testGetChatCompletions(t, chatClient, "gpt-3.5-turbo") } -func testGetChatCompletions(t *testing.T, chatClient *Client) { +func testGetChatCompletions(t *testing.T, chatClient *Client, modelOrDeployment string) { type args struct { ctx context.Context deploymentID string @@ -85,7 +92,7 @@ func testGetChatCompletions(t *testing.T, chatClient *Client) { client: chatClient, args: args{ ctx: context.TODO(), - deploymentID: "gpt-35-turbo", + deploymentID: modelOrDeployment, body: ChatCompletionsOptions{ Messages: []*ChatMessage{ { @@ -95,6 +102,7 @@ func testGetChatCompletions(t *testing.T, chatClient *Client) { }, MaxTokens: to.Ptr(int32(1024)), Temperature: to.Ptr(float32(0.0)), + Model: &modelOrDeployment, }, options: nil, }, diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 55418896c007..982d33dada86 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -136,25 +136,31 @@ func (o streamCompletionsOptions) MarshalJSON() ([]byte, error) { // GetCompletionsStream - Return the completions for a given prompt as a sequence of events. // If the operation fails it returns an *azcore.ResponseError type. -// - options - ClientGetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. -func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *ClientGetCompletionsStreamOptions) (GetCompletionsStreamResponse, error) { +// - options - GetCompletionsOptions contains the optional parameters for the Client.GetCompletions method. +func (client *Client) GetCompletionsStream(ctx context.Context, body CompletionsOptions, options *GetCompletionsStreamOptions) (GetCompletionsStreamResponse, error) { req, err := client.getCompletionsCreateRequest(ctx, CompletionsOptions{}, &GetCompletionsOptions{}) - var cer GetCompletionsStreamResponse + if err != nil { - return cer, err + return GetCompletionsStreamResponse{}, err } - err = runtime.MarshalAsJSON(req, streamCompletionsOptions{body, true}) - if err != nil { - return cer, err + + if err := runtime.MarshalAsJSON(req, streamCompletionsOptions{body, true}); err != nil { + return GetCompletionsStreamResponse{}, err } + runtime.SkipBodyDownload(req) + resp, err := client.internal.Pipeline().Do(req) + if err != nil { - return cer, err + return GetCompletionsStreamResponse{}, err } + if !runtime.HasStatusCode(resp, http.StatusOK) { - return cer, runtime.NewResponseError(resp) + return GetCompletionsStreamResponse{}, runtime.NewResponseError(resp) } - cer.Events = newEventReader[Completions](resp.Body) - return cer, nil + + return GetCompletionsStreamResponse{ + Events: newEventReader[Completions](resp.Body), + }, nil } diff --git a/sdk/cognitiveservices/azopenai/custom_models.go b/sdk/cognitiveservices/azopenai/custom_models.go index afe028d6a9f8..8213d9f4d6a5 100644 --- a/sdk/cognitiveservices/azopenai/custom_models.go +++ b/sdk/cognitiveservices/azopenai/custom_models.go @@ -8,8 +8,8 @@ package azopenai // Models for methods that return streaming response -// ClientGetCompletionsStreamOptions contains the optional parameters for the Client.GetCompletions method. -type ClientGetCompletionsStreamOptions struct { +// GetCompletionsStreamOptions contains the optional parameters for the Client.GetCompletions method. +type GetCompletionsStreamOptions struct { // placeholder for future optional parameters } From 4bfc4b2f05e3f216e2cd99a9a5b02e69fdf31173 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 22:16:45 -0700 Subject: [PATCH 46/62] Test for getting back an error from OpenAI directly. --- sdk/cognitiveservices/azopenai/client_test.go | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 7d5998c560b2..b7117fe684ef 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -9,6 +9,7 @@ package azopenai import ( "context" "log" + "net/http" "os" "testing" @@ -71,6 +72,30 @@ func TestClient_OpenAI(t *testing.T) { testGetChatCompletions(t, chatClient, "gpt-3.5-turbo") } +func TestClient_OpenAI_InvalidModel(t *testing.T) { + if openAIKey == "" { + t.Skipf("OPENAI_API_KEY not defined, skipping OpenAI public endpoint test") + } + + chatClient, err := NewClientForOpenAI(openAIEndpoint, KeyCredential{APIKey: openAIKey}, newClientOptionsForTest(t)) + require.NoError(t, err) + + _, err = chatClient.GetChatCompletions(context.Background(), ChatCompletionsOptions{ + Messages: []*ChatMessage{ + { + Role: to.Ptr(ChatRoleSystem), + Content: to.Ptr("hello"), + }, + }, + Model: to.Ptr("non-existent-model"), + }, nil) + + var respErr *azcore.ResponseError + require.ErrorAs(t, err, &respErr) + require.Equal(t, http.StatusNotFound, respErr.StatusCode) + require.Contains(t, respErr.Error(), "The model `non-existent-model` does not exist") +} + func testGetChatCompletions(t *testing.T, chatClient *Client, modelOrDeployment string) { type args struct { ctx context.Context From 08e85f4e2a290dcb2a316a225bdc4583ed365d34 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Wed, 14 Jun 2023 22:49:50 -0700 Subject: [PATCH 47/62] Some more tests. --- sdk/cognitiveservices/azopenai/assets.json | 2 +- sdk/cognitiveservices/azopenai/client_test.go | 57 +++++++++++-------- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index 8ab0c5f15e42..98ecb7171058 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_d15b530c4b" + "Tag": "go/cognitiveservices/azopenai_87c0306011" } diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index b7117fe684ef..9b3c25b0e657 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -61,26 +61,15 @@ func TestClient_GetChatCompletions_DefaultAzureCredential(t *testing.T) { testGetChatCompletions(t, chatClient, deploymentID) } -func TestClient_OpenAI(t *testing.T) { - if openAIKey == "" { - t.Skipf("OPENAI_API_KEY not defined, skipping OpenAI public endpoint test") - } - - chatClient, err := NewClientForOpenAI(openAIEndpoint, KeyCredential{APIKey: openAIKey}, newClientOptionsForTest(t)) - require.NoError(t, err) - +func TestClient_OpenAI_GetChatCompletions(t *testing.T) { + chatClient := newOpenAIClientForTest(t) testGetChatCompletions(t, chatClient, "gpt-3.5-turbo") } func TestClient_OpenAI_InvalidModel(t *testing.T) { - if openAIKey == "" { - t.Skipf("OPENAI_API_KEY not defined, skipping OpenAI public endpoint test") - } + chatClient := newOpenAIClientForTest(t) - chatClient, err := NewClientForOpenAI(openAIEndpoint, KeyCredential{APIKey: openAIKey}, newClientOptionsForTest(t)) - require.NoError(t, err) - - _, err = chatClient.GetChatCompletions(context.Background(), ChatCompletionsOptions{ + _, err := chatClient.GetChatCompletions(context.Background(), ChatCompletionsOptions{ Messages: []*ChatMessage{ { Role: to.Ptr(ChatRoleSystem), @@ -269,19 +258,30 @@ func TestClient_GetCompletions(t *testing.T) { } } +func TestClient_OpenAI_GetEmbeddings(t *testing.T) { + client := newOpenAIClientForTest(t) + modelID := "text-similarity-curie-001" + testGetEmbeddings(t, client, modelID) +} + func TestClient_GetEmbeddings(t *testing.T) { + // model deployment points to `text-similarity-curie-001` + deploymentID := "embedding" + + cred := KeyCredential{APIKey: apiKey} + client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) + require.NoError(t, err) + + testGetEmbeddings(t, client, deploymentID) +} + +func testGetEmbeddings(t *testing.T, client *Client, modelOrDeploymentID string) { type args struct { ctx context.Context deploymentID string body EmbeddingsOptions options *GetEmbeddingsOptions } - deploymentID := "embedding" - cred := KeyCredential{APIKey: apiKey} - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) - if err != nil { - log.Fatalf("%v", err) - } tests := []struct { name string @@ -295,10 +295,10 @@ func TestClient_GetEmbeddings(t *testing.T) { client: client, args: args{ ctx: context.TODO(), - deploymentID: "embedding", + deploymentID: modelOrDeploymentID, body: EmbeddingsOptions{ Input: []byte("\"Your text string goes here\""), - Model: to.Ptr("text-similarity-curie-001"), + Model: &modelOrDeploymentID, }, options: nil, }, @@ -325,3 +325,14 @@ func TestClient_GetEmbeddings(t *testing.T) { }) } } + +func newOpenAIClientForTest(t *testing.T) *Client { + if openAIKey == "" { + t.Skipf("OPENAI_API_KEY not defined, skipping OpenAI public endpoint test") + } + + chatClient, err := NewClientForOpenAI(openAIEndpoint, KeyCredential{APIKey: openAIKey}, newClientOptionsForTest(t)) + require.NoError(t, err) + + return chatClient +} From 77f56cceee3906da1b8179b2d1c449af8ef5d6f0 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 15 Jun 2023 10:41:40 -0700 Subject: [PATCH 48/62] Upated doc comment and field name from Jeff's suggestion. --- sdk/cognitiveservices/azopenai/custom_client.go | 2 +- sdk/cognitiveservices/azopenai/custom_client_test.go | 2 +- sdk/cognitiveservices/azopenai/custom_models.go | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index 982d33dada86..bc7dede71e06 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -161,6 +161,6 @@ func (client *Client) GetCompletionsStream(ctx context.Context, body Completions } return GetCompletionsStreamResponse{ - Events: newEventReader[Completions](resp.Body), + CompletionsStream: newEventReader[Completions](resp.Body), }, nil } diff --git a/sdk/cognitiveservices/azopenai/custom_client_test.go b/sdk/cognitiveservices/azopenai/custom_client_test.go index 50915cfc9d57..50a0088f0202 100644 --- a/sdk/cognitiveservices/azopenai/custom_client_test.go +++ b/sdk/cognitiveservices/azopenai/custom_client_test.go @@ -93,7 +93,7 @@ func TestClient_GetCompletionsStream(t *testing.T) { t.Errorf("Client.GetCompletionsStream() error = %v", err) return } - reader := response.Events + reader := response.CompletionsStream defer reader.Close() var sb strings.Builder diff --git a/sdk/cognitiveservices/azopenai/custom_models.go b/sdk/cognitiveservices/azopenai/custom_models.go index 8213d9f4d6a5..fb320bebfb02 100644 --- a/sdk/cognitiveservices/azopenai/custom_models.go +++ b/sdk/cognitiveservices/azopenai/custom_models.go @@ -15,8 +15,6 @@ type GetCompletionsStreamOptions struct { // GetCompletionsStreamResponse is the response from [GetCompletionsStream]. type GetCompletionsStreamResponse struct { - // REQUIRED; An EventReader to obtain the streaming completions choices associated with this completions response. - // Generally, n choices are generated per provided prompt with a default value of 1. Token limits and other settings - // may limit the number of choices generated. - Events *EventReader[Completions] + // CompletionsStream returns the stream of completions. Token limits and other settings may limit the number of completions returned by the service. + CompletionsStream *EventReader[Completions] } From 69eb508d74925e7dda653faef7f77508de86c536 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 15 Jun 2023 12:00:11 -0700 Subject: [PATCH 49/62] Adding client creation examples --- .../azopenai/examples_client_test.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 sdk/cognitiveservices/azopenai/examples_client_test.go diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go new file mode 100644 index 000000000000..f0cf54efac29 --- /dev/null +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +package azopenai_test + +import ( + "github.com/Azure/azure-sdk-for-go/sdk/azidentity" + "github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" +) + +func ExampleNewClientForOpenAI() { + keyCredential := azopenai.KeyCredential{ + APIKey: "open-ai-apikey", + } + + client, err := azopenai.NewClientForOpenAI("https://api.openai.com/v1", keyCredential, nil) + + if err != nil { + panic(err) + } + + _ = client +} + +func ExampleNewClient() { + dac, err := azidentity.NewDefaultAzureCredential(nil) + + if err != nil { + panic(err) + } + + modelDeploymentID := "model deployment ID" + client, err := azopenai.NewClient("https://.openai.azure.com", dac, modelDeploymentID, nil) + + if err != nil { + panic(err) + } + + _ = client +} + +func ExampleNewClientWithKeyCredential() { + keyCredential := azopenai.KeyCredential{ + APIKey: "Azure OpenAI apikey", + } + + modelDeploymentID := "model deployment ID" + client, err := azopenai.NewClientWithKeyCredential("https://.openai.azure.com", keyCredential, modelDeploymentID, nil) + + if err != nil { + panic(err) + } + + _ = client +} From 7f6cf7811dbfd07196cd424f004c56bcb0e2213f Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 15 Jun 2023 12:06:22 -0700 Subject: [PATCH 50/62] Update sdk/cognitiveservices/azopenai/CHANGELOG.md Co-authored-by: Rick Winter --- sdk/cognitiveservices/azopenai/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/CHANGELOG.md b/sdk/cognitiveservices/azopenai/CHANGELOG.md index 077c60d77c60..c00ce1cf1381 100644 --- a/sdk/cognitiveservices/azopenai/CHANGELOG.md +++ b/sdk/cognitiveservices/azopenai/CHANGELOG.md @@ -2,4 +2,4 @@ ## 0.1.0 (unreleased) -* This is the initial release of the `azopenai` library +* Initial release of the `azopenai` library From a3f593272bf0f03b943bfa8056bc2b66910ea9a4 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 15 Jun 2023 12:06:30 -0700 Subject: [PATCH 51/62] Update eng/config.json Co-authored-by: Rick Winter --- eng/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/config.json b/eng/config.json index dc6ba5ecdeea..d04f536773cd 100644 --- a/eng/config.json +++ b/eng/config.json @@ -102,4 +102,4 @@ "CoverageGoal": 0.80 } ] -} \ No newline at end of file +} From 8417772160af82394e5959c5204c22d6651e70f9 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:08:16 -0700 Subject: [PATCH 52/62] Update sdk/cognitiveservices/azopenai/README.md Co-authored-by: Rick Winter --- sdk/cognitiveservices/azopenai/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index 99578d6e7ce1..418264282163 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -1,6 +1,8 @@ # Azure OpenAI client module for Go -The Azure OpenAI client module is used to ... +Azure OpenAI is a managed service that allows developers to deploy, tune, and generate content from OpenAI models on Azure resources. + +The Azure OpenAI client library for GO is an adaptation of OpenAI's REST APIs that provides an idiomatic interface and rich integration with the rest of the Azure SDK ecosystem. [Source code][azopenai_repo] | [Package (pkg.go.dev)][azopenai_pkg_go] | [REST API documentation][openai_rest_docs] | [Product documentation][openai_docs] From 97c14ae4a563930483be5ee2b3a2091f292f4eb3 Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:09:04 -0700 Subject: [PATCH 53/62] Update sdk/cognitiveservices/azopenai/README.md Co-authored-by: Rick Winter --- sdk/cognitiveservices/azopenai/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index 418264282163..6510d08d4a61 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -11,7 +11,8 @@ The Azure OpenAI client library for GO is an adaptation of OpenAI's REST APIs th ### Prerequisites * Go, version 1.18 or higher - [Install Go](https://go.dev/doc/install) -* Azure subscription - [Create a free account][azure_sub] +* [Azure subscription][azure_sub] +* [Azure OpenAI access][azure_openai_access] ### Install the packages From a57e1a6b91fc1ae0cbd9e60248b5dfd60d1d9f6b Mon Sep 17 00:00:00 2001 From: Richard Park <51494936+richardpark-msft@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:09:14 -0700 Subject: [PATCH 54/62] Update sdk/cognitiveservices/azopenai/README.md Co-authored-by: Rick Winter --- sdk/cognitiveservices/azopenai/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/cognitiveservices/azopenai/README.md b/sdk/cognitiveservices/azopenai/README.md index 6510d08d4a61..8b23a1894444 100644 --- a/sdk/cognitiveservices/azopenai/README.md +++ b/sdk/cognitiveservices/azopenai/README.md @@ -93,6 +93,7 @@ comments. +[azure_openai_access]: https://learn.microsoft.com/azure/cognitive-services/openai/overview#how-do-i-get-access-to-azure-openai [azopenai_repo]: https://github.com/Azure/azure-sdk-for-go/tree/main/sdk [azopenai_pkg_go]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk [azure_identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity From 6c50f68664b8932b890cd1d29373150309d632ef Mon Sep 17 00:00:00 2001 From: Richard Park Date: Thu, 15 Jun 2023 13:49:54 -0700 Subject: [PATCH 55/62] Examples update --- .../azopenai/custom_client.go | 18 +++++++++--------- .../azopenai/examples_client_test.go | 6 ++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/custom_client.go b/sdk/cognitiveservices/azopenai/custom_client.go index bc7dede71e06..98780286a11a 100644 --- a/sdk/cognitiveservices/azopenai/custom_client.go +++ b/sdk/cognitiveservices/azopenai/custom_client.go @@ -32,9 +32,9 @@ type ClientOptions struct { azcore.ClientOptions } -// NewClient creates a new instance of Client with the specified values. +// NewClient creates a new instance of Client that connects to an Azure OpenAI endpoint. // - endpoint - Azure OpenAI service endpoint, for example: https://{your-resource-name}.openai.azure.com -// - credential - used to authorize requests. Usually a credential from azidentity. +// - credential - used to authorize requests. Usually a credential from [github.com/Azure/azure-sdk-for-go/sdk/azidentity]. // - deploymentID - the deployment ID of the model to query // - options - client options, pass nil to accept the default values. func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID string, options *ClientOptions) (*Client, error) { @@ -52,12 +52,7 @@ func NewClient(endpoint string, credential azcore.TokenCredential, deploymentID return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil } -func formatAzureOpenAIURL(endpoint, deploymentID string) string { - escapedDeplID := url.PathEscape(deploymentID) - return runtime.JoinPaths(endpoint, "openai", "deployments", escapedDeplID) -} - -// NewClientWithKeyCredential creates a new instance of Client with the specified values. +// NewClientWithKeyCredential creates a new instance of Client that connects to an Azure OpenAI endpoint. // - endpoint - Azure OpenAI service endpoint, for example: https://{your-resource-name}.openai.azure.com // - credential - used to authorize requests with an API Key credential // - deploymentID - the deployment ID of the model to query @@ -77,7 +72,7 @@ func NewClientWithKeyCredential(endpoint string, credential KeyCredential, deplo return &Client{endpoint: fullEndpoint, internal: azcoreClient}, nil } -// NewClientForOpenAI creates a new instance of Client with the specified values. +// NewClientForOpenAI creates a new instance of Client which connects to the public OpenAI endpoint. // - endpoint - OpenAI service endpoint, for example: https://api.openai.com/v1 // - credential - used to authorize requests with an API Key credential // - options - client options, pass nil to accept the default values. @@ -164,3 +159,8 @@ func (client *Client) GetCompletionsStream(ctx context.Context, body Completions CompletionsStream: newEventReader[Completions](resp.Body), }, nil } + +func formatAzureOpenAIURL(endpoint, deploymentID string) string { + escapedDeplID := url.PathEscape(deploymentID) + return runtime.JoinPaths(endpoint, "openai", "deployments", escapedDeplID) +} diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go index f0cf54efac29..1cd3732f160d 100644 --- a/sdk/cognitiveservices/azopenai/examples_client_test.go +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -9,6 +9,8 @@ import ( ) func ExampleNewClientForOpenAI() { + // NOTE: this constructor creates a client that connects to the public OpenAI endpoint. + // To connect to an Azure OpenAI endpoint, use azopenai.NewClient() or azopenai.NewClientWithyKeyCredential. keyCredential := azopenai.KeyCredential{ APIKey: "open-ai-apikey", } @@ -23,6 +25,8 @@ func ExampleNewClientForOpenAI() { } func ExampleNewClient() { + // NOTE: this constructor creates a client that connects to an Azure OpenAI endpoint. + // To connect to the public OpenAI endpoint, use azopenai.NewClientForOpenAI dac, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { @@ -40,6 +44,8 @@ func ExampleNewClient() { } func ExampleNewClientWithKeyCredential() { + // NOTE: this constructor creates a client that connects to an Azure OpenAI endpoint. + // To connect to the public OpenAI endpoint, use azopenai.NewClientForOpenAI keyCredential := azopenai.KeyCredential{ APIKey: "Azure OpenAI apikey", } From 7986b4df9d8ec363b34924fab9187edfe129960f Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 16:30:34 -0700 Subject: [PATCH 56/62] Added in a streaming completions example (with a test!) --- .../azopenai/examples_client_test.go | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go index 1cd3732f160d..9b70a21586ed 100644 --- a/sdk/cognitiveservices/azopenai/examples_client_test.go +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -4,6 +4,13 @@ package azopenai_test import ( + "context" + "errors" + "fmt" + "io" + "os" + + "github.com/Azure/azure-sdk-for-go/sdk/azcore/to" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "github.com/Azure/azure-sdk-for-go/sdk/cognitiveservices/azopenai" ) @@ -59,3 +66,51 @@ func ExampleNewClientWithKeyCredential() { _ = client } + +func ExampleClient_GetCompletionsStream() { + azureOpenAIKey := os.Getenv("AOAI_API_KEY") + modelDeploymentID := os.Getenv("AOAI_STREAMING_MODEL") + + // Ex: "https://.openai.azure.com" + azureOpenAIEndpoint := os.Getenv("AOAI_ENDPOINT") + + keyCredential := azopenai.KeyCredential{ + APIKey: azureOpenAIKey, + } + + client, err := azopenai.NewClientWithKeyCredential(azureOpenAIEndpoint, keyCredential, modelDeploymentID, nil) + + if err != nil { + panic(err) + } + + resp, err := client.GetCompletionsStream(context.TODO(), azopenai.CompletionsOptions{ + Prompt: []*string{to.Ptr("What is Azure OpenAI?")}, + MaxTokens: to.Ptr(int32(2048 - 127)), + Temperature: to.Ptr(float32(0.0)), + }, nil) + + if err != nil { + panic(err) + } + + for { + entry, err := resp.CompletionsStream.Read() + + if errors.Is(err, io.EOF) { + fmt.Printf("More more completions") + break + } + + if err != nil { + panic(err) + } + + for _, choice := range entry.Choices { + fmt.Printf("%s", *choice.Text) + } + } + + // Output: + // Azure OpenAI is a platform from Microsoft that provides access to OpenAI's artificial intelligence (AI) technologies. It enables developers to build, train, and deploy AI models in the cloud. Azure OpenAI provides access to OpenAI's powerful AI technologies, such as GPT-3, which can be used to create natural language processing (NLP) applications, computer vision models, and reinforcement learning models.More more completions +} From 3b3f54990fe3bbbc93c7a66a120dec972be3bae1 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 16:31:45 -0700 Subject: [PATCH 57/62] Don't fail the example test if there's no key actually configured. --- sdk/cognitiveservices/azopenai/examples_client_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go index 9b70a21586ed..201ccef6a2e4 100644 --- a/sdk/cognitiveservices/azopenai/examples_client_test.go +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -74,6 +74,10 @@ func ExampleClient_GetCompletionsStream() { // Ex: "https://.openai.azure.com" azureOpenAIEndpoint := os.Getenv("AOAI_ENDPOINT") + if azureOpenAIKey == "" || modelDeploymentID == "" || azureOpenAIEndpoint == "" { + return + } + keyCredential := azopenai.KeyCredential{ APIKey: azureOpenAIKey, } From aa90d2026bb3ddfa422b61f81414fbd78cb27fb7 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 16:49:46 -0700 Subject: [PATCH 58/62] Updating some more, use the same env variable for the streaming deployment model. --- sdk/cognitiveservices/azopenai/client_shared_test.go | 11 ++++++++--- sdk/cognitiveservices/azopenai/client_test.go | 5 ++--- sdk/cognitiveservices/azopenai/custom_client_test.go | 4 ++-- .../azopenai/examples_client_test.go | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index c353a2500757..181881e484f9 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -16,8 +16,10 @@ import ( ) var ( - endpoint string - apiKey string + endpoint string + apiKey string + streamingModelDeployment string + openAIKey string openAIEndpoint string ) @@ -45,8 +47,11 @@ func init() { } apiKey = os.Getenv("AOAI_API_KEY") - openAIKey = os.Getenv("OPENAI_API_KEY") + // Ex: text-davinci-003 + streamingModelDeployment = os.Getenv("AOAI_STREAMING_MODEL_DEPLOYMENT") + + openAIKey = os.Getenv("OPENAI_API_KEY") openAIEndpoint = os.Getenv("OPENAI_ENDPOINT") if !strings.HasSuffix(openAIEndpoint, "/") { diff --git a/sdk/cognitiveservices/azopenai/client_test.go b/sdk/cognitiveservices/azopenai/client_test.go index 9b3c25b0e657..7c2335eaff1a 100644 --- a/sdk/cognitiveservices/azopenai/client_test.go +++ b/sdk/cognitiveservices/azopenai/client_test.go @@ -198,8 +198,7 @@ func TestClient_GetCompletions(t *testing.T) { options *GetCompletionsOptions } cred := KeyCredential{APIKey: apiKey} - deploymentID := "text-davinci-003" - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) + client, err := NewClientWithKeyCredential(endpoint, cred, streamingModelDeployment, newClientOptionsForTest(t)) if err != nil { log.Fatalf("%v", err) } @@ -215,7 +214,7 @@ func TestClient_GetCompletions(t *testing.T) { client: client, args: args{ ctx: context.TODO(), - deploymentID: deploymentID, + deploymentID: streamingModelDeployment, body: CompletionsOptions{ Prompt: []*string{to.Ptr("What is Azure OpenAI?")}, MaxTokens: to.Ptr(int32(2048 - 127)), diff --git a/sdk/cognitiveservices/azopenai/custom_client_test.go b/sdk/cognitiveservices/azopenai/custom_client_test.go index 50a0088f0202..412e04169310 100644 --- a/sdk/cognitiveservices/azopenai/custom_client_test.go +++ b/sdk/cognitiveservices/azopenai/custom_client_test.go @@ -82,8 +82,8 @@ func TestClient_GetCompletionsStream(t *testing.T) { Temperature: to.Ptr(float32(0.0)), } cred := KeyCredential{APIKey: apiKey} - deploymentID := "text-davinci-003" - client, err := NewClientWithKeyCredential(endpoint, cred, deploymentID, newClientOptionsForTest(t)) + + client, err := NewClientWithKeyCredential(endpoint, cred, streamingModelDeployment, newClientOptionsForTest(t)) if err != nil { t.Errorf("NewClientWithKeyCredential() error = %v", err) return diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go index 201ccef6a2e4..e1bf2fbacb81 100644 --- a/sdk/cognitiveservices/azopenai/examples_client_test.go +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -69,7 +69,7 @@ func ExampleNewClientWithKeyCredential() { func ExampleClient_GetCompletionsStream() { azureOpenAIKey := os.Getenv("AOAI_API_KEY") - modelDeploymentID := os.Getenv("AOAI_STREAMING_MODEL") + modelDeploymentID := os.Getenv("AOAI_STREAMING_MODEL_DEPLOYMENT") // Ex: "https://.openai.azure.com" azureOpenAIEndpoint := os.Getenv("AOAI_ENDPOINT") From 176af418532315ab9e7d3eb1dc48280a55ca839a Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 18:12:25 -0700 Subject: [PATCH 59/62] Rerecording. --- sdk/cognitiveservices/azopenai/assets.json | 2 +- .../azopenai/client_shared_test.go | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index 98ecb7171058..faf28b43dd8f 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_87c0306011" + "Tag": "go/cognitiveservices/azopenai_f49432497f" } diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index 181881e484f9..596cbcb0ccfe 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -6,6 +6,7 @@ package azopenai import ( "fmt" "os" + "regexp" "strings" "testing" @@ -16,12 +17,12 @@ import ( ) var ( - endpoint string - apiKey string - streamingModelDeployment string + endpoint string // env: AOAI_ENDPOINT + apiKey string // env: AOAI_API_KEY + streamingModelDeployment string // env: AOAI_STREAMING_MODEL_DEPLOYMENT - openAIKey string - openAIEndpoint string + openAIKey string // env: OPENAI_API_KEY + openAIEndpoint string // env: OPENAI_ENDPOINT ) const fakeEndpoint = "https://recordedhost/" @@ -41,7 +42,7 @@ func init() { endpoint = os.Getenv("AOAI_ENDPOINT") - if !strings.HasSuffix(endpoint, "/") { + if endpoint != "" && !strings.HasSuffix(endpoint, "/") { // (this just makes recording replacement easier) endpoint += "/" } @@ -54,7 +55,7 @@ func init() { openAIKey = os.Getenv("OPENAI_API_KEY") openAIEndpoint = os.Getenv("OPENAI_ENDPOINT") - if !strings.HasSuffix(openAIEndpoint, "/") { + if openAIEndpoint != "" && !strings.HasSuffix(openAIEndpoint, "/") { // (this just makes recording replacement easier) openAIEndpoint += "/" } @@ -73,11 +74,11 @@ func newRecordingTransporter(t *testing.T) policy.Transporter { require.NoError(t, err) // "RequestUri": "https://openai-shared.openai.azure.com/openai/deployments/text-davinci-003/completions?api-version=2023-03-15-preview", - err = recording.AddURISanitizer(fakeEndpoint, endpoint, nil) + err = recording.AddURISanitizer(fakeEndpoint, regexp.QuoteMeta(endpoint), nil) require.NoError(t, err) if openAIEndpoint != "" { - err = recording.AddURISanitizer(fakeEndpoint, openAIEndpoint, nil) + err = recording.AddURISanitizer(fakeEndpoint, regexp.QuoteMeta(openAIEndpoint), nil) require.NoError(t, err) } } From 4250ac87260ae8cd63c18f92e5b0e6746fd4dd28 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 19:15:53 -0700 Subject: [PATCH 60/62] Don't let the test run for now (output is conditional since the env vars aren't always there) --- sdk/cognitiveservices/azopenai/examples_client_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/sdk/cognitiveservices/azopenai/examples_client_test.go b/sdk/cognitiveservices/azopenai/examples_client_test.go index e1bf2fbacb81..ea9ebf1e7ef0 100644 --- a/sdk/cognitiveservices/azopenai/examples_client_test.go +++ b/sdk/cognitiveservices/azopenai/examples_client_test.go @@ -114,7 +114,4 @@ func ExampleClient_GetCompletionsStream() { fmt.Printf("%s", *choice.Text) } } - - // Output: - // Azure OpenAI is a platform from Microsoft that provides access to OpenAI's artificial intelligence (AI) technologies. It enables developers to build, train, and deploy AI models in the cloud. Azure OpenAI provides access to OpenAI's powerful AI technologies, such as GPT-3, which can be used to create natural language processing (NLP) applications, computer vision models, and reinforcement learning models.More more completions } From 8b3ec9f6456cb43937de77dc9e649ae3d75a0661 Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 19:18:14 -0700 Subject: [PATCH 61/62] Needed to fill in another fake variable. --- sdk/cognitiveservices/azopenai/client_shared_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/cognitiveservices/azopenai/client_shared_test.go b/sdk/cognitiveservices/azopenai/client_shared_test.go index 596cbcb0ccfe..c3d643709801 100644 --- a/sdk/cognitiveservices/azopenai/client_shared_test.go +++ b/sdk/cognitiveservices/azopenai/client_shared_test.go @@ -34,6 +34,7 @@ func init() { apiKey = fakeAPIKey openAIKey = fakeAPIKey openAIEndpoint = fakeEndpoint + streamingModelDeployment = "text-davinci-003" } else { if err := godotenv.Load(); err != nil { fmt.Printf("Failed to load .env file: %s\n", err) From 432cdfb013c0fc5524af18f692310feae9130aff Mon Sep 17 00:00:00 2001 From: Richard Park Date: Mon, 19 Jun 2023 21:50:46 -0700 Subject: [PATCH 62/62] rerecord... --- sdk/cognitiveservices/azopenai/assets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/cognitiveservices/azopenai/assets.json b/sdk/cognitiveservices/azopenai/assets.json index faf28b43dd8f..ba5284a4a597 100644 --- a/sdk/cognitiveservices/azopenai/assets.json +++ b/sdk/cognitiveservices/azopenai/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "go", "TagPrefix": "go/cognitiveservices/azopenai", - "Tag": "go/cognitiveservices/azopenai_f49432497f" + "Tag": "go/cognitiveservices/azopenai_0bc6dc4171" }