@vibesdotdev/integrations-custom 0.0.0-stage → 1.0.0-rc.4

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.
Files changed (63) hide show
  1. package/LICENSE +126 -0
  2. package/README.md +18 -2
  3. package/dist/ai/index.d.ts +4 -0
  4. package/dist/ai/index.d.ts.map +1 -0
  5. package/dist/ai/index.js +4 -0
  6. package/dist/ai/index.js.map +1 -0
  7. package/dist/ai/provider.plugin.d.ts +6 -0
  8. package/dist/ai/provider.plugin.d.ts.map +1 -0
  9. package/dist/ai/provider.plugin.js +88 -0
  10. package/dist/ai/provider.plugin.js.map +1 -0
  11. package/dist/ai/providers/cloud/api/custom/config/config.custom.descriptor.d.ts +4206 -0
  12. package/dist/ai/providers/cloud/api/custom/config/config.custom.descriptor.d.ts.map +1 -0
  13. package/dist/ai/providers/cloud/api/custom/config/config.custom.descriptor.js +53 -0
  14. package/dist/ai/providers/cloud/api/custom/config/config.custom.descriptor.js.map +1 -0
  15. package/dist/ai/providers/cloud/api/custom/config/schemas/index.d.ts +29 -0
  16. package/dist/ai/providers/cloud/api/custom/config/schemas/index.d.ts.map +1 -0
  17. package/dist/ai/providers/cloud/api/custom/config/schemas/index.js +15 -0
  18. package/dist/ai/providers/cloud/api/custom/config/schemas/index.js.map +1 -0
  19. package/dist/ai/providers/cloud/api/custom/index.d.ts +5 -0
  20. package/dist/ai/providers/cloud/api/custom/index.d.ts.map +1 -0
  21. package/dist/ai/providers/cloud/api/custom/index.js +4 -0
  22. package/dist/ai/providers/cloud/api/custom/index.js.map +1 -0
  23. package/dist/ai/providers/cloud/api/custom/provider.custom.descriptor.d.ts +183 -0
  24. package/dist/ai/providers/cloud/api/custom/provider.custom.descriptor.d.ts.map +1 -0
  25. package/dist/ai/providers/cloud/api/custom/provider.custom.descriptor.js +92 -0
  26. package/dist/ai/providers/cloud/api/custom/provider.custom.descriptor.js.map +1 -0
  27. package/dist/ai/providers/custom/custom.provider.impl.d.ts +25 -0
  28. package/dist/ai/providers/custom/custom.provider.impl.d.ts.map +1 -0
  29. package/dist/ai/providers/custom/custom.provider.impl.js +192 -0
  30. package/dist/ai/providers/custom/custom.provider.impl.js.map +1 -0
  31. package/dist/ai/providers/custom/detection/index.d.ts +2 -0
  32. package/dist/ai/providers/custom/detection/index.d.ts.map +1 -0
  33. package/dist/ai/providers/custom/detection/index.js +2 -0
  34. package/dist/ai/providers/custom/detection/index.js.map +1 -0
  35. package/dist/ai/providers/custom/detection/system.d.ts +5 -0
  36. package/dist/ai/providers/custom/detection/system.d.ts.map +1 -0
  37. package/dist/ai/providers/custom/detection/system.js +30 -0
  38. package/dist/ai/providers/custom/detection/system.js.map +1 -0
  39. package/dist/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.d.ts +4 -0
  40. package/dist/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.d.ts.map +1 -0
  41. package/dist/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.js +25 -0
  42. package/dist/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.js.map +1 -0
  43. package/dist/ai/providers/custom/index.d.ts +5 -0
  44. package/dist/ai/providers/custom/index.d.ts.map +1 -0
  45. package/dist/ai/providers/custom/index.js +5 -0
  46. package/dist/ai/providers/custom/index.js.map +1 -0
  47. package/dist/ai/providers/custom/recommendations.d.ts +22 -0
  48. package/dist/ai/providers/custom/recommendations.d.ts.map +1 -0
  49. package/dist/ai/providers/custom/recommendations.js +70 -0
  50. package/dist/ai/providers/custom/recommendations.js.map +1 -0
  51. package/dist/index.d.ts +2 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +2 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/schemas/catalog.d.ts +8 -0
  56. package/dist/schemas/catalog.d.ts.map +1 -0
  57. package/dist/schemas/catalog.js +3 -0
  58. package/dist/schemas/catalog.js.map +1 -0
  59. package/dist/schemas/detection.d.ts +7 -0
  60. package/dist/schemas/detection.d.ts.map +1 -0
  61. package/dist/schemas/detection.js +4 -0
  62. package/dist/schemas/detection.js.map +1 -0
  63. package/package.json +98 -4
@@ -0,0 +1,192 @@
1
+ import { assertNoPlaintextCredentials, resolveSecretReference } from '@vibesdotdev/ai/providers-runtime';
2
+ import { fetchAIProvider } from '@vibesdotdev/ai/providers-runtime/client';
3
+ import { getVibesAIClient } from '@vibesdotdev/ai/client';
4
+ import { customConnectionSchema } from "../cloud/api/custom/config/schemas/index.js";
5
+ import { customCatalogSchema } from "../../../schemas/catalog.js";
6
+ import { AnyGenerationRequestSchema } from '@vibesdotdev/ai/generation/execution/schemas/request';
7
+ import { createAIModelDescriptor, UNCLASSIFIED_MODEL_TAG } from '@vibesdotdev/ai/models/schemas';
8
+ import { getVibesModelId } from '@vibesdotdev/ai/metadata/ids';
9
+ import { isCredentialReference } from '@vibesdotdev/ai/providers-runtime';
10
+ import { CapabilityError, isCapabilityError, settle } from '@vibesdotdev/kernel';
11
+ import { detectCustomSystem } from "./detection/system.js";
12
+ function connection(config) {
13
+ const parsed = customConnectionSchema.safeParse(config);
14
+ if (!parsed.success)
15
+ throw new CapabilityError('Invalid custom endpoint configuration', 'INVALID_INPUT', {
16
+ reason: 'custom-configuration-invalid'
17
+ });
18
+ return parsed.data;
19
+ }
20
+ export class CustomProviderType {
21
+ descriptor;
22
+ context;
23
+ constructor(descriptor, context) {
24
+ this.descriptor = descriptor;
25
+ this.context = context;
26
+ }
27
+ async generate(provider, model, request, options) {
28
+ const ai = await getVibesAIClient(this.context.runtime);
29
+ const response = await ai.requestGeneration({
30
+ ...AnyGenerationRequestSchema.parse(request), provider, model
31
+ }, {
32
+ ...options,
33
+ metadata: { ...options?.metadata, scope: options?.scope, specId: options?.specId, capability: options?.capability }
34
+ });
35
+ return { response, adapterId: 'ai/generation', generationMethod: 'runtime' };
36
+ }
37
+ async detectInstalled() {
38
+ const detected = await detectCustomSystem(this.context.runtime);
39
+ return detected
40
+ ? [{ name: detected.name, source: 'system', config: detected.configuration ?? {} }]
41
+ : [];
42
+ }
43
+ async recommendModels() {
44
+ return [
45
+ {
46
+ modelId: 'custom:configured-model',
47
+ modelName: 'Configured custom model',
48
+ score: 70,
49
+ reason: 'Use the model id advertised by the configured OpenAI-compatible endpoint',
50
+ capabilities: ['chat', 'tools'],
51
+ useCaseFit: 70
52
+ }
53
+ ];
54
+ }
55
+ async resolveCredential(config, options) {
56
+ const reference = config.apiKey;
57
+ assertNoPlaintextCredentials({ apiKey: reference });
58
+ if (!isCredentialReference(reference) || reference.source === 'inline')
59
+ return undefined;
60
+ if (options?.resolveCredential)
61
+ return options.resolveCredential(reference);
62
+ return resolveSecretReference(reference, this.context.runtime);
63
+ }
64
+ authorizationHeader(authType, secret) {
65
+ if (authType === 'none' || !secret)
66
+ return undefined;
67
+ if (authType === 'api_key')
68
+ return secret;
69
+ if (authType === 'basic') {
70
+ return secret.startsWith('Basic ') ? secret : `Basic ${secret}`;
71
+ }
72
+ return secret.startsWith('Bearer ') ? secret : `Bearer ${secret}`;
73
+ }
74
+ async requestHeaders(config, options) {
75
+ const authType = config.authType;
76
+ const secret = authType === 'none' ? undefined : await this.resolveCredential(config, options);
77
+ if (authType !== 'none' && !secret)
78
+ throw new CapabilityError('Custom endpoint credential is unavailable', 'AUTH_REQUIRED', {
79
+ reason: 'custom-credential-unavailable'
80
+ });
81
+ const headers = new Headers(config.headers);
82
+ const authorization = this.authorizationHeader(authType, secret);
83
+ if (authorization)
84
+ headers.set('authorization', authorization);
85
+ return headers;
86
+ }
87
+ async listModels(providerInstance, options) {
88
+ // This provider executes over an OpenAI-compatible text API. A /models
89
+ // response declares no model's kind, so each listed model is a text model
90
+ // of that endpoint that claims no capability (not chat, vision, tool use
91
+ // or embedding) and no model type: it stays unclassified. For any other
92
+ // modality the catalog cannot say which models serve it, so the answer is
93
+ // "unknown", never "none": a model registered in that modality on this
94
+ // connection (e.g. an embedder) must not be refused as unavailable.
95
+ if (options?.modality && options.modality !== 'text') {
96
+ throw new CapabilityError(`A custom endpoint's catalog cannot classify ${options.modality} models`, 'UNAVAILABLE', {
97
+ reason: 'custom-catalog-unclassified',
98
+ recoveryHint: 'Register the model in that modality explicitly: vibes ai models add <connection> <model-id> --modality <modality>.'
99
+ });
100
+ }
101
+ const config = connection(providerInstance.configuration ?? {});
102
+ const baseUrl = config.baseUrl;
103
+ const headers = await this.requestHeaders(config, options);
104
+ const wait = {
105
+ timeoutMs: options?.timeout ?? config.timeout,
106
+ reason: 'custom model catalog'
107
+ };
108
+ if (options?.signal)
109
+ wait.signal = options.signal;
110
+ const fetched = await settle(() => this.context.runtime.lifecycle.wait(async (signal) => {
111
+ const response = await fetchAIProvider(this.context, `${baseUrl.replace(/\/+$/, '')}/models`, { headers, signal });
112
+ if (!response.ok)
113
+ throw new CapabilityError(`Custom model catalog returned HTTP ${response.status}`, 'UNAVAILABLE', {
114
+ reason: 'custom-catalog-failed'
115
+ });
116
+ const decoded = await settle(() => response.json());
117
+ const catalog = customCatalogSchema.safeParse(decoded.ok ? decoded.value : undefined);
118
+ if (!catalog.success)
119
+ throw new CapabilityError('Custom model catalog must contain data entries with non-empty model ids', 'INVALID_INPUT', {
120
+ reason: 'custom-catalog-malformed'
121
+ });
122
+ return catalog.data;
123
+ }, wait));
124
+ if (!fetched.ok) {
125
+ if (isCapabilityError(fetched.cause))
126
+ throw fetched.cause;
127
+ throw new CapabilityError('Custom model catalog request failed', 'UNAVAILABLE', { reason: 'custom-catalog-failed' });
128
+ }
129
+ const catalog = fetched.value;
130
+ return [...new Set(catalog.data.map((model) => model.id))].map((wireId) => createAIModelDescriptor({
131
+ id: getVibesModelId(providerInstance.id, wireId),
132
+ providerId: providerInstance.id,
133
+ name: wireId,
134
+ modalities: ['text'],
135
+ capabilities: [],
136
+ // The catalog named the id, not the kind: a sync must not let this guess
137
+ // overwrite a stored classification (e.g. a registered embedder).
138
+ tags: [UNCLASSIFIED_MODEL_TAG],
139
+ configuration: { modelId: wireId },
140
+ enabled: true
141
+ }));
142
+ }
143
+ async checkHealth(config, options) {
144
+ const start = Date.now();
145
+ const parsed = customConnectionSchema.safeParse(config);
146
+ if (!parsed.success)
147
+ return {
148
+ healthy: false, message: 'Invalid custom endpoint configuration',
149
+ error: { code: 'INVALID_CONFIGURATION', message: 'Check the custom connection schema' },
150
+ checkedAt: new Date()
151
+ };
152
+ const configured = parsed.data;
153
+ const headers = await this.requestHeaders(configured, options);
154
+ const endpointBaseUrl = configured.baseUrl.replace(/\/+$/, '');
155
+ const probed = await settle(async () => {
156
+ const wait = { timeoutMs: options?.timeout ?? configured.timeout, reason: 'custom health probe' };
157
+ if (options?.signal)
158
+ wait.signal = options.signal;
159
+ return this.context.runtime.lifecycle.wait((signal) => fetchAIProvider(this.context, `${endpointBaseUrl}/models`, { headers, signal }), wait);
160
+ });
161
+ if (!probed.ok) {
162
+ // An unreachable endpoint is this probe's answer: the cause is reported in it.
163
+ return {
164
+ healthy: false,
165
+ latencyMs: Date.now() - start,
166
+ message: 'Custom endpoint is unavailable',
167
+ error: { code: 'CONNECTION_ERROR', message: 'Custom endpoint request failed or exceeded its deadline' },
168
+ checkedAt: new Date()
169
+ };
170
+ }
171
+ const response = probed.value;
172
+ return {
173
+ healthy: response.ok,
174
+ latencyMs: Date.now() - start,
175
+ message: response.ok
176
+ ? 'Custom OpenAI-compatible endpoint responded'
177
+ : `Custom endpoint returned ${response.status}`,
178
+ error: response.ok ? undefined : { code: 'API_ERROR', message: 'Custom endpoint refused the health request' },
179
+ checkedAt: new Date(),
180
+ availableModalities: response.ok ? ['text'] : undefined
181
+ };
182
+ }
183
+ async validateConnection(config) {
184
+ const parsed = customConnectionSchema.safeParse(config);
185
+ return parsed.success ? { valid: true } : {
186
+ valid: false,
187
+ errors: parsed.error.issues.map((issue) => `Invalid ${issue.path.join('.')}`)
188
+ };
189
+ }
190
+ async dispose() { }
191
+ }
192
+ //# sourceMappingURL=custom.provider.impl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom.provider.impl.js","sourceRoot":"","sources":["../../../../src/ai/providers/custom/custom.provider.impl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { detectCustomSystem } from './system.ts';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { detectCustomSystem } from "./system.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/detection/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type RuntimeRef } from '@vibesdotdev/kernel';
2
+ export { CustomDetectionConfigSchema } from '../../../../schemas/detection.ts';
3
+ import type { DetectedProvider } from '@vibesdotdev/ai/providers-runtime/client/types';
4
+ export declare function detectCustomSystem(runtime: RuntimeRef): Promise<DetectedProvider | null>;
5
+ //# sourceMappingURL=system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.d.ts","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/detection/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gDAAgD,CAAC;AAEvF,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,UAAU,GACjB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsBlC"}
@@ -0,0 +1,30 @@
1
+ import { readPluginConfig } from '@vibesdotdev/kernel';
2
+ import { CustomDetectionConfigSchema } from "../../../../schemas/detection.js";
3
+ export { CustomDetectionConfigSchema } from "../../../../schemas/detection.js";
4
+ export async function detectCustomSystem(runtime) {
5
+ const config = await readPluginConfig(runtime, 'integrations-custom/ai', CustomDetectionConfigSchema);
6
+ if (!config?.baseUrl)
7
+ return null;
8
+ const baseUrl = config.baseUrl;
9
+ const credential = await runtime.resolveCredential({ source: 'secret', key: 'CUSTOM_API_KEY' });
10
+ if (!credential.ok && credential.error.reason !== 'credential-not-set')
11
+ throw credential.error;
12
+ const hasCredential = credential.ok && Boolean(credential.value.trim());
13
+ const configuration = {
14
+ baseUrl,
15
+ authType: hasCredential ? 'bearer' : 'none',
16
+ timeout: config.timeout
17
+ };
18
+ if (hasCredential)
19
+ configuration.apiKey = { source: 'secret', key: 'CUSTOM_API_KEY' };
20
+ return {
21
+ providerType: 'custom',
22
+ name: 'Custom OpenAI-Compatible',
23
+ description: hasCredential
24
+ ? 'Credential reference available from CUSTOM_API_KEY'
25
+ : 'Custom endpoint declared in integrations-custom/ai plugin configuration',
26
+ status: 'available',
27
+ configuration
28
+ };
29
+ }
30
+ //# sourceMappingURL=system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/detection/system.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAG/E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,OAAmB;IAEnB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,CAAC,CAAC;IACtG,IAAI,CAAC,MAAM,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,KAAK,oBAAoB;QAAE,MAAM,UAAU,CAAC,KAAK,CAAC;IAC/F,MAAM,aAAa,GAAG,UAAU,CAAC,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACxE,MAAM,aAAa,GAAsC;QACxD,OAAO;QACP,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;QAC3C,OAAO,EAAE,MAAM,CAAC,OAAO;KACvB,CAAC;IACF,IAAI,aAAa;QAAE,aAAa,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;IACtF,OAAO;QACN,YAAY,EAAE,QAAQ;QACtB,IAAI,EAAE,0BAA0B;QAChC,WAAW,EAAE,aAAa;YACzB,CAAC,CAAC,oDAAoD;YACtD,CAAC,CAAC,yEAAyE;QAC5E,MAAM,EAAE,WAAW;QACnB,aAAa;KACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DocsTopicDescriptor } from '@vibesdotdev/docs-contracts';
2
+ declare const descriptor: DocsTopicDescriptor;
3
+ export default descriptor;
4
+ //# sourceMappingURL=ai.providers.custom.docs.descriptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.providers.custom.docs.descriptor.d.ts","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,QAAA,MAAM,UAAU,EAAE,mBAsBjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,25 @@
1
+ const descriptor = {
2
+ kind: 'docs/topic',
3
+ id: 'ai.providers.custom',
4
+ title: 'Custom OpenAI-compatible provider',
5
+ summary: 'Point Vibes at a bring-your-own OpenAI-compatible endpoint without storing raw secrets.',
6
+ body: {
7
+ type: 'markdown',
8
+ sourceType: 'raw',
9
+ source: `# Custom OpenAI-compatible provider
10
+
11
+ \`@vibesdotdev/integrations-custom\` owns the bring-your-own OpenAI-compatible provider.
12
+ Configure \`integrations-custom/ai\` plugin \`config.baseUrl\` and, when the host requires auth, a \`CredentialReference\` for
13
+ \`CUSTOM_API_KEY\`. Generation resolves \`ai/generation\`; the host selects the external
14
+ \`openai-chat\` spec. Detection never returns secret material.
15
+ `
16
+ },
17
+ tags: ['ai', 'providers', 'custom', 'openai-compatible'],
18
+ parent: 'ai.providers',
19
+ order: 80,
20
+ surfaces: ['cli', 'web', 'in-app'],
21
+ hardware: ['consumer', 'cloud'],
22
+ enabled: true
23
+ };
24
+ export default descriptor;
25
+ //# sourceMappingURL=ai.providers.custom.docs.descriptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.providers.custom.docs.descriptor.js","sourceRoot":"","sources":["../../../../../src/ai/providers/custom/docs/ai.providers.custom.docs.descriptor.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAwB;IACvC,IAAI,EAAE,YAAY;IAClB,EAAE,EAAE,qBAAqB;IACzB,KAAK,EAAE,mCAAmC;IAC1C,OAAO,EAAE,yFAAyF;IAClG,IAAI,EAAE;QACL,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE;;;;;;CAMT;KACC;IACD,IAAI,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,mBAAmB,CAAC;IACxD,MAAM,EAAE,cAAc;IACtB,KAAK,EAAE,EAAE;IACT,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC;IAClC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC;IAC/B,OAAO,EAAE,IAAI;CACb,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { CustomProviderType } from './custom.provider.impl.ts';
2
+ export { detectCustomSystem } from './detection/system.ts';
3
+ export { CustomRecommendation } from './recommendations.ts';
4
+ export { default as customDocsDescriptor } from './docs/ai.providers.custom.docs.descriptor.ts';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ai/providers/custom/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+CAA+C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { CustomProviderType } from "./custom.provider.impl.js";
2
+ export { detectCustomSystem } from "./detection/system.js";
3
+ export { CustomRecommendation } from "./recommendations.js";
4
+ export { default as customDocsDescriptor } from "./docs/ai.providers.custom.docs.descriptor.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ai/providers/custom/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,+CAA+C,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { ProviderRecommendation, type ModelAdapter } from '@vibesdotdev/ai/recommendations/base';
2
+ import type { ModelRecommendation, RecommendationContext, SetupMethod, SetupStep, UseCase } from '@vibesdotdev/ai/recommendations/schemas';
3
+ export declare class CustomRecommendation extends ProviderRecommendation {
4
+ readonly providerType = "custom";
5
+ readonly displayName = "Custom OpenAI-Compatible";
6
+ getUseCaseScore(useCase: UseCase): number;
7
+ getRequiredEnvironmentVariables(): string[];
8
+ getReason(): string;
9
+ getStrengths(): string[];
10
+ getWeaknesses(context: RecommendationContext): string[];
11
+ getSupportedSetupMethods(): SetupMethod[];
12
+ getSetupSteps(method: SetupMethod): Promise<SetupStep[]>;
13
+ recommendModels(_adapter: ModelAdapter | null, context: RecommendationContext): Promise<ModelRecommendation[]>;
14
+ getExecutionContext(): {
15
+ recommendModels: "server";
16
+ getSetupSteps: "both";
17
+ };
18
+ supportsOAuth(): boolean;
19
+ supportsLocal(): boolean;
20
+ requiresGPU(): boolean;
21
+ }
22
+ //# sourceMappingURL=recommendations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../../../../src/ai/providers/custom/recommendations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,KAAK,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACjG,OAAO,KAAK,EACX,mBAAmB,EACnB,qBAAqB,EACrB,WAAW,EACX,SAAS,EACT,OAAO,EACP,MAAM,yCAAyC,CAAC;AAEjD,qBAAa,oBAAqB,SAAQ,sBAAsB;IAC/D,QAAQ,CAAC,YAAY,YAAY;IACjC,QAAQ,CAAC,WAAW,8BAA8B;IAClD,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM;IAKzC,+BAA+B,IAAI,MAAM,EAAE;IAG3C,SAAS,IAAI,MAAM;IAGnB,YAAY,IAAI,MAAM,EAAE;IAGxB,aAAa,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,EAAE;IAKvD,wBAAwB,IAAI,WAAW,EAAE;IAGnC,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAkBxD,eAAe,CACpB,QAAQ,EAAE,YAAY,GAAG,IAAI,EAC7B,OAAO,EAAE,qBAAqB,GAC5B,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAcjC,mBAAmB;;;;IAGnB,aAAa,IAAI,OAAO;IAGxB,aAAa,IAAI,OAAO;IAGxB,WAAW,IAAI,OAAO;CAGtB"}
@@ -0,0 +1,70 @@
1
+ import { ProviderRecommendation } from '@vibesdotdev/ai/recommendations/base';
2
+ export class CustomRecommendation extends ProviderRecommendation {
3
+ providerType = 'custom';
4
+ displayName = 'Custom OpenAI-Compatible';
5
+ getUseCaseScore(useCase) {
6
+ return { chat: 55, development: 50, research: 45, images: 5, video: 0, audio: 0, organization: 30 }[useCase];
7
+ }
8
+ getRequiredEnvironmentVariables() {
9
+ return [];
10
+ }
11
+ getReason() {
12
+ return 'Bring-your-own OpenAI-compatible endpoint for self-hosted or vendor-specific APIs';
13
+ }
14
+ getStrengths() {
15
+ return ['Works with any OpenAI-compatible host', 'Credentials stay as references', 'Consumer and cloud hardware'];
16
+ }
17
+ getWeaknesses(context) {
18
+ return context.requiresLocal
19
+ ? ['Availability depends on the configured host remaining reachable']
20
+ : ['Quality and rate limits are owned by the configured endpoint'];
21
+ }
22
+ getSupportedSetupMethods() {
23
+ return ['api_key', 'env_var'];
24
+ }
25
+ async getSetupSteps(method) {
26
+ if (method === 'api_key') {
27
+ return [
28
+ {
29
+ step: 'Store endpoint credential',
30
+ description: 'Bind the endpoint secret through the Vibes credential boundary when the host requires auth.',
31
+ action: 'credential:CUSTOM_API_KEY'
32
+ }
33
+ ];
34
+ }
35
+ return [
36
+ {
37
+ step: 'Bind endpoint URL',
38
+ description: 'Set integrations-custom/ai plugin config.baseUrl to the OpenAI-compatible origin, including any /v1 prefix. Bind environment inputs through the host composition config owner.',
39
+ action: 'config:integrations-custom/ai.baseUrl'
40
+ }
41
+ ];
42
+ }
43
+ async recommendModels(_adapter, context) {
44
+ return [
45
+ {
46
+ modelId: 'custom:configured-model',
47
+ modelName: 'Configured custom model',
48
+ score: context.useCase === 'chat' ? 72 : 68,
49
+ reason: 'Use the model advertised by the configured OpenAI-compatible endpoint',
50
+ capabilities: ['chat', 'tools'],
51
+ isAvailable: true,
52
+ requiresUpgrade: false,
53
+ useCaseFit: context.useCase === 'chat' ? 72 : 68
54
+ }
55
+ ];
56
+ }
57
+ getExecutionContext() {
58
+ return { recommendModels: 'server', getSetupSteps: 'both' };
59
+ }
60
+ supportsOAuth() {
61
+ return false;
62
+ }
63
+ supportsLocal() {
64
+ return true;
65
+ }
66
+ requiresGPU() {
67
+ return false;
68
+ }
69
+ }
70
+ //# sourceMappingURL=recommendations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendations.js","sourceRoot":"","sources":["../../../../src/ai/providers/custom/recommendations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAqB,MAAM,sCAAsC,CAAC;AASjG,MAAM,OAAO,oBAAqB,SAAQ,sBAAsB;IACtD,YAAY,GAAG,QAAQ,CAAC;IACxB,WAAW,GAAG,0BAA0B,CAAC;IAClD,eAAe,CAAC,OAAgB;QAC/B,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAClG,OAAO,CACP,CAAC;IACH,CAAC;IACD,+BAA+B;QAC9B,OAAO,EAAE,CAAC;IACX,CAAC;IACD,SAAS;QACR,OAAO,mFAAmF,CAAC;IAC5F,CAAC;IACD,YAAY;QACX,OAAO,CAAC,uCAAuC,EAAE,gCAAgC,EAAE,6BAA6B,CAAC,CAAC;IACnH,CAAC;IACD,aAAa,CAAC,OAA8B;QAC3C,OAAO,OAAO,CAAC,aAAa;YAC3B,CAAC,CAAC,CAAC,iEAAiE,CAAC;YACrE,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC;IACrE,CAAC;IACD,wBAAwB;QACvB,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,MAAmB;QACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO;gBACN;oBACC,IAAI,EAAE,2BAA2B;oBACjC,WAAW,EAAE,6FAA6F;oBAC1G,MAAM,EAAE,2BAA2B;iBACnC;aACD,CAAC;QACH,CAAC;QACD,OAAO;YACN;gBACC,IAAI,EAAE,mBAAmB;gBACzB,WAAW,EAAE,gLAAgL;gBAC7L,MAAM,EAAE,uCAAuC;aAC/C;SACD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,eAAe,CACpB,QAA6B,EAC7B,OAA8B;QAE9B,OAAO;YACN;gBACC,OAAO,EAAE,yBAAyB;gBAClC,SAAS,EAAE,yBAAyB;gBACpC,KAAK,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;gBAC3C,MAAM,EAAE,uEAAuE;gBAC/E,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;gBAC/B,WAAW,EAAE,IAAI;gBACjB,eAAe,EAAE,KAAK;gBACtB,UAAU,EAAE,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;aAChD;SACD,CAAC;IACH,CAAC;IACD,mBAAmB;QAClB,OAAO,EAAE,eAAe,EAAE,QAAiB,EAAE,aAAa,EAAE,MAAe,EAAE,CAAC;IAC/E,CAAC;IACD,aAAa;QACZ,OAAO,KAAK,CAAC;IACd,CAAC;IACD,aAAa;QACZ,OAAO,IAAI,CAAC;IACb,CAAC;IACD,WAAW;QACV,OAAO,KAAK,CAAC;IACd,CAAC;CACD"}
@@ -0,0 +1,2 @@
1
+ export * from './ai/index.ts';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./ai/index.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as z from 'zod/v4';
2
+ export declare const customCatalogSchema: z.ZodObject<{
3
+ data: z.ZodArray<z.ZodObject<{
4
+ id: z.ZodString;
5
+ }, z.core.$strip>>;
6
+ }, z.core.$strip>;
7
+ export type CustomCatalog = z.infer<typeof customCatalogSchema>;
8
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/schemas/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,eAAO,MAAM,mBAAmB;;;;iBAAmE,CAAC;AACpG,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import * as z from 'zod/v4';
2
+ export const customCatalogSchema = z.object({ data: z.array(z.object({ id: z.string().min(1) })) });
3
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/schemas/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import * as z from 'zod/v4';
2
+ export declare const CustomDetectionConfigSchema: z.ZodObject<{
3
+ baseUrl: z.ZodOptional<z.ZodString>;
4
+ timeout: z.ZodDefault<z.ZodNumber>;
5
+ }, z.core.$strict>;
6
+ export type CustomDetectionConfig = z.infer<typeof CustomDetectionConfigSchema>;
7
+ //# sourceMappingURL=detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detection.d.ts","sourceRoot":"","sources":["../../src/schemas/detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,eAAO,MAAM,2BAA2B;;;kBAAiI,CAAC;AAC1K,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import * as z from 'zod/v4';
2
+ import { customConnectionSchema } from "../ai/providers/cloud/api/custom/config/schemas/index.js";
3
+ export const CustomDetectionConfigSchema = z.object({ baseUrl: customConnectionSchema.shape.baseUrl.optional(), timeout: customConnectionSchema.shape.timeout }).strict();
4
+ //# sourceMappingURL=detection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detection.js","sourceRoot":"","sources":["../../src/schemas/detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,0DAA0D,CAAC;AAElG,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,sBAAsB,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,100 @@
1
1
  {
2
2
  "name": "@vibesdotdev/integrations-custom",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0-rc.4",
4
+ "dependencies": {
5
+ "@vibesdotdev/ai": "^1.0.0-rc.0",
6
+ "@vibesdotdev/docs-contracts": "^1.0.0-rc.0",
7
+ "zod": "^4.6.7",
8
+ "@vibesdotdev/kernel": "^1.0.0-rc.0"
9
+ },
10
+ "gitHead": "319e9e534fac11da0c374ab44efeed6c9722d3ec",
11
+ "_vibes_source": {
12
+ "repo": "ssh://git@git.vibes.dev/vibesdotdev/integrations.git",
13
+ "sha": "319e9e534fac11da0c374ab44efeed6c9722d3ec",
14
+ "workspaceDigest": "sha256:8d28431cae5e9ed1c4a191ac09092ea1300cfbd020cc7985834fee7a145b8a6b"
15
+ },
16
+ "main": "./dist/index.js",
17
+ "exports": {
18
+ ".": {
19
+ "bun": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
23
+ },
24
+ "./ai": {
25
+ "bun": "./dist/ai/index.js",
26
+ "types": "./dist/ai/index.d.ts",
27
+ "import": "./dist/ai/index.js",
28
+ "default": "./dist/ai/index.js"
29
+ },
30
+ "./ai/*": {
31
+ "bun": "./dist/ai/*.js",
32
+ "types": "./dist/ai/*.d.ts",
33
+ "import": "./dist/ai/*.js",
34
+ "default": "./dist/ai/*.js"
35
+ },
36
+ "./ai/plugin": {
37
+ "bun": "./dist/ai/provider.plugin.js",
38
+ "types": "./dist/ai/provider.plugin.d.ts",
39
+ "import": "./dist/ai/provider.plugin.js",
40
+ "default": "./dist/ai/provider.plugin.js"
41
+ }
42
+ },
43
+ "files": [
44
+ "dist",
45
+ "README.md",
46
+ "LICENSE",
47
+ "!**/.turbo/**",
48
+ "!**/.svelte-kit/**",
49
+ "!**/.vibes/**",
50
+ "!**/__tests__/**",
51
+ "!**/__stubs__/**",
52
+ "!**/*.test.js",
53
+ "!**/*.test.mjs",
54
+ "!**/*.test.cjs",
55
+ "!**/*.test.jsx",
56
+ "!**/*.test.ts",
57
+ "!**/*.test.mts",
58
+ "!**/*.test.cts",
59
+ "!**/*.test.tsx",
60
+ "!**/*.spec.js",
61
+ "!**/*.spec.mjs",
62
+ "!**/*.spec.cjs",
63
+ "!**/*.spec.jsx",
64
+ "!**/*.spec.ts",
65
+ "!**/*.spec.mts",
66
+ "!**/*.spec.cts",
67
+ "!**/*.spec.tsx",
68
+ "!**/SPEC.md",
69
+ "!**/tsconfig.json",
70
+ "!**/tsconfig.*.json",
71
+ "!**/*.tsbuildinfo",
72
+ "!**/.build-ok.json",
73
+ "!**/*.tgz"
74
+ ],
75
+ "scripts": {
76
+ "lint": "node ../../node_modules/@vibesdotdev/internal-oxlint-toolchain/ratchet.mjs .",
77
+ "check": "bun --bun tsc -p tsconfig.json --noEmit",
78
+ "test": "bun test src",
79
+ "build": "tsc -p tsconfig.build.json"
80
+ },
81
+ "repository": {
82
+ "type": "git",
83
+ "url": "ssh://git@git.vibes.dev/vibesdotdev/integrations.git",
84
+ "directory": "integrations/custom"
85
+ },
86
+ "publishConfig": {
87
+ "registry": "https://packages.vibes.dev",
88
+ "access": "public"
89
+ },
90
+ "vibes": {
91
+ "visibility": "public",
92
+ "registry": {
93
+ "repositoryId": "70be51c9-5ab7-4d7e-9f47-801cb17720d8",
94
+ "directory": "integrations/custom"
95
+ }
96
+ },
97
+ "type": "module",
98
+ "types": "./dist/index.d.ts",
99
+ "license": "BUSL-1.1"
100
+ }