Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit fc53976

Browse files
authored
fix: add support image url for jan (#1798)
1 parent 5e84fb5 commit fc53976

File tree

4 files changed

+54
-15
lines changed

4 files changed

+54
-15
lines changed

engine/common/message.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,27 @@ struct Message : JsonSerializable {
137137
if (root["content"].isArray() && !root["content"].empty()) {
138138
if (root["content"][0]["type"].asString() == "text") {
139139
message.content = ParseContents(std::move(root["content"])).value();
140+
} else if (root["content"][0]["type"].asString() == "image") {
141+
// deprecated, for supporting jan and should be removed in the future
142+
auto text_str = root["content"][0]["text"]["value"].asString();
143+
auto img_url =
144+
root["content"][0]["text"]["annotations"][0].asString();
145+
auto text_content = std::make_unique<OpenAi::TextContent>();
146+
{
147+
auto text = OpenAi::Text();
148+
auto empty_annotations =
149+
std::vector<std::unique_ptr<Annotation>>();
150+
text.value = std::move(text_str);
151+
text.annotations = std::move(empty_annotations);
152+
text_content->text = std::move(text);
153+
}
154+
155+
auto image_url_obj = OpenAi::ImageUrl(img_url, "auto");
156+
auto image_url_content = std::make_unique<OpenAi::ImageUrlContent>(
157+
"image_url", std::move(image_url_obj));
158+
159+
message.content.push_back(std::move(text_content));
160+
message.content.push_back(std::move(image_url_content));
140161
} else {
141162
// deprecated, for supporting jan and should be removed in the future
142163
// check if annotations is empty

engine/common/message_content_image_url.h

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@
44

55
namespace OpenAi {
66

7-
struct ImageUrl {
8-
// The external URL of the image, must be a supported image types: jpeg, jpg, png, gif, webp.
7+
struct ImageUrl : public JsonSerializable {
8+
/**
9+
* The external URL of the image, must be a supported image types:
10+
* jpeg, jpg, png, gif, webp.
11+
*/
912
std::string url;
1013

11-
// Specifies the detail level of the image. low uses fewer tokens, you can opt in to high resolution using high. Default value is auto
14+
/**
15+
* Specifies the detail level of the image. low uses fewer tokens, you
16+
* can opt in to high resolution using high. Default value is auto
17+
*/
1218
std::string detail;
1319

14-
ImageUrl() = default;
20+
ImageUrl(const std::string& url, const std::string& detail = "auto")
21+
: url{url}, detail{detail} {}
1522

1623
ImageUrl(ImageUrl&&) noexcept = default;
1724

@@ -20,13 +27,25 @@ struct ImageUrl {
2027
ImageUrl(const ImageUrl&) = delete;
2128

2229
ImageUrl& operator=(const ImageUrl&) = delete;
30+
31+
cpp::result<Json::Value, std::string> ToJson() override {
32+
try {
33+
Json::Value root;
34+
root["url"] = url;
35+
root["detail"] = detail;
36+
return root;
37+
} catch (const std::exception& e) {
38+
return cpp::fail(std::string("ToJson failed: ") + e.what());
39+
}
40+
}
2341
};
2442

2543
// References an image URL in the content of a message.
2644
struct ImageUrlContent : Content {
2745

2846
// The type of the content part.
29-
ImageUrlContent(const std::string& type) : Content(type) {}
47+
explicit ImageUrlContent(const std::string& type, ImageUrl&& image_url)
48+
: Content(type), image_url{std::move(image_url)} {}
3049

3150
ImageUrlContent(ImageUrlContent&&) noexcept = default;
3251

@@ -38,18 +57,18 @@ struct ImageUrlContent : Content {
3857

3958
ImageUrl image_url;
4059

60+
~ImageUrlContent() override = default;
61+
4162
static cpp::result<ImageUrlContent, std::string> FromJson(
4263
Json::Value&& json) {
4364
if (json.empty()) {
4465
return cpp::fail("Json string is empty");
4566
}
4667

4768
try {
48-
ImageUrlContent content{"image_url"};
49-
ImageUrl image_url;
50-
image_url.url = std::move(json["image_url"]["url"].asString());
51-
image_url.detail = std::move(json["image_url"]["detail"].asString());
52-
content.image_url = std::move(image_url);
69+
auto image_url = ImageUrl(json["image_url"]["url"].asString(),
70+
json["image_url"]["detail"].asString());
71+
ImageUrlContent content{"image_url", std::move(image_url)};
5372
return content;
5473
} catch (const std::exception& e) {
5574
return cpp::fail(std::string("FromJson failed: ") + e.what());
@@ -60,8 +79,7 @@ struct ImageUrlContent : Content {
6079
try {
6180
Json::Value json;
6281
json["type"] = type;
63-
json["image_url"]["url"] = image_url.url;
64-
json["image_url"]["detail"] = image_url.detail;
82+
json["image_url"] = image_url.ToJson().value();
6583
return json;
6684
} catch (const std::exception& e) {
6785
return cpp::fail(std::string("ToJson failed: ") + e.what());

engine/common/message_content_text.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ struct FilePathWrapper : Annotation {
122122

123123
struct Text : JsonSerializable {
124124
// The data that makes up the text.
125-
126125
Text() = default;
127126

128127
Text(Text&&) noexcept = default;
@@ -214,6 +213,8 @@ struct TextContent : Content {
214213

215214
Text text;
216215

216+
~TextContent() override = default;
217+
217218
static cpp::result<TextContent, std::string> FromJson(Json::Value&& json) {
218219
if (json.empty()) {
219220
return cpp::fail("Json string is empty");

engine/test/components/test_models_db.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#include "database/models.h"
22
#include "gtest/gtest.h"
3-
#include "utils/file_manager_utils.h"
43

54
namespace cortex::db {
65
namespace {
@@ -122,4 +121,4 @@ TEST_F(ModelsTestSuite, TestHasModel) {
122121
EXPECT_TRUE(model_list_.DeleteModelEntry(kTestModel.model).value());
123122
}
124123

125-
} // namespace cortex::db
124+
} // namespace cortex::db

0 commit comments

Comments
 (0)