@shipfox/api-agent 12.2.0 → 13.1.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.
Files changed (132) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +19 -0
  3. package/dist/config.d.ts +5 -1
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +72 -7
  6. package/dist/config.js.map +1 -1
  7. package/dist/core/errors.d.ts +4 -0
  8. package/dist/core/errors.d.ts.map +1 -1
  9. package/dist/core/errors.js +6 -0
  10. package/dist/core/errors.js.map +1 -1
  11. package/dist/core/index.d.ts +2 -1
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +2 -1
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/model-provider-catalog.d.ts +5 -2
  16. package/dist/core/model-provider-catalog.d.ts.map +1 -1
  17. package/dist/core/model-provider-catalog.js +33 -1
  18. package/dist/core/model-provider-catalog.js.map +1 -1
  19. package/dist/core/resolve-agent-config.d.ts +4 -2
  20. package/dist/core/resolve-agent-config.d.ts.map +1 -1
  21. package/dist/core/resolve-agent-config.js +86 -31
  22. package/dist/core/resolve-agent-config.js.map +1 -1
  23. package/dist/core/resolve-runtime-credentials.d.ts +6 -2
  24. package/dist/core/resolve-runtime-credentials.d.ts.map +1 -1
  25. package/dist/core/resolve-runtime-credentials.js +59 -3
  26. package/dist/core/resolve-runtime-credentials.js.map +1 -1
  27. package/dist/core/validation-catalog.d.ts +2 -1
  28. package/dist/core/validation-catalog.d.ts.map +1 -1
  29. package/dist/core/validation-catalog.js +65 -17
  30. package/dist/core/validation-catalog.js.map +1 -1
  31. package/dist/core/workspace-agent-defaults-resolver.d.ts +2 -1
  32. package/dist/core/workspace-agent-defaults-resolver.d.ts.map +1 -1
  33. package/dist/core/workspace-agent-defaults-resolver.js +4 -2
  34. package/dist/core/workspace-agent-defaults-resolver.js.map +1 -1
  35. package/dist/core/workspace-provider-policy.d.ts +7 -0
  36. package/dist/core/workspace-provider-policy.d.ts.map +1 -0
  37. package/dist/core/workspace-provider-policy.js +10 -0
  38. package/dist/core/workspace-provider-policy.js.map +1 -0
  39. package/dist/index.d.ts +3 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +15 -4
  42. package/dist/index.js.map +1 -1
  43. package/dist/presentation/e2eRoutes/create-model-provider.d.ts +2 -1
  44. package/dist/presentation/e2eRoutes/create-model-provider.d.ts.map +1 -1
  45. package/dist/presentation/e2eRoutes/create-model-provider.js +7 -1
  46. package/dist/presentation/e2eRoutes/create-model-provider.js.map +1 -1
  47. package/dist/presentation/e2eRoutes/index.d.ts +2 -1
  48. package/dist/presentation/e2eRoutes/index.d.ts.map +1 -1
  49. package/dist/presentation/e2eRoutes/index.js +4 -2
  50. package/dist/presentation/e2eRoutes/index.js.map +1 -1
  51. package/dist/presentation/inter-module.d.ts +3 -0
  52. package/dist/presentation/inter-module.d.ts.map +1 -1
  53. package/dist/presentation/inter-module.js +22 -6
  54. package/dist/presentation/inter-module.js.map +1 -1
  55. package/dist/presentation/routes/create-custom-model-provider.d.ts +2 -1
  56. package/dist/presentation/routes/create-custom-model-provider.d.ts.map +1 -1
  57. package/dist/presentation/routes/create-custom-model-provider.js +5 -2
  58. package/dist/presentation/routes/create-custom-model-provider.js.map +1 -1
  59. package/dist/presentation/routes/delete-model-provider-config.d.ts +2 -1
  60. package/dist/presentation/routes/delete-model-provider-config.d.ts.map +1 -1
  61. package/dist/presentation/routes/delete-model-provider-config.js +7 -2
  62. package/dist/presentation/routes/delete-model-provider-config.js.map +1 -1
  63. package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.d.ts +2 -1
  64. package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.d.ts.map +1 -1
  65. package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.js +5 -2
  66. package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.js.map +1 -1
  67. package/dist/presentation/routes/discover-custom-model-provider-models.d.ts +2 -0
  68. package/dist/presentation/routes/discover-custom-model-provider-models.d.ts.map +1 -1
  69. package/dist/presentation/routes/discover-custom-model-provider-models.js +29 -23
  70. package/dist/presentation/routes/discover-custom-model-provider-models.js.map +1 -1
  71. package/dist/presentation/routes/errors.d.ts.map +1 -1
  72. package/dist/presentation/routes/errors.js +10 -1
  73. package/dist/presentation/routes/errors.js.map +1 -1
  74. package/dist/presentation/routes/index.d.ts +5 -1
  75. package/dist/presentation/routes/index.d.ts.map +1 -1
  76. package/dist/presentation/routes/index.js +21 -14
  77. package/dist/presentation/routes/index.js.map +1 -1
  78. package/dist/presentation/routes/list-model-provider-catalog.d.ts +5 -0
  79. package/dist/presentation/routes/list-model-provider-catalog.d.ts.map +1 -1
  80. package/dist/presentation/routes/list-model-provider-catalog.js +21 -13
  81. package/dist/presentation/routes/list-model-provider-catalog.js.map +1 -1
  82. package/dist/presentation/routes/set-default-model-provider.d.ts +2 -0
  83. package/dist/presentation/routes/set-default-model-provider.d.ts.map +1 -1
  84. package/dist/presentation/routes/set-default-model-provider.js +44 -38
  85. package/dist/presentation/routes/set-default-model-provider.js.map +1 -1
  86. package/dist/presentation/routes/update-custom-model-provider.d.ts +2 -1
  87. package/dist/presentation/routes/update-custom-model-provider.d.ts.map +1 -1
  88. package/dist/presentation/routes/update-custom-model-provider.js +5 -2
  89. package/dist/presentation/routes/update-custom-model-provider.js.map +1 -1
  90. package/dist/presentation/routes/update-model-provider-default-model.d.ts +2 -0
  91. package/dist/presentation/routes/update-model-provider-default-model.d.ts.map +1 -1
  92. package/dist/presentation/routes/update-model-provider-default-model.js +35 -29
  93. package/dist/presentation/routes/update-model-provider-default-model.js.map +1 -1
  94. package/dist/presentation/routes/upsert-model-provider-config.d.ts +2 -1
  95. package/dist/presentation/routes/upsert-model-provider-config.d.ts.map +1 -1
  96. package/dist/presentation/routes/upsert-model-provider-config.js +5 -2
  97. package/dist/presentation/routes/upsert-model-provider-config.js.map +1 -1
  98. package/dist/tsconfig.test.tsbuildinfo +1 -1
  99. package/package.json +2 -2
  100. package/src/config.test.ts +165 -4
  101. package/src/config.ts +94 -9
  102. package/src/core/errors.ts +7 -0
  103. package/src/core/index.ts +5 -0
  104. package/src/core/model-provider-catalog.test.ts +30 -0
  105. package/src/core/model-provider-catalog.ts +41 -1
  106. package/src/core/resolve-agent-config.test.ts +92 -0
  107. package/src/core/resolve-agent-config.ts +152 -43
  108. package/src/core/resolve-runtime-credentials.test.ts +169 -1
  109. package/src/core/resolve-runtime-credentials.ts +68 -3
  110. package/src/core/validation-catalog.test.ts +54 -0
  111. package/src/core/validation-catalog.ts +124 -19
  112. package/src/core/workspace-agent-defaults-resolver.ts +7 -2
  113. package/src/core/workspace-provider-policy.ts +19 -0
  114. package/src/index.ts +25 -4
  115. package/src/presentation/e2eRoutes/create-model-provider.ts +11 -1
  116. package/src/presentation/e2eRoutes/index.ts +9 -2
  117. package/src/presentation/inter-module.test.ts +51 -0
  118. package/src/presentation/inter-module.ts +38 -6
  119. package/src/presentation/routes/create-custom-model-provider.ts +10 -2
  120. package/src/presentation/routes/delete-model-provider-config.ts +12 -2
  121. package/src/presentation/routes/discover-custom-model-provider-models-by-slug.ts +7 -1
  122. package/src/presentation/routes/discover-custom-model-provider-models.ts +30 -18
  123. package/src/presentation/routes/errors.ts +11 -0
  124. package/src/presentation/routes/index.ts +32 -14
  125. package/src/presentation/routes/list-model-provider-catalog.ts +32 -11
  126. package/src/presentation/routes/model-provider-catalog.test.ts +49 -1
  127. package/src/presentation/routes/model-provider-config.test.ts +62 -1
  128. package/src/presentation/routes/set-default-model-provider.ts +42 -31
  129. package/src/presentation/routes/update-custom-model-provider.ts +10 -2
  130. package/src/presentation/routes/update-model-provider-default-model.ts +37 -26
  131. package/src/presentation/routes/upsert-model-provider-config.ts +10 -2
  132. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,24 +1,24 @@
1
1
  import { agentThinkingByHarness, DEFAULT_HARNESS, getHarnessDescriptor } from '@shipfox/api-agent-dto';
2
- import { InvalidAgentModelError, UnsupportedHarnessProviderError, UnsupportedHarnessThinkingError, UnsupportedModelProviderError } from './errors.js';
2
+ import { InvalidAgentModelError, UnsupportedHarnessProviderError, UnsupportedHarnessThinkingError, UnsupportedModelProviderError, WorkspaceProvidersDisabledError } from './errors.js';
3
3
  import { listHarnessProviderModels } from './harness/index.js';
4
4
  import { getModelProviderEntry } from './model-provider-policy.js';
5
5
  export function resolveAgentConfig(step, ctx = {}) {
6
6
  const harness = step.harness ?? ctx.workspaceDefaultHarnessId ?? DEFAULT_HARNESS;
7
7
  const provider = resolveProvider(step, ctx, harness);
8
- const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(provider);
8
+ const providerConfig = getProviderConfig(provider, ctx);
9
9
  const model = resolveModel({
10
10
  step,
11
11
  ctx,
12
12
  harness,
13
13
  provider,
14
- workspaceProviderConfig
14
+ providerConfig
15
15
  });
16
16
  const thinking = resolveThinking({
17
17
  step,
18
18
  ctx,
19
19
  harness,
20
20
  provider,
21
- workspaceProviderConfig
21
+ providerConfig
22
22
  });
23
23
  return {
24
24
  harness,
@@ -30,10 +30,24 @@ export function resolveAgentConfig(step, ctx = {}) {
30
30
  export const catalogDefaultAgentResolver = (step)=>resolveAgentConfig(step);
31
31
  function resolveProvider(step, ctx, harness) {
32
32
  const descriptor = getHarnessDescriptor(harness);
33
+ if (ctx.workspaceProviders === 'disabled') {
34
+ const managedProvider = ctx.managedProvider;
35
+ if (managedProvider === undefined) {
36
+ throw new Error('workspace provider configuration is disabled but no managed provider is registered');
37
+ }
38
+ if (step.provider !== undefined && step.provider !== managedProvider.id) {
39
+ throw new WorkspaceProvidersDisabledError(managedProvider.id);
40
+ }
41
+ const providerConfig = getProviderConfig(managedProvider.id, ctx);
42
+ if (!isHarnessCompatible(harness, managedProvider.id, providerConfig)) {
43
+ throw new UnsupportedHarnessProviderError(harness, managedProvider.id, supportedProviderIds(harness, descriptor, ctx));
44
+ }
45
+ return managedProvider.id;
46
+ }
33
47
  if (step.provider !== undefined) {
34
48
  const provider = resolveSupportedProvider(step.provider, ctx);
35
- if (!isHarnessCompatible(harness, provider, ctx.workspaceProviderConfigs?.get(provider))) {
36
- throw new UnsupportedHarnessProviderError(harness, step.provider, descriptor.supportedProviderIds);
49
+ if (!isHarnessCompatible(harness, provider, getProviderConfig(provider, ctx))) {
50
+ throw new UnsupportedHarnessProviderError(harness, step.provider, supportedProviderIds(harness, descriptor, ctx));
37
51
  }
38
52
  return provider;
39
53
  }
@@ -44,13 +58,14 @@ function resolveProvider(step, ctx, harness) {
44
58
  ];
45
59
  for (const candidate of candidates){
46
60
  if (candidate === undefined || candidate === null) continue;
47
- const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(candidate);
48
- if (!isHarnessCompatible(harness, candidate, workspaceProviderConfig)) continue;
61
+ const providerConfig = getProviderConfig(candidate, ctx);
62
+ if (!isHarnessCompatible(harness, candidate, providerConfig)) continue;
49
63
  return resolveSupportedProvider(candidate, ctx);
50
64
  }
51
65
  return descriptor.defaultProviderId;
52
66
  }
53
67
  function resolveSupportedProvider(provider, ctx) {
68
+ if (ctx.managedProvider?.id === provider) return provider;
54
69
  const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(provider);
55
70
  if (workspaceProviderConfig?.kind === 'custom') return provider;
56
71
  const entry = getModelProviderEntry(provider);
@@ -60,29 +75,30 @@ function resolveSupportedProvider(provider, ctx) {
60
75
  return provider;
61
76
  }
62
77
  function resolveModel(params) {
78
+ const providerConfig = params.providerConfig;
63
79
  if (params.step.model !== undefined) {
64
- validateModel(params.harness, params.provider, params.step.model, params.workspaceProviderConfig);
80
+ validateModel(params.harness, params.provider, params.step.model, params.providerConfig);
65
81
  return params.step.model;
66
82
  }
67
- const candidates = [
68
- ()=>params.workspaceProviderConfig?.defaultModel
69
- ];
70
- if (params.workspaceProviderConfig?.kind === 'custom') {
71
- candidates.push(()=>customDefaultModel(params.workspaceProviderConfig));
83
+ const candidates = [];
84
+ if (providerConfig?.kind === 'custom') {
85
+ candidates.push(()=>providerConfig.defaultModel, ()=>customDefaultModel(providerConfig));
86
+ } else if (providerConfig?.kind === 'managed') {
87
+ candidates.push(()=>instanceDefaultModel(params.provider, params.ctx), ()=>providerConfig.defaultModel, ()=>managedDefaultModel(params.harness, providerConfig));
72
88
  } else {
73
- candidates.push(()=>instanceDefaultModel(params.provider, params.ctx), ()=>catalogDefaultModel(params.harness, params.provider));
89
+ candidates.push(()=>providerConfig?.defaultModel, ()=>instanceDefaultModel(params.provider, params.ctx), ()=>catalogDefaultModel(params.harness, params.provider));
74
90
  }
75
91
  for (const resolveCandidate of candidates){
76
92
  const candidate = resolveCandidate();
77
93
  if (candidate === undefined || candidate === null) continue;
78
- if (modelIsAvailable(params.harness, params.provider, candidate, params.workspaceProviderConfig)) {
94
+ if (modelIsAvailable(params.harness, params.provider, candidate, params.providerConfig)) {
79
95
  return candidate;
80
96
  }
81
97
  }
82
98
  throw new InvalidAgentModelError(params.harness, params.provider, '');
83
99
  }
84
100
  function catalogDefaultModel(harness, provider) {
85
- const catalogModels = listProviderModels(harness, provider);
101
+ const catalogModels = listProviderModels(harness, provider, undefined);
86
102
  const entry = getModelProviderEntry(provider);
87
103
  if (entry === undefined || entry.support_status !== 'supported') {
88
104
  throw new UnsupportedModelProviderError(provider);
@@ -100,25 +116,34 @@ function instanceDefaultModel(provider, ctx) {
100
116
  function instanceDefaultThinking(provider, ctx) {
101
117
  return provider === ctx.instanceDefaultProvider ? ctx.instanceDefaultThinking : undefined;
102
118
  }
103
- function customDefaultModel(workspaceProviderConfig) {
104
- if (workspaceProviderConfig?.kind !== 'custom') return undefined;
105
- return workspaceProviderConfig.models?.[0]?.id;
119
+ function customDefaultModel(providerConfig) {
120
+ if (providerConfig?.kind !== 'custom') return undefined;
121
+ return providerConfig.models?.[0]?.id;
122
+ }
123
+ function managedDefaultModel(harness, providerConfig) {
124
+ return listManagedProviderModels(harness, providerConfig)[0]?.id;
106
125
  }
107
- function validateModel(harness, provider, model, workspaceProviderConfig) {
108
- if (modelIsAvailable(harness, provider, model, workspaceProviderConfig)) return;
126
+ function validateModel(harness, provider, model, providerConfig) {
127
+ if (modelIsAvailable(harness, provider, model, providerConfig)) return;
109
128
  throw new InvalidAgentModelError(harness, provider, model);
110
129
  }
111
- function modelIsAvailable(harness, provider, model, workspaceProviderConfig) {
112
- if (workspaceProviderConfig?.kind === 'custom') {
113
- return workspaceProviderConfig.models?.some((candidate)=>candidate.id === model) ?? false;
130
+ function modelIsAvailable(harness, provider, model, providerConfig) {
131
+ if (providerConfig?.kind === 'custom') {
132
+ return providerConfig.models?.some((candidate)=>candidate.id === model) ?? false;
114
133
  }
115
- return listProviderModels(harness, provider).some((candidate)=>candidate.id === model);
134
+ return listProviderModels(harness, provider, providerConfig).some((candidate)=>candidate.id === model);
116
135
  }
117
- function listProviderModels(harness, provider) {
136
+ function listProviderModels(harness, provider, providerConfig) {
137
+ if (providerConfig?.kind === 'managed') {
138
+ return listManagedProviderModels(harness, providerConfig);
139
+ }
118
140
  return listHarnessProviderModels(harness, provider);
119
141
  }
120
- function isHarnessCompatible(harness, provider, workspaceProviderConfig) {
121
- if (workspaceProviderConfig?.kind === 'custom') return harness === 'pi';
142
+ function isHarnessCompatible(harness, provider, providerConfig) {
143
+ if (providerConfig?.kind === 'custom') return harness === 'pi';
144
+ if (providerConfig?.kind === 'managed') {
145
+ return listManagedProviderModels(harness, providerConfig).length > 0;
146
+ }
122
147
  return getHarnessDescriptor(harness).supportedProviderIds.includes(provider);
123
148
  }
124
149
  function resolveThinking(params) {
@@ -131,8 +156,12 @@ function resolveThinking(params) {
131
156
  }
132
157
  return parsed.data;
133
158
  }
134
- const candidates = [
135
- params.workspaceProviderConfig?.defaultThinking,
159
+ const candidates = params.providerConfig?.kind === 'managed' ? [
160
+ instanceDefaultThinking(params.provider, params.ctx),
161
+ params.providerConfig.defaultThinking,
162
+ descriptor.defaultThinking
163
+ ] : [
164
+ params.providerConfig?.defaultThinking,
136
165
  instanceDefaultThinking(params.provider, params.ctx),
137
166
  descriptor.defaultThinking
138
167
  ];
@@ -141,5 +170,31 @@ function resolveThinking(params) {
141
170
  }
142
171
  return descriptor.defaultThinking;
143
172
  }
173
+ function getProviderConfig(provider, ctx) {
174
+ if (ctx.managedProvider?.id === provider) {
175
+ return {
176
+ kind: 'managed',
177
+ defaultModel: ctx.managedProvider.defaultModel,
178
+ defaultThinking: ctx.managedProvider.defaultThinking,
179
+ models: ctx.managedProvider.models
180
+ };
181
+ }
182
+ return ctx.workspaceProviderConfigs?.get(provider);
183
+ }
184
+ function listManagedProviderModels(harness, providerConfig) {
185
+ return providerConfig.models.filter((model)=>managedModelSupportsHarness(harness, model));
186
+ }
187
+ function managedModelSupportsHarness(harness, model) {
188
+ return harness === 'pi' || model.api === 'anthropic-messages';
189
+ }
190
+ function supportedProviderIds(harness, descriptor, ctx) {
191
+ if (ctx.managedProvider === undefined || !ctx.managedProvider.models.some((model)=>managedModelSupportsHarness(harness, model))) {
192
+ return descriptor.supportedProviderIds;
193
+ }
194
+ return [
195
+ ...descriptor.supportedProviderIds,
196
+ ctx.managedProvider.id
197
+ ];
198
+ }
144
199
 
145
200
  //# sourceMappingURL=resolve-agent-config.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/resolve-agent-config.ts"],"sourcesContent":["import {\n type AgentThinking,\n agentThinkingByHarness,\n type CustomAgentModelDto,\n DEFAULT_HARNESS,\n getHarnessDescriptor,\n type Harness,\n type ModelProviderRef,\n type SupportedModelProviderId,\n} from '@shipfox/api-agent-dto';\nimport {\n InvalidAgentModelError,\n UnsupportedHarnessProviderError,\n UnsupportedHarnessThinkingError,\n UnsupportedModelProviderError,\n} from './errors.js';\nimport {listHarnessProviderModels} from './harness/index.js';\nimport {getModelProviderEntry} from './model-provider-policy.js';\n\nexport interface ContextualAgentConfig {\n readonly harness?: Harness | undefined;\n readonly provider?: string | undefined;\n readonly model?: string | undefined;\n /** A resolved template can carry any string. `resolveThinking` validates it. */\n readonly thinking?: string | undefined;\n}\n\nexport interface ResolvedAgentConfig {\n readonly harness: Harness;\n readonly provider: ModelProviderRef;\n readonly model: string;\n readonly thinking: AgentThinking;\n}\n\nexport type AgentDefaultsResolver = (step: ContextualAgentConfig) => ResolvedAgentConfig;\n\nexport interface AgentConfigResolutionContext {\n readonly workspaceDefaultHarnessId?: Harness | null | undefined;\n readonly workspaceDefaultProviderId?: ModelProviderRef | null | undefined;\n readonly workspaceProviderConfigs?: ReadonlyMap<ModelProviderRef, WorkspaceProviderDefaults>;\n readonly instanceDefaultProvider?: SupportedModelProviderId | undefined;\n readonly instanceDefaultModel?: string | undefined;\n readonly instanceDefaultThinking?: AgentThinking | undefined;\n}\n\ninterface WorkspaceProviderDefaults {\n readonly kind?: 'builtin' | 'custom' | undefined;\n readonly defaultModel: string | null;\n readonly defaultThinking: AgentThinking;\n readonly models?: readonly CustomAgentModelDto[] | null | undefined;\n}\n\ntype ModelCandidateResolver = () => string | null | undefined;\n\nexport function resolveAgentConfig(\n step: ContextualAgentConfig,\n ctx: AgentConfigResolutionContext = {},\n): ResolvedAgentConfig {\n const harness = step.harness ?? ctx.workspaceDefaultHarnessId ?? DEFAULT_HARNESS;\n const provider = resolveProvider(step, ctx, harness);\n const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(provider);\n const model = resolveModel({\n step,\n ctx,\n harness,\n provider,\n workspaceProviderConfig,\n });\n const thinking = resolveThinking({step, ctx, harness, provider, workspaceProviderConfig});\n\n return {harness, provider, model, thinking};\n}\n\nexport const catalogDefaultAgentResolver: AgentDefaultsResolver = (step) =>\n resolveAgentConfig(step);\n\nfunction resolveProvider(\n step: ContextualAgentConfig,\n ctx: AgentConfigResolutionContext,\n harness: Harness,\n): ModelProviderRef {\n const descriptor = getHarnessDescriptor(harness);\n if (step.provider !== undefined) {\n const provider = resolveSupportedProvider(step.provider, ctx);\n if (!isHarnessCompatible(harness, provider, ctx.workspaceProviderConfigs?.get(provider))) {\n throw new UnsupportedHarnessProviderError(\n harness,\n step.provider,\n descriptor.supportedProviderIds,\n );\n }\n return provider;\n }\n\n const candidates = [\n ctx.workspaceDefaultProviderId,\n ctx.instanceDefaultProvider,\n descriptor.defaultProviderId,\n ];\n for (const candidate of candidates) {\n if (candidate === undefined || candidate === null) continue;\n\n const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(candidate);\n if (!isHarnessCompatible(harness, candidate, workspaceProviderConfig)) continue;\n\n return resolveSupportedProvider(candidate, ctx);\n }\n\n return descriptor.defaultProviderId;\n}\n\nfunction resolveSupportedProvider(\n provider: string,\n ctx: AgentConfigResolutionContext,\n): ModelProviderRef {\n const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(provider);\n if (workspaceProviderConfig?.kind === 'custom') return provider;\n\n const entry = getModelProviderEntry(provider);\n if (entry === undefined || entry.support_status !== 'supported') {\n throw new UnsupportedModelProviderError(provider);\n }\n return provider as SupportedModelProviderId;\n}\n\nfunction resolveModel(params: {\n step: ContextualAgentConfig;\n ctx: AgentConfigResolutionContext;\n harness: Harness;\n provider: ModelProviderRef;\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined;\n}): string {\n if (params.step.model !== undefined) {\n validateModel(\n params.harness,\n params.provider,\n params.step.model,\n params.workspaceProviderConfig,\n );\n return params.step.model;\n }\n\n const candidates: ModelCandidateResolver[] = [() => params.workspaceProviderConfig?.defaultModel];\n if (params.workspaceProviderConfig?.kind === 'custom') {\n candidates.push(() => customDefaultModel(params.workspaceProviderConfig));\n } else {\n candidates.push(\n () => instanceDefaultModel(params.provider, params.ctx),\n () => catalogDefaultModel(params.harness, params.provider),\n );\n }\n\n for (const resolveCandidate of candidates) {\n const candidate = resolveCandidate();\n if (candidate === undefined || candidate === null) continue;\n if (\n modelIsAvailable(params.harness, params.provider, candidate, params.workspaceProviderConfig)\n ) {\n return candidate;\n }\n }\n\n throw new InvalidAgentModelError(params.harness, params.provider, '');\n}\n\nfunction catalogDefaultModel(harness: Harness, provider: ModelProviderRef): string {\n const catalogModels = listProviderModels(harness, provider);\n const entry = getModelProviderEntry(provider);\n if (entry === undefined || entry.support_status !== 'supported') {\n throw new UnsupportedModelProviderError(provider);\n }\n if (\n entry.default_model !== null &&\n catalogModels.some((candidate) => candidate.id === entry.default_model)\n ) {\n return entry.default_model;\n }\n\n const firstModel = catalogModels[0];\n if (firstModel === undefined) throw new InvalidAgentModelError(harness, provider, '');\n return firstModel.id;\n}\n\nfunction instanceDefaultModel(\n provider: ModelProviderRef,\n ctx: AgentConfigResolutionContext,\n): string | undefined {\n return provider === ctx.instanceDefaultProvider ? ctx.instanceDefaultModel : undefined;\n}\n\nfunction instanceDefaultThinking(\n provider: ModelProviderRef,\n ctx: AgentConfigResolutionContext,\n): AgentThinking | undefined {\n return provider === ctx.instanceDefaultProvider ? ctx.instanceDefaultThinking : undefined;\n}\n\nfunction customDefaultModel(\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined,\n): string | undefined {\n if (workspaceProviderConfig?.kind !== 'custom') return undefined;\n return workspaceProviderConfig.models?.[0]?.id;\n}\n\nfunction validateModel(\n harness: Harness,\n provider: ModelProviderRef,\n model: string,\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined,\n): void {\n if (modelIsAvailable(harness, provider, model, workspaceProviderConfig)) return;\n throw new InvalidAgentModelError(harness, provider, model);\n}\n\nfunction modelIsAvailable(\n harness: Harness,\n provider: ModelProviderRef,\n model: string,\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined,\n): boolean {\n if (workspaceProviderConfig?.kind === 'custom') {\n return workspaceProviderConfig.models?.some((candidate) => candidate.id === model) ?? false;\n }\n\n return listProviderModels(harness, provider).some((candidate) => candidate.id === model);\n}\n\nfunction listProviderModels(harness: Harness, provider: ModelProviderRef): readonly {id: string}[] {\n return listHarnessProviderModels(harness, provider);\n}\n\nfunction isHarnessCompatible(\n harness: Harness,\n provider: ModelProviderRef,\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined,\n): boolean {\n if (workspaceProviderConfig?.kind === 'custom') return harness === 'pi';\n\n return getHarnessDescriptor(harness).supportedProviderIds.includes(provider);\n}\n\nfunction resolveThinking(params: {\n step: ContextualAgentConfig;\n ctx: AgentConfigResolutionContext;\n harness: Harness;\n provider: ModelProviderRef;\n workspaceProviderConfig: WorkspaceProviderDefaults | undefined;\n}): AgentThinking {\n const thinkingSchema = agentThinkingByHarness[params.harness];\n const descriptor = getHarnessDescriptor(params.harness);\n\n if (params.step.thinking !== undefined) {\n const parsed = thinkingSchema.safeParse(params.step.thinking);\n if (!parsed.success) {\n throw new UnsupportedHarnessThinkingError(\n params.harness,\n params.step.thinking,\n descriptor.thinkingLevels,\n );\n }\n return parsed.data;\n }\n\n const candidates = [\n params.workspaceProviderConfig?.defaultThinking,\n instanceDefaultThinking(params.provider, params.ctx),\n descriptor.defaultThinking,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && thinkingSchema.safeParse(candidate).success) return candidate;\n }\n\n return descriptor.defaultThinking;\n}\n"],"names":["agentThinkingByHarness","DEFAULT_HARNESS","getHarnessDescriptor","InvalidAgentModelError","UnsupportedHarnessProviderError","UnsupportedHarnessThinkingError","UnsupportedModelProviderError","listHarnessProviderModels","getModelProviderEntry","resolveAgentConfig","step","ctx","harness","workspaceDefaultHarnessId","provider","resolveProvider","workspaceProviderConfig","workspaceProviderConfigs","get","model","resolveModel","thinking","resolveThinking","catalogDefaultAgentResolver","descriptor","undefined","resolveSupportedProvider","isHarnessCompatible","supportedProviderIds","candidates","workspaceDefaultProviderId","instanceDefaultProvider","defaultProviderId","candidate","kind","entry","support_status","params","validateModel","defaultModel","push","customDefaultModel","instanceDefaultModel","catalogDefaultModel","resolveCandidate","modelIsAvailable","catalogModels","listProviderModels","default_model","some","id","firstModel","instanceDefaultThinking","models","includes","thinkingSchema","parsed","safeParse","success","thinkingLevels","data","defaultThinking"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/resolve-agent-config.ts"],"sourcesContent":["import {\n type AgentThinking,\n agentThinkingByHarness,\n type CustomAgentModelDto,\n DEFAULT_HARNESS,\n getHarnessDescriptor,\n type Harness,\n type ManagedModelEntry,\n type ManagedModelProvider,\n type ModelProviderRef,\n type WorkspaceProvidersPolicy,\n} from '@shipfox/api-agent-dto';\nimport {\n InvalidAgentModelError,\n UnsupportedHarnessProviderError,\n UnsupportedHarnessThinkingError,\n UnsupportedModelProviderError,\n WorkspaceProvidersDisabledError,\n} from './errors.js';\nimport {listHarnessProviderModels} from './harness/index.js';\nimport {getModelProviderEntry} from './model-provider-policy.js';\n\nexport interface ContextualAgentConfig {\n readonly harness?: Harness | undefined;\n readonly provider?: string | undefined;\n readonly model?: string | undefined;\n /** A resolved template can carry any string. `resolveThinking` validates it. */\n readonly thinking?: string | undefined;\n}\n\nexport interface ResolvedAgentConfig {\n readonly harness: Harness;\n readonly provider: ModelProviderRef;\n readonly model: string;\n readonly thinking: AgentThinking;\n}\n\nexport type AgentDefaultsResolver = (step: ContextualAgentConfig) => ResolvedAgentConfig;\n\nexport interface AgentConfigResolutionContext {\n readonly workspaceDefaultHarnessId?: Harness | null | undefined;\n readonly workspaceDefaultProviderId?: ModelProviderRef | null | undefined;\n readonly workspaceProviderConfigs?: ReadonlyMap<ModelProviderRef, WorkspaceProviderDefaults>;\n readonly instanceDefaultProvider?: ModelProviderRef | undefined;\n readonly instanceDefaultModel?: string | undefined;\n readonly instanceDefaultThinking?: AgentThinking | undefined;\n readonly managedProvider?: ManagedModelProvider | undefined;\n readonly workspaceProviders?: WorkspaceProvidersPolicy | undefined;\n}\n\ninterface WorkspaceProviderDefaults {\n readonly kind?: 'builtin' | 'custom' | undefined;\n readonly defaultModel: string | null;\n readonly defaultThinking: AgentThinking;\n readonly models?: readonly CustomAgentModelDto[] | null | undefined;\n}\n\ninterface ManagedProviderDefaults {\n readonly kind: 'managed';\n readonly defaultModel: string;\n readonly defaultThinking?: AgentThinking | undefined;\n readonly models: readonly ManagedModelEntry[];\n}\n\ntype ProviderDefaults = WorkspaceProviderDefaults | ManagedProviderDefaults;\n\ntype ModelCandidateResolver = () => string | null | undefined;\n\nexport function resolveAgentConfig(\n step: ContextualAgentConfig,\n ctx: AgentConfigResolutionContext = {},\n): ResolvedAgentConfig {\n const harness = step.harness ?? ctx.workspaceDefaultHarnessId ?? DEFAULT_HARNESS;\n const provider = resolveProvider(step, ctx, harness);\n const providerConfig = getProviderConfig(provider, ctx);\n const model = resolveModel({\n step,\n ctx,\n harness,\n provider,\n providerConfig,\n });\n const thinking = resolveThinking({step, ctx, harness, provider, providerConfig});\n\n return {harness, provider, model, thinking};\n}\n\nexport const catalogDefaultAgentResolver: AgentDefaultsResolver = (step) =>\n resolveAgentConfig(step);\n\nfunction resolveProvider(\n step: ContextualAgentConfig,\n ctx: AgentConfigResolutionContext,\n harness: Harness,\n): ModelProviderRef {\n const descriptor = getHarnessDescriptor(harness);\n if (ctx.workspaceProviders === 'disabled') {\n const managedProvider = ctx.managedProvider;\n if (managedProvider === undefined) {\n throw new Error(\n 'workspace provider configuration is disabled but no managed provider is registered',\n );\n }\n if (step.provider !== undefined && step.provider !== managedProvider.id) {\n throw new WorkspaceProvidersDisabledError(managedProvider.id);\n }\n\n const providerConfig = getProviderConfig(managedProvider.id, ctx);\n if (!isHarnessCompatible(harness, managedProvider.id, providerConfig)) {\n throw new UnsupportedHarnessProviderError(\n harness,\n managedProvider.id,\n supportedProviderIds(harness, descriptor, ctx),\n );\n }\n return managedProvider.id;\n }\n\n if (step.provider !== undefined) {\n const provider = resolveSupportedProvider(step.provider, ctx);\n if (!isHarnessCompatible(harness, provider, getProviderConfig(provider, ctx))) {\n throw new UnsupportedHarnessProviderError(\n harness,\n step.provider,\n supportedProviderIds(harness, descriptor, ctx),\n );\n }\n return provider;\n }\n\n const candidates = [\n ctx.workspaceDefaultProviderId,\n ctx.instanceDefaultProvider,\n descriptor.defaultProviderId,\n ];\n for (const candidate of candidates) {\n if (candidate === undefined || candidate === null) continue;\n\n const providerConfig = getProviderConfig(candidate, ctx);\n if (!isHarnessCompatible(harness, candidate, providerConfig)) continue;\n\n return resolveSupportedProvider(candidate, ctx);\n }\n\n return descriptor.defaultProviderId;\n}\n\nfunction resolveSupportedProvider(\n provider: string,\n ctx: AgentConfigResolutionContext,\n): ModelProviderRef {\n if (ctx.managedProvider?.id === provider) return provider;\n\n const workspaceProviderConfig = ctx.workspaceProviderConfigs?.get(provider);\n if (workspaceProviderConfig?.kind === 'custom') return provider;\n\n const entry = getModelProviderEntry(provider);\n if (entry === undefined || entry.support_status !== 'supported') {\n throw new UnsupportedModelProviderError(provider);\n }\n return provider;\n}\n\nfunction resolveModel(params: {\n step: ContextualAgentConfig;\n ctx: AgentConfigResolutionContext;\n harness: Harness;\n provider: ModelProviderRef;\n providerConfig: ProviderDefaults | undefined;\n}): string {\n const providerConfig = params.providerConfig;\n\n if (params.step.model !== undefined) {\n validateModel(params.harness, params.provider, params.step.model, params.providerConfig);\n return params.step.model;\n }\n\n const candidates: ModelCandidateResolver[] = [];\n if (providerConfig?.kind === 'custom') {\n candidates.push(\n () => providerConfig.defaultModel,\n () => customDefaultModel(providerConfig),\n );\n } else if (providerConfig?.kind === 'managed') {\n candidates.push(\n () => instanceDefaultModel(params.provider, params.ctx),\n () => providerConfig.defaultModel,\n () => managedDefaultModel(params.harness, providerConfig),\n );\n } else {\n candidates.push(\n () => providerConfig?.defaultModel,\n () => instanceDefaultModel(params.provider, params.ctx),\n () => catalogDefaultModel(params.harness, params.provider),\n );\n }\n\n for (const resolveCandidate of candidates) {\n const candidate = resolveCandidate();\n if (candidate === undefined || candidate === null) continue;\n if (modelIsAvailable(params.harness, params.provider, candidate, params.providerConfig)) {\n return candidate;\n }\n }\n\n throw new InvalidAgentModelError(params.harness, params.provider, '');\n}\n\nfunction catalogDefaultModel(harness: Harness, provider: ModelProviderRef): string {\n const catalogModels = listProviderModels(harness, provider, undefined);\n const entry = getModelProviderEntry(provider);\n if (entry === undefined || entry.support_status !== 'supported') {\n throw new UnsupportedModelProviderError(provider);\n }\n if (\n entry.default_model !== null &&\n catalogModels.some((candidate) => candidate.id === entry.default_model)\n ) {\n return entry.default_model;\n }\n\n const firstModel = catalogModels[0];\n if (firstModel === undefined) throw new InvalidAgentModelError(harness, provider, '');\n return firstModel.id;\n}\n\nfunction instanceDefaultModel(\n provider: ModelProviderRef,\n ctx: AgentConfigResolutionContext,\n): string | undefined {\n return provider === ctx.instanceDefaultProvider ? ctx.instanceDefaultModel : undefined;\n}\n\nfunction instanceDefaultThinking(\n provider: ModelProviderRef,\n ctx: AgentConfigResolutionContext,\n): AgentThinking | undefined {\n return provider === ctx.instanceDefaultProvider ? ctx.instanceDefaultThinking : undefined;\n}\n\nfunction customDefaultModel(providerConfig: ProviderDefaults | undefined): string | undefined {\n if (providerConfig?.kind !== 'custom') return undefined;\n return providerConfig.models?.[0]?.id;\n}\n\nfunction managedDefaultModel(\n harness: Harness,\n providerConfig: ManagedProviderDefaults,\n): string | undefined {\n return listManagedProviderModels(harness, providerConfig)[0]?.id;\n}\n\nfunction validateModel(\n harness: Harness,\n provider: ModelProviderRef,\n model: string,\n providerConfig: ProviderDefaults | undefined,\n): void {\n if (modelIsAvailable(harness, provider, model, providerConfig)) return;\n throw new InvalidAgentModelError(harness, provider, model);\n}\n\nfunction modelIsAvailable(\n harness: Harness,\n provider: ModelProviderRef,\n model: string,\n providerConfig: ProviderDefaults | undefined,\n): boolean {\n if (providerConfig?.kind === 'custom') {\n return providerConfig.models?.some((candidate) => candidate.id === model) ?? false;\n }\n\n return listProviderModels(harness, provider, providerConfig).some(\n (candidate) => candidate.id === model,\n );\n}\n\nfunction listProviderModels(\n harness: Harness,\n provider: ModelProviderRef,\n providerConfig: ProviderDefaults | undefined,\n): readonly {id: string}[] {\n if (providerConfig?.kind === 'managed') {\n return listManagedProviderModels(harness, providerConfig);\n }\n return listHarnessProviderModels(harness, provider);\n}\n\nfunction isHarnessCompatible(\n harness: Harness,\n provider: ModelProviderRef,\n providerConfig: ProviderDefaults | undefined,\n): boolean {\n if (providerConfig?.kind === 'custom') return harness === 'pi';\n if (providerConfig?.kind === 'managed') {\n return listManagedProviderModels(harness, providerConfig).length > 0;\n }\n\n return getHarnessDescriptor(harness).supportedProviderIds.includes(provider);\n}\n\nfunction resolveThinking(params: {\n step: ContextualAgentConfig;\n ctx: AgentConfigResolutionContext;\n harness: Harness;\n provider: ModelProviderRef;\n providerConfig: ProviderDefaults | undefined;\n}): AgentThinking {\n const thinkingSchema = agentThinkingByHarness[params.harness];\n const descriptor = getHarnessDescriptor(params.harness);\n\n if (params.step.thinking !== undefined) {\n const parsed = thinkingSchema.safeParse(params.step.thinking);\n if (!parsed.success) {\n throw new UnsupportedHarnessThinkingError(\n params.harness,\n params.step.thinking,\n descriptor.thinkingLevels,\n );\n }\n return parsed.data;\n }\n\n const candidates =\n params.providerConfig?.kind === 'managed'\n ? [\n instanceDefaultThinking(params.provider, params.ctx),\n params.providerConfig.defaultThinking,\n descriptor.defaultThinking,\n ]\n : [\n params.providerConfig?.defaultThinking,\n instanceDefaultThinking(params.provider, params.ctx),\n descriptor.defaultThinking,\n ];\n for (const candidate of candidates) {\n if (candidate !== undefined && thinkingSchema.safeParse(candidate).success) return candidate;\n }\n\n return descriptor.defaultThinking;\n}\n\nfunction getProviderConfig(\n provider: ModelProviderRef,\n ctx: AgentConfigResolutionContext,\n): ProviderDefaults | undefined {\n if (ctx.managedProvider?.id === provider) {\n return {\n kind: 'managed',\n defaultModel: ctx.managedProvider.defaultModel,\n defaultThinking: ctx.managedProvider.defaultThinking,\n models: ctx.managedProvider.models,\n };\n }\n\n return ctx.workspaceProviderConfigs?.get(provider);\n}\n\nfunction listManagedProviderModels(\n harness: Harness,\n providerConfig: ManagedProviderDefaults,\n): readonly ManagedModelEntry[] {\n return providerConfig.models.filter((model) => managedModelSupportsHarness(harness, model));\n}\n\nfunction managedModelSupportsHarness(harness: Harness, model: ManagedModelEntry): boolean {\n return harness === 'pi' || model.api === 'anthropic-messages';\n}\n\nfunction supportedProviderIds(\n harness: Harness,\n descriptor: ReturnType<typeof getHarnessDescriptor>,\n ctx: AgentConfigResolutionContext,\n): readonly string[] {\n if (\n ctx.managedProvider === undefined ||\n !ctx.managedProvider.models.some((model) => managedModelSupportsHarness(harness, model))\n ) {\n return descriptor.supportedProviderIds;\n }\n\n return [...descriptor.supportedProviderIds, ctx.managedProvider.id];\n}\n"],"names":["agentThinkingByHarness","DEFAULT_HARNESS","getHarnessDescriptor","InvalidAgentModelError","UnsupportedHarnessProviderError","UnsupportedHarnessThinkingError","UnsupportedModelProviderError","WorkspaceProvidersDisabledError","listHarnessProviderModels","getModelProviderEntry","resolveAgentConfig","step","ctx","harness","workspaceDefaultHarnessId","provider","resolveProvider","providerConfig","getProviderConfig","model","resolveModel","thinking","resolveThinking","catalogDefaultAgentResolver","descriptor","workspaceProviders","managedProvider","undefined","Error","id","isHarnessCompatible","supportedProviderIds","resolveSupportedProvider","candidates","workspaceDefaultProviderId","instanceDefaultProvider","defaultProviderId","candidate","workspaceProviderConfig","workspaceProviderConfigs","get","kind","entry","support_status","params","validateModel","push","defaultModel","customDefaultModel","instanceDefaultModel","managedDefaultModel","catalogDefaultModel","resolveCandidate","modelIsAvailable","catalogModels","listProviderModels","default_model","some","firstModel","instanceDefaultThinking","models","listManagedProviderModels","length","includes","thinkingSchema","parsed","safeParse","success","thinkingLevels","data","defaultThinking","filter","managedModelSupportsHarness","api"],"mappings":"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"}
@@ -1,19 +1,23 @@
1
- import type { AgentRuntimeCredentialsResponseDto, AgentThinking, Harness, ModelProviderRef, SupportedModelProviderId } from '@shipfox/api-agent-dto';
1
+ import type { AgentRuntimeCredentialsResponseDto, AgentThinking, Harness, ManagedModelProvider, ModelProviderRef, WorkspaceProvidersPolicy } from '@shipfox/api-agent-dto';
2
2
  import { type AgentSecretsClient } from './secrets-client.js';
3
3
  export interface ResolveRuntimeCredentialsParams {
4
4
  workspaceId: string;
5
+ runId: string;
6
+ stepAttemptId: string;
5
7
  harness: Harness;
6
8
  provider: ModelProviderRef;
7
9
  model: string;
8
10
  thinking: AgentThinking;
9
11
  }
10
12
  interface RuntimeCredentialsConfig {
11
- AGENT_DEFAULT_PROVIDER?: SupportedModelProviderId | undefined;
13
+ AGENT_DEFAULT_PROVIDER?: ModelProviderRef | undefined;
12
14
  AGENT_DEFAULT_PROVIDER_API_KEY?: string | undefined;
13
15
  }
14
16
  interface ResolveRuntimeCredentialsOptions {
15
17
  runtimeConfig?: RuntimeCredentialsConfig | undefined;
18
+ workspaceProviders?: WorkspaceProvidersPolicy | undefined;
16
19
  secrets?: AgentSecretsClient | undefined;
20
+ managedProvider?: ManagedModelProvider | undefined;
17
21
  getCredentialBag?: ((params: {
18
22
  workspaceId: string;
19
23
  namespace: string;
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-runtime-credentials.d.ts","sourceRoot":"","sources":["../../src/core/resolve-runtime-credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,aAAa,EACb,OAAO,EACP,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAchC,OAAO,EAAC,KAAK,kBAAkB,EAA4B,MAAM,qBAAqB,CAAC;AAEvF,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED,UAAU,wBAAwB;IAChC,sBAAsB,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC9D,8BAA8B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrD;AAED,UAAU,gCAAgC;IACxC,aAAa,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IACrD,OAAO,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,gBAAgB,CAAC,EACb,CAAC,CAAC,MAAM,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GACvF,SAAS,CAAC;CACf;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,EACvC,OAAO,CAAC,EAAE,gCAAgC,GACzC,OAAO,CAAC,kCAAkC,CAAC,CA0D7C;AAED,wBAAgB,0CAA0C,CACxD,UAAU,EAAE,gBAAgB,GAC3B,SAAS,GAAG,SAAS,CAQvB"}
1
+ {"version":3,"file":"resolve-runtime-credentials.d.ts","sourceRoot":"","sources":["../../src/core/resolve-runtime-credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kCAAkC,EAClC,aAAa,EACb,OAAO,EACP,oBAAoB,EAEpB,gBAAgB,EAEhB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAchC,OAAO,EAAC,KAAK,kBAAkB,EAA4B,MAAM,qBAAqB,CAAC;AAEvF,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED,UAAU,wBAAwB;IAChC,sBAAsB,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACtD,8BAA8B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrD;AAED,UAAU,gCAAgC;IACxC,aAAa,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IACrD,kBAAkB,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;IAC1D,OAAO,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACzC,eAAe,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACnD,gBAAgB,CAAC,EACb,CAAC,CAAC,MAAM,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GACvF,SAAS,CAAC;CACf;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,+BAA+B,EACvC,OAAO,CAAC,EAAE,gCAAgC,GACzC,OAAO,CAAC,kCAAkC,CAAC,CAqF7C;AAED,wBAAgB,0CAA0C,CACxD,UAAU,EAAE,gBAAgB,GAC3B,SAAS,GAAG,SAAS,CAQvB"}
@@ -1,15 +1,43 @@
1
1
  import { secretsInterModuleContract } from '@shipfox/api-secrets-dto/inter-module';
2
2
  import { isInterModuleKnownError } from '@shipfox/inter-module';
3
- import { config } from '#config.js';
3
+ import { config, workspaceProvidersPolicy } from '#config.js';
4
4
  import { getModelProviderConfig } from '#db/index.js';
5
5
  import { agentRuntimeConfigResolvedCount } from '#metrics/index.js';
6
6
  import { agentSystemNamespace, storeValuesToCustomRuntimeCredentials, storeValuesToRuntimeCredentials } from './credential-fingerprints.js';
7
- import { ModelProviderConfigNotFoundError } from './errors.js';
7
+ import { ModelProviderConfigNotFoundError, WorkspaceProvidersDisabledError } from './errors.js';
8
8
  import { getModelProviderEntry, modelProviderCredentialKeysMatch } from './model-provider-policy.js';
9
9
  import { requireAgentSecretsClient } from './secrets-client.js';
10
10
  export async function resolveRuntimeCredentials(params, options) {
11
11
  const runtimeConfig = options?.runtimeConfig ?? config;
12
+ const configuredWorkspaceProviders = options?.workspaceProviders ?? workspaceProvidersPolicy;
12
13
  const secrets = options?.secrets;
14
+ const managedProvider = options?.managedProvider;
15
+ if (managedProvider?.id === params.provider) {
16
+ const managedRuntimeConfig = await managedProvider.resolveCredentials({
17
+ workspaceId: params.workspaceId,
18
+ runId: params.runId,
19
+ stepAttemptId: params.stepAttemptId,
20
+ model: params.model
21
+ });
22
+ agentRuntimeConfigResolvedCount.add(1, {
23
+ source: 'instance',
24
+ outcome: 'resolved'
25
+ });
26
+ return toResponse(params, managedRuntimeConfig.credentials, undefined, {
27
+ provider: managedProvider,
28
+ runtimeConfig: managedRuntimeConfig
29
+ });
30
+ }
31
+ if (configuredWorkspaceProviders === 'disabled') {
32
+ agentRuntimeConfigResolvedCount.add(1, {
33
+ source: params.provider === runtimeConfig.AGENT_DEFAULT_PROVIDER ? 'instance' : 'workspace',
34
+ outcome: 'unavailable'
35
+ });
36
+ if (managedProvider !== undefined) {
37
+ throw new WorkspaceProvidersDisabledError(managedProvider.id);
38
+ }
39
+ throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);
40
+ }
13
41
  const providerConfig = await getModelProviderConfig({
14
42
  workspaceId: params.workspaceId,
15
43
  providerId: params.provider
@@ -82,7 +110,7 @@ function instanceFallbackCredentials(providerId, runtimeConfig) {
82
110
  [fieldKey]: instanceApiKey
83
111
  };
84
112
  }
85
- function toResponse(params, credentials, providerConfig) {
113
+ function toResponse(params, credentials, providerConfig, managed) {
86
114
  const response = {
87
115
  harness: params.harness,
88
116
  provider_id: params.provider,
@@ -100,6 +128,34 @@ function toResponse(params, credentials, providerConfig) {
100
128
  requires_api_key: providerConfig.requiresApiKey
101
129
  };
102
130
  }
131
+ if (managed !== undefined) {
132
+ const model = managed.provider.models.find((candidate)=>candidate.id === params.model);
133
+ const modelDescriptor = {
134
+ id: params.model,
135
+ label: model?.label ?? params.model
136
+ };
137
+ if (params.harness === 'pi') {
138
+ response.custom_provider = {
139
+ api: managed.runtimeConfig.api,
140
+ base_url: managed.runtimeConfig.baseUrl,
141
+ headers: [],
142
+ secret_header_names: [],
143
+ models: [
144
+ modelDescriptor
145
+ ],
146
+ requires_api_key: true
147
+ };
148
+ } else {
149
+ const authToken = managed.runtimeConfig.credentials.api_key;
150
+ if (authToken === undefined) {
151
+ throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);
152
+ }
153
+ response.claude = {
154
+ base_url: managed.runtimeConfig.baseUrl,
155
+ auth_token: authToken
156
+ };
157
+ }
158
+ }
103
159
  return response;
104
160
  }
105
161
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/resolve-runtime-credentials.ts"],"sourcesContent":["import type {\n AgentRuntimeCredentialsResponseDto,\n AgentThinking,\n Harness,\n ModelProviderRef,\n SupportedModelProviderId,\n} from '@shipfox/api-agent-dto';\nimport {secretsInterModuleContract} from '@shipfox/api-secrets-dto/inter-module';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {config} from '#config.js';\nimport {getModelProviderConfig} from '#db/index.js';\nimport {agentRuntimeConfigResolvedCount} from '#metrics/index.js';\nimport {\n agentSystemNamespace,\n storeValuesToCustomRuntimeCredentials,\n storeValuesToRuntimeCredentials,\n} from './credential-fingerprints.js';\nimport type {ModelProviderConfig} from './entities/model-provider-config.js';\nimport {ModelProviderConfigNotFoundError} from './errors.js';\nimport {getModelProviderEntry, modelProviderCredentialKeysMatch} from './model-provider-policy.js';\nimport {type AgentSecretsClient, requireAgentSecretsClient} from './secrets-client.js';\n\nexport interface ResolveRuntimeCredentialsParams {\n workspaceId: string;\n harness: Harness;\n provider: ModelProviderRef;\n model: string;\n thinking: AgentThinking;\n}\n\ninterface RuntimeCredentialsConfig {\n AGENT_DEFAULT_PROVIDER?: SupportedModelProviderId | undefined;\n AGENT_DEFAULT_PROVIDER_API_KEY?: string | undefined;\n}\n\ninterface ResolveRuntimeCredentialsOptions {\n runtimeConfig?: RuntimeCredentialsConfig | undefined;\n secrets?: AgentSecretsClient | undefined;\n getCredentialBag?:\n | ((params: {workspaceId: string; namespace: string}) => Promise<Record<string, string>>)\n | undefined;\n}\n\nexport async function resolveRuntimeCredentials(\n params: ResolveRuntimeCredentialsParams,\n options?: ResolveRuntimeCredentialsOptions,\n): Promise<AgentRuntimeCredentialsResponseDto> {\n const runtimeConfig = options?.runtimeConfig ?? config;\n const secrets = options?.secrets;\n const providerConfig = await getModelProviderConfig({\n workspaceId: params.workspaceId,\n providerId: params.provider,\n });\n\n if (providerConfig) {\n try {\n const values = options?.getCredentialBag\n ? await options.getCredentialBag({\n workspaceId: params.workspaceId,\n namespace: agentSystemNamespace(params.provider),\n })\n : (\n await requireAgentSecretsClient(secrets).getSecretsByNamespace({\n workspaceId: params.workspaceId,\n namespace: agentSystemNamespace(params.provider),\n })\n ).values;\n if (providerConfig.kind === 'custom') {\n const credentials = storeValuesToCustomRuntimeCredentials(values);\n agentRuntimeConfigResolvedCount.add(1, {source: 'workspace', outcome: 'resolved'});\n return toResponse(params, credentials, providerConfig);\n }\n\n const providerId = params.provider as SupportedModelProviderId;\n const credentials = storeValuesToRuntimeCredentials(providerId, values);\n if (!modelProviderCredentialKeysMatch(providerId, credentials)) {\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n }\n agentRuntimeConfigResolvedCount.add(1, {source: 'workspace', outcome: 'resolved'});\n return toResponse(params, credentials, providerConfig);\n } catch (error) {\n if (\n isInterModuleKnownError(secretsInterModuleContract.methods.getSecretsByNamespace, error)\n ) {\n agentRuntimeConfigResolvedCount.add(1, {\n source: 'workspace',\n outcome: 'decryption_failed',\n });\n }\n throw error;\n }\n }\n\n const instanceCredentials = instanceFallbackCredentials(params.provider, runtimeConfig);\n if (instanceCredentials) {\n agentRuntimeConfigResolvedCount.add(1, {source: 'instance', outcome: 'resolved'});\n return toResponse(params, instanceCredentials);\n }\n\n agentRuntimeConfigResolvedCount.add(1, {\n source: params.provider === runtimeConfig.AGENT_DEFAULT_PROVIDER ? 'instance' : 'workspace',\n outcome: 'unavailable',\n });\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n}\n\nexport function getInstanceDefaultModelProviderApiKeyField(\n providerId: ModelProviderRef,\n): 'api_key' | undefined {\n const credentialFields =\n getModelProviderEntry(providerId as SupportedModelProviderId)?.credential_fields ?? [];\n const field = credentialFields[0];\n if (credentialFields.length !== 1 || field?.key !== 'api_key' || !field.secret) {\n return undefined;\n }\n return 'api_key';\n}\n\nfunction instanceFallbackCredentials(\n providerId: ModelProviderRef,\n runtimeConfig: RuntimeCredentialsConfig,\n): Record<string, string> | undefined {\n const instanceApiKey = runtimeConfig.AGENT_DEFAULT_PROVIDER_API_KEY;\n if (providerId !== runtimeConfig.AGENT_DEFAULT_PROVIDER || !instanceApiKey) return undefined;\n\n const fieldKey = getInstanceDefaultModelProviderApiKeyField(providerId);\n if (!fieldKey) return undefined;\n\n return {[fieldKey]: instanceApiKey};\n}\n\nfunction toResponse(\n params: ResolveRuntimeCredentialsParams,\n credentials: Record<string, string>,\n providerConfig?: ModelProviderConfig | undefined,\n): AgentRuntimeCredentialsResponseDto {\n const response: AgentRuntimeCredentialsResponseDto = {\n harness: params.harness,\n provider_id: params.provider,\n model: params.model,\n thinking: params.thinking,\n credentials,\n };\n\n if (providerConfig?.kind === 'custom') {\n response.custom_provider = {\n api: providerConfig.api ?? 'openai-responses',\n base_url: providerConfig.baseUrl ?? '',\n headers: providerConfig.headers ?? [],\n secret_header_names: Object.keys(credentials)\n .filter((key) => key.startsWith('header:'))\n .map((key) => key.slice('header:'.length))\n .sort(),\n models: providerConfig.models ?? [],\n requires_api_key: providerConfig.requiresApiKey,\n };\n }\n\n return response;\n}\n"],"names":["secretsInterModuleContract","isInterModuleKnownError","config","getModelProviderConfig","agentRuntimeConfigResolvedCount","agentSystemNamespace","storeValuesToCustomRuntimeCredentials","storeValuesToRuntimeCredentials","ModelProviderConfigNotFoundError","getModelProviderEntry","modelProviderCredentialKeysMatch","requireAgentSecretsClient","resolveRuntimeCredentials","params","options","runtimeConfig","secrets","providerConfig","workspaceId","providerId","provider","values","getCredentialBag","namespace","getSecretsByNamespace","kind","credentials","add","source","outcome","toResponse","error","methods","instanceCredentials","instanceFallbackCredentials","AGENT_DEFAULT_PROVIDER","getInstanceDefaultModelProviderApiKeyField","credentialFields","credential_fields","field","length","key","secret","undefined","instanceApiKey","AGENT_DEFAULT_PROVIDER_API_KEY","fieldKey","response","harness","provider_id","model","thinking","custom_provider","api","base_url","baseUrl","headers","secret_header_names","Object","keys","filter","startsWith","map","slice","sort","models","requires_api_key","requiresApiKey"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/resolve-runtime-credentials.ts"],"sourcesContent":["import type {\n AgentRuntimeCredentialsResponseDto,\n AgentThinking,\n Harness,\n ManagedModelProvider,\n ManagedProviderRuntimeConfig,\n ModelProviderRef,\n SupportedModelProviderId,\n WorkspaceProvidersPolicy,\n} from '@shipfox/api-agent-dto';\nimport {secretsInterModuleContract} from '@shipfox/api-secrets-dto/inter-module';\nimport {isInterModuleKnownError} from '@shipfox/inter-module';\nimport {config, workspaceProvidersPolicy} from '#config.js';\nimport {getModelProviderConfig} from '#db/index.js';\nimport {agentRuntimeConfigResolvedCount} from '#metrics/index.js';\nimport {\n agentSystemNamespace,\n storeValuesToCustomRuntimeCredentials,\n storeValuesToRuntimeCredentials,\n} from './credential-fingerprints.js';\nimport type {ModelProviderConfig} from './entities/model-provider-config.js';\nimport {ModelProviderConfigNotFoundError, WorkspaceProvidersDisabledError} from './errors.js';\nimport {getModelProviderEntry, modelProviderCredentialKeysMatch} from './model-provider-policy.js';\nimport {type AgentSecretsClient, requireAgentSecretsClient} from './secrets-client.js';\n\nexport interface ResolveRuntimeCredentialsParams {\n workspaceId: string;\n runId: string;\n stepAttemptId: string;\n harness: Harness;\n provider: ModelProviderRef;\n model: string;\n thinking: AgentThinking;\n}\n\ninterface RuntimeCredentialsConfig {\n AGENT_DEFAULT_PROVIDER?: ModelProviderRef | undefined;\n AGENT_DEFAULT_PROVIDER_API_KEY?: string | undefined;\n}\n\ninterface ResolveRuntimeCredentialsOptions {\n runtimeConfig?: RuntimeCredentialsConfig | undefined;\n workspaceProviders?: WorkspaceProvidersPolicy | undefined;\n secrets?: AgentSecretsClient | undefined;\n managedProvider?: ManagedModelProvider | undefined;\n getCredentialBag?:\n | ((params: {workspaceId: string; namespace: string}) => Promise<Record<string, string>>)\n | undefined;\n}\n\nexport async function resolveRuntimeCredentials(\n params: ResolveRuntimeCredentialsParams,\n options?: ResolveRuntimeCredentialsOptions,\n): Promise<AgentRuntimeCredentialsResponseDto> {\n const runtimeConfig = options?.runtimeConfig ?? config;\n const configuredWorkspaceProviders = options?.workspaceProviders ?? workspaceProvidersPolicy;\n const secrets = options?.secrets;\n const managedProvider = options?.managedProvider;\n if (managedProvider?.id === params.provider) {\n const managedRuntimeConfig = await managedProvider.resolveCredentials({\n workspaceId: params.workspaceId,\n runId: params.runId,\n stepAttemptId: params.stepAttemptId,\n model: params.model,\n });\n agentRuntimeConfigResolvedCount.add(1, {source: 'instance', outcome: 'resolved'});\n return toResponse(params, managedRuntimeConfig.credentials, undefined, {\n provider: managedProvider,\n runtimeConfig: managedRuntimeConfig,\n });\n }\n\n if (configuredWorkspaceProviders === 'disabled') {\n agentRuntimeConfigResolvedCount.add(1, {\n source: params.provider === runtimeConfig.AGENT_DEFAULT_PROVIDER ? 'instance' : 'workspace',\n outcome: 'unavailable',\n });\n if (managedProvider !== undefined) {\n throw new WorkspaceProvidersDisabledError(managedProvider.id);\n }\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n }\n\n const providerConfig = await getModelProviderConfig({\n workspaceId: params.workspaceId,\n providerId: params.provider,\n });\n\n if (providerConfig) {\n try {\n const values = options?.getCredentialBag\n ? await options.getCredentialBag({\n workspaceId: params.workspaceId,\n namespace: agentSystemNamespace(params.provider),\n })\n : (\n await requireAgentSecretsClient(secrets).getSecretsByNamespace({\n workspaceId: params.workspaceId,\n namespace: agentSystemNamespace(params.provider),\n })\n ).values;\n if (providerConfig.kind === 'custom') {\n const credentials = storeValuesToCustomRuntimeCredentials(values);\n agentRuntimeConfigResolvedCount.add(1, {source: 'workspace', outcome: 'resolved'});\n return toResponse(params, credentials, providerConfig);\n }\n\n const providerId = params.provider as SupportedModelProviderId;\n const credentials = storeValuesToRuntimeCredentials(providerId, values);\n if (!modelProviderCredentialKeysMatch(providerId, credentials)) {\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n }\n agentRuntimeConfigResolvedCount.add(1, {source: 'workspace', outcome: 'resolved'});\n return toResponse(params, credentials, providerConfig);\n } catch (error) {\n if (\n isInterModuleKnownError(secretsInterModuleContract.methods.getSecretsByNamespace, error)\n ) {\n agentRuntimeConfigResolvedCount.add(1, {\n source: 'workspace',\n outcome: 'decryption_failed',\n });\n }\n throw error;\n }\n }\n\n const instanceCredentials = instanceFallbackCredentials(params.provider, runtimeConfig);\n if (instanceCredentials) {\n agentRuntimeConfigResolvedCount.add(1, {source: 'instance', outcome: 'resolved'});\n return toResponse(params, instanceCredentials);\n }\n\n agentRuntimeConfigResolvedCount.add(1, {\n source: params.provider === runtimeConfig.AGENT_DEFAULT_PROVIDER ? 'instance' : 'workspace',\n outcome: 'unavailable',\n });\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n}\n\nexport function getInstanceDefaultModelProviderApiKeyField(\n providerId: ModelProviderRef,\n): 'api_key' | undefined {\n const credentialFields =\n getModelProviderEntry(providerId as SupportedModelProviderId)?.credential_fields ?? [];\n const field = credentialFields[0];\n if (credentialFields.length !== 1 || field?.key !== 'api_key' || !field.secret) {\n return undefined;\n }\n return 'api_key';\n}\n\nfunction instanceFallbackCredentials(\n providerId: ModelProviderRef,\n runtimeConfig: RuntimeCredentialsConfig,\n): Record<string, string> | undefined {\n const instanceApiKey = runtimeConfig.AGENT_DEFAULT_PROVIDER_API_KEY;\n if (providerId !== runtimeConfig.AGENT_DEFAULT_PROVIDER || !instanceApiKey) return undefined;\n\n const fieldKey = getInstanceDefaultModelProviderApiKeyField(providerId);\n if (!fieldKey) return undefined;\n\n return {[fieldKey]: instanceApiKey};\n}\n\nfunction toResponse(\n params: ResolveRuntimeCredentialsParams,\n credentials: Record<string, string>,\n providerConfig?: ModelProviderConfig | undefined,\n managed?:\n | {\n provider: ManagedModelProvider;\n runtimeConfig: ManagedProviderRuntimeConfig;\n }\n | undefined,\n): AgentRuntimeCredentialsResponseDto {\n const response: AgentRuntimeCredentialsResponseDto = {\n harness: params.harness,\n provider_id: params.provider,\n model: params.model,\n thinking: params.thinking,\n credentials,\n };\n\n if (providerConfig?.kind === 'custom') {\n response.custom_provider = {\n api: providerConfig.api ?? 'openai-responses',\n base_url: providerConfig.baseUrl ?? '',\n headers: providerConfig.headers ?? [],\n secret_header_names: Object.keys(credentials)\n .filter((key) => key.startsWith('header:'))\n .map((key) => key.slice('header:'.length))\n .sort(),\n models: providerConfig.models ?? [],\n requires_api_key: providerConfig.requiresApiKey,\n };\n }\n\n if (managed !== undefined) {\n const model = managed.provider.models.find((candidate) => candidate.id === params.model);\n const modelDescriptor = {id: params.model, label: model?.label ?? params.model};\n\n if (params.harness === 'pi') {\n response.custom_provider = {\n api: managed.runtimeConfig.api,\n base_url: managed.runtimeConfig.baseUrl,\n headers: [],\n secret_header_names: [],\n models: [modelDescriptor],\n requires_api_key: true,\n };\n } else {\n const authToken = managed.runtimeConfig.credentials.api_key;\n if (authToken === undefined) {\n throw new ModelProviderConfigNotFoundError(params.workspaceId, params.provider);\n }\n response.claude = {\n base_url: managed.runtimeConfig.baseUrl,\n auth_token: authToken,\n };\n }\n }\n\n return response;\n}\n"],"names":["secretsInterModuleContract","isInterModuleKnownError","config","workspaceProvidersPolicy","getModelProviderConfig","agentRuntimeConfigResolvedCount","agentSystemNamespace","storeValuesToCustomRuntimeCredentials","storeValuesToRuntimeCredentials","ModelProviderConfigNotFoundError","WorkspaceProvidersDisabledError","getModelProviderEntry","modelProviderCredentialKeysMatch","requireAgentSecretsClient","resolveRuntimeCredentials","params","options","runtimeConfig","configuredWorkspaceProviders","workspaceProviders","secrets","managedProvider","id","provider","managedRuntimeConfig","resolveCredentials","workspaceId","runId","stepAttemptId","model","add","source","outcome","toResponse","credentials","undefined","AGENT_DEFAULT_PROVIDER","providerConfig","providerId","values","getCredentialBag","namespace","getSecretsByNamespace","kind","error","methods","instanceCredentials","instanceFallbackCredentials","getInstanceDefaultModelProviderApiKeyField","credentialFields","credential_fields","field","length","key","secret","instanceApiKey","AGENT_DEFAULT_PROVIDER_API_KEY","fieldKey","managed","response","harness","provider_id","thinking","custom_provider","api","base_url","baseUrl","headers","secret_header_names","Object","keys","filter","startsWith","map","slice","sort","models","requires_api_key","requiresApiKey","find","candidate","modelDescriptor","label","authToken","api_key","claude","auth_token"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
+ import type { ManagedModelProvider, WorkspaceProvidersPolicy } from '@shipfox/api-agent-dto';
1
2
  import type { AgentValidationCatalog } from '@shipfox/api-agent-dto/inter-module';
2
3
  /** Produces the versioned, JSON-safe policy snapshot consumed by Definitions. */
3
- export declare function getAgentValidationCatalog(): AgentValidationCatalog;
4
+ export declare function getAgentValidationCatalog(managedProvider?: ManagedModelProvider | undefined, workspaceProviders?: WorkspaceProvidersPolicy): AgentValidationCatalog;
4
5
  //# sourceMappingURL=validation-catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation-catalog.d.ts","sourceRoot":"","sources":["../../src/core/validation-catalog.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAKhF,iFAAiF;AACjF,wBAAgB,yBAAyB,IAAI,sBAAsB,CAsBlE"}
1
+ {"version":3,"file":"validation-catalog.d.ts","sourceRoot":"","sources":["../../src/core/validation-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAMhC,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,qCAAqC,CAAC;AAOhF,iFAAiF;AACjF,wBAAgB,yBAAyB,CACvC,eAAe,CAAC,EAAE,oBAAoB,GAAG,SAAS,EAClD,kBAAkB,GAAE,wBAAoC,GACvD,sBAAsB,CAUxB"}
@@ -2,28 +2,76 @@ import { listEnabledHarnessTools, listHarnessDescriptors, MODEL_PROVIDER_IDS } f
2
2
  import { harnessToolDeploymentConfig } from '#config.js';
3
3
  import { listHarnessProviderModels } from './harness/index.js';
4
4
  import { getModelProviderEntry } from './model-provider-policy.js';
5
- /** Produces the versioned, JSON-safe policy snapshot consumed by Definitions. */ export function getAgentValidationCatalog() {
5
+ /** Produces the versioned, JSON-safe policy snapshot consumed by Definitions. */ export function getAgentValidationCatalog(managedProvider, workspaceProviders = 'enabled') {
6
+ const managedOnly = workspaceProviders === 'disabled';
6
7
  return {
7
8
  version: 1,
8
- providers: MODEL_PROVIDER_IDS.map((id)=>({
9
+ providers: buildValidationProviders(managedProvider, managedOnly),
10
+ harnesses: listHarnessDescriptors().map((harness)=>buildHarnessValidationCatalog(harness, managedProvider, managedOnly))
11
+ };
12
+ }
13
+ function buildValidationProviders(managedProvider, managedOnly) {
14
+ const providers = [];
15
+ if (!managedOnly) {
16
+ providers.push(...MODEL_PROVIDER_IDS.map((id)=>({
9
17
  id,
10
18
  support_status: getModelProviderEntry(id)?.support_status ?? 'unsupported'
11
- })),
12
- harnesses: listHarnessDescriptors().map((harness)=>({
13
- id: harness.id,
14
- supported_provider_ids: [
15
- ...harness.supportedProviderIds
16
- ],
17
- model_ids_by_provider: Object.fromEntries(harness.supportedProviderIds.map((providerId)=>[
18
- providerId,
19
- listHarnessProviderModels(harness.id, providerId).map((model)=>model.id)
20
- ])),
21
- thinking_levels: [
22
- ...harness.thinkingLevels
23
- ],
24
- effective_tools: listEnabledHarnessTools(harness.id, harnessToolDeploymentConfig).map((tool)=>tool.name)
25
- }))
19
+ })));
20
+ }
21
+ if (managedProvider !== undefined) {
22
+ providers.push({
23
+ id: managedProvider.id,
24
+ support_status: 'supported'
25
+ });
26
+ }
27
+ return providers;
28
+ }
29
+ function buildHarnessValidationCatalog(harness, managedProvider, managedOnly) {
30
+ const managedModels = getManagedModelsForHarness(harness, managedProvider);
31
+ return {
32
+ id: harness.id,
33
+ supported_provider_ids: buildSupportedProviderIds(harness, managedProvider, managedModels, managedOnly),
34
+ model_ids_by_provider: buildModelIdsByProvider(harness, managedProvider, managedModels, managedOnly),
35
+ thinking_levels: [
36
+ ...harness.thinkingLevels
37
+ ],
38
+ effective_tools: listEnabledHarnessTools(harness.id, harnessToolDeploymentConfig).map((tool)=>tool.name)
26
39
  };
27
40
  }
41
+ function buildSupportedProviderIds(harness, managedProvider, managedModels, managedOnly) {
42
+ if (managedOnly) {
43
+ if (managedProvider === undefined || managedModels.length === 0) return [];
44
+ return [
45
+ managedProvider.id
46
+ ];
47
+ }
48
+ const providerIds = [
49
+ ...harness.supportedProviderIds
50
+ ];
51
+ if (managedProvider !== undefined && managedModels.length > 0) {
52
+ providerIds.push(managedProvider.id);
53
+ }
54
+ return providerIds;
55
+ }
56
+ function buildModelIdsByProvider(harness, managedProvider, managedModels, managedOnly) {
57
+ const modelIdsByProvider = {};
58
+ if (!managedOnly) {
59
+ for (const providerId of harness.supportedProviderIds){
60
+ modelIdsByProvider[providerId] = listHarnessProviderModels(harness.id, providerId).map((model)=>model.id);
61
+ }
62
+ }
63
+ if (managedProvider !== undefined) {
64
+ modelIdsByProvider[managedProvider.id] = managedModels.map((model)=>model.id);
65
+ }
66
+ return modelIdsByProvider;
67
+ }
68
+ function getManagedModelsForHarness(harness, managedProvider) {
69
+ if (managedProvider === undefined) return [];
70
+ return managedModelsForHarness(harness.id, managedProvider);
71
+ }
72
+ function managedModelsForHarness(harness, managedProvider) {
73
+ if (harness === 'pi') return managedProvider.models;
74
+ return managedProvider.models.filter((model)=>model.api === 'anthropic-messages');
75
+ }
28
76
 
29
77
  //# sourceMappingURL=validation-catalog.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/validation-catalog.ts"],"sourcesContent":["import {\n listEnabledHarnessTools,\n listHarnessDescriptors,\n MODEL_PROVIDER_IDS,\n} from '@shipfox/api-agent-dto';\nimport type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';\nimport {harnessToolDeploymentConfig} from '#config.js';\nimport {listHarnessProviderModels} from './harness/index.js';\nimport {getModelProviderEntry} from './model-provider-policy.js';\n\n/** Produces the versioned, JSON-safe policy snapshot consumed by Definitions. */\nexport function getAgentValidationCatalog(): AgentValidationCatalog {\n return {\n version: 1,\n providers: MODEL_PROVIDER_IDS.map((id) => ({\n id,\n support_status: getModelProviderEntry(id)?.support_status ?? 'unsupported',\n })),\n harnesses: listHarnessDescriptors().map((harness) => ({\n id: harness.id,\n supported_provider_ids: [...harness.supportedProviderIds],\n model_ids_by_provider: Object.fromEntries(\n harness.supportedProviderIds.map((providerId) => [\n providerId,\n listHarnessProviderModels(harness.id, providerId).map((model) => model.id),\n ]),\n ),\n thinking_levels: [...harness.thinkingLevels],\n effective_tools: listEnabledHarnessTools(harness.id, harnessToolDeploymentConfig).map(\n (tool) => tool.name,\n ),\n })),\n };\n}\n"],"names":["listEnabledHarnessTools","listHarnessDescriptors","MODEL_PROVIDER_IDS","harnessToolDeploymentConfig","listHarnessProviderModels","getModelProviderEntry","getAgentValidationCatalog","version","providers","map","id","support_status","harnesses","harness","supported_provider_ids","supportedProviderIds","model_ids_by_provider","Object","fromEntries","providerId","model","thinking_levels","thinkingLevels","effective_tools","tool","name"],"mappings":"AAAA,SACEA,uBAAuB,EACvBC,sBAAsB,EACtBC,kBAAkB,QACb,yBAAyB;AAEhC,SAAQC,2BAA2B,QAAO,aAAa;AACvD,SAAQC,yBAAyB,QAAO,qBAAqB;AAC7D,SAAQC,qBAAqB,QAAO,6BAA6B;AAEjE,+EAA+E,GAC/E,OAAO,SAASC;IACd,OAAO;QACLC,SAAS;QACTC,WAAWN,mBAAmBO,GAAG,CAAC,CAACC,KAAQ,CAAA;gBACzCA;gBACAC,gBAAgBN,sBAAsBK,KAAKC,kBAAkB;YAC/D,CAAA;QACAC,WAAWX,yBAAyBQ,GAAG,CAAC,CAACI,UAAa,CAAA;gBACpDH,IAAIG,QAAQH,EAAE;gBACdI,wBAAwB;uBAAID,QAAQE,oBAAoB;iBAAC;gBACzDC,uBAAuBC,OAAOC,WAAW,CACvCL,QAAQE,oBAAoB,CAACN,GAAG,CAAC,CAACU,aAAe;wBAC/CA;wBACAf,0BAA0BS,QAAQH,EAAE,EAAES,YAAYV,GAAG,CAAC,CAACW,QAAUA,MAAMV,EAAE;qBAC1E;gBAEHW,iBAAiB;uBAAIR,QAAQS,cAAc;iBAAC;gBAC5CC,iBAAiBvB,wBAAwBa,QAAQH,EAAE,EAAEP,6BAA6BM,GAAG,CACnF,CAACe,OAASA,KAAKC,IAAI;YAEvB,CAAA;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/core/validation-catalog.ts"],"sourcesContent":["import type {\n HarnessDescriptor,\n ManagedModelProvider,\n WorkspaceProvidersPolicy,\n} from '@shipfox/api-agent-dto';\nimport {\n listEnabledHarnessTools,\n listHarnessDescriptors,\n MODEL_PROVIDER_IDS,\n} from '@shipfox/api-agent-dto';\nimport type {AgentValidationCatalog} from '@shipfox/api-agent-dto/inter-module';\nimport {harnessToolDeploymentConfig} from '#config.js';\nimport {listHarnessProviderModels} from './harness/index.js';\nimport {getModelProviderEntry} from './model-provider-policy.js';\n\ntype HarnessValidationCatalog = AgentValidationCatalog['harnesses'][number];\n\n/** Produces the versioned, JSON-safe policy snapshot consumed by Definitions. */\nexport function getAgentValidationCatalog(\n managedProvider?: ManagedModelProvider | undefined,\n workspaceProviders: WorkspaceProvidersPolicy = 'enabled',\n): AgentValidationCatalog {\n const managedOnly = workspaceProviders === 'disabled';\n\n return {\n version: 1,\n providers: buildValidationProviders(managedProvider, managedOnly),\n harnesses: listHarnessDescriptors().map((harness) =>\n buildHarnessValidationCatalog(harness, managedProvider, managedOnly),\n ),\n };\n}\n\nfunction buildValidationProviders(\n managedProvider: ManagedModelProvider | undefined,\n managedOnly: boolean,\n): AgentValidationCatalog['providers'] {\n const providers: AgentValidationCatalog['providers'] = [];\n\n if (!managedOnly) {\n providers.push(\n ...MODEL_PROVIDER_IDS.map((id) => ({\n id,\n support_status: getModelProviderEntry(id)?.support_status ?? 'unsupported',\n })),\n );\n }\n\n if (managedProvider !== undefined) {\n providers.push({id: managedProvider.id, support_status: 'supported'});\n }\n\n return providers;\n}\n\nfunction buildHarnessValidationCatalog(\n harness: HarnessDescriptor,\n managedProvider: ManagedModelProvider | undefined,\n managedOnly: boolean,\n): HarnessValidationCatalog {\n const managedModels = getManagedModelsForHarness(harness, managedProvider);\n\n return {\n id: harness.id,\n supported_provider_ids: buildSupportedProviderIds(\n harness,\n managedProvider,\n managedModels,\n managedOnly,\n ),\n model_ids_by_provider: buildModelIdsByProvider(\n harness,\n managedProvider,\n managedModels,\n managedOnly,\n ),\n thinking_levels: [...harness.thinkingLevels],\n effective_tools: listEnabledHarnessTools(harness.id, harnessToolDeploymentConfig).map(\n (tool) => tool.name,\n ),\n };\n}\n\nfunction buildSupportedProviderIds(\n harness: HarnessDescriptor,\n managedProvider: ManagedModelProvider | undefined,\n managedModels: ManagedModelProvider['models'],\n managedOnly: boolean,\n): string[] {\n if (managedOnly) {\n if (managedProvider === undefined || managedModels.length === 0) return [];\n return [managedProvider.id];\n }\n\n const providerIds = [...harness.supportedProviderIds];\n if (managedProvider !== undefined && managedModels.length > 0) {\n providerIds.push(managedProvider.id);\n }\n return providerIds;\n}\n\nfunction buildModelIdsByProvider(\n harness: HarnessDescriptor,\n managedProvider: ManagedModelProvider | undefined,\n managedModels: ManagedModelProvider['models'],\n managedOnly: boolean,\n): Record<string, string[]> {\n const modelIdsByProvider: Record<string, string[]> = {};\n\n if (!managedOnly) {\n for (const providerId of harness.supportedProviderIds) {\n modelIdsByProvider[providerId] = listHarnessProviderModels(harness.id, providerId).map(\n (model) => model.id,\n );\n }\n }\n\n if (managedProvider !== undefined) {\n modelIdsByProvider[managedProvider.id] = managedModels.map((model) => model.id);\n }\n\n return modelIdsByProvider;\n}\n\nfunction getManagedModelsForHarness(\n harness: HarnessDescriptor,\n managedProvider: ManagedModelProvider | undefined,\n): ManagedModelProvider['models'] {\n if (managedProvider === undefined) return [];\n return managedModelsForHarness(harness.id, managedProvider);\n}\n\nfunction managedModelsForHarness(\n harness: 'pi' | 'claude',\n managedProvider: ManagedModelProvider,\n): ManagedModelProvider['models'] {\n if (harness === 'pi') return managedProvider.models;\n return managedProvider.models.filter((model) => model.api === 'anthropic-messages');\n}\n"],"names":["listEnabledHarnessTools","listHarnessDescriptors","MODEL_PROVIDER_IDS","harnessToolDeploymentConfig","listHarnessProviderModels","getModelProviderEntry","getAgentValidationCatalog","managedProvider","workspaceProviders","managedOnly","version","providers","buildValidationProviders","harnesses","map","harness","buildHarnessValidationCatalog","push","id","support_status","undefined","managedModels","getManagedModelsForHarness","supported_provider_ids","buildSupportedProviderIds","model_ids_by_provider","buildModelIdsByProvider","thinking_levels","thinkingLevels","effective_tools","tool","name","length","providerIds","supportedProviderIds","modelIdsByProvider","providerId","model","managedModelsForHarness","models","filter","api"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { ManagedModelProvider, WorkspaceProvidersPolicy } from '@shipfox/api-agent-dto';
1
2
  import type { AgentDefaultsResolver } from './resolve-agent-config.js';
2
- export declare function createWorkspaceAgentDefaultsResolver(workspaceId: string): Promise<AgentDefaultsResolver>;
3
+ export declare function createWorkspaceAgentDefaultsResolver(workspaceId: string, managedProvider?: ManagedModelProvider | undefined, workspaceProviders?: WorkspaceProvidersPolicy | undefined): Promise<AgentDefaultsResolver>;
3
4
  //# sourceMappingURL=workspace-agent-defaults-resolver.d.ts.map