Skip to content

Commit

Permalink
[CLI] Add Store config to CLI (#2548)
Browse files Browse the repository at this point in the history
  • Loading branch information
hinthornw authored Nov 28, 2024
1 parent ee8653d commit 1130c3a
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 41 deletions.
31 changes: 18 additions & 13 deletions libs/cli/langgraph_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,19 +511,6 @@ def dockerfile(save_path: str, config: pathlib.Path, add_docker_compose: bool) -
)


@click.argument("path", required=False)
@click.option(
"--template",
type=str,
help=TEMPLATE_HELP_STRING,
)
@cli.command("new", help="🌱 Create a new LangGraph project from a template.")
@log_command
def new(path: Optional[str], template: Optional[str]) -> None:
"""Create a new LangGraph project from a template."""
return create_new(path, template)


@click.option(
"--host",
default="127.0.0.1",
Expand Down Expand Up @@ -608,6 +595,10 @@ def dev(
sys.path.append(str(dep_path))

graphs = config_json.get("graphs", {})
additional_config = {}
if config_json.get("store"):
additional_config["store"] = config_json["store"]

run_server(
host,
port,
Expand All @@ -617,9 +608,23 @@ def dev(
open_browser=not no_browser,
debug_port=debug_port,
env=config_json.get("env", None),
config=additional_config,
)


@click.argument("path", required=False)
@click.option(
"--template",
type=str,
help=TEMPLATE_HELP_STRING,
)
@cli.command("new", help="🌱 Create a new LangGraph project from a template.")
@log_command
def new(path: Optional[str], template: Optional[str]) -> None:
"""Create a new LangGraph project from a template."""
return create_new(path, template)


def prepare_args_and_stdin(
*,
capabilities: DockerCapabilities,
Expand Down
68 changes: 63 additions & 5 deletions libs/cli/langgraph_cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,52 @@
MIN_PYTHON_VERSION = "3.11"


class Config(TypedDict):
class IndexConfig(TypedDict, total=False):
"""Configuration for indexing documents for semantic search in the store."""

dims: int
"""Number of dimensions in the embedding vectors.
Common embedding models have the following dimensions:
- OpenAI text-embedding-3-large: 256, 1024, or 3072
- OpenAI text-embedding-3-small: 512 or 1536
- OpenAI text-embedding-ada-002: 1536
- Cohere embed-english-v3.0: 1024
- Cohere embed-english-light-v3.0: 384
- Cohere embed-multilingual-v3.0: 1024
- Cohere embed-multilingual-light-v3.0: 384
"""

embed: str
"""Optional model (string) to generate embeddings from text or path to model or function.
Examples:
- "openai:text-embedding-3-large"
- "cohere:embed-multilingual-v3.0"
- "src/app.py:embeddings
"""

fields: Optional[list[str]]
"""Fields to extract text from for embedding generation.
Defaults to the root ["$"], which embeds the json object as a whole.
"""


class StoreConfig(TypedDict, total=False):
embed: Optional[IndexConfig]
"""Configuration for vector embeddings in store."""


class Config(TypedDict, total=False):
python_version: str
node_version: Optional[str]
pip_config_file: Optional[str]
dockerfile_lines: list[str]
dependencies: list[str]
graphs: dict[str, str]
env: Union[dict[str, str], str]
store: Optional[StoreConfig]


def _parse_version(version_str: str) -> tuple[int, int]:
Expand Down Expand Up @@ -49,6 +87,7 @@ def validate_config(config: Config) -> Config:
"dockerfile_lines": config.get("dockerfile_lines", []),
"graphs": config.get("graphs", {}),
"env": config.get("env", {}),
"store": config.get("store"),
}
if config.get("node_version")
else {
Expand All @@ -58,6 +97,7 @@ def validate_config(config: Config) -> Config:
"dependencies": config.get("dependencies", []),
"graphs": config.get("graphs", {}),
"env": config.get("env", {}),
"store": config.get("store"),
}
)

Expand Down Expand Up @@ -352,15 +392,24 @@ def python_config_to_docker(config_path: pathlib.Path, config: Config, base_imag
],
)
)

additional_config = {}
if config.get("store"):
additional_config["store"] = config["store"]
env_additional_config = (
""
if not additional_config
else f"""
ENV LANGGRAPH_CONFIG='{json.dumps(additional_config)}'
"""
)
return f"""FROM {base_image}:{config['python_version']}
{os.linesep.join(config["dockerfile_lines"])}
{installs}
RUN {pip_install} -e /deps/*
{env_additional_config}
ENV LANGSERVE_GRAPHS='{json.dumps(config["graphs"])}'
{f"WORKDIR {local_deps.working_dir}" if local_deps.working_dir else ""}"""
Expand Down Expand Up @@ -390,15 +439,24 @@ def test_file(file_name):
install_cmd = "npm ci"
else:
install_cmd = "npm i"

additional_config = {}
if config.get("store"):
additional_config["store"] = config["store"]
env_additional_config = (
""
if not additional_config
else f"""
ENV LANGGRAPH_CONFIG='{json.dumps(additional_config)}'
"""
)
return f"""FROM {base_image}:{config['node_version']}
{os.linesep.join(config["dockerfile_lines"])}
ADD . {faux_path}
RUN cd {faux_path} && {install_cmd}
{env_additional_config}
ENV LANGSERVE_GRAPHS='{json.dumps(config["graphs"])}'
WORKDIR {faux_path}
Expand Down
75 changes: 54 additions & 21 deletions libs/cli/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions libs/cli/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langgraph-cli"
version = "0.1.59"
version = "0.1.60"
description = "CLI for interacting with LangGraph API"
authors = []
license = "MIT"
Expand All @@ -14,7 +14,7 @@ langgraph = "langgraph_cli.cli:cli"
[tool.poetry.dependencies]
python = "^3.9.0,<4.0"
click = "^8.1.7"
langgraph-api = { version = ">=0.0.2,<0.1.0", optional = true, python = ">=3.11,<4.0" }
langgraph-api = { version = ">=0.0.5,<0.1.0", optional = true, python = ">=3.11,<4.0" }
python-dotenv = { version = ">=0.8.0", optional = true }

[tool.poetry.group.dev.dependencies]
Expand Down
2 changes: 2 additions & 0 deletions libs/cli/tests/unit_tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def test_validate_config():
"pip_config_file": None,
"dockerfile_lines": [],
"env": {},
"store": None,
**expected_config,
}
actual_config = validate_config(expected_config)
Expand All @@ -46,6 +47,7 @@ def test_validate_config():
"agent": "./agent.py:graph",
},
"env": env,
"store": None,
}
actual_config = validate_config(expected_config)
assert actual_config == expected_config
Expand Down

0 comments on commit 1130c3a

Please sign in to comment.