feat: add CLI tool execution with dynamic schema prompting#22
Conversation
Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
gabe-l-hart
left a comment
There was a problem hiding this comment.
This is a great new feature! I've tested it directly and it works nicely for simple tool calls.
start mcp server
python3 -m mcpgateway.translate --stdio "docker run --rm -i ghcr.io/ibm/fast-time-server:latest -transport=stdio" --expose-sse --port 9005boot CF
rm tmp/*; CONTEXTFORGE_HOME=$PWD/tmp cforge serve --port 5555 --no-auth
# Register in the UItest with prompting
PORT=5555 CONTEXTFORGE_HOME=$PWD/tmp cforge tools execute 7a43e085175545f58d214c329889d2a9test with data
PORT=5555 CONTEXTFORGE_HOME=$PWD/tmp cforge tools execute 7a43e085175545f58d214c329889d2a9 --data <(echo '{"timezone": "EST"}')I've got a few NITs and a large-ish request to refactor the new prompt_for_json_schema to avoid code duplication with prompt_for_schema.
Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
- Skip final jsonschema validation for prompt_for_schema (prompt schema is lossy) - Add schema_validation helper and regression coverage - Bump Typer minimum version Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
- Add docstrings for nested prompting helpers - Exclude generated cforge/_version.py from interrogate hook Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
|
I incorporated the refactor + NITs in the latest commits on this branch:
Tests: |
gabe-l-hart
left a comment
There was a problem hiding this comment.
I love the blowup of common.py. Much more understandable now. I do have some questions about whether we can use some more standardized jsonschema and pydantic functions to reduce the type/schema munging a bit.
Refactors prompting to be JSON-Schema-first. prompt_for_schema() now uses Pydantic model_json_schema() and tool schemas and Pydantic models go through the same prompting path. Removes the custom x-* hint fields and replaces them with schema-based prompting heuristics (including array-of-strings CSV input and optional object include gating). Fixes default rendering to distinguish “default key present” vs absent and renders defaults via json.dumps. Adds validate_schema() for early JSON Schema validation, updates tools execute to fail fast on empty IDs and to accept string-encoded schemas when they decode to an object, and restores recursive dict key-type validation for nested Pydantic models. Updates tests accordingly and adjusts interrogate exclusions for generated cforge/_version.py. Cleans up .gitignore duplicates.
gabe-l-hart
left a comment
There was a problem hiding this comment.
Almost there! A few small change requests left:
- Remove the dead function in
prompting.py - Comment for why we retain the local-only
$refresolution vs using third party - Revert changes to
.gitignore(unless you want to discuss this one further) - Open question on dependency lower-bound bump
Signed-off-by: Matthew Grigsby <38010437+MatthewGrigsby@users.noreply.github.com>
gabe-l-hart
left a comment
There was a problem hiding this comment.
Ship it! Thanks for this great progress
Description
Add CLI support for executing tools with dynamic JSON Schema prompting, so users can run tool calls from
cforgewithout switching to the desktop app or admin UI.Closes #5
Changes
cforge tools execute <tool-id>command and wire it intocforge maincommand registration.--data <file.json>for prefilled arguments from a JSON object file.prompt_for_json_schema(...)incforge/common.pyto drive interactive prompts from dynamic JSON Schemas.$ref/$defsreferences (including array/object references), detect cycles, and reject unsupported external references.--datais provided.CaseInsensitiveEnumincforge/common.py.plugins list --modecase-insensitively (e.g.--mode EnFoRcE).plugins get) from admin API unavailability.tools execute.Testing
uv run pytest --no-cov tests/commands/resources/test_tools.py tests/commands/resources/test_plugins.py tests/test_common.pyuv run pytest -o addopts='' --cov=cforge.commands.resources.tools --cov=cforge.commands.resources.plugins --cov=cforge.common --cov-report=term-missing:skip-covered tests/commands/resources/test_tools.py tests/commands/resources/test_plugins.py tests/test_common.pytest-cfg-cli/MANUAL_TEST_CASES.mdfor:--data)$refobject/array schema handling$refrejectionDiscussion
prompt_for_json_schemacurrently supports local JSON Pointer references (#/...) and intentionally rejects external refs.Definition Of Done
Follow-up update for a5aacb4
tests/test_common.pycases to fully coverprompt_for_json_schemaedge paths ($ref, enum parsing, optional/required branches, scalar/array/object prompts,and
additionalPropertiesbehavior).pragmaannotations incforge/common.pyfor defensive/unreachable branches only.uv run pytestpasses, and total coverage remains 100%.