diff --git a/libs/checkpoint-postgres/Makefile b/libs/checkpoint-postgres/Makefile index 1116d5daf..c4f560f0e 100644 --- a/libs/checkpoint-postgres/Makefile +++ b/libs/checkpoint-postgres/Makefile @@ -1,4 +1,4 @@ -.PHONY: test test_watch lint format +.PHONY: test test_watch lint type format ###################### # TESTING AND COVERAGE @@ -61,6 +61,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) [ "$(PYTHON_FILES)" = "" ] || uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --select I --fix $(PYTHON_FILES) diff --git a/libs/checkpoint-sqlite/Makefile b/libs/checkpoint-sqlite/Makefile index 376c05d74..66f7cf600 100644 --- a/libs/checkpoint-sqlite/Makefile +++ b/libs/checkpoint-sqlite/Makefile @@ -1,4 +1,4 @@ -.PHONY: test test_watch lint format +.PHONY: test test_watch lint type format ###################### # TESTING AND COVERAGE @@ -32,6 +32,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) [ "$(PYTHON_FILES)" = "" ] || uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --select I --fix $(PYTHON_FILES) diff --git a/libs/checkpoint/Makefile b/libs/checkpoint/Makefile index 376c05d74..66f7cf600 100644 --- a/libs/checkpoint/Makefile +++ b/libs/checkpoint/Makefile @@ -1,4 +1,4 @@ -.PHONY: test test_watch lint format +.PHONY: test test_watch lint type format ###################### # TESTING AND COVERAGE @@ -32,6 +32,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) [ "$(PYTHON_FILES)" = "" ] || uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --select I --fix $(PYTHON_FILES) diff --git a/libs/cli/Makefile b/libs/cli/Makefile index 60a781d8e..0de616fa7 100644 --- a/libs/cli/Makefile +++ b/libs/cli/Makefile @@ -1,4 +1,4 @@ -.PHONY: test lint format test-integration update-schema bump-version +.PHONY: test lint type format test-integration update-schema bump-version ###################### # TESTING AND COVERAGE @@ -29,6 +29,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || uv run ruff check --select I $(PYTHON_FILES) [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) || uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy $(PYTHON_FILES) --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --select I --fix $(PYTHON_FILES) diff --git a/libs/cli/generate_schema.py b/libs/cli/generate_schema.py index 32543c037..3aa1ccd16 100644 --- a/libs/cli/generate_schema.py +++ b/libs/cli/generate_schema.py @@ -20,6 +20,7 @@ from langgraph_cli.schemas import ( Config, ConfigurableHeaderConfig, CorsConfig, + GraphDef, HttpConfig, IndexConfig, SecurityConfig, @@ -108,6 +109,7 @@ def add_descriptions_to_schema(schema, cls): # Find the class that corresponds to this definition for potential_cls in [ Config, + GraphDef, StoreConfig, IndexConfig, AuthConfig, diff --git a/libs/cli/langgraph_cli/schemas.py b/libs/cli/langgraph_cli/schemas.py index 63dcce4c1..011ce4752 100644 --- a/libs/cli/langgraph_cli/schemas.py +++ b/libs/cli/langgraph_cli/schemas.py @@ -529,6 +529,21 @@ class WebhookUrlPolicy(TypedDict, total=False): """Disallow relative URLs (internal loopback calls) when true.""" +class GraphDef(TypedDict, total=False): + """Definition of a graph with additional metadata.""" + + path: str + """Required. Import path to the graph object. + + Format: "path/to/file.py:object_name" + """ + description: str | None + """Optional. A description of the graph's purpose and functionality. + + This description is surfaced in the API and can help users understand what the graph does. + """ + + class WebhooksConfig(TypedDict, total=False): env_prefix: str """Required prefix for environment variables referenced in header templates. @@ -619,19 +634,23 @@ class Config(TypedDict, total=False): Defaults to an empty list, meaning no additional packages installed beyond your base environment. """ - graphs: dict[str, str] + graphs: dict[str, str | GraphDef] """Optional. Named definitions of graphs, each pointing to a Python object. - + Graphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context managers that accept a single configuration argument (of type RunnableConfig) and return a pregel object (instance of Stategraph, etc.). - - Keys are graph names, values are "path/to/file.py:object_name". + + Keys are graph names, values are either "path/to/file.py:object_name" strings + or objects with a "path" key and optional "description" key. Example: { "mygraph": "graphs/my_graph.py:graph_definition", - "anothergraph": "graphs/another.py:get_graph" + "anothergraph": { + "path": "graphs/another.py:get_graph", + "description": "A graph that does X" + } } """ @@ -696,6 +715,7 @@ class Config(TypedDict, total=False): __all__ = [ "Config", + "GraphDef", "StoreConfig", "CheckpointerConfig", "AuthConfig", diff --git a/libs/cli/schemas/schema.json b/libs/cli/schemas/schema.json index 7b1117811..4ba2700e8 100644 --- a/libs/cli/schemas/schema.json +++ b/libs/cli/schemas/schema.json @@ -127,9 +127,16 @@ "graphs": { "type": "object", "additionalProperties": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/GraphDef" + } + ] }, - "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n" + "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n\nor objects with a \"path\" key and optional \"description\" key." }, "http": { "anyOf": [ @@ -341,9 +348,16 @@ "graphs": { "type": "object", "additionalProperties": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/GraphDef" + } + ] }, - "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n" + "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n\nor objects with a \"path\" key and optional \"description\" key." }, "http": { "anyOf": [ @@ -662,6 +676,29 @@ }, "required": [] }, + "GraphDef": { + "title": "GraphDef", + "description": "Definition of a graph with additional metadata.", + "type": "object", + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional. A description of the graph's purpose and functionality.\n\nThis description is surfaced in the API and can help users understand what the graph does.\n" + }, + "path": { + "type": "string", + "description": "Required. Import path to the graph object.\n" + } + }, + "required": [] + }, "HttpConfig": { "title": "HttpConfig", "description": "Configuration for the built-in HTTP server that powers your deployment's routes and endpoints.", diff --git a/libs/cli/schemas/schema.v0.json b/libs/cli/schemas/schema.v0.json index 7b1117811..4ba2700e8 100644 --- a/libs/cli/schemas/schema.v0.json +++ b/libs/cli/schemas/schema.v0.json @@ -127,9 +127,16 @@ "graphs": { "type": "object", "additionalProperties": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/GraphDef" + } + ] }, - "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n" + "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n\nor objects with a \"path\" key and optional \"description\" key." }, "http": { "anyOf": [ @@ -341,9 +348,16 @@ "graphs": { "type": "object", "additionalProperties": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/$defs/GraphDef" + } + ] }, - "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n" + "description": "Optional. Named definitions of graphs, each pointing to a Python object.\n\n\nGraphs can be StateGraph, @entrypoint, or any other Pregel object OR they can point to (async) context\nmanagers that accept a single configuration argument (of type RunnableConfig) and return a pregel object\n(instance of Stategraph, etc.).\n\nor objects with a \"path\" key and optional \"description\" key." }, "http": { "anyOf": [ @@ -662,6 +676,29 @@ }, "required": [] }, + "GraphDef": { + "title": "GraphDef", + "description": "Definition of a graph with additional metadata.", + "type": "object", + "properties": { + "description": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optional. A description of the graph's purpose and functionality.\n\nThis description is surfaced in the API and can help users understand what the graph does.\n" + }, + "path": { + "type": "string", + "description": "Required. Import path to the graph object.\n" + } + }, + "required": [] + }, "HttpConfig": { "title": "HttpConfig", "description": "Configuration for the built-in HTTP server that powers your deployment's routes and endpoints.", diff --git a/libs/langgraph/Makefile b/libs/langgraph/Makefile index 86852414a..3b406baf4 100644 --- a/libs/langgraph/Makefile +++ b/libs/langgraph/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test test_watch integration_tests spell_check spell_fix benchmark profile start-dev-server integration_tests +.PHONY: all format lint type test test_watch integration_tests spell_check spell_fix benchmark profile start-dev-server integration_tests # Default target executed when no arguments are given to make. all: help @@ -125,6 +125,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) [ "$(PYTHON_FILES)" = "" ] || uv run mypy langgraph --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy langgraph --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --select I --fix $(PYTHON_FILES) @@ -147,6 +150,7 @@ help: @echo '-- LINTING --' @echo 'format - run code formatters' @echo 'lint - run linters' + @echo 'type - run type checking' @echo 'spell_check - run codespell on the project' @echo 'spell_fix - run codespell on the project and fix the errors' @echo '-- TESTS --' diff --git a/libs/prebuilt/Makefile b/libs/prebuilt/Makefile index f737f4d81..d42454c2e 100644 --- a/libs/prebuilt/Makefile +++ b/libs/prebuilt/Makefile @@ -1,4 +1,4 @@ -.PHONY: all format lint test test-fast test_watch integration_tests spell_check spell_fix benchmark profile +.PHONY: all format lint type test test-fast test_watch integration_tests spell_check spell_fix benchmark profile # Default target executed when no arguments are given to make. all: help @@ -50,6 +50,9 @@ lint lint_diff lint_package lint_tests: [ "$(PYTHON_FILES)" = "" ] || mkdir -p $(MYPY_CACHE) [ "$(PYTHON_FILES)" = "" ] || uv run mypy langgraph --cache-dir $(MYPY_CACHE) +type: + mkdir -p $(MYPY_CACHE) && uv run mypy langgraph --cache-dir $(MYPY_CACHE) + format format_diff: uv run ruff format $(PYTHON_FILES) uv run ruff check --fix $(PYTHON_FILES) @@ -72,6 +75,7 @@ help: @echo '-- LINTING --' @echo 'format - run code formatters' @echo 'lint - run linters' + @echo 'type - run type checking' @echo 'spell_check - run codespell on the project' @echo 'spell_fix - run codespell on the project and fix the errors' @echo '-- TESTS --' diff --git a/libs/sdk-py/Makefile b/libs/sdk-py/Makefile index 59990054c..a1efa0bfd 100644 --- a/libs/sdk-py/Makefile +++ b/libs/sdk-py/Makefile @@ -1,4 +1,4 @@ -.PHONY: lint format test +.PHONY: lint type format test test: uv run pytest tests @@ -19,6 +19,9 @@ lint lint_diff: [ "$(PYTHON_FILES)" = "" ] || uv run ruff check --select I $(PYTHON_FILES) uv run ty check . +type: + uv run ty check . + format format_diff: uv run ruff check --select I --fix $(PYTHON_FILES) uv run ruff format $(PYTHON_FILES)