dhti-cli 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -105
- package/dist/commands/docker.d.ts +1 -0
- package/dist/commands/docker.js +45 -8
- package/dist/commands/elixir.js +2 -2
- package/oclif.manifest.json +10 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,27 +3,43 @@
|
|
|
3
3
|
<img src="https://github.com/dermatologist/dhti/blob/develop/notes/dhti-logo.jpg" />
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
|
-
[](https://www.npmjs.com/package/dhti)
|
|
7
|
-
[](https://www.npmjs.com/package/dhti)
|
|
6
|
+
[](https://www.npmjs.com/package/dhti-cli)
|
|
7
|
+
[](https://www.npmjs.com/package/dhti-cli)
|
|
8
8
|
[](https://nuchange.ca)
|
|
9
|
-
[](https://www.npmjs.com/package/dhti)
|
|
9
|
+
[](https://www.npmjs.com/package/dhti-cli)
|
|
10
10
|
[](https://dermatologist.github.io/dhti/)
|
|
11
|
+
[](https://github.com/dermatologist/dhti/wiki)
|
|
12
|
+
|
|
11
13
|
|
|
12
|
-
## About
|
|
13
14
|
- 🚀 *Dhanvantari rose out of the water with his four hands, holding a pot full of elixirs!*
|
|
14
15
|
|
|
15
|
-
TL; DR:
|
|
16
|
-
[
|
|
16
|
+
#### TL; DR: 🏥 DHTI enables rapid prototyping, sharing, and testing of GenAI applications within an Electronic Health Record (EHR), facilitating the seamless transition of your experiments to clinical practice.
|
|
17
|
+
👉 [Try it out today!](#try-it-out) and give us a star ⭐️ if you like it!
|
|
18
|
+
|
|
19
|
+
### About
|
|
20
|
+
|
|
21
|
+
Generative AI features are built as [LangServe Apps](https://python.langchain.com/docs/langserve/) (elixirs) that can be installed into a LangServe instance and exposed as APIs. [OpenMRS O3 esm](https://o3-docs.openmrs.org/) / [**CDS hook** clients](https://github.com/dermatologist/cds-hooks-sandbox/tree/dhti-1) (conchs) provide the interface to communicate with these APIs. All backend data exchange is done through the **FHIR API** (a base class provides all these features). dhti-cli simplifies this process by providing a CLI that includes managing a Docker Compose with all additional components, such as [Ollama](https://ollama.com/) for **local LLM hosting**. LLM and hyperparameters are **injected at runtime** and can be easily swapped. In essence, dhti decouples GenAI modules from the rest of the system. 👉 [Try it out today!](#try-it-out)
|
|
22
|
+
|
|
23
|
+
### Want to know more?
|
|
17
24
|
|
|
18
25
|
Gen AI can transform medicine. But it needs a framework for collaborative research and practice. DHTI is a reference architecture and an implementation for such a framework that integrates an EMR ([OpenMRS](https://openmrs.org/)), :link: Gen AI application server ([LangServe](https://python.langchain.com/v0.2/docs/langserve/)), self-hosted LLMs for privacy ([Ollama](https://ollama.com/)), tools on [MCP server](https://github.com/dermatologist/fhir-mcp-server), vector store for RAG ([redis](https://redis.io/)), monitoring ([LangFuse](https://langfuse.com/)), 🔥 FHIR repository with [CQL](https://nuchange.ca/2025/06/v-llm-in-the-loop-cql-execution-with-unstructured-data-and-fhir-terminology-support.html) support ([HAPI](https://cloud.alphora.com/sandbox/r4/cqm/)) and graph utilities ([Neo4j](https://neo4j.com/)) in one docker-compose! DHTI is inspired by [Bahmni](https://www.bahmni.org/) and **aims to facilitate GenAI adoption and research in areas with low resources.** The MCP server hosts pluggable, agent-invokable tools (FHIR query, summarization, terminology lookup, custom analytics, etc.) that you can extend without modifying core services.
|
|
19
26
|
|
|
20
|
-
The essence of DHTI is *modularity* with an emphasis on *configuration!* It is non-opinionated on LLMs, hyperparameters and pretty much everything. DHTI supports installable Gen AI routines through [
|
|
27
|
+
The essence of DHTI is *modularity* with an emphasis on *configuration!* It is non-opinionated on LLMs, hyperparameters and pretty much everything. DHTI supports installable Gen AI routines through [LangServe Apps](https://python.langchain.com/docs/langserve/) (which we call :curry: **elixir**) and installable UI elements through [OpenMRS O3](https://o3-docs.openmrs.org/) React container (which we call :shell: **conch**). 🔥 FHIR is used for backend and [CDS-Hooks](https://cds-hooks.org/) for frontend communication, decoupling conches from OpenMRS, making them potentially usable with any health information system. We have a [fork of the cds-hook sandbox](https://github.com/dermatologist/cds-hooks-sandbox/tree/dhti-1) for testing that uses the [order-select](https://cds-hooks.org/hooks/order-select/) hook, utilizing the contentString from the [FHIR CommunicationRequest](https://build.fhir.org/communicationrequest.html) within the [cds-hook context](https://cds-hooks.org/examples/) for user inputs (recommended).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="https://github.com/dermatologist/openmrs-esm-dhti-template/blob/develop/notes/conch.jpg" />
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
*[OpenMRS ESM DHTI template](https://github.com/dermatologist/openmrs-esm-dhti-template) + [DHTI elixir template](https://github.com/dermatologist/dhti-elixir-template) together forms a simple but functional EMR chatbot too!* 👉 [Try it out today!](#try-it-out)
|
|
21
35
|
|
|
22
36
|
<p align="center">
|
|
23
37
|
<img src="https://github.com/dermatologist/dhti/blob/develop/notes/cds-hook-sandbox.jpg" />
|
|
24
38
|
</p>
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
*[CDS-Hooks sandbox](https://github.com/dermatologist/cds-hooks-sandbox) for testing conchs without OpenMRS.* 👉 [Try it out today!](#try-it-out)
|
|
41
|
+
|
|
42
|
+
🚀 dhti-cli is a CLI tool for quick prototyping and testing of elixirs and conches. You can create a new docker-compose with required modules, start/stop services, install Elixirs and conch, create Docker images for them, and more. 🚀 This helps to test new ideas and share them with others quickly. 🚀 Once tested, you can transition them to the production team for deployment. Adoption of standards makes this transition easier! 👉 [Try it out today!](#try-it-out)
|
|
27
43
|
|
|
28
44
|
⭐️ **Pitched at [Falling Walls Lab Illinois](https://falling-walls.com/falling-walls-lab-illinois) and released on 09/12/2025.**
|
|
29
45
|
|
|
@@ -43,6 +59,8 @@ The essence of DHTI is *modularity* with an emphasis on *configuration!* It is n
|
|
|
43
59
|
<img src="https://github.com/dermatologist/dhti/blob/develop/notes/arch-1.drawio.svg" />
|
|
44
60
|
</p>
|
|
45
61
|
|
|
62
|
+
🔥 **Coming soon!:** We are currently working on expanding the DHTI architecture to support traditional machine learning models, such as *EEG sleep stage classification* and *trichogram analysis*, exposing inference pipelines as agentic tools!
|
|
63
|
+
|
|
46
64
|
## ✨ Features
|
|
47
65
|
* **Modular**: Supports installable Gen AI routines and UI elements.
|
|
48
66
|
* **Quick prototyping**: CLI helps in quick prototyping and testing of Gen AI routines and UI elements.
|
|
@@ -63,13 +81,14 @@ The essence of DHTI is *modularity* with an emphasis on *configuration!* It is n
|
|
|
63
81
|
|
|
64
82
|
*Developers can build elixirs and conchs for DHTI.*
|
|
65
83
|
|
|
66
|
-
:curry: Elixirs are [
|
|
84
|
+
:curry: Elixirs are [LangServe Apps](https://python.langchain.com/docs/langserve/) for backend GenAI functionality. By convention, Elixirs are prefixed with *dhti-elixir-* and all elixirs depend on [dhti-elixir-base](https://github.com/dermatologist/dhti-elixir-base) which provides some base classes and defines dependencies. You can use [this template](https://github.com/dermatologist/dhti-elixir-template) or the [cookiecutter](https://github.com/dermatologist/cookiecutter-uv) to build new elixirs, and license it the way you want (We :heart: open-source!).
|
|
67
85
|
|
|
68
|
-
:shell: Conches are [OpenMRS O3s](https://o3-docs.openmrs.org/) and follow the standard naming convention *openmrs-esm-*.
|
|
86
|
+
:shell: Conches are [OpenMRS O3s](https://o3-docs.openmrs.org/) and follow the standard naming convention *openmrs-esm-*. You can use [this template](https://github.com/dermatologist/openmrs-esm-dhti-template) to build new conches.
|
|
69
87
|
|
|
70
88
|
:white_check_mark:
|
|
71
89
|
* **Developer friendly**: Copy working files to running containers for testing.
|
|
72
90
|
* **Dependency Injection**: Dependency injection for models and hyperparameters for configuring elixirs.
|
|
91
|
+
* 👉 [Try it out today!](#try-it-out)
|
|
73
92
|
|
|
74
93
|
## 🧠 For Gen AI Researchers
|
|
75
94
|
|
|
@@ -82,8 +101,9 @@ Tools to fine-tune language models for the stack are on our roadmap. We encourag
|
|
|
82
101
|
:white_check_mark:
|
|
83
102
|
* **Generate synthetic data**: DHTI supports generating synthetic data for testing.
|
|
84
103
|
* **CQL support**: [CQL for clinical decision support](https://nuchange.ca/2025/06/v-llm-in-the-loop-cql-execution-with-unstructured-data-and-fhir-terminology-support.html).
|
|
85
|
-
* **FHIR**: Data exchange with FHIR schema.
|
|
86
|
-
* **EMR**: Built
|
|
104
|
+
* **FHIR**: Data exchange with FHIR schema and **CDS-Hooks** for frontend-backend communication.
|
|
105
|
+
* **EMR**: Built-in EMR, OpenMRS, for patient records.
|
|
106
|
+
* 👉 [Try it out today!](#try-it-out)
|
|
87
107
|
|
|
88
108
|
🌈 *Join us to make the Gen AI equitable and help doctors save lives!*
|
|
89
109
|
|
|
@@ -94,6 +114,7 @@ Tools to fine-tune language models for the stack are on our roadmap. We encourag
|
|
|
94
114
|
## :sparkles: Resources (in Beta)
|
|
95
115
|
* [dhti-elixir-base](https://github.com/dermatologist/dhti-elixir-base): Base classes for dhti-elixir
|
|
96
116
|
* [dhti-elixir-template](https://github.com/dermatologist/dhti-elixir-template): A template for creating new dhti-elixirs.
|
|
117
|
+
* [openmrs-esm-dhti-template](https://github.com/dermatologist/openmrs-esm-dhti-template): A conch template for OpenMRS
|
|
97
118
|
* [fhir-mcp-server](https://github.com/dermatologist/fhir-mcp-server): A MCP server for hosting FHIR-compliant tools.
|
|
98
119
|
|
|
99
120
|
## :sparkles: Resources (in Alpha)
|
|
@@ -107,104 +128,23 @@ Tools to fine-tune language models for the stack are on our roadmap. We encourag
|
|
|
107
128
|
* [dhti-elixir-upload](https://github.com/dermatologist/dhti-elixir-upload-file): Upload documents to the vector store for clinical knowledgebase and clinical trial matching.
|
|
108
129
|
* [openmrs-esm-qa](https://github.com/dermatologist/openmrs-esm-genai): A sample conch for Q&A on patient records using the dhti-elixir-fhire elixir.
|
|
109
130
|
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
### List of plugins
|
|
113
|
-
```
|
|
114
|
-
dhti-cli help
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Get help for each plugin
|
|
118
|
-
* As an example, get help for compose:
|
|
119
|
-
|
|
120
|
-
```
|
|
121
|
-
dhti-cli compose --help
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### 🏗️ *Try it out! It takes only a few minutes to setup GenAI backed EMR in your local machine!*
|
|
125
|
-
|
|
126
|
-
You only need:
|
|
127
|
-
* docker
|
|
128
|
-
* nodejs
|
|
129
|
-
|
|
130
|
-
## :walking: Step 1
|
|
131
|
-
|
|
132
|
-
* Git clone this repository: `git clone https://github.com/dermatologist/dhti.git && cd dhti`
|
|
133
|
-
* Install the required packages: `npm install`
|
|
134
|
-
* Build the CLI: `npm run build`
|
|
135
|
-
* Install CLI locally: `npm link`
|
|
136
|
-
* Test the CLI: `dhti-cli help` *This will show the available commands.*
|
|
137
|
-
* The working directory is `~/dhti` (Customizable)
|
|
138
|
-
|
|
139
|
-
### 🔧 Create a new docker-compose
|
|
140
|
-
* Create a new docker-compose file: `dhti-cli compose add -m openmrs -m langserve`
|
|
141
|
-
|
|
142
|
-
* The docker-compose.yml is created with the following modules:
|
|
143
|
-
- OpenMRS (EMR)
|
|
144
|
-
- LangServe (API for LLM models)
|
|
145
|
-
|
|
146
|
-
Other available modules: `ollama, langfuse, cqlFhir, redis, neo4j and mcpFhir` (Documentation in progress)
|
|
131
|
+
## Try it out
|
|
147
132
|
|
|
148
|
-
You can
|
|
133
|
+
* You only need [Node.js](https://nodejs.org/) and [Docker](https://www.docker.com/) installed to run this project. Optionally, you can install [Python](https://www.python.org/) if you want to develop new elixirs. We use a fake LLM script for testing purposes, so you don't need an OpenAI key to run this project. It just says "Paris" or "I don't know" to any prompt. You can replace it with any internal or external LLM service later.
|
|
149
134
|
|
|
135
|
+
* `npx dhti-cli help` to see all available commands.
|
|
150
136
|
|
|
151
|
-
|
|
152
|
-
* Start the services: `dhti-cli docker -u`
|
|
137
|
+
* `npx dhti-cli compose add -m openmrs -m langserve` to add OpenMRS and Langserve elixirs to your docker-compose.yml at ~/dhti. Other available modules: `ollama, langfuse, cqlFhir, redis, neo4j and mcpFhir`. You can read the newly created docker-compose by: `npx dhti-cli compose read`
|
|
153
138
|
|
|
154
|
-
|
|
139
|
+
* `npx dhti-cli elixir install -g https://github.com/dermatologist/dhti-elixir-template.git -n dhti-elixir-template` to install a sample elixir from github. (Optionally) You may configure the hyperparameters in `~/dhti/elixir/app/bootstrap.py`. You can install multiple elixirs.
|
|
155
140
|
|
|
141
|
+
* `npx dhti-cli docker -n yourdockerhandle/genai-test:1.0 -t elixir` to build a docker image for the elixir.
|
|
156
142
|
|
|
157
|
-
|
|
158
|
-
* Go to `http://localhost/openmrs/spa/home`
|
|
159
|
-
* Login with the following credentials:
|
|
160
|
-
- Username: admin
|
|
161
|
-
- Password: Admin123
|
|
162
|
-
- Choose any location and click on 'confirm'.
|
|
163
|
-
|
|
164
|
-
### 🚀 Access the LangServe API
|
|
165
|
-
* Go to `localhost:8001/docs` (Empty Swagger UI)
|
|
166
|
-
|
|
167
|
-
## Congratulations! You have successfully setup DHTI! :tada:
|
|
168
|
-
* Shut down the services: `dhti-cli docker -d`
|
|
169
|
-
|
|
170
|
-
## :running: STEP 2: 🛠️ *Now let us Install an Elixir (Gen AI functionalities are packaged as elixirs)*
|
|
171
|
-
|
|
172
|
-
* Let's install the elixir here: https://github.com/dermatologist/dhti-elixir-template. This is just a template that uses a Mock LLM to output random text. You can use this template to build your own elixirs! (Cookiecutter to be released soon!) Later you will see how to add real LLM support.
|
|
173
|
-
|
|
174
|
-
:running:
|
|
175
|
-
|
|
176
|
-
`dhti-cli elixir install -g https://github.com/dermatologist/dhti-elixir-template.git -n dhti-elixir-template`.
|
|
177
|
-
|
|
178
|
-
You may also install from PyPi or a wheel file!
|
|
179
|
-
|
|
180
|
-
### 🔍 Examine bootstrap.py (Optional)
|
|
181
|
-
`cat ~/dhti/elixir/app/bootstrap.py`
|
|
143
|
+
* `npx dhti-cli conch install -g https://github.com/dermatologist/openmrs-esm-dhti-template.git -n openmrs-esm-dhti-template` to install a simple OpenMRS ESM module (conch)from github. You can install multiple conches.
|
|
182
144
|
|
|
183
|
-
|
|
145
|
+
* `npx dhti-cli docker -n yourdockerhandle/conch-test:1.0 -t conch` to build a docker image for the conches.
|
|
184
146
|
|
|
185
|
-
|
|
186
|
-
`dhti-cli docker -n beapen/genai-test:1.0 -t elixir`
|
|
187
|
-
|
|
188
|
-
(You may replace `beapen/genai-test:1.0` with your own image name)
|
|
189
|
-
|
|
190
|
-
### 🚀 Congratulations! You installed your first elixir. We will see it in action later!
|
|
191
|
-
|
|
192
|
-
While developing you can copy the app folder to a running container for testing (provided there are no changes in dependencies). Read more [here](/notes/dev-copy.md).
|
|
193
|
-
|
|
194
|
-
## STEP 3: :shell: *Now let us Install a Conch (The UI component)*
|
|
195
|
-
|
|
196
|
-
* Let's install the conch here:https://github.com/dermatologist/openmrs-esm-dhti-template. This uses the elixir template that we installed in STEP 2 as the backend. You can use the template to build your own conchs.
|
|
197
|
-
|
|
198
|
-
:shell: `dhti-cli conch install -g https://github.com/dermatologist/openmrs-esm-dhti-template.git -n openmrs-esm-dhti-template`
|
|
199
|
-
|
|
200
|
-
We can also install from a dev folder after cloning the repository. While developing you can copy the dist folder to a running container for testing. Read more [here](/notes/dev-copy.md).
|
|
201
|
-
|
|
202
|
-
### 🔧 Create new docker container
|
|
203
|
-
`dhti-cli docker -n beapen/conch-test:1.0 -t conch`
|
|
204
|
-
|
|
205
|
-
## 🚀 It is now time to start DHTI!
|
|
206
|
-
|
|
207
|
-
`dhti-cli docker -u`
|
|
147
|
+
* `npx dhti-cli docker -u` to start all the docker images in your docker-compose.yml.
|
|
208
148
|
|
|
209
149
|
### :clap: Access the Conch in OpenMRS and test the integration
|
|
210
150
|
|
|
@@ -219,8 +159,9 @@ This is just a template, though. You can build your own conchs!
|
|
|
219
159
|
Add some text to the text area and click on **Submit**.
|
|
220
160
|
You will see the text above the textbox.
|
|
221
161
|
|
|
222
|
-
|
|
223
|
-
|
|
162
|
+
* `npx dhti-cli docker -d` to stop and delete all the docker containers.
|
|
163
|
+
|
|
164
|
+
Read more in [notes/steps.md](/notes/steps.md). Complete documentation is in progress.
|
|
224
165
|
|
|
225
166
|
### The demo uses a template with mock LLM. [Check out how to add real LLM support using Google Gemini.](/notes/add-llm.md)
|
|
226
167
|
|
|
@@ -228,6 +169,7 @@ You can remove the services by: `dhti-cli docker -d`
|
|
|
228
169
|
|
|
229
170
|
## 🚀 Advanced
|
|
230
171
|
|
|
172
|
+
* [Detailed steps to try it out](/notes/steps.md)
|
|
231
173
|
* [Setting up Ollama](/notes/setup-ollama.md)
|
|
232
174
|
* [CLI Options](/notes/cli-options.md)
|
|
233
175
|
|
|
@@ -238,4 +180,4 @@ If you find this project useful, give us a star. It helps others discover the pr
|
|
|
238
180
|
|
|
239
181
|
## Contributors
|
|
240
182
|
|
|
241
|
-
* [Bell Eapen](https://nuchange.ca) | [](https://twitter.com/beapen)
|
|
183
|
+
* [Bell Eapen](https://nuchange.ca) ([UIS](https://www.uis.edu/directory/bell-punneliparambil-eapen)) | [Contact](https://nuchange.ca/contact) | [](https://twitter.com/beapen)
|
|
@@ -8,6 +8,7 @@ export default class Docker extends Command {
|
|
|
8
8
|
static flags: {
|
|
9
9
|
down: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
10
|
file: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
container: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
13
|
type: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
14
|
up: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
package/dist/commands/docker.js
CHANGED
|
@@ -9,12 +9,19 @@ export default class Docker extends Command {
|
|
|
9
9
|
path: Args.string({ default: `${os.homedir()}/dhti`, description: 'Docker project path to build. Ex: dhti' }),
|
|
10
10
|
};
|
|
11
11
|
static description = 'Build a docker project and update docker-compose file';
|
|
12
|
-
static examples = [
|
|
13
|
-
'<%= config.bin %> <%= command.id %>',
|
|
14
|
-
];
|
|
12
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
15
13
|
static flags = {
|
|
16
14
|
down: Flags.boolean({ char: 'd', default: false, description: 'Run docker-compose down after building' }),
|
|
17
|
-
file: Flags.string({
|
|
15
|
+
file: Flags.string({
|
|
16
|
+
char: 'f',
|
|
17
|
+
default: `${os.homedir()}/dhti/docker-compose.yml`,
|
|
18
|
+
description: 'Full path to the docker compose file to edit or run.',
|
|
19
|
+
}),
|
|
20
|
+
container: Flags.string({
|
|
21
|
+
char: 'c',
|
|
22
|
+
default: 'dhti-langserve-1',
|
|
23
|
+
description: 'Name of the container to copy the bootstrap file to while in dev mode',
|
|
24
|
+
}),
|
|
18
25
|
name: Flags.string({ char: 'n', description: 'Name of the container to build' }),
|
|
19
26
|
type: Flags.string({ char: 't', default: 'elixir', description: 'Type of the service (elixir/conch)' }),
|
|
20
27
|
up: Flags.boolean({ char: 'u', default: false, description: 'Run docker-compose up after building' }),
|
|
@@ -43,10 +50,36 @@ export default class Docker extends Command {
|
|
|
43
50
|
});
|
|
44
51
|
return;
|
|
45
52
|
}
|
|
46
|
-
if (!flags.name &&
|
|
47
|
-
console.log(
|
|
53
|
+
if (args.path !== 'bootstrap' && !flags.name && !flags.up && !flags.down) {
|
|
54
|
+
console.log('Please provide a name for the container to build');
|
|
48
55
|
this.exit(1);
|
|
49
56
|
}
|
|
57
|
+
if (args.path === 'bootstrap') {
|
|
58
|
+
// if flags.file does not end with bootstrap.py then exit
|
|
59
|
+
if (!flags.file.endsWith('bootstrap.py')) {
|
|
60
|
+
console.log('Please provide a valid path to bootstrap.py file');
|
|
61
|
+
this.exit(1);
|
|
62
|
+
}
|
|
63
|
+
// copy -f to container:/app/app/ and only restart after copy completes
|
|
64
|
+
exec(`docker cp ${flags.file} ${flags.container}:/app/app/bootstrap.py`, (error, stdout, stderr) => {
|
|
65
|
+
if (error) {
|
|
66
|
+
console.error(`exec error: ${error}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log(`stdout: ${stdout}`);
|
|
70
|
+
console.error(`stderr: ${stderr}`);
|
|
71
|
+
// restart the container only after copy completes
|
|
72
|
+
exec(`docker restart ${flags.container}`, (restartError, restartStdout, restartStderr) => {
|
|
73
|
+
if (restartError) {
|
|
74
|
+
console.error(`exec error: ${restartError}`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
console.log(`stdout: ${restartStdout}`);
|
|
78
|
+
console.error(`stderr: ${restartStderr}`);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
50
83
|
// cd to path, docker build tag with name
|
|
51
84
|
const spinner = ora('Running docker build ..').start();
|
|
52
85
|
exec(`cd ${args.path}/${flags.type} && docker build -t ${flags.name} . > /dev/null 2>&1`, (error, stdout, stderr) => {
|
|
@@ -60,15 +93,19 @@ export default class Docker extends Command {
|
|
|
60
93
|
console.error(`stderr: ${stderr}`);
|
|
61
94
|
});
|
|
62
95
|
// read the docker-compose file
|
|
96
|
+
if (!fs.existsSync(flags.file)) {
|
|
97
|
+
console.error(`Error: The file "${flags.file}" does not exist.`);
|
|
98
|
+
this.exit(1);
|
|
99
|
+
}
|
|
63
100
|
const dockerCompose = yaml.load(fs.readFileSync(flags.file, 'utf8'));
|
|
64
101
|
// if type is elixir set image of backend to name, else set image of frontend to name
|
|
65
102
|
if (flags.type === 'elixir') {
|
|
66
103
|
dockerCompose.services.langserve.image = flags.name;
|
|
67
|
-
dockerCompose.services.langserve.pull_policy =
|
|
104
|
+
dockerCompose.services.langserve.pull_policy = 'if_not_present';
|
|
68
105
|
}
|
|
69
106
|
else {
|
|
70
107
|
dockerCompose.services.frontend.image = flags.name;
|
|
71
|
-
dockerCompose.services.frontend.pull_policy =
|
|
108
|
+
dockerCompose.services.frontend.pull_policy = 'if_not_present';
|
|
72
109
|
}
|
|
73
110
|
// write the docker-compose file
|
|
74
111
|
fs.writeFileSync(flags.file, yaml.dump(dockerCompose));
|
package/dist/commands/elixir.js
CHANGED
|
@@ -47,9 +47,9 @@ export default class Elixir extends Command {
|
|
|
47
47
|
// if arg is dev then copy to docker as below
|
|
48
48
|
// docker restart dhti-langserve-1
|
|
49
49
|
if (args.op === 'dev') {
|
|
50
|
-
console.log(`cd ${flags.dev} && docker cp
|
|
50
|
+
console.log(`cd ${flags.dev} && docker cp src/${expoName}/. ${flags.container}:/app/.venv/lib/python3.12/site-packages/${expoName}`);
|
|
51
51
|
try {
|
|
52
|
-
exec(`cd ${flags.dev} && docker cp
|
|
52
|
+
exec(`cd ${flags.dev} && docker cp src/${expoName}/. ${flags.container}:/app/.venv/lib/python3.12/site-packages/${expoName}`, (error, stdout, stderr) => {
|
|
53
53
|
if (error) {
|
|
54
54
|
console.error(`exec error: ${error}`);
|
|
55
55
|
return;
|
package/oclif.manifest.json
CHANGED
|
@@ -176,6 +176,15 @@
|
|
|
176
176
|
"multiple": false,
|
|
177
177
|
"type": "option"
|
|
178
178
|
},
|
|
179
|
+
"container": {
|
|
180
|
+
"char": "c",
|
|
181
|
+
"description": "Name of the container to copy the bootstrap file to while in dev mode",
|
|
182
|
+
"name": "container",
|
|
183
|
+
"default": "dhti-langserve-1",
|
|
184
|
+
"hasDynamicHelp": false,
|
|
185
|
+
"multiple": false,
|
|
186
|
+
"type": "option"
|
|
187
|
+
},
|
|
179
188
|
"name": {
|
|
180
189
|
"char": "n",
|
|
181
190
|
"description": "Name of the container to build",
|
|
@@ -440,5 +449,5 @@
|
|
|
440
449
|
]
|
|
441
450
|
}
|
|
442
451
|
},
|
|
443
|
-
"version": "0.3.
|
|
452
|
+
"version": "0.3.3"
|
|
444
453
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dhti-cli",
|
|
3
3
|
"description": "DHTI CLI",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"author": "Bell Eapen",
|
|
6
6
|
"bin": {
|
|
7
7
|
"dhti-cli": "bin/run.js"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@types/chai": "^4",
|
|
26
26
|
"@types/js-yaml": "^4.0.9",
|
|
27
27
|
"@types/mocha": "^10",
|
|
28
|
-
"@types/node": "^
|
|
28
|
+
"@types/node": "^24",
|
|
29
29
|
"@types/request": "^2.48.12",
|
|
30
30
|
"@types/sinon": "^17.0.4",
|
|
31
31
|
"chai": "^4",
|