feat: add shell tool wire types - #264
Conversation
| vec![] | ||
| } | ||
| Self::Shell(_) => { | ||
| tracing::debug!("shell tool skipped in normalize - handler not yet registered"); |
There was a problem hiding this comment.
@bojiang3 shell tool type as below taken from openai examples in https://developers.openai.com/api/docs/guides/tools-shell
"tools": [ { "type": "shell", "environment": { "type": "container_auto", "network_policy": { "type": "allowlist", "allowed_domains": ["pypi.org", "files.pythonhosted.org", "github.com"] } } }
is not recognized by vLLM upstream. even if some of the types might be recognized by upstream still to keep agentic-api consistent and compatible with multiple upstreams for inference we always normalize/canonicalize any tool types into function types. so all tool support on agentic-api either client owned like shell or owned on gateway by agentic-api need to implement a ToolHandler interface so that we can normalize and validate the tools's schema for inference. kindly follow ARCHITECTURE.md and TERMINOLOGY.md.
there should be also request and responses cassettes recording for this tool type from openai as ground truth and agentic-api (gateway) to match the behavior of gateway with openai Responses API. you can read https://github.com/vllm-project/agentic-api/blob/main/crates/agentic-server-core/tests/cassettes/README.md how to record a cassettes and there are shell script examples like https://github.com/vllm-project/agentic-api/blob/main/crates/agentic-server-core/tests/cassettes/record_web_search_cassettes.sh, https://github.com/vllm-project/agentic-api/blob/main/crates/agentic-server-core/tests/cassettes/record_mcp_cassettes.sh
that use our python cassettes recorder.
There was a problem hiding this comment.
Addressed the handler/normalization feedback in 0aaebc9: shell now has a client-owned ShellHandler, validates local-only environments, registers as client-owned, normalizes to a vLLM-compatible function schema, and restores both blocking and streaming calls to typed shell_call items. Unsupported environments and malformed actions fail closed; no gateway command execution was added. I also added record_shell_cassettes.sh for matching OpenAI/gateway streaming and non-streaming recordings. I could not capture authentic YAML in this environment because OPENAI_API_KEY is unset and the configured gateway endpoint is unavailable, so I intentionally did not hand-author fixtures. Validation: full cargo test -p agentic-server-core passed (448 passed, 8 environment-dependent ignored), plus fmt and clippy with warnings denied.
There was a problem hiding this comment.
@bojiang3 do you have resources to record cassettes for both gatewayand for openai ? openai would need api key! if you cant actually record cassettes , I will record and push in your branch then you can write integration test comparing openai ground truth to agentic-api behavior. cassettes are a required for landing features specially for tool supports.
franciscojavierarceo
left a comment
There was a problem hiding this comment.
the local shell wire types, call/output pairing, and storage round-trip look consistent with this slice. i don't have additional findings beyond the existing handler and cassette feedback. this was a source review; i haven't independently run the tests.
Signed-off-by: bojiang3 <bojiang3@illinois.edu>
Signed-off-by: bojiang3 <bojiang3@illinois.edu>
5cf6c7c to
0aaebc9
Compare
|
the client-executed shell loop still breaks on continuation, and the public Rust API doesn't yet let someone plug in their own shell executor. on
for pluggability, we should expose an optional typed shell executor registration through i captured eight local cassettes covering streaming, blocking, continuation, and explicit selection against OpenAI directly and this gateway backed by the same model. they aren't pushed yet. all 448 core unit tests pass, as do Clippy and formatting; the recordings expose the strict replay failure above, and five focused review assertions fail. |
Signed-off-by: bojiang3 <bojiang3@illinois.edu>
- Prevent duplicate type tags in serialized shell inputs - Convert shell calls and outputs to matching function history - Support explicit shell tool selection and completed call status - Translate shell command SSE events and validate native stream lifecycle - Add two-turn cassettes and gateway/OpenAI compatibility tests Signed-off-by: maral <maralbahari.98@gmail.com>
|
@bojiang3 @franciscojavierarceo
The latest recordings match on shell actions, limits, completion status, command lifecycle, and continuation behavior. Delta fragment sizes differ, but reconstruct the same commands. The recordings use simulated client command outputs. |
|
@bojiang3 please resolve the conflicts. afterwards I'll re-record cassettes again to make sure there is no regression. |
Summary
shell_callandshell_call_outputitems, including command limits, stdout/stderr, and exit/timeout outcomesShellHandlerthat validatesenvironment.type: "local"and normalizes shell declarations to vLLM-compatible function toolsshell_callshape without ever executing commands in the gatewayPart of #170.
Safety boundary
This slice is client-owned only.
ShellHandlerintentionally does not implementGatewayExecutor, so declaring a shell tool cannot cause the gateway host to execute arbitrary commands. A separately configured, policy-enforced executor remains follow-up work.Test Plan
cargo fmt --all -- --checkcargo test -p agentic-server-core(448 passed, 8 environment-dependent tests ignored)cargo clippy -p agentic-server-core --all-targets -- -D warningsCassette status
record_shell_cassettes.shrecords matching streaming and non-streaming suites against OpenAI and the gateway using the repository's standard recorder. This environment has noOPENAI_API_KEY, and the configured gateway endpoint was unavailable, so this update deliberately does not include fabricated cassette YAML. The recorder is ready to run where those endpoints are available.