diff --git a/trustgraph-flow/scripts/prompt-generic b/trustgraph-flow/scripts/prompt-generic
deleted file mode 100755
index 61e4d41d..00000000
--- a/trustgraph-flow/scripts/prompt-generic
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env python3
-
-from trustgraph.model.prompt.generic import run
-
-run()
-
diff --git a/trustgraph-flow/scripts/prompt-template b/trustgraph-flow/scripts/prompt-template
index 91d94216..65f68a9c 100755
--- a/trustgraph-flow/scripts/prompt-template
+++ b/trustgraph-flow/scripts/prompt-template
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-from trustgraph.model.prompt.template import run
+from trustgraph.prompt.template import run
run()
diff --git a/trustgraph-flow/trustgraph/model/prompt/generic/prompts.py b/trustgraph-flow/trustgraph/model/prompt/generic/prompts.py
deleted file mode 100644
index c16afc89..00000000
--- a/trustgraph-flow/trustgraph/model/prompt/generic/prompts.py
+++ /dev/null
@@ -1,176 +0,0 @@
-
-def to_relationships(text):
-
- prompt = f"""You are a helpful assistant that performs information extraction tasks for a provided text.
-
-Read the provided text. You will model the text as an information network for a RDF knowledge graph in JSON.
-
-Information Network Rules:
-- An information network has subjects connected by predicates to objects.
-- A subject is a named-entity or a conceptual topic.
-- One subject can have many predicates and objects.
-- An object is a property or attribute of a subject.
-- A subject can be connected by a predicate to another subject.
-
-Reading Instructions:
-- Ignore document formatting in the provided text.
-- Study the provided text carefully.
-
-Here is the text:
-{text}
-
-Response Instructions:
-- Obey the information network rules.
-- Do not return special characters.
-- Respond only with well-formed JSON.
-- The JSON response shall be an array of JSON objects with keys "subject", "predicate", "object", and "object-entity".
-- The JSON response shall use the following structure:
-
-```json
-[{{"subject": string, "predicate": string, "object": string, "object-entity": boolean}}]
-```
-
-- The key "object-entity" is TRUE only if the "object" is a subject.
-- Do not write any additional text or explanations.
-"""
-
- return prompt
-
-def to_topics(text):
-
- prompt = f"""You are a helpful assistant that performs information extraction tasks for a provided text.\nRead the provided text. You will identify topics and their definitions in JSON.
-
-Reading Instructions:
-- Ignore document formatting in the provided text.
-- Study the provided text carefully.
-
-Here is the text:
-{text}
-
-Response Instructions:
-- Do not respond with special characters.
-- Return only topics that are concepts and unique to the provided text.
-- Respond only with well-formed JSON.
-- The JSON response shall be an array of objects with keys "topic" and "definition".
-- The JSON response shall use the following structure:
-
-```json
-[{{"topic": string, "definition": string}}]
-```
-
-- Do not write any additional text or explanations.
-"""
-
- return prompt
-
-def to_definitions(text):
-
- prompt = f"""You are a helpful assistant that performs information extraction tasks for a provided text.\nRead the provided text. You will identify entities and their definitions in JSON.
-
-Reading Instructions:
-- Ignore document formatting in the provided text.
-- Study the provided text carefully.
-
-Here is the text:
-{text}
-
-Response Instructions:
-- Do not respond with special characters.
-- Return only entities that are named-entities such as: people, organizations, physical objects, locations, animals, products, commodotities, or substances.
-- Respond only with well-formed JSON.
-- The JSON response shall be an array of objects with keys "entity" and "definition".
-- The JSON response shall use the following structure:
-
-```json
-[{{"entity": string, "definition": string}}]
-```
-
-- Do not write any additional text or explanations.
-"""
-
- return prompt
-
-def to_rows(schema, text):
-
- field_schema = [
- f"- Name: {f.name}\n Type: {f.type}\n Definition: {f.description}"
- for f in schema.fields
- ]
-
- field_schema = "\n".join(field_schema)
-
- schema = f"""Object name: {schema.name}
-Description: {schema.description}
-
-Fields:
-{field_schema}"""
-
- prompt = f"""
-Study the following text and derive objects which match the schema provided.
-
-You must output an array of JSON objects for each object you discover
-which matches the schema. For each object, output a JSON object whose fields
-carry the name field specified in the schema.
-
-
-
-{schema}
-
-
-
-{text}
-
-
-
-You will respond only with raw JSON format data. Do not provide
-explanations. Do not add markdown formatting or headers or prefixes.
-"""
-
- return prompt
-
-def get_cypher(kg):
-
- sg2 = []
-
- for f in kg:
-
- print(f)
-
- sg2.append(f"({f.s})-[{f.p}]->({f.o})")
-
- print(sg2)
-
- kg = "\n".join(sg2)
- kg = kg.replace("\\", "-")
-
- return kg
-
-def to_kg_query(query, kg):
-
- cypher = get_cypher(kg)
-
- prompt=f"""Study the following set of knowledge statements. The statements are written in Cypher format that has been extracted from a knowledge graph. Use only the provided set of knowledge statements in your response. Do not speculate if the answer is not found in the provided set of knowledge statements.
-
-Here's the knowledge statements:
-{cypher}
-
-Use only the provided knowledge statements to respond to the following:
-{query}
-"""
-
- return prompt
-
-def to_document_query(query, documents):
-
- documents = "\n\n".join(documents)
-
- prompt=f"""Study the following context. Use only the information provided in the context in your response. Do not speculate if the answer is not found in the provided set of knowledge statements.
-
-Here is the context:
-{documents}
-
-Use only the provided knowledge statements to respond to the following:
-{query}
-"""
-
- return prompt
diff --git a/trustgraph-flow/trustgraph/model/prompt/generic/service.py b/trustgraph-flow/trustgraph/model/prompt/generic/service.py
deleted file mode 100755
index b10da491..00000000
--- a/trustgraph-flow/trustgraph/model/prompt/generic/service.py
+++ /dev/null
@@ -1,485 +0,0 @@
-"""
-Language service abstracts prompt engineering from LLM.
-"""
-
-#
-# FIXME: This module is broken, it doesn't conform to the prompt API change
-# made in 0.14, nor the prompt template support.
-#
-# It could be made to conform by using prompt-template as a starting
-# point, and hard-coding all the information.
-#
-
-
-import json
-import re
-
-from .... schema import Definition, Relationship, Triple
-from .... schema import Topic
-from .... schema import PromptRequest, PromptResponse, Error
-from .... schema import TextCompletionRequest, TextCompletionResponse
-from .... schema import text_completion_request_queue
-from .... schema import text_completion_response_queue
-from .... schema import prompt_request_queue, prompt_response_queue
-from .... base import ConsumerProducer
-from .... clients.llm_client import LlmClient
-
-from . prompts import to_definitions, to_relationships, to_topics
-from . prompts import to_kg_query, to_document_query, to_rows
-
-module = "prompt"
-
-default_input_queue = prompt_request_queue
-default_output_queue = prompt_response_queue
-default_subscriber = module
-
-class Processor(ConsumerProducer):
-
- def __init__(self, **params):
-
- input_queue = params.get("input_queue", default_input_queue)
- output_queue = params.get("output_queue", default_output_queue)
- subscriber = params.get("subscriber", default_subscriber)
- tc_request_queue = params.get(
- "text_completion_request_queue", text_completion_request_queue
- )
- tc_response_queue = params.get(
- "text_completion_response_queue", text_completion_response_queue
- )
-
- super(Processor, self).__init__(
- **params | {
- "input_queue": input_queue,
- "output_queue": output_queue,
- "subscriber": subscriber,
- "input_schema": PromptRequest,
- "output_schema": PromptResponse,
- "text_completion_request_queue": tc_request_queue,
- "text_completion_response_queue": tc_response_queue,
- }
- )
-
- self.llm = LlmClient(
- subscriber=subscriber,
- input_queue=tc_request_queue,
- output_queue=tc_response_queue,
- pulsar_host = self.pulsar_host,
- pulsar_api_key=self.pulsar_api_key,
- )
-
- def parse_json(self, text):
- json_match = re.search(r'```(?:json)?(.*?)```', text, re.DOTALL)
-
- if json_match:
- json_str = json_match.group(1).strip()
- else:
- # If no delimiters, assume the entire output is JSON
- json_str = text.strip()
-
- return json.loads(json_str)
-
- async def handle(self, msg):
-
- v = msg.value()
-
- # Sender-produced ID
-
- id = msg.properties()["id"]
-
- kind = v.kind
-
- print(f"Handling kind {kind}...", flush=True)
-
- if kind == "extract-definitions":
-
- await self.handle_extract_definitions(id, v)
- return
-
- elif kind == "extract-topics":
-
- await self.handle_extract_topics(id, v)
- return
-
- elif kind == "extract-relationships":
-
- await self.handle_extract_relationships(id, v)
- return
-
- elif kind == "extract-rows":
-
- await self.handle_extract_rows(id, v)
- return
-
- elif kind == "kg-prompt":
-
- await self.handle_kg_prompt(id, v)
- return
-
- elif kind == "document-prompt":
-
- await self.handle_document_prompt(id, v)
- return
-
- else:
-
- print("Invalid kind.", flush=True)
- return
-
- async def handle_extract_definitions(self, id, v):
-
- try:
-
- prompt = to_definitions(v.chunk)
-
- ans = self.llm.request(prompt)
-
- # Silently ignore JSON parse error
- try:
- defs = self.parse_json(ans)
- except:
- print("JSON parse error, ignored", flush=True)
- defs = []
-
- output = []
-
- for defn in defs:
-
- try:
- e = defn["entity"]
- d = defn["definition"]
-
- if e == "": continue
- if e is None: continue
- if d == "": continue
- if d is None: continue
-
- output.append(
- Definition(
- name=e, definition=d
- )
- )
-
- except:
- print("definition fields missing, ignored", flush=True)
-
- print("Send response...", flush=True)
- r = PromptResponse(definitions=output, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- async def handle_extract_topics(self, id, v):
-
- try:
-
- prompt = to_topics(v.chunk)
-
- ans = self.llm.request(prompt)
-
- # Silently ignore JSON parse error
- try:
- defs = self.parse_json(ans)
- except:
- print("JSON parse error, ignored", flush=True)
- defs = []
-
- output = []
-
- for defn in defs:
-
- try:
- e = defn["topic"]
- d = defn["definition"]
-
- if e == "": continue
- if e is None: continue
- if d == "": continue
- if d is None: continue
-
- output.append(
- Topic(
- name=e, definition=d
- )
- )
-
- except:
- print("definition fields missing, ignored", flush=True)
-
- print("Send response...", flush=True)
- r = PromptResponse(topics=output, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- async def handle_extract_relationships(self, id, v):
-
- try:
-
- prompt = to_relationships(v.chunk)
-
- ans = self.llm.request(prompt)
-
- # Silently ignore JSON parse error
- try:
- defs = self.parse_json(ans)
- except:
- print("JSON parse error, ignored", flush=True)
- defs = []
-
- output = []
-
- for defn in defs:
-
- try:
-
- s = defn["subject"]
- p = defn["predicate"]
- o = defn["object"]
- o_entity = defn["object-entity"]
-
- if s == "": continue
- if s is None: continue
-
- if p == "": continue
- if p is None: continue
-
- if o == "": continue
- if o is None: continue
-
- if o_entity == "" or o_entity is None:
- o_entity = False
-
- output.append(
- Relationship(
- s = s,
- p = p,
- o = o,
- o_entity = o_entity,
- )
- )
-
- except Exception as e:
- print("relationship fields missing, ignored", flush=True)
-
- print("Send response...", flush=True)
- r = PromptResponse(relationships=output, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- async def handle_extract_rows(self, id, v):
-
- try:
-
- fields = v.row_schema.fields
-
- prompt = to_rows(v.row_schema, v.chunk)
-
- print(prompt)
-
- ans = self.llm.request(prompt)
-
- print(ans)
-
- # Silently ignore JSON parse error
- try:
- objs = self.parse_json(ans)
- except:
- print("JSON parse error, ignored", flush=True)
- objs = []
-
- output = []
-
- for obj in objs:
-
- try:
-
- row = {}
-
- for f in fields:
-
- if f.name not in obj:
- print(f"Object ignored, missing field {f.name}")
- row = {}
- break
-
- row[f.name] = obj[f.name]
-
- if row == {}:
- continue
-
- output.append(row)
-
- except Exception as e:
- print("row fields missing, ignored", flush=True)
-
- for row in output:
- print(row)
-
- print("Send response...", flush=True)
- r = PromptResponse(rows=output, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- async def handle_kg_prompt(self, id, v):
-
- try:
-
- prompt = to_kg_query(v.query, v.kg)
-
- print(prompt)
-
- ans = self.llm.request(prompt)
-
- print(ans)
-
- print("Send response...", flush=True)
- r = PromptResponse(answer=ans, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- async def handle_document_prompt(self, id, v):
-
- try:
-
- prompt = to_document_query(v.query, v.documents)
-
- print("prompt")
- print(prompt)
-
- print("Call LLM...")
-
- ans = self.llm.request(prompt)
-
- print(ans)
-
- print("Send response...", flush=True)
- r = PromptResponse(answer=ans, error=None)
- await self.send(r, properties={"id": id})
-
- print("Done.", flush=True)
-
- except Exception as e:
-
- print(f"Exception: {e}")
-
- print("Send error response...", flush=True)
-
- r = PromptResponse(
- error=Error(
- type = "llm-error",
- message = str(e),
- ),
- response=None,
- )
-
- await self.send(r, properties={"id": id})
-
- @staticmethod
- def add_args(parser):
-
- ConsumerProducer.add_args(
- parser, default_input_queue, default_subscriber,
- default_output_queue,
- )
-
- parser.add_argument(
- '--text-completion-request-queue',
- default=text_completion_request_queue,
- help=f'Text completion request queue (default: {text_completion_request_queue})',
- )
-
- parser.add_argument(
- '--text-completion-response-queue',
- default=text_completion_response_queue,
- help=f'Text completion response queue (default: {text_completion_response_queue})',
- )
-
-def run():
-
- raise RuntimeError("NOT IMPLEMENTED")
-
- Processor.launch(module, __doc__)
-
diff --git a/trustgraph-flow/trustgraph/model/prompt/template/__init__.py b/trustgraph-flow/trustgraph/model/prompt/template/__init__.py
deleted file mode 100644
index ba844705..00000000
--- a/trustgraph-flow/trustgraph/model/prompt/template/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-from . service import *
-
diff --git a/trustgraph-flow/trustgraph/model/prompt/template/__main__.py b/trustgraph-flow/trustgraph/model/prompt/template/__main__.py
deleted file mode 100755
index e9136855..00000000
--- a/trustgraph-flow/trustgraph/model/prompt/template/__main__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env python3
-
-from . service import run
-
-if __name__ == '__main__':
- run()
-
diff --git a/trustgraph-flow/trustgraph/model/prompt/__init__.py b/trustgraph-flow/trustgraph/prompt/__init__.py
similarity index 100%
rename from trustgraph-flow/trustgraph/model/prompt/__init__.py
rename to trustgraph-flow/trustgraph/prompt/__init__.py
diff --git a/trustgraph-flow/trustgraph/model/prompt/template/README.md b/trustgraph-flow/trustgraph/prompt/template/README.md
similarity index 100%
rename from trustgraph-flow/trustgraph/model/prompt/template/README.md
rename to trustgraph-flow/trustgraph/prompt/template/README.md
diff --git a/trustgraph-flow/trustgraph/model/prompt/generic/__init__.py b/trustgraph-flow/trustgraph/prompt/template/__init__.py
similarity index 100%
rename from trustgraph-flow/trustgraph/model/prompt/generic/__init__.py
rename to trustgraph-flow/trustgraph/prompt/template/__init__.py
diff --git a/trustgraph-flow/trustgraph/model/prompt/generic/__main__.py b/trustgraph-flow/trustgraph/prompt/template/__main__.py
similarity index 100%
rename from trustgraph-flow/trustgraph/model/prompt/generic/__main__.py
rename to trustgraph-flow/trustgraph/prompt/template/__main__.py
diff --git a/trustgraph-flow/trustgraph/model/prompt/template/service.py b/trustgraph-flow/trustgraph/prompt/template/service.py
similarity index 98%
rename from trustgraph-flow/trustgraph/model/prompt/template/service.py
rename to trustgraph-flow/trustgraph/prompt/template/service.py
index f60d3f45..02395d6d 100755
--- a/trustgraph-flow/trustgraph/model/prompt/template/service.py
+++ b/trustgraph-flow/trustgraph/prompt/template/service.py
@@ -15,7 +15,7 @@ from ....schema import TextCompletionRequest, TextCompletionResponse
from ....base import FlowProcessor
from ....base import ProducerSpec, ConsumerSpec, TextCompletionClientSpec
-from ..template import PromptConfiguration, Prompt, PromptManager
+from .template import PromptConfiguration, Prompt, PromptManager
default_ident = "prompt"
default_concurrency = 1
diff --git a/trustgraph-flow/trustgraph/templates/__init__.py b/trustgraph-flow/trustgraph/template/__init__.py
similarity index 100%
rename from trustgraph-flow/trustgraph/templates/__init__.py
rename to trustgraph-flow/trustgraph/template/__init__.py
diff --git a/trustgraph-flow/trustgraph/templates/prompt_manager.py b/trustgraph-flow/trustgraph/template/prompt_manager.py
similarity index 100%
rename from trustgraph-flow/trustgraph/templates/prompt_manager.py
rename to trustgraph-flow/trustgraph/template/prompt_manager.py