Quick Start Conversation

A brief overview of the conversational flow

Introduction

This guide provides a concise overview of how to engage in a conversation with the Nutrition Advisor using the API. It includes code examples in Python to help you get started quickly.

This guide assumes you have read and executed the Authorization Process and Request Setup. All requests in code examples pass an undefined headers which you can quickly build following the steps in the above guides.

The Response Object

All responses from the Nutrition Advisor will be returned in the AdvisorResponse object format:

Field
Type
Description

threadId

string

The unique identifier of the conversation thread.

messageId

string

The unique identifier of the advisor's response message.

content

string

The main content of the advisor's response. Empty if message has a dataRequest or actionResponse. Should be JSON decoded from string when received.

contentToolHints

[]string

An array of tool names (or empty) that the advisor has sensed could be useful to run on this response.

dataRequest

AdvisorDataRequest

If the advisor requires additional information, this field contains the details of the data request.

actionResponse

AdvisorActionResponse

If the advisor performs an action based on the message, this field contains the details of the action response.

usage

AdvisorResponseUsage

Information about the token usage for the response.

List Available Tools

To list the available tools, make a GET request to /v2/products/nutrition-advisor/tools. The response will include an array of tool objects with the following fields:

Field
Type
Description

name

string

The unique name of the tool.

displayName

string

The display name of the tool.

description

string

A brief description of what the tool does.

type

enum

The type of the tool: target, inputsense, or vision.

Code Example

import requests

url = "https://api.passiolife.com/v2/products/nutrition-advisor/tools"
response = requests.get(url, headers=headers)
tools = response.json()

# Store tools for future reference
cached_tools = {tool["name"]: tool for tool in tools}

Start A Conversation Thread

To start a new conversation, make a POST request to /v2/products/nutrition-advisor/threads. You can optionally include the ?plainText=true query parameter to receive plain text responses without markdown formatting.

Code Example

import requests

url = "https://api.passiolife.com/v2/products/nutrition-advisor/threads?plainText=false"
response = requests.post(url, headers=headers)
advisor_response = response.json()

thread_id = advisor_response["threadId"]

Interraction Flow

When you receive an AdvisorResponse back from the Nutrition Advisor, follow these steps:

1. Check if content is non-empty (Lines 2-17)

  • If so, parse contentToolHints.

  • If any tools are found, match them to the name field of a cached available tool.

  • Use a switch statement based on the tool name to handle specific cases.

  • For example, if the tool name is "SearchIngredientMatches", make a call to the target tool type using the message.

2. Check if dataRequest is not null (Lines 19-40)

  • If not null, parse the name field and use a switch statement to handle specific cases.

  • For example, if the tool name is "DetectMealLogsRequired" and the parameters field contains daysBack: 1, respond to the data request with the appropriate meal log data.

3. Check if actionResponse is not null (Lines 41-48)

  • If not null, parse the name field and use a switch statement to handle specific cases.

  • For example, if the tool name is "SearchIngredientMatches", parse the data field as JSON to obtain an array of ingredient data.

Code Example

def handle_advisor_response(advisor_response, thread_id, cached_tools):
    # check the advisor for `content`. This is its text-response to the chat
    # If a value exists here, no value will exist in either
    # `dataRequest` or `actionResponse`
    if advisor_response["content"]:
        content = json.loads(advisor_response["content"])
        tool_hints = advisor_response["contentToolHints"]
        
        for tool_name in tool_hints:
            if tool_name in cached_tools:
                if tool_name == "SearchIngredientMatches":
                    tool_url = f"https://api.passiolife.com/v2/products/nutrition-advisor/threads/{thread_id}/messages/tools/target/{tool_name}"
                    tool_response = requests.post(tool_url, json={"messageId": advisor_response["messageId"]}, headers=headers)
                    
                    # Recursively handle the response from the tool request
                    handle_advisor_response(tool_response.json(), thread_id, cached_tools)
                    return
                    
    # If we sent a message with InputSense tools enabled, the response might
    # contain `content`, if no input sense tools were detected as necessary.
    # otherwise, `content` is empty and `dataRequest` is filled, containing
    # info on the data you need to proivde
    if advisor_response["dataRequest"]:
        data_request = advisor_response["dataRequest"]
        
        if data_request["name"] == "DetectMealLogsRequired":
            parameters = json.loads(data_request["respondParameters"])
            days_back = parameters["daysBack"]
            
            respond_url = f"https://api.passiolife.com/v2/products/nutrition-advisor/threads/{thread_id}/messages/{advisor_response['messageId']}/respond"
            respond_data = {
                "data": "...",
                "runId": data_request["runId"],
                "toolCallId": data_request["toolCallId"]
            }
            respond_response = requests.post(respond_url, json=respond_data, headers=headers)
            
            # Recursively handle the response from fulfilling the data request
            handle_advisor_response(respond_response.json(), thread_id, cached_tools)
            return

    # If we sent a tool request, parse actionResponse to retrieve its data
    if advisor_response["actionResponse"]:
        action_response = advisor_response["actionResponse"]
        
        if action_response["name"] == "SearchIngredientMatches":
            ingredient_data = json.loads(action_response["data"])
            # ... do something with the ingredient data
            

Last updated