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

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 (94) hide show
  1. package/package.json +17 -17
  2. package/src/lib/components/ai-brief-dialog.component.js +15 -1
  3. package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
  4. package/src/lib/components/ai-job-links.js +1 -1
  5. package/src/lib/components/ai-job-links.js.map +1 -1
  6. package/src/lib/components/ai-job-plan.component.js +20 -2
  7. package/src/lib/components/ai-job-plan.component.js.map +1 -1
  8. package/src/lib/components/ai-jobs-store.d.ts +11 -0
  9. package/src/lib/components/ai-jobs-store.js +22 -0
  10. package/src/lib/components/ai-jobs-store.js.map +1 -1
  11. package/src/lib/jobs/ai-job-crm-step.js +7 -4
  12. package/src/lib/jobs/ai-job-crm-step.js.map +1 -1
  13. package/src/lib/jobs/ai-job-drafts.d.ts +24 -0
  14. package/src/lib/jobs/ai-job-drafts.js +46 -0
  15. package/src/lib/jobs/ai-job-drafts.js.map +1 -1
  16. package/src/lib/jobs/ai-job-experiment-step.js +6 -1
  17. package/src/lib/jobs/ai-job-experiment-step.js.map +1 -1
  18. package/src/lib/jobs/ai-job-form-reuse.d.ts +78 -0
  19. package/src/lib/jobs/ai-job-form-reuse.js +136 -0
  20. package/src/lib/jobs/ai-job-form-reuse.js.map +1 -0
  21. package/src/lib/jobs/ai-job-form-step.d.ts +17 -0
  22. package/src/lib/jobs/ai-job-form-step.js +63 -11
  23. package/src/lib/jobs/ai-job-form-step.js.map +1 -1
  24. package/src/lib/jobs/ai-job-insight-step.js +6 -1
  25. package/src/lib/jobs/ai-job-insight-step.js.map +1 -1
  26. package/src/lib/jobs/ai-job-plan-step.d.ts +19 -0
  27. package/src/lib/jobs/ai-job-plan-step.js +39 -1
  28. package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
  29. package/src/lib/jobs/ai-job-seo-step.js +5 -3
  30. package/src/lib/jobs/ai-job-seo-step.js.map +1 -1
  31. package/src/lib/jobs/ai-job-site-content.d.ts +7 -5
  32. package/src/lib/jobs/ai-job-site-content.js +7 -5
  33. package/src/lib/jobs/ai-job-site-content.js.map +1 -1
  34. package/src/lib/jobs/ai-job-text-step.js +6 -3
  35. package/src/lib/jobs/ai-job-text-step.js.map +1 -1
  36. package/src/lib/jobs/ai-layout-stock-photos.d.ts +11 -7
  37. package/src/lib/jobs/ai-layout-stock-photos.js +25 -10
  38. package/src/lib/jobs/ai-layout-stock-photos.js.map +1 -1
  39. package/src/lib/jobs/ai-stock-business-nouns.d.ts +62 -0
  40. package/src/lib/jobs/ai-stock-business-nouns.js +264 -0
  41. package/src/lib/jobs/ai-stock-business-nouns.js.map +1 -0
  42. package/src/lib/model/ai-build-plan.d.ts +7 -3
  43. package/src/lib/model/ai-build-plan.js +11 -1
  44. package/src/lib/model/ai-build-plan.js.map +1 -1
  45. package/src/lib/model/ai-credit-estimate.d.ts +32 -18
  46. package/src/lib/model/ai-credit-estimate.js +36 -18
  47. package/src/lib/model/ai-credit-estimate.js.map +1 -1
  48. package/src/lib/model/ai-job-activity.d.ts +30 -0
  49. package/src/lib/model/ai-job-activity.js +35 -0
  50. package/src/lib/model/ai-job-activity.js.map +1 -1
  51. package/src/lib/model/ai-media-credits.d.ts +5 -3
  52. package/src/lib/model/ai-media-credits.js +7 -5
  53. package/src/lib/model/ai-media-credits.js.map +1 -1
  54. package/src/lib/model/ai-site-job.js +6 -3
  55. package/src/lib/model/ai-site-job.js.map +1 -1
  56. package/src/lib/model/ai-site-store-pages.d.ts +5 -0
  57. package/src/lib/model/ai-site-store-pages.js +2 -0
  58. package/src/lib/model/ai-site-store-pages.js.map +1 -1
  59. package/src/lib/plugin-config.js +2 -2
  60. package/src/lib/plugin-config.js.map +1 -1
  61. package/src/lib/providers/anthropic-crm-wording-superseded.d.ts +29 -0
  62. package/src/lib/providers/anthropic-crm-wording-superseded.js +31 -0
  63. package/src/lib/providers/anthropic-crm-wording-superseded.js.map +1 -0
  64. package/src/lib/providers/catalog.d.ts +24 -17
  65. package/src/lib/providers/catalog.js +63 -30
  66. package/src/lib/providers/catalog.js.map +1 -1
  67. package/src/lib/providers/model-choice.d.ts +1 -1
  68. package/src/lib/providers/model-choice.js +39 -30
  69. package/src/lib/providers/model-choice.js.map +1 -1
  70. package/src/lib/providers/routing.d.ts +20 -1
  71. package/src/lib/providers/routing.js +47 -8
  72. package/src/lib/providers/routing.js.map +1 -1
  73. package/src/lib/runtime/ai-dev-env.d.ts +37 -1
  74. package/src/lib/runtime/ai-dev-env.js +59 -6
  75. package/src/lib/runtime/ai-dev-env.js.map +1 -1
  76. package/src/lib/runtime/ai-doctrine-validators.js +3 -1
  77. package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
  78. package/src/lib/runtime/ai-doctrine.js +8 -4
  79. package/src/lib/runtime/ai-doctrine.js.map +1 -1
  80. package/src/lib/runtime/ai-eval-live.d.ts +8 -0
  81. package/src/lib/runtime/ai-eval-live.js +34 -8
  82. package/src/lib/runtime/ai-eval-live.js.map +1 -1
  83. package/src/lib/runtime/ai-palette.generated.js +4 -0
  84. package/src/lib/runtime/ai-palette.generated.js.map +1 -1
  85. package/src/lib/runtime/ai-runtime.js +17 -2
  86. package/src/lib/runtime/ai-runtime.js.map +1 -1
  87. package/src/lib/runtime/seo-fields.js +4 -3
  88. package/src/lib/runtime/seo-fields.js.map +1 -1
  89. package/src/lib/server/ai-assist.js +3 -2
  90. package/src/lib/server/ai-assist.js.map +1 -1
  91. package/src/lib/server/ai-media-svg.js +4 -0
  92. package/src/lib/server/ai-media-svg.js.map +1 -1
  93. package/src/lib/usage/ai-allotment-alerts.js +2 -5
  94. package/src/lib/usage/ai-allotment-alerts.js.map +1 -1
@@ -22,6 +22,7 @@
22
22
  * system module into a server that will never use one. Every answer is `off`
23
23
  * in a deployed server.
24
24
  */
25
+ import type { AiEffort } from '../providers/contract';
25
26
  export type AiDevReplayMode = 'off' | 'replay' | 'refresh';
26
27
  /** The variable that turns the replay cache on, off, or to refresh. */
27
28
  export declare const AI_REPLAY_ENV = "AGLYN_AI_REPLAY";
@@ -34,6 +35,17 @@ export declare const AI_LIVE_LAUNCHER_ENV = "AI_EVAL_LIVE_LAUNCHER";
34
35
  export type AiDevEnv = Readonly<Record<string, string | undefined>>;
35
36
  /** Whether this process is a deployed server, where no development layer may run. */
36
37
  export declare function aiIsDeployedRuntime(env?: AiDevEnv): boolean;
38
+ /** The variable every live spec is started with. */
39
+ export declare const AI_LIVE_RUN_ENV = "AGLYN_LIVE_AI";
40
+ /**
41
+ * Whether this process is a development run that asked for the live
42
+ * provider: through the launcher, or a live spec started with
43
+ * `AGLYN_LIVE_AI=1` (AGL-3781). Every development layer is on by default in
44
+ * such a run — a live spec started without the launcher's mark used to send
45
+ * every request again, at the five-minute cache and full price — and each can
46
+ * still be turned off by its own variable.
47
+ */
48
+ export declare function aiUnderLiveRun(env?: AiDevEnv): boolean;
37
49
  /** The replay mode this process runs under; `off` in any deployed server. */
38
50
  export declare function aiDevReplayMode(env?: AiDevEnv): AiDevReplayMode;
39
51
  /**
@@ -49,5 +61,29 @@ export declare function aiDevCacheTtl(env?: AiDevEnv): '1h' | undefined;
49
61
  export declare function aiWarnIfReplayAskedInDeployment(env?: AiDevEnv): void;
50
62
  /** The variable that turns batch mode on (`runtime/ai-live-batch.ts`). */
51
63
  export declare const AI_LIVE_BATCH_ENV = "AGLYN_LIVE_AI_BATCH";
52
- /** Whether this process batches its live requests. */
64
+ /**
65
+ * Whether this process batches its live requests: what `AGLYN_LIVE_AI_BATCH`
66
+ * says, and in a live run that says nothing, yes (AGL-3781). Nobody waits on
67
+ * an eval's answers, and a batch is half price on every token, cache reads
68
+ * and writes included; `AGLYN_LIVE_AI_BATCH=0` is for the quick single run an
69
+ * iteration wants back in seconds.
70
+ */
53
71
  export declare function aiLiveBatchWanted(env?: AiDevEnv): boolean;
72
+ /**
73
+ * The most a batched live run may take: the adapter waits up to an hour on
74
+ * each batch, and a run's requests go as a few batches one after another —
75
+ * the answers, their re-asks, the grades. A spec that timed out would keep
76
+ * none of the answers it already paid for, so the bound is the worst case.
77
+ */
78
+ export declare const AI_LIVE_BATCH_TIMEOUT_MS: number;
79
+ /** A live spec's timeout: `baseMs`, or the batched run's when this run batches. */
80
+ export declare function aiLiveTimeoutMs(baseMs: number, env?: AiDevEnv): number;
81
+ /**
82
+ * The variable an effort A/B names its arm with (AGL-3781): a step kind's
83
+ * effort for this run, as `job.form:medium,job.text:low`, or `*:medium` for
84
+ * every kind. A development run only, so the defaults stay where production
85
+ * runs them until a recorded round shows a lower effort holds.
86
+ */
87
+ export declare const AI_EFFORT_ARM_ENV = "AGLYN_AI_EFFORT";
88
+ /** The effort this development run's A/B arm asks `step` at, or `undefined` for the step's own. */
89
+ export declare function aiDevEffortFor(step: string | undefined, env?: AiDevEnv): AiEffort | undefined;
@@ -27,8 +27,18 @@
27
27
  /** Whether this process is a deployed server, where no development layer may run. */ export function aiIsDeployedRuntime(env = process.env) {
28
28
  return env['NODE_ENV'] === 'production' || env['VERCEL_ENV'] === 'production' || env['VERCEL_ENV'] === 'preview' || Boolean(env['K_SERVICE']);
29
29
  }
30
- /** Whether this process is a development run that asked for the live provider through the launcher. */ function underLiveLauncher(env) {
31
- return Boolean(env[AI_LIVE_LAUNCHER_ENV]);
30
+ /** The variable every live spec is started with. */ export const AI_LIVE_RUN_ENV = 'AGLYN_LIVE_AI';
31
+ /**
32
+ * Whether this process is a development run that asked for the live
33
+ * provider: through the launcher, or a live spec started with
34
+ * `AGLYN_LIVE_AI=1` (AGL-3781). Every development layer is on by default in
35
+ * such a run — a live spec started without the launcher's mark used to send
36
+ * every request again, at the five-minute cache and full price — and each can
37
+ * still be turned off by its own variable.
38
+ */ export function aiUnderLiveRun(env = process.env) {
39
+ var _env_AI_LIVE_RUN_ENV;
40
+ if (aiIsDeployedRuntime(env)) return false;
41
+ return Boolean(env[AI_LIVE_LAUNCHER_ENV]) || String((_env_AI_LIVE_RUN_ENV = env[AI_LIVE_RUN_ENV]) != null ? _env_AI_LIVE_RUN_ENV : '').trim() === '1';
32
42
  }
33
43
  /** The replay mode this process runs under; `off` in any deployed server. */ export function aiDevReplayMode(env = process.env) {
34
44
  var _env_AI_REPLAY_ENV;
@@ -37,7 +47,7 @@
37
47
  if (raw === 'refresh') return 'refresh';
38
48
  if (raw === '1' || raw === 'on' || raw === 'true' || raw === 'replay') return 'replay';
39
49
  if (raw === '0' || raw === 'off' || raw === 'false') return 'off';
40
- return underLiveLauncher(env) ? 'replay' : 'off';
50
+ return aiUnderLiveRun(env) ? 'replay' : 'off';
41
51
  }
42
52
  /**
43
53
  * The prompt-cache lifetime a development run asks for. An agent re-runs a
@@ -53,7 +63,7 @@
53
63
  const raw = String((_env_AI_DEV_CACHE_TTL_ENV = env[AI_DEV_CACHE_TTL_ENV]) != null ? _env_AI_DEV_CACHE_TTL_ENV : '').trim().toLowerCase();
54
64
  if (raw === '1h') return '1h';
55
65
  if (raw === '5m') return undefined;
56
- return underLiveLauncher(env) ? '1h' : undefined;
66
+ return aiUnderLiveRun(env) ? '1h' : undefined;
57
67
  }
58
68
  /** A deployed server that was handed the variable says so once, and runs without it. */ let warnedDeployed = false;
59
69
  export function aiWarnIfReplayAskedInDeployment(env = process.env) {
@@ -63,10 +73,53 @@ export function aiWarnIfReplayAskedInDeployment(env = process.env) {
63
73
  console.error(`[ai] ${AI_REPLAY_ENV} / ${AI_DEV_CACHE_TTL_ENV} are development-only and are ignored in a deployed server`);
64
74
  }
65
75
  /** The variable that turns batch mode on (`runtime/ai-live-batch.ts`). */ export const AI_LIVE_BATCH_ENV = 'AGLYN_LIVE_AI_BATCH';
66
- /** Whether this process batches its live requests. */ export function aiLiveBatchWanted(env = process.env) {
76
+ /**
77
+ * Whether this process batches its live requests: what `AGLYN_LIVE_AI_BATCH`
78
+ * says, and in a live run that says nothing, yes (AGL-3781). Nobody waits on
79
+ * an eval's answers, and a batch is half price on every token, cache reads
80
+ * and writes included; `AGLYN_LIVE_AI_BATCH=0` is for the quick single run an
81
+ * iteration wants back in seconds.
82
+ */ export function aiLiveBatchWanted(env = process.env) {
67
83
  var _env_AI_LIVE_BATCH_ENV;
68
84
  if (aiIsDeployedRuntime(env)) return false;
69
- return /^(?:1|true|yes|on)$/i.test(String((_env_AI_LIVE_BATCH_ENV = env[AI_LIVE_BATCH_ENV]) != null ? _env_AI_LIVE_BATCH_ENV : '').trim());
85
+ const raw = String((_env_AI_LIVE_BATCH_ENV = env[AI_LIVE_BATCH_ENV]) != null ? _env_AI_LIVE_BATCH_ENV : '').trim();
86
+ if (/^(?:1|true|yes|on)$/i.test(raw)) return true;
87
+ if (/^(?:0|false|no|off)$/i.test(raw)) return false;
88
+ return aiUnderLiveRun(env);
89
+ }
90
+ /**
91
+ * The most a batched live run may take: the adapter waits up to an hour on
92
+ * each batch, and a run's requests go as a few batches one after another —
93
+ * the answers, their re-asks, the grades. A spec that timed out would keep
94
+ * none of the answers it already paid for, so the bound is the worst case.
95
+ */ export const AI_LIVE_BATCH_TIMEOUT_MS = 5 * 60 * 60000;
96
+ /** A live spec's timeout: `baseMs`, or the batched run's when this run batches. */ export function aiLiveTimeoutMs(baseMs, env = process.env) {
97
+ return aiLiveBatchWanted(env) ? Math.max(baseMs, AI_LIVE_BATCH_TIMEOUT_MS) : baseMs;
98
+ }
99
+ /**
100
+ * The variable an effort A/B names its arm with (AGL-3781): a step kind's
101
+ * effort for this run, as `job.form:medium,job.text:low`, or `*:medium` for
102
+ * every kind. A development run only, so the defaults stay where production
103
+ * runs them until a recorded round shows a lower effort holds.
104
+ */ export const AI_EFFORT_ARM_ENV = 'AGLYN_AI_EFFORT';
105
+ const AI_EFFORT_LEVELS = [
106
+ 'low',
107
+ 'medium',
108
+ 'high'
109
+ ];
110
+ /** The effort this development run's A/B arm asks `step` at, or `undefined` for the step's own. */ export function aiDevEffortFor(step, env = process.env) {
111
+ var _env_AI_EFFORT_ARM_ENV;
112
+ if (aiIsDeployedRuntime(env)) return undefined;
113
+ const raw = String((_env_AI_EFFORT_ARM_ENV = env[AI_EFFORT_ARM_ENV]) != null ? _env_AI_EFFORT_ARM_ENV : '').trim();
114
+ if (!raw) return undefined;
115
+ let fallback;
116
+ for (const pair of raw.split(',')){
117
+ const [kind, level] = pair.split(':').map((part)=>part.trim());
118
+ if (!AI_EFFORT_LEVELS.includes(level)) continue;
119
+ if (kind === step) return level;
120
+ if (kind === '*') fallback = level;
121
+ }
122
+ return fallback;
70
123
  }
71
124
 
72
125
  //# sourceMappingURL=ai-dev-env.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-dev-env.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Which development layers this process runs (AGL-3660): the replay cache,\n * the hour-long prompt cache and batch mode, each read from the environment.\n * Kept apart from `ai-dev-replay.ts`, which reads and writes files, so the\n * runtime asks these questions on every request without loading a file\n * system module into a server that will never use one. Every answer is `off`\n * in a deployed server.\n */\n\nexport type AiDevReplayMode = 'off' | 'replay' | 'refresh'\n\n/** The variable that turns the replay cache on, off, or to refresh. */\nexport const AI_REPLAY_ENV = 'AGLYN_AI_REPLAY'\n/** Where the answers are kept, when not under the repository's `.cache/ai-replay`. */\nexport const AI_REPLAY_DIR_ENV = 'AGLYN_AI_REPLAY_DIR'\n/** The prompt-cache lifetime a development run asks for: `1h` or `5m`. */\nexport const AI_DEV_CACHE_TTL_ENV = 'AGLYN_AI_CACHE_TTL'\n/** The mark the live-eval launcher leaves, which `jest.setup.js` also reads. */\nexport const AI_LIVE_LAUNCHER_ENV = 'AI_EVAL_LIVE_LAUNCHER'\n\nexport type AiDevEnv = Readonly<Record<string, string | undefined>>\n\n/** Whether this process is a deployed server, where no development layer may run. */\nexport function aiIsDeployedRuntime(env: AiDevEnv = process.env): boolean {\n return (\n env['NODE_ENV'] === 'production' ||\n env['VERCEL_ENV'] === 'production' ||\n env['VERCEL_ENV'] === 'preview' ||\n Boolean(env['K_SERVICE'])\n )\n}\n\n/** Whether this process is a development run that asked for the live provider through the launcher. */\nfunction underLiveLauncher(env: AiDevEnv): boolean {\n return Boolean(env[AI_LIVE_LAUNCHER_ENV])\n}\n\n/** The replay mode this process runs under; `off` in any deployed server. */\nexport function aiDevReplayMode(env: AiDevEnv = process.env): AiDevReplayMode {\n if (aiIsDeployedRuntime(env)) return 'off'\n const raw = String(env[AI_REPLAY_ENV] ?? '').trim().toLowerCase()\n if (raw === 'refresh') return 'refresh'\n if (raw === '1' || raw === 'on' || raw === 'true' || raw === 'replay') return 'replay'\n if (raw === '0' || raw === 'off' || raw === 'false') return 'off'\n return underLiveLauncher(env) ? 'replay' : 'off'\n}\n\n/**\n * The prompt-cache lifetime a development run asks for. An agent re-runs a\n * live eval every ten to forty minutes while it iterates, which is past the\n * default five-minute entry and inside an hour, so under the launcher the\n * breakpoints ask for the hour: the second run reads the prefix the first one\n * wrote instead of writing it again. Production keeps the default — its\n * steps run a minute apart on the beat, inside five minutes — and never reads\n * this: `undefined` there.\n */\nexport function aiDevCacheTtl(env: AiDevEnv = process.env): '1h' | undefined {\n if (aiIsDeployedRuntime(env)) return undefined\n const raw = String(env[AI_DEV_CACHE_TTL_ENV] ?? '').trim().toLowerCase()\n if (raw === '1h') return '1h'\n if (raw === '5m') return undefined\n return underLiveLauncher(env) ? '1h' : undefined\n}\n\n/** A deployed server that was handed the variable says so once, and runs without it. */\nlet warnedDeployed = false\nexport function aiWarnIfReplayAskedInDeployment(env: AiDevEnv = process.env): void {\n if (warnedDeployed || !aiIsDeployedRuntime(env)) return\n if (!env[AI_REPLAY_ENV] && !env[AI_DEV_CACHE_TTL_ENV]) return\n warnedDeployed = true\n console.error(\n `[ai] ${AI_REPLAY_ENV} / ${AI_DEV_CACHE_TTL_ENV} are development-only and are ignored in a deployed server`,\n )\n}\n\n/** The variable that turns batch mode on (`runtime/ai-live-batch.ts`). */\nexport const AI_LIVE_BATCH_ENV = 'AGLYN_LIVE_AI_BATCH'\n\n/** Whether this process batches its live requests. */\nexport function aiLiveBatchWanted(env: AiDevEnv = process.env): boolean {\n if (aiIsDeployedRuntime(env)) return false\n return /^(?:1|true|yes|on)$/i.test(String(env[AI_LIVE_BATCH_ENV] ?? '').trim())\n}\n"],"names":["AI_REPLAY_ENV","AI_REPLAY_DIR_ENV","AI_DEV_CACHE_TTL_ENV","AI_LIVE_LAUNCHER_ENV","aiIsDeployedRuntime","env","process","Boolean","underLiveLauncher","aiDevReplayMode","raw","String","trim","toLowerCase","aiDevCacheTtl","undefined","warnedDeployed","aiWarnIfReplayAskedInDeployment","console","error","AI_LIVE_BATCH_ENV","aiLiveBatchWanted","test"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAED;;;;;;;CAOC,GAID,qEAAqE,GACrE,OAAO,MAAMA,gBAAgB,kBAAiB;AAC9C,oFAAoF,GACpF,OAAO,MAAMC,oBAAoB,sBAAqB;AACtD,wEAAwE,GACxE,OAAO,MAAMC,uBAAuB,qBAAoB;AACxD,8EAA8E,GAC9E,OAAO,MAAMC,uBAAuB,wBAAuB;AAI3D,mFAAmF,GACnF,OAAO,SAASC,oBAAoBC,MAAgBC,QAAQD,GAAG;IAC7D,OACEA,GAAG,CAAC,WAAW,KAAK,gBACpBA,GAAG,CAAC,aAAa,KAAK,gBACtBA,GAAG,CAAC,aAAa,KAAK,aACtBE,QAAQF,GAAG,CAAC,YAAY;AAE5B;AAEA,qGAAqG,GACrG,SAASG,kBAAkBH,GAAa;IACtC,OAAOE,QAAQF,GAAG,CAACF,qBAAqB;AAC1C;AAEA,2EAA2E,GAC3E,OAAO,SAASM,gBAAgBJ,MAAgBC,QAAQD,GAAG;QAEtCA;IADnB,IAAID,oBAAoBC,MAAM,OAAO;IACrC,MAAMK,MAAMC,QAAON,qBAAAA,GAAG,CAACL,cAAc,YAAlBK,qBAAsB,IAAIO,IAAI,GAAGC,WAAW;IAC/D,IAAIH,QAAQ,WAAW,OAAO;IAC9B,IAAIA,QAAQ,OAAOA,QAAQ,QAAQA,QAAQ,UAAUA,QAAQ,UAAU,OAAO;IAC9E,IAAIA,QAAQ,OAAOA,QAAQ,SAASA,QAAQ,SAAS,OAAO;IAC5D,OAAOF,kBAAkBH,OAAO,WAAW;AAC7C;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASS,cAAcT,MAAgBC,QAAQD,GAAG;QAEpCA;IADnB,IAAID,oBAAoBC,MAAM,OAAOU;IACrC,MAAML,MAAMC,QAAON,4BAAAA,GAAG,CAACH,qBAAqB,YAAzBG,4BAA6B,IAAIO,IAAI,GAAGC,WAAW;IACtE,IAAIH,QAAQ,MAAM,OAAO;IACzB,IAAIA,QAAQ,MAAM,OAAOK;IACzB,OAAOP,kBAAkBH,OAAO,OAAOU;AACzC;AAEA,sFAAsF,GACtF,IAAIC,iBAAiB;AACrB,OAAO,SAASC,gCAAgCZ,MAAgBC,QAAQD,GAAG;IACzE,IAAIW,kBAAkB,CAACZ,oBAAoBC,MAAM;IACjD,IAAI,CAACA,GAAG,CAACL,cAAc,IAAI,CAACK,GAAG,CAACH,qBAAqB,EAAE;IACvDc,iBAAiB;IACjBE,QAAQC,KAAK,CACX,CAAC,KAAK,EAAEnB,cAAc,GAAG,EAAEE,qBAAqB,0DAA0D,CAAC;AAE/G;AAEA,wEAAwE,GACxE,OAAO,MAAMkB,oBAAoB,sBAAqB;AAEtD,oDAAoD,GACpD,OAAO,SAASC,kBAAkBhB,MAAgBC,QAAQD,GAAG;QAEjBA;IAD1C,IAAID,oBAAoBC,MAAM,OAAO;IACrC,OAAO,uBAAuBiB,IAAI,CAACX,QAAON,yBAAAA,GAAG,CAACe,kBAAkB,YAAtBf,yBAA0B,IAAIO,IAAI;AAC9E"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/ai/src/lib/runtime/ai-dev-env.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Which development layers this process runs (AGL-3660): the replay cache,\n * the hour-long prompt cache and batch mode, each read from the environment.\n * Kept apart from `ai-dev-replay.ts`, which reads and writes files, so the\n * runtime asks these questions on every request without loading a file\n * system module into a server that will never use one. Every answer is `off`\n * in a deployed server.\n */\n\nimport type { AiEffort } from '../providers/contract'\n\nexport type AiDevReplayMode = 'off' | 'replay' | 'refresh'\n\n/** The variable that turns the replay cache on, off, or to refresh. */\nexport const AI_REPLAY_ENV = 'AGLYN_AI_REPLAY'\n/** Where the answers are kept, when not under the repository's `.cache/ai-replay`. */\nexport const AI_REPLAY_DIR_ENV = 'AGLYN_AI_REPLAY_DIR'\n/** The prompt-cache lifetime a development run asks for: `1h` or `5m`. */\nexport const AI_DEV_CACHE_TTL_ENV = 'AGLYN_AI_CACHE_TTL'\n/** The mark the live-eval launcher leaves, which `jest.setup.js` also reads. */\nexport const AI_LIVE_LAUNCHER_ENV = 'AI_EVAL_LIVE_LAUNCHER'\n\nexport type AiDevEnv = Readonly<Record<string, string | undefined>>\n\n/** Whether this process is a deployed server, where no development layer may run. */\nexport function aiIsDeployedRuntime(env: AiDevEnv = process.env): boolean {\n return (\n env['NODE_ENV'] === 'production' ||\n env['VERCEL_ENV'] === 'production' ||\n env['VERCEL_ENV'] === 'preview' ||\n Boolean(env['K_SERVICE'])\n )\n}\n\n/** The variable every live spec is started with. */\nexport const AI_LIVE_RUN_ENV = 'AGLYN_LIVE_AI'\n\n/**\n * Whether this process is a development run that asked for the live\n * provider: through the launcher, or a live spec started with\n * `AGLYN_LIVE_AI=1` (AGL-3781). Every development layer is on by default in\n * such a run — a live spec started without the launcher's mark used to send\n * every request again, at the five-minute cache and full price — and each can\n * still be turned off by its own variable.\n */\nexport function aiUnderLiveRun(env: AiDevEnv = process.env): boolean {\n if (aiIsDeployedRuntime(env)) return false\n return Boolean(env[AI_LIVE_LAUNCHER_ENV]) || String(env[AI_LIVE_RUN_ENV] ?? '').trim() === '1'\n}\n\n/** The replay mode this process runs under; `off` in any deployed server. */\nexport function aiDevReplayMode(env: AiDevEnv = process.env): AiDevReplayMode {\n if (aiIsDeployedRuntime(env)) return 'off'\n const raw = String(env[AI_REPLAY_ENV] ?? '').trim().toLowerCase()\n if (raw === 'refresh') return 'refresh'\n if (raw === '1' || raw === 'on' || raw === 'true' || raw === 'replay') return 'replay'\n if (raw === '0' || raw === 'off' || raw === 'false') return 'off'\n return aiUnderLiveRun(env) ? 'replay' : 'off'\n}\n\n/**\n * The prompt-cache lifetime a development run asks for. An agent re-runs a\n * live eval every ten to forty minutes while it iterates, which is past the\n * default five-minute entry and inside an hour, so under the launcher the\n * breakpoints ask for the hour: the second run reads the prefix the first one\n * wrote instead of writing it again. Production keeps the default — its\n * steps run a minute apart on the beat, inside five minutes — and never reads\n * this: `undefined` there.\n */\nexport function aiDevCacheTtl(env: AiDevEnv = process.env): '1h' | undefined {\n if (aiIsDeployedRuntime(env)) return undefined\n const raw = String(env[AI_DEV_CACHE_TTL_ENV] ?? '').trim().toLowerCase()\n if (raw === '1h') return '1h'\n if (raw === '5m') return undefined\n return aiUnderLiveRun(env) ? '1h' : undefined\n}\n\n/** A deployed server that was handed the variable says so once, and runs without it. */\nlet warnedDeployed = false\nexport function aiWarnIfReplayAskedInDeployment(env: AiDevEnv = process.env): void {\n if (warnedDeployed || !aiIsDeployedRuntime(env)) return\n if (!env[AI_REPLAY_ENV] && !env[AI_DEV_CACHE_TTL_ENV]) return\n warnedDeployed = true\n console.error(\n `[ai] ${AI_REPLAY_ENV} / ${AI_DEV_CACHE_TTL_ENV} are development-only and are ignored in a deployed server`,\n )\n}\n\n/** The variable that turns batch mode on (`runtime/ai-live-batch.ts`). */\nexport const AI_LIVE_BATCH_ENV = 'AGLYN_LIVE_AI_BATCH'\n\n/**\n * Whether this process batches its live requests: what `AGLYN_LIVE_AI_BATCH`\n * says, and in a live run that says nothing, yes (AGL-3781). Nobody waits on\n * an eval's answers, and a batch is half price on every token, cache reads\n * and writes included; `AGLYN_LIVE_AI_BATCH=0` is for the quick single run an\n * iteration wants back in seconds.\n */\nexport function aiLiveBatchWanted(env: AiDevEnv = process.env): boolean {\n if (aiIsDeployedRuntime(env)) return false\n const raw = String(env[AI_LIVE_BATCH_ENV] ?? '').trim()\n if (/^(?:1|true|yes|on)$/i.test(raw)) return true\n if (/^(?:0|false|no|off)$/i.test(raw)) return false\n return aiUnderLiveRun(env)\n}\n\n/**\n * The most a batched live run may take: the adapter waits up to an hour on\n * each batch, and a run's requests go as a few batches one after another —\n * the answers, their re-asks, the grades. A spec that timed out would keep\n * none of the answers it already paid for, so the bound is the worst case.\n */\nexport const AI_LIVE_BATCH_TIMEOUT_MS = 5 * 60 * 60_000\n\n/** A live spec's timeout: `baseMs`, or the batched run's when this run batches. */\nexport function aiLiveTimeoutMs(baseMs: number, env: AiDevEnv = process.env): number {\n return aiLiveBatchWanted(env) ? Math.max(baseMs, AI_LIVE_BATCH_TIMEOUT_MS) : baseMs\n}\n\n/**\n * The variable an effort A/B names its arm with (AGL-3781): a step kind's\n * effort for this run, as `job.form:medium,job.text:low`, or `*:medium` for\n * every kind. A development run only, so the defaults stay where production\n * runs them until a recorded round shows a lower effort holds.\n */\nexport const AI_EFFORT_ARM_ENV = 'AGLYN_AI_EFFORT'\n\nconst AI_EFFORT_LEVELS: readonly AiEffort[] = ['low', 'medium', 'high']\n\n/** The effort this development run's A/B arm asks `step` at, or `undefined` for the step's own. */\nexport function aiDevEffortFor(step: string | undefined, env: AiDevEnv = process.env): AiEffort | undefined {\n if (aiIsDeployedRuntime(env)) return undefined\n const raw = String(env[AI_EFFORT_ARM_ENV] ?? '').trim()\n if (!raw) return undefined\n let fallback: AiEffort | undefined\n for (const pair of raw.split(',')) {\n const [kind, level] = pair.split(':').map((part) => part.trim())\n if (!AI_EFFORT_LEVELS.includes(level as AiEffort)) continue\n if (kind === step) return level as AiEffort\n if (kind === '*') fallback = level as AiEffort\n }\n return fallback\n}\n"],"names":["AI_REPLAY_ENV","AI_REPLAY_DIR_ENV","AI_DEV_CACHE_TTL_ENV","AI_LIVE_LAUNCHER_ENV","aiIsDeployedRuntime","env","process","Boolean","AI_LIVE_RUN_ENV","aiUnderLiveRun","String","trim","aiDevReplayMode","raw","toLowerCase","aiDevCacheTtl","undefined","warnedDeployed","aiWarnIfReplayAskedInDeployment","console","error","AI_LIVE_BATCH_ENV","aiLiveBatchWanted","test","AI_LIVE_BATCH_TIMEOUT_MS","aiLiveTimeoutMs","baseMs","Math","max","AI_EFFORT_ARM_ENV","AI_EFFORT_LEVELS","aiDevEffortFor","step","fallback","pair","split","kind","level","map","part","includes"],"mappings":"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"}
@@ -4473,7 +4473,9 @@ function slugKey(slug) {
4473
4473
  layout: 64,
4474
4474
  firstSection: 44,
4475
4475
  laterSection: 20,
4476
- listing: 3
4476
+ // A page's listing, on the fast tier at the platform's markup since
4477
+ // AGL-3781 (3 credits at Claude Haiku 4.5's cost before).
4478
+ listing: 1
4477
4479
  };
4478
4480
  /**
4479
4481
  * The most sections a Free job fits in `FREE_AI_TASTE_CREDITS_PER_MONTH` at