API — ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot
The public contract of 11 header(s) under src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot — 16 class/struct definition(s), 78 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICoreCopilotContext.h | ICoreCopilotContext | 3 | — |
ICoreCopilotSettings.h | ICoreCopilotSettings | 12 | — |
ICoreCredentialStore.h | ICoreCredentialStore | 6 | — |
ICoreAnthropicBackend.h | ICoreAnthropicBackend | 8 | public ICoreLLMBackend |
ICoreLLMBackend.h | ICoreLLMBackend | 23 | — |
ICoreLLMBackendFactory.h | ICoreLLMBackendFactory | 4 | — |
ICoreLLMTypes.h | ICoreLLMToolCall, ICoreLLMMessage, ICoreLLMTool, ICoreLLMUsage, ICoreLLMRequest, ICoreLLMResponse | 6 | — |
ICoreOpenAIBackend.h | ICoreOpenAIBackend | 8 | public ICoreLLMBackend |
ICoreCopilotConnectionDialog.h | ICoreCopilotConnectionDialog | 2 | public ICoreDialog |
ICoreCopilotConnectionSettings.h | ICoreCopilotConnectionSettings | 3 | public ICoreWidget |
ICoreCopilotPanel.h | ICoreCopilotPanel | 3 | public ICoreWidget |
ICoreCopilotContext.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/ICoreCopilotContext.h
ICoreCopilotContext#
ICoreCopilotContext.h:31 · class · 3 declaration(s)
Assembles what the copilot knows about the project before a question is sent.
class ICoreCopilotContext {
public:
// The stable prefix. Deterministic for a given build: the block catalog is
// sorted, so two calls in the same session produce identical bytes.
static ICoreString buildSystemPrompt();
// The live diagram as recipe text, wrapped with the level it came from.
// Returns a short "empty diagram" note rather than an empty string, so the
// model can tell "nothing there" apart from "context was not supplied".
static ICoreString buildDiagramContext(ICoreSubsystemTreeNode* node);
// The subsystem currently on screen in the focused editor tab, or Home when
// no tab is focused. Never null in a running editor.
static ICoreSubsystemTreeNode* currentNode();
};
ICoreCopilotSettings.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/ICoreCopilotSettings.h
ICoreCopilotSettings#
ICoreCopilotSettings.h:24 · class · 12 declaration(s)
Non-secret copilot configuration: which provider is active, which model, and any endpoint override.
class ICoreCopilotSettings {
public:
static long initializeCopilotSettings();
// "openai" or "anthropic". Defaults to "anthropic".
static ICoreString activeProviderId();
static void setActiveProviderId(const ICoreString& providerId);
static ICoreStringList availableProviderIds();
// Empty => the backend's own defaultModel().
static ICoreString modelForProvider(const ICoreString& providerId);
static void setModelForProvider(const ICoreString& providerId, const ICoreString& model);
// Empty => the provider's public API. Set this to point at a local or
// self-hosted server; for the OpenAI-compatible backend that is what makes
// Ollama / vLLM / LM Studio work.
static ICoreString baseUrlForProvider(const ICoreString& providerId);
static void setBaseUrlForProvider(const ICoreString& providerId, const ICoreString& baseUrl);
static int maxOutputTokens();
static void setMaxOutputTokens(int tokens);
// Whether to send the provider's cache-control markers on the stable
// prefix. On by default; exposed mainly so an OpenAI-compatible server that
// chokes on unknown fields can be worked around without a rebuild.
static bool cacheStablePrefix();
static void setCacheStablePrefix(bool enabled);
};
ICoreCredentialStore.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/ICoreCredentialStore.h
ICoreCredentialStore#
ICoreCredentialStore.h:24 · class · 6 declaration(s)
Stores copilot API keys in the operating system's own credential vault, keyed by provider id ("openai" / "anthropic").
class ICoreCredentialStore {
public:
// Empty string when no key is stored (or the lookup failed — an absent key
// and an unreadable vault are not distinguished, because the caller's
// response to both is the same: prompt for a key).
static ICoreString loadApiKey(const ICoreString& providerId);
// Overwrites any existing key for that provider. An empty `key` clears it,
// which is the same path as forgetApiKey().
static bool saveApiKey(const ICoreString& providerId, const ICoreString& key);
static bool forgetApiKey(const ICoreString& providerId);
static bool hasApiKey(const ICoreString& providerId);
// False on platforms using the file fallback. Surface this in the UI.
static bool isSecure();
// Human-readable name of the backing store, for the settings panel
// ("macOS Keychain", "Windows Credential Manager", "local file").
static ICoreString backingStoreName();
};
ICoreAnthropicBackend.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/Backends/ICoreAnthropicBackend.h
ICoreAnthropicBackend#
ICoreAnthropicBackend.h:23 · class · bases public ICoreLLMBackend · pImpl · 8 declaration(s)
Messages API backend — POST {base}/v1/messages.
class ICoreAnthropicBackend : public ICoreLLMBackend {
public:
ICoreAnthropicBackend();
~ICoreAnthropicBackend() override;
ICoreString providerId() const override;
ICoreString displayName() const override;
ICoreString defaultModel() const override;
ICoreStringList suggestedModels() const override;
protected:
void buildHttpRequest(const ICoreLLMRequest& request,
ICoreHttpRequest& httpRequest,
ICoreJsonObject& body) const override;
void handleStreamEvent(const ICoreString& eventName, const ICoreJsonObject& data) override;
void resetStreamState() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreLLMBackend.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/Backends/ICoreLLMBackend.h
ICoreLLMBackend#
ICoreLLMBackend.h:31 · class · pImpl · 23 declaration(s)
Abstract streaming chat backend.
class ICoreLLMBackend {
public:
ICoreLLMBackend();
virtual ~ICoreLLMBackend();
// Stable identifier persisted in settings: "openai" / "anthropic".
virtual ICoreString providerId() const = 0;
// Human-readable, for the settings panel.
virtual ICoreString displayName() const = 0;
// Used when ICoreLLMRequest::model is empty.
virtual ICoreString defaultModel() const = 0;
// Offered in the settings combo box. Free-text entry is still allowed, so
// this list going stale degrades the UI but never blocks a new model.
virtual ICoreStringList suggestedModels() const = 0;
// The key is read from ICoreCredentialStore at send() time rather than
// cached, so revoking or replacing it takes effect on the next message
// without restarting the app.
void setApiKey(const ICoreString& key);
ICoreString apiKey() const;
// Override the endpoint host. Empty => the provider's own API. This is what
// makes a self-hosted or proxied deployment work without a code change: any
// server speaking the same wire format can be pointed at here.
void setBaseUrl(const ICoreString& url);
ICoreString baseUrl() const;
bool isBusy() const;
// Begins a streaming request. Raises onTextDelta as tokens arrive, then
// exactly one of onFinished or onFailed. Never both.
void send(const ICoreLLMRequest& request);
// Aborts an in-flight request. Raises onFinished with stopReason "cancelled"
// and whatever text had already streamed, so a partial answer is preserved
// in the transcript rather than discarded.
void cancel();
// What this backend reports. All four are raised with post(), because a
// reply arrives on the network thread and every subscriber is UI: post()
// hops to the GUI thread, which is what the queued connections these
// replace were doing.
ICoreSignal<ICoreString> onTextDelta;
// Raised once per completed tool call, after its arguments have been fully
// accumulated and parsed. Also present in the final response's toolCalls.
ICoreSignal<ICoreLLMToolCall> onToolCallReady;
ICoreSignal<ICoreLLMResponse> onFinished;
ICoreSignal<ICoreString> onFailed;
// ---- The backend seam ---------------------------------------------
// PUBLIC by owner decision, 2026-08-14. These eight are what the OpenAI
// and Anthropic subclasses are written against; they were protected
// non-virtual, which the header surface rule bans and which exemption 2
// (protected VIRTUAL override surfaces) does not reach. Publishing them
// was chosen over making them virtual -- they are not meant to be
// overridden -- and over granting the header an exemption.
//
// Nothing here changed behaviour: same names, same signatures, same
// bodies. Only the access specifier moved.
void emitText(const ICoreString& chunk);
void setStopReason(const ICoreString& reason);
void setUsage(const ICoreLLMUsage& usage);
// Usage accumulated so far this response. Providers that report input and
// output token counts in different events need this to merge rather than
// clobber — see ICoreAnthropicBackend's message_delta handling.
ICoreLLMUsage currentUsage() const;
// Streamed tool arguments arrive as JSON fragments that are only valid once
// concatenated, and both providers key those fragments by an integer index
// within the response. These three calls own that reassembly.
void beginToolCall(int index, const ICoreString& id, const ICoreString& name);
void appendToolArguments(int index, const ICoreString& jsonFragment);
// Parses the accumulated fragment and raises onToolCallReady. A fragment that
// does not parse is reported through onFailed rather than silently dropped —
// a malformed tool call that reaches the recipe interpreter is far worse
// than a visible error.
void completeToolCall(int index);
// Extracts a human-readable message from a provider error body. Both
// providers nest it at error.message; falls back to the raw body.
static ICoreString extractErrorMessage(const ICoreByteArray& body, int httpStatus);
protected:
// ---- Subclass contract -------------------------------------------------
// Fill in URL, headers and the JSON body for `request`. Called once per send().
virtual void buildHttpRequest(const ICoreLLMRequest& request,
ICoreHttpRequest& httpRequest,
ICoreJsonObject& body) const = 0;
// Handle one decoded SSE event. `eventName` is the `event:` line when the
// provider sends one (Anthropic) and empty when it does not (OpenAI).
// Implementations push text through emitText() and tool calls through the
// accumulator helpers below.
virtual void handleStreamEvent(const ICoreString& eventName, const ICoreJsonObject& data) = 0;
// Wipe any subclass-local streaming state. Called before every send().
virtual void resetStreamState();
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreLLMBackendFactory.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/Backends/ICoreLLMBackendFactory.h
ICoreLLMBackendFactory#
ICoreLLMBackendFactory.h:16 · class · 4 declaration(s)
Builds a backend for a provider id and wires it up from ICoreCopilotSettings and ICoreCredentialStore.
class ICoreLLMBackendFactory {
public:
// Backend for the provider the user has selected. Never null — an unknown
// id falls back to the default provider rather than returning nothing, so
// callers do not each need a null branch.
//
// The caller OWNS what comes back -- there is no parent link to take it
// down, so the returned unique_ptr is the whole of its lifetime. The API key
// is read at construction AND refreshed on every send by the caller via
// applyStoredCredentials(), so a key changed in the settings panel takes
// effect without rebuilding the backend.
static std::unique_ptr<ICoreLLMBackend> createActiveBackend();
static std::unique_ptr<ICoreLLMBackend> createBackend(const ICoreString& providerId);
// Re-reads key / model / base URL from settings into a live backend. Borrows
// it -- ownership stays with the caller.
static void applyStoredCredentials(ICoreLLMBackend* backend);
// True when the active provider has a key stored. The chat panel uses this
// to show a "connect an account" state instead of failing on first send.
static bool activeProviderIsConfigured();
};
};
ICoreLLMTypes.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/Backends/ICoreLLMTypes.h
ICoreLLMToolCall#
ICoreLLMTypes.h:30 · struct · 0 declaration(s)
One model-requested call of a tool the copilot exposes (create_block, connect, set_config, ...).
struct ICoreLLMToolCall {
public:
ICoreString id; // provider-assigned; echoed back on the tool result
ICoreString name;
ICoreJsonObject arguments;
};
};
ICoreLLMMessage#
ICoreLLMTypes.h:36 · struct · 3 declaration(s)
struct ICoreLLMMessage {
public:
ICoreLLMRole role = ICoreLLMRole::User;
ICoreString text;
ICoreList<ICoreLLMToolCall> toolCalls; // Assistant turns only
ICoreString toolCallId; // Tool turns only — which call this answers
bool isError = false; // Tool turns only — result is a failure
static ICoreLLMMessage user(const ICoreString& body);
static ICoreLLMMessage assistant(const ICoreString& body);
// A tool result. `body` is what the model reads, so put the interpreter's
// actual error text here on failure rather than a generic string — that text
// is what lets the model correct its own recipe on the next turn.
static ICoreLLMMessage toolResult(const ICoreString& callId, const ICoreString& body, bool failed = false);
};
};
ICoreLLMTool#
ICoreLLMTypes.h:58 · struct · 0 declaration(s)
A tool the model may call.
struct ICoreLLMTool {
public:
ICoreString name;
ICoreString description;
ICoreJsonObject parametersSchema;
bool strict = true;
};
};
ICoreLLMUsage#
ICoreLLMTypes.h:65 · struct · 0 declaration(s)
struct ICoreLLMUsage {
public:
int inputTokens = 0;
int outputTokens = 0;
int cacheReadTokens = 0; // billed at a fraction of input; 0 when unsupported
int cacheWriteTokens = 0; // Anthropic only — OpenAI caching is implicit
};
};
ICoreLLMRequest#
ICoreLLMTypes.h:72 · struct · 1 declaration(s)
struct ICoreLLMRequest {
public:
ICoreString model; // empty => backend's defaultModel()
ICoreString systemPrompt; // the stable prefix: persona + block catalog
ICoreList<ICoreLLMMessage> messages;
ICoreList<ICoreLLMTool> tools;
int maxOutputTokens = 8192;
// Ask the provider to cache `systemPrompt` + `tools`. This is the whole
// reason the catalog is worth sending in full on every turn: the prefix is
// byte-identical across requests, so it bills at a fraction after the first
// write. It only holds if the caller keeps the prompt and the tool ORDER
// stable — a re-sorted tool list is a different prefix and silently costs
// full price. See ICoreCopilotContext for where that ordering is fixed.
bool cacheStablePrefix = true;
};
};
ICoreLLMResponse#
ICoreLLMTypes.h:88 · struct · 2 declaration(s)
struct ICoreLLMResponse {
public:
bool ok = false;
ICoreString text;
ICoreList<ICoreLLMToolCall> toolCalls;
ICoreLLMUsage usage;
// Normalized across providers: "end_turn", "tool_use", "max_tokens",
// "refusal", "cancelled", or "error".
ICoreString stopReason;
// Set when ok == false. Already human-readable — surface it through
// ICoreNotificationCenter as-is.
ICoreString failureReason;
bool hitTokenCeiling() const;
bool wantsToolCall() const;
};
};
File-scope declarations#
// Provider-neutral vocabulary shared by every ICoreLLMBackend implementation.
//
// The point of these types is that NOTHING above the backend layer — not the
// chat panel, not the recipe tool dispatcher — should ever know whether it is
// talking to OpenAI or Anthropic. Each backend owns the translation between
// these structs and its own wire format, and the two wire formats really are
enum class ICoreLLMRole {
System, // hoisted into the provider's system slot, never a messages[] entry
User,
Assistant,
Tool // a tool RESULT being handed back; pairs with toolCallId
};
ICoreOpenAIBackend.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/Backends/ICoreOpenAIBackend.h
ICoreOpenAIBackend#
ICoreOpenAIBackend.h:23 · class · bases public ICoreLLMBackend · pImpl · 8 declaration(s)
Chat Completions backend — POST {base}/v1/chat/completions.
class ICoreOpenAIBackend : public ICoreLLMBackend {
public:
ICoreOpenAIBackend();
~ICoreOpenAIBackend() override;
ICoreString providerId() const override;
ICoreString displayName() const override;
ICoreString defaultModel() const override;
ICoreStringList suggestedModels() const override;
protected:
void buildHttpRequest(const ICoreLLMRequest& request,
ICoreHttpRequest& httpRequest,
ICoreJsonObject& body) const override;
void handleStreamEvent(const ICoreString& eventName, const ICoreJsonObject& data) override;
void resetStreamState() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreCopilotConnectionDialog.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/UI/ICoreCopilotConnectionDialog.h
ICoreCopilotConnectionDialog#
ICoreCopilotConnectionDialog.h:28 · class · final · bases public ICoreDialog · pImpl · 2 declaration(s)
"Copilot Connection" -- the provider/model/key form, in a window of its own.
class ICoreCopilotConnectionDialog final : public ICoreDialog {
public:
explicit ICoreCopilotConnectionDialog(ICoreWidget* parent = nullptr);
// Declared, defined in the .cpp: the residue below is a unique_ptr to an
// Impl this header cannot see. (v9's note: a DUPLICATE out-of-line
// destructor is the fault to avoid here -- one declaration, one definition.)
~ICoreCopilotConnectionDialog() override;
// Relayed from the hosted form, live rather than on close.
ICoreSignal<> onSettingsChanged;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreCopilotConnectionSettings.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/UI/ICoreCopilotConnectionSettings.h
ICoreCopilotConnectionSettings#
ICoreCopilotConnectionSettings.h:26 · class · bases public ICoreWidget · pImpl · 3 declaration(s)
Connection settings for the copilot: which provider, which model, an optional endpoint override, and the API key.
class ICoreCopilotConnectionSettings : public ICoreWidget {
public:
// The parent is an ICoreAnyWidget: the one caller is
// ICoreCopilotConnectionDialog, which is an ICoreDialog and therefore not an
// ICoreWidget, so this cannot narrow.
// Q1.1 narrowed this -- see ICoreDialogButtonBox.h's twin note.
explicit ICoreCopilotConnectionSettings(ICoreNativeWidget* parent = nullptr);
// Declared, defined once in the .cpp: the residue below is a unique_ptr to
// an Impl this header cannot see.
~ICoreCopilotConnectionSettings() override;
// True when the active provider has a key stored. The chat panel refuses to
// send without one rather than surfacing a provider auth error.
static bool activeProviderHasKey();
ICoreSignal<> onSettingsChanged;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};
ICoreCopilotPanel.h#
src/ICoreSDK/ICoreStudio/StudioObjects/Panels/ICoreCopilot/UI/ICoreCopilotPanel.h
ICoreCopilotPanel#
ICoreCopilotPanel.h:43 · class · bases public ICoreWidget · pImpl · 3 declaration(s)
Left-panel page: a chat with the copilot about the diagram that is open.
class ICoreCopilotPanel : public ICoreWidget {
public:
explicit ICoreCopilotPanel(ICoreWidget* parent = nullptr);
// Out of line: the backend it owns is only forward-declared here.
~ICoreCopilotPanel() override;
protected:
// The panel lives in a stacked layout; refresh the readiness banner
// whenever it becomes the visible page, since the key may have been added
// or removed since it was last shown.
void shown() override;
private:
class Impl; // the two-line residue; state lives here
std::unique_ptr<Impl> impl;
};