Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
C
coderai
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexlab
coderai
Commits
f88c2e1d
Commit
f88c2e1d
authored
May 06, 2026
by
Stefy Lanza (nextime / spora )
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add multimodal client artifact handling
parent
30f105dc
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
0 deletions
+110
-0
test_manual_multimodal_test_client.py
tests/test_manual_multimodal_test_client.py
+51
-0
manual_multimodal_test_client.py
tools/manual_multimodal_test_client.py
+59
-0
No files found.
tests/test_manual_multimodal_test_client.py
View file @
f88c2e1d
...
...
@@ -3,6 +3,7 @@ from tools.manual_multimodal_test_client import (
build_request_spec
,
build_parser
,
choose_mode_interactively
,
handle_response_payload
,
parse_args
,
resolve_mode_config
,
)
...
...
@@ -353,3 +354,53 @@ def test_build_request_spec_for_transcription_requires_existing_audio_file(tmp_p
with
pytest
.
raises
(
FileNotFoundError
,
match
=
rf
"File not found: {missing_path}
\
. Supply --audio-file
\
."
):
build_request_spec
(
config
)
class
DummyResponse
:
def
__init__
(
self
,
payload
,
status_code
=
200
):
self
.
_payload
=
payload
self
.
status_code
=
status_code
self
.
text
=
"payload-text"
def
json
(
self
):
return
self
.
_payload
def
raise_for_status
(
self
):
if
self
.
status_code
>=
400
:
raise
RuntimeError
(
f
"HTTP {self.status_code}"
)
def
test_handle_response_payload_returns_llm_text_without_artifact
(
tmp_path
):
response
=
DummyResponse
({
"choices"
:
[{
"message"
:
{
"content"
:
"hello from model"
}}]
})
result
=
handle_response_payload
(
"llm"
,
response
,
tmp_path
)
assert
result
[
"text"
]
==
"hello from model"
assert
result
[
"artifact_path"
]
is
None
def
test_handle_response_payload_downloads_url_artifact
(
monkeypatch
,
tmp_path
):
response
=
DummyResponse
({
"data"
:
[{
"url"
:
"http://example.invalid/audio.wav"
}]
})
monkeypatch
.
setattr
(
"tools.manual_multimodal_test_client._download_artifact"
,
lambda
url
:
b
"wave-bytes"
,
)
result
=
handle_response_payload
(
"audio-generation"
,
response
,
tmp_path
)
assert
result
[
"artifact_path"
]
.
suffix
==
".wav"
assert
result
[
"artifact_path"
]
.
read_bytes
()
==
b
"wave-bytes"
def
test_handle_response_payload_decodes_base64_artifact
(
tmp_path
):
response
=
DummyResponse
({
"data"
:
[{
"b64_json"
:
"aGVsbG8="
}]
})
result
=
handle_response_payload
(
"audio-generation"
,
response
,
tmp_path
)
assert
result
[
"artifact_path"
]
.
read_bytes
()
==
b
"hello"
tools/manual_multimodal_test_client.py
View file @
f88c2e1d
from
__future__
import
annotations
import
argparse
import
base64
import
json
import
time
from
pathlib
import
Path
import
requests
MODES
=
[
"llm"
,
...
...
@@ -192,3 +197,57 @@ def choose_mode_interactively() -> str:
if
selected
<
1
or
selected
>
len
(
MODES
):
raise
ValueError
(
f
"Invalid mode selection: {raw}"
)
return
MODES
[
selected
-
1
]
def
_download_artifact
(
url
:
str
)
->
bytes
:
response
=
requests
.
get
(
url
,
timeout
=
60
)
response
.
raise_for_status
()
return
response
.
content
def
_artifact_suffix_for_mode
(
mode
:
str
)
->
str
:
if
mode
==
"audio-generation"
:
return
".wav"
if
mode
==
"video-generation"
:
return
".mp4"
return
".bin"
def
_write_artifact
(
output_dir
:
Path
,
mode
:
str
,
payload
:
bytes
)
->
Path
:
output_dir
.
mkdir
(
parents
=
True
,
exist_ok
=
True
)
artifact_path
=
output_dir
/
f
"{mode}-{int(time.time() * 1000)}{_artifact_suffix_for_mode(mode)}"
artifact_path
.
write_bytes
(
payload
)
return
artifact_path
def
handle_response_payload
(
mode
:
str
,
response
,
output_dir
:
Path
)
->
dict
:
response
.
raise_for_status
()
payload
=
response
.
json
()
if
mode
in
{
"llm"
,
"video-doubt"
,
"music-audio-doubt"
}:
text
=
payload
[
"choices"
][
0
][
"message"
][
"content"
]
return
{
"text"
:
text
,
"artifact_path"
:
None
,
"payload"
:
payload
}
if
mode
==
"transcription"
:
text
=
payload
.
get
(
"text"
)
or
payload
.
get
(
"transcript"
)
or
json
.
dumps
(
payload
)
return
{
"text"
:
text
,
"artifact_path"
:
None
,
"payload"
:
payload
}
if
mode
in
{
"audio-generation"
,
"video-generation"
}:
first
=
payload
[
"data"
][
0
]
text
=
first
.
get
(
"text"
)
or
first
.
get
(
"caption"
)
or
""
if
"url"
in
first
:
artifact_bytes
=
_download_artifact
(
first
[
"url"
])
elif
"b64_json"
in
first
:
artifact_bytes
=
base64
.
b64decode
(
first
[
"b64_json"
])
else
:
raise
ValueError
(
f
"No artifact found in generation response for mode: {mode}"
)
artifact_path
=
_write_artifact
(
output_dir
,
mode
,
artifact_bytes
)
return
{
"text"
:
text
,
"artifact_path"
:
artifact_path
,
"payload"
:
payload
}
raise
ValueError
(
f
"Unsupported response mode: {mode}"
)
def
execute_request
(
spec
:
dict
):
method
=
spec
[
"method"
]
kwargs
=
{
key
:
value
for
key
,
value
in
spec
.
items
()
if
key
not
in
{
"method"
,
"url"
}}
return
requests
.
request
(
method
,
spec
[
"url"
],
timeout
=
300
,
**
kwargs
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment