Skip to content

Commit 7084245

Browse files
committed
safeguard static openai funciton checks; update async tests to use custom llm
1 parent bc949cf commit 7084245

File tree

14 files changed

+279
-126
lines changed

14 files changed

+279
-126
lines changed

guardrails/applications/text2sql.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import asyncio
22
import json
33
import os
4+
import openai
45
from string import Template
56
from typing import Callable, Dict, Optional, Type, cast
67

78
from guardrails.classes import ValidationOutcome
89
from guardrails.document_store import DocumentStoreBase, EphemeralDocumentStore
910
from guardrails.embedding import EmbeddingBase, OpenAIEmbedding
1011
from guardrails.guard import Guard
11-
from guardrails.utils.openai_utils import get_static_openai_create_func
1212
from guardrails.utils.sql_utils import create_sql_driver
1313
from guardrails.vectordb import Faiss, VectorDBBase
1414

@@ -89,7 +89,7 @@ def __init__(
8989
reask_prompt: Prompt to use for reasking. Defaults to REASK_PROMPT.
9090
"""
9191
if llm_api is None:
92-
llm_api = get_static_openai_create_func()
92+
llm_api = openai.completions.create
9393

9494
self.example_formatter = example_formatter
9595
self.llm_api = llm_api

guardrails/llm_providers.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
from guardrails.utils.openai_utils import (
2828
AsyncOpenAIClient,
2929
OpenAIClient,
30-
get_static_openai_acreate_func,
31-
get_static_openai_chat_acreate_func,
32-
get_static_openai_chat_create_func,
33-
get_static_openai_create_func,
30+
is_static_openai_acreate_func,
31+
is_static_openai_chat_acreate_func,
32+
is_static_openai_chat_create_func,
33+
is_static_openai_create_func,
3434
)
3535
from guardrails.utils.pydantic_utils import convert_pydantic_model_to_openai_fn
3636
from guardrails.utils.safe_get import safe_get
@@ -784,9 +784,9 @@ def get_llm_ask(
784784
except ImportError:
785785
pass
786786

787-
if llm_api == get_static_openai_create_func():
787+
if is_static_openai_create_func(llm_api):
788788
return OpenAICallable(*args, **kwargs)
789-
if llm_api == get_static_openai_chat_create_func():
789+
if is_static_openai_chat_create_func(llm_api):
790790
return OpenAIChatCallable(*args, **kwargs)
791791

792792
try:
@@ -1252,9 +1252,12 @@ def get_async_llm_ask(
12521252
pass
12531253

12541254
# these only work with openai v0 (None otherwise)
1255-
if llm_api == get_static_openai_acreate_func():
1255+
# We no longer support OpenAI v0
1256+
# We should drop these checks or update the logic to support
1257+
# OpenAI v1 clients instead of just static methods
1258+
if is_static_openai_acreate_func(llm_api):
12561259
return AsyncOpenAICallable(*args, **kwargs)
1257-
if llm_api == get_static_openai_chat_acreate_func():
1260+
if is_static_openai_chat_acreate_func(llm_api):
12581261
return AsyncOpenAIChatCallable(*args, **kwargs)
12591262

12601263
try:
@@ -1293,13 +1296,13 @@ def get_llm_api_enum(
12931296
) -> Optional[LLMResource]:
12941297
# TODO: Distinguish between v1 and v2
12951298
model = get_llm_ask(llm_api, *args, **kwargs)
1296-
if llm_api == get_static_openai_create_func():
1299+
if is_static_openai_create_func(llm_api):
12971300
return LLMResource.OPENAI_DOT_COMPLETION_DOT_CREATE
1298-
elif llm_api == get_static_openai_chat_create_func():
1301+
elif is_static_openai_chat_create_func(llm_api):
12991302
return LLMResource.OPENAI_DOT_CHAT_COMPLETION_DOT_CREATE
1300-
elif llm_api == get_static_openai_acreate_func():
1303+
elif is_static_openai_acreate_func(llm_api): # This is always False
13011304
return LLMResource.OPENAI_DOT_COMPLETION_DOT_ACREATE
1302-
elif llm_api == get_static_openai_chat_acreate_func():
1305+
elif is_static_openai_chat_acreate_func(llm_api): # This is always False
13031306
return LLMResource.OPENAI_DOT_CHAT_COMPLETION_DOT_ACREATE
13041307
elif isinstance(model, LiteLLMCallable):
13051308
return LLMResource.LITELLM_DOT_COMPLETION

guardrails/utils/openai_utils/__init__.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
from .v1 import OpenAIClientV1 as OpenAIClient
33
from .v1 import (
44
OpenAIServiceUnavailableError,
5-
get_static_openai_acreate_func,
6-
get_static_openai_chat_acreate_func,
7-
get_static_openai_chat_create_func,
8-
get_static_openai_create_func,
5+
is_static_openai_acreate_func,
6+
is_static_openai_chat_acreate_func,
7+
is_static_openai_chat_create_func,
8+
is_static_openai_create_func,
99
)
1010

1111
__all__ = [
1212
"AsyncOpenAIClient",
1313
"OpenAIClient",
14-
"get_static_openai_create_func",
15-
"get_static_openai_chat_create_func",
16-
"get_static_openai_acreate_func",
17-
"get_static_openai_chat_acreate_func",
14+
"is_static_openai_create_func",
15+
"is_static_openai_chat_create_func",
16+
"is_static_openai_acreate_func",
17+
"is_static_openai_chat_acreate_func",
1818
"OpenAIServiceUnavailableError",
1919
]

guardrails/utils/openai_utils/v1.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, AsyncIterable, Dict, Iterable, List, cast
1+
from typing import Any, AsyncIterable, Callable, Dict, Iterable, List, Optional, cast
22

33
import openai
44

@@ -12,20 +12,30 @@
1212
from guardrails.telemetry import trace_llm_call, trace_operation
1313

1414

15-
def get_static_openai_create_func():
16-
return openai.completions.create
15+
def is_static_openai_create_func(llm_api: Optional[Callable]) -> bool:
16+
try:
17+
return llm_api == openai.completions.create
18+
except openai.OpenAIError:
19+
return False
1720

1821

19-
def get_static_openai_chat_create_func():
20-
return openai.chat.completions.create
22+
def is_static_openai_chat_create_func(llm_api: Optional[Callable]) -> bool:
23+
try:
24+
return llm_api == openai.chat.completions.create
25+
except openai.OpenAIError:
26+
return False
2127

2228

23-
def get_static_openai_acreate_func():
24-
return None
29+
def is_static_openai_acreate_func(llm_api: Optional[Callable]) -> bool:
30+
# Because the static version of this does not exist in OpenAI 1.x
31+
# Can we just drop these checks?
32+
return False
2533

2634

27-
def get_static_openai_chat_acreate_func():
28-
return None
35+
def is_static_openai_chat_acreate_func(llm_api: Optional[Callable]) -> bool:
36+
# Because the static version of this does not exist in OpenAI 1.x
37+
# Can we just drop these checks?
38+
return False
2939

3040

3141
OpenAIServiceUnavailableError = openai.APIError

tests/integration_tests/test_assets/entity_extraction/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@
3333

3434
# Compiled prompts
3535
COMPILED_PROMPT = reader("compiled_prompt.txt")
36+
NON_OPENAI_COMPILED_PROMPT = reader("non_openai_compiled_prompt.txt")
3637
COMPILED_PROMPT_WITHOUT_INSTRUCTIONS = reader(
3738
"compiled_prompt_without_instructions.txt"
3839
)
3940
COMPILED_PROMPT_REASK = reader("compiled_prompt_reask.txt")
41+
NON_OPENAI_COMPILED_PROMPT_REASK = reader("non_openai_compiled_prompt_reask.txt")
4042
COMPILED_PROMPT_REASK_WITHOUT_INSTRUCTIONS = reader(
4143
"compiled_prompt_reask_without_instructions.txt"
4244
)
@@ -82,8 +84,10 @@
8284

8385
__all__ = [
8486
"COMPILED_PROMPT",
87+
"NON_OPENAI_COMPILED_PROMPT",
8588
"COMPILED_PROMPT_WITHOUT_INSTRUCTIONS",
8689
"COMPILED_PROMPT_REASK",
90+
"NON_OPENAI_COMPILED_PROMPT_REASK",
8791
"COMPILED_PROMPT_REASK_WITHOUT_INSTRUCTIONS",
8892
"COMPILED_INSTRUCTIONS",
8993
"COMPILED_INSTRUCTIONS_REASK",
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
2+
Given the following document, answer the following questions. If the answer doesn't exist in the document, enter 'None'.
3+
4+
2/25/23, 7:59 PM about:blank
5+
about:blank 1/4
6+
PRICING INFORMATION
7+
INTEREST RATES AND INTEREST CHARGES
8+
Purchase Annual
9+
Percentage Rate (APR) 0% Intro APR for the first 18 months that your Account is open.
10+
After that, 19.49%. This APR will vary with the market based on the Prime
11+
Rate.
12+
a
13+
My Chase Loan
14+
SM APR 19.49%. This APR will vary with the market based on the Prime Rate.
15+
a
16+
Promotional offers with fixed APRs and varying durations may be available from
17+
time to time on some accounts.
18+
Balance Transfer APR 0% Intro APR for the first 18 months that your Account is open.
19+
After that, 19.49%. This APR will vary with the market based on the Prime
20+
Rate.
21+
a
22+
Cash Advance APR 29.49%. This APR will vary with the market based on the Prime Rate.
23+
b
24+
Penalty APR and When
25+
It Applies
26+
Up to 29.99%. This APR will vary with the market based on the Prime Rate.
27+
c
28+
We may apply the Penalty APR to your account if you:
29+
fail to make a Minimum Payment by the date and time that it is due; or
30+
make a payment to us that is returned unpaid.
31+
How Long Will the Penalty APR Apply?: If we apply the Penalty APR for
32+
either of these reasons, the Penalty APR could potentially remain in effect
33+
indefinitely.
34+
How to Avoid Paying
35+
Interest on Purchases
36+
Your due date will be a minimum of 21 days after the close of each billing cycle.
37+
We will not charge you interest on new purchases if you pay your entire balance
38+
or Interest Saving Balance by the due date each month. We will begin charging
39+
interest on balance transfers and cash advances on the transaction date.
40+
Minimum Interest
41+
Charge
42+
None
43+
Credit Card Tips from
44+
the Consumer Financial
45+
Protection Bureau
46+
To learn more about factors to consider when applying for or using a credit card,
47+
visit the website of the Consumer Financial Protection Bureau at
48+
http://www.consumerfinance.gov/learnmore.
49+
FEES
50+
Annual Membership
51+
Fee
52+
None
53+
My Chase Plan
54+
SM Fee
55+
(fixed finance charge)
56+
Monthly fee of 0% of the amount of each eligible purchase transaction or
57+
amount selected to create a My Chase Plan while in the 0% Intro Purchase
58+
APR period.
59+
After that, monthly fee of 1.72% of the amount of each eligible purchase
60+
transaction or amount selected to create a My Chase Plan. The My Chase Plan
61+
Fee will be determined at the time each My Chase Plan is created and will
62+
remain the same until the My Chase Plan is paid in full.
63+
d
64+
Transaction Fees
65+
Balance Transfers Intro fee of either $5 or 3% of the amount of each transfer, whichever is greater,
66+
on transfers made within 60 days of account opening. After that: Either $5 or 5%
67+
of the amount of each transfer, whichever is greater.
68+
Cash Advances Either $10 or 5% of the amount of each transaction, whichever is greater.
69+
2/25/23, 7:59 PM about:blank
70+
about:blank 2/4
71+
Foreign Transactions 3% of the amount of each transaction in U.S. dollars.
72+
Penalty Fees
73+
Late Payment Up to $40.
74+
Over-the-Credit-Limit None
75+
Return Payment Up to $40.
76+
Return Check None
77+
Note: This account may not be eligible for balance transfers.
78+
Loss of Intro APR: We will end your introductory APR if any required Minimum Payment is 60 days late, and
79+
apply the Penalty APR.
80+
How We Will Calculate Your Balance: We use the daily balance method (including new transactions).
81+
Prime Rate: Variable APRs are based on the 7.75% Prime Rate as of 2/7/2023.
82+
aWe add 11.74% to the Prime Rate to determine the Purchase/My Chase Loan/Balance Transfer APR.
83+
Maximum APR 29.99%.
84+
bWe add 21.74% to the Prime Rate to determine the Cash Advance APR. Maximum APR 29.99%.
85+
cWe add up to 26.99% to the Prime Rate to determine the Penalty APR. Maximum APR 29.99%.
86+
dMy Chase Plan Fee: The My Chase Plan Fee is calculated at the time each plan is created and is based on
87+
the amount of each purchase transaction or amount selected to create the plan, the number of billing periods
88+
you choose to pay the balance in full, and other factors. The monthly and aggregate dollar amount of your My
89+
Chase Plan Fee will be disclosed during the activation of each My Chase Plan.
90+
MILITARY LENDING ACT NOTICE: Federal law provides important protections to members of the Armed
91+
Forces and their dependents relating to extensions of consumer credit. In general, the cost of consumer credit
92+
to a member of the Armed Forces and his or her dependent may not exceed an annual percentage rate of 36
93+
percent. This rate must include, as applicable to the credit transaction or account: the costs associated with
94+
credit insurance premiums; fees for ancillary products sold in connection with the credit transaction; any
95+
application fee charged (other than certain application fees for specified credit transactions or accounts); and
96+
any participation fee charged (other than certain participation fees for a credit card account). To receive this
97+
information and a description of your payment obligation verbally, please call 1-800-235-9978.
98+
TERMS & CONDITIONS
99+
Authorization: When you respond to this credit card offer from JPMorgan Chase Bank, N.A., Member FDIC, a
100+
subsidiary of JPMorgan Chase & Co. ("Chase", "we", or "us"), you agree to the following:
101+
1. You authorize us to obtain credit bureau reports, employment, and income information about you that we
102+
will use when considering your application for credit. We may obtain and use information about your
103+
accounts with us and others such as Checking, Deposit, Investment, and Utility accounts from credit
104+
bureaus and other entities. You also authorize us to obtain credit bureau reports and any other
105+
information about you in connection with: 1) extensions of credit on your account; 2) the administration,
106+
review or collection of your account; and 3) offering you enhanced or additional products and services. If
107+
you ask, we will tell you the name and address of the credit bureau from which we obtained a report
108+
about you.
109+
2. If an account is opened, you will receive a Cardmember Agreement with your card(s). You agree to the
110+
terms of this agreement by: using the account or any card, authorizing their use, or making any payment
111+
on the account.
112+
3. By providing your mobile ph
113+
114+
115+
Given below is XML that describes the information to extract from this document and the tags to extract it into.
116+
117+
118+
<output>
119+
<list description="What fees and charges are associated with my account?" name="fees" required="true">
120+
<object required="true">
121+
<integer format="1-indexed" name="index" required="true"></integer>
122+
<string format="lower-case; two-words" name="name" required="true"></string>
123+
<string format="one-line" name="explanation" required="true"></string>
124+
<float format="percentage" name="value" required="true"></float>
125+
</object>
126+
</list>
127+
<object description="What are the interest rates offered by the bank on savings and checking accounts, loans, and credit products?" name="interest_rates" required="true"></object>
128+
</output>
129+
130+
131+
ONLY return a valid JSON object (no other text is necessary). The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
I was given the following JSON response, which had problems due to incorrect values.
3+
4+
{
5+
"fees": [
6+
{
7+
"name": {
8+
"incorrect_value": "my chase plan",
9+
"error_messages": [
10+
"must be exactly two words"
11+
]
12+
}
13+
},
14+
{
15+
"name": {
16+
"incorrect_value": "over-the-credit-limit",
17+
"error_messages": [
18+
"must be exactly two words"
19+
]
20+
}
21+
}
22+
]
23+
}
24+
25+
Help me correct the incorrect values based on the given error messages.
26+
27+
Given below is XML that describes the information to extract from this document and the tags to extract it into.
28+
29+
<output>
30+
<list description="What fees and charges are associated with my account?" name="fees" required="true">
31+
<object required="true">
32+
<integer format="1-indexed" name="index" required="true"></integer>
33+
<string format="lower-case; two-words" name="name" required="true"></string>
34+
<string format="one-line" name="explanation" required="true"></string>
35+
<float format="percentage" name="value" required="true"></float>
36+
</object>
37+
</list>
38+
<object description="What are the interest rates offered by the bank on savings and checking accounts, loans, and credit products?" name="interest_rates" required="true"></object>
39+
</output>
40+
41+
ONLY return a valid JSON object (no other text is necessary), where the key of the field in JSON is the `name` attribute of the corresponding XML, and the value is of the type specified by the corresponding XML's tag. The JSON MUST conform to the XML format, including any types and format requests e.g. requests for lists, objects and specific types. Be correct and concise. If you are unsure anywhere, enter `null`.

0 commit comments

Comments
 (0)