@aglyn/plugins-ai 1.0.0-beta.252 → 1.0.0-beta.254

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 (65) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-site-start-card.component.js +16 -8
  3. package/src/lib/components/ai-site-start-card.component.js.map +1 -1
  4. package/src/lib/jobs/ai-job-form-dataset.d.ts +6 -1
  5. package/src/lib/jobs/ai-job-form-dataset.js +7 -2
  6. package/src/lib/jobs/ai-job-form-dataset.js.map +1 -1
  7. package/src/lib/jobs/ai-job-page-language.d.ts +10 -5
  8. package/src/lib/jobs/ai-job-page-language.js +10 -5
  9. package/src/lib/jobs/ai-job-page-language.js.map +1 -1
  10. package/src/lib/jobs/ai-job-plan-step.d.ts +13 -1
  11. package/src/lib/jobs/ai-job-plan-step.js +27 -8
  12. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  13. package/src/lib/jobs/ai-job-site-content.d.ts +32 -16
  14. package/src/lib/jobs/ai-job-site-content.js +43 -20
  15. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  16. package/src/lib/jobs/ai-job-site-datasets.d.ts +1 -1
  17. package/src/lib/jobs/ai-job-site-datasets.js +2 -2
  18. package/src/lib/jobs/ai-job-site-datasets.js.map +1 -1
  19. package/src/lib/jobs/ai-job-site-step.d.ts +3 -0
  20. package/src/lib/jobs/ai-job-site-step.js +25 -12
  21. package/src/lib/jobs/ai-job-site-step.js.map +1 -1
  22. package/src/lib/layout-language/ai-layout-language.js +5 -1
  23. package/src/lib/layout-language/ai-layout-language.js.map +1 -1
  24. package/src/lib/layout-language/ai-layout-links.js +5 -2
  25. package/src/lib/layout-language/ai-layout-links.js.map +1 -1
  26. package/src/lib/model/ai-credit-estimate.d.ts +7 -1
  27. package/src/lib/model/ai-credit-estimate.js +7 -1
  28. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  29. package/src/lib/model/ai-plan-capabilities.d.ts +5 -0
  30. package/src/lib/model/ai-plan-capabilities.js.map +1 -1
  31. package/src/lib/model/ai-site-job.d.ts +32 -12
  32. package/src/lib/model/ai-site-job.js +35 -20
  33. package/src/lib/model/ai-site-job.js.map +1 -1
  34. package/src/lib/model/ai-site-kinds.d.ts +5 -5
  35. package/src/lib/model/ai-site-kinds.js +5 -5
  36. package/src/lib/model/ai-site-kinds.js.map +1 -1
  37. package/src/lib/model/ai-site-start-seo.d.ts +11 -2
  38. package/src/lib/model/ai-site-start-seo.js +29 -15
  39. package/src/lib/model/ai-site-start-seo.js.map +1 -1
  40. package/src/lib/providers/anthropic.js +29 -7
  41. package/src/lib/providers/anthropic.js.map +1 -1
  42. package/src/lib/providers/contract.d.ts +19 -1
  43. package/src/lib/providers/contract.js +10 -0
  44. package/src/lib/providers/contract.js.map +1 -1
  45. package/src/lib/providers/routing.js +24 -4
  46. package/src/lib/providers/routing.js.map +1 -1
  47. package/src/lib/runtime/ai-dev-env.d.ts +25 -4
  48. package/src/lib/runtime/ai-dev-env.js +41 -14
  49. package/src/lib/runtime/ai-dev-env.js.map +1 -1
  50. package/src/lib/runtime/ai-dev-replay.d.ts +4 -0
  51. package/src/lib/runtime/ai-dev-replay.js +4 -0
  52. package/src/lib/runtime/ai-dev-replay.js.map +1 -1
  53. package/src/lib/runtime/ai-doctrine-validators.js +13 -3
  54. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  55. package/src/lib/runtime/ai-eval-live.d.ts +35 -1
  56. package/src/lib/runtime/ai-eval-live.js +46 -2
  57. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  58. package/src/lib/runtime/ai-live-batch.d.ts +20 -4
  59. package/src/lib/runtime/ai-live-batch.js +57 -10
  60. package/src/lib/runtime/ai-live-batch.js.map +1 -1
  61. package/src/lib/runtime/ai-runtime.js +4 -2
  62. package/src/lib/runtime/ai-runtime.js.map +1 -1
  63. package/src/lib/server/ai-media-image.d.ts +5 -1
  64. package/src/lib/server/ai-media-image.js +6 -2
  65. package/src/lib/server/ai-media-image.js.map +1 -1
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import type { AiJob } from '../model/ai-jobs.types';
18
18
  import { type AiProductsProposal } from '../model/ai-products';
19
- import type { AiImagePart, AiProvider, AiSystemBlock, AiTool } from '../providers/contract';
19
+ import type { AiEffort, AiImagePart, AiProvider, AiSystemBlock, AiTool } from '../providers/contract';
20
20
  import { type AiCustomGenerationInput } from './ai-doctrine';
21
21
  import { type AiEvalCandidate, type AiEvalCase, type AiEvalKind, type AiEvalRubric } from './ai-eval';
22
22
  /**
@@ -301,6 +301,40 @@ export interface AiEvalLiveReport {
301
301
  /** The briefs whose run threw; empty when every brief a recorder covers came back. */
302
302
  failed: AiEvalLiveFailure[];
303
303
  }
304
+ /** The effort A/B arm a live run records under (AGL-3781). */
305
+ export interface AiEvalEffortArm {
306
+ /** `effort-` and 8 hex characters of a hash of `efforts`: the same arm always gets the same tag. */
307
+ tag: string;
308
+ /** Each step kind the arm names, in kind order, with its effort; `*` for every other kind. */
309
+ efforts: Record<string, AiEffort>;
310
+ }
311
+ /**
312
+ * The arm `AGLYN_AI_EFFORT` names, or null when it names none. A recording's
313
+ * filename carries only the tag, and the recording carries the map: the
314
+ * filename once spelled the whole list out, and a list of five kinds was
315
+ * longer than a filename may be (ENAMETOOLONG lost the round's recordings).
316
+ * The hash is of the parsed, sorted map, so the same efforts written in
317
+ * another order or spacing are the same arm.
318
+ */
319
+ export declare function aiEvalEffortArm(env: Record<string, string | undefined>): AiEvalEffortArm | null;
320
+ /** A recording's file name: `<case>.<model>.json`, with the arm's tag before `.json` when one ran. */
321
+ export declare function aiEvalRecordingFileName(caseId: string, model: string | null | undefined, arm: AiEvalEffortArm | null): string;
322
+ /**
323
+ * What a recording holds: the brief, the answer, and under `arm` the arm's
324
+ * tag and every effort it named, when one ran — the candidate's own `effort`
325
+ * is the one its step was asked at.
326
+ */
327
+ export declare function aiEvalRecordingBody(caseId: string, candidate: AiEvalCandidate, arm: AiEvalEffortArm | null): string;
328
+ /**
329
+ * One brief's score line. Everything before the colon is the pairing key —
330
+ * `score <case> (<kind>) <model>`, then the arm's tag when one ran — so a
331
+ * default run's line and an arm's line for the same brief sort side by side.
332
+ */
333
+ export declare function aiEvalScoreLine(entry: {
334
+ caseId: string;
335
+ kind: AiEvalKind;
336
+ candidate: AiEvalCandidate;
337
+ }, pass: boolean | null, arm: AiEvalEffortArm | null): string;
304
338
  /**
305
339
  * Record and grade an answer for every brief a recorder covers. Refused
306
340
  * before anything else unless `AI_EVAL_LIVE=1` names the run, and before any
@@ -14,7 +14,8 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
14
14
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
- */ import { assistCreditsFromUsd } from "../usage/assist-credits.js";
17
+ */ import { createHash } from "node:crypto";
18
+ import { assistCreditsFromUsd } from "../usage/assist-credits.js";
18
19
  import { LAYOUT_SLOT_COMPONENT_ID } from "@aglyn/aglyn/app-utils/compose-layout-nodes";
19
20
  import { stampDocumentLandmark } from "@aglyn/aglyn/app-utils/document-landmark";
20
21
  import { decodeStoredNodes } from "@aglyn/aglyn/app-utils/stored-nodes";
@@ -41,7 +42,7 @@ import { aiSiteInventoryBlock, runValidatedGeneration } from "./ai-doctrine.js";
41
42
  import { AI_EVAL_AUTOMATION_CAPABILITIES, AI_EVAL_SITE_ID, AI_EVAL_TREE_OUTPUT } from "./ai-eval.js";
42
43
  import { aiEvalMemoryFirestore, aiEvalMemoryInventory } from "./ai-eval-memory-firestore.js";
43
44
  import { aiCategoriesPrompt, aiProductCopyPrompt } from "./ai-products-generation.js";
44
- import { aiLiveBatchWanted } from "./ai-dev-env.js";
45
+ import { aiDevEffortArm, aiLiveBatchWanted } from "./ai-dev-env.js";
45
46
  import { aiModelReadsImages } from "./ai-runtime.js";
46
47
  /**
47
48
  * THE EVAL HARNESS, LIVE (AGL-2937): recording new answers from the model.
@@ -1189,6 +1190,49 @@ const looseText = (value)=>typeof value === 'string' ? value.replace(/\s+/g, ' '
1189
1190
  }
1190
1191
  return result.value;
1191
1192
  }
1193
+ /**
1194
+ * The arm `AGLYN_AI_EFFORT` names, or null when it names none. A recording's
1195
+ * filename carries only the tag, and the recording carries the map: the
1196
+ * filename once spelled the whole list out, and a list of five kinds was
1197
+ * longer than a filename may be (ENAMETOOLONG lost the round's recordings).
1198
+ * The hash is of the parsed, sorted map, so the same efforts written in
1199
+ * another order or spacing are the same arm.
1200
+ */ export function aiEvalEffortArm(env) {
1201
+ const efforts = aiDevEffortArm(env);
1202
+ if (!Object.keys(efforts).length) return null;
1203
+ const hash = createHash('sha256').update(JSON.stringify(efforts)).digest('hex').slice(0, 8);
1204
+ return {
1205
+ tag: `effort-${hash}`,
1206
+ efforts
1207
+ };
1208
+ }
1209
+ /** A recording's file name: `<case>.<model>.json`, with the arm's tag before `.json` when one ran. */ export function aiEvalRecordingFileName(caseId, model, arm) {
1210
+ return `${caseId}.${model != null ? model : 'unknown'}${arm ? `.${arm.tag}` : ''}.json`;
1211
+ }
1212
+ /**
1213
+ * What a recording holds: the brief, the answer, and under `arm` the arm's
1214
+ * tag and every effort it named, when one ran — the candidate's own `effort`
1215
+ * is the one its step was asked at.
1216
+ */ export function aiEvalRecordingBody(caseId, candidate, arm) {
1217
+ return `${JSON.stringify(_extends({
1218
+ caseId
1219
+ }, arm ? {
1220
+ arm
1221
+ } : {}, {
1222
+ candidate
1223
+ }), null, 2)}\n`;
1224
+ }
1225
+ /**
1226
+ * One brief's score line. Everything before the colon is the pairing key —
1227
+ * `score <case> (<kind>) <model>`, then the arm's tag when one ran — so a
1228
+ * default run's line and an arm's line for the same brief sort side by side.
1229
+ */ export function aiEvalScoreLine(entry, pass, arm) {
1230
+ var _candidate_model, _ref, _ref1, _ref2, _ref3;
1231
+ var _candidate_usage;
1232
+ const { caseId, kind, candidate } = entry;
1233
+ const rubric = candidate.rubric;
1234
+ return `score ${caseId} (${kind}) ${(_candidate_model = candidate.model) != null ? _candidate_model : 'unknown'}${arm ? ` ${arm.tag}` : ''}: ` + `${pass ? 'pass' : 'fail'}, structure ${(_ref = rubric == null ? void 0 : rubric.structure) != null ? _ref : '-'}, copy ${(_ref1 = rubric == null ? void 0 : rubric.copy) != null ? _ref1 : '-'}` + `, reuse ${(_ref2 = rubric == null ? void 0 : rubric.reuse) != null ? _ref2 : '-'}, output ${(_ref3 = (_candidate_usage = candidate.usage) == null ? void 0 : _candidate_usage.outputTokens) != null ? _ref3 : '-'} tokens`;
1235
+ }
1192
1236
  /** The vendor's request id off a thrown `UpstreamServiceError`, when it carried one. */ function requestIdOfThrown(error) {
1193
1237
  const id = error == null ? void 0 : error.requestId;
1194
1238
  return typeof id === 'string' && id ? id : null;