diff --git a/.github/workflows/secscan.yaml b/.github/workflows/secscan.yaml index bb381567baa5..c09f30867db8 100644 --- a/.github/workflows/secscan.yaml +++ b/.github/workflows/secscan.yaml @@ -15,15 +15,15 @@ jobs: steps: - name: Checkout Source uses: actions/checkout@v6 - if: ${{ github.actor != 'dependabot[bot]' }} + if: ${{ !github.repository.fork && github.actor != 'dependabot[bot]' }} - name: Run Gosec Security Scanner - if: ${{ github.actor != 'dependabot[bot]' }} + if: ${{ !github.repository.fork && github.actor != 'dependabot[bot]' }} uses: securego/gosec@v2.27.1 with: # we let the report trigger content trigger a failure using the GitHub Security features. args: '-no-fail -fmt sarif -out results.sarif ./...' - name: Upload SARIF file - if: ${{ github.actor != 'dependabot[bot]' }} + if: ${{ !github.repository.fork && github.actor != 'dependabot[bot]' }} uses: github/codeql-action/upload-sarif@v4 with: # Path to SARIF file relative to the root of the repository diff --git a/pkg/mcp/localaitools/coverage_test.go b/pkg/mcp/localaitools/coverage_test.go index 8159afcf9e89..ced3b85d73b4 100644 --- a/pkg/mcp/localaitools/coverage_test.go +++ b/pkg/mcp/localaitools/coverage_test.go @@ -30,7 +30,7 @@ var toolToHTTPRoute = map[string]string{ ToolListInstalledModels: "GET / (welcome JSON, ModelsConfig field)", ToolListGalleries: "GET /models/galleries", ToolGetJobStatus: "GET /models/jobs/:uuid", - ToolGetModelConfig: "(none) — no JSON-only REST yet; httpapi.Client returns a documented stub", + ToolGetModelConfig: "GET /api/models/config-yaml/:name", ToolListBackends: "GET /backends", ToolListKnownBackends: "GET /backends/known", ToolSystemInfo: "GET / (welcome JSON)", diff --git a/pkg/mcp/localaitools/httpapi/client.go b/pkg/mcp/localaitools/httpapi/client.go index c180b79c2655..55b331dd901e 100644 --- a/pkg/mcp/localaitools/httpapi/client.go +++ b/pkg/mcp/localaitools/httpapi/client.go @@ -228,17 +228,19 @@ func (c *Client) GetJobStatus(ctx context.Context, jobID string) (*localaitools. }, nil } -// GetModelConfig is intentionally a stub for the HTTP client: LocalAI's -// /models/edit/:name endpoint returns rendered HTML, not JSON, so the -// standalone CLI's `get_model_config` tool surfaces a clear error to the -// LLM. Tracked under the localai-assistant follow-ups (see -// .agents/localai-assistant-mcp.md) — once a JSON-only -// GET /api/models/config-yaml/:name endpoint lands on the server, this -// method calls it and the stub goes away. -// -// FIXME(localai-assistant): wire to a JSON read-back endpoint. -func (c *Client) GetModelConfig(_ context.Context, _ string) (*localaitools.ModelConfigView, error) { - return nil, errors.New("get_model_config over HTTP not yet supported by this client; use the in-process inproc client or REST /models/edit/{name}") +func (c *Client) GetModelConfig(ctx context.Context, name string) (*localaitools.ModelConfigView, error) { + if name == "" { + return nil, errors.New("name is required") + } + var raw struct { + Name string `json:"name"` + YAML string `json:"yaml"` + JSON map[string]any `json:"json"` + } + if err := c.do(ctx, http.MethodGet, routeModelConfigYAML(name), nil, &raw); err != nil { + return nil, err + } + return &localaitools.ModelConfigView{Name: raw.Name, YAML: raw.YAML, JSON: raw.JSON}, nil } // ---- Models / gallery (write) ---- diff --git a/pkg/mcp/localaitools/httpapi/routes.go b/pkg/mcp/localaitools/httpapi/routes.go index 4be8f2ad87d1..953be44fb925 100644 --- a/pkg/mcp/localaitools/httpapi/routes.go +++ b/pkg/mcp/localaitools/httpapi/routes.go @@ -34,6 +34,10 @@ const ( routeRouterDecisions = "/api/router/decisions" ) +func routeModelConfigYAML(name string) string { + return "/api/models/config-yaml/" + url.PathEscape(name) +} + func routePIIPatternByID(id string) string { return "/api/pii/patterns/" + url.PathEscape(id) }