mirror of
https://github.com/wolfpld/tracy
synced 2026-01-19 04:52:09 +00:00
Retrieve images from wikipedia.
This commit is contained in:
@@ -224,3 +224,18 @@ CPMAddPackage(
|
||||
VERSION 0.9.5
|
||||
DOWNLOAD_ONLY TRUE
|
||||
)
|
||||
|
||||
# base64
|
||||
|
||||
set(BUILD_SHARED_LIBS_SAVE ${BUILD_SHARED_LIBS})
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
CPMAddPackage(
|
||||
NAME base64
|
||||
GITHUB_REPOSITORY aklomp/base64
|
||||
GIT_TAG v0.5.2
|
||||
OPTIONS
|
||||
"BASE64_BUILD_CLI OFF"
|
||||
"BASE64_WITH_OpenMP OFF"
|
||||
EXCLUDE_FROM_ALL TRUE
|
||||
)
|
||||
set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVE})
|
||||
|
||||
@@ -206,7 +206,7 @@ else()
|
||||
endif()
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE TracyServer TracyImGui Threads::Threads TracyLibcurl)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE TracyServer TracyImGui Threads::Threads TracyLibcurl base64)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${ollama-hpp_SOURCE_DIR}/include)
|
||||
|
||||
if(NOT DEFINED GIT_REV)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <libbase64.h>
|
||||
#include <curl/curl.h>
|
||||
#include <ollama.hpp>
|
||||
#include <stdint.h>
|
||||
@@ -643,7 +644,16 @@ bool TracyLlm::OnResponse( const ollama::response& response )
|
||||
auto tool = lines[0];
|
||||
lines.erase( lines.begin() );
|
||||
const auto reply = HandleToolCalls( tool, lines );
|
||||
m_chat->emplace_back( ollama::message( "tool", reply ) );
|
||||
if( reply.image.empty() )
|
||||
{
|
||||
m_chat->emplace_back( ollama::message( "tool", reply.reply ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<ollama::image> images;
|
||||
images.emplace_back( ollama::image::from_base64_string( reply.image ) );
|
||||
m_chat->emplace_back( ollama::message( "tool", reply.reply, images ) );
|
||||
}
|
||||
|
||||
m_jobs.emplace_back( WorkItem {
|
||||
.task = Task::SendMessage,
|
||||
@@ -792,37 +802,25 @@ static std::string UrlEncode( const std::string& str )
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string TracyLlm::HandleToolCalls( const std::string& name, const std::vector<std::string>& args )
|
||||
TracyLlm::ToolReply TracyLlm::HandleToolCalls( const std::string& name, const std::vector<std::string>& args )
|
||||
{
|
||||
if( name == "get_current_time" ) return GetCurrentTime();
|
||||
if( name == "get_current_time" ) return { .reply = GetCurrentTime() };
|
||||
if( name == "fetch_web_page" )
|
||||
{
|
||||
if( args.empty() ) return "Missing URL argument";
|
||||
return FetchWebPage( args[0] );
|
||||
if( args.empty() ) return { .reply = "Missing URL argument" };
|
||||
return { .reply = FetchWebPage( args[0] ) };
|
||||
}
|
||||
if( name == "search_wikipedia" )
|
||||
{
|
||||
if( args.empty() ) return "Missing search term argument";
|
||||
auto query = args[0];
|
||||
std::ranges::replace( query, ' ', '+' );
|
||||
return FetchWebPage( "https://en.wikipedia.org/w/rest.php/v1/search/page?q=" + UrlEncode( query ) + "&limit=1" );
|
||||
if( args.empty() ) return { .reply = "Missing search term argument" };
|
||||
return SearchWikipedia( args[0] );
|
||||
}
|
||||
if( name == "get_wikipedia" )
|
||||
{
|
||||
if( args.empty() ) return "Missing page name argument";
|
||||
auto page = args[0];
|
||||
std::ranges::replace( page, ' ', '_' );
|
||||
auto res = FetchWebPage( "https://en.wikipedia.org/w/rest.php/v1/page/" + page );
|
||||
|
||||
// Limit the size of the response to avoid exceeding the context size
|
||||
// Assume average token size is 4 bytes. Make space for 3 articles to be retrieved.
|
||||
const auto ctxSize = std::min( m_models[m_modelIdx].ctxSize, s_config.llmContext );
|
||||
const auto maxSize = ( ctxSize * 4 ) / 3;
|
||||
|
||||
if( res.size() > maxSize ) res = res.substr( 0, maxSize );
|
||||
return res;
|
||||
if( args.empty() ) return { .reply = "Missing page name argument" };
|
||||
return { .reply = GetWikipedia( args[0] ) };
|
||||
}
|
||||
return "Unknown tool call: " + name;
|
||||
return { .reply = "Unknown tool call: " + name };
|
||||
}
|
||||
|
||||
std::string TracyLlm::GetCurrentTime()
|
||||
@@ -883,4 +881,59 @@ std::string TracyLlm::FetchWebPage( const std::string& url )
|
||||
return response;
|
||||
}
|
||||
|
||||
TracyLlm::ToolReply TracyLlm::SearchWikipedia( std::string query )
|
||||
{
|
||||
std::ranges::replace( query, ' ', '+' );
|
||||
const auto response = FetchWebPage( "https://en.wikipedia.org/w/rest.php/v1/search/page?q=" + UrlEncode( query ) + "&limit=1" );
|
||||
auto json = nlohmann::json::parse( response );
|
||||
std::string reply = "No results found";
|
||||
std::string image;
|
||||
if( json.contains( "pages" ) )
|
||||
{
|
||||
auto& page = json["pages"];
|
||||
if( page.size() > 0 )
|
||||
{
|
||||
auto& page0 = page[0];
|
||||
reply = page0.dump( 2 );
|
||||
if( page0.contains( "thumbnail" ) )
|
||||
{
|
||||
auto& thumb = page0["thumbnail"];
|
||||
if( thumb.contains( "url" ) )
|
||||
{
|
||||
auto url = "https:" + thumb["url"].get_ref<const std::string&>();
|
||||
url = url.substr( 0, url.find_last_of( '/' ) );
|
||||
auto pos = url.find( "/thumb" );
|
||||
url.erase( pos, 6 );
|
||||
auto imgData = FetchWebPage( url );
|
||||
if( !imgData.empty() && imgData[0] != '<' && strncmp( imgData.c_str(), "Error:", 6 ) != 0 )
|
||||
{
|
||||
size_t b64sz = ( ( 4 * imgData.size() / 3 ) + 3 ) & ~3;
|
||||
char* b64 = new char[b64sz+1];
|
||||
b64[b64sz] = 0;
|
||||
size_t outSz;
|
||||
base64_encode( (const char*)imgData.data(), imgData.size(), b64, &outSz, 0 );
|
||||
image = std::string( b64, outSz );
|
||||
delete[] b64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { .reply = reply, .image = image };
|
||||
}
|
||||
|
||||
std::string TracyLlm::GetWikipedia( std::string page )
|
||||
{
|
||||
std::ranges::replace( page, ' ', '_' );
|
||||
auto res = FetchWebPage( "https://en.wikipedia.org/w/rest.php/v1/page/" + page );
|
||||
|
||||
// Limit the size of the response to avoid exceeding the context size
|
||||
// Assume average token size is 4 bytes. Make space for 3 articles to be retrieved.
|
||||
const auto ctxSize = std::min( m_models[m_modelIdx].ctxSize, s_config.llmContext );
|
||||
const auto maxSize = ( ctxSize * 4 ) / 3;
|
||||
|
||||
if( res.size() > maxSize ) res = res.substr( 0, maxSize );
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,6 +53,12 @@ class TracyLlm
|
||||
bool codeBlock;
|
||||
};
|
||||
|
||||
struct ToolReply
|
||||
{
|
||||
std::string reply;
|
||||
std::string image;
|
||||
};
|
||||
|
||||
public:
|
||||
struct LlmModel
|
||||
{
|
||||
@@ -91,10 +97,12 @@ private:
|
||||
void PrintLine( LineContext& ctx, const std::string& str, int num );
|
||||
void CleanContext( LineContext& ctx);
|
||||
|
||||
std::string HandleToolCalls( const std::string& name, const std::vector<std::string>& args );
|
||||
ToolReply HandleToolCalls( const std::string& name, const std::vector<std::string>& args );
|
||||
|
||||
std::string GetCurrentTime();
|
||||
std::string FetchWebPage( const std::string& url );
|
||||
ToolReply SearchWikipedia( std::string query );
|
||||
std::string GetWikipedia( std::string page );
|
||||
|
||||
std::unique_ptr<Ollama> m_ollama;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user