diff --git a/templates/components.jsonnet b/templates/components.jsonnet index f27be5cd..1c8d3900 100644 --- a/templates/components.jsonnet +++ b/templates/components.jsonnet @@ -16,13 +16,10 @@ "ollama": import "components/ollama.jsonnet", "openai": import "components/openai.jsonnet", "override-recursive-chunker": import "components/chunker-recursive.jsonnet", - "prompt-template-definitions": import "components/null.jsonnet", - "prompt-template-document-query": import "components/null.jsonnet", - "prompt-template-kq-query": import "components/null.jsonnet", - "prompt-template-relationships": import "components/null.jsonnet", - "prompt-template-rows-template": import "components/null.jsonnet", - "prompt-generic": import "components/prompt-generic.jsonnet", + "prompt-template": import "components/prompt-template.jsonnet", + "prompt-overrides": import "components/prompt-overrides.jsonnet", + "pulsar": import "components/pulsar.jsonnet", "pulsar-manager": import "components/pulsar-manager.jsonnet", "trustgraph-base": import "components/trustgraph.jsonnet", diff --git a/templates/components/prompt-generic.jsonnet b/templates/components/prompt-generic.jsonnet deleted file mode 100644 index 5d6d7c54..00000000 --- a/templates/components/prompt-generic.jsonnet +++ /dev/null @@ -1,81 +0,0 @@ -local base = import "base/base.jsonnet"; -local images = import "values/images.jsonnet"; -local url = import "values/url.jsonnet"; -local prompts = import "prompts/mixtral.jsonnet"; - -{ - - "prompt" +: { - - create:: function(engine) - - local container = - engine.container("prompt") - .with_image(images.trustgraph) - .with_command([ - "prompt-generic", - "-p", - url.pulsar, - "--text-completion-request-queue", - "non-persistent://tg/request/text-completion", - "--text-completion-response-queue", - "non-persistent://tg/response/text-completion-response", - ]) - .with_limits("0.5", "128M") - .with_reservations("0.1", "128M"); - - local containerSet = engine.containers( - "prompt", [ container ] - ); - - local service = - engine.internalService(containerSet) - .with_port(8080, 8080, "metrics"); - - engine.resources([ - containerSet, - service, - ]) - - }, - - "prompt-rag" +: { - - create:: function(engine) - - local container = - engine.container("prompt-rag") - .with_image(images.trustgraph) - .with_command([ - "prompt-generic", - "-p", - url.pulsar, - "-i", - "non-persistent://tg/request/prompt-rag", - "-o", - "non-persistent://tg/response/prompt-rag-response", - "--text-completion-request-queue", - "non-persistent://tg/request/text-completion-rag", - "--text-completion-response-queue", - "non-persistent://tg/response/text-completion-rag-response", - ]) - .with_limits("0.5", "128M") - .with_reservations("0.1", "128M"); - - local containerSet = engine.containers( - "prompt-rag", [ container ] - ); - - local service = - engine.internalService(containerSet) - .with_port(8080, 8080, "metrics"); - - engine.resources([ - containerSet, - service, - ]) - - }, - -} - diff --git a/templates/components/prompt-overrides.jsonnet b/templates/components/prompt-overrides.jsonnet new file mode 100644 index 00000000..de02d82a --- /dev/null +++ b/templates/components/prompt-overrides.jsonnet @@ -0,0 +1,28 @@ +local base = import "base/base.jsonnet"; +local images = import "values/images.jsonnet"; +local url = import "values/url.jsonnet"; +local prompts = import "prompts/mixtral.jsonnet"; +local default_prompts = import "prompts/default-prompts.jsonnet"; + +{ + + with:: function(key, value) + if (key == "system-template") then + self + { + prompts +:: { + "system-template": value, + } + } + else + self + { + prompts +:: { + templates +:: { + [key]: { + prompt +:: value + } + } + } + }, + +} + default_prompts + diff --git a/templates/generate b/templates/generate new file mode 100755 index 00000000..e4925cec --- /dev/null +++ b/templates/generate @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 + +import _jsonnet as j +import json +import yaml +import logging +import os +import sys +import zipfile + +logger = logging.getLogger("generate") +logging.basicConfig(level=logging.INFO, format='%(message)s') + +private_json = "Put your GCP private.json here" + +class Generator: + + def __init__(self, config, base="./templates/", version="0.0.0"): + + self.jsonnet_base = base + self.config = config + self.version = f"\"{version}\"".encode("utf-8") + + def process(self, config): + + res = j.evaluate_snippet("config", config, import_callback=self.load) + return json.loads(res) + + def load(self, dir, filename): + + logger.debug("Request jsonnet: %s %s", dir, filename) + + if filename == "config.json" and dir == "": + path = os.path.join(".", dir, filename) + return str(path), self.config + + if filename == "version.jsonnet" and dir == "./templates/values/": + path = os.path.join(".", dir, filename) + return str(path), self.version + + if dir: + candidates = [ + os.path.join(".", dir, filename), + os.path.join(".", filename) + ] + else: + candidates = [ + os.path.join(".", filename) + ] + + try: + + if filename == "vertexai/private.json": + + return candidates[0], private_json.encode("utf-8") + + for c in candidates: + logger.debug("Try: %s", c) + + if os.path.isfile(c): + with open(c, "rb") as f: + logger.debug("Loading: %s", c) + return str(c), f.read() + + raise RuntimeError( + f"Could not load file={filename} dir={dir}" + ) + + except: + + path = os.path.join(self.jsonnet_base, filename) + logger.debug("Try: %s", path) + with open(path, "rb") as f: + logger.debug("Loaded: %s", path) + return str(path), f.read() + +def main(): + + if len(sys.argv) != 3: + print() + print("Usage:") + print(" generate < input.json") + print() + raise RuntimeError("Arg error") + + outfile = sys.argv[1] + version = sys.argv[2] + + cfg = sys.stdin.read() + cfg = json.loads(cfg) + + logger.info(f"Outputting to {outfile}...") + + with zipfile.ZipFile(outfile, mode='w') as out: + + def output(name, content): + logger.info(f"Adding {name}...") + out.writestr(name, content) + + fname = "tg-launch.yaml" + + platform = "docker-compose" + + with open(f"./templates/config-to-{platform}.jsonnet", "r") as f: + wrapper = f.read() + + gen = Generator(json.dumps(cfg).encode("utf-8"), version=version) + + processed = gen.process(wrapper) + + y = yaml.dump(processed) + + output(fname, y) + + # Placeholder for the private.json file. Won't put actual credentials + # here. + output("docker-compose/vertexai/private.json", private_json) + + # Grafana config + with open("grafana/dashboards/dashboard.json") as f: + output( + "docker-compose/grafana/dashboards/dashboard.json", f.read() + ) + + with open("grafana/provisioning/dashboard.yml") as f: + output( + "docker-compose/grafana/provisioning/dashboard.yml", f.read() + ) + + with open("grafana/provisioning/datasource.yml") as f: + output( + "docker-compose/grafana/provisioning/datasource.yml", f.read() + ) + + # Prometheus config + with open("prometheus/prometheus.yml") as f: + output("docker-compose/prometheus/prometheus.yml", f.read()) + +main() + diff --git a/templates/util/decode-config.jsonnet b/templates/util/decode-config.jsonnet index a1bd146e..503b5b6b 100644 --- a/templates/util/decode-config.jsonnet +++ b/templates/util/decode-config.jsonnet @@ -3,9 +3,7 @@ local components = import "components.jsonnet"; local apply = function(p, components) - local component = components[p.name]; - - (component + { + local base = { with:: function(k, v) self + { [k]:: v @@ -18,7 +16,11 @@ local apply = function(p, components) self ), - }).with_params(p.parameters); + }; + + local component = base + components[p.name]; + + component.with_params(p.parameters); local decode = function(config) local add = function(state, c) state + apply(c, components); diff --git a/trustgraph-flow/trustgraph/model/prompt/generic/service.py b/trustgraph-flow/trustgraph/model/prompt/generic/service.py index 16986980..96c9be57 100755 --- a/trustgraph-flow/trustgraph/model/prompt/generic/service.py +++ b/trustgraph-flow/trustgraph/model/prompt/generic/service.py @@ -2,6 +2,15 @@ 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 @@ -469,5 +478,7 @@ class Processor(ConsumerProducer): def run(): + raise RuntimeError("NOT IMPLEMENTED") + Processor.start(module, __doc__)