@contractspec/lib.content-gen 3.0.0 → 3.2.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.
@@ -923,11 +923,15 @@ class BlogGenerator {
923
923
  model;
924
924
  temperature;
925
925
  i18n;
926
+ modelSelector;
927
+ selectionContext;
926
928
  constructor(options) {
927
929
  this.llm = options?.llm;
928
930
  this.model = options?.model;
929
931
  this.temperature = options?.temperature ?? 0.4;
930
932
  this.i18n = createContentGenI18n(options?.locale);
933
+ this.modelSelector = options?.modelSelector;
934
+ this.selectionContext = options?.selectionContext;
931
935
  }
932
936
  async generate(brief) {
933
937
  if (this.llm) {
@@ -935,10 +939,23 @@ class BlogGenerator {
935
939
  }
936
940
  return this.generateDeterministic(brief);
937
941
  }
942
+ async resolveModel() {
943
+ if (this.model)
944
+ return this.model;
945
+ if (this.modelSelector) {
946
+ const ctx = this.selectionContext ?? {
947
+ taskDimension: "reasoning"
948
+ };
949
+ const result = await this.modelSelector.select(ctx);
950
+ return result.modelId;
951
+ }
952
+ return;
953
+ }
938
954
  async generateWithLlm(brief) {
939
955
  if (!this.llm) {
940
956
  return this.generateDeterministic(brief);
941
957
  }
958
+ const model = await this.resolveModel();
942
959
  const response = await this.llm.chat([
943
960
  {
944
961
  role: "system",
@@ -960,7 +977,7 @@ class BlogGenerator {
960
977
  }
961
978
  ], {
962
979
  responseFormat: "json",
963
- model: this.model,
980
+ model,
964
981
  temperature: this.temperature
965
982
  });
966
983
  const jsonPart = response.message.content.find((part) => ("text" in part));
@@ -1022,11 +1039,15 @@ class EmailCampaignGenerator {
1022
1039
  model;
1023
1040
  temperature;
1024
1041
  i18n;
1042
+ modelSelector;
1043
+ selectionContext;
1025
1044
  constructor(options) {
1026
1045
  this.llm = options?.llm;
1027
1046
  this.model = options?.model;
1028
1047
  this.temperature = options?.temperature ?? 0.6;
1029
1048
  this.i18n = createContentGenI18n(options?.locale);
1049
+ this.modelSelector = options?.modelSelector;
1050
+ this.selectionContext = options?.selectionContext;
1030
1051
  }
1031
1052
  async generate(input) {
1032
1053
  if (this.llm) {
@@ -1036,9 +1057,22 @@ class EmailCampaignGenerator {
1036
1057
  }
1037
1058
  return this.generateFallback(input);
1038
1059
  }
1060
+ async resolveModel() {
1061
+ if (this.model)
1062
+ return this.model;
1063
+ if (this.modelSelector) {
1064
+ const ctx = this.selectionContext ?? {
1065
+ taskDimension: "reasoning"
1066
+ };
1067
+ const result = await this.modelSelector.select(ctx);
1068
+ return result.modelId;
1069
+ }
1070
+ return;
1071
+ }
1039
1072
  async generateWithLlm(input) {
1040
1073
  if (!this.llm)
1041
1074
  return null;
1075
+ const model = await this.resolveModel();
1042
1076
  const response = await this.llm.chat([
1043
1077
  {
1044
1078
  role: "system",
@@ -1055,7 +1089,7 @@ class EmailCampaignGenerator {
1055
1089
  }
1056
1090
  ], {
1057
1091
  responseFormat: "json",
1058
- model: this.model,
1092
+ model,
1059
1093
  temperature: this.temperature
1060
1094
  });
1061
1095
  const jsonPart = response.message.content.find((chunk) => ("text" in chunk));
@@ -1151,11 +1185,15 @@ class LandingPageGenerator {
1151
1185
  llm;
1152
1186
  model;
1153
1187
  i18n;
1188
+ modelSelector;
1189
+ selectionContext;
1154
1190
  constructor(options) {
1155
1191
  this.options = options;
1156
1192
  this.llm = options?.llm;
1157
1193
  this.model = options?.model;
1158
1194
  this.i18n = createContentGenI18n(options?.locale);
1195
+ this.modelSelector = options?.modelSelector;
1196
+ this.selectionContext = options?.selectionContext;
1159
1197
  }
1160
1198
  async generate(brief) {
1161
1199
  if (this.llm) {
@@ -1163,10 +1201,21 @@ class LandingPageGenerator {
1163
1201
  }
1164
1202
  return this.generateFallback(brief);
1165
1203
  }
1204
+ async resolveModel() {
1205
+ if (this.model)
1206
+ return this.model;
1207
+ if (this.modelSelector) {
1208
+ const ctx = this.selectionContext ?? { taskDimension: "coding" };
1209
+ const result = await this.modelSelector.select(ctx);
1210
+ return result.modelId;
1211
+ }
1212
+ return;
1213
+ }
1166
1214
  async generateWithLlm(brief) {
1167
1215
  if (!this.llm) {
1168
1216
  return this.generateFallback(brief);
1169
1217
  }
1218
+ const model = await this.resolveModel();
1170
1219
  const response = await this.llm.chat([
1171
1220
  {
1172
1221
  role: "system",
@@ -1183,7 +1232,7 @@ class LandingPageGenerator {
1183
1232
  }
1184
1233
  ], {
1185
1234
  responseFormat: "json",
1186
- model: this.model,
1235
+ model,
1187
1236
  temperature: this.options?.temperature ?? 0.5
1188
1237
  });
1189
1238
  const part = response.message.content.find((chunk) => ("text" in chunk));
@@ -1246,10 +1295,14 @@ class SocialPostGenerator {
1246
1295
  llm;
1247
1296
  model;
1248
1297
  i18n;
1298
+ modelSelector;
1299
+ selectionContext;
1249
1300
  constructor(options) {
1250
1301
  this.llm = options?.llm;
1251
1302
  this.model = options?.model;
1252
1303
  this.i18n = createContentGenI18n(options?.locale);
1304
+ this.modelSelector = options?.modelSelector;
1305
+ this.selectionContext = options?.selectionContext;
1253
1306
  }
1254
1307
  async generate(brief) {
1255
1308
  if (this.llm) {
@@ -1259,9 +1312,22 @@ class SocialPostGenerator {
1259
1312
  }
1260
1313
  return this.generateFallback(brief);
1261
1314
  }
1315
+ async resolveModel() {
1316
+ if (this.model)
1317
+ return this.model;
1318
+ if (this.modelSelector) {
1319
+ const ctx = this.selectionContext ?? {
1320
+ taskDimension: "reasoning"
1321
+ };
1322
+ const result = await this.modelSelector.select(ctx);
1323
+ return result.modelId;
1324
+ }
1325
+ return;
1326
+ }
1262
1327
  async generateWithLlm(brief) {
1263
1328
  if (!this.llm)
1264
1329
  return [];
1330
+ const model = await this.resolveModel();
1265
1331
  const response = await this.llm.chat([
1266
1332
  {
1267
1333
  role: "system",
@@ -1276,7 +1342,7 @@ class SocialPostGenerator {
1276
1342
  role: "user",
1277
1343
  content: [{ type: "text", text: JSON.stringify(brief) }]
1278
1344
  }
1279
- ], { responseFormat: "json", model: this.model });
1345
+ ], { responseFormat: "json", model });
1280
1346
  const part = response.message.content.find((chunk) => ("text" in chunk));
1281
1347
  if (!part || !("text" in part))
1282
1348
  return [];
@@ -16,8 +16,11 @@ export declare class LandingPageGenerator {
16
16
  private readonly llm?;
17
17
  private readonly model?;
18
18
  private readonly i18n;
19
+ private readonly modelSelector?;
20
+ private readonly selectionContext?;
19
21
  constructor(options?: GeneratorOptions | undefined);
20
22
  generate(brief: ContentBrief): Promise<LandingPageCopy>;
23
+ private resolveModel;
21
24
  private generateWithLlm;
22
25
  private generateFallback;
23
26
  private buildFaq;
@@ -923,11 +923,15 @@ class LandingPageGenerator {
923
923
  llm;
924
924
  model;
925
925
  i18n;
926
+ modelSelector;
927
+ selectionContext;
926
928
  constructor(options) {
927
929
  this.options = options;
928
930
  this.llm = options?.llm;
929
931
  this.model = options?.model;
930
932
  this.i18n = createContentGenI18n(options?.locale);
933
+ this.modelSelector = options?.modelSelector;
934
+ this.selectionContext = options?.selectionContext;
931
935
  }
932
936
  async generate(brief) {
933
937
  if (this.llm) {
@@ -935,10 +939,21 @@ class LandingPageGenerator {
935
939
  }
936
940
  return this.generateFallback(brief);
937
941
  }
942
+ async resolveModel() {
943
+ if (this.model)
944
+ return this.model;
945
+ if (this.modelSelector) {
946
+ const ctx = this.selectionContext ?? { taskDimension: "coding" };
947
+ const result = await this.modelSelector.select(ctx);
948
+ return result.modelId;
949
+ }
950
+ return;
951
+ }
938
952
  async generateWithLlm(brief) {
939
953
  if (!this.llm) {
940
954
  return this.generateFallback(brief);
941
955
  }
956
+ const model = await this.resolveModel();
942
957
  const response = await this.llm.chat([
943
958
  {
944
959
  role: "system",
@@ -955,7 +970,7 @@ class LandingPageGenerator {
955
970
  }
956
971
  ], {
957
972
  responseFormat: "json",
958
- model: this.model,
973
+ model,
959
974
  temperature: this.options?.temperature ?? 0.5
960
975
  });
961
976
  const part = response.message.content.find((chunk) => ("text" in chunk));
@@ -3,8 +3,11 @@ export declare class SocialPostGenerator {
3
3
  private readonly llm?;
4
4
  private readonly model?;
5
5
  private readonly i18n;
6
+ private readonly modelSelector?;
7
+ private readonly selectionContext?;
6
8
  constructor(options?: GeneratorOptions);
7
9
  generate(brief: ContentBrief): Promise<SocialPost[]>;
10
+ private resolveModel;
8
11
  private generateWithLlm;
9
12
  private generateFallback;
10
13
  private buildHashtags;
@@ -922,10 +922,14 @@ class SocialPostGenerator {
922
922
  llm;
923
923
  model;
924
924
  i18n;
925
+ modelSelector;
926
+ selectionContext;
925
927
  constructor(options) {
926
928
  this.llm = options?.llm;
927
929
  this.model = options?.model;
928
930
  this.i18n = createContentGenI18n(options?.locale);
931
+ this.modelSelector = options?.modelSelector;
932
+ this.selectionContext = options?.selectionContext;
929
933
  }
930
934
  async generate(brief) {
931
935
  if (this.llm) {
@@ -935,9 +939,22 @@ class SocialPostGenerator {
935
939
  }
936
940
  return this.generateFallback(brief);
937
941
  }
942
+ async resolveModel() {
943
+ if (this.model)
944
+ return this.model;
945
+ if (this.modelSelector) {
946
+ const ctx = this.selectionContext ?? {
947
+ taskDimension: "reasoning"
948
+ };
949
+ const result = await this.modelSelector.select(ctx);
950
+ return result.modelId;
951
+ }
952
+ return;
953
+ }
938
954
  async generateWithLlm(brief) {
939
955
  if (!this.llm)
940
956
  return [];
957
+ const model = await this.resolveModel();
941
958
  const response = await this.llm.chat([
942
959
  {
943
960
  role: "system",
@@ -952,7 +969,7 @@ class SocialPostGenerator {
952
969
  role: "user",
953
970
  content: [{ type: "text", text: JSON.stringify(brief) }]
954
971
  }
955
- ], { responseFormat: "json", model: this.model });
972
+ ], { responseFormat: "json", model });
956
973
  const part = response.message.content.find((chunk) => ("text" in chunk));
957
974
  if (!part || !("text" in part))
958
975
  return [];
package/dist/index.js CHANGED
@@ -923,11 +923,15 @@ class BlogGenerator {
923
923
  model;
924
924
  temperature;
925
925
  i18n;
926
+ modelSelector;
927
+ selectionContext;
926
928
  constructor(options) {
927
929
  this.llm = options?.llm;
928
930
  this.model = options?.model;
929
931
  this.temperature = options?.temperature ?? 0.4;
930
932
  this.i18n = createContentGenI18n(options?.locale);
933
+ this.modelSelector = options?.modelSelector;
934
+ this.selectionContext = options?.selectionContext;
931
935
  }
932
936
  async generate(brief) {
933
937
  if (this.llm) {
@@ -935,10 +939,23 @@ class BlogGenerator {
935
939
  }
936
940
  return this.generateDeterministic(brief);
937
941
  }
942
+ async resolveModel() {
943
+ if (this.model)
944
+ return this.model;
945
+ if (this.modelSelector) {
946
+ const ctx = this.selectionContext ?? {
947
+ taskDimension: "reasoning"
948
+ };
949
+ const result = await this.modelSelector.select(ctx);
950
+ return result.modelId;
951
+ }
952
+ return;
953
+ }
938
954
  async generateWithLlm(brief) {
939
955
  if (!this.llm) {
940
956
  return this.generateDeterministic(brief);
941
957
  }
958
+ const model = await this.resolveModel();
942
959
  const response = await this.llm.chat([
943
960
  {
944
961
  role: "system",
@@ -960,7 +977,7 @@ class BlogGenerator {
960
977
  }
961
978
  ], {
962
979
  responseFormat: "json",
963
- model: this.model,
980
+ model,
964
981
  temperature: this.temperature
965
982
  });
966
983
  const jsonPart = response.message.content.find((part) => ("text" in part));
@@ -1022,11 +1039,15 @@ class EmailCampaignGenerator {
1022
1039
  model;
1023
1040
  temperature;
1024
1041
  i18n;
1042
+ modelSelector;
1043
+ selectionContext;
1025
1044
  constructor(options) {
1026
1045
  this.llm = options?.llm;
1027
1046
  this.model = options?.model;
1028
1047
  this.temperature = options?.temperature ?? 0.6;
1029
1048
  this.i18n = createContentGenI18n(options?.locale);
1049
+ this.modelSelector = options?.modelSelector;
1050
+ this.selectionContext = options?.selectionContext;
1030
1051
  }
1031
1052
  async generate(input) {
1032
1053
  if (this.llm) {
@@ -1036,9 +1057,22 @@ class EmailCampaignGenerator {
1036
1057
  }
1037
1058
  return this.generateFallback(input);
1038
1059
  }
1060
+ async resolveModel() {
1061
+ if (this.model)
1062
+ return this.model;
1063
+ if (this.modelSelector) {
1064
+ const ctx = this.selectionContext ?? {
1065
+ taskDimension: "reasoning"
1066
+ };
1067
+ const result = await this.modelSelector.select(ctx);
1068
+ return result.modelId;
1069
+ }
1070
+ return;
1071
+ }
1039
1072
  async generateWithLlm(input) {
1040
1073
  if (!this.llm)
1041
1074
  return null;
1075
+ const model = await this.resolveModel();
1042
1076
  const response = await this.llm.chat([
1043
1077
  {
1044
1078
  role: "system",
@@ -1055,7 +1089,7 @@ class EmailCampaignGenerator {
1055
1089
  }
1056
1090
  ], {
1057
1091
  responseFormat: "json",
1058
- model: this.model,
1092
+ model,
1059
1093
  temperature: this.temperature
1060
1094
  });
1061
1095
  const jsonPart = response.message.content.find((chunk) => ("text" in chunk));
@@ -1151,11 +1185,15 @@ class LandingPageGenerator {
1151
1185
  llm;
1152
1186
  model;
1153
1187
  i18n;
1188
+ modelSelector;
1189
+ selectionContext;
1154
1190
  constructor(options) {
1155
1191
  this.options = options;
1156
1192
  this.llm = options?.llm;
1157
1193
  this.model = options?.model;
1158
1194
  this.i18n = createContentGenI18n(options?.locale);
1195
+ this.modelSelector = options?.modelSelector;
1196
+ this.selectionContext = options?.selectionContext;
1159
1197
  }
1160
1198
  async generate(brief) {
1161
1199
  if (this.llm) {
@@ -1163,10 +1201,21 @@ class LandingPageGenerator {
1163
1201
  }
1164
1202
  return this.generateFallback(brief);
1165
1203
  }
1204
+ async resolveModel() {
1205
+ if (this.model)
1206
+ return this.model;
1207
+ if (this.modelSelector) {
1208
+ const ctx = this.selectionContext ?? { taskDimension: "coding" };
1209
+ const result = await this.modelSelector.select(ctx);
1210
+ return result.modelId;
1211
+ }
1212
+ return;
1213
+ }
1166
1214
  async generateWithLlm(brief) {
1167
1215
  if (!this.llm) {
1168
1216
  return this.generateFallback(brief);
1169
1217
  }
1218
+ const model = await this.resolveModel();
1170
1219
  const response = await this.llm.chat([
1171
1220
  {
1172
1221
  role: "system",
@@ -1183,7 +1232,7 @@ class LandingPageGenerator {
1183
1232
  }
1184
1233
  ], {
1185
1234
  responseFormat: "json",
1186
- model: this.model,
1235
+ model,
1187
1236
  temperature: this.options?.temperature ?? 0.5
1188
1237
  });
1189
1238
  const part = response.message.content.find((chunk) => ("text" in chunk));
@@ -1246,10 +1295,14 @@ class SocialPostGenerator {
1246
1295
  llm;
1247
1296
  model;
1248
1297
  i18n;
1298
+ modelSelector;
1299
+ selectionContext;
1249
1300
  constructor(options) {
1250
1301
  this.llm = options?.llm;
1251
1302
  this.model = options?.model;
1252
1303
  this.i18n = createContentGenI18n(options?.locale);
1304
+ this.modelSelector = options?.modelSelector;
1305
+ this.selectionContext = options?.selectionContext;
1253
1306
  }
1254
1307
  async generate(brief) {
1255
1308
  if (this.llm) {
@@ -1259,9 +1312,22 @@ class SocialPostGenerator {
1259
1312
  }
1260
1313
  return this.generateFallback(brief);
1261
1314
  }
1315
+ async resolveModel() {
1316
+ if (this.model)
1317
+ return this.model;
1318
+ if (this.modelSelector) {
1319
+ const ctx = this.selectionContext ?? {
1320
+ taskDimension: "reasoning"
1321
+ };
1322
+ const result = await this.modelSelector.select(ctx);
1323
+ return result.modelId;
1324
+ }
1325
+ return;
1326
+ }
1262
1327
  async generateWithLlm(brief) {
1263
1328
  if (!this.llm)
1264
1329
  return [];
1330
+ const model = await this.resolveModel();
1265
1331
  const response = await this.llm.chat([
1266
1332
  {
1267
1333
  role: "system",
@@ -1276,7 +1342,7 @@ class SocialPostGenerator {
1276
1342
  role: "user",
1277
1343
  content: [{ type: "text", text: JSON.stringify(brief) }]
1278
1344
  }
1279
- ], { responseFormat: "json", model: this.model });
1345
+ ], { responseFormat: "json", model });
1280
1346
  const part = response.message.content.find((chunk) => ("text" in chunk));
1281
1347
  if (!part || !("text" in part))
1282
1348
  return [];
@@ -922,11 +922,15 @@ class BlogGenerator {
922
922
  model;
923
923
  temperature;
924
924
  i18n;
925
+ modelSelector;
926
+ selectionContext;
925
927
  constructor(options) {
926
928
  this.llm = options?.llm;
927
929
  this.model = options?.model;
928
930
  this.temperature = options?.temperature ?? 0.4;
929
931
  this.i18n = createContentGenI18n(options?.locale);
932
+ this.modelSelector = options?.modelSelector;
933
+ this.selectionContext = options?.selectionContext;
930
934
  }
931
935
  async generate(brief) {
932
936
  if (this.llm) {
@@ -934,10 +938,23 @@ class BlogGenerator {
934
938
  }
935
939
  return this.generateDeterministic(brief);
936
940
  }
941
+ async resolveModel() {
942
+ if (this.model)
943
+ return this.model;
944
+ if (this.modelSelector) {
945
+ const ctx = this.selectionContext ?? {
946
+ taskDimension: "reasoning"
947
+ };
948
+ const result = await this.modelSelector.select(ctx);
949
+ return result.modelId;
950
+ }
951
+ return;
952
+ }
937
953
  async generateWithLlm(brief) {
938
954
  if (!this.llm) {
939
955
  return this.generateDeterministic(brief);
940
956
  }
957
+ const model = await this.resolveModel();
941
958
  const response = await this.llm.chat([
942
959
  {
943
960
  role: "system",
@@ -959,7 +976,7 @@ class BlogGenerator {
959
976
  }
960
977
  ], {
961
978
  responseFormat: "json",
962
- model: this.model,
979
+ model,
963
980
  temperature: this.temperature
964
981
  });
965
982
  const jsonPart = response.message.content.find((part) => ("text" in part));
@@ -922,11 +922,15 @@ class EmailCampaignGenerator {
922
922
  model;
923
923
  temperature;
924
924
  i18n;
925
+ modelSelector;
926
+ selectionContext;
925
927
  constructor(options) {
926
928
  this.llm = options?.llm;
927
929
  this.model = options?.model;
928
930
  this.temperature = options?.temperature ?? 0.6;
929
931
  this.i18n = createContentGenI18n(options?.locale);
932
+ this.modelSelector = options?.modelSelector;
933
+ this.selectionContext = options?.selectionContext;
930
934
  }
931
935
  async generate(input) {
932
936
  if (this.llm) {
@@ -936,9 +940,22 @@ class EmailCampaignGenerator {
936
940
  }
937
941
  return this.generateFallback(input);
938
942
  }
943
+ async resolveModel() {
944
+ if (this.model)
945
+ return this.model;
946
+ if (this.modelSelector) {
947
+ const ctx = this.selectionContext ?? {
948
+ taskDimension: "reasoning"
949
+ };
950
+ const result = await this.modelSelector.select(ctx);
951
+ return result.modelId;
952
+ }
953
+ return;
954
+ }
939
955
  async generateWithLlm(input) {
940
956
  if (!this.llm)
941
957
  return null;
958
+ const model = await this.resolveModel();
942
959
  const response = await this.llm.chat([
943
960
  {
944
961
  role: "system",
@@ -955,7 +972,7 @@ class EmailCampaignGenerator {
955
972
  }
956
973
  ], {
957
974
  responseFormat: "json",
958
- model: this.model,
975
+ model,
959
976
  temperature: this.temperature
960
977
  });
961
978
  const jsonPart = response.message.content.find((chunk) => ("text" in chunk));