Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ source .venv/bin/activate
We have provided a custom run.yaml file to specify the required providers. Use the following command to run the Llama Stack with the custom configuration file.

```
cp pyproject.llama-stack.toml pyproject.toml
uv sync
source .venv/bin/activate
uv run llama stack run run.yaml
Comment on lines +74 to 77

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Readme dirties dependency files 🐞 Bug ⚙ Maintainability

README.md now instructs users to overwrite the tracked pyproject.toml in-place (twice) and run `uv
sync`, which can also update the tracked uv.lock and leave the repo in a dirty state. If those
changes are accidentally committed, the app container build can fail because it uses `uv sync
--frozen` and requires uv.lock to match pyproject.toml exactly.
Agent Prompt
## Issue description
README instructions overwrite `pyproject.toml` in-place (switching between `pyproject.llama-stack.toml` and `pyproject.orig.toml`) and rerun `uv sync`. This commonly leaves modified tracked files (`pyproject.toml`, and potentially `uv.lock`) in the working tree, increasing the chance of accidental commits; those commits can break the container build because it relies on `uv sync --frozen`.

## Issue Context
- The app image build copies `pyproject.toml` + `uv.lock` and runs `uv sync --frozen`.
- The README now suggests swapping `pyproject.toml` for different dependency sets.

## Fix Focus Areas
- README.md[71-78]
- README.md[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

```

Expand Down Expand Up @@ -117,6 +120,9 @@ uv run llama-stack-client configure --endpoint http://localhost:8321 --api-key n
## Run the application Code

```bash
cp pyproject.orig.toml pyproject.toml

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SHould we delete the pyproject.toml from main? Because it is still present in the repo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I wasn't sure @maysunfaisal .... I suspect it is better to have one in place just in case, so that the compiling etc. of the python project is viable out of the box

I also considered creating a "run llama stack" sub directory, and just move that pyproject.toml there, and then change the directions to cd into that directory, do the other stuff, etc.

WDYT ... maybe I should pivot to the subdirectory ? Any other ideas on how to better manager this?

uv sync
source .venv/bin/activate
uv run streamlit run streamlit_app.py
```

Expand Down
38 changes: 38 additions & 0 deletions pyproject.orig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[project]
name = "llama-stack-agentic-sample"
version = "0.1.0"
description = "Llama-Stack LangGraph Customer Service Example"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"docling>=2.63.0",
"llama-stack-client>=0.3.1",
"llama-stack>=0.3.1",
"pygithub>=2.8.1",
"pyyaml>=6.0.3",
"langgraph>=1.0.4",
"ollama>=0.6.1",
"mcp>=1.23.1",
"chardet>=5.2.0",
"streamlit>=1.52.1",
"grandalf>=0.8",
]

[tool.setuptools.packages.find]
where = ["src"]

[dependency-groups]
dev = ["ruff>=0.8.0", "pytest>=7.4.0", "pre-commit>=3.5.0"]

[tool.ruff]
line-length = 88
target-version = "py312"
exclude = ["tests", "*.pyi"]
include = ["src/**/*.py", "streamlit_app.py"]

[tool.ruff.lint]
select = ["E", "F", "I"]
ignore = []

[tool.ruff.lint.isort]
known-first-party = ["src"]
6 changes: 3 additions & 3 deletions src/ingest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import tempfile
import time
from pathlib import Path
from typing import Any
from typing import Any, cast

import requests
import yaml
Expand Down Expand Up @@ -293,7 +293,7 @@ def _fetch_github_dir_contents(
if isinstance(c, ContentFile):
contents_list.append(c)
elif hasattr(c, "type") and hasattr(c, "name"):
contents_list.append(c) # type: ignore[arg-type]
contents_list.append(cast(ContentFile, c))
pdf_files.extend(
self._fetch_github_dir_contents(
repo, contents_list, branch, path, download_dir
Expand Down Expand Up @@ -384,7 +384,7 @@ def fetch_from_github(
if isinstance(c, ContentFile):
contents_list.append(c)
elif hasattr(c, "type") and hasattr(c, "name"):
contents_list.append(c) # type: ignore[arg-type]
contents_list.append(cast(ContentFile, c))
pdf_files = self._fetch_github_dir_contents(
repo, contents_list, branch, path, download_dir
)
Expand Down
14 changes: 7 additions & 7 deletions src/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def git_agent(
if not tools_llm:
raise AgentRunMethodParameterError("tools_llm is required in git agent")

openai_mcp_tool: "dict[str, Any]" = {
openai_mcp_tool: "Any" = {
"type": "mcp",
"server_label": "github",
"server_url": "https://api.githubcopilot.com/mcp/",
Expand All @@ -319,7 +319,7 @@ def git_agent(
sub_id=state["submission_id"],
user_question=state["input"],
),
tools=[openai_mcp_tool], # type: ignore[arg-type]
tools=[openai_mcp_tool],
)
logger.debug("git_agent response returned")

Expand Down Expand Up @@ -371,7 +371,7 @@ def git_agent(
issue_id=gh_issue,
comment_body=body_as_string,
),
tools=[openai_mcp_tool], # type: ignore[arg-type]
tools=[openai_mcp_tool],
timeout=240.0, # the bigger comment calls can take
# especially long ... put a cap on it
)
Expand Down Expand Up @@ -440,7 +440,7 @@ def pod_agent(
if not tools_llm:
raise AgentRunMethodParameterError("tools_llm is required in git agent")

openai_mcp_tool: "dict[str, Any]" = {
openai_mcp_tool: "Any" = {
"type": "mcp",
"server_label": "OpenShift / Kubernetes MCP Tools",
"server_url": MCP_SERVER_URL,
Expand All @@ -455,7 +455,7 @@ def pod_agent(
resp = openai_client.responses.create(
model=tools_llm,
input=WorkflowAgentPrompts.POD_PROMPT.format(namespace=state["namespace"]),
tools=[openai_mcp_tool], # type: ignore[arg-type]
tools=[openai_mcp_tool],
)
logger.debug(
f"K8S Agent successful return MCP request "
Expand Down Expand Up @@ -518,7 +518,7 @@ def perf_agent(
if not tools_llm:
raise AgentRunMethodParameterError("tools_llm is required in git agent")

openai_mcp_tool: "dict[str, Any]" = {
openai_mcp_tool: "Any" = {
"type": "mcp",
"server_label": "OpenShift / Kubernetes MCP Tools",
"server_url": MCP_SERVER_URL,
Expand All @@ -534,7 +534,7 @@ def perf_agent(
resp = openai_client.responses.create(
model=tools_llm,
input=WorkflowAgentPrompts.PERF_PROMPT.format(namespace=state["namespace"]),
tools=[openai_mcp_tool], # type: ignore[arg-type]
tools=[openai_mcp_tool],
)
logger.debug(
f"K8S perf Agent successful return MCP request "
Expand Down
8 changes: 4 additions & 4 deletions src/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def _call_openai_llm(self, state: "WorkflowState") -> "str":
messages = self._convert_messages_to_openai_format(state)
completion = self.rag_service.openai_client.chat.completions.create(
model=INFERENCE_MODEL,
messages=messages, # type: ignore[invalid-argument-type]
messages=cast("Any", messages),
)
return completion.choices[0].message.content or ""

Expand Down Expand Up @@ -206,7 +206,7 @@ def llm_node(state: "WorkflowState") -> "WorkflowState":
rag_response = client_to_use.responses.create(
model=INFERENCE_MODEL,
input=rag_prompt,
tools=[file_search_tool], # type: ignore[invalid-argument-type]
tools=cast("Any", [file_search_tool]),
)
rag_end_time = time.time()
state["rag_query_time"] = rag_end_time - rag_start_time
Expand Down Expand Up @@ -290,7 +290,7 @@ def llm_node(state: "WorkflowState") -> "WorkflowState":

return state

agent_builder = StateGraph(WorkflowState) # type: ignore[arg-type]
agent_builder = StateGraph(cast("Any", WorkflowState))
agent_builder.add_node(f"{department_name}_set_message", init_message)
agent_builder.add_node("llm_node", llm_node)
agent_builder.add_edge(START, f"{department_name}_set_message")
Expand Down Expand Up @@ -450,7 +450,7 @@ def perf_agent_node(state: "WorkflowState") -> "WorkflowState":
tools_llm=tools_llm,
)

overall_workflow = StateGraph(WorkflowState) # type: ignore[arg-type]
overall_workflow = StateGraph(cast("Any", WorkflowState))
overall_workflow.add_node(
"classification_agent",
classification_node,
Expand Down
4 changes: 2 additions & 2 deletions streamlit_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ def _run_async_in_thread(coro):


async def run_workflow_task_async(
workflow: "Workflow", question: "str", submission_id: "str"
workflow: "Any", question: "str", submission_id: "str"
) -> "None":
"""
async task to run a single workflow with concurrent operations
Expand All @@ -599,7 +599,7 @@ async def run_workflow_task_async(
# the question through appropriate agents (classification -> dept agents)
# Note: workflow.invoke is synchronous but we're in an async context
# to allow future async operations within the workflow
result = workflow.invoke( # type: ignore[attr-defined]
result = workflow.invoke(
{
"input": question,
"submission_id": submission_id,
Expand Down