-
Notifications
You must be signed in to change notification settings - Fork 290
Introduce chat history class #2816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
apaniukov
merged 45 commits into
openvinotoolkit:master
from
yatarkan:yt/json-chat-history
Oct 17, 2025
Merged
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
87d0e32
Add json container class
yatarkan c85d316
Enable int and json container types in any to json function
yatarkan dc5f639
Add unit tests for json container
yatarkan 8d97cb0
Remove commented code
yatarkan 6fc758e
Fix equality tests
yatarkan 15f55b0
Add tests for copy, share and move
yatarkan 9501674
Merge branch 'master' into yt/json-container
yatarkan ac4dcf4
Rename methods
yatarkan 1bec5e1
Add static methods for creating empty json array and object container
yatarkan 513721e
Fix spelling
yatarkan aa81b51
Remove redundant include
yatarkan 3c888f2
Add test for json container modification
yatarkan bfa7687
Add chat history class
yatarkan 54f7815
Update apply chat template with chat history
yatarkan 07faaa0
Fix chat history usages in pipelines
yatarkan cad08f9
Add py object to json container utility function
yatarkan aabc834
Update apply chat template python binding with chat history
yatarkan 6b61440
Remove json keys sorting in apply chat template test
yatarkan b884418
Merge branch 'master' into yt/json-chat-history
yatarkan bb24aee
Add chat history class bindings
yatarkan b3fc29f
Update python bindings
yatarkan b0b97d5
Add assert hf equals genai utility function
yatarkan befe3b6
Add test with chat history instance in apply chat template
yatarkan 81e0f25
Move chat history bindings to separate file
yatarkan ac133cc
Fix spacing
yatarkan 3aac1be
Fix python bindings
yatarkan 6af46db
Switch json container to PIMPL, add json adl serializer, update tests…
yatarkan 3274723
Fix JS bindings for new chat history
yatarkan 6074863
Merge branch 'master' into yt/json-chat-history
yatarkan ef16c97
Update tokenizer JS tests to match new chat history
yatarkan 6c80af0
Fix lint
yatarkan 32d29fb
Merge branch 'master' into yt/json-chat-history
yatarkan aa10568
Add tools and extra context to chat history
yatarkan bf55512
Make tools and extra context optional in apply chat template with pri…
yatarkan 2ae2636
Update python bindings
yatarkan 40f8576
Update JS bindings for new apply chat template
yatarkan c63d0e7
Add JS tests for tools and extra context in apply chat template
yatarkan f8fbc5c
Add python test for checking tools/extra_context in chat history and …
yatarkan cc4aa64
Merge branch 'master' into yt/json-chat-history
yatarkan adf10a9
Fix JS tokenizer tests
yatarkan e7206ca
Merge branch 'master' into yt/json-chat-history
yatarkan d75a22c
Add todo
yatarkan 662aa38
Add utility method for converting json container to py object
yatarkan 48cec9d
Reuse json_container_to_py_object method
yatarkan 64ec9c6
Merge branch 'master' into yt/json-chat-history
yatarkan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (C) 2025 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include "openvino/genai/visibility.hpp" | ||
#include "openvino/genai/json_container.hpp" | ||
|
||
namespace ov { | ||
namespace genai { | ||
|
||
/** | ||
* @brief ChatHistory stores conversation messages and optional metadata for chat templates. | ||
* | ||
* Manages: | ||
* - Message history (array of message objects) | ||
* - Optional tools definitions array (for function calling) | ||
* - Optional extra context object (for custom template variables) | ||
*/ | ||
class OPENVINO_GENAI_EXPORTS ChatHistory { | ||
public: | ||
ChatHistory(); | ||
|
||
explicit ChatHistory(const JsonContainer& messages); | ||
|
||
explicit ChatHistory(const std::vector<ov::AnyMap>& messages); | ||
|
||
/** | ||
* @brief Construct from initializer list for convenient inline creation. | ||
* | ||
* Example: | ||
* ChatHistory history({ | ||
* {{"role", "system"}, {"content", "You are helpful assistant."}}, | ||
* {{"role", "user"}, {"content", "Hello"}} | ||
* }); | ||
*/ | ||
ChatHistory(std::initializer_list<std::initializer_list<std::pair<std::string, ov::Any>>> messages); | ||
|
||
~ChatHistory(); | ||
|
||
ChatHistory& push_back(const JsonContainer& message); | ||
ChatHistory& push_back(const ov::AnyMap& message); | ||
ChatHistory& push_back(std::initializer_list<std::pair<std::string, ov::Any>> message); | ||
|
||
void pop_back(); | ||
|
||
const JsonContainer& get_messages() const; | ||
JsonContainer& get_messages(); | ||
|
||
JsonContainer operator[](size_t index) const; | ||
JsonContainer operator[](int index) const; | ||
|
||
JsonContainer first() const; | ||
JsonContainer last() const; | ||
|
||
void clear(); | ||
|
||
size_t size() const; | ||
bool empty() const; | ||
|
||
ChatHistory& set_tools(const JsonContainer& tools); | ||
const JsonContainer& get_tools() const; | ||
|
||
ChatHistory& set_extra_context(const JsonContainer& extra_context); | ||
const JsonContainer& get_extra_context() const; | ||
|
||
private: | ||
JsonContainer m_messages = JsonContainer::array(); | ||
JsonContainer m_tools = JsonContainer::array(); | ||
JsonContainer m_extra_context = JsonContainer::object(); | ||
}; | ||
|
||
} // namespace genai | ||
} // namespace ov |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
// Copyright (C) 2025 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "openvino/genai/chat_history.hpp" | ||
|
||
namespace ov { | ||
namespace genai { | ||
|
||
ChatHistory::ChatHistory() = default; | ||
|
||
ChatHistory::ChatHistory(const JsonContainer& messages) : m_messages(messages) { | ||
if (!m_messages.is_array()) { | ||
OPENVINO_THROW("Chat history must be initialized with a JSON array."); | ||
} | ||
} | ||
ChatHistory::ChatHistory(const std::vector<ov::AnyMap>& messages) : | ||
m_messages(JsonContainer::array()) { | ||
for (const auto& message : messages) { | ||
m_messages.push_back(JsonContainer(message)); | ||
} | ||
} | ||
|
||
ChatHistory::ChatHistory(std::initializer_list<std::initializer_list<std::pair<std::string, ov::Any>>> messages) : | ||
m_messages(JsonContainer::array()) { | ||
for (const auto& message : messages) { | ||
m_messages.push_back(JsonContainer(message)); | ||
} | ||
} | ||
|
||
ChatHistory::~ChatHistory() = default; | ||
|
||
ChatHistory& ChatHistory::push_back(const JsonContainer& message) { | ||
m_messages.push_back(message); | ||
return *this; | ||
} | ||
|
||
ChatHistory& ChatHistory::push_back(const ov::AnyMap& message) { | ||
m_messages.push_back(JsonContainer(message)); | ||
return *this; | ||
} | ||
|
||
ChatHistory& ChatHistory::push_back(std::initializer_list<std::pair<std::string, ov::Any>> message) { | ||
m_messages.push_back(JsonContainer(message)); | ||
return *this; | ||
} | ||
|
||
void ChatHistory::pop_back() { | ||
if (m_messages.empty()) { | ||
OPENVINO_THROW("Cannot pop_back from an empty chat history."); | ||
} | ||
m_messages.erase(m_messages.size() - 1); | ||
} | ||
|
||
const JsonContainer& ChatHistory::get_messages() const { | ||
return m_messages; | ||
} | ||
|
||
JsonContainer& ChatHistory::get_messages() { | ||
return m_messages; | ||
} | ||
|
||
JsonContainer ChatHistory::operator[](size_t index) const { | ||
if (index >= m_messages.size()) { | ||
OPENVINO_THROW("Index ", index, " is out of bounds for chat history of size ", m_messages.size()); | ||
} | ||
return m_messages[index]; | ||
} | ||
|
||
JsonContainer ChatHistory::operator[](int index) const { | ||
return operator[](size_t(index)); | ||
} | ||
|
||
JsonContainer ChatHistory::first() const { | ||
if (m_messages.empty()) { | ||
OPENVINO_THROW("Cannot access first message of an empty chat history."); | ||
} | ||
return m_messages[0]; | ||
} | ||
|
||
JsonContainer ChatHistory::last() const { | ||
if (m_messages.empty()) { | ||
OPENVINO_THROW("Cannot access last message of an empty chat history."); | ||
} | ||
return m_messages[m_messages.size() - 1]; | ||
} | ||
|
||
void ChatHistory::clear() { | ||
m_messages.clear(); | ||
} | ||
|
||
size_t ChatHistory::size() const { | ||
return m_messages.size(); | ||
} | ||
|
||
bool ChatHistory::empty() const { | ||
return m_messages.empty(); | ||
} | ||
|
||
ChatHistory& ChatHistory::set_tools(const JsonContainer& tools) { | ||
if (!tools.is_array()) { | ||
OPENVINO_THROW("Tools must be an array-like JsonContainer."); | ||
} | ||
m_tools = tools; | ||
return *this; | ||
} | ||
|
||
const JsonContainer& ChatHistory::get_tools() const { | ||
return m_tools; | ||
} | ||
|
||
ChatHistory& ChatHistory::set_extra_context(const JsonContainer& extra_context) { | ||
if (!extra_context.is_object()) { | ||
OPENVINO_THROW("Extra context must be an object-like JsonContainer."); | ||
} | ||
m_extra_context = extra_context; | ||
return *this; | ||
} | ||
|
||
const JsonContainer& ChatHistory::get_extra_context() const { | ||
return m_extra_context; | ||
} | ||
|
||
} // namespace genai | ||
} // namespace ov |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.