@agents-at-scale/ark 0.1.41 → 0.1.43

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 (79) hide show
  1. package/dist/arkServices.js +0 -9
  2. package/dist/commands/completion/index.js +46 -1
  3. package/dist/commands/evaluation/index.d.ts +3 -0
  4. package/dist/commands/evaluation/index.js +60 -0
  5. package/dist/commands/evaluation/index.spec.d.ts +1 -0
  6. package/dist/commands/evaluation/index.spec.js +161 -0
  7. package/dist/commands/generate/generators/team.js +4 -1
  8. package/dist/commands/install/index.js +27 -0
  9. package/dist/commands/marketplace/index.d.ts +4 -0
  10. package/dist/commands/marketplace/index.js +50 -0
  11. package/dist/commands/memory/index.d.ts +15 -0
  12. package/dist/commands/memory/index.js +130 -0
  13. package/dist/commands/memory/index.spec.d.ts +1 -0
  14. package/dist/commands/memory/index.spec.js +124 -0
  15. package/dist/commands/models/create.d.ts +5 -6
  16. package/dist/commands/models/create.js +14 -119
  17. package/dist/commands/models/create.spec.js +51 -0
  18. package/dist/commands/models/kubernetes/manifest-builder.d.ts +11 -0
  19. package/dist/commands/models/kubernetes/manifest-builder.js +109 -0
  20. package/dist/commands/models/kubernetes/secret-manager.d.ts +7 -0
  21. package/dist/commands/models/kubernetes/secret-manager.js +20 -0
  22. package/dist/commands/models/providers/azure.d.ts +31 -0
  23. package/dist/commands/models/providers/azure.js +82 -0
  24. package/dist/commands/models/providers/azure.spec.d.ts +1 -0
  25. package/dist/commands/models/providers/azure.spec.js +232 -0
  26. package/dist/commands/models/providers/bedrock.d.ts +37 -0
  27. package/dist/commands/models/providers/bedrock.js +105 -0
  28. package/dist/commands/models/providers/bedrock.spec.d.ts +1 -0
  29. package/dist/commands/models/providers/bedrock.spec.js +241 -0
  30. package/dist/commands/models/providers/factory.d.ts +18 -0
  31. package/dist/commands/models/providers/factory.js +31 -0
  32. package/dist/commands/models/providers/index.d.ts +17 -0
  33. package/dist/commands/models/providers/index.js +9 -0
  34. package/dist/commands/models/providers/openai.d.ts +28 -0
  35. package/dist/commands/models/providers/openai.js +68 -0
  36. package/dist/commands/models/providers/openai.spec.d.ts +1 -0
  37. package/dist/commands/models/providers/openai.spec.js +180 -0
  38. package/dist/commands/models/providers/types.d.ts +51 -0
  39. package/dist/commands/models/providers/types.js +1 -0
  40. package/dist/commands/queries/delete.d.ts +7 -0
  41. package/dist/commands/queries/delete.js +24 -0
  42. package/dist/commands/queries/delete.spec.d.ts +1 -0
  43. package/dist/commands/queries/delete.spec.js +74 -0
  44. package/dist/commands/queries/index.d.ts +3 -0
  45. package/dist/commands/queries/index.js +108 -0
  46. package/dist/commands/queries/list.d.ts +6 -0
  47. package/dist/commands/queries/list.js +66 -0
  48. package/dist/commands/queries/list.spec.d.ts +1 -0
  49. package/dist/commands/queries/list.spec.js +170 -0
  50. package/dist/commands/queries/validation.d.ts +2 -0
  51. package/dist/commands/queries/validation.js +10 -0
  52. package/dist/commands/queries/validation.spec.d.ts +1 -0
  53. package/dist/commands/queries/validation.spec.js +27 -0
  54. package/dist/commands/query/index.js +3 -1
  55. package/dist/commands/query/index.spec.js +24 -0
  56. package/dist/commands/uninstall/index.js +27 -0
  57. package/dist/components/ChatUI.js +2 -0
  58. package/dist/index.js +8 -0
  59. package/dist/lib/arkApiClient.d.ts +4 -0
  60. package/dist/lib/arkApiClient.js +57 -0
  61. package/dist/lib/errors.d.ts +1 -0
  62. package/dist/lib/errors.js +1 -0
  63. package/dist/lib/executeEvaluation.d.ts +16 -0
  64. package/dist/lib/executeEvaluation.js +155 -0
  65. package/dist/lib/executeQuery.d.ts +1 -4
  66. package/dist/lib/executeQuery.js +98 -68
  67. package/dist/lib/executeQuery.spec.js +176 -99
  68. package/dist/lib/kubectl.d.ts +15 -0
  69. package/dist/lib/kubectl.js +47 -0
  70. package/dist/lib/kubectl.spec.d.ts +1 -0
  71. package/dist/lib/kubectl.spec.js +176 -0
  72. package/dist/lib/stdin.d.ts +1 -0
  73. package/dist/lib/stdin.js +16 -0
  74. package/dist/lib/stdin.spec.d.ts +1 -0
  75. package/dist/lib/stdin.spec.js +82 -0
  76. package/dist/lib/types.d.ts +39 -0
  77. package/dist/marketplaceServices.d.ts +15 -0
  78. package/dist/marketplaceServices.js +51 -0
  79. package/package.json +2 -1
@@ -0,0 +1,124 @@
1
+ import { describe, it, expect, jest, beforeEach, afterEach, beforeAll, } from '@jest/globals';
2
+ // ESM-safe mocking: declare variables to hold dynamically imported modules
3
+ let createMemoryCommand;
4
+ let deleteSession;
5
+ let deleteQuery;
6
+ let deleteAll;
7
+ let ArkApiProxy;
8
+ let output;
9
+ // Mock dependencies
10
+ jest.unstable_mockModule('../../lib/output.js', () => ({
11
+ default: {
12
+ info: jest.fn(),
13
+ success: jest.fn(),
14
+ error: jest.fn(),
15
+ },
16
+ }));
17
+ // Mock ArkApiProxy with a simpler approach
18
+ jest.unstable_mockModule('../../lib/arkApiProxy.js', () => ({
19
+ __esModule: true,
20
+ ArkApiProxy: jest.fn().mockImplementation(() => ({
21
+ start: jest.fn(),
22
+ stop: jest.fn(),
23
+ })),
24
+ }));
25
+ beforeAll(async () => {
26
+ // After mocks are registered, dynamically import modules
27
+ ({ ArkApiProxy } = await import('../../lib/arkApiProxy.js'));
28
+ ({ default: output } = await import('../../lib/output.js'));
29
+ ({ createMemoryCommand, deleteSession, deleteQuery, deleteAll } = await import('./index.js'));
30
+ });
31
+ describe('Memory Command', () => {
32
+ let mockConfig;
33
+ beforeEach(() => {
34
+ jest.clearAllMocks();
35
+ mockConfig = {};
36
+ });
37
+ afterEach(() => {
38
+ jest.restoreAllMocks();
39
+ });
40
+ describe('Command Structure', () => {
41
+ it('should create memory command with correct structure', () => {
42
+ const command = createMemoryCommand(mockConfig);
43
+ expect(command.name()).toBe('memory');
44
+ expect(command.alias()).toBe('mem');
45
+ expect(command.description()).toBe('Manage memory sessions and queries');
46
+ });
47
+ it('should have list subcommand', () => {
48
+ const command = createMemoryCommand(mockConfig);
49
+ const subcommands = command.commands.map((cmd) => cmd.name());
50
+ expect(subcommands).toContain('list');
51
+ });
52
+ it('should have delete subcommand with nested commands and flags', () => {
53
+ const command = createMemoryCommand(mockConfig);
54
+ const deleteCommand = command.commands.find((cmd) => cmd.name() === 'delete');
55
+ expect(deleteCommand).toBeDefined();
56
+ expect(deleteCommand?.description()).toBe('Delete memory data');
57
+ const deleteSubcommands = deleteCommand?.commands.map((cmd) => cmd.name()) || [];
58
+ expect(deleteSubcommands).toContain('session');
59
+ expect(deleteSubcommands).toContain('query');
60
+ // --all flag is supported on the delete root instead of an 'all' subcommand
61
+ });
62
+ });
63
+ describe('Command Creation', () => {
64
+ it('should create command without errors', () => {
65
+ expect(() => createMemoryCommand(mockConfig)).not.toThrow();
66
+ });
67
+ it('should return a command object', () => {
68
+ const command = createMemoryCommand(mockConfig);
69
+ expect(command).toBeDefined();
70
+ expect(typeof command.name).toBe('function');
71
+ expect(typeof command.description).toBe('function');
72
+ });
73
+ });
74
+ describe('Error Scenarios', () => {
75
+ let exitSpy;
76
+ beforeEach(async () => {
77
+ exitSpy = jest
78
+ .spyOn(process, 'exit')
79
+ .mockImplementation(((..._args) => undefined));
80
+ });
81
+ afterEach(() => {
82
+ exitSpy.mockRestore();
83
+ });
84
+ it('deleteSession handles 500 error', async () => {
85
+ const err = new Error('Internal Server Error');
86
+ const fakeClient = {
87
+ deleteSession: jest.fn().mockRejectedValue(err),
88
+ };
89
+ ArkApiProxy.mockImplementation(() => ({
90
+ start: jest.fn().mockResolvedValue(fakeClient),
91
+ stop: jest.fn(),
92
+ }));
93
+ await deleteSession('sess-1', { output: 'text' }).catch(() => { });
94
+ expect(output.error).toHaveBeenCalled();
95
+ expect(process.exit).toHaveBeenCalledWith(1);
96
+ });
97
+ it('deleteQuery handles network timeout', async () => {
98
+ const err = new Error('Network timeout');
99
+ const fakeClient = {
100
+ deleteQueryMessages: jest.fn().mockRejectedValue(err),
101
+ };
102
+ ArkApiProxy.mockImplementation(() => ({
103
+ start: jest.fn().mockResolvedValue(fakeClient),
104
+ stop: jest.fn(),
105
+ }));
106
+ await deleteQuery('sess-2', 'query-9', { output: 'text' }).catch(() => { });
107
+ expect(output.error).toHaveBeenCalled();
108
+ expect(process.exit).toHaveBeenCalledWith(1);
109
+ });
110
+ it('deleteAll handles no memory services reachable', async () => {
111
+ const err = new Error('No memory services reachable');
112
+ const fakeClient = {
113
+ deleteAllSessions: jest.fn().mockRejectedValue(err),
114
+ };
115
+ ArkApiProxy.mockImplementation(() => ({
116
+ start: jest.fn().mockResolvedValue(fakeClient),
117
+ stop: jest.fn(),
118
+ }));
119
+ await deleteAll({ output: 'text' }).catch(() => { });
120
+ expect(output.error).toHaveBeenCalled();
121
+ expect(process.exit).toHaveBeenCalledWith(1);
122
+ });
123
+ });
124
+ });
@@ -1,9 +1,8 @@
1
- export interface CreateModelOptions {
2
- type?: string;
3
- model?: string;
4
- baseUrl?: string;
5
- apiKey?: string;
6
- apiVersion?: string;
1
+ import { BaseCollectorOptions } from './providers/index.js';
2
+ /**
3
+ * Common options for model creation.
4
+ */
5
+ export interface CreateModelOptions extends BaseCollectorOptions {
7
6
  yes?: boolean;
8
7
  }
9
8
  export declare function createModel(modelName?: string, options?: CreateModelOptions): Promise<boolean>;
@@ -1,6 +1,9 @@
1
1
  import { execa } from 'execa';
2
2
  import inquirer from 'inquirer';
3
3
  import output from '../../lib/output.js';
4
+ import { ProviderConfigCollectorFactory, } from './providers/index.js';
5
+ import { KubernetesSecretManager } from './kubernetes/secret-manager.js';
6
+ import { KubernetesModelManifestBuilder } from './kubernetes/manifest-builder.js';
4
7
  export async function createModel(modelName, options = {}) {
5
8
  // Step 1: Get model name if not provided
6
9
  if (!modelName) {
@@ -56,6 +59,7 @@ export async function createModel(modelName, options = {}) {
56
59
  choices: [
57
60
  { name: 'Azure OpenAI', value: 'azure' },
58
61
  { name: 'OpenAI', value: 'openai' },
62
+ { name: 'AWS Bedrock', value: 'bedrock' },
59
63
  ],
60
64
  default: 'azure',
61
65
  },
@@ -75,133 +79,24 @@ export async function createModel(modelName, options = {}) {
75
79
  ]);
76
80
  model = answer.model;
77
81
  }
78
- // Step 4: Get base URL
79
- let baseUrl = options.baseUrl;
80
- if (!baseUrl) {
81
- const answer = await inquirer.prompt([
82
- {
83
- type: 'input',
84
- name: 'baseUrl',
85
- message: 'base URL:',
86
- validate: (input) => {
87
- if (!input)
88
- return 'base URL is required';
89
- try {
90
- new URL(input);
91
- return true;
92
- }
93
- catch {
94
- return 'please enter a valid URL';
95
- }
96
- },
97
- },
98
- ]);
99
- baseUrl = answer.baseUrl;
100
- }
101
- // Validate and clean base URL
102
- if (!baseUrl) {
103
- output.error('base URL is required');
104
- return false;
105
- }
106
- baseUrl = baseUrl.replace(/\/$/, '');
107
- // Step 5: Get API version (Azure only)
108
- let apiVersion = options.apiVersion || '';
109
- if (modelType === 'azure' && !options.apiVersion) {
110
- const answer = await inquirer.prompt([
111
- {
112
- type: 'input',
113
- name: 'apiVersion',
114
- message: 'Azure API version:',
115
- default: '2024-12-01-preview',
116
- },
117
- ]);
118
- apiVersion = answer.apiVersion;
119
- }
120
- // Step 6: Get API key
121
- let apiKey = options.apiKey;
122
- if (!apiKey) {
123
- const answer = await inquirer.prompt([
124
- {
125
- type: 'password',
126
- name: 'apiKey',
127
- message: 'API key:',
128
- mask: '*',
129
- validate: (input) => {
130
- if (!input)
131
- return 'API key is required';
132
- return true;
133
- },
134
- },
135
- ]);
136
- apiKey = answer.apiKey;
137
- }
138
- // Step 6: Create the Kubernetes secret
139
- const secretName = `${modelName}-model-api-key`;
82
+ // Step 4: Collect provider-specific configuration
83
+ const collector = ProviderConfigCollectorFactory.create(modelType);
84
+ const config = await collector.collectConfig({ ...options, model });
85
+ config.secretName = `${modelName}-model-secret`;
86
+ // Step 5: Create the Kubernetes secret
140
87
  try {
141
- await execa('kubectl', [
142
- 'create',
143
- 'secret',
144
- 'generic',
145
- secretName,
146
- `--from-literal=api-key=${apiKey}`,
147
- ], { stdio: 'pipe' });
148
- output.success(`created secret ${secretName}`);
88
+ const secretManager = new KubernetesSecretManager();
89
+ await secretManager.createSecret(config);
149
90
  }
150
91
  catch (error) {
151
92
  output.error('failed to create secret');
152
93
  console.error(error);
153
94
  return false;
154
95
  }
155
- // Step 7: Create the Model resource
96
+ // Step 6: Create the Model resource
156
97
  output.info(`creating model ${modelName}...`);
157
- const modelManifest = {
158
- apiVersion: 'ark.mckinsey.com/v1alpha1',
159
- kind: 'Model',
160
- metadata: {
161
- name: modelName,
162
- },
163
- spec: {
164
- type: modelType,
165
- model: {
166
- value: model,
167
- },
168
- config: {},
169
- },
170
- };
171
- // Add provider-specific config
172
- if (modelType === 'azure') {
173
- modelManifest.spec.config.azure = {
174
- apiKey: {
175
- valueFrom: {
176
- secretKeyRef: {
177
- name: secretName,
178
- key: 'api-key',
179
- },
180
- },
181
- },
182
- baseUrl: {
183
- value: baseUrl,
184
- },
185
- apiVersion: {
186
- value: apiVersion,
187
- },
188
- };
189
- }
190
- else {
191
- modelManifest.spec.config.openai = {
192
- apiKey: {
193
- valueFrom: {
194
- secretKeyRef: {
195
- name: secretName,
196
- key: 'api-key',
197
- },
198
- },
199
- },
200
- baseUrl: {
201
- value: baseUrl,
202
- },
203
- };
204
- }
98
+ const manifestBuilder = new KubernetesModelManifestBuilder(modelName);
99
+ const modelManifest = manifestBuilder.build(config);
205
100
  try {
206
101
  // Apply the model manifest using kubectl
207
102
  const manifestJson = JSON.stringify(modelManifest);
@@ -25,6 +25,57 @@ describe('createModel', () => {
25
25
  beforeEach(() => {
26
26
  jest.clearAllMocks();
27
27
  });
28
+ it('creates new model for type aws bedrock', async () => {
29
+ mockExeca.mockRejectedValueOnce(new Error('not found')); // model doesn't exist
30
+ mockInquirer.prompt
31
+ .mockResolvedValueOnce({ modelType: 'bedrock' }) // user selects from list
32
+ .mockResolvedValueOnce({ model: 'anthropic.claude-3-sonnet-20240229-v1:0' })
33
+ .mockResolvedValueOnce({ region: 'us-east-1' })
34
+ .mockResolvedValueOnce({ accessKeyId: 'AKIAIOSFODNN7EXAMPLE' })
35
+ .mockResolvedValueOnce({
36
+ secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
37
+ })
38
+ .mockResolvedValueOnce({ sessionToken: 'optional-session-token' })
39
+ .mockResolvedValueOnce({
40
+ modelArn: 'arn:aws:bedrock:us-east-1:123456789012:model/anthropic.claude-3-sonnet-20240229-v1:0',
41
+ });
42
+ mockExeca.mockResolvedValue({}); // kubectl ops succeed
43
+ await createModel('test-model');
44
+ // Verify that model type prompt was called
45
+ expect(mockInquirer.prompt).toHaveBeenCalledWith([
46
+ expect.objectContaining({
47
+ type: 'list',
48
+ name: 'modelType',
49
+ message: 'select model provider:',
50
+ choices: expect.arrayContaining([
51
+ { name: 'Azure OpenAI', value: 'azure' },
52
+ { name: 'OpenAI', value: 'openai' },
53
+ { name: 'AWS Bedrock', value: 'bedrock' },
54
+ ]),
55
+ }),
56
+ ]);
57
+ // Verify Bedrock-specific prompts were called
58
+ expect(mockInquirer.prompt).toHaveBeenCalledWith([
59
+ expect.objectContaining({
60
+ name: 'region',
61
+ message: 'AWS region:',
62
+ }),
63
+ ]);
64
+ expect(mockInquirer.prompt).toHaveBeenCalledWith([
65
+ expect.objectContaining({
66
+ name: 'accessKeyId',
67
+ message: 'AWS access key ID:',
68
+ }),
69
+ ]);
70
+ expect(mockInquirer.prompt).toHaveBeenCalledWith([
71
+ expect.objectContaining({
72
+ name: 'secretAccessKey',
73
+ message: 'AWS secret access key:',
74
+ type: 'password',
75
+ }),
76
+ ]);
77
+ expect(mockOutput.success).toHaveBeenCalledWith('model test-model created');
78
+ });
28
79
  it('creates new model with provided name', async () => {
29
80
  // Model doesn't exist
30
81
  mockExeca.mockRejectedValueOnce(new Error('not found'));
@@ -0,0 +1,11 @@
1
+ import { ProviderConfig } from '../providers/index.js';
2
+ export interface ModelManifestBuilder {
3
+ build(config: ProviderConfig): Record<string, unknown>;
4
+ }
5
+ export declare class KubernetesModelManifestBuilder implements ModelManifestBuilder {
6
+ private modelName;
7
+ constructor(modelName: string);
8
+ build(config: ProviderConfig): Record<string, unknown>;
9
+ private buildProviderConfig;
10
+ private buildBedrockConfig;
11
+ }
@@ -0,0 +1,109 @@
1
+ // Kubernetes model manifest builder
2
+ export class KubernetesModelManifestBuilder {
3
+ constructor(modelName) {
4
+ this.modelName = modelName;
5
+ }
6
+ build(config) {
7
+ const manifest = {
8
+ apiVersion: 'ark.mckinsey.com/v1alpha1',
9
+ kind: 'Model',
10
+ metadata: {
11
+ name: this.modelName,
12
+ },
13
+ spec: {
14
+ type: config.type,
15
+ model: {
16
+ value: config.modelValue,
17
+ },
18
+ config: {},
19
+ },
20
+ };
21
+ manifest.spec.config = this.buildProviderConfig(config);
22
+ return manifest;
23
+ }
24
+ buildProviderConfig(config) {
25
+ if (config.type === 'azure') {
26
+ return {
27
+ azure: {
28
+ apiKey: {
29
+ valueFrom: {
30
+ secretKeyRef: {
31
+ name: config.secretName,
32
+ key: 'api-key',
33
+ },
34
+ },
35
+ },
36
+ baseUrl: {
37
+ value: config.baseUrl,
38
+ },
39
+ apiVersion: {
40
+ value: config.apiVersion,
41
+ },
42
+ },
43
+ };
44
+ }
45
+ if (config.type === 'bedrock') {
46
+ return this.buildBedrockConfig(config);
47
+ }
48
+ if (config.type === 'openai') {
49
+ return {
50
+ openai: {
51
+ apiKey: {
52
+ valueFrom: {
53
+ secretKeyRef: {
54
+ name: config.secretName,
55
+ key: 'api-key',
56
+ },
57
+ },
58
+ },
59
+ baseUrl: {
60
+ value: config.baseUrl,
61
+ },
62
+ },
63
+ };
64
+ }
65
+ throw new Error(`Unknown provider type: ${config.type}`);
66
+ }
67
+ buildBedrockConfig(config) {
68
+ const bedrockConfig = {
69
+ bedrock: {
70
+ region: {
71
+ value: config.region,
72
+ },
73
+ accessKeyId: {
74
+ valueFrom: {
75
+ secretKeyRef: {
76
+ name: config.secretName,
77
+ key: 'access-key-id',
78
+ },
79
+ },
80
+ },
81
+ secretAccessKey: {
82
+ valueFrom: {
83
+ secretKeyRef: {
84
+ name: config.secretName,
85
+ key: 'secret-access-key',
86
+ },
87
+ },
88
+ },
89
+ },
90
+ };
91
+ const bedrock = bedrockConfig.bedrock;
92
+ if (config.sessionToken) {
93
+ bedrock.sessionToken = {
94
+ valueFrom: {
95
+ secretKeyRef: {
96
+ name: config.secretName,
97
+ key: 'session-token',
98
+ },
99
+ },
100
+ };
101
+ }
102
+ if (config.modelArn) {
103
+ bedrock.modelArn = {
104
+ value: config.modelArn,
105
+ };
106
+ }
107
+ return bedrockConfig;
108
+ }
109
+ }
@@ -0,0 +1,7 @@
1
+ import { ProviderConfig } from '../providers/index.js';
2
+ export interface SecretManager {
3
+ createSecret(config: ProviderConfig): Promise<void>;
4
+ }
5
+ export declare class KubernetesSecretManager implements SecretManager {
6
+ createSecret(config: ProviderConfig): Promise<void>;
7
+ }
@@ -0,0 +1,20 @@
1
+ import { execa } from 'execa';
2
+ import output from '../../../lib/output.js';
3
+ // Kubernetes secret manager implementation
4
+ export class KubernetesSecretManager {
5
+ async createSecret(config) {
6
+ const secretArgs = ['create', 'secret', 'generic', config.secretName];
7
+ if (config.type === 'bedrock') {
8
+ secretArgs.push(`--from-literal=access-key-id=${config.accessKeyId}`);
9
+ secretArgs.push(`--from-literal=secret-access-key=${config.secretAccessKey}`);
10
+ if (config.sessionToken) {
11
+ secretArgs.push(`--from-literal=session-token=${config.sessionToken}`);
12
+ }
13
+ }
14
+ else {
15
+ secretArgs.push(`--from-literal=api-key=${config.apiKey}`);
16
+ }
17
+ await execa('kubectl', secretArgs, { stdio: 'pipe' });
18
+ output.success(`created secret ${config.secretName}`);
19
+ }
20
+ }
@@ -0,0 +1,31 @@
1
+ import { BaseProviderConfig, BaseCollectorOptions, ProviderConfigCollector } from './types.js';
2
+ /**
3
+ * Configuration for Azure OpenAI models.
4
+ */
5
+ export interface AzureConfig extends BaseProviderConfig {
6
+ type: 'azure';
7
+ baseUrl: string;
8
+ apiKey: string;
9
+ apiVersion: string;
10
+ }
11
+ /**
12
+ * Options specific to Azure collector.
13
+ */
14
+ export interface AzureCollectorOptions extends BaseCollectorOptions {
15
+ baseUrl?: string;
16
+ apiKey?: string;
17
+ apiVersion?: string;
18
+ }
19
+ /**
20
+ * Configuration collector for Azure OpenAI models.
21
+ *
22
+ * Collects the necessary configuration to connect to Azure OpenAI Service:
23
+ * - baseUrl: The Azure OpenAI endpoint URL (e.g., https://<resource>.openai.azure.com)
24
+ * - apiVersion: The API version to use (defaults to 2024-12-01-preview)
25
+ * - apiKey: The authentication key for the Azure OpenAI resource
26
+ *
27
+ * Values can be provided via command-line options or will be prompted interactively.
28
+ */
29
+ export declare class AzureConfigCollector implements ProviderConfigCollector {
30
+ collectConfig(options: BaseCollectorOptions): Promise<AzureConfig>;
31
+ }
@@ -0,0 +1,82 @@
1
+ import inquirer from 'inquirer';
2
+ /**
3
+ * Configuration collector for Azure OpenAI models.
4
+ *
5
+ * Collects the necessary configuration to connect to Azure OpenAI Service:
6
+ * - baseUrl: The Azure OpenAI endpoint URL (e.g., https://<resource>.openai.azure.com)
7
+ * - apiVersion: The API version to use (defaults to 2024-12-01-preview)
8
+ * - apiKey: The authentication key for the Azure OpenAI resource
9
+ *
10
+ * Values can be provided via command-line options or will be prompted interactively.
11
+ */
12
+ export class AzureConfigCollector {
13
+ async collectConfig(options) {
14
+ const azureOptions = options;
15
+ let baseUrl = azureOptions.baseUrl;
16
+ if (!baseUrl) {
17
+ const answer = await inquirer.prompt([
18
+ {
19
+ type: 'input',
20
+ name: 'baseUrl',
21
+ message: 'base URL:',
22
+ validate: (input) => {
23
+ if (!input)
24
+ return 'base URL is required';
25
+ try {
26
+ new URL(input);
27
+ return true;
28
+ }
29
+ catch {
30
+ return 'please enter a valid URL';
31
+ }
32
+ },
33
+ },
34
+ ]);
35
+ baseUrl = answer.baseUrl;
36
+ }
37
+ if (!baseUrl) {
38
+ throw new Error('base URL is required');
39
+ }
40
+ baseUrl = baseUrl.replace(/\/$/, '');
41
+ let apiVersion = azureOptions.apiVersion || '';
42
+ if (!azureOptions.apiVersion) {
43
+ const answer = await inquirer.prompt([
44
+ {
45
+ type: 'input',
46
+ name: 'apiVersion',
47
+ message: 'Azure API version:',
48
+ default: '2024-12-01-preview',
49
+ },
50
+ ]);
51
+ apiVersion = answer.apiVersion;
52
+ }
53
+ let apiKey = azureOptions.apiKey;
54
+ if (!apiKey) {
55
+ const answer = await inquirer.prompt([
56
+ {
57
+ type: 'password',
58
+ name: 'apiKey',
59
+ message: 'API key:',
60
+ mask: '*',
61
+ validate: (input) => {
62
+ if (!input)
63
+ return 'API key is required';
64
+ return true;
65
+ },
66
+ },
67
+ ]);
68
+ apiKey = answer.apiKey;
69
+ }
70
+ if (!apiKey) {
71
+ throw new Error('API key is required');
72
+ }
73
+ return {
74
+ type: 'azure',
75
+ modelValue: options.model,
76
+ secretName: '',
77
+ baseUrl,
78
+ apiKey,
79
+ apiVersion,
80
+ };
81
+ }
82
+ }
@@ -0,0 +1 @@
1
+ export {};