mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-16 05:20:22 +08:00
* feat(providers): add Google Vertex AI provider Adds Vertex AI provider profiles, routing, credential refresh plumbing, CLI support, docs, and regression coverage. Keeps the related NETLINK_ROUTE seccomp allowance needed by Vertex client tooling that calls getifaddrs. * docs: add Vertex AI sandbox usage for Claude Code and OpenCode Cover the full end-to-end setup for running Claude Code and OpenCode inside an OpenShell sandbox via inference.local with a Vertex AI backend: - google-vertex-ai.mdx: add 'Use from a Sandbox' section with tabbed examples for Claude Code (--bare flag, no /v1 suffix) and OpenCode (/v1 suffix required). Add providers_v2_enabled prerequisite and --no-verify note for global region. Document policy proposals table covering metadata.google.internal (always blocked), downloads.claude.ai, and storage.googleapis.com. - inference-routing.mdx: expand 'Use the Local Endpoint' section with tabbed examples for Claude Code, OpenCode, Python OpenAI SDK, and Python Anthropic SDK. Add notes explaining the /v1 path suffix difference between clients. - supported-agents.mdx: update Claude Code and OpenCode rows to mention inference.local support and correct base URL requirements. * fix: address vertex review findings * test(sandbox): retry on spurious Ok in fork-exec ambiguity test On arm64 under heavy CI load, the /proc fd scan in find_socket_inode_owners can transiently miss the parent process's socket fd entry, returning only the child as an owner. This causes resolve_process_identity to return Ok (single owner, no ambiguity check fires) instead of the expected ambiguous-ownership Err. Extend the retry loop to also handle unexpected Ok results, mirroring the existing retry for transient Err results. 10 retries at 50ms gives a 500ms settling window, which is sufficient for procfs to stabilize on loaded arm64 runners. * fix: address vertex review regressions * docs(router): clarify stream_response semantics for Vertex rawPredict routing Document the three call sites of prepare_backend_request and their stream_response values in a caller table: - send_backend_request: false → :rawPredict (unary endpoint) - send_backend_request_streaming: true → :streamRawPredict - verify_backend_endpoint: explicitly false to probe the unary endpoint Cross-reference the table from build_provider_url and is_vertex_anthropic_rawpredict_route so the stream_response=true guard in the suffix upgrade branch is understood in full context. Also note that is_vertex_anthropic_rawpredict_route is a structural predicate (model_in_path + anthropic_messages + :rawPredict suffix), not a named-provider check, so any future provider with the same route shape inherits the transforms automatically.
126 lines
4.2 KiB
Protocol Buffer
126 lines
4.2 KiB
Protocol Buffer
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
syntax = "proto3";
|
|
|
|
package openshell.inference.v1;
|
|
|
|
import "datamodel.proto";
|
|
|
|
// Inference service provides cluster inference configuration and bundle delivery.
|
|
service Inference {
|
|
// Return the resolved inference route bundle for sandbox-local execution.
|
|
rpc GetInferenceBundle(GetInferenceBundleRequest)
|
|
returns (GetInferenceBundleResponse);
|
|
|
|
// Set cluster-level inference configuration.
|
|
//
|
|
// This controls how requests sent to `inference.local` are routed.
|
|
rpc SetClusterInference(SetClusterInferenceRequest)
|
|
returns (SetClusterInferenceResponse);
|
|
|
|
// Get cluster-level inference configuration.
|
|
rpc GetClusterInference(GetClusterInferenceRequest)
|
|
returns (GetClusterInferenceResponse);
|
|
|
|
}
|
|
|
|
// Persisted cluster inference configuration.
|
|
//
|
|
// Only `provider_name` and `model_id` are stored; endpoint, protocols,
|
|
// credentials, and auth style are resolved from the provider at bundle time.
|
|
message ClusterInferenceConfig {
|
|
// Provider record name backing this route.
|
|
string provider_name = 1;
|
|
// Model identifier to force on generation calls.
|
|
string model_id = 2;
|
|
// Per-route request timeout in seconds. 0 means use default (60s).
|
|
uint64 timeout_secs = 3;
|
|
}
|
|
|
|
// Storage envelope for the managed cluster inference route.
|
|
message InferenceRoute {
|
|
openshell.datamodel.v1.ObjectMeta metadata = 1;
|
|
ClusterInferenceConfig config = 2;
|
|
// Monotonic version incremented on every update.
|
|
uint64 version = 3;
|
|
}
|
|
|
|
message SetClusterInferenceRequest {
|
|
// Provider record name to use for credentials + endpoint mapping.
|
|
string provider_name = 1;
|
|
// Model identifier to force on generation calls.
|
|
string model_id = 2;
|
|
// Route name to target. Empty string defaults to "inference.local" (user-facing).
|
|
// Use "sandbox-system" for the sandbox system-level inference route.
|
|
string route_name = 3;
|
|
// Verify the resolved upstream endpoint synchronously before persistence.
|
|
bool verify = 4;
|
|
// Skip synchronous endpoint validation before persistence.
|
|
bool no_verify = 5;
|
|
// Per-route request timeout in seconds. 0 means use default (60s).
|
|
uint64 timeout_secs = 6;
|
|
}
|
|
|
|
message ValidatedEndpoint {
|
|
string url = 1;
|
|
string protocol = 2;
|
|
}
|
|
|
|
message SetClusterInferenceResponse {
|
|
string provider_name = 1;
|
|
string model_id = 2;
|
|
uint64 version = 3;
|
|
// Route name that was configured.
|
|
string route_name = 4;
|
|
// Whether endpoint verification ran as part of this request.
|
|
bool validation_performed = 5;
|
|
// The concrete endpoints that were probed during validation, when available.
|
|
repeated ValidatedEndpoint validated_endpoints = 6;
|
|
// Per-route request timeout in seconds that was persisted.
|
|
uint64 timeout_secs = 7;
|
|
}
|
|
|
|
message GetClusterInferenceRequest {
|
|
// Route name to query. Empty string defaults to "inference.local" (user-facing).
|
|
// Use "sandbox-system" for the sandbox system-level inference route.
|
|
string route_name = 1;
|
|
}
|
|
|
|
message GetClusterInferenceResponse {
|
|
string provider_name = 1;
|
|
string model_id = 2;
|
|
uint64 version = 3;
|
|
// Route name that was queried.
|
|
string route_name = 4;
|
|
// Per-route request timeout in seconds. 0 means default (60s).
|
|
uint64 timeout_secs = 5;
|
|
}
|
|
|
|
message GetInferenceBundleRequest {}
|
|
|
|
// A single resolved route ready for sandbox-local execution.
|
|
message ResolvedRoute {
|
|
string name = 1;
|
|
string base_url = 2;
|
|
repeated string protocols = 3;
|
|
string api_key = 4;
|
|
string model_id = 5;
|
|
string provider_type = 6;
|
|
// Per-route request timeout in seconds. 0 means use default (60s).
|
|
uint64 timeout_secs = 7;
|
|
// When true, the model identifier is embedded in the URL path (e.g. Vertex AI).
|
|
bool model_in_path = 8;
|
|
// Optional override for the request path. When set, replaces the protocol-derived path.
|
|
// An empty string means POST directly to base_url/model_id with no additional path.
|
|
optional string request_path_override = 9;
|
|
}
|
|
|
|
message GetInferenceBundleResponse {
|
|
repeated ResolvedRoute routes = 1;
|
|
// Opaque revision tag for cache freshness checks.
|
|
string revision = 2;
|
|
// Timestamp (epoch ms) when this bundle was generated.
|
|
int64 generated_at_ms = 3;
|
|
}
|