mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-21 11:11:03 +02:00
Major Python client API rework, break down API & colossal class
This commit is contained in:
parent
c49568dd34
commit
46a60d891c
29 changed files with 688 additions and 623 deletions
|
|
@ -1,61 +1,14 @@
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
import dataclasses
|
|
||||||
import base64
|
import base64
|
||||||
from typing import List
|
|
||||||
import datetime
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from trustgraph.knowledge import hash, Uri, Literal
|
from . library import Library
|
||||||
|
from . flow import Flow
|
||||||
class ProtocolException(Exception):
|
from . config import Config
|
||||||
pass
|
from . exceptions import *
|
||||||
|
from . types import *
|
||||||
class ApplicationException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class Triple:
|
|
||||||
s : str
|
|
||||||
p : str
|
|
||||||
o : str
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class ConfigKey:
|
|
||||||
type : str
|
|
||||||
key : str
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class ConfigValue:
|
|
||||||
type : str
|
|
||||||
key : str
|
|
||||||
value : str
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class DocumentMetadata:
|
|
||||||
id : str
|
|
||||||
time : datetime.datetime
|
|
||||||
kind : str
|
|
||||||
title : str
|
|
||||||
comments : str
|
|
||||||
metadata : List[Triple]
|
|
||||||
user : str
|
|
||||||
tags : List[str]
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
|
||||||
class ProcessingMetadata:
|
|
||||||
id : str
|
|
||||||
document_id : str
|
|
||||||
time : datetime.datetime
|
|
||||||
flow : str
|
|
||||||
user : str
|
|
||||||
collection : str
|
|
||||||
tags : List[str]
|
|
||||||
|
|
||||||
def to_value(x):
|
|
||||||
if x["e"]: return Uri(x["v"])
|
|
||||||
return Literal(x["v"])
|
|
||||||
|
|
||||||
def check_error(response):
|
def check_error(response):
|
||||||
|
|
||||||
|
|
@ -80,13 +33,19 @@ class Api:
|
||||||
|
|
||||||
self.url += "api/v1/"
|
self.url += "api/v1/"
|
||||||
|
|
||||||
def flow(self, flow="0000"):
|
def flow(self):
|
||||||
return Flow(api=self, flow=flow)
|
return Flow(api=self)
|
||||||
|
|
||||||
|
def config(self):
|
||||||
|
return Config(api=self)
|
||||||
|
|
||||||
def request(self, path, request):
|
def request(self, path, request):
|
||||||
|
|
||||||
url = f"{self.url}{path}"
|
url = f"{self.url}{path}"
|
||||||
|
|
||||||
|
# print("uri:", url)
|
||||||
|
# print(json.dumps(request, indent=4))
|
||||||
|
|
||||||
# Invoke the API, input is passed as JSON
|
# Invoke the API, input is passed as JSON
|
||||||
resp = requests.post(url, json=request)
|
resp = requests.post(url, json=request)
|
||||||
|
|
||||||
|
|
@ -94,6 +53,8 @@ class Api:
|
||||||
if resp.status_code != 200:
|
if resp.status_code != 200:
|
||||||
raise ProtocolException(f"Status code {resp.status_code}")
|
raise ProtocolException(f"Status code {resp.status_code}")
|
||||||
|
|
||||||
|
# print(resp.text)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Parse the response as JSON
|
# Parse the response as JSON
|
||||||
object = resp.json()
|
object = resp.json()
|
||||||
|
|
@ -104,524 +65,5 @@ class Api:
|
||||||
|
|
||||||
return object
|
return object
|
||||||
|
|
||||||
def config_all(self):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "config"
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request("config", input)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return object["config"], object["version"]
|
|
||||||
except:
|
|
||||||
raise ProtocolException(f"Response not formatted correctly")
|
|
||||||
|
|
||||||
def library(self):
|
def library(self):
|
||||||
return Library(self)
|
return Library(self)
|
||||||
|
|
||||||
def config_get(self, keys):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "get",
|
|
||||||
"keys": [
|
|
||||||
{ "type": k.type, "key": k.key }
|
|
||||||
for k in keys
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request("config", input)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return [
|
|
||||||
ConfigValue(
|
|
||||||
type = v["type"],
|
|
||||||
key = v["key"],
|
|
||||||
value = v["value"]
|
|
||||||
)
|
|
||||||
for v in object["values"]
|
|
||||||
]
|
|
||||||
except:
|
|
||||||
raise ProtocolException(f"Response not formatted correctly")
|
|
||||||
|
|
||||||
def config_put(self, values):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "put",
|
|
||||||
"values": [
|
|
||||||
{ "type": v.type, "key": v.key, "value": v.value }
|
|
||||||
for v in values
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
self.request("config", input)
|
|
||||||
|
|
||||||
def config_list(self, type):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "list",
|
|
||||||
"type": type,
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request("config", input)["directory"]
|
|
||||||
|
|
||||||
def config_getvalues(self, type):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "getvalues",
|
|
||||||
"type": type,
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request("config", input)["directory"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
return [
|
|
||||||
ConfigValue(
|
|
||||||
type = v["type"],
|
|
||||||
key = v["key"],
|
|
||||||
value = v["value"]
|
|
||||||
)
|
|
||||||
for v in object["values"]
|
|
||||||
]
|
|
||||||
except:
|
|
||||||
raise ProtocolException(f"Response not formatted correctly")
|
|
||||||
|
|
||||||
def flow_list_classes(self):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "list-classes",
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request("flow", input)["class-names"]
|
|
||||||
|
|
||||||
def flow_get_class(self, class_name):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "get-class",
|
|
||||||
"class-name": class_name,
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.loads(self.request("flow", input)["class-definition"])
|
|
||||||
|
|
||||||
def flow_put_class(self, class_name, definition):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "put-class",
|
|
||||||
"class-name": class_name,
|
|
||||||
"class-definition": json.dumps(definition),
|
|
||||||
}
|
|
||||||
|
|
||||||
self.request("flow", input)
|
|
||||||
|
|
||||||
def flow_delete_class(self, class_name):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "delete-class",
|
|
||||||
"class-name": class_name,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.request("flow", input)
|
|
||||||
|
|
||||||
def flow_list(self):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "list-flows",
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request("flow", input)["flow-ids"]
|
|
||||||
|
|
||||||
def flow_get(self, id):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "get-flow",
|
|
||||||
"flow-id": id,
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.loads(self.request("flow", input)["flow"])
|
|
||||||
|
|
||||||
def flow_start(self, class_name, id, description):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "start-flow",
|
|
||||||
"flow-id": id,
|
|
||||||
"class-name": class_name,
|
|
||||||
"description": description,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.request("flow", input)
|
|
||||||
|
|
||||||
def flow_stop(self, id):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"operation": "stop-flow",
|
|
||||||
"flow-id": id,
|
|
||||||
}
|
|
||||||
|
|
||||||
self.request("flow", input)
|
|
||||||
|
|
||||||
class Library:
|
|
||||||
|
|
||||||
def __init__(self, api):
|
|
||||||
self.api = api
|
|
||||||
|
|
||||||
def request(self, request):
|
|
||||||
return self.api.request(f"librarian", request)
|
|
||||||
|
|
||||||
def add_document(
|
|
||||||
self, document, id, metadata, user, title, comments,
|
|
||||||
kind="text/plain", tags=[],
|
|
||||||
):
|
|
||||||
|
|
||||||
if id is None:
|
|
||||||
|
|
||||||
if metadata is not None:
|
|
||||||
|
|
||||||
# Situation makes no sense. What can the metadata possibly
|
|
||||||
# mean if the caller doesn't know the document ID.
|
|
||||||
# Metadata should relate to the document by ID
|
|
||||||
raise RuntimeError("Can't specify metadata without id")
|
|
||||||
|
|
||||||
id = hash(document)
|
|
||||||
|
|
||||||
if not title: title = ""
|
|
||||||
if not comments: comments = ""
|
|
||||||
|
|
||||||
triples = []
|
|
||||||
|
|
||||||
def emit(t):
|
|
||||||
triples.append(t)
|
|
||||||
|
|
||||||
if metadata:
|
|
||||||
metadata.emit(
|
|
||||||
lambda t: triples.append({
|
|
||||||
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
|
||||||
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
|
||||||
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"operation": "add-document",
|
|
||||||
"document-metadata": {
|
|
||||||
"id": id,
|
|
||||||
"time": int(time.time()),
|
|
||||||
"kind": kind,
|
|
||||||
"title": title,
|
|
||||||
"comments": comments,
|
|
||||||
"metadata": triples,
|
|
||||||
"user": user,
|
|
||||||
"tags": tags
|
|
||||||
},
|
|
||||||
"content": base64.b64encode(document).decode("utf-8"),
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(input)
|
|
||||||
|
|
||||||
def get_documents(self, user):
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"operation": "list-documents",
|
|
||||||
"user": user,
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request(input)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return [
|
|
||||||
DocumentMetadata(
|
|
||||||
id = v["id"],
|
|
||||||
time = datetime.datetime.fromtimestamp(v["time"]),
|
|
||||||
kind = v["kind"],
|
|
||||||
title = v["title"],
|
|
||||||
comments = v.get("comments", ""),
|
|
||||||
metadata = [
|
|
||||||
Triple(
|
|
||||||
s = to_value(w["s"]),
|
|
||||||
p = to_value(w["p"]),
|
|
||||||
o = to_value(w["o"])
|
|
||||||
)
|
|
||||||
for w in v["metadata"]
|
|
||||||
],
|
|
||||||
user = v["user"],
|
|
||||||
tags = v["tags"]
|
|
||||||
)
|
|
||||||
for v in object["document-metadatas"]
|
|
||||||
]
|
|
||||||
except:
|
|
||||||
raise ProtocolException(f"Response not formatted correctly")
|
|
||||||
|
|
||||||
def remove_document(self, user, id):
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"operation": "remove-document",
|
|
||||||
"user": user,
|
|
||||||
"document-id": id,
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request(input)
|
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
||||||
class Flow:
|
|
||||||
|
|
||||||
def __init__(self, api, flow):
|
|
||||||
self.api = api
|
|
||||||
self.flow = flow
|
|
||||||
|
|
||||||
def request(self, path, request):
|
|
||||||
|
|
||||||
return self.api.request(f"flow/{self.flow}/{path}", request)
|
|
||||||
|
|
||||||
def text_completion(self, system, prompt):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"system": system,
|
|
||||||
"prompt": prompt
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/text-completion",
|
|
||||||
input
|
|
||||||
)["response"]
|
|
||||||
|
|
||||||
def agent(self, question):
|
|
||||||
|
|
||||||
# The input consists of a question
|
|
||||||
input = {
|
|
||||||
"question": question
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/agent",
|
|
||||||
input
|
|
||||||
)["answer"]
|
|
||||||
|
|
||||||
def graph_rag(
|
|
||||||
self, question, user="trustgraph", collection="default",
|
|
||||||
entity_limit=50, triple_limit=30, max_subgraph_size=150,
|
|
||||||
max_path_length=2,
|
|
||||||
):
|
|
||||||
|
|
||||||
# The input consists of a question
|
|
||||||
input = {
|
|
||||||
"query": question,
|
|
||||||
"user": user,
|
|
||||||
"collection": collection,
|
|
||||||
"entity-limit": entity_limit,
|
|
||||||
"triple-limit": triple_limit,
|
|
||||||
"max-subgraph-size": max_subgraph_size,
|
|
||||||
"max-path-length": max_path_length,
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/graph-rag",
|
|
||||||
input
|
|
||||||
)["response"]
|
|
||||||
|
|
||||||
def document_rag(
|
|
||||||
self, question, user="trustgraph", collection="default",
|
|
||||||
doc_limit=10,
|
|
||||||
):
|
|
||||||
|
|
||||||
# The input consists of a question
|
|
||||||
input = {
|
|
||||||
"query": question,
|
|
||||||
"user": user,
|
|
||||||
"collection": collection,
|
|
||||||
"doc-limit": doc_limit,
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/document-rag",
|
|
||||||
input
|
|
||||||
)["response"]
|
|
||||||
|
|
||||||
def embeddings(self, text):
|
|
||||||
|
|
||||||
# The input consists of a text block
|
|
||||||
input = {
|
|
||||||
"text": text
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/embeddings",
|
|
||||||
input
|
|
||||||
)["vectors"]
|
|
||||||
|
|
||||||
def prompt(self, id, variables):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"id": id,
|
|
||||||
"variables": variables
|
|
||||||
}
|
|
||||||
|
|
||||||
object = self.request(
|
|
||||||
"service/prompt",
|
|
||||||
input
|
|
||||||
)
|
|
||||||
|
|
||||||
if "text" in object:
|
|
||||||
return object["text"]
|
|
||||||
|
|
||||||
if "object" in object:
|
|
||||||
try:
|
|
||||||
return json.loads(object["object"])
|
|
||||||
except Exception as e:
|
|
||||||
raise ProtocolException(
|
|
||||||
"Returned object not well-formed JSON"
|
|
||||||
)
|
|
||||||
|
|
||||||
raise ProtocolException("Response not formatted correctly")
|
|
||||||
|
|
||||||
def triples_query(
|
|
||||||
self, s=None, p=None, o=None,
|
|
||||||
user=None, collection=None, limit=10000
|
|
||||||
):
|
|
||||||
|
|
||||||
# The input consists of system and prompt strings
|
|
||||||
input = {
|
|
||||||
"limit": limit
|
|
||||||
}
|
|
||||||
|
|
||||||
if user:
|
|
||||||
input["user"] = user
|
|
||||||
|
|
||||||
if collection:
|
|
||||||
input["collection"] = collection
|
|
||||||
|
|
||||||
if s:
|
|
||||||
if not isinstance(s, Uri):
|
|
||||||
raise RuntimeError("s must be Uri")
|
|
||||||
input["s"] = { "v": str(s), "e": isinstance(s, Uri), }
|
|
||||||
|
|
||||||
if p:
|
|
||||||
if not isinstance(p, Uri):
|
|
||||||
raise RuntimeError("p must be Uri")
|
|
||||||
input["p"] = { "v": str(p), "e": isinstance(p, Uri), }
|
|
||||||
|
|
||||||
if o:
|
|
||||||
if not isinstance(o, Uri) and not isinstance(o, Literal):
|
|
||||||
raise RuntimeError("o must be Uri or Literal")
|
|
||||||
input["o"] = { "v": str(o), "e": isinstance(o, Uri), }
|
|
||||||
|
|
||||||
object = self.request(
|
|
||||||
"service/triples",
|
|
||||||
input
|
|
||||||
)
|
|
||||||
|
|
||||||
return [
|
|
||||||
Triple(
|
|
||||||
s=to_value(t["s"]),
|
|
||||||
p=to_value(t["p"]),
|
|
||||||
o=to_value(t["o"])
|
|
||||||
)
|
|
||||||
for t in object["response"]
|
|
||||||
]
|
|
||||||
|
|
||||||
def load_document(
|
|
||||||
self, document, id=None, metadata=None, user=None,
|
|
||||||
collection=None,
|
|
||||||
):
|
|
||||||
|
|
||||||
if id is None:
|
|
||||||
|
|
||||||
if metadata is not None:
|
|
||||||
|
|
||||||
# Situation makes no sense. What can the metadata possibly
|
|
||||||
# mean if the caller doesn't know the document ID.
|
|
||||||
# Metadata should relate to the document by ID
|
|
||||||
raise RuntimeError("Can't specify metadata without id")
|
|
||||||
|
|
||||||
id = hash(document)
|
|
||||||
|
|
||||||
triples = []
|
|
||||||
|
|
||||||
def emit(t):
|
|
||||||
triples.append(t)
|
|
||||||
|
|
||||||
if metadata:
|
|
||||||
metadata.emit(
|
|
||||||
lambda t: triples.append({
|
|
||||||
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
|
||||||
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
|
||||||
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"id": id,
|
|
||||||
"metadata": triples,
|
|
||||||
"data": base64.b64encode(document).decode("utf-8"),
|
|
||||||
}
|
|
||||||
|
|
||||||
if user:
|
|
||||||
input["user"] = user
|
|
||||||
|
|
||||||
if collection:
|
|
||||||
input["collection"] = collection
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/document-load",
|
|
||||||
input
|
|
||||||
)
|
|
||||||
|
|
||||||
def load_text(
|
|
||||||
self, text, id=None, metadata=None, charset="utf-8",
|
|
||||||
user=None, collection=None,
|
|
||||||
):
|
|
||||||
|
|
||||||
if id is None:
|
|
||||||
|
|
||||||
if metadata is not None:
|
|
||||||
|
|
||||||
# Situation makes no sense. What can the metadata possibly
|
|
||||||
# mean if the caller doesn't know the document ID.
|
|
||||||
# Metadata should relate to the document by ID
|
|
||||||
raise RuntimeError("Can't specify metadata without id")
|
|
||||||
|
|
||||||
id = hash(text)
|
|
||||||
|
|
||||||
triples = []
|
|
||||||
|
|
||||||
if metadata:
|
|
||||||
metadata.emit(
|
|
||||||
lambda t: triples.append({
|
|
||||||
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
|
||||||
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
|
||||||
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
input = {
|
|
||||||
"id": id,
|
|
||||||
"metadata": triples,
|
|
||||||
"charset": charset,
|
|
||||||
"text": base64.b64encode(text).decode("utf-8"),
|
|
||||||
}
|
|
||||||
|
|
||||||
if user:
|
|
||||||
input["user"] = user
|
|
||||||
|
|
||||||
if collection:
|
|
||||||
input["collection"] = collection
|
|
||||||
|
|
||||||
return self.request(
|
|
||||||
"service/text-load",
|
|
||||||
input
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
||||||
97
trustgraph-base/trustgraph/api/config.py
Normal file
97
trustgraph-base/trustgraph/api/config.py
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
|
||||||
|
from . exceptions import *
|
||||||
|
from . types import ConfigValue
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
|
||||||
|
def __init__(self, api):
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
def request(self, request):
|
||||||
|
return self.api.request("config", request)
|
||||||
|
|
||||||
|
def get(self, keys):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "get",
|
||||||
|
"keys": [
|
||||||
|
{ "type": k.type, "key": k.key }
|
||||||
|
for k in keys
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(input)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return [
|
||||||
|
ConfigValue(
|
||||||
|
type = v["type"],
|
||||||
|
key = v["key"],
|
||||||
|
value = v["value"]
|
||||||
|
)
|
||||||
|
for v in object["values"]
|
||||||
|
]
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
raise ProtocolException("Response not formatted correctly")
|
||||||
|
|
||||||
|
def put(self, values):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "put",
|
||||||
|
"values": [
|
||||||
|
{ "type": v.type, "key": v.key, "value": v.value }
|
||||||
|
for v in values
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request(input)
|
||||||
|
|
||||||
|
def list(self, type):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "list",
|
||||||
|
"type": type,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(input)["directory"]
|
||||||
|
|
||||||
|
def get_values(self, type):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "getvalues",
|
||||||
|
"type": type,
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(input)["directory"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
return [
|
||||||
|
ConfigValue(
|
||||||
|
type = v["type"],
|
||||||
|
key = v["key"],
|
||||||
|
value = v["value"]
|
||||||
|
)
|
||||||
|
for v in object["values"]
|
||||||
|
]
|
||||||
|
except:
|
||||||
|
raise ProtocolException(f"Response not formatted correctly")
|
||||||
|
|
||||||
|
def all(self):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "config"
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(input)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return object["config"], object["version"]
|
||||||
|
except:
|
||||||
|
raise ProtocolException(f"Response not formatted correctly")
|
||||||
|
|
||||||
6
trustgraph-base/trustgraph/api/exceptions.py
Normal file
6
trustgraph-base/trustgraph/api/exceptions.py
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
class ProtocolException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ApplicationException(Exception):
|
||||||
|
pass
|
||||||
359
trustgraph-base/trustgraph/api/flow.py
Normal file
359
trustgraph-base/trustgraph/api/flow.py
Normal file
|
|
@ -0,0 +1,359 @@
|
||||||
|
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from .. knowledge import hash, Uri, Literal
|
||||||
|
|
||||||
|
def to_value(x):
|
||||||
|
if x["e"]: return Uri(x["v"])
|
||||||
|
return Literal(x["v"])
|
||||||
|
|
||||||
|
class Flow:
|
||||||
|
|
||||||
|
def __init__(self, api):
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
def request(self, path=None, request=None):
|
||||||
|
|
||||||
|
if request is None:
|
||||||
|
raise RuntimeError("request must be specified")
|
||||||
|
|
||||||
|
if path:
|
||||||
|
return self.api.request(f"flow/{path}", request)
|
||||||
|
else:
|
||||||
|
return self.api.request(f"flow", request)
|
||||||
|
|
||||||
|
def id(self, id="0000"):
|
||||||
|
return FlowInstance(api=self, id=id)
|
||||||
|
|
||||||
|
def list_classes(self):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "list-classes",
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(request = input)["class-names"]
|
||||||
|
|
||||||
|
def get_class(self, class_name):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "get-class",
|
||||||
|
"class-name": class_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.loads(self.request(request = input)["class-definition"])
|
||||||
|
|
||||||
|
def put_class(self, class_name, definition):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "put-class",
|
||||||
|
"class-name": class_name,
|
||||||
|
"class-definition": json.dumps(definition),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request(request = input)
|
||||||
|
|
||||||
|
def delete_class(self, class_name):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "delete-class",
|
||||||
|
"class-name": class_name,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request(request = input)
|
||||||
|
|
||||||
|
def list(self):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "list-flows",
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(request = input)["flow-ids"]
|
||||||
|
|
||||||
|
def get(self, id):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "get-flow",
|
||||||
|
"flow-id": id,
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.loads(self.request(request = input)["flow"])
|
||||||
|
|
||||||
|
def start(self, class_name, id, description):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "start-flow",
|
||||||
|
"flow-id": id,
|
||||||
|
"class-name": class_name,
|
||||||
|
"description": description,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request(request = input)
|
||||||
|
|
||||||
|
def stop(self, id):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"operation": "stop-flow",
|
||||||
|
"flow-id": id,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.request(request = input)
|
||||||
|
|
||||||
|
class FlowInstance:
|
||||||
|
|
||||||
|
def __init__(self, api, id):
|
||||||
|
self.api = api
|
||||||
|
self.id = id
|
||||||
|
|
||||||
|
def request(self, path, request):
|
||||||
|
|
||||||
|
return self.api.request(path = f"{self.id}/{path}", request = request)
|
||||||
|
|
||||||
|
def text_completion(self, system, prompt):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"system": system,
|
||||||
|
"prompt": prompt
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/text-completion",
|
||||||
|
input
|
||||||
|
)["response"]
|
||||||
|
|
||||||
|
def agent(self, question):
|
||||||
|
|
||||||
|
# The input consists of a question
|
||||||
|
input = {
|
||||||
|
"question": question
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/agent",
|
||||||
|
input
|
||||||
|
)["answer"]
|
||||||
|
|
||||||
|
def graph_rag(
|
||||||
|
self, question, user="trustgraph", collection="default",
|
||||||
|
entity_limit=50, triple_limit=30, max_subgraph_size=150,
|
||||||
|
max_path_length=2,
|
||||||
|
):
|
||||||
|
|
||||||
|
# The input consists of a question
|
||||||
|
input = {
|
||||||
|
"query": question,
|
||||||
|
"user": user,
|
||||||
|
"collection": collection,
|
||||||
|
"entity-limit": entity_limit,
|
||||||
|
"triple-limit": triple_limit,
|
||||||
|
"max-subgraph-size": max_subgraph_size,
|
||||||
|
"max-path-length": max_path_length,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/graph-rag",
|
||||||
|
input
|
||||||
|
)["response"]
|
||||||
|
|
||||||
|
def document_rag(
|
||||||
|
self, question, user="trustgraph", collection="default",
|
||||||
|
doc_limit=10,
|
||||||
|
):
|
||||||
|
|
||||||
|
# The input consists of a question
|
||||||
|
input = {
|
||||||
|
"query": question,
|
||||||
|
"user": user,
|
||||||
|
"collection": collection,
|
||||||
|
"doc-limit": doc_limit,
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/document-rag",
|
||||||
|
input
|
||||||
|
)["response"]
|
||||||
|
|
||||||
|
def embeddings(self, text):
|
||||||
|
|
||||||
|
# The input consists of a text block
|
||||||
|
input = {
|
||||||
|
"text": text
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/embeddings",
|
||||||
|
input
|
||||||
|
)["vectors"]
|
||||||
|
|
||||||
|
def prompt(self, id, variables):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"id": id,
|
||||||
|
"variables": variables
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(
|
||||||
|
"service/prompt",
|
||||||
|
input
|
||||||
|
)
|
||||||
|
|
||||||
|
if "text" in object:
|
||||||
|
return object["text"]
|
||||||
|
|
||||||
|
if "object" in object:
|
||||||
|
try:
|
||||||
|
return json.loads(object["object"])
|
||||||
|
except Exception as e:
|
||||||
|
raise ProtocolException(
|
||||||
|
"Returned object not well-formed JSON"
|
||||||
|
)
|
||||||
|
|
||||||
|
raise ProtocolException("Response not formatted correctly")
|
||||||
|
|
||||||
|
def triples_query(
|
||||||
|
self, s=None, p=None, o=None,
|
||||||
|
user=None, collection=None, limit=10000
|
||||||
|
):
|
||||||
|
|
||||||
|
# The input consists of system and prompt strings
|
||||||
|
input = {
|
||||||
|
"limit": limit
|
||||||
|
}
|
||||||
|
|
||||||
|
if user:
|
||||||
|
input["user"] = user
|
||||||
|
|
||||||
|
if collection:
|
||||||
|
input["collection"] = collection
|
||||||
|
|
||||||
|
if s:
|
||||||
|
if not isinstance(s, Uri):
|
||||||
|
raise RuntimeError("s must be Uri")
|
||||||
|
input["s"] = { "v": str(s), "e": isinstance(s, Uri), }
|
||||||
|
|
||||||
|
if p:
|
||||||
|
if not isinstance(p, Uri):
|
||||||
|
raise RuntimeError("p must be Uri")
|
||||||
|
input["p"] = { "v": str(p), "e": isinstance(p, Uri), }
|
||||||
|
|
||||||
|
if o:
|
||||||
|
if not isinstance(o, Uri) and not isinstance(o, Literal):
|
||||||
|
raise RuntimeError("o must be Uri or Literal")
|
||||||
|
input["o"] = { "v": str(o), "e": isinstance(o, Uri), }
|
||||||
|
|
||||||
|
object = self.request(
|
||||||
|
"service/triples",
|
||||||
|
input
|
||||||
|
)
|
||||||
|
|
||||||
|
return [
|
||||||
|
Triple(
|
||||||
|
s=to_value(t["s"]),
|
||||||
|
p=to_value(t["p"]),
|
||||||
|
o=to_value(t["o"])
|
||||||
|
)
|
||||||
|
for t in object["response"]
|
||||||
|
]
|
||||||
|
|
||||||
|
def load_document(
|
||||||
|
self, document, id=None, metadata=None, user=None,
|
||||||
|
collection=None,
|
||||||
|
):
|
||||||
|
|
||||||
|
if id is None:
|
||||||
|
|
||||||
|
if metadata is not None:
|
||||||
|
|
||||||
|
# Situation makes no sense. What can the metadata possibly
|
||||||
|
# mean if the caller doesn't know the document ID.
|
||||||
|
# Metadata should relate to the document by ID
|
||||||
|
raise RuntimeError("Can't specify metadata without id")
|
||||||
|
|
||||||
|
id = hash(document)
|
||||||
|
|
||||||
|
triples = []
|
||||||
|
|
||||||
|
def emit(t):
|
||||||
|
triples.append(t)
|
||||||
|
|
||||||
|
if metadata:
|
||||||
|
metadata.emit(
|
||||||
|
lambda t: triples.append({
|
||||||
|
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
||||||
|
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
||||||
|
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"id": id,
|
||||||
|
"metadata": triples,
|
||||||
|
"data": base64.b64encode(document).decode("utf-8"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if user:
|
||||||
|
input["user"] = user
|
||||||
|
|
||||||
|
if collection:
|
||||||
|
input["collection"] = collection
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/document-load",
|
||||||
|
input
|
||||||
|
)
|
||||||
|
|
||||||
|
def load_text(
|
||||||
|
self, text, id=None, metadata=None, charset="utf-8",
|
||||||
|
user=None, collection=None,
|
||||||
|
):
|
||||||
|
|
||||||
|
if id is None:
|
||||||
|
|
||||||
|
if metadata is not None:
|
||||||
|
|
||||||
|
# Situation makes no sense. What can the metadata possibly
|
||||||
|
# mean if the caller doesn't know the document ID.
|
||||||
|
# Metadata should relate to the document by ID
|
||||||
|
raise RuntimeError("Can't specify metadata without id")
|
||||||
|
|
||||||
|
id = hash(text)
|
||||||
|
|
||||||
|
triples = []
|
||||||
|
|
||||||
|
if metadata:
|
||||||
|
metadata.emit(
|
||||||
|
lambda t: triples.append({
|
||||||
|
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
||||||
|
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
||||||
|
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"id": id,
|
||||||
|
"metadata": triples,
|
||||||
|
"charset": charset,
|
||||||
|
"text": base64.b64encode(text).decode("utf-8"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if user:
|
||||||
|
input["user"] = user
|
||||||
|
|
||||||
|
if collection:
|
||||||
|
input["collection"] = collection
|
||||||
|
|
||||||
|
return self.request(
|
||||||
|
"service/text-load",
|
||||||
|
input
|
||||||
|
)
|
||||||
|
|
||||||
116
trustgraph-base/trustgraph/api/library.py
Normal file
116
trustgraph-base/trustgraph/api/library.py
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
import base64
|
||||||
|
|
||||||
|
from . types import DocumentMetadata, ProcessingMetadata, Triple
|
||||||
|
from .. knowledge import hash, Uri, Literal
|
||||||
|
from . exceptions import *
|
||||||
|
|
||||||
|
def to_value(x):
|
||||||
|
if x["e"]: return Uri(x["v"])
|
||||||
|
return Literal(x["v"])
|
||||||
|
|
||||||
|
class Library:
|
||||||
|
|
||||||
|
def __init__(self, api):
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
def request(self, request):
|
||||||
|
return self.api.request(f"librarian", request)
|
||||||
|
|
||||||
|
def add_document(
|
||||||
|
self, document, id, metadata, user, title, comments,
|
||||||
|
kind="text/plain", tags=[],
|
||||||
|
):
|
||||||
|
|
||||||
|
if id is None:
|
||||||
|
|
||||||
|
if metadata is not None:
|
||||||
|
|
||||||
|
# Situation makes no sense. What can the metadata possibly
|
||||||
|
# mean if the caller doesn't know the document ID.
|
||||||
|
# Metadata should relate to the document by ID
|
||||||
|
raise RuntimeError("Can't specify metadata without id")
|
||||||
|
|
||||||
|
id = hash(document)
|
||||||
|
|
||||||
|
if not title: title = ""
|
||||||
|
if not comments: comments = ""
|
||||||
|
|
||||||
|
triples = []
|
||||||
|
|
||||||
|
def emit(t):
|
||||||
|
triples.append(t)
|
||||||
|
|
||||||
|
if metadata:
|
||||||
|
metadata.emit(
|
||||||
|
lambda t: triples.append({
|
||||||
|
"s": { "v": t["s"], "e": isinstance(t["s"], Uri) },
|
||||||
|
"p": { "v": t["p"], "e": isinstance(t["p"], Uri) },
|
||||||
|
"o": { "v": t["o"], "e": isinstance(t["o"], Uri) }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"operation": "add-document",
|
||||||
|
"document-metadata": {
|
||||||
|
"id": id,
|
||||||
|
"time": int(time.time()),
|
||||||
|
"kind": kind,
|
||||||
|
"title": title,
|
||||||
|
"comments": comments,
|
||||||
|
"metadata": triples,
|
||||||
|
"user": user,
|
||||||
|
"tags": tags
|
||||||
|
},
|
||||||
|
"content": base64.b64encode(document).decode("utf-8"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.request(input)
|
||||||
|
|
||||||
|
def get_documents(self, user):
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"operation": "list-documents",
|
||||||
|
"user": user,
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(input)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return [
|
||||||
|
DocumentMetadata(
|
||||||
|
id = v["id"],
|
||||||
|
time = datetime.datetime.fromtimestamp(v["time"]),
|
||||||
|
kind = v["kind"],
|
||||||
|
title = v["title"],
|
||||||
|
comments = v.get("comments", ""),
|
||||||
|
metadata = [
|
||||||
|
Triple(
|
||||||
|
s = to_value(w["s"]),
|
||||||
|
p = to_value(w["p"]),
|
||||||
|
o = to_value(w["o"])
|
||||||
|
)
|
||||||
|
for w in v["metadata"]
|
||||||
|
],
|
||||||
|
user = v["user"],
|
||||||
|
tags = v["tags"]
|
||||||
|
)
|
||||||
|
for v in object["document-metadatas"]
|
||||||
|
]
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
raise ProtocolException(f"Response not formatted correctly")
|
||||||
|
|
||||||
|
def remove_document(self, user, id):
|
||||||
|
|
||||||
|
input = {
|
||||||
|
"operation": "remove-document",
|
||||||
|
"user": user,
|
||||||
|
"document-id": id,
|
||||||
|
}
|
||||||
|
|
||||||
|
object = self.request(input)
|
||||||
|
|
||||||
|
return {}
|
||||||
42
trustgraph-base/trustgraph/api/types.py
Normal file
42
trustgraph-base/trustgraph/api/types.py
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
import dataclasses
|
||||||
|
import datetime
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class Triple:
|
||||||
|
s : str
|
||||||
|
p : str
|
||||||
|
o : str
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class ConfigKey:
|
||||||
|
type : str
|
||||||
|
key : str
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class ConfigValue:
|
||||||
|
type : str
|
||||||
|
key : str
|
||||||
|
value : str
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class DocumentMetadata:
|
||||||
|
id : str
|
||||||
|
time : datetime.datetime
|
||||||
|
kind : str
|
||||||
|
title : str
|
||||||
|
comments : str
|
||||||
|
metadata : List[Triple]
|
||||||
|
user : str
|
||||||
|
tags : List[str]
|
||||||
|
|
||||||
|
@dataclasses.dataclass
|
||||||
|
class ProcessingMetadata:
|
||||||
|
id : str
|
||||||
|
document_id : str
|
||||||
|
time : datetime.datetime
|
||||||
|
flow : str
|
||||||
|
user : str
|
||||||
|
collection : str
|
||||||
|
tags : List[str]
|
||||||
|
|
@ -13,9 +13,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def delete_flow_class(url, class_name):
|
def delete_flow_class(url, class_name):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow()
|
||||||
|
|
||||||
class_names = api.flow_delete_class(class_name)
|
class_names = api.delete_class(class_name)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def get_flow_class(url, class_name):
|
def get_flow_class(url, class_name):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow()
|
||||||
|
|
||||||
cls = api.flow_get_class(class_name)
|
cls = api.get_class(class_name)
|
||||||
|
|
||||||
print(json.dumps(cls, indent=4))
|
print(json.dumps(cls, indent=4))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ default_collection = 'default'
|
||||||
|
|
||||||
def show_graph(url, flow_id, user, collection):
|
def show_graph(url, flow_id, user, collection):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
rows = api.flow(flow_id).triples_query(
|
rows = api.triples_query(
|
||||||
user=user, collection=collection,
|
user=user, collection=collection,
|
||||||
s=None, p=None, o=None, limit=10_000,
|
s=None, p=None, o=None, limit=10_000,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ default_collection = 'default'
|
||||||
|
|
||||||
def show_graph(url, flow_id, user, collection):
|
def show_graph(url, flow_id, user, collection):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
rows = api.flow(flow_id).triples_query(
|
rows = api.triples_query(
|
||||||
s=None, p=None, o=None,
|
s=None, p=None, o=None,
|
||||||
user=user, collection=collection,
|
user=user, collection=collection,
|
||||||
limit=10_000)
|
limit=10_000)
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ default_doc_limit = 10
|
||||||
|
|
||||||
def question(url, flow_id, question, user, collection, doc_limit):
|
def question(url, flow_id, question, user, collection, doc_limit):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
resp = api.flow(flow_id).document_rag(
|
resp = api.document_rag(
|
||||||
question=question, user=user, collection=collection,
|
question=question, user=user, collection=collection,
|
||||||
doc_limit=doc_limit,
|
doc_limit=doc_limit,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ def question(
|
||||||
max_subgraph_size, max_path_length
|
max_subgraph_size, max_path_length
|
||||||
):
|
):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
resp = api.flow(flow_id).graph_rag(
|
resp = api.graph_rag(
|
||||||
question=question, user=user, collection=collection,
|
question=question, user=user, collection=collection,
|
||||||
entity_limit=entity_limit, triple_limit=triple_limit,
|
entity_limit=entity_limit, triple_limit=triple_limit,
|
||||||
max_subgraph_size=max_subgraph_size,
|
max_subgraph_size=max_subgraph_size,
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def query(url, flow_id, system, prompt):
|
def query(url, flow_id, system, prompt):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id).
|
||||||
|
|
||||||
resp = api.flow(flow_id).text_completion(system=system, prompt=prompt)
|
resp = api.text_completion(system=system, prompt=prompt)
|
||||||
|
|
||||||
print(resp)
|
print(resp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def query(url, flow_id, template_id, variables):
|
def query(url, flow_id, template_id, variables):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
resp = api.flow(flow_id).prompt(id=template_id, variables=variables)
|
resp = api.prompt(id=template_id, variables=variables)
|
||||||
|
|
||||||
if isinstance(resp, str):
|
if isinstance(resp, str):
|
||||||
print(resp)
|
print(resp)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ class Loader:
|
||||||
metadata,
|
metadata,
|
||||||
):
|
):
|
||||||
|
|
||||||
self.api = Api(url).flow(flow_id)
|
self.api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
self.user = user
|
self.user = user
|
||||||
self.collection = collection
|
self.collection = collection
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ class Loader:
|
||||||
metadata,
|
metadata,
|
||||||
):
|
):
|
||||||
|
|
||||||
self.api = Api(url).flow(flow_id)
|
self.api = Api(url).flow().id(flow_id)
|
||||||
|
|
||||||
self.user = user
|
self.user = user
|
||||||
self.collection = collection
|
self.collection = collection
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Loads Graph embeddings into TrustGraph processing.
|
Loads Graph embeddings into TrustGraph processing.
|
||||||
|
|
||||||
|
FIXME: This hasn't been updated following API gateway change.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pulsar
|
import pulsar
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ Dumps out the current configuration
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import tabulate
|
|
||||||
from trustgraph.api import Api
|
from trustgraph.api import Api
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
@ -16,7 +15,7 @@ def put_flow_class(url, class_name, config):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url)
|
||||||
|
|
||||||
class_names = api.flow_put_class(class_name, config)
|
class_names = api.flow().put_class(class_name, config)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def set_system(url, system):
|
def set_system(url, system):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).config()
|
||||||
|
|
||||||
api.config_put([
|
api.put([
|
||||||
ConfigValue(type="prompt", key="system", value=json.dumps(system))
|
ConfigValue(type="prompt", key="system", value=json.dumps(system))
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def set_costs(api_url, model, input_costs, output_costs):
|
def set_costs(api_url, model, input_costs, output_costs):
|
||||||
|
|
||||||
api = Api(api_url)
|
api = Api(api_url).config()
|
||||||
|
|
||||||
api.config_put([
|
api.put([
|
||||||
ConfigValue(
|
ConfigValue(
|
||||||
type="token-costs", key=model,
|
type="token-costs", key=model,
|
||||||
value=json.dumps({
|
value=json.dumps({
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def show_config(url):
|
def show_config(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).config()
|
||||||
|
|
||||||
config, version = api.config_all()
|
config, version = api.all()
|
||||||
|
|
||||||
print("Version:", version)
|
print("Version:", version)
|
||||||
print(json.dumps(config, indent=4))
|
print(json.dumps(config, indent=4))
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def show_flow_classes(url):
|
def show_flow_classes(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow()
|
||||||
|
|
||||||
class_names = api.flow_list_classes()
|
class_names = api.list_classes()
|
||||||
|
|
||||||
if len(class_names) == 0:
|
if len(class_names) == 0:
|
||||||
print("No flows.")
|
print("No flows.")
|
||||||
|
|
@ -24,7 +24,7 @@ def show_flow_classes(url):
|
||||||
classes = []
|
classes = []
|
||||||
|
|
||||||
for class_name in class_names:
|
for class_name in class_names:
|
||||||
cls = api.flow_get_class(class_name)
|
cls = api.get_class(class_name)
|
||||||
classes.append((
|
classes.append((
|
||||||
class_name,
|
class_name,
|
||||||
cls.get("description", ""),
|
cls.get("description", ""),
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def dump_status(metrics_url, api_url, flow_id):
|
def dump_status(metrics_url, api_url, flow_id):
|
||||||
|
|
||||||
api = Api(api_url)
|
api = Api(api_url).flow()
|
||||||
|
|
||||||
flow = api.flow_get(flow_id)
|
flow = api.get(flow_id)
|
||||||
class_name = flow["class-name"]
|
class_name = flow["class-name"]
|
||||||
|
|
||||||
print()
|
print()
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ import json
|
||||||
|
|
||||||
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def get_interface(api, i):
|
def get_interface(config_api, i):
|
||||||
|
|
||||||
key = ConfigKey("interface-descriptions", i)
|
key = ConfigKey("interface-descriptions", i)
|
||||||
|
|
||||||
value = api.config_get([key])[0].value
|
value = config_api.get([key])[0].value
|
||||||
|
|
||||||
return json.loads(value)
|
return json.loads(value)
|
||||||
|
|
||||||
|
|
@ -49,15 +49,17 @@ def describe_interfaces(intdefs, flow):
|
||||||
def show_flows(url):
|
def show_flows(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url)
|
||||||
|
config_api = api.config()
|
||||||
|
flow_api = api.flow()
|
||||||
|
|
||||||
interface_names = api.config_list("interface-descriptions")
|
interface_names = config_api.list("interface-descriptions")
|
||||||
|
|
||||||
interface_defs = {
|
interface_defs = {
|
||||||
i: get_interface(api, i)
|
i: get_interface(config_api, i)
|
||||||
for i in interface_names
|
for i in interface_names
|
||||||
}
|
}
|
||||||
|
|
||||||
flow_ids = api.flow_list()
|
flow_ids = flow_api.list()
|
||||||
|
|
||||||
if len(flow_ids) == 0:
|
if len(flow_ids) == 0:
|
||||||
print("No flows.")
|
print("No flows.")
|
||||||
|
|
@ -67,7 +69,7 @@ def show_flows(url):
|
||||||
|
|
||||||
for id in flow_ids:
|
for id in flow_ids:
|
||||||
|
|
||||||
flow = api.flow_get(id)
|
flow = flow_api.get(id)
|
||||||
|
|
||||||
table = []
|
table = []
|
||||||
table.append(("id", id))
|
table.append(("id", id))
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def show_config(url):
|
def show_config(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).config()
|
||||||
|
|
||||||
values = api.config_get([
|
values = api.get([
|
||||||
ConfigKey(type="prompt", key="system"),
|
ConfigKey(type="prompt", key="system"),
|
||||||
ConfigKey(type="prompt", key="template-index")
|
ConfigKey(type="prompt", key="template-index")
|
||||||
])
|
])
|
||||||
|
|
@ -25,7 +25,7 @@ def show_config(url):
|
||||||
system = json.loads(values[0].value)
|
system = json.loads(values[0].value)
|
||||||
ix = json.loads(values[1].value)
|
ix = json.loads(values[1].value)
|
||||||
|
|
||||||
values = api.config_get([
|
values = api.get([
|
||||||
ConfigKey(type="prompt", key=f"template.{v}")
|
ConfigKey(type="prompt", key=f"template.{v}")
|
||||||
for v in ix
|
for v in ix
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def show_config(url):
|
def show_config(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).config()
|
||||||
|
|
||||||
models = api.config_list("token-costs")
|
models = api.list("token-costs")
|
||||||
|
|
||||||
costs = []
|
costs = []
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ def show_config(url):
|
||||||
for model in models:
|
for model in models:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
values = json.loads(api.config_get([
|
values = json.loads(api.get([
|
||||||
ConfigKey(type="token-costs", key=model),
|
ConfigKey(type="token-costs", key=model),
|
||||||
])[0].value)
|
])[0].value)
|
||||||
costs.append((
|
costs.append((
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,15 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def show_config(url):
|
def show_config(url):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).config()
|
||||||
|
|
||||||
values = api.config_get([
|
values = api.get([
|
||||||
ConfigKey(type="agent", key="tool-index")
|
ConfigKey(type="agent", key="tool-index")
|
||||||
])
|
])
|
||||||
|
|
||||||
ix = json.loads(values[0].value)
|
ix = json.loads(values[0].value)
|
||||||
|
|
||||||
values = api.config_get([
|
values = api.get([
|
||||||
ConfigKey(type="agent", key=f"tool.{v}")
|
ConfigKey(type="agent", key=f"tool.{v}")
|
||||||
for v in ix
|
for v in ix
|
||||||
])
|
])
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def start_flow(url, class_name, flow_id, description):
|
def start_flow(url, class_name, flow_id, description):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow()
|
||||||
|
|
||||||
api.flow_start(
|
api.start(
|
||||||
class_name = class_name,
|
class_name = class_name,
|
||||||
id = flow_id,
|
id = flow_id,
|
||||||
description = description,
|
description = description,
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
|
||||||
|
|
||||||
def stop_flow(url, flow_id):
|
def stop_flow(url, flow_id):
|
||||||
|
|
||||||
api = Api(url)
|
api = Api(url).flow()
|
||||||
|
|
||||||
api.flow_stop(id = flow_id)
|
api.stop(id = flow_id)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue