openai/openai-dotnet

Public

mirrored from https://github.com/openai/openai-dotnetAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
achandmsft-patch-2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

codegen/generator/src/Visitors/MetadataQueryParamVisitor.cs

109lines · modecode

1using System;
2using System.Collections.Generic;
3using System.Linq;
4using Microsoft.TypeSpec.Generator.ClientModel;
5using Microsoft.TypeSpec.Generator.Expressions;
6using Microsoft.TypeSpec.Generator.Primitives;
7using Microsoft.TypeSpec.Generator.Providers;
8using Microsoft.TypeSpec.Generator.Snippets;
9using Microsoft.TypeSpec.Generator.Statements;
10using static OpenAILibraryPlugin.Visitors.VisitorHelpers;
11
12namespace OpenAILibraryPlugin.Visitors;
13
14/// <summary>
15/// This visitor fixes up usage of the metadata query parameter into the proper format.
16/// </summary>
17public class MetadataQueryParamVisitor : ScmLibraryVisitor
18{
19
20 private static readonly string[] _chatParamsToReplace = ["after", "before", "limit", "order", "model", "metadata"];
21
22 /// <summary>
23 /// Visits Create*Request methods to modify how metadata query parameters are handled.
24 /// It replaces the following statements:
25 /// <code>
26 /// List<object> list = new List<object>();
27 /// foreach (var @param in metadata)
28 /// {
29 /// uri.AppendQuery($"metadata[{@param.Key}]", @param.Value, true);
30 /// list.Add(@param.Key);
31 /// list.Add(@param.Value);
32 /// }
33 /// uri.AppendQueryDelimited("metadata", list, ",", null, true);
34 /// </code>
35 /// with:
36 /// <code>
37 /// foreach (var @param in metadata)
38 /// {
39 /// uri.AppendQuery($"metadata[{@param.Key}]", @param.Value, true);
40 /// }
41 /// </summary>
42 /// <param name="method"></param>
43 /// <returns></returns>
44 protected override MethodProvider? VisitMethod(MethodProvider method)
45 {
46 // Check if the method is one of the Create*Request methods and has a signature that takes a metadata parameter like IDictionary<string, string> metadata
47 if (method.Signature.Name.StartsWith("Create") && method.Signature.Name.EndsWith("Request") &&
48 method.Signature.Parameters.Any(p => p.Type.IsDictionary && p.Name == "metadata"))
49 {
50 ValueExpression? uri = null;
51 var statements = method.BodyStatements?.ToList() ?? new List<MethodBodyStatement>();
52 VisitExplodedMethodBodyStatements(
53 statements!,
54 statement =>
55 {
56 // Check if the statement is an assignment to a variable named "uri"
57 // Capture it if so
58 if (statement is ExpressionStatement expressionStatement &&
59 expressionStatement.Expression is AssignmentExpression assignmentExpression &&
60 assignmentExpression.Variable is DeclarationExpression declarationExpression &&
61 declarationExpression.Variable is VariableExpression variableExpression &&
62 variableExpression.Declaration.RequestedName == "uri")
63 {
64 uri = variableExpression;
65 }
66 // Try to remove the unnecessary list declaration
67 if (statement is ExpressionStatement expressionStatement2 &&
68 expressionStatement2.Expression is AssignmentExpression assignmentExpression2 &&
69 assignmentExpression2.Variable is DeclarationExpression declarationExpression2 &&
70 declarationExpression2.Variable is VariableExpression variableExpression2 &&
71 variableExpression2.Declaration.RequestedName == "list" &&
72 variableExpression2.Type.IsCollection && variableExpression2.Type.IsGenericType)
73 {
74 // Remove the list declaration
75 return new SingleLineCommentStatement("Plugin customization: remove unnecessary list declaration");
76 }
77
78 if (uri is not null &&
79 statement is ForEachStatement foreachStatement &&
80 foreachStatement.Enumerable is DictionaryExpression dictionaryExpression &&
81 dictionaryExpression.Original is VariableExpression variable &&
82 variable.Declaration.RequestedName == "metadata")
83 {
84 var formatString = new FormattableStringExpression("metadata[{0}]", [foreachStatement.ItemVariable.Property("Key")]);
85 var appendQueryStatement = uri.Invoke("AppendQuery", [formatString, foreachStatement.ItemVariable.Property("Value"), Snippet.True]);
86 foreachStatement.Body.Clear();
87 foreachStatement.Body.Add(new SingleLineCommentStatement("Plugin customization: Properly handle metadata query parameters"));
88 foreachStatement.Body.Add(appendQueryStatement.Terminate());
89 }
90
91 // Remove the call to AppendQueryDelimited for metadata
92 if (statement is ExpressionStatement expressionStatement3 &&
93 expressionStatement3.Expression is InvokeMethodExpression invokeMethodExpression &&
94 invokeMethodExpression.MethodName == "AppendQueryDelimited" &&
95 invokeMethodExpression.Arguments.Count == 5 &&
96 invokeMethodExpression.Arguments[0].ToDisplayString() == "\"metadata\"")
97 {
98 return new SingleLineCommentStatement("Plugin customization: remove unnecessary AppendQueryDelimited for metadata");
99 }
100 return statement;
101 });
102
103 // Rebuild the method body with the modified statements
104 method.Update(bodyStatements: statements);
105 }
106
107 return base.VisitMethod(method);
108 }
109}