theodo-group / LLPhant

LLPhant - A comprehensive PHP Generative AI Framework using OpenAI GPT 4. Inspired by Langchain
MIT License
775 stars 79 forks source link

Feed called function results back into OpenAI #219

Open prykris opened 5 days ago

prykris commented 5 days ago

Since the conversation history is built using Message instances it doesn't allow me to return the called function result back into the conversation.

The error I receive: Invalid parameter: messages with role 'tool' must be a response to a preceding message with 'tool_calls'.

Route::get('/tools-test', function () {
    $config = new OpenAIConfig;
    $config->apiKey = config('services.openai.api_key');

    $chatSession = new ChatSession(
        new OpenAIChat($config),
        []
    );

    $chatSession->getChat()->addTool(FunctionBuilder::buildFunctionInfo(new class
    {
        /**
         * Returns current user's username
         */
        public function getUserName(): string
        {
            return auth()->user()->name;
        }
    }, 'getUserName'));

    dd($chatSession('What is my username?'));
});

Here is how I handle the tool call, and attempt to feed it back

public function generateResult(string $prompt): Result
    {
        $isFirstMessage = empty($this->results);
        $history = $this->buildChatHistory($prompt);

        $start = microtime(true);
        $responseOrFunction = $this->chat->generateChatOrReturnFunctionCalled($history);
        $end = microtime(true);

        $responseObject = $this->chat->getLastResponse();

        if ($responseOrFunction instanceof FunctionInfo) {
            $history[] = Message::toolResult(
                FunctionRunner::run($responseOrFunction)
            );

            $responseText = $this->chat->generateChat($history);
        } else {
            $responseText = $responseOrFunction;
        }

        $llmResult = new Result(
            new Generation($prompt, $responseText),
            new Metadata(
                [
                    'prompt_tokens' => $responseObject->usage->promptTokens,
                    'completion_tokens' => $responseObject->usage->completionTokens,
                    'total_tokens' => $responseObject->usage->totalTokens,
                ],
                $responseObject->choices[0]->finishReason,
                $this->chat->model,
                $start,
                $end,
            ),
            $isFirstMessage
        );

        $this->results[] = $llmResult;

        return $llmResult;
    }

And if I attempt to use functionCall instead, I get the following error: Missing parameter 'name': messages with role 'function' must have a 'name'.

I can't seem to make it "work" without hacking the implementation of OpenAIChat, which I DO NOT want to do. But I might have to extend and overwrite the method in order to get it working.

functions are deprecated and are replaced by tools it seems, but there yet does not seem to be a way that properly returns tool call data.

prykris commented 5 days ago

https://github.com/theodo-group/LLPhant/pull/194/files