{
	"plugin": "model-hub",
	"apiVersion": "0.4.0",
	"root": "HubApi",
	"declarations": "model-hub-api.d.ts",
	"entries": [
		{
			"name": "CAPABILITIES",
			"kind": "const",
			"exported": false,
			"signature": "declare const CAPABILITIES: readonly [\n    \"streaming\",\n    \"tools\",\n    \"structuredOutput\",\n    \"reasoning\",\n    \"webSearch\",\n    \"imageInput\",\n    \"pdfInput\",\n    \"embeddings\",\n    \"promptCaching\",\n    \"decisions\"\n];",
			"doc": ""
		},
		{
			"name": "Capability",
			"exported": true,
			"kind": "type",
			"signature": "type Capability = (typeof CAPABILITIES)[number];",
			"doc": "One thing a model can do. A call that needs a capability its model lacks is refused (`capability-missing`)."
		},
		{
			"name": "Pricing",
			"exported": true,
			"kind": "interface",
			"signature": "interface Pricing",
			"doc": "US dollars per token. `null` means the price is unknown.",
			"members": [
				{
					"name": "input",
					"kind": "property",
					"optional": false,
					"signature": "input: number | null",
					"doc": ""
				},
				{
					"name": "output",
					"kind": "property",
					"optional": false,
					"signature": "output: number | null",
					"doc": ""
				},
				{
					"name": "cacheRead",
					"kind": "property",
					"optional": true,
					"signature": "cacheRead?: number | null",
					"doc": ""
				},
				{
					"name": "cacheWrite",
					"kind": "property",
					"optional": true,
					"signature": "cacheWrite?: number | null",
					"doc": ""
				}
			]
		},
		{
			"name": "ModelInfo",
			"exported": true,
			"kind": "interface",
			"signature": "interface ModelInfo",
			"doc": "A model as the Hub knows it, from its provider's own listing. `models()` returns these for pickers.",
			"members": [
				{
					"name": "provider",
					"kind": "property",
					"optional": false,
					"signature": "provider: string",
					"doc": "The provider's id in the Hub, such as `openrouter` or `ollama`."
				},
				{
					"name": "id",
					"kind": "property",
					"optional": false,
					"signature": "id: string",
					"doc": "The model's id at that provider, as a candidate names it."
				},
				{
					"name": "label",
					"kind": "property",
					"optional": true,
					"signature": "label?: string",
					"doc": "A name to show; fall back to `id`."
				},
				{
					"name": "contextLength",
					"kind": "property",
					"optional": true,
					"signature": "contextLength?: number",
					"doc": "Context window in tokens, when the provider says."
				},
				{
					"name": "pricing",
					"kind": "property",
					"optional": false,
					"signature": "pricing: Pricing",
					"doc": ""
				},
				{
					"name": "capabilities",
					"kind": "property",
					"optional": false,
					"signature": "capabilities: Capability[]",
					"doc": ""
				}
			]
		},
		{
			"name": "BillingKind",
			"exported": true,
			"kind": "type",
			"signature": "type BillingKind = \"metered\" | \"local\" | \"subscription\";",
			"doc": "How a provider charges: per token, nothing (local), or a flat subscription."
		},
		{
			"name": "Usage",
			"exported": true,
			"kind": "interface",
			"signature": "interface Usage",
			"doc": "Tokens a call used, as the provider reported them.",
			"members": [
				{
					"name": "inputTokens",
					"kind": "property",
					"optional": false,
					"signature": "inputTokens: number",
					"doc": "All input tokens, cached ones included."
				},
				{
					"name": "outputTokens",
					"kind": "property",
					"optional": false,
					"signature": "outputTokens: number",
					"doc": "All output tokens, reasoning included."
				},
				{
					"name": "cacheReadTokens",
					"kind": "property",
					"optional": false,
					"signature": "cacheReadTokens: number",
					"doc": "Input tokens read from the provider's prompt cache."
				},
				{
					"name": "cacheWriteTokens",
					"kind": "property",
					"optional": false,
					"signature": "cacheWriteTokens: number",
					"doc": "Input tokens written to the provider's prompt cache."
				},
				{
					"name": "reasoningTokens",
					"kind": "property",
					"optional": false,
					"signature": "reasoningTokens: number",
					"doc": "Output tokens spent on reasoning."
				}
			]
		},
		{
			"name": "BUILTIN_TIERS",
			"kind": "const",
			"exported": true,
			"signature": "declare const BUILTIN_TIERS: readonly [\n    \"quick\",\n    \"balanced\",\n    \"careful\",\n    \"frontier\",\n    \"research\",\n    \"embedding\",\n    \"decision\"\n];",
			"doc": "The seven tiers every Hub has. They can't be deleted, and no custom tier may shadow one."
		},
		{
			"name": "BuiltinTierName",
			"exported": true,
			"kind": "type",
			"signature": "type BuiltinTierName = (typeof BUILTIN_TIERS)[number];",
			"doc": "The id of one of the seven built-in tiers."
		},
		{
			"name": "TierName",
			"exported": true,
			"kind": "type",
			"signature": "type TierName = string;",
			"doc": "A tier's id (a built-in tier's name, or a custom tier's id such as `clusters-bulk`); lookups also accept its name."
		},
		{
			"name": "TIER_NAMES",
			"kind": "const",
			"exported": true,
			"signature": "declare const TIER_NAMES: readonly [\n    \"quick\",\n    \"balanced\",\n    \"careful\",\n    \"frontier\",\n    \"research\",\n    \"embedding\",\n    \"decision\"\n];",
			"doc": "The name API 0.1–0.3 gave {@link BUILTIN_TIERS}; kept so their consumers still compile."
		},
		{
			"name": "DEFAULT_TIER",
			"kind": "const",
			"exported": true,
			"signature": "declare const DEFAULT_TIER: BuiltinTierName;",
			"doc": "What a role resolves to when it names neither a tier nor models, or names a tier that doesn't exist."
		},
		{
			"name": "isBuiltinTier",
			"exported": true,
			"kind": "function",
			"signature": "declare function isBuiltinTier(s: unknown): s is BuiltinTierName;",
			"doc": "True for the id of a built-in tier (`quick`, `balanced`…); false for a custom tier's id or any name."
		},
		{
			"name": "Candidate",
			"exported": true,
			"kind": "interface",
			"signature": "interface Candidate",
			"doc": "One model to try: a provider, a model, and how to call it.",
			"members": [
				{
					"name": "provider",
					"kind": "property",
					"optional": false,
					"signature": "provider: string",
					"doc": ""
				},
				{
					"name": "model",
					"kind": "property",
					"optional": false,
					"signature": "model: string",
					"doc": ""
				},
				{
					"name": "routing",
					"kind": "property",
					"optional": true,
					"signature": "routing?: Record<string, unknown>",
					"doc": "Provider-specific routing (OpenRouter: order, ignore, max_price, data policy, fallbackModels…)."
				},
				{
					"name": "reasoning",
					"kind": "property",
					"optional": true,
					"signature": "reasoning?: boolean",
					"doc": ""
				},
				{
					"name": "maxOutputTokens",
					"kind": "property",
					"optional": true,
					"signature": "maxOutputTokens?: number",
					"doc": ""
				},
				{
					"name": "contextTokens",
					"kind": "property",
					"optional": true,
					"signature": "contextTokens?: number",
					"doc": "Context length to ask a local model for (Ollama's num_ctx)."
				}
			]
		},
		{
			"name": "ModelPolicy",
			"exported": true,
			"kind": "interface",
			"signature": "interface ModelPolicy",
			"doc": "The models to try and the spending limits: what a tier holds, and what a role may carry of its own.",
			"members": [
				{
					"name": "candidates",
					"kind": "property",
					"optional": false,
					"signature": "candidates: Candidate[]",
					"doc": "Priority order: the first that can serve the call is used; a failed call moves to the next."
				},
				{
					"name": "ceilingUsd",
					"kind": "property",
					"optional": true,
					"signature": "ceilingUsd?: number",
					"doc": "Most a single call may cost, in US dollars."
				},
				{
					"name": "monthlyBudgetUsd",
					"kind": "property",
					"optional": true,
					"signature": "monthlyBudgetUsd?: number",
					"doc": "Most this may spend in a calendar month, in US dollars (metered calls only)."
				}
			]
		},
		{
			"name": "Tier",
			"exported": true,
			"kind": "type",
			"signature": "type Tier = ModelPolicy & {\n    id: string;\n    name: TierName;\n    custom: boolean;\n};",
			"doc": "A tier as listed: its policy, its stable `id` (a built-in tier's is its name; a custom tier's never\nchanges, even when it is renamed), its display `name`, and whether the user made it."
		},
		{
			"name": "DecisionInput",
			"exported": true,
			"kind": "type",
			"signature": "type DecisionInput = string | Record<string, unknown> | unknown[];",
			"doc": "Text, or structured data the question can refer to by field name in backticks."
		},
		{
			"name": "Question",
			"exported": true,
			"kind": "type",
			"signature": "type Question = {\n    type: \"noul\";\n    instructions: DecisionInput;\n    criteria?: {\n        true?: DecisionInput;\n        false?: DecisionInput;\n    };\n} | {\n    type: \"choice\";\n    instructions: DecisionInput;\n    criteria: Record<string, DecisionInput | null>;\n} | {\n    type: \"score\";\n    instructions: DecisionInput;\n    criteria: DecisionInput[];\n};",
			"doc": "One question about the state: yes/no (`noul`), pick one (`choice`) or rate on levels (`score`)."
		},
		{
			"name": "DecisionRequest",
			"exported": true,
			"kind": "interface",
			"signature": "interface DecisionRequest",
			"doc": "What `decide()` takes: the thing being judged, and the questions to answer about it.",
			"members": [
				{
					"name": "state",
					"kind": "property",
					"optional": false,
					"signature": "state: DecisionInput",
					"doc": "What the questions are about: text, or structured data."
				},
				{
					"name": "questions",
					"kind": "property",
					"optional": false,
					"signature": "questions: Record<string, Question>",
					"doc": "The questions, each under an id of your choosing; the answers come back under the same ids."
				}
			]
		},
		{
			"name": "Answer",
			"exported": true,
			"kind": "type",
			"signature": "type Answer = {\n    type: \"noul\";\n    noul: number;\n} | {\n    type: \"choice\";\n    choice: string;\n    probabilities: Record<string, number>;\n    confidence?: number;\n} | {\n    type: \"score\";\n    score: number;\n    legend: Record<string, string>;\n    probabilities: Record<string, number>;\n    confidence?: number;\n};",
			"doc": "The answer to one question, in the shape of its type."
		},
		{
			"name": "DecisionAnswers",
			"exported": false,
			"kind": "interface",
			"signature": "interface DecisionAnswers",
			"doc": "",
			"members": [
				{
					"name": "answers",
					"kind": "property",
					"optional": false,
					"signature": "answers: Record<string, Answer>",
					"doc": "One answer per question, under the question's id."
				},
				{
					"name": "calibrated",
					"kind": "property",
					"optional": false,
					"signature": "calibrated: boolean",
					"doc": "True when the probabilities come from a calibrated decision model (e.g. Jev), not a text model's single answer."
				},
				{
					"name": "usage",
					"kind": "property",
					"optional": false,
					"signature": "usage: {\n    inputTokens: number;\n    outputTokens: number;\n}",
					"doc": ""
				},
				{
					"name": "model",
					"kind": "property",
					"optional": true,
					"signature": "model?: string",
					"doc": "The model that answered, when the provider says."
				}
			]
		},
		{
			"name": "HubErrorCode",
			"exported": true,
			"kind": "type",
			"signature": "type HubErrorCode = \"invalid-role-name\" | \"invalid-skill\" | \"skill-taken\" | \"unknown-role\" | \"role-taken\" | \"unknown-tier\" | \"invalid-tier-name\" | \"unknown-provider\" | \"unknown-model\" | \"model-not-allowed\" | \"capability-missing\" | \"unpriced-model\" | \"over-ceiling\" | \"over-budget\" | \"no-models\" | \"invalid-request\" | \"provider-unavailable\" | \"provider-error\" | \"aborted\";",
			"doc": "Why the Hub refused or failed a call. Every refusal names its cause; nothing falls back silently."
		},
		{
			"name": "HubError",
			"exported": false,
			"kind": "class",
			"signature": "class HubError extends Error",
			"doc": "",
			"members": [
				{
					"name": "code",
					"kind": "property",
					"optional": false,
					"signature": "readonly code: HubErrorCode",
					"doc": "Why the call was refused or failed."
				},
				{
					"name": "details",
					"kind": "property",
					"optional": false,
					"signature": "readonly details: Record<string, unknown>",
					"doc": "Facts behind the refusal, by code: the role, the tier, the estimate and ceiling, what the model lacks (`missing`)…"
				}
			]
		},
		{
			"name": "LedgerRow",
			"exported": true,
			"kind": "interface",
			"signature": "interface LedgerRow",
			"doc": "One call, as the ledger records it. Refusals and failures are recorded too, at cost 0.",
			"members": [
				{
					"name": "id",
					"kind": "property",
					"optional": false,
					"signature": "id: string",
					"doc": ""
				},
				{
					"name": "time",
					"kind": "property",
					"optional": false,
					"signature": "time: string",
					"doc": ""
				},
				{
					"name": "plugin",
					"kind": "property",
					"optional": false,
					"signature": "plugin: string",
					"doc": ""
				},
				{
					"name": "role",
					"kind": "property",
					"optional": false,
					"signature": "role: string",
					"doc": ""
				},
				{
					"name": "tier",
					"kind": "property",
					"optional": true,
					"signature": "tier?: string",
					"doc": "The id of the tier the role resolved to."
				},
				{
					"name": "tierName",
					"kind": "property",
					"optional": true,
					"signature": "tierName?: string",
					"doc": "That tier's name at the time of the call."
				},
				{
					"name": "attempt",
					"kind": "property",
					"optional": true,
					"signature": "attempt?: number",
					"doc": "Which try this was, when the call fell back along its candidates (1 = the first candidate sent to)."
				},
				{
					"name": "routing",
					"kind": "property",
					"optional": true,
					"signature": "routing?: Record<string, unknown>",
					"doc": "Routing the caller added for this call, if any."
				},
				{
					"name": "for",
					"kind": "property",
					"optional": true,
					"signature": "for?: string",
					"doc": "What the call was about, as the calling plugin describes it."
				},
				{
					"name": "operation",
					"kind": "property",
					"optional": false,
					"signature": "operation: \"complete\" | \"stream\" | \"embed\" | \"decide\"",
					"doc": ""
				},
				{
					"name": "provider",
					"kind": "property",
					"optional": false,
					"signature": "provider: string",
					"doc": ""
				},
				{
					"name": "billing",
					"kind": "property",
					"optional": false,
					"signature": "billing: BillingKind",
					"doc": ""
				},
				{
					"name": "askedModel",
					"kind": "property",
					"optional": false,
					"signature": "askedModel: string",
					"doc": ""
				},
				{
					"name": "servedModel",
					"kind": "property",
					"optional": true,
					"signature": "servedModel?: string",
					"doc": ""
				},
				{
					"name": "servedProvider",
					"kind": "property",
					"optional": true,
					"signature": "servedProvider?: string",
					"doc": ""
				},
				{
					"name": "usage",
					"kind": "property",
					"optional": false,
					"signature": "usage: Usage",
					"doc": ""
				},
				{
					"name": "listedUsd",
					"kind": "property",
					"optional": false,
					"signature": "listedUsd: number | null",
					"doc": "US dollars at listed prices; null when the model has no listed price."
				},
				{
					"name": "billedUsd",
					"kind": "property",
					"optional": true,
					"signature": "billedUsd?: number",
					"doc": "US dollars the provider says it billed, when it says."
				},
				{
					"name": "overcharged",
					"kind": "property",
					"optional": false,
					"signature": "overcharged: boolean",
					"doc": ""
				},
				{
					"name": "durationMs",
					"kind": "property",
					"optional": false,
					"signature": "durationMs: number",
					"doc": ""
				},
				{
					"name": "outcome",
					"kind": "property",
					"optional": false,
					"signature": "outcome: \"ok\" | \"refused\" | \"failed\"",
					"doc": ""
				},
				{
					"name": "errorCode",
					"kind": "property",
					"optional": true,
					"signature": "errorCode?: HubErrorCode",
					"doc": ""
				},
				{
					"name": "errorMessage",
					"kind": "property",
					"optional": true,
					"signature": "errorMessage?: string",
					"doc": ""
				}
			]
		},
		{
			"name": "LedgerFilter",
			"exported": true,
			"kind": "interface",
			"signature": "interface LedgerFilter",
			"doc": "Which ledger rows `usage()` returns. Every field given must match; none returns every row.",
			"members": [
				{
					"name": "plugin",
					"kind": "property",
					"optional": true,
					"signature": "plugin?: string",
					"doc": "Calls made through this plugin's roles."
				},
				{
					"name": "role",
					"kind": "property",
					"optional": true,
					"signature": "role?: string",
					"doc": "Calls through this role."
				},
				{
					"name": "since",
					"kind": "property",
					"optional": true,
					"signature": "since?: string",
					"doc": "Calls at or after this time (ISO 8601)."
				},
				{
					"name": "until",
					"kind": "property",
					"optional": true,
					"signature": "until?: string",
					"doc": "Calls before this time (ISO 8601)."
				}
			]
		},
		{
			"name": "RoleDefinition",
			"exported": true,
			"kind": "interface",
			"signature": "interface RoleDefinition extends Partial<ModelPolicy>",
			"doc": "A role as a plugin registers it: a name, a description, and its model policy — a tier and/or its own\nordered candidates, a per-call ceiling and a monthly budget. The same schema as a tier.\n\nThe one-model form (`provider` + `model`, API 0.1) still works and becomes a one-candidate list.",
			"members": [
				{
					"name": "name",
					"kind": "property",
					"optional": false,
					"signature": "name: string",
					"doc": ""
				},
				{
					"name": "description",
					"kind": "property",
					"optional": true,
					"signature": "description?: string",
					"doc": ""
				},
				{
					"name": "tier",
					"kind": "property",
					"optional": true,
					"signature": "tier?: TierName",
					"doc": "The tier this role uses, built in or the user's own, by id or by name; `balanced` when it names none. A tier\nthat doesn't exist (yet) is kept as named: the role runs on `balanced`, flagged `tierMissing`, until it is made.\nStore the `id` `createTier` returns; a name keeps working across renames (old names stay as aliases)."
				},
				{
					"name": "allowAnyModel",
					"kind": "property",
					"optional": true,
					"signature": "allowAnyModel?: boolean",
					"doc": "Any model in the catalog may be picked for one run (interactive roles such as the chat panel's). Limits still apply."
				},
				{
					"name": "provider",
					"kind": "property",
					"optional": true,
					"signature": "provider?: string",
					"doc": "API 0.1: one provider and model."
				},
				{
					"name": "model",
					"kind": "property",
					"optional": true,
					"signature": "model?: string",
					"doc": ""
				},
				{
					"name": "reasoning",
					"kind": "property",
					"optional": true,
					"signature": "reasoning?: boolean",
					"doc": ""
				},
				{
					"name": "maxOutputTokens",
					"kind": "property",
					"optional": true,
					"signature": "maxOutputTokens?: number",
					"doc": ""
				},
				{
					"name": "contextTokens",
					"kind": "property",
					"optional": true,
					"signature": "contextTokens?: number",
					"doc": ""
				},
				{
					"name": "routing",
					"kind": "property",
					"optional": true,
					"signature": "routing?: Record<string, unknown>",
					"doc": ""
				},
				{
					"name": "allowedModels",
					"kind": "property",
					"optional": true,
					"signature": "allowedModels?: {\n    provider: string;\n    model: string;\n}[]",
					"doc": "API 0.1: models a caller may pick for one run."
				}
			]
		},
		{
			"name": "RoleOverride",
			"exported": true,
			"kind": "interface",
			"signature": "interface RoleOverride",
			"doc": "The user's setting for a role: any of a tier, own candidates and limits. `null` fields clear back to the plugin's default.",
			"members": [
				{
					"name": "tier",
					"kind": "property",
					"optional": true,
					"signature": "tier?: TierName",
					"doc": ""
				},
				{
					"name": "candidates",
					"kind": "property",
					"optional": true,
					"signature": "candidates?: Candidate[]",
					"doc": ""
				},
				{
					"name": "ceilingUsd",
					"kind": "property",
					"optional": true,
					"signature": "ceilingUsd?: number | null",
					"doc": ""
				},
				{
					"name": "monthlyBudgetUsd",
					"kind": "property",
					"optional": true,
					"signature": "monthlyBudgetUsd?: number | null",
					"doc": ""
				}
			]
		},
		{
			"name": "RoleSpec",
			"exported": true,
			"kind": "interface",
			"signature": "interface RoleSpec",
			"doc": "A role's settings after the plugin's default and the user's override are combined.",
			"members": [
				{
					"name": "name",
					"kind": "property",
					"optional": false,
					"signature": "name: string",
					"doc": ""
				},
				{
					"name": "owner",
					"kind": "property",
					"optional": false,
					"signature": "owner: string",
					"doc": ""
				},
				{
					"name": "description",
					"kind": "property",
					"optional": true,
					"signature": "description?: string",
					"doc": ""
				},
				{
					"name": "tier",
					"kind": "property",
					"optional": false,
					"signature": "tier: TierName",
					"doc": ""
				},
				{
					"name": "candidates",
					"kind": "property",
					"optional": false,
					"signature": "candidates: Candidate[]",
					"doc": "The role's own candidates; empty means \"the tier's\"."
				},
				{
					"name": "ceilingUsd",
					"kind": "property",
					"optional": true,
					"signature": "ceilingUsd?: number",
					"doc": ""
				},
				{
					"name": "monthlyBudgetUsd",
					"kind": "property",
					"optional": true,
					"signature": "monthlyBudgetUsd?: number",
					"doc": ""
				},
				{
					"name": "allowAnyModel",
					"kind": "property",
					"optional": false,
					"signature": "allowAnyModel: boolean",
					"doc": ""
				},
				{
					"name": "allowedModels",
					"kind": "property",
					"optional": false,
					"signature": "allowedModels: {\n    provider: string;\n    model: string;\n}[]",
					"doc": ""
				},
				{
					"name": "overridden",
					"kind": "property",
					"optional": false,
					"signature": "overridden: boolean",
					"doc": "True when the user has changed anything."
				}
			]
		},
		{
			"name": "ResolvedRole",
			"exported": true,
			"kind": "interface",
			"signature": "interface ResolvedRole extends RoleSpec",
			"doc": "What a call through a role uses: the candidates to try, and every limit that applies.",
			"members": [
				{
					"name": "effective",
					"kind": "property",
					"optional": false,
					"signature": "effective: Candidate[]",
					"doc": "The candidates to try, in order (the role's own, else the tier's)."
				},
				{
					"name": "ceilings",
					"kind": "property",
					"optional": false,
					"signature": "ceilings: number[]",
					"doc": "Every per-call ceiling that applies (role and tier); a call must fit all of them."
				},
				{
					"name": "budgets",
					"kind": "property",
					"optional": false,
					"signature": "budgets: {\n    scope: \"role\" | \"tier\";\n    limitUsd: number;\n}[]",
					"doc": "Every monthly budget that applies."
				},
				{
					"name": "tierName",
					"kind": "property",
					"optional": false,
					"signature": "tierName: string",
					"doc": "The display name of the tier `tier` is the id of."
				},
				{
					"name": "tierMissing",
					"kind": "property",
					"optional": true,
					"signature": "tierMissing?: true",
					"doc": "Set when the role names a tier that doesn't exist (a deleted or not-yet-made custom tier): it runs on `balanced`."
				},
				{
					"name": "missingTier",
					"kind": "property",
					"optional": true,
					"signature": "missingTier?: TierName",
					"doc": "The tier the role names (as it names it) but that doesn't exist."
				}
			]
		},
		{
			"name": "CallOptionsBase",
			"exported": false,
			"kind": "interface",
			"signature": "interface CallOptionsBase",
			"doc": "",
			"members": [
				{
					"name": "tier",
					"kind": "property",
					"optional": true,
					"signature": "tier?: TierName",
					"doc": "Use this tier's models and limits for one run instead of the role's (roles that allow any model)."
				},
				{
					"name": "routing",
					"kind": "property",
					"optional": true,
					"signature": "routing?: Record<string, unknown>",
					"doc": "Routing merged into every candidate's own routing for this call (OpenRouter: pin or exclude providers, a price cap…).\nRecorded in the ledger."
				},
				{
					"name": "candidates",
					"kind": "property",
					"optional": true,
					"signature": "candidates?: Candidate[]",
					"doc": "This call's own ordered candidates (roles that allow any model). Limits still apply."
				},
				{
					"name": "model",
					"kind": "property",
					"optional": true,
					"signature": "model?: {\n    provider: string;\n    model: string;\n}",
					"doc": "Use this model for one run instead of the role's candidates (no fallback). It must be one of the role's candidates, or the role must allow any model."
				},
				{
					"name": "for",
					"kind": "property",
					"optional": true,
					"signature": "for?: string",
					"doc": "What the call is about, for the ledger."
				},
				{
					"name": "signal",
					"kind": "property",
					"optional": true,
					"signature": "signal?: AbortSignal",
					"doc": "Stops the call; it then rejects with `aborted`."
				}
			]
		},
		{
			"name": "CompleteOptions",
			"exported": true,
			"kind": "interface",
			"signature": "interface CompleteOptions extends CallOptionsBase",
			"doc": "Options for `complete()`.",
			"members": [
				{
					"name": "system",
					"kind": "property",
					"optional": true,
					"signature": "system?: string",
					"doc": "The system prompt. Skills' text goes before it."
				},
				{
					"name": "maxOutputTokens",
					"kind": "property",
					"optional": true,
					"signature": "maxOutputTokens?: number",
					"doc": "The longest reply allowed (default 4096). The per-call ceiling is checked against the cost of a reply this long."
				},
				{
					"name": "tools",
					"kind": "property",
					"optional": true,
					"signature": "tools?: ToolSet",
					"doc": "Tools the model may call. They are returned, not run: v1 is single-turn."
				},
				{
					"name": "output",
					"kind": "property",
					"optional": true,
					"signature": "output?: FlexibleSchema<unknown>",
					"doc": "A schema (zod or JSON Schema) the reply must match."
				},
				{
					"name": "webSearch",
					"kind": "property",
					"optional": true,
					"signature": "webSearch?: boolean",
					"doc": "Let the provider search the web; the model must have `webSearch`. Sources come back in `sources`."
				},
				{
					"name": "needs",
					"kind": "property",
					"optional": true,
					"signature": "needs?: Capability[]",
					"doc": "Capabilities the caller needs beyond what the options imply."
				},
				{
					"name": "skills",
					"kind": "property",
					"optional": true,
					"signature": "skills?: string[]",
					"doc": "Skills to apply, by name. When given (even empty), the always-on skills join them; their text goes\nbefore `system`, and what they require of the model is checked like any other capability."
				}
			]
		},
		{
			"name": "StreamOptions",
			"exported": true,
			"kind": "type",
			"signature": "type StreamOptions = Omit<CompleteOptions, \"output\">;",
			"doc": "Options for `stream()`: those of `complete()`, without structured output."
		},
		{
			"name": "EmbedOptions",
			"exported": true,
			"kind": "type",
			"signature": "type EmbedOptions = CallOptionsBase;",
			"doc": "Options for `embed()`."
		},
		{
			"name": "DecideOptions",
			"exported": true,
			"kind": "type",
			"signature": "type DecideOptions = CallOptionsBase;",
			"doc": "Options for `decide()`."
		},
		{
			"name": "Attempt",
			"exported": true,
			"kind": "interface",
			"signature": "interface Attempt",
			"doc": "One candidate the call considered: skipped before sending, sent and failed, or the one that answered.",
			"members": [
				{
					"name": "provider",
					"kind": "property",
					"optional": false,
					"signature": "provider: string",
					"doc": ""
				},
				{
					"name": "model",
					"kind": "property",
					"optional": false,
					"signature": "model: string",
					"doc": ""
				},
				{
					"name": "outcome",
					"kind": "property",
					"optional": false,
					"signature": "outcome: \"skipped\" | \"failed\" | \"ok\"",
					"doc": ""
				},
				{
					"name": "code",
					"kind": "property",
					"optional": true,
					"signature": "code?: HubErrorCode",
					"doc": ""
				},
				{
					"name": "reason",
					"kind": "property",
					"optional": true,
					"signature": "reason?: string",
					"doc": ""
				}
			]
		},
		{
			"name": "BudgetStatus",
			"exported": true,
			"kind": "interface",
			"signature": "interface BudgetStatus",
			"doc": "One monthly budget that applies to a call, and how much of it is spent.",
			"members": [
				{
					"name": "scope",
					"kind": "property",
					"optional": false,
					"signature": "scope: \"role\" | \"tier\"",
					"doc": "Whether the budget is the role's own or its tier's."
				},
				{
					"name": "spentUsd",
					"kind": "property",
					"optional": false,
					"signature": "spentUsd: number",
					"doc": "Spent this calendar month, before this call."
				},
				{
					"name": "limitUsd",
					"kind": "property",
					"optional": false,
					"signature": "limitUsd: number",
					"doc": ""
				},
				{
					"name": "warn",
					"kind": "property",
					"optional": false,
					"signature": "warn: boolean",
					"doc": "Spent at least 80% of the limit."
				}
			]
		},
		{
			"name": "CallReport",
			"exported": true,
			"kind": "interface",
			"signature": "interface CallReport",
			"doc": "What every finished call reports: who served it, the usage, the cost, and how it got there.",
			"members": [
				{
					"name": "provider",
					"kind": "property",
					"optional": false,
					"signature": "provider: string",
					"doc": ""
				},
				{
					"name": "billing",
					"kind": "property",
					"optional": false,
					"signature": "billing: LedgerRow[\"billing\"]",
					"doc": "How the provider charges: per token, nothing (local) or a subscription."
				},
				{
					"name": "askedModel",
					"kind": "property",
					"optional": false,
					"signature": "askedModel: string",
					"doc": ""
				},
				{
					"name": "servedModel",
					"kind": "property",
					"optional": true,
					"signature": "servedModel?: string",
					"doc": ""
				},
				{
					"name": "servedProvider",
					"kind": "property",
					"optional": true,
					"signature": "servedProvider?: string",
					"doc": ""
				},
				{
					"name": "usage",
					"kind": "property",
					"optional": false,
					"signature": "usage: Usage",
					"doc": ""
				},
				{
					"name": "listedUsd",
					"kind": "property",
					"optional": false,
					"signature": "listedUsd: number | null",
					"doc": "US dollars at listed prices (for a subscription: the API-price equivalent); null when unknown."
				},
				{
					"name": "billedUsd",
					"kind": "property",
					"optional": true,
					"signature": "billedUsd?: number",
					"doc": ""
				},
				{
					"name": "overcharged",
					"kind": "property",
					"optional": false,
					"signature": "overcharged: boolean",
					"doc": ""
				},
				{
					"name": "durationMs",
					"kind": "property",
					"optional": false,
					"signature": "durationMs: number",
					"doc": ""
				},
				{
					"name": "ledgerId",
					"kind": "property",
					"optional": false,
					"signature": "ledgerId: string",
					"doc": ""
				},
				{
					"name": "tier",
					"kind": "property",
					"optional": false,
					"signature": "tier: TierName",
					"doc": ""
				},
				{
					"name": "attempts",
					"kind": "property",
					"optional": false,
					"signature": "attempts: Attempt[]",
					"doc": "Every candidate considered, in order."
				},
				{
					"name": "fellBack",
					"kind": "property",
					"optional": false,
					"signature": "fellBack: boolean",
					"doc": "True when the answer didn't come from the first candidate."
				},
				{
					"name": "budgets",
					"kind": "property",
					"optional": false,
					"signature": "budgets: BudgetStatus[]",
					"doc": "Monthly budgets that apply, with this month's spend before this call."
				}
			]
		},
		{
			"name": "CompleteResult",
			"exported": true,
			"kind": "interface",
			"signature": "interface CompleteResult extends CallReport",
			"doc": "What `complete()` resolves to: the reply, and the call's report.",
			"members": [
				{
					"name": "text",
					"kind": "property",
					"optional": false,
					"signature": "text: string",
					"doc": "The reply's text."
				},
				{
					"name": "object",
					"kind": "property",
					"optional": true,
					"signature": "object?: unknown",
					"doc": "The reply as data, when the call gave an `output` schema."
				},
				{
					"name": "toolCalls",
					"kind": "property",
					"optional": false,
					"signature": "toolCalls: {\n    toolName: string;\n    input: unknown;\n}[]",
					"doc": "Tools the model asked to call. The Hub returns them; it doesn't run them."
				},
				{
					"name": "sources",
					"kind": "property",
					"optional": false,
					"signature": "sources: {\n    url: string;\n    title?: string;\n}[]",
					"doc": "Web pages the reply drew on, when the call searched the web."
				},
				{
					"name": "finishReason",
					"kind": "property",
					"optional": false,
					"signature": "finishReason: string",
					"doc": "Why the model stopped, as the provider reports it (`stop`, `length`, `tool-calls`…)."
				},
				{
					"name": "skills",
					"kind": "property",
					"optional": true,
					"signature": "skills?: {\n    included: string[];\n    dropped: string[];\n}",
					"doc": "Skills that went into the request, and any left out for size."
				}
			]
		},
		{
			"name": "StreamResult",
			"exported": true,
			"kind": "interface",
			"signature": "interface StreamResult",
			"doc": "What `stream()` returns at once: the text as it arrives, and a promise of the full result.",
			"members": [
				{
					"name": "textStream",
					"kind": "property",
					"optional": false,
					"signature": "textStream: AsyncIterable<string>",
					"doc": "Text as it arrives. Ends with a HubError if the call fails or is stopped."
				},
				{
					"name": "result",
					"kind": "property",
					"optional": false,
					"signature": "result: Promise<CompleteResult>",
					"doc": "Resolves when the stream ends, with the full result; rejects with a HubError."
				}
			]
		},
		{
			"name": "EmbedResult",
			"exported": true,
			"kind": "interface",
			"signature": "interface EmbedResult extends CallReport",
			"doc": "What `embed()` resolves to.",
			"members": [
				{
					"name": "embeddings",
					"kind": "property",
					"optional": false,
					"signature": "embeddings: number[][]",
					"doc": "One vector per input text, in order."
				}
			]
		},
		{
			"name": "DecideResult",
			"exported": true,
			"kind": "interface",
			"signature": "interface DecideResult extends CallReport, Pick<DecisionAnswers, \"answers\" | \"calibrated\">",
			"doc": "What `decide()` resolves to: the answers, whether they are calibrated, and the call's report.",
			"members": []
		},
		{
			"name": "BatchOptions",
			"exported": true,
			"kind": "interface",
			"signature": "interface BatchOptions",
			"doc": "Options for `batch()`.",
			"members": [
				{
					"name": "concurrency",
					"kind": "property",
					"optional": true,
					"signature": "concurrency?: number",
					"doc": "Calls running at once (default 4)."
				},
				{
					"name": "stopOnOvercharge",
					"kind": "property",
					"optional": true,
					"signature": "stopOnOvercharge?: boolean",
					"doc": "Stop the batch when a call is billed well above its listed price (default true)."
				},
				{
					"name": "maxSpendUsd",
					"kind": "property",
					"optional": true,
					"signature": "maxSpendUsd?: number",
					"doc": "Stop the batch once this much has been spent, in US dollars."
				},
				{
					"name": "signal",
					"kind": "property",
					"optional": true,
					"signature": "signal?: AbortSignal",
					"doc": "Stops the whole batch."
				},
				{
					"name": "onProgress",
					"kind": "property",
					"optional": true,
					"signature": "onProgress?: (p: BatchProgress) => void",
					"doc": "Called after each item finishes or fails."
				}
			]
		},
		{
			"name": "BatchProgress",
			"exported": true,
			"kind": "interface",
			"signature": "interface BatchProgress",
			"doc": "How far a batch has got.",
			"members": [
				{
					"name": "done",
					"kind": "property",
					"optional": false,
					"signature": "done: number",
					"doc": "Items finished, failures included."
				},
				{
					"name": "total",
					"kind": "property",
					"optional": false,
					"signature": "total: number",
					"doc": ""
				},
				{
					"name": "failed",
					"kind": "property",
					"optional": false,
					"signature": "failed: number",
					"doc": "Items whose call rejected."
				},
				{
					"name": "spentUsd",
					"kind": "property",
					"optional": false,
					"signature": "spentUsd: number",
					"doc": "Spent so far: each call's billed cost, or its listed cost when the provider reports none."
				}
			]
		},
		{
			"name": "BatchResult",
			"exported": true,
			"kind": "interface",
			"signature": "interface BatchResult<R>",
			"doc": "What `batch()` resolves to. It doesn't reject when calls fail: each failure is in `results`.",
			"members": [
				{
					"name": "results",
					"kind": "property",
					"optional": false,
					"signature": "results: (R | HubError | undefined)[]",
					"doc": "One entry per item, in order: the result, the error, or undefined when the batch stopped before it."
				},
				{
					"name": "progress",
					"kind": "property",
					"optional": false,
					"signature": "progress: BatchProgress",
					"doc": "The final count and spend."
				},
				{
					"name": "stopped",
					"kind": "property",
					"optional": true,
					"signature": "stopped?: {\n    reason: \"overcharge\" | \"spend-limit\" | \"aborted\";\n    index: number;\n    message: string;\n}",
					"doc": "Why the batch stopped early, if it did."
				}
			]
		},
		{
			"name": "SkillRegistration",
			"exported": true,
			"kind": "interface",
			"signature": "interface SkillRegistration",
			"doc": "A skill a plugin registers: its folder's text files, by relative path, `SKILL.md` among them.",
			"members": [
				{
					"name": "files",
					"kind": "property",
					"optional": false,
					"signature": "files: Record<string, string>",
					"doc": ""
				}
			]
		},
		{
			"name": "HUB_READY_EVENT",
			"kind": "const",
			"exported": true,
			"signature": "declare const HUB_READY_EVENT = \"model-hub:ready\";",
			"doc": "The workspace event the Hub fires each time it loads, with its API: at startup, and when the user disables\nand enables it again. A new Hub starts with no registered skills, so consumers register theirs again on it."
		},
		{
			"name": "isCompatible",
			"exported": true,
			"kind": "function",
			"signature": "declare function isCompatible(actual: string, wanted: string): boolean;",
			"doc": "True when a consumer built against `wanted` can use an API at `actual`: same major and a minor at least\nas new. Before 1.0, minors break by default, so a 0.x Hub serves only the minors it promises (0.1 and up)."
		},
		{
			"name": "HUB_PLUGIN_ID",
			"kind": "const",
			"exported": true,
			"signature": "declare const HUB_PLUGIN_ID = \"model-hub\";",
			"doc": "Model Hub's plugin id, as `app.plugins.getPlugin` knows it."
		},
		{
			"name": "SkillSummary",
			"exported": true,
			"kind": "interface",
			"signature": "interface SkillSummary",
			"doc": "A skill as `skills()` lists it.",
			"members": [
				{
					"name": "name",
					"kind": "property",
					"optional": false,
					"signature": "name: string",
					"doc": "The name a call puts in `skills`."
				},
				{
					"name": "description",
					"kind": "property",
					"optional": false,
					"signature": "description: string",
					"doc": "What the skill is for, from its `SKILL.md`."
				},
				{
					"name": "mode",
					"kind": "property",
					"optional": false,
					"signature": "mode: \"always\" | \"chosen\"",
					"doc": "`always` skills join every call that asks for skills. Only the user's vault skills may be `always`."
				},
				{
					"name": "requires",
					"kind": "property",
					"optional": false,
					"signature": "requires: Capability[]",
					"doc": "What a model must be able to do for this skill to be used."
				},
				{
					"name": "origin",
					"kind": "property",
					"optional": false,
					"signature": "origin: \"builtin\" | \"vault\"",
					"doc": "`builtin`: shipped with the Hub or registered by a plugin (see `plugin`); `vault`: in the user's skills folder."
				},
				{
					"name": "plugin",
					"kind": "property",
					"optional": true,
					"signature": "plugin?: string",
					"doc": "The plugin that registered this skill with `registerSkills`. (Since 0.4.)",
					"since": "0.4"
				},
				{
					"name": "extends",
					"kind": "property",
					"optional": true,
					"signature": "extends?: string",
					"doc": "A skill this one layers on; its instructions are included before this one's."
				},
				{
					"name": "extendsMissing",
					"kind": "property",
					"optional": true,
					"signature": "extendsMissing?: boolean",
					"doc": "`extends` names a skill that isn't loaded (for example, the plugin that registers it is off). (Since 0.4.)",
					"since": "0.4"
				},
				{
					"name": "files",
					"kind": "method",
					"optional": false,
					"signature": "files(): Promise<Record<string, string>>",
					"doc": "The skill's own text files, by path relative to its folder (`reader.yml`, `prompts/extract.md`), recursive,\nwithout `SKILL.md`. A vault skill's are read from the vault at each call, so edits show at once. Only this\nskill's files: a parent's (`extends`) are the parent's `files()`; merging them is up to you. (Since 0.4.)",
					"since": "0.4"
				}
			]
		},
		{
			"name": "HubApi",
			"exported": true,
			"kind": "interface",
			"signature": "interface HubApi",
			"doc": "The Hub, as `getHub` returns it. Every call another plugin makes goes through this.",
			"members": [
				{
					"name": "version",
					"kind": "property",
					"optional": false,
					"signature": "readonly version: string",
					"doc": "Semantic version of this API. Check it with `isCompatible` (or use `getHub`)."
				},
				{
					"name": "registerRoles",
					"kind": "method",
					"optional": false,
					"signature": "registerRoles(pluginId: string, roles: RoleDefinition[]): void",
					"doc": "Declares the roles your plugin uses. Each role names a tier (default `balanced`) and/or its own ordered\ncandidates, with an optional per-call ceiling and monthly budget. The first plugin to use a namespace owns it.\nA custom tier is named by id or by name: store the `id` `createTier` returns; names keep working across\nrenames via aliases (a renamed tier keeps its old names, and its id reads as the name it was made with).\nHarmless to repeat, for example on `model-hub:ready` (see `onHubReady`)."
				},
				{
					"name": "roles",
					"kind": "method",
					"optional": false,
					"signature": "roles(pluginId: string): ResolvedRole[]",
					"doc": "Your plugin's roles, with the tier, candidates and limits each resolves to now. `tier` is the id of the tier\na role runs on. A role may name a tier by id or by name (in `registerRoles` or `setRole`): store the `id`\n`createTier` returns; names keep working across renames via aliases. When the tier it names doesn't exist\n(not made yet, or deleted), it runs on `balanced` and comes back with `tierMissing: true` and `missingTier`\nholding the name as given. (Since 0.4; before, an unknown tier became `balanced` unflagged.)",
					"since": "0.4"
				},
				{
					"name": "setRole",
					"kind": "method",
					"optional": false,
					"signature": "setRole(pluginId: string, role: string, override: RoleOverride | null): void",
					"doc": "Changes one of your roles (a tier, own candidates, limits); `null` puts it back to your default. Only the owning plugin may."
				},
				{
					"name": "openRoleEditor",
					"kind": "method",
					"optional": false,
					"signature": "openRoleEditor(pluginId: string): void",
					"doc": "Opens the Hub's role editor for your plugin's roles: one consistent screen, no UI to write."
				},
				{
					"name": "tiers",
					"kind": "method",
					"optional": false,
					"signature": "tiers(): Tier[]",
					"doc": "Every tier as the user has set them (candidates, ceiling, monthly budget): the seven built-in tiers first,\nthen the user's own in the order they were made. Each has a stable `id` (a built-in tier's is its name; a\ncustom tier's never changes, even when the user renames it), a display `name`, and `custom`."
				},
				{
					"name": "createTier",
					"kind": "method",
					"optional": false,
					"signature": "createTier(pluginId: string, name: string, policy: ModelPolicy): Promise<Tier | null>",
					"doc": "Asks the user to add a tier of their own: the Hub opens a dialog naming your plugin (the id is as you\ndeclare it; the dialog shows the name from that plugin's manifest, or \"(unknown plugin)\" when no installed\nplugin has that id) and showing the tier's\nmodels and limits, which the user may change before confirming. Resolves to the tier made (its name may be\nthe user's), or `null` if the user declines. Rejects with a HubError for a name that is taken, empty, over\n40 characters or a built-in tier's (`invalid-tier-name`), or a malformed policy (`invalid-request`)."
				},
				{
					"name": "deleteTier",
					"kind": "method",
					"optional": false,
					"signature": "deleteTier(pluginId: string, id: string): Promise<boolean>",
					"doc": "Asks the user to delete a tier of their own (by id, or name): the Hub's dialog names your plugin as\n`createTier`'s does (the id is self-declared) and lists the roles mapped to it,\nand each the user moved there goes back to its plugin's default. Resolves `true` once deleted, `false` if the\nuser declines. Rejects for an unknown tier (`unknown-tier`) or a built-in one (`invalid-request`)."
				},
				{
					"name": "complete",
					"kind": "method",
					"optional": false,
					"signature": "complete(role: string, messages: ModelMessage[], opts?: CompleteOptions): Promise<CompleteResult>",
					"doc": "One call through a role. Rejects with an error whose `code` is a HubErrorCode."
				},
				{
					"name": "stream",
					"kind": "method",
					"optional": false,
					"signature": "stream(role: string, messages: ModelMessage[], opts?: StreamOptions): StreamResult",
					"doc": "The same, streamed."
				},
				{
					"name": "decide",
					"kind": "method",
					"optional": false,
					"signature": "decide(role: string, request: DecisionRequest, opts?: DecideOptions): Promise<DecideResult>",
					"doc": "Typed decisions about a state: yes/no (`noul`), pick one (`choice`), rate on levels (`score`). Through a\nrole on the decision tier; `calibrated` says whether the probabilities come from a decision model (Jev)."
				},
				{
					"name": "batch",
					"kind": "method",
					"optional": false,
					"signature": "batch<T, R extends {\n    billedUsd?: number;\n    listedUsd: number | null;\n    overcharged: boolean;\n}>(items: T[], fn: (item: T, signal: AbortSignal) => Promise<R>, opts?: BatchOptions): Promise<BatchResult<R>>",
					"doc": "Runs many calls with limited concurrency, reporting progress and cost, and stops early when a call is\novercharged, a spend limit is reached or the signal aborts. Pass the given signal to each Hub call."
				},
				{
					"name": "embed",
					"kind": "method",
					"optional": false,
					"signature": "embed(role: string, values: string[], opts?: EmbedOptions): Promise<EmbedResult>",
					"doc": "Embeddings for a batch of texts."
				},
				{
					"name": "models",
					"kind": "method",
					"optional": false,
					"signature": "models(filter?: {\n    provider?: string;\n    needs?: Capability[];\n}): ModelInfo[]",
					"doc": "Models the Hub knows, filtered by provider or by what they can do (for pickers)."
				},
				{
					"name": "skills",
					"kind": "method",
					"optional": false,
					"signature": "skills(): SkillSummary[]",
					"doc": "Skills the Hub can apply (name them in `skills` on a call): the Hub's own, those plugins registered, and the\nvault's. Vault skills arrive at layout-ready: await `skillsReady()` before relying on them."
				},
				{
					"name": "registerSkills",
					"kind": "method",
					"optional": false,
					"signature": "registerSkills(pluginId: string, skills: SkillRegistration[]): void",
					"doc": "Registers your plugin's built-in skills, each as its folder's text files: `{ files: { 'SKILL.md': …,\n'reader.yml': …, 'prompts/extract.md': … } }`. Replaces what your plugin registered before (`[]` removes\nthem). They stay through every reload of the vault skills, and are removed when your plugin unloads. A\nvault skill of the same name overrides one; a name belongs to the first plugin to register it. Throws a\nHubError: `skill-taken` (another plugin's, or the Hub's own), `invalid-skill` (no or bad SKILL.md, a path\noutside the folder, a name given twice, `mode: always`: a plugin's skill is used only when a call names it;\nthe user can make a vault copy always-on), `invalid-request` (no plugin id). (Since 0.4.)\n\nRegistrations live in the Hub that is loaded: when the user disables and enables Model Hub, the new Hub\nstarts without them and fires `model-hub:ready` on the workspace. Register again then: `onHubReady` (below\n`getHub`) does both, or `this.registerEvent(this.app.workspace.on('model-hub:ready', (api) => …))`.",
					"since": "0.4"
				},
				{
					"name": "skillsReady",
					"kind": "method",
					"optional": false,
					"signature": "skillsReady(): Promise<void>",
					"doc": "Resolves once the vault's skills have loaded (at layout-ready); registered skills are there as soon as registered. (Since 0.4.)",
					"since": "0.4"
				},
				{
					"name": "onSkillsChanged",
					"kind": "method",
					"optional": false,
					"signature": "onSkillsChanged(cb: () => void): () => void",
					"doc": "Calls `cb` whenever the skills change: a plugin registers or unregisters, or the skills folder is edited\n(files included) or reloaded. Returns the function that stops it; pass it to `this.register()`. (Since 0.4.)",
					"since": "0.4"
				},
				{
					"name": "usage",
					"kind": "method",
					"optional": false,
					"signature": "usage(filter?: LedgerFilter): Promise<LedgerRow[]>",
					"doc": "Ledger rows: every call, with tokens and cost."
				}
			]
		},
		{
			"name": "GetHubResult",
			"exported": true,
			"kind": "type",
			"signature": "type GetHubResult = {\n    hub: HubApi;\n} | {\n    hub: null;\n    reason: \"missing\" | \"incompatible\";\n    message: string;\n    version?: string;\n};",
			"doc": "What `getHub` returns: the Hub, or why there isn't one, with a `message` to show the user."
		},
		{
			"name": "getHub",
			"exported": true,
			"kind": "function",
			"signature": "declare function getHub(app: unknown, wanted: string): GetHubResult;",
			"doc": "Finds the Hub in this vault and checks its API version against the one you built for. The Hub may be\ndisabled and enabled again while your plugin runs, and the new Hub has none of your registered skills: listen\nfor `model-hub:ready` (or use `onHubReady`) and call `getHub` + `registerSkills` again there."
		},
		{
			"name": "onHubReady",
			"exported": true,
			"kind": "function",
			"signature": "declare function onHubReady(app: unknown, plugin: {\n    registerEvent(ref: unknown): void;\n}, wanted: string, cb: (hub: HubApi) => void): void;",
			"doc": "Runs `cb` with the Hub now if it is loaded (and compatible with `wanted`), and again each time the Hub loads:\nthe Hub fires `model-hub:ready` on the workspace when it loads, and one disabled and enabled again starts with\nno registered skills. Do your `registerSkills` (and `registerRoles`, harmless to repeat) in `cb`, on the hub it\nis given. The listener is registered on your plugin, so it stops when your plugin unloads. (Since 0.4.)\n\n```ts\nonHubReady(this.app, this, '0.4.0', (hub) => hub.registerSkills(this.manifest.id, MY_SKILLS));\n```\n\nWithout the helper: `this.registerEvent(this.app.workspace.on('model-hub:ready', (api) => …))`, checking\n`api.version` with `isCompatible`.",
			"since": "0.4"
		}
	]
}
