Skip to content

Commit

Permalink
Merge branch 'main' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ARajgor committed Mar 30, 2024
2 parents ae18354 + b72bd7f commit 1d03d1b
Show file tree
Hide file tree
Showing 40 changed files with 697 additions and 99 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
Expand Down
33 changes: 33 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

.PHONY = setup deps compose-up compose-down compose-destroy

# to check if docker is installed on the machine
DOCKER := $(shell command -v docker)
DOCKER_COMPOSE := $(shell command -v docker-compose)
deps:
ifndef DOCKER
@echo "Docker is not available. Please install docker"
@echo "try running sudo apt-get install docker"
@exit 1
endif
ifndef DOCKER_COMPOSE
@echo "docker-compose is not available. Please install docker-compose"
@echo "try running sudo apt-get install docker-compose"
@exit 1
endif

setup:
sh +x build

compose-down: deps
docker volume ls
docker-compose ps
docker images
docker-compose down;

compose-up: deps compose-down
docker-compose up --build

compose-destroy: deps
docker images | grep -i devika | awk '{print $$3}' | xargs docker rmi -f
docker volume prune
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ ollama serve
git clone https://github.com/stitionai/devika.git
cd devika/
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
cd ui/
bun install
bun run dev
cd ..
python3 devika.py
```

Expand Down Expand Up @@ -226,12 +228,24 @@ To join the Devika community Discord server, [click here](https://discord.com/in

## Contributing

We welcome contributions to enhance Devika's capabilities and improve its performance. To contribute, please see the `CONTRIBUTING.md` file for steps.
We welcome contributions to enhance Devika's capabilities and improve its performance. To contribute, please see the [`CONTRIBUTING.md`](CONTRIBUTING.md) file for steps.

## License

Devika is released under the [MIT License](https://opensource.org/licenses/MIT). See the `LICENSE` file for more information.

## Star History

<div align="center">
<a href="https://star-history.com/#stitionai/devika&Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=stitionai/devika&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=stitionai/devika&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=stitionai/devika&type=Date" />
</picture>
</a>
</div>

---

We hope you find Devika to be a valuable tool in your software development journey. If you have any questions, feedback, or suggestions, please don't hesitate to reach out. Happy coding with Devika!
29 changes: 29 additions & 0 deletions app.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM debian:12

# setting up build variable
ARG VITE_API_BASE_URL
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}

# setting up os env
USER root
WORKDIR /home/nonroot/client
RUN groupadd -r nonroot && useradd -r -g nonroot -d /home/nonroot/client -s /bin/bash nonroot

# install node js
RUN apt-get update && apt-get upgrade
RUN apt-get install -y build-essential software-properties-common curl sudo wget git
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
RUN apt-get install nodejs

# copying devika app client only
COPY ui /home/nonroot/client/ui
COPY src /home/nonroot/client/src
COPY config.toml /home/nonroot/client/

RUN cd ui && npm install && npm install -g npm && npm install -g bun
RUN chown -R nonroot:nonroot /home/nonroot/client

USER nonroot
WORKDIR /home/nonroot/client/ui

ENTRYPOINT [ "npx", "bun", "run", "dev", "--", "--host" ]
35 changes: 35 additions & 0 deletions devika.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
FROM debian:12

# setting up os env
USER root
WORKDIR /home/nonroot/devika
RUN groupadd -r nonroot && useradd -r -g nonroot -d /home/nonroot/devika -s /bin/bash nonroot

ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1

# setting up python3
RUN apt-get update && apt-get upgrade
RUN apt-get install -y build-essential software-properties-common curl sudo wget git
RUN apt-get install -y python3 python3-pip
RUN curl -fsSL https://astral.sh/uv/install.sh | sudo -E bash -
RUN $HOME/.cargo/bin/uv venv
ENV PATH="/home/nonroot/devika/.venv/bin:$HOME/.cargo/bin:$PATH"

# copy devika python engine only
RUN $HOME/.cargo/bin/uv venv
COPY requirements.txt /home/nonroot/devika/
RUN UV_HTTP_TIMEOUT=100000 $HOME/.cargo/bin/uv pip install -r requirements.txt
RUN playwright install --with-deps

COPY src /home/nonroot/devika/src
COPY config.toml /home/nonroot/devika/
COPY devika.py /home/nonroot/devika/
RUN chown -R nonroot:nonroot /home/nonroot/devika

USER nonroot
WORKDIR /home/nonroot/devika
ENV PATH="/home/nonroot/devika/.venv/bin:$HOME/.cargo/bin:$PATH"
RUN mkdir /home/nonroot/devika/db

ENTRYPOINT [ "python3", "-m", "devika" ]
5 changes: 3 additions & 2 deletions devika.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ def calculate_tokens():
@app.route("/api/token-usage", methods=["GET"])
@route_logger(logger)
def token_usage():
from src.llm import TOKEN_USAGE
return jsonify({"token_usage": TOKEN_USAGE})
project_name = request.args.get("project_name")
token_count = AgentState().get_latest_token_usage(project_name)
return jsonify({"token_usage": token_count})


@app.route("/api/logs", methods=["GET"])
Expand Down
61 changes: 61 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: "3.9"

services:
ollama-service:
image: ollama/ollama:latest
expose:
- 11434
ports:
- 11434:11434
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:11434/ || exit 1"]
interval: 5s
timeout: 30s
retries: 5
start_period: 30s
networks:
- devika-subnetwork

devika-backend-engine:
build:
context: .
dockerfile: devika.dockerfile
depends_on:
- ollama-service
expose:
- 1337
ports:
- 1337:1337
environment:
- OLLAMA_HOST=http://ollama-service:11434
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:1337/ || exit 1"]
interval: 5s
timeout: 30s
retries: 5
start_period: 30s
volumes:
- devika-backend-dbstore:/home/nonroot/devika/db
networks:
- devika-subnetwork

devika-frontend-app:
build:
context: .
dockerfile: app.dockerfile
args:
- VITE_API_BASE_URL=http://127.0.0.1:1337
depends_on:
- devika-backend-engine
expose:
- 3000
ports:
- 3000:3000
networks:
- devika-subnetwork

networks:
devika-subnetwork:

volumes:
devika-backend-dbstore:
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ xhtml2pdf
mistralai
Flask-SocketIO
eventlet
groq
8 changes: 7 additions & 1 deletion sample.config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ LOGS_DIR = "data/logs"
REPOS_DIR = "data/repos"

[API_KEYS]
NETLIFY = "<YOUR_NETLIFY_API_KEY>"
BING = "<YOUR_BING_API_KEY>"
GOOGLE = "<YOUR_GOOGLE_API_KEY>"
GOOGLE_CX = "<YOUR_GOOGLE_CUSTOM_SEARCH_ENGINE_ID>"
CLAUDE = "<YOUR_CLAUDE_API_KEY>"
NETLIFY = "<YOUR_NETLIFY_API_KEY>"
OPENAI = "<YOUR_OPENAI_API_KEY>"
GEMINI = "<YOUR_GEMINI_API_KEY>"
MISTRAL = "<YOUR_MISTRAL_API_KEY>"
GROQ = "<YOUR_GROQ_API_KEY>"

[API_ENDPOINTS]
BING = "https://api.bing.microsoft.com/v7.0/search"
GOOGLE = "https://www.googleapis.com/customsearch/v1"
OLLAMA = "http://127.0.0.1:11434"

[LOGGING]
LOG_REST_API = "true"
LOG_PROMPTS = "false"
6 changes: 3 additions & 3 deletions src/agents/action/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ def validate_response(self, response: str):
else:
return response["response"], response["action"]

def execute(self, conversation: list) -> str:
def execute(self, conversation: list, project_name: str) -> str:
prompt = self.render(conversation)
response = self.llm.inference(prompt)
response = self.llm.inference(prompt, project_name)

valid_response = self.validate_response(response)

while not valid_response:
print("Invalid response from the model, trying again...")
return self.execute(conversation)
return self.execute(conversation, project_name)

print("===" * 10)
print(valid_response)
Expand Down
43 changes: 24 additions & 19 deletions src/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,17 @@ def search_queries(self, queries: list, project_name: str) -> dict:
browser.go_to(link)
browser.screenshot(project_name)

""" Formatter Agent is invoked to format and learn from the contents """
results[query] = self.formatter.execute(browser.extract_text())

""" Add the newly acquired data to the knowledge base """
"""
Formatter Agent is invoked to format and learn from the contents
"""
results[query] = self.formatter.execute(
browser.extract_text(),
project_name
)

"""
Add the newly acquired data to the knowledge base
"""
# knowledge_base.add_knowledge(tag=query, contents=results[query])

return results
Expand All @@ -110,11 +117,8 @@ def update_contextual_keywords(self, sentence: str):
return self.collected_context_keywords

def make_decision(self, prompt: str, project_name: str) -> str:
"""
Decision making Agent
"""
decision = self.decision.execute(prompt)

decision = self.decision.execute(prompt, project_name)

for item in decision:
function = item["function"]
args = item["args"]
Expand All @@ -129,7 +133,7 @@ def make_decision(self, prompt: str, project_name: str) -> str:
elif function == "generate_pdf_document":
user_prompt = args["user_prompt"]
# Call the reporter agent to generate the PDF document
markdown = self.reporter.execute([user_prompt], "")
markdown = self.reporter.execute([user_prompt], "", project_name)
_out_pdf_file = PDF().markdown_to_pdf(markdown, project_name)

project_name_space_url = project_name.replace(" ", "%20")
Expand All @@ -150,10 +154,10 @@ def make_decision(self, prompt: str, project_name: str) -> str:
elif function == "coding_project":
user_prompt = args["user_prompt"]
# Call the planner, researcher, coder agents in sequence
plan = self.planner.execute(user_prompt)
plan = self.planner.execute(user_prompt, project_name)
planner_response = self.planner.parse_response(plan)

research = self.researcher.execute(plan, self.collected_context_keywords)
research = self.researcher.execute(plan, self.collected_context_keywords, project_name)
search_results = self.search_queries(research["queries"], project_name)

code = self.coder.execute(
Expand All @@ -176,7 +180,7 @@ def subsequent_execute(self, prompt: str, project_name: str):
conversation = self.project_manager.get_all_messages_formatted(project_name)
code_markdown = ReadCode(project_name).code_set_to_markdown()

response, action = self.action.execute(conversation)
response, action = self.action.execute(conversation, project_name)

self.project_manager.add_message_from_devika(project_name, response)

Expand All @@ -187,7 +191,8 @@ def subsequent_execute(self, prompt: str, project_name: str):
if action == "answer":
response = self.answer.execute(
conversation=conversation,
code_markdown=code_markdown
code_markdown=code_markdown,
project_name=project_name
)
self.project_manager.add_message_from_devika(project_name, response)
elif action == "run":
Expand Down Expand Up @@ -237,7 +242,7 @@ def subsequent_execute(self, prompt: str, project_name: str):

self.patcher.save_code_to_project(code, project_name)
elif action == "report":
markdown = self.reporter.execute(conversation, code_markdown)
markdown = self.reporter.execute(conversation, code_markdown, project_name)

_out_pdf_file = PDF().markdown_to_pdf(markdown, project_name)

Expand All @@ -262,7 +267,7 @@ def execute(self, prompt: str, project_name_from_user: str = None):
if project_name_from_user:
self.project_manager.add_message_from_user(project_name_from_user, prompt)

plan = self.planner.execute(prompt)
plan = self.planner.execute(prompt, project_name_from_user)
print("\nplan :: ", plan)
print("=====" * 10)

Expand Down Expand Up @@ -290,15 +295,15 @@ def execute(self, prompt: str, project_name_from_user: str = None):
self.update_contextual_keywords(focus)
print("\ncontext_keywords :: ", self.collected_context_keywords)

internal_monologue = self.internal_monologue.execute(current_prompt=plan)
internal_monologue = self.internal_monologue.execute(current_prompt=plan, project_name=project_name)
print("\ninternal_monologue :: ", internal_monologue)
print("=====" * 10)

new_state = self.agent_state.new_state()
new_state["internal_monologue"] = internal_monologue
self.agent_state.add_to_current_state(project_name, new_state)

research = self.researcher.execute(plan, self.collected_context_keywords)
research = self.researcher.execute(plan, self.collected_context_keywords, project_name=project_name)
print("\nresearch :: ", research)
print("=====" * 10)

Expand Down
Loading

0 comments on commit 1d03d1b

Please sign in to comment.