microsoft / semantic-kernel

Integrate cutting-edge LLM technology quickly and easily into your apps
https://aka.ms/semantic-kernel
MIT License
21.97k stars 3.27k forks source link

Python: json.decoder.JSONDecodeError: Extra data: line 7 column 1 (char 125) #1930

Closed ewitkon closed 1 year ago

ewitkon commented 1 year ago

Describe the bug A clear and concise description of what the bug is.

When running the sample python hello world we get: json.decoder.JSONDecodeError: Extra data: line 7 column 1 (char 125)

Exception has occurred: JSONDecodeError
Extra data: line 7 column 1 (char 125)
  File "/Volumes/git/osdk-semanticKernel-python/hello_world/main.py", line 34, in main
    result = await planner.execute_plan_async(plan, kernel)
  File "/Volumes/git/osdk-semanticKernel-python/hello_world/main.py", line 54, in <module>
    asyncio.run(main())
json.decoder.JSONDecodeError: Extra data: line 7 column 1 (char 125)

config: kernel.add_chat_service("dv", AzureTextCompletion(deployment, endpoint, api_key))

AZURE_OPENAI_ENDPOINT="https://api.llm.palantir.tech/preview"
AZURE_OPENAI_DEPLOYMENT_NAME="gpt-35-turbo"

Expected behavior A clear and concise description of what you expected to happen.

This does not happens with OPENAI

Screenshots If applicable, add screenshots to help explain your problem. image

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

ewitkon commented 1 year ago

Here is a full repro of the problem:

import semantic_kernel as sk

kernel = sk.Kernel()
from semantic_kernel.connectors.ai.open_ai import AzureTextCompletion

deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
kernel.add_text_completion_service("dv", AzureTextCompletion(deployment, endpoint, api_key))
<semantic_kernel.kernel.Kernel at 0x7fb1707c0c40>
kernel.set_default_text_completion_service("dv")
<semantic_kernel.kernel.Kernel at 0x7fb1707c0c40>
import sys

from dotenv import dotenv_values

from semantic_kernel.skill_definition import (
    sk_function,
)
from semantic_kernel.orchestration.sk_context import SKContext
sys.path.append("./generated/")
from foundry_osdk import OntologyClient
config = dotenv_values(".env")
client = OntologyClient(hostname=config["FOUNDRY_HOSTNAME"], token=config["FOUNDRY_AUTH_TOKEN"])

class OSDKPlugin:

    def _search_for_flight(airport_code: str) -> str:        
        from foundry_osdk.dev_opi_test_ontology.search import Flight

        myOntology = client.dev_opi_test_ontology
        myFlights = myOntology.objects.Flight
        results = myFlights.where(Flight.arrival_airport_code == airport_code).take(1)
        return str(results[0])

    @sk_function(
        description="Searches for a flight by airport arrival code",
        name="search_for_flight",
        input_description="The code of the airport to search for",
    )
    def search_for_flight(self, airport_code: str) -> str:        
        return str(OSDKPlugin._search_for_flight(airport_code))

    @sk_function(
        description="Searches for an aircraft by aircraft registration returning its properties",
        name="search_for_aircraft",
        input_description="The aircraft registration to search for",
    )
    def search_for_aircraft(self, aircraft_registration: str) -> str:
        from foundry_osdk.dev_opi_test_ontology.search import Aircraft
        myOntology = client.dev_opi_test_ontology
        myAircraft = myOntology.objects.Aircraft
        results = myAircraft.where(Aircraft.aircraft_registration ==aircraft_registration).take(1)
        return str(results)
from semantic_kernel.planning.basic_planner import BasicPlanner
planner = BasicPlanner()
# Import the native functions
osdkPlugin = kernel.import_skill(OSDKPlugin(), "OSDKPlugin")

ask = "Which flights are arriving to airport code JFK?"
plan = await planner.create_plan_async(ask, kernel)

# print(plan.generated_plan)
# Execute the plan
# result = await planner.execute_plan_async(plan, kernel)

# print("Plan results:")
# print(result)
print(OSDKPlugin._search_for_flight("JFK"))
# Execute the plan
result = await planner.execute_plan_async(plan, kernel)
# print("Plan results:")
print(result)
Flight(arrival_city=New York, arrival_airport_code=JFK, type=A320, airline_id=1, arrival_latitude=40.63980103, scheduled_departure_time=1398772480000000, departure_geohash=33.63669968,-84.42810059, title=ATL-JFK-2014-04-29 11:54:40, departure_latitude=33.63669968, plane_id=117, departure_airport_code=ATL, flight_id=568918, decision_workflow_id=Aircraft Swap, aircraft_registration=Q-AEM, departure_city=Atlanta, scheduled_arrival_time=1398785690000000, arrival_longitude=-73.77890015, departure_longitude=-84.42810059, arrival_geohash=40.63980103,-73.77890015)

---------------------------------------------------------------------------

JSONDecodeError                           Traceback (most recent call last)

Cell In[6], line 15
     13 print(OSDKPlugin._search_for_flight("JFK"))
     14 # Execute the plan
---> 15 result = await planner.execute_plan_async(plan, kernel)
     16 # print("Plan results:")
     17 print(result)

File ~/miniconda3/lib/python3.10/site-packages/semantic_kernel/planning/basic_planner.py:190, in BasicPlanner.execute_plan_async(self, plan, kernel)
    185 async def execute_plan_async(self, plan: Plan, kernel: Kernel) -> str:
    186     """
    187     Given a plan, execute each of the functions within the plan
    188     from start to finish and output the result.
    189     """
--> 190     generated_plan = json.loads(plan.generated_plan.result)
    192     context = ContextVariables()
    193     context["input"] = generated_plan["input"]

File ~/miniconda3/lib/python3.10/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    341     s = s.decode(detect_encoding(s), 'surrogatepass')
    343 if (cls is None and object_hook is None and
    344         parse_int is None and parse_float is None and
    345         parse_constant is None and object_pairs_hook is None and not kw):
--> 346     return _default_decoder.decode(s)
    347 if cls is None:
    348     cls = JSONDecoder

File ~/miniconda3/lib/python3.10/json/decoder.py:340, in JSONDecoder.decode(self, s, _w)
    338 end = _w(s, end).end()
    339 if end != len(s):
--> 340     raise JSONDecodeError("Extra data", s, end)
    341 return obj

JSONDecodeError: Extra data: line 8 column 1 (char 126)
ewitkon commented 1 year ago
!python -m pip show semantic-kernel
Name: semantic-kernel
Version: 0.3.1.dev0
Summary: 
Home-page: 
Author: Microsoft
Author-email: SK-Support@microsoft.com
License: 
Location: /Users/ewitkon/miniconda3/lib/python3.10/site-packages
Requires: aiofiles, numpy, openai, python-dotenv
Required-by: 
kajasherif commented 1 year ago

When running the sample semantic kernel code, I'm facing this issue.

image

ewitkon commented 1 year ago

For me this problem was solved by using a different model kernel.add_text_completion_service("dv", AzureTextCompletion("text_devinchi_003", endpoint, api_key))

alexchaomander commented 1 year ago

Thanks for the detailed walkthrough of the error! We'll definitely take a look. I'll also point out that this might be resolved with some of the new planners and the updated plan object model that's currently in PR

1916 #1907 #1948

alexchaomander commented 1 year ago

Also just from looking at it, text completion models should be matched with the right one (i.e. text-davinci-003)

If you want to use gpt-35-turbo, you'll need to use the AzureChatCompletion

if useAzureOpenAI:
    deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
    kernel.add_chat_service(
        "chat_completion",
        AzureChatCompletion("gpt-35-turbo", endpoint, api_key),
    )
else:
    api_key, org_id = sk.openai_settings_from_dot_env()
    kernel.add_chat_service(
        "chat-gpt", OpenAIChatCompletion("gpt-3.5-turbo", api_key, org_id)
    )
nacharya1 commented 1 year ago

@ewitkon - Alex's suggestion should solve this issue for you. Let us know if this issue is still persisting for you and we can look into this again.