LLMs
LLM management — generation-time model registration.
Namespace: Goodmem.Client.Api · Class: LlmsApi
Reach this surface as client.Llms on a GoodmemClient. Every network method is asynchronous — it returns a Task<T> (or an IAsyncEnumerable<T> for pagination and streaming) and accepts a CancellationToken; the Async suffix marks the standard .NET Task-based async pattern.
Methods
| Method | Summary |
|---|---|
CreateAsync | Create a new LLM. |
GetAsync | Get an LLM by ID. |
ListAsync | List LLMs. |
UpdateAsync | Update an LLM. |
DeleteAsync | Delete an LLM. |
CreateAsync
Creates a new LLM configuration for text generation services. LLMs represent connections to different language model API services (like OpenAI, vLLM, etc.) and include all the necessary configuration to use them for text generation. DUPLICATE DETECTION: Returns HTTP 409 Conflict (ALREADY_EXISTS) if another LLM exists with identical {ownerId, providerType, endpointUrl, apiPath, modelIdentifier, credentialsFingerprint} after URL canonicalization. Uniqueness is enforced per-owner. Credentials are hashed (SHA-256) for uniqueness while remaining encrypted. The apiPath field defaults to '/chat/completions' if omitted. Requires CREATE_LLM_OWN permission (or CREATE_LLM_ANY for admin users).
Declaration
public Task<CreateLlmResponse> CreateAsync(LlmCreationRequest request, string? apiKey = null, CancellationToken ct = default)
HTTP — POST /v1/llms
Parameters
| Type | Name | Description |
|---|---|---|
LlmCreationRequest | request | The request payload; the linked model lists every field and its JSON wire name. |
string | apiKey | Bare provider API key. The convenience layer auto-fills provider / endpoint / dimensionality from the bundled model registry and converts the key to structured credentials. Pass null to keep any credentials already set on request. (optional) |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<CreateLlmResponse> — an awaitable that resolves to CreateLlmResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentNullException | request is null. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var resp = await client.Llms.CreateAsync(
new LlmCreationRequest
{
DisplayName = "Doc LLM",
ModelIdentifier = "gpt-4o-mini",
Labels = new Dictionary<string, string> { ["env"] = "docs" },
},
"sk-..."
);
var llm = resp.Llm;
Console.WriteLine(llm.LlmId);GetAsync
Retrieves the details of a specific LLM configuration by its unique identifier. Requires READ_LLM_OWN permission for LLMs you own (or READ_LLM_ANY for admin users to view any user's LLMs). This is a read-only operation with no side effects.
Declaration
public Task<LlmResponse> GetAsync(string id, CancellationToken ct = default)
HTTP — GET /v1/llms/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | The unique identifier of the LLM to retrieve |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<LlmResponse> — an awaitable that resolves to LlmResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var llm = await client.Llms.GetAsync("your-llm-id");
Console.WriteLine(llm.DisplayName);ListAsync
Retrieves a list of LLM configurations accessible to the caller, with optional filtering. LABEL FILTERS: Label filters accept either label.<key>=<value> or label[key]=value (for example, label.environment=production or label[environment]=production). PERMISSION-BASED FILTERING: With LIST_LLM_OWN permission, you can only see your own LLMs (ownerId filter is ignored if set to another user). With LIST_LLM_ANY permission, you can see all LLMs or filter by any ownerId. This is a read-only operation with no side effects.
Declaration
public Task<ListLlmsResponse> ListAsync(LlmsListOptions? options = null, CancellationToken ct = default)
HTTP — GET /v1/llms
Parameters
| Type | Name | Description |
|---|---|---|
LlmsListOptions | options | Options bag carrying the lookup key(s) / convenience knobs; the linked type lists them all. (optional) |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<ListLlmsResponse> — an awaitable that resolves to ListLlmsResponse.
Exceptions
| Type | Condition |
|---|---|
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var resp = await client.Llms.ListAsync();
foreach (var llm in resp.Llms)
Console.WriteLine($"{llm.LlmId} {llm.DisplayName}");UpdateAsync
Updates an existing LLM configuration including display information, endpoint configuration, model parameters, credentials, and labels. All fields are optional - only specified fields will be updated. SUPPORTED_MODALITIES UPDATE: If the array contains >=1 elements, it replaces the stored set; if empty or omitted, no change occurs and it does not count as an update by itself. IMPORTANT: providerType is IMMUTABLE after creation and cannot be changed. Requires UPDATE_LLM_OWN permission for LLMs you own (or UPDATE_LLM_ANY for admin users).
Declaration
public Task<LlmResponse> UpdateAsync(string id, LlmUpdateRequest request, CancellationToken ct = default)
HTTP — PUT /v1/llms/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | The unique identifier of the LLM to update |
LlmUpdateRequest | request | The request payload; the linked model lists every field and its JSON wire name. |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task<LlmResponse> — an awaitable that resolves to LlmResponse.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
ArgumentNullException | request is null. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
var updated = await client.Llms.UpdateAsync(
"your-llm-id",
new LlmUpdateRequest
{
DisplayName = "Doc LLM (updated)",
MergeLabels = new Dictionary<string, string> { ["version"] = "2" },
}
);
Console.WriteLine(updated.LlmId);DeleteAsync
Permanently deletes an LLM configuration. This operation cannot be undone and removes the LLM record and securely deletes stored credentials. IMPORTANT: This does NOT invalidate or delete any previously generated content using this LLM - existing generations remain accessible. Requires DELETE_LLM_OWN permission for LLMs you own (or DELETE_LLM_ANY for admin users).
Declaration
public Task DeleteAsync(string id, CancellationToken ct = default)
HTTP — DELETE /v1/llms/{id}
Parameters
| Type | Name | Description |
|---|---|---|
string | id | The unique identifier of the LLM to delete |
CancellationToken | ct | Cancellation / deadline signal for the call. (optional) |
Returns
Task — completes when the operation finishes; there is no response body.
Exceptions
| Type | Condition |
|---|---|
ArgumentException | id is null or empty. |
NetworkException | The request could not reach the server (DNS, connection, or TLS failure). |
ApiException | The server returned a non-success (non-2xx) status. A status-specific subtype is thrown where it applies — e.g. NotFoundException (404), PermissionDeniedException (403), ConflictException (409). |
Example
await client.Llms.DeleteAsync("your-llm-id");Data Models
Types in the Goodmem.Client.Models namespace. Each row lists the C# property, its type, the JSON wire name, and a description.
LLMCreationRequest
Request body for creating a new LLM. An LLM represents a configuration for text generation services.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
DisplayName | string | displayName | User-facing name of the LLM |
Description | string | description | Description of the LLM (optional) |
ProviderType | LlmProviderType | providerType | Type of LLM provider |
EndpointUrl | string | endpointUrl | API endpoint base URL (OpenAI-compatible base, typically ends with /v1) |
ApiPath | string | apiPath | API path for chat/completions request (defaults to /chat/completions if not provided) (optional) |
ModelIdentifier | string | modelIdentifier | Model identifier |
SupportedModalities | IReadOnlyList<Modality> | supportedModalities | Supported content modalities (defaults to TEXT if not provided) (optional) |
Credentials | EndpointAuthentication | credentials | Structured credential payload describing how to authenticate with the provider. Required for SaaS providers; optional for local or proxy providers. (optional) |
Labels | IReadOnlyDictionary<string, string> | labels | User-defined labels for categorization (optional) |
Version | string | version | Version information (optional) |
MonitoringEndpoint | string | monitoringEndpoint | Monitoring endpoint URL (optional) |
Capabilities | LlmCapabilities | capabilities | LLM capabilities defining supported features and modes. Optional - server infers capabilities from model identifier if not provided. (optional) |
DefaultSamplingParams | LlmSamplingParams | defaultSamplingParams | Default sampling parameters for generation requests (optional) |
MaxContextLength | int | maxContextLength | Maximum context window size in tokens (optional) |
ClientConfig | IReadOnlyDictionary<string, object> | clientConfig | Provider-specific client configuration as flexible JSON structure (optional) |
OwnerId | string | ownerId | Optional owner ID. If not provided, derived from the authentication context. Requires CREATE_LLM_ANY permission if specified. (optional) |
LlmId | string | llmId | Optional client-provided UUID for idempotent creation. If not provided, server generates a new UUID. Returns ALREADY_EXISTS if ID is already in use. (optional) |
LLMProviderType
LLM provider types
String enum: "OPENAI" · "LITELLM_PROXY" · "OPEN_ROUTER" · "VLLM" · "OLLAMA" · "LLAMA_CPP" · "CUSTOM_OPENAI_COMPATIBLE"
LLMCapabilities
Capabilities and features supported by an LLM service
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
SupportsChat | bool | supportsChat | Supports conversational/chat completion format with message roles (optional) |
SupportsCompletion | bool | supportsCompletion | Supports raw text completion with prompt continuation (optional) |
SupportsFunctionCalling | bool | supportsFunctionCalling | Supports function/tool calling with structured responses (optional) |
SupportsSystemMessages | bool | supportsSystemMessages | Supports system prompts to define model behavior and context (optional) |
SupportsStreaming | bool | supportsStreaming | Supports real-time token streaming during generation (optional) |
SupportsSamplingParameters | bool | supportsSamplingParameters | Supports sampling parameters like temperature, top_p, and top_k for generation control (optional) |
LLMSamplingParams
Sampling and generation parameters for controlling LLM text output
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
MaxTokens | int | maxTokens | Maximum tokens to generate (>0 if set; provider-dependent limits apply) (optional) |
Temperature | double | temperature | Sampling temperature; valid range depends on the configured provider (optional) |
TopP | double | topP | Nucleus sampling threshold 0.0-1.0 (smaller values focus on higher probability tokens) (optional) |
TopK | int | topK | Top-k sampling limit (>0 if set; primarily for local/open-source models) (optional) |
FrequencyPenalty | double | frequencyPenalty | Frequency penalty; valid range depends on the configured provider (optional) |
PresencePenalty | double | presencePenalty | Presence penalty; valid range depends on the configured provider (optional) |
StopSequences | IReadOnlyList<string> | stopSequences | Generation stop sequences; generation halts on exact match (optional) |
CreateLLMResponse
Response containing the created LLM and any informational status messages
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
Llm | LlmResponse | llm | The created LLM configuration |
Statuses | IReadOnlyList<GoodMemStatus> | statuses | Optional status messages providing information about server-side operations performed during creation, such as capability inference results (optional) |
LLMResponse
LLM configuration information
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
LlmId | string | llmId | Unique identifier of the LLM |
DisplayName | string | displayName | User-facing name of the LLM |
Description | string | description | Description of the LLM (optional) |
ProviderType | LlmProviderType | providerType | Type of LLM provider |
EndpointUrl | string | endpointUrl | API endpoint base URL |
ApiPath | string | apiPath | API path for chat/completions request (optional) |
ModelIdentifier | string | modelIdentifier | Model identifier |
SupportedModalities | IReadOnlyList<Modality> | supportedModalities | Supported content modalities |
Credentials | EndpointAuthentication | credentials | Structured credential payload used for upstream authentication (optional) |
Labels | IReadOnlyDictionary<string, string> | labels | User-defined labels for categorization |
Version | string | version | Version information (optional) |
MonitoringEndpoint | string | monitoringEndpoint | Monitoring endpoint URL (optional) |
Capabilities | LlmCapabilities | capabilities | LLM capabilities defining supported features and modes |
DefaultSamplingParams | LlmSamplingParams | defaultSamplingParams | Default sampling parameters for generation requests (optional) |
MaxContextLength | int | maxContextLength | Maximum context window size in tokens (optional) |
ClientConfig | IReadOnlyDictionary<string, object> | clientConfig | Provider-specific client configuration (optional) |
OwnerId | string | ownerId | Owner ID of the LLM |
CreatedAt | DateTimeOffset | createdAt | Creation timestamp (milliseconds since epoch) |
UpdatedAt | DateTimeOffset | updatedAt | Last update timestamp (milliseconds since epoch) |
CreatedById | string | createdById | ID of the user who created the LLM |
UpdatedById | string | updatedById | ID of the user who last updated the LLM |
ListLLMsResponse
Response containing a list of LLM configurations
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
Llms | IReadOnlyList<LlmResponse> | llms | List of LLM configurations matching the request filters |
LLMUpdateRequest
Request body for updating an existing LLM. All fields are optional - only specified fields will be updated. supportedModalities replaces the stored set only when the array contains at least one value; empty or omitted leaves it unchanged and does not count as an update by itself.
| Property | Type | JSON (wire) | Description |
|---|---|---|---|
DisplayName | string | displayName | Update display name (optional) |
Description | string | description | Update description (optional) |
EndpointUrl | string | endpointUrl | Update endpoint base URL (OpenAI-compatible base, typically ends with /v1) (optional) |
ApiPath | string | apiPath | Update API path (optional) |
ModelIdentifier | string | modelIdentifier | Update model identifier (cannot be empty) (optional) |
SupportedModalities | IReadOnlyList<Modality> | supportedModalities | Update supported modalities (if array contains >=1 elements, replaces stored set; if empty or omitted, no change and does not count as an update by itself) (optional) |
Credentials | EndpointAuthentication | credentials | Update credentials (optional) |
Version | string | version | Update version information (optional) |
MonitoringEndpoint | string | monitoringEndpoint | Update monitoring endpoint URL (optional) |
Capabilities | LlmCapabilities | capabilities | Update LLM capabilities (replaces entire capability set; clients MUST send all flags) (optional) |
DefaultSamplingParams | LlmSamplingParams | defaultSamplingParams | Update default sampling parameters (optional) |
MaxContextLength | int | maxContextLength | Update maximum context window size in tokens (optional) |
ClientConfig | IReadOnlyDictionary<string, object> | clientConfig | Update provider-specific client configuration (replaces entire config; no merging) (optional) |
ReplaceLabels | IReadOnlyDictionary<string, string> | replaceLabels | Replace all existing labels with this set. Empty map clears all labels. Cannot be used with mergeLabels. (optional) |
MergeLabels | IReadOnlyDictionary<string, string> | mergeLabels | Merge with existing labels: upserts with overwrite. Labels not mentioned are preserved. Cannot be used with replaceLabels. (optional) |