agent-relay-providers 0.104.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/claude.ts ADDED
@@ -0,0 +1,129 @@
1
+ import { registerProvider } from "./registry.js";
2
+ import type { ProviderManifest, ProviderModelCapabilities, ProviderModelLimits } from "./types.js";
3
+
4
+ const CLAUDE_LOW_TO_MAX = ["low", "medium", "high", "max"];
5
+ const CLAUDE_LOW_TO_XHIGH_MAX = ["low", "medium", "high", "xhigh", "max"];
6
+ const CONTEXT_200K = { value: 200_000, source: "catalog", confidence: "declared" } as const;
7
+ const CONTEXT_1M = { value: 1_000_000, source: "catalog", confidence: "declared" } as const;
8
+ const CODE_MODEL_CAPABILITIES: ProviderModelCapabilities = {
9
+ modalities: {
10
+ input: { text: true, image: true },
11
+ output: { text: true },
12
+ },
13
+ tools: {
14
+ code: true,
15
+ review: true,
16
+ debug: true,
17
+ refactor: true,
18
+ },
19
+ source: "catalog",
20
+ confidence: "declared",
21
+ };
22
+ const quotaWindows = [
23
+ { name: "five_hour", unit: "%", reset: true },
24
+ { name: "seven_day", unit: "%", reset: true },
25
+ ] as const;
26
+
27
+ function codeModel(limits?: ProviderModelLimits): Pick<NonNullable<ProviderManifest["catalog"]["models"][number]>, "limits" | "capabilities"> {
28
+ return {
29
+ ...(limits ? { limits } : {}),
30
+ capabilities: CODE_MODEL_CAPABILITIES,
31
+ };
32
+ }
33
+
34
+ export const claudeProviderManifest = {
35
+ id: "claude",
36
+ label: "Claude",
37
+ icon: "🟠",
38
+ launch: {
39
+ managedPolicyPrompt: {
40
+ alwaysOn: "append-system-prompt",
41
+ },
42
+ },
43
+ catalog: {
44
+ defaultModel: "sonnet-4.6",
45
+ models: [
46
+ { alias: "fable-5", label: "Fable 5", providerModel: "claude-fable-5", efforts: CLAUDE_LOW_TO_XHIGH_MAX, defaultEffort: "medium", unavailable: "suspended by export-control directive, 2026-06-12", ...codeModel({ contextWindowTokens: CONTEXT_1M }) },
47
+ { alias: "opus-4.8", label: "Opus 4.8", providerModel: "claude-opus-4-8", efforts: CLAUDE_LOW_TO_XHIGH_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
48
+ { alias: "opus-4.8[1m]", label: "Opus 4.8 1M", providerModel: "claude-opus-4-8[1m]", efforts: CLAUDE_LOW_TO_XHIGH_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_1M }) },
49
+ { alias: "opus-4.7", label: "Opus 4.7", providerModel: "claude-opus-4-7", efforts: CLAUDE_LOW_TO_XHIGH_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
50
+ { alias: "opus-4.7[1m]", label: "Opus 4.7 1M", providerModel: "claude-opus-4-7[1m]", efforts: CLAUDE_LOW_TO_XHIGH_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_1M }) },
51
+ { alias: "opus-4.6", label: "Opus 4.6", providerModel: "claude-opus-4-6", efforts: CLAUDE_LOW_TO_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
52
+ { alias: "opus-4.6[1m]", label: "Opus 4.6 1M", providerModel: "claude-opus-4-6[1m]", efforts: CLAUDE_LOW_TO_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_1M }) },
53
+ { alias: "sonnet-4.6", label: "Sonnet 4.6", providerModel: "claude-sonnet-4-6", efforts: CLAUDE_LOW_TO_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
54
+ { alias: "sonnet-4.6[1m]", label: "Sonnet 4.6 1M", providerModel: "claude-sonnet-4-6[1m]", efforts: CLAUDE_LOW_TO_MAX, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_1M }) },
55
+ { alias: "haiku", label: "Haiku", providerModel: "haiku", efforts: [], ...codeModel() },
56
+ ],
57
+ },
58
+ quotaWindows: [...quotaWindows],
59
+ capabilityDefaults: {
60
+ lifecycle: {
61
+ managed: true,
62
+ shutdownHard: { when: "headless", value: true, otherwise: false },
63
+ restartHard: { when: "headless", value: true, otherwise: false },
64
+ semanticStatus: true,
65
+ reconnect: true,
66
+ },
67
+ session: {
68
+ fileRead: true,
69
+ fileWrite: { when: "approval:not-read-only", value: true, otherwise: false },
70
+ shell: true,
71
+ shellMode: { open: "unrestricted", guarded: "guarded", readOnly: "read-only-guarded" },
72
+ },
73
+ context: {
74
+ managed: "headless",
75
+ compact: { when: "headless", value: true, otherwise: false },
76
+ clear: { when: "headless", value: true, otherwise: false },
77
+ inject: true,
78
+ resumePreference: ["native", "clear-inject", "none"],
79
+ },
80
+ quota: {
81
+ supported: true,
82
+ source: "probe",
83
+ unit: "%",
84
+ windows: [...quotaWindows],
85
+ },
86
+ terminal: {
87
+ mode: "live",
88
+ condition: "headless",
89
+ live: { read: true, write: true },
90
+ },
91
+ liveSession: {
92
+ capture: true,
93
+ inject: true,
94
+ interrupt: true,
95
+ promptEcho: true,
96
+ reasoning: true,
97
+ slashCommands: true,
98
+ },
99
+ },
100
+ slashCommands: ["/clear", "/compact", "/model", "/help"],
101
+ resume: { supported: true, idFormat: "uuid-v4", idPattern: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" },
102
+ home: { configDir: ".claude", envPrefix: "CLAUDE", configDirEnvVar: "CLAUDE_CONFIG_DIR", quotaCredentialFile: ".credentials.json", authItems: [".credentials.json", "statsig"] },
103
+ provisioning: {
104
+ pluginManifestPath: ".claude-plugin/plugin.json",
105
+ bundledPlugin: {
106
+ ref: "agent-relay-claude-plugin",
107
+ dir: "runner/plugins/claude",
108
+ title: "Agent Relay Claude plugin",
109
+ description: "Bundled Agent Relay Claude plugin, materialized whole through the provisioning registry.",
110
+ omitFiles: ["monitors/relay-monitor.provisioned.mjs"],
111
+ fileOverrides: [{ path: "monitors/relay-monitor.ts", sourcePath: "monitors/relay-monitor.provisioned.mjs" }],
112
+ },
113
+ },
114
+ upgrade: {
115
+ packages: ["agent-relay-runner", "agent-relay-plugin"],
116
+ detectPackages: ["agent-relay-runner"],
117
+ detectCommands: ["claude"],
118
+ },
119
+ probe: {
120
+ command: "claude",
121
+ args: ["--version"],
122
+ healthCheck: "claude --version",
123
+ featureChecks: [{ name: "rig", command: "claude-rig", homeDir: ".claude-rig" }],
124
+ },
125
+ quotaPoll: { strategy: "none" },
126
+ shim: { kind: "claude-relay" },
127
+ } satisfies ProviderManifest;
128
+
129
+ registerProvider(claudeProviderManifest);
package/codex.ts ADDED
@@ -0,0 +1,125 @@
1
+ import { registerProvider } from "./registry.js";
2
+ import type { ProviderManifest, ProviderModelCapabilities, ProviderModelLimits } from "./types.js";
3
+
4
+ const CODEX_REASONING = ["low", "medium", "high", "xhigh"];
5
+ const CONTEXT_200K = { value: 200_000, source: "catalog", confidence: "declared" } as const;
6
+ const CODE_MODEL_CAPABILITIES: ProviderModelCapabilities = {
7
+ modalities: {
8
+ input: { text: true, image: true },
9
+ output: { text: true },
10
+ },
11
+ tools: {
12
+ code: true,
13
+ review: true,
14
+ debug: true,
15
+ refactor: true,
16
+ },
17
+ source: "catalog",
18
+ confidence: "declared",
19
+ };
20
+ const quotaWindows = [
21
+ { name: "primary", unit: "%", reset: true },
22
+ { name: "secondary", unit: "%", reset: true },
23
+ ] as const;
24
+
25
+ function codeModel(limits?: ProviderModelLimits): Pick<NonNullable<ProviderManifest["catalog"]["models"][number]>, "limits" | "capabilities"> {
26
+ return {
27
+ ...(limits ? { limits } : {}),
28
+ capabilities: CODE_MODEL_CAPABILITIES,
29
+ };
30
+ }
31
+
32
+ export const codexProviderManifest = {
33
+ id: "codex",
34
+ label: "Codex",
35
+ icon: "⌨️",
36
+ launch: {
37
+ managedPolicyPrompt: {
38
+ alwaysOn: "prompt",
39
+ },
40
+ },
41
+ catalog: {
42
+ defaultModel: "gpt-5.5",
43
+ models: [
44
+ { alias: "gpt-5.5", label: "GPT-5.5", providerModel: "gpt-5.5", efforts: CODEX_REASONING, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
45
+ { alias: "gpt-5.4", label: "GPT-5.4", providerModel: "gpt-5.4", efforts: CODEX_REASONING, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
46
+ { alias: "gpt-5.4-mini", label: "GPT-5.4 Mini", providerModel: "gpt-5.4-mini", efforts: CODEX_REASONING, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
47
+ { alias: "gpt-5.3-codex", label: "GPT-5.3 Codex", providerModel: "gpt-5.3-codex", efforts: CODEX_REASONING, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
48
+ { alias: "gpt-5.3-codex-spark", label: "GPT-5.3 Codex Spark", providerModel: "gpt-5.3-codex-spark", efforts: CODEX_REASONING, defaultEffort: "high", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
49
+ { alias: "gpt-5.2", label: "GPT-5.2", providerModel: "gpt-5.2", efforts: CODEX_REASONING, defaultEffort: "medium", ...codeModel({ contextWindowTokens: CONTEXT_200K }) },
50
+ ],
51
+ },
52
+ quotaWindows: [...quotaWindows],
53
+ capabilityDefaults: {
54
+ lifecycle: {
55
+ managed: true,
56
+ shutdownHard: true,
57
+ restartHard: true,
58
+ semanticStatus: true,
59
+ reconnect: true,
60
+ },
61
+ session: {
62
+ fileRead: true,
63
+ fileWrite: { when: "approval:not-read-only", value: true, otherwise: false },
64
+ shell: { when: "approval:not-read-only", value: true, otherwise: false },
65
+ shellMode: { open: "unrestricted", guarded: "guarded", readOnly: "none" },
66
+ },
67
+ context: {
68
+ managed: "always",
69
+ compact: true,
70
+ clear: true,
71
+ inject: true,
72
+ resumePreference: ["native", "clear-inject", "none"],
73
+ },
74
+ quota: {
75
+ supported: true,
76
+ source: "probe",
77
+ unit: "%",
78
+ windows: [...quotaWindows],
79
+ },
80
+ terminal: {
81
+ mode: "attach",
82
+ attach: {
83
+ create: true,
84
+ read: true,
85
+ write: true,
86
+ detach: true,
87
+ },
88
+ },
89
+ liveSession: {
90
+ capture: true,
91
+ inject: true,
92
+ interrupt: true,
93
+ promptEcho: true,
94
+ reasoning: true,
95
+ slashCommands: true,
96
+ },
97
+ },
98
+ slashCommands: ["/compact", "/new"],
99
+ resume: { supported: true, idFormat: "codex-thread-id", idPattern: "[\\w-]+" },
100
+ home: { configDir: ".codex", envPrefix: "CODEX", configDirEnvVar: "CODEX_HOME", quotaCredentialFile: "auth.json", authItems: ["auth.json", "installation_id"] },
101
+ provisioning: {
102
+ pluginManifestPath: ".codex-plugin/plugin.json",
103
+ bundledSkills: {
104
+ refPrefix: "agent-relay-codex-",
105
+ dir: "runner/plugins/codex/skills",
106
+ titlePrefix: "Agent Relay Codex skill: ",
107
+ description: "Bundled Agent Relay Codex skill, materialized through the provisioning registry.",
108
+ entryFile: "SKILL.md",
109
+ },
110
+ },
111
+ upgrade: {
112
+ packages: ["agent-relay-runner", "agent-relay-codex"],
113
+ detectPackages: ["agent-relay-runner", "agent-relay-codex"],
114
+ detectCommands: ["codex-relay", "agent-relay-runner"],
115
+ },
116
+ probe: {
117
+ command: "codex",
118
+ args: ["--version"],
119
+ healthCheck: "codex --version",
120
+ },
121
+ quotaPoll: { strategy: "codex-app-server" },
122
+ shim: { kind: "codex-relay", extraBinPaths: ["codex/bin/codex"], cleanLegacyHooks: true },
123
+ } satisfies ProviderManifest;
124
+
125
+ registerProvider(codexProviderManifest);
package/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import "./claude.js";
2
+ import "./codex.js";
3
+
4
+ export * from "./registry.js";
5
+ export * from "./types.js";
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "agent-relay-providers",
3
+ "version": "0.104.0",
4
+ "description": "Serializable provider manifests for Agent Relay deploy targets",
5
+ "type": "module",
6
+ "license": "AGPL-3.0-or-later",
7
+ "author": "Edin Mujkanovic <edin@exelerus.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/edimuj/agent-relay.git",
11
+ "directory": "providers"
12
+ },
13
+ "main": "./index.ts",
14
+ "types": "./index.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./index.ts",
18
+ "import": "./index.ts"
19
+ },
20
+ "./types": {
21
+ "types": "./types.ts",
22
+ "import": "./types.ts"
23
+ }
24
+ },
25
+ "files": [
26
+ "*.ts"
27
+ ]
28
+ }
package/registry.ts ADDED
@@ -0,0 +1,56 @@
1
+ import type { ProviderManifest } from "./types.js";
2
+
3
+ const PROVIDER_ID_RE = /^[a-z][a-z0-9-]*$/;
4
+ const manifests = new Map<string, ProviderManifest>();
5
+
6
+ export function registerProvider(manifest: ProviderManifest): void {
7
+ if (!PROVIDER_ID_RE.test(manifest.id)) {
8
+ throw new Error(`invalid provider id: ${manifest.id}`);
9
+ }
10
+ if (!manifest.label.trim()) {
11
+ throw new Error(`provider ${manifest.id} is missing a label`);
12
+ }
13
+ if (!manifest.icon.trim()) {
14
+ throw new Error(`provider ${manifest.id} is missing an icon`);
15
+ }
16
+ if (manifests.has(manifest.id)) {
17
+ throw new Error(`provider already registered: ${manifest.id}`);
18
+ }
19
+ manifests.set(manifest.id, manifest);
20
+ }
21
+
22
+ export function getManifest(id: string): ProviderManifest | undefined {
23
+ return manifests.get(id);
24
+ }
25
+
26
+ export function getAllManifests(): ProviderManifest[] {
27
+ return [...manifests.values()];
28
+ }
29
+
30
+ export function isValidResumeId(providerId: string, id: string): boolean {
31
+ if (!id) return false;
32
+ const manifest = manifests.get(providerId);
33
+ if (!manifest?.resume?.supported) return false;
34
+ const pattern = manifest.resume.idPattern;
35
+ if (!pattern) return true;
36
+ return new RegExp(`^${pattern}$`, "i").test(id);
37
+ }
38
+
39
+ export function resumeLogExtractionRe(providerId: string): RegExp | undefined {
40
+ const manifest = manifests.get(providerId);
41
+ if (!manifest?.resume?.supported || !manifest.resume.idPattern || !manifest.probe?.command) return undefined;
42
+ return new RegExp(`\\b${manifest.probe.command}\\s+--resume\\s+(${manifest.resume.idPattern})\\b`, "gi");
43
+ }
44
+
45
+ type AccountKeyAliasResolver = (accountKey: string) => string[];
46
+ const accountKeyAliasResolvers = new Map<string, AccountKeyAliasResolver>();
47
+
48
+ export function registerAccountKeyAliases(providerId: string, resolver: AccountKeyAliasResolver): void {
49
+ accountKeyAliasResolvers.set(providerId, resolver);
50
+ }
51
+
52
+ export function quotaAccountKeyAliases(providerId: string, accountKey: string): string[] {
53
+ return accountKeyAliasResolvers.get(providerId)?.(accountKey) ?? [];
54
+ }
55
+
56
+ export const PROVIDER_MANIFESTS: ReadonlyMap<string, ProviderManifest> = manifests;
package/types.ts ADDED
@@ -0,0 +1,244 @@
1
+ export type ProviderCatalogValueSource = "catalog" | "provider" | "runtime" | "override";
2
+ export type ProviderCatalogConfidence = "declared" | "verified" | "estimated" | "unknown";
3
+
4
+ export interface ProviderCatalogValue<T> {
5
+ value: T;
6
+ source: ProviderCatalogValueSource;
7
+ confidence: ProviderCatalogConfidence;
8
+ lastUpdatedAt?: number;
9
+ }
10
+
11
+ export interface ProviderModelLimits {
12
+ contextWindowTokens?: ProviderCatalogValue<number>;
13
+ maxOutputTokens?: ProviderCatalogValue<number>;
14
+ }
15
+
16
+ export interface ProviderContextThreshold {
17
+ selfCompactUtilization: number;
18
+ warnUtilization?: number;
19
+ hardBackstopUtilization?: number;
20
+ }
21
+
22
+ export interface ProviderModelModalities {
23
+ input: {
24
+ text: boolean;
25
+ image?: boolean;
26
+ audio?: boolean;
27
+ video?: boolean;
28
+ pdf?: boolean;
29
+ };
30
+ output: {
31
+ text: boolean;
32
+ image?: boolean;
33
+ audio?: boolean;
34
+ video?: boolean;
35
+ };
36
+ }
37
+
38
+ export interface ProviderModelToolCapabilities {
39
+ code?: boolean;
40
+ review?: boolean;
41
+ debug?: boolean;
42
+ refactor?: boolean;
43
+ shell?: boolean;
44
+ fileRead?: boolean;
45
+ fileWrite?: boolean;
46
+ webSearch?: boolean;
47
+ imageGeneration?: boolean;
48
+ imageEditing?: boolean;
49
+ }
50
+
51
+ export interface ProviderModelCapabilities {
52
+ modalities: ProviderModelModalities;
53
+ tools?: ProviderModelToolCapabilities;
54
+ source: ProviderCatalogValueSource;
55
+ confidence: ProviderCatalogConfidence;
56
+ lastUpdatedAt?: number;
57
+ }
58
+
59
+ export interface ProviderModelEntry {
60
+ alias: string;
61
+ label: string;
62
+ providerModel: string;
63
+ efforts: string[];
64
+ defaultEffort?: string;
65
+ disabled?: boolean;
66
+ unavailable?: string;
67
+ limits?: ProviderModelLimits;
68
+ contextThreshold?: ProviderContextThreshold;
69
+ capabilities?: ProviderModelCapabilities;
70
+ }
71
+
72
+ export interface QuotaWindowDescriptor {
73
+ name: string;
74
+ unit: "%" | string;
75
+ reset: boolean;
76
+ description?: string;
77
+ }
78
+
79
+ export interface ProviderProbeFeatureCheck {
80
+ name: string;
81
+ command?: string;
82
+ homeDir?: string;
83
+ }
84
+
85
+ export interface ProviderProbeDescriptor {
86
+ command?: string;
87
+ args?: string[];
88
+ healthCheck?: string;
89
+ featureChecks?: ProviderProbeFeatureCheck[];
90
+ }
91
+
92
+ export interface ProviderHomeDescriptor {
93
+ configDir?: string;
94
+ envPrefix?: string;
95
+ /** The environment variable that sets the provider's config home directory
96
+ * (e.g. "CLAUDE_CONFIG_DIR", "CODEX_HOME"). */
97
+ configDirEnvVar?: string;
98
+ quotaCredentialFile?: string;
99
+ /** Auth-related items to symlink from the host provider home into an isolated
100
+ * home so the provider is launch-ready without a re-login. */
101
+ authItems?: string[];
102
+ }
103
+
104
+ export interface ProviderUpgradeDescriptor {
105
+ packages: string[];
106
+ detectPackages?: string[];
107
+ detectCommands?: string[];
108
+ }
109
+
110
+ export interface ProviderQuotaPollDescriptor {
111
+ strategy: "none" | "codex-app-server";
112
+ }
113
+
114
+ export interface ProviderShimDescriptor {
115
+ kind: "claude-relay" | "codex-relay";
116
+ extraBinPaths?: string[];
117
+ cleanLegacyHooks?: boolean;
118
+ }
119
+
120
+ export type ProviderCapabilityCondition =
121
+ | "always"
122
+ | "never"
123
+ | "headless"
124
+ | "interactive"
125
+ | "approval:read-only"
126
+ | "approval:not-read-only"
127
+ | "adapter:compact-supports-instructions"
128
+ | "adapter:clear-context";
129
+
130
+ export interface ConditionalBooleanDefault {
131
+ when: ProviderCapabilityCondition;
132
+ value: boolean;
133
+ otherwise: boolean;
134
+ }
135
+
136
+ export type BooleanCapabilityDefault = boolean | ConditionalBooleanDefault;
137
+
138
+ export interface ProviderCapabilityDefaults {
139
+ lifecycle: {
140
+ managed: boolean;
141
+ shutdownHard: BooleanCapabilityDefault;
142
+ restartHard: BooleanCapabilityDefault;
143
+ semanticStatus: boolean;
144
+ reconnect: boolean;
145
+ };
146
+ session: {
147
+ fileRead: boolean;
148
+ fileWrite: BooleanCapabilityDefault;
149
+ shell: BooleanCapabilityDefault;
150
+ shellMode: {
151
+ open: string;
152
+ guarded: string;
153
+ readOnly: string;
154
+ };
155
+ };
156
+ context: {
157
+ managed: ProviderCapabilityCondition;
158
+ compact: BooleanCapabilityDefault;
159
+ clear: BooleanCapabilityDefault;
160
+ inject: boolean;
161
+ resumePreference: Array<"native" | "clear-inject" | "none">;
162
+ };
163
+ quota: {
164
+ supported: boolean;
165
+ source: "probe" | "provider" | "runtime";
166
+ unit: "%" | string;
167
+ windows: QuotaWindowDescriptor[];
168
+ };
169
+ terminal: {
170
+ mode: "none" | "live" | "attach";
171
+ condition?: ProviderCapabilityCondition;
172
+ live?: {
173
+ read: boolean;
174
+ write: boolean;
175
+ };
176
+ attach?: {
177
+ create: boolean;
178
+ read: boolean;
179
+ write: boolean;
180
+ detach: boolean;
181
+ };
182
+ };
183
+ liveSession: {
184
+ capture: boolean;
185
+ inject: boolean;
186
+ interrupt: boolean;
187
+ promptEcho: boolean;
188
+ reasoning: boolean;
189
+ slashCommands: boolean;
190
+ };
191
+ }
192
+
193
+ export interface ProviderBundledFileOverride {
194
+ path: string;
195
+ sourcePath: string;
196
+ }
197
+
198
+ export interface ProviderBundledPluginDescriptor {
199
+ ref: string;
200
+ dir: string;
201
+ title: string;
202
+ description: string;
203
+ omitFiles?: string[];
204
+ fileOverrides?: ProviderBundledFileOverride[];
205
+ }
206
+
207
+ export interface ProviderBundledSkillSetDescriptor {
208
+ refPrefix: string;
209
+ dir: string;
210
+ titlePrefix: string;
211
+ description: string;
212
+ entryFile?: string;
213
+ }
214
+
215
+ export interface ProviderProvisioningDescriptor {
216
+ pluginManifestPath?: string;
217
+ bundledPlugin?: ProviderBundledPluginDescriptor;
218
+ bundledSkills?: ProviderBundledSkillSetDescriptor;
219
+ }
220
+
221
+ export interface ProviderManifest {
222
+ id: string;
223
+ label: string;
224
+ icon: string;
225
+ launch?: {
226
+ managedPolicyPrompt?: {
227
+ alwaysOn: "prompt" | "append-system-prompt";
228
+ };
229
+ };
230
+ catalog: {
231
+ models: ProviderModelEntry[];
232
+ defaultModel?: string;
233
+ };
234
+ quotaWindows: QuotaWindowDescriptor[];
235
+ capabilityDefaults: Partial<ProviderCapabilityDefaults>;
236
+ slashCommands?: string[];
237
+ resume?: { supported: boolean; idFormat?: string; idPattern?: string };
238
+ home?: ProviderHomeDescriptor;
239
+ provisioning?: ProviderProvisioningDescriptor;
240
+ upgrade?: ProviderUpgradeDescriptor;
241
+ probe?: ProviderProbeDescriptor;
242
+ quotaPoll?: ProviderQuotaPollDescriptor;
243
+ shim?: ProviderShimDescriptor;
244
+ }