10xgraph-api 0.7.0__py3-none-any.whl

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.
Files changed (203) hide show
  1. 10xgraph_api-0.7.0.dist-info/METADATA +618 -0
  2. 10xgraph_api-0.7.0.dist-info/RECORD +203 -0
  3. 10xgraph_api-0.7.0.dist-info/WHEEL +5 -0
  4. 10xgraph_api-0.7.0.dist-info/entry_points.txt +3 -0
  5. 10xgraph_api-0.7.0.dist-info/licenses/LICENSE +21 -0
  6. 10xgraph_api-0.7.0.dist-info/top_level.txt +2 -0
  7. agentflow_cli/__init__.py +69 -0
  8. tenxgraph_api/__init__.py +23 -0
  9. tenxgraph_api/cli/__init__.py +6 -0
  10. tenxgraph_api/cli/capabilities.py +127 -0
  11. tenxgraph_api/cli/commands/__init__.py +49 -0
  12. tenxgraph_api/cli/commands/api.py +262 -0
  13. tenxgraph_api/cli/commands/audit.py +213 -0
  14. tenxgraph_api/cli/commands/build.py +305 -0
  15. tenxgraph_api/cli/commands/config.py +71 -0
  16. tenxgraph_api/cli/commands/demo.py +93 -0
  17. tenxgraph_api/cli/commands/eval.py +909 -0
  18. tenxgraph_api/cli/commands/init.py +531 -0
  19. tenxgraph_api/cli/commands/skills.py +532 -0
  20. tenxgraph_api/cli/commands/test.py +113 -0
  21. tenxgraph_api/cli/commands/version.py +47 -0
  22. tenxgraph_api/cli/config_editor/__init__.py +15 -0
  23. tenxgraph_api/cli/config_editor/schema.py +566 -0
  24. tenxgraph_api/cli/config_editor/server.py +240 -0
  25. tenxgraph_api/cli/config_editor/static/app.css +2 -0
  26. tenxgraph_api/cli/config_editor/static/app.js +3 -0
  27. tenxgraph_api/cli/config_editor/static/favicon.svg +11 -0
  28. tenxgraph_api/cli/config_editor/static/index.html +20 -0
  29. tenxgraph_api/cli/config_editor/store.py +120 -0
  30. tenxgraph_api/cli/config_editor/validation.py +377 -0
  31. tenxgraph_api/cli/constants.py +112 -0
  32. tenxgraph_api/cli/context.py +46 -0
  33. tenxgraph_api/cli/core/__init__.py +0 -0
  34. tenxgraph_api/cli/core/animations.py +550 -0
  35. tenxgraph_api/cli/core/config.py +279 -0
  36. tenxgraph_api/cli/core/output.py +625 -0
  37. tenxgraph_api/cli/core/prompts.py +220 -0
  38. tenxgraph_api/cli/core/screen.py +287 -0
  39. tenxgraph_api/cli/core/steps.py +621 -0
  40. tenxgraph_api/cli/core/theme.py +242 -0
  41. tenxgraph_api/cli/core/validation.py +251 -0
  42. tenxgraph_api/cli/exceptions.py +129 -0
  43. tenxgraph_api/cli/logger.py +84 -0
  44. tenxgraph_api/cli/main.py +936 -0
  45. tenxgraph_api/cli/templates/__init__.py +0 -0
  46. tenxgraph_api/cli/templates/defaults.py +844 -0
  47. tenxgraph_api/cli/templates/dev/.env.example +1 -0
  48. tenxgraph_api/cli/templates/dev/10xgraph.json +16 -0
  49. tenxgraph_api/cli/templates/dev/graph/__init__.py +0 -0
  50. tenxgraph_api/cli/templates/dev/graph/agent.py +63 -0
  51. tenxgraph_api/cli/templates/prod/.env.example +75 -0
  52. tenxgraph_api/cli/templates/prod/.pre-commit-config.yaml +50 -0
  53. tenxgraph_api/cli/templates/prod/.python-version +1 -0
  54. tenxgraph_api/cli/templates/prod/10xgraph.json +42 -0
  55. tenxgraph_api/cli/templates/prod/auth/__init__.py +0 -0
  56. tenxgraph_api/cli/templates/prod/auth/agent_auth.py +46 -0
  57. tenxgraph_api/cli/templates/prod/evals/__init__.py +0 -0
  58. tenxgraph_api/cli/templates/prod/evals/user_simulator_eval.py +76 -0
  59. tenxgraph_api/cli/templates/prod/evals/weather_agents_eval.py +53 -0
  60. tenxgraph_api/cli/templates/prod/graph/__init__.py +0 -0
  61. tenxgraph_api/cli/templates/prod/graph/agent.py +50 -0
  62. tenxgraph_api/cli/templates/prod/graph/state.py +5 -0
  63. tenxgraph_api/cli/templates/prod/graph/thread_name_generator.py +7 -0
  64. tenxgraph_api/cli/templates/prod/graph/tools/__init__.py +0 -0
  65. tenxgraph_api/cli/templates/prod/graph/tools/weather_tool.py +43 -0
  66. tenxgraph_api/cli/templates/prod/graph/validators/__init__.py +0 -0
  67. tenxgraph_api/cli/templates/prod/graph/validators/lifecyle.py +107 -0
  68. tenxgraph_api/cli/templates/prod/graph/validators/manager.py +9 -0
  69. tenxgraph_api/cli/templates/prod/graph/validators/validators.py +21 -0
  70. tenxgraph_api/cli/templates/prod/pyproject.toml +79 -0
  71. tenxgraph_api/cli/templates/prod/tests/__init__.py +0 -0
  72. tenxgraph_api/cli/templates/prod/tests/conftest.py +6 -0
  73. tenxgraph_api/cli/templates/prod/tests/test_agent_eval.py +78 -0
  74. tenxgraph_api/cli/templates/prod/tests/test_catalog_tools.py +47 -0
  75. tenxgraph_api/cli/templates/prod/tests/test_graph_nodes.py +57 -0
  76. tenxgraph_api/cli/templates/skills/10xgraph/SKILL.md +92 -0
  77. tenxgraph_api/cli/templates/skills/10xgraph/references/agents-and-tools.md +389 -0
  78. tenxgraph_api/cli/templates/skills/10xgraph/references/api-client.md +61 -0
  79. tenxgraph_api/cli/templates/skills/10xgraph/references/api-configuration.md +75 -0
  80. tenxgraph_api/cli/templates/skills/10xgraph/references/api-settings-and-middleware.md +89 -0
  81. tenxgraph_api/cli/templates/skills/10xgraph/references/architecture.md +91 -0
  82. tenxgraph_api/cli/templates/skills/10xgraph/references/auth-and-authorization.md +149 -0
  83. tenxgraph_api/cli/templates/skills/10xgraph/references/callbacks-and-command.md +283 -0
  84. tenxgraph_api/cli/templates/skills/10xgraph/references/checkpointing-and-threads.md +63 -0
  85. tenxgraph_api/cli/templates/skills/10xgraph/references/cli-commands.md +73 -0
  86. tenxgraph_api/cli/templates/skills/10xgraph/references/client-auth-and-errors.md +94 -0
  87. tenxgraph_api/cli/templates/skills/10xgraph/references/client-messages-invoke-stream.md +115 -0
  88. tenxgraph_api/cli/templates/skills/10xgraph/references/client-threads-memory-files.md +80 -0
  89. tenxgraph_api/cli/templates/skills/10xgraph/references/context-id-background.md +80 -0
  90. tenxgraph_api/cli/templates/skills/10xgraph/references/dependency-injection.md +58 -0
  91. tenxgraph_api/cli/templates/skills/10xgraph/references/evaluation.md +500 -0
  92. tenxgraph_api/cli/templates/skills/10xgraph/references/id-and-thread-name-generators.md +69 -0
  93. tenxgraph_api/cli/templates/skills/10xgraph/references/media-and-files.md +66 -0
  94. tenxgraph_api/cli/templates/skills/10xgraph/references/memory-and-store.md +70 -0
  95. tenxgraph_api/cli/templates/skills/10xgraph/references/prebuilt-agents-and-tools.md +394 -0
  96. tenxgraph_api/cli/templates/skills/10xgraph/references/production-runtime.md +56 -0
  97. tenxgraph_api/cli/templates/skills/10xgraph/references/providers-and-adapters.md +89 -0
  98. tenxgraph_api/cli/templates/skills/10xgraph/references/publishers-and-runtime-protocols.md +84 -0
  99. tenxgraph_api/cli/templates/skills/10xgraph/references/rate-limiting.md +194 -0
  100. tenxgraph_api/cli/templates/skills/10xgraph/references/realtime.md +172 -0
  101. tenxgraph_api/cli/templates/skills/10xgraph/references/remote-tools.md +55 -0
  102. tenxgraph_api/cli/templates/skills/10xgraph/references/rest-api-and-errors.md +97 -0
  103. tenxgraph_api/cli/templates/skills/10xgraph/references/security-and-validators.md +86 -0
  104. tenxgraph_api/cli/templates/skills/10xgraph/references/state-and-messages.md +68 -0
  105. tenxgraph_api/cli/templates/skills/10xgraph/references/state-graph.md +232 -0
  106. tenxgraph_api/cli/templates/skills/10xgraph/references/stream-emitter.md +144 -0
  107. tenxgraph_api/cli/templates/skills/10xgraph/references/streaming.md +53 -0
  108. tenxgraph_api/cli/templates/skills/10xgraph/references/testing-and-evaluation.md +64 -0
  109. tenxgraph_api/cli/templates/skills/10xgraph/references/unit-testing.md +202 -0
  110. tenxgraph_api/cli/templates/skills/copilot/10xgraph.instructions.md +108 -0
  111. tenxgraph_api/py.typed +0 -0
  112. tenxgraph_api/src/__init__.py +0 -0
  113. tenxgraph_api/src/app/__init__.py +13 -0
  114. tenxgraph_api/src/app/core/__init__.py +15 -0
  115. tenxgraph_api/src/app/core/auth/__init__.py +0 -0
  116. tenxgraph_api/src/app/core/auth/auth_backend.py +38 -0
  117. tenxgraph_api/src/app/core/auth/authorization.py +379 -0
  118. tenxgraph_api/src/app/core/auth/base_auth.py +27 -0
  119. tenxgraph_api/src/app/core/auth/jwt_auth.py +122 -0
  120. tenxgraph_api/src/app/core/auth/ownership_resolver.py +170 -0
  121. tenxgraph_api/src/app/core/auth/permissions.py +354 -0
  122. tenxgraph_api/src/app/core/auth/request_config.py +130 -0
  123. tenxgraph_api/src/app/core/auth/route_guard.py +105 -0
  124. tenxgraph_api/src/app/core/config/__init__.py +0 -0
  125. tenxgraph_api/src/app/core/config/graph_config.py +532 -0
  126. tenxgraph_api/src/app/core/config/media_settings.py +72 -0
  127. tenxgraph_api/src/app/core/config/sentry_config.py +60 -0
  128. tenxgraph_api/src/app/core/config/settings.py +202 -0
  129. tenxgraph_api/src/app/core/config/setup_logs.py +65 -0
  130. tenxgraph_api/src/app/core/config/setup_middleware.py +483 -0
  131. tenxgraph_api/src/app/core/config/worker_middleware.py +99 -0
  132. tenxgraph_api/src/app/core/exceptions/__init__.py +17 -0
  133. tenxgraph_api/src/app/core/exceptions/general_exception.py +58 -0
  134. tenxgraph_api/src/app/core/exceptions/handle_errors.py +363 -0
  135. tenxgraph_api/src/app/core/exceptions/resources_exceptions.py +72 -0
  136. tenxgraph_api/src/app/core/exceptions/user_exception.py +58 -0
  137. tenxgraph_api/src/app/core/middleware/__init__.py +25 -0
  138. tenxgraph_api/src/app/core/middleware/rate_limit/__init__.py +15 -0
  139. tenxgraph_api/src/app/core/middleware/rate_limit/base.py +27 -0
  140. tenxgraph_api/src/app/core/middleware/rate_limit/factory.py +98 -0
  141. tenxgraph_api/src/app/core/middleware/rate_limit/keying.py +133 -0
  142. tenxgraph_api/src/app/core/middleware/rate_limit/memory.py +98 -0
  143. tenxgraph_api/src/app/core/middleware/rate_limit/middleware.py +90 -0
  144. tenxgraph_api/src/app/core/middleware/rate_limit/redis.py +115 -0
  145. tenxgraph_api/src/app/core/middleware/request_limits.py +154 -0
  146. tenxgraph_api/src/app/core/middleware/security_headers.py +239 -0
  147. tenxgraph_api/src/app/core/utils/__init__.py +14 -0
  148. tenxgraph_api/src/app/core/utils/log_sanitizer.py +216 -0
  149. tenxgraph_api/src/app/loader.py +516 -0
  150. tenxgraph_api/src/app/main.py +180 -0
  151. tenxgraph_api/src/app/routers/__init__.py +4 -0
  152. tenxgraph_api/src/app/routers/ag_ui/__init__.py +10 -0
  153. tenxgraph_api/src/app/routers/ag_ui/converter.py +195 -0
  154. tenxgraph_api/src/app/routers/ag_ui/event_mapper.py +353 -0
  155. tenxgraph_api/src/app/routers/ag_ui/router.py +90 -0
  156. tenxgraph_api/src/app/routers/ag_ui/service.py +193 -0
  157. tenxgraph_api/src/app/routers/checkpointer/__init__.py +1 -0
  158. tenxgraph_api/src/app/routers/checkpointer/router.py +482 -0
  159. tenxgraph_api/src/app/routers/checkpointer/schemas/__init__.py +1 -0
  160. tenxgraph_api/src/app/routers/checkpointer/schemas/checkpointer_schemas.py +121 -0
  161. tenxgraph_api/src/app/routers/checkpointer/services/__init__.py +1 -0
  162. tenxgraph_api/src/app/routers/checkpointer/services/checkpointer_service.py +300 -0
  163. tenxgraph_api/src/app/routers/evals/__init__.py +6 -0
  164. tenxgraph_api/src/app/routers/evals/router.py +38 -0
  165. tenxgraph_api/src/app/routers/evals/services/__init__.py +1 -0
  166. tenxgraph_api/src/app/routers/evals/services/eval_report_service.py +354 -0
  167. tenxgraph_api/src/app/routers/graph/__init__.py +6 -0
  168. tenxgraph_api/src/app/routers/graph/realtime_guard.py +161 -0
  169. tenxgraph_api/src/app/routers/graph/router.py +821 -0
  170. tenxgraph_api/src/app/routers/graph/schemas/__init__.py +1 -0
  171. tenxgraph_api/src/app/routers/graph/schemas/graph_schemas.py +386 -0
  172. tenxgraph_api/src/app/routers/graph/services/__init__.py +1 -0
  173. tenxgraph_api/src/app/routers/graph/services/graph_service.py +1219 -0
  174. tenxgraph_api/src/app/routers/graph/services/multimodal_preprocessor.py +164 -0
  175. tenxgraph_api/src/app/routers/media/__init__.py +506 -0
  176. tenxgraph_api/src/app/routers/media/router.py +242 -0
  177. tenxgraph_api/src/app/routers/media/schemas.py +39 -0
  178. tenxgraph_api/src/app/routers/ping/__init__.py +4 -0
  179. tenxgraph_api/src/app/routers/ping/router.py +28 -0
  180. tenxgraph_api/src/app/routers/setup_router.py +60 -0
  181. tenxgraph_api/src/app/routers/store/__init__.py +4 -0
  182. tenxgraph_api/src/app/routers/store/router.py +200 -0
  183. tenxgraph_api/src/app/routers/store/schemas/__init__.py +28 -0
  184. tenxgraph_api/src/app/routers/store/schemas/store_schemas.py +200 -0
  185. tenxgraph_api/src/app/routers/store/services/__init__.py +4 -0
  186. tenxgraph_api/src/app/routers/store/services/store_service.py +203 -0
  187. tenxgraph_api/src/app/tasks/__init__.py +0 -0
  188. tenxgraph_api/src/app/tasks/user_tasks.py +38 -0
  189. tenxgraph_api/src/app/utils/__init__.py +12 -0
  190. tenxgraph_api/src/app/utils/callable_helper.py +26 -0
  191. tenxgraph_api/src/app/utils/media/__init__.py +15 -0
  192. tenxgraph_api/src/app/utils/media/extractor.py +172 -0
  193. tenxgraph_api/src/app/utils/media/pipeline.py +83 -0
  194. tenxgraph_api/src/app/utils/parse_output.py +17 -0
  195. tenxgraph_api/src/app/utils/response_helper.py +129 -0
  196. tenxgraph_api/src/app/utils/schemas/__init__.py +11 -0
  197. tenxgraph_api/src/app/utils/schemas/output_schemas.py +28 -0
  198. tenxgraph_api/src/app/utils/schemas/user_schemas.py +13 -0
  199. tenxgraph_api/src/app/utils/snowflake_id_generator.py +90 -0
  200. tenxgraph_api/src/app/utils/swagger_helper.py +160 -0
  201. tenxgraph_api/src/app/utils/telemetry_store.py +123 -0
  202. tenxgraph_api/src/app/utils/thread_name_generator.py +304 -0
  203. tenxgraph_api/src/app/worker.py +91 -0
@@ -0,0 +1,21 @@
1
+ from tenxgraph.utils.validators import PromptInjectionValidator
2
+
3
+
4
+ prompt_validator = PromptInjectionValidator(
5
+ strict_mode=True,
6
+ max_length=1000,
7
+ blocked_patterns=[],
8
+ suspicious_keywords=[
9
+ "ignore previous",
10
+ "forget previous",
11
+ "disregard previous",
12
+ "bypass",
13
+ "circumvent",
14
+ "override",
15
+ "disable",
16
+ "remove restrictions",
17
+ "token",
18
+ "coupon",
19
+ "free",
20
+ ],
21
+ )
@@ -0,0 +1,79 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "$agent_name_slug"
7
+ version = "0.1.0"
8
+ description = "$agent_name — an AI agent built with 10xGraph."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.12"
12
+ authors = []
13
+ dependencies = [
14
+ "10xgraph",
15
+ "10xgraph-api",
16
+ "google-genai",
17
+ ]
18
+
19
+ [project.optional-dependencies]
20
+ test = [
21
+ "pytest",
22
+ "pytest-asyncio",
23
+ "pytest-cov",
24
+ "pytest-env",
25
+ ]
26
+
27
+ [tool.ruff]
28
+ line-length = 100
29
+ target-version = "py312"
30
+ lint.fixable = ["ALL"]
31
+ lint.select = [
32
+ "E", "W", "F", "PL", "I", "B", "A", "S", "ISC", "ICN", "PIE", "Q",
33
+ "RET", "SIM", "TID", "RUF", "YTT", "UP", "C4", "PTH", "G", "INP", "T20",
34
+ ]
35
+ lint.ignore = [
36
+ "UP006", "UP007", "RUF012", "G004", "B904", "B008", "ISC001",
37
+ ]
38
+ lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
39
+ exclude = ["venv/*"]
40
+
41
+ [tool.ruff.lint.per-file-ignores]
42
+ "*/tests/*.py" = ["S101", "T201"]
43
+ "*/__init__.py" = ["E402", "S101"]
44
+
45
+ [tool.ruff.lint.isort]
46
+ lines-after-imports = 2
47
+
48
+ [tool.ruff.format]
49
+ docstring-code-format = true
50
+
51
+ [tool.ruff.lint.pydocstyle]
52
+ convention = "google"
53
+
54
+ [tool.bandit]
55
+ skips = ["B101"]
56
+
57
+ [tool.pytest.ini_options]
58
+ env = ["ENVIRONMENT=pytest"]
59
+ testpaths = ["tests"]
60
+ pythonpath = ["."]
61
+ filterwarnings = ["ignore::DeprecationWarning"]
62
+ addopts = [
63
+ "--cov=graph", "--cov-report=html", "--cov-report=term-missing",
64
+ "--cov-report=xml", "--cov-fail-under=0", "--strict-markers", "-v"
65
+ ]
66
+
67
+ [tool.coverage.run]
68
+ source = ["graph"]
69
+ branch = true
70
+ omit = [
71
+ "*/__init__.py", "*/tests/*", "*/venv/*", "*/.venv/*",
72
+ ]
73
+
74
+ [tool.coverage.report]
75
+ exclude_lines = [
76
+ "if __name__ == '__main__':", "pragma: no cover", "@abstractmethod",
77
+ "raise NotImplementedError",
78
+ ]
79
+ show_missing = true
File without changes
@@ -0,0 +1,6 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+
5
+
6
+ os.environ.setdefault("GEMINI_API_KEY", "test-key")
@@ -0,0 +1,78 @@
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+
5
+ from tenxgraph.qa import QuickTest
6
+ from tenxgraph.qa.evaluation import (
7
+ CriterionResult,
8
+ EvalCaseResult,
9
+ EvalReport,
10
+ EvalSummary,
11
+ ReporterConfig,
12
+ ReporterManager,
13
+ )
14
+
15
+ from evals.weather_agents_eval import get_eval_set
16
+
17
+
18
+ def test_eval_set_covers_core_weather_behaviors() -> None:
19
+ eval_set = get_eval_set()
20
+
21
+ case_ids = {case.eval_id for case in eval_set.eval_cases}
22
+ case_names = {case.name for case in eval_set.eval_cases}
23
+
24
+ assert eval_set.name == "weather-agent-regression"
25
+ assert len(eval_set.eval_cases) == 4
26
+ assert "greeting_response" in case_names
27
+ assert "weather_london" in case_ids
28
+ assert "weather_new_york" in case_ids
29
+ assert "weather_tokyo" in case_ids
30
+
31
+
32
+ def test_reporter_writes_html_and_json_artifacts(tmp_path) -> None:
33
+ report = EvalReport(
34
+ eval_set_id="weather-agent-regression",
35
+ eval_set_name="weather-agent-regression",
36
+ results=[
37
+ EvalCaseResult(
38
+ eval_id="sample",
39
+ name="sample",
40
+ passed=True,
41
+ actual_response="The weather in London is sunny",
42
+ criterion_results=[
43
+ CriterionResult(
44
+ criterion="response",
45
+ score=1.0,
46
+ passed=True,
47
+ threshold=0.6,
48
+ )
49
+ ],
50
+ )
51
+ ],
52
+ summary=EvalSummary(
53
+ total_cases=1,
54
+ passed_cases=1,
55
+ failed_cases=0,
56
+ error_cases=0,
57
+ pass_rate=1.0,
58
+ ),
59
+ )
60
+
61
+ output = ReporterManager(
62
+ ReporterConfig(output_dir=str(tmp_path), html=True, json_report=True, console=False)
63
+ ).run_all(report, output_dir=str(tmp_path))
64
+
65
+ assert output.json_path is not None
66
+ assert output.html_path is not None
67
+ assert "weather-agent-regression" in tmp_path.joinpath(output.json_path).read_text(
68
+ encoding="utf-8"
69
+ )
70
+
71
+
72
+ def test_quick_test_smoke_for_expected_weather_greeting() -> None:
73
+ result = QuickTest.single_turn(
74
+ agent_response="Hello! I can help you check the weather anywhere. What location are you interested in?",
75
+ user_message="Hi",
76
+ )
77
+
78
+ asyncio.run(result).assert_contains("weather").assert_no_errors()
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ from unittest.mock import MagicMock, patch
4
+
5
+ from graph.state import WeatherState
6
+ from graph.tools.weather_tool import get_weather
7
+
8
+
9
+ def test_get_weather_returns_sunny_message_for_location() -> None:
10
+ with patch(
11
+ "graph.tools.weather_tool.call_weather_api", return_value="The weather in London is sunny"
12
+ ):
13
+ result = get_weather(location="London")
14
+
15
+ assert "London" in result
16
+ assert "sunny" in result
17
+
18
+
19
+ def test_get_weather_retries_on_failure_and_returns_error_after_max_attempts() -> None:
20
+ with patch("graph.tools.weather_tool.call_weather_api", side_effect=Exception("API error")):
21
+ result = get_weather(location="Paris")
22
+
23
+ assert "Paris" in result
24
+ assert "sorry" in result.lower()
25
+
26
+
27
+ def test_get_weather_emits_progress_events_when_emitter_is_provided() -> None:
28
+ emit = MagicMock()
29
+
30
+ with patch(
31
+ "graph.tools.weather_tool.call_weather_api", return_value="The weather in Tokyo is sunny"
32
+ ):
33
+ result = get_weather(location="Tokyo", emit=emit)
34
+
35
+ emit.progress.assert_called()
36
+ assert "Tokyo" in result
37
+
38
+
39
+ def test_get_weather_accepts_injected_tool_call_id_and_state() -> None:
40
+ state = WeatherState()
41
+
42
+ with patch(
43
+ "graph.tools.weather_tool.call_weather_api", return_value="The weather in Berlin is sunny"
44
+ ):
45
+ result = get_weather(location="Berlin", tool_call_id="call_1", state=state)
46
+
47
+ assert "Berlin" in result
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+ from types import SimpleNamespace
4
+
5
+ from tenxgraph.core.state.message import Message
6
+ from tenxgraph.utils.constants import END
7
+
8
+ from graph.nodes.main_node import agent
9
+ from graph.utils.tool_decision import should_use_tools
10
+
11
+
12
+ def test_main_agent_is_configured_for_weather_assistant() -> None:
13
+ assert agent.model == "gemini-3-flash-preview"
14
+ assert agent.provider == "google"
15
+ assert agent.trim_context is True
16
+ assert agent.tool_node == "TOOL"
17
+
18
+ system_prompt_text = " ".join(
19
+ block["content"] for block in agent.system_prompt if "content" in block
20
+ )
21
+ assert "helpful assistant" in system_prompt_text.lower()
22
+
23
+
24
+ def test_should_end_when_no_context_exists() -> None:
25
+ assert should_use_tools(SimpleNamespace(context=[])) == END
26
+
27
+
28
+ def test_should_route_assistant_tool_calls_to_tool_node() -> None:
29
+ state = SimpleNamespace(
30
+ context=[
31
+ Message(
32
+ role="assistant",
33
+ content=[],
34
+ tools_calls=[
35
+ {
36
+ "id": "call_1",
37
+ "name": "get_weather",
38
+ "args": {"location": "London"},
39
+ }
40
+ ],
41
+ )
42
+ ]
43
+ )
44
+
45
+ assert should_use_tools(state) == "TOOL"
46
+
47
+
48
+ def test_should_route_tool_result_back_to_main_agent() -> None:
49
+ state = SimpleNamespace(context=[Message(role="tool", content=[])])
50
+
51
+ assert should_use_tools(state) == "MAIN"
52
+
53
+
54
+ def test_should_end_after_regular_assistant_response() -> None:
55
+ state = SimpleNamespace(context=[Message(role="assistant", content=[])])
56
+
57
+ assert should_use_tools(state) == END
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: 10xgraph
3
+ description: >-
4
+ Expert guidance for building, debugging, and extending applications with 10xGraph
5
+ (10xgraph). Use when code imports from tenxgraph or the legacy agentflow name (e.g. `from tenxgraph import`,
6
+ `StateGraph`, `Agent`, `ToolNode`, `AgentState`); when the user references `10xgraph.json`
7
+ or CLI commands (`10xgraph init`, `10xgraph api`, `10xgraph play`, `10xgraph build`,
8
+ `10xgraph skills`); or when the user is building graph-based multi-agent workflows, tools,
9
+ memory, checkpointing, or streaming with this framework. Skip generic Python or multi-agent
10
+ questions that do not reference 10xGraph, and other frameworks (LangGraph, CrewAI, AutoGen)
11
+ unless comparing.
12
+ license: MIT
13
+ ---
14
+
15
+ # 10xGraph Project Skill
16
+
17
+ Use this skill when working in a 10xGraph project. 10xGraph is a multi-agent framework that wraps official OpenAI and Google SDK capabilities behind a unified graph, agent, tool, state, storage, API, CLI, and TypeScript client interface.
18
+
19
+ Treat https://10xgraph.com/ as the first source of truth for public package names, install commands, and user-facing behavior. Use implementation source after the docs establish the intended API.
20
+
21
+ ## Workflow
22
+
23
+ 1. Identify the published package or docs surface involved:
24
+ - PyPI core Python SDK: `10xgraph` (`pip install 10xgraph`), source at https://github.com/10xGraph/10xGraph/tree/main/tenxgraph
25
+ - PyPI API/CLI SDK: `10xgraph-api` (`pip install 10xgraph-api`), source at https://github.com/10xGraph/10xgraph-api/tree/main/tenxgraph_api
26
+ - npm TypeScript SDK: `@10xscale/agentflow-client` (`npm install @10xscale/agentflow-client`), source at https://github.com/10xHub/Agentflow/tree/main/agentflow-client/src
27
+ - Main docs: https://10xgraph.com/
28
+ - Playground/UI: `10xgraph play` command after installed cli
29
+
30
+ 2. Read the matching reference file before changing behavior. Paths are relative to this skill's directory:
31
+
32
+ ### Core Python SDK
33
+ - Architecture and package flow: `references/architecture.md`
34
+ - Agent constructor, provider, reasoning, retry, fallback, output_schema: `references/agents-and-tools.md`
35
+ - Graph construction, nodes, edges, compile, interrupts, config keys: `references/state-graph.md`
36
+ - State, messages, and content blocks: `references/state-and-messages.md`
37
+ - Threads and checkpointing: `references/checkpointing-and-threads.md`
38
+ - Dependency injection (InjectQ): `references/dependency-injection.md`
39
+ - Multimodal files and media stores: `references/media-and-files.md`
40
+ - Long-term memory stores (MemoryConfig, QdrantStore, Mem0Store): `references/memory-and-store.md`
41
+ - Streaming, StreamChunk, SSE, ResponseGranularity: `references/streaming.md`
42
+ - Stream emitter for tool progress updates: `references/stream-emitter.md`
43
+ - Observability hooks, validators, and runtime jumps: `references/callbacks-and-command.md`
44
+ - Prebuilt agents (ReactAgent, PlanActReflectAgent, StructuredOutputAgent, SupervisorTeamAgent, SwarmAgent, RAGAgent) and tools: `references/prebuilt-agents-and-tools.md`
45
+ - Event publishers and A2A/ACP runtime protocols: `references/publishers-and-runtime-protocols.md`
46
+ - Context management, ID generation, and background tasks: `references/context-id-background.md`
47
+ - Provider internals and adapters: `references/providers-and-adapters.md`
48
+ - Prompt-injection and validation safety: `references/security-and-validators.md`
49
+ - Realtime audio-to-audio voice agents (AudioAgent, Gemini Live, `arealtime`, WebSocket bridge): `references/realtime.md`
50
+
51
+ ### API/CLI SDK
52
+ - CLI commands and generated project files: `references/cli-commands.md`
53
+ - `10xgraph.json` and dependency loading: `references/api-configuration.md`
54
+ - API auth and authorization: `references/auth-and-authorization.md`
55
+ - API environment, settings, and middleware: `references/api-settings-and-middleware.md`
56
+ - Rate limiting (config, backends, headers, custom backend): `references/rate-limiting.md`
57
+ - REST routes and error behavior: `references/rest-api-and-errors.md`
58
+ - API Snowflake IDs and thread naming: `references/id-and-thread-name-generators.md`
59
+ - API server and deployment runtime: `references/production-runtime.md`
60
+
61
+ ### TypeScript client SDK
62
+ - REST and TypeScript client surface: `references/api-client.md`
63
+ - Browser/client-side tool execution: `references/remote-tools.md`
64
+ - TypeScript auth helpers and structured errors: `references/client-auth-and-errors.md`
65
+ - TypeScript messages, invoke, and stream details: `references/client-messages-invoke-stream.md`
66
+ - TypeScript thread, memory, and file APIs: `references/client-threads-memory-files.md`
67
+
68
+ ### Testing and QA
69
+ - Unit testing without LLM calls (TestAgent, QuickTest, MockToolRegistry, `10xgraph test`): `references/unit-testing.md`
70
+ - Evaluation framework (EvalSet, criteria, AgentEvaluator, QuickEval, UserSimulator, `10xgraph eval`): `references/evaluation.md`
71
+ - Testing helpers overview: `references/testing-and-evaluation.md`
72
+
73
+ 3. Prefer existing 10xGraph abstractions over new custom wiring:
74
+ - Build workflows with `StateGraph`, `Agent`, `ToolNode`, `AgentState`, and `Message`.
75
+ - Use prebuilt agents (`ReactAgent`, `PlanActReflectAgent`, `StructuredOutputAgent`, `SupervisorTeamAgent`, `SwarmAgent`, `RAGAgent`) for common patterns before hand-writing graph loops.
76
+ - Persist conversation state with checkpointers; use stores only for cross-thread memory.
77
+ - Put business services in `InjectQ` instead of global variables.
78
+ - Keep API/CLI graph modules storage-agnostic and wire dependencies through `10xgraph.json`.
79
+
80
+ 4. Verify against source when implementation details matter. Public names and expected behavior should match https://10xgraph.com/; source under https://github.com/10xGraph/10xGraph (core), https://github.com/10xGraph/10xgraph-api (API/CLI), and https://github.com/10xHub/agentflow-client (TypeScript) explains how that behavior is implemented.
81
+
82
+ ## Local Conventions
83
+
84
+ - A compiled graph is normally loaded once by the API server and reused per request.
85
+ - Public package naming matters: use `10xgraph`, `10xgraph-api`, and `@10xscale/agentflow-client` in user-facing docs and examples, not repository folder names.
86
+ - Every persisted interaction should include `config.thread_id`.
87
+ - Tools need docstrings and type annotations so model-facing schemas are useful.
88
+ - Injectable tool and node parameters (`state`, `config`, `tool_call_id`) are hidden from the model schema.
89
+ - For production, avoid process-local storage for shared state; use durable checkpointer/store backends.
90
+ - Add observability or audit side effects by registering a `GraphLifecycleHook` on `CallbackManager` — do not wrap `ainvoke()` / `astream()` calls in application code to achieve the same result.
91
+ - `reasoning_config` is on by default at medium effort; disable explicitly with `reasoning_config=None` when not needed.
92
+ - Provider is auto-detected from the model name; use `base_url` for third-party OpenAI-compatible APIs (Ollama, DeepSeek, OpenRouter).