mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-14 15:52:11 +02:00
feat: pluggable image-to-text service with OpenAI vision backend (#1038)
Adds a full-stack image description service: schema, base class,
OpenAI backend, gateway dispatch, client APIs (sync/async REST +
websocket), tg-describe-image CLI, IAM capability, and specs.
Closes #879
This commit is contained in:
parent
9136526863
commit
40f01c123b
42 changed files with 1845 additions and 14 deletions
|
|
@ -33,6 +33,7 @@ tg-delete-flow-blueprint = "trustgraph.cli.delete_flow_blueprint:main"
|
|||
tg-delete-mcp-tool = "trustgraph.cli.delete_mcp_tool:main"
|
||||
tg-delete-kg-core = "trustgraph.cli.delete_kg_core:main"
|
||||
tg-delete-tool = "trustgraph.cli.delete_tool:main"
|
||||
tg-describe-image = "trustgraph.cli.describe_image:main"
|
||||
tg-dump-msgpack = "trustgraph.cli.dump_msgpack:main"
|
||||
tg-dump-queues = "trustgraph.cli.dump_queues:main"
|
||||
tg-monitor-prompts = "trustgraph.cli.monitor_prompts:main"
|
||||
|
|
|
|||
123
trustgraph-cli/trustgraph/cli/describe_image.py
Normal file
123
trustgraph-cli/trustgraph/cli/describe_image.py
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
"""
|
||||
Invokes the image-to-text service to produce a text description of an
|
||||
image file. The image MIME type is guessed from the filename unless
|
||||
specified.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import mimetypes
|
||||
import os
|
||||
from trustgraph.api import Api, TrustGraphException
|
||||
|
||||
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||
default_token = os.getenv("TRUSTGRAPH_TOKEN", None)
|
||||
default_workspace = os.getenv("TRUSTGRAPH_WORKSPACE", "default")
|
||||
|
||||
def query(url, flow_id, image, mime_type, prompt=None, system=None,
|
||||
token=None, workspace="default"):
|
||||
|
||||
with open(image, "rb") as f:
|
||||
image_data = f.read()
|
||||
|
||||
if mime_type is None:
|
||||
mime_type, _ = mimetypes.guess_type(image)
|
||||
if mime_type is None:
|
||||
raise RuntimeError(
|
||||
f"Can't guess MIME type of {image}, specify --mime-type"
|
||||
)
|
||||
|
||||
api = Api(url=url, token=token, workspace=workspace)
|
||||
socket = api.socket()
|
||||
flow = socket.flow(flow_id)
|
||||
|
||||
try:
|
||||
|
||||
result = flow.image_to_text(
|
||||
image=image_data,
|
||||
mime_type=mime_type,
|
||||
prompt=prompt,
|
||||
system=system,
|
||||
)
|
||||
|
||||
print(result.text)
|
||||
|
||||
finally:
|
||||
socket.close()
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='tg-describe-image',
|
||||
description=__doc__,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-u', '--url',
|
||||
default=default_url,
|
||||
help=f'API URL (default: {default_url})',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-t', '--token',
|
||||
default=default_token,
|
||||
help='Authentication token (default: $TRUSTGRAPH_TOKEN)',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-w', '--workspace',
|
||||
default=default_workspace,
|
||||
help=f'Workspace (default: {default_workspace})',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-f', '--flow-id',
|
||||
default="default",
|
||||
help=f'Flow ID (default: default)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-i', '--image',
|
||||
required=True,
|
||||
help='Image file to describe e.g. photo.jpg',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--mime-type',
|
||||
help='Image MIME type (default: guessed from filename)',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-p', '--prompt',
|
||||
help='Prompt to use e.g. What is shown in this image?',
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-s', '--system',
|
||||
help='System prompt to use',
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
|
||||
query(
|
||||
url=args.url,
|
||||
flow_id=args.flow_id,
|
||||
image=args.image,
|
||||
mime_type=args.mime_type,
|
||||
prompt=args.prompt,
|
||||
system=args.system,
|
||||
token=args.token,
|
||||
workspace=args.workspace,
|
||||
)
|
||||
|
||||
except TrustGraphException as e:
|
||||
|
||||
print(f"Error: [{e.error_type}] {e.message}", flush=True)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
print("Exception:", e, flush=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue