-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Support for OpenAI v4 #4232
Conversation
Overall package sizeSelf size: 6.33 MB Dependency sizes
🤖 This report was automatically generated by heaviest-objects-in-the-universe |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #4232 +/- ##
==========================================
- Coverage 73.16% 69.19% -3.98%
==========================================
Files 245 1 -244
Lines 10442 198 -10244
Branches 33 33
==========================================
- Hits 7640 137 -7503
+ Misses 2802 61 -2741 ☔ View full report in Codecov by Sentry. |
Hello, any ETA on when this will be merged ? 🙏🏼 |
ESM test failures related to DataDog/import-in-the-middle#60 |
…into sabrenner/openai4.x
This reverts commit ff854c2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. Also, that test file is enormous. Can we break that up somehow? Maybe with some fixture files or something?
@@ -113,42 +113,42 @@ class OpenApiPlugin extends TracingPlugin { | |||
} | |||
|
|||
switch (methodName) { | |||
case 'createFineTune': | |||
case 'createFineTune': case 'fine_tuning.jobs.create': case 'fine-tune.create': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably not be putting multiple cases on the same line. I'm surprised the linter doesn't complain about this. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah fair, will make these each their own line. yeah, surprised this wasn't linted (I think I had done it this way while I was working to let myself know it was the same function but different name).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use blank lines to group renames together.
try { | ||
headers = Object.fromEntries(headers) | ||
} catch { /* headers are already an object */ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather we check it's an object rather than try/catching our way out of this.
try { | ||
path = new URL(path).pathname | ||
} catch { /* path is already a URL pathname */ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with the object case above, can we just do a check rather than a try/catch? Exceptions are expensive.
@Qard Fair point. My original intent was to not disturb the content or structure too much for this PR, as I really just wanted to isolate the changes to the instrumentation and test those accordingly. But, I agree it's completely an unmanageable size and format. Will look tomorrow at breaking it up for this PR |
Feel free to break that up as a follow-up. That comment was more an observation than a request for changes. I won't consider that a blocker here. 😅 |
@Qard Sounds good; in the interest of seeing if this PR can land a bit quicker, I'll do a refactor of this integration as a whole (+ its tests, maybe in two PRs, as its a fairly large and involved integration) separately. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get some screenshots of manual/demo traces generated by the new OpenAI support before we merge? Otherwise, lgtm!
@Yun-Kim hope the following looks ok! let me know if anything should be different (which, if there is, and it's not too concerning, I can address in a follow-up PR). Using the latest version of OpenAI:
With a simple chat completion like: await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [{"role": "user", "content": "Hello!"}],
}) |
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
* add instrumenation shims for openai v4.x * instrumentation populates fields correctly * fix method name * wrap apipromise.parse to always return apipromise type * support everything but streaming * fix completion test and give tests generic names * update tests + plugin for finetune api change * tag tools * fix logger test for tool calls * fix tool call logger test * streaming * Revert "streaming" This reverts commit ff854c2. * request message tagging + tools log * discard .only * tool test * tool test + finetune updates * lint * linting + fixes, clamping version for ESM tests for CI --------- Co-authored-by: Mark Hayes <mcleodm@gmail.com>
What does this PR do?
Updates the
openai
integration to support the latest major release line of the Node.js OpenAI SDK.Notes for Reviewers
Most of the LOC on this PR are for test changes, which are mostly changing relevant method calls to v4 syntax (ie
createChatCompletion
vschat.completions.create
), and relevant payload differences. The tests themselves still have the same content.The important files changed are both the instrumentation and plugin code.
Instrumentation Updates
The instrumentation ensures the same functions are wrapped from the existing support for v3 of the OpenAI SDK. However, these methods are not available on the top-level export anymore, and instead are found in various files throughout, and is reflected in the wrapping configuration (by specifying all the different locations and target classes to wrap in an object)
There are two major differences in how these methods are implemented on the SDK side that affect the instrumentation.
APIPromise
, which has a methodwithResponse
that can be called after the promise resolves.Response
object associated with the underlying call to the OpenAI API, which we used to extract headers for tagging and metrics. This is now not available off of the resolved promise.To work with the restriction of needing to return a custom promise type, there is no promise chaining on the returned object to publish the span end event. Rather, the
APIPromise
object itself is wrapped. This allows for access to an internal variable which represents the raw response from the external call to the OpenAI API,this.responsePromise
.However, the
then
method of the promise cannot be wrapped either, as it is also possible to resolve theAPIPromise
by callingwithResponse()
, which allows the user to get the response as well as the data associated with the call. Boththen
andwithResponse
utilize a privateparse
method on theAPIPromise
, which takes in the raw response, and parses it to the refined data object which the user typically sees. Wrappingparse
allows for the raw response and final output to be gathered together, and sent to the plugin to populate data fields on the span.Plugin Updates
There are minimal changes made to the plugin side. The overall idea is, the updates made in this PR should not impact the tags/metrics/logs emitted from the overall integration. The only things that needed to be changed were method name switch cases, as well as a few miscellaneous changes due to payload structure difference in the API.
Testing Updates
The content of the tests themselves (checking for specific tags/metrics, as well as calls to the mock logger and DogStatsD) remain largely unchanged. Instead, lots of version gates were added to use different method calls (ie
openai.createCompletion
vsopenai.completions.create
) and check for the resulting differences in tag values (mostly resource names following a similarly highlighted pattern).Motivation
Support the latest major release line for the Node.js OpenAI SDK.
Outstanding Issues
import-in-the-middle
that needs to be addressed, TBD