agent-accelerator 0.5.6 → 0.5.8

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 (57) hide show
  1. package/README.md +10 -17
  2. package/package.json +1 -1
  3. package/src/agent/agent.ts +92 -57
  4. package/src/agent/architecture.md +25 -0
  5. package/src/agent/context.ts +7 -3
  6. package/src/agent/delegation.ts +30 -96
  7. package/src/agent/loop.ts +54 -56
  8. package/src/agent/subagent.ts +4 -4
  9. package/src/agent/worker.ts +1 -3
  10. package/src/architecture.md +28 -0
  11. package/src/index.ts +13 -80
  12. package/src/models/architecture.md +14 -0
  13. package/src/models/catalog-cache.ts +10 -7
  14. package/src/models/catalog.ts +20 -13
  15. package/src/providers/architecture.md +24 -0
  16. package/src/providers/google.ts +24 -4
  17. package/src/providers/openai-compat.ts +29 -7
  18. package/src/providers/openai.ts +22 -6
  19. package/src/providers/openrouter.ts +14 -2
  20. package/src/providers/registry.ts +1 -0
  21. package/src/providers/shared.ts +4 -4
  22. package/src/providers.ts +9 -53
  23. package/src/scheduler/architecture.md +22 -0
  24. package/src/scheduler/scheduler.ts +131 -56
  25. package/src/scheduler/store.ts +274 -54
  26. package/src/scheduler/time.ts +2 -0
  27. package/src/session/architecture.md +19 -0
  28. package/src/session/store.ts +37 -22
  29. package/src/session/usage.ts +1 -0
  30. package/src/streaming/architecture.md +13 -0
  31. package/src/streaming/event-stream.ts +16 -11
  32. package/src/telemetry-file.ts +74 -24
  33. package/src/telemetry.ts +3 -2
  34. package/src/tools/architecture.md +19 -0
  35. package/src/tools/executor.ts +14 -1
  36. package/src/tools/schema.ts +1 -0
  37. package/src/tools/subagent-result.ts +1 -0
  38. package/src/tools/tool.ts +8 -8
  39. package/src/types/agent.ts +22 -20
  40. package/src/types/architecture.md +20 -0
  41. package/src/types/response.ts +8 -8
  42. package/src/types/scheduler.ts +2 -2
  43. package/src/types/tool.ts +5 -5
  44. package/src/update-models.ts +2 -2
  45. package/src/utils/architecture.md +25 -0
  46. package/src/utils/base64.ts +2 -0
  47. package/src/utils/cache.ts +6 -4
  48. package/src/utils/durable.ts +78 -3
  49. package/src/utils/env.ts +1 -1
  50. package/src/utils/errors.ts +4 -0
  51. package/src/utils/headers.ts +7 -4
  52. package/src/utils/home.ts +1 -1
  53. package/src/utils/media.ts +1 -0
  54. package/src/utils/raw-capture.ts +3 -0
  55. package/src/utils/retry.ts +2 -1
  56. package/src/utils/safe-io.ts +4 -0
  57. package/src/utils/session.ts +10 -166
package/src/providers.ts CHANGED
@@ -42,6 +42,7 @@ export type ProviderCapabilityStatus =
42
42
  */
43
43
  const emittedWarnings = new Set<string>();
44
44
 
45
+ /** Warns once per provider, capability and request about something that cannot be applied as asked: a `provider_warning` bus event, the legacy global sink and console; in: the mappers and adapters, out: those channels. */
45
46
  export function emitProviderWarning(options: {
46
47
  provider: string;
47
48
  capability: string;
@@ -190,40 +191,6 @@ export function mapThinkingLevelToOpenRouterChat(
190
191
  return {};
191
192
  }
192
193
 
193
- /**
194
- * Maps a canonical ThinkingLevel onto OpenRouter Responses `reasoning.effort`.
195
- * Documented efforts: minimal|low|medium|high (server default medium).
196
- * Wire-validated extras: `none` disables reasoning output; `xhigh`/`max` are
197
- * echoed but are NOT documented levels, so they clamp to `high` with a warning.
198
- *
199
- * @deprecated The Responses skin is discontinued for OpenRouter
200
- * (removed from core). Use
201
- * {@link mapThinkingLevelToOpenRouterChat} with the stable Chat Completions
202
- * transport instead.
203
- */
204
- export function mapThinkingLevelToOpenRouter(
205
- level: ThinkingLevel | string | undefined
206
- ): { effort?: string } {
207
- if (!level) return {};
208
- const norm = String(level).toLowerCase().trim();
209
- if (norm === "dynamic") return {}; // server default (medium)
210
- if (norm === "none") return { effort: "none" };
211
- if (norm === "xhigh" || norm === "max") {
212
- emitProviderWarning({
213
- provider: "openrouter",
214
- capability: "thinking level",
215
- requested: String(level),
216
- reason: "OpenRouter documents reasoning efforts up to high.",
217
- fallback: "reasoning effort high",
218
- });
219
- return { effort: "high" };
220
- }
221
- if (norm === "minimal" || norm === "low" || norm === "medium" || norm === "high") {
222
- return { effort: norm };
223
- }
224
- return {};
225
- }
226
-
227
194
  /** Maps canonical ServiceTier onto OpenRouter `service_tier` (omit = auto). */
228
195
  export function mapServiceTierToOpenRouter(tier: ServiceTier | undefined): "flex" | "priority" | undefined {
229
196
  if (tier === "flex" || tier === "priority") return tier;
@@ -287,25 +254,6 @@ export function mapToolChoiceToOpenRouterChat(
287
254
  return undefined;
288
255
  }
289
256
 
290
- /** OpenRouter Responses `tool_choice` wire values.
291
- * @deprecated Discontinued skin; see {@link OpenRouterChatToolChoice}. */
292
- export type OpenRouterToolChoice = "auto" | "none" | "required" | { type: "function"; name: string };
293
-
294
- /**
295
- * Maps canonical toolChoice onto OpenRouter Responses `tool_choice`.
296
- * `auto` is the server default (omitted); `required` is natively supported
297
- * (validated); a function pin passes through verbatim.
298
- */
299
- export function mapToolChoiceToOpenRouter(
300
- choice: "auto" | "none" | "required" | { type: "function"; function: { name: string } } | undefined
301
- ): OpenRouterToolChoice | undefined {
302
- if (!choice || choice === "auto") return undefined;
303
- if (choice === "none" || choice === "required") return choice;
304
- const name = choice.function?.name;
305
- if (name) return { type: "function", name };
306
- return undefined;
307
- }
308
-
309
257
  /**
310
258
  * Maps a canonical ThinkingLevel onto OpenAI Responses `reasoning.effort`.
311
259
  * Documented efforts: none|minimal|low|medium|high|xhigh|max (server default
@@ -383,6 +331,7 @@ export function normalizeToolChoice(
383
331
  return { mode: "any" };
384
332
  }
385
333
 
334
+ // True for a non-array object; in: the argument and schema helpers, out: a type guard.
386
335
  function isPlainObject(value: unknown): value is Record<string, unknown> {
387
336
  return !!value && typeof value === "object" && !Array.isArray(value);
388
337
  }
@@ -449,6 +398,7 @@ export interface GenerationParams {
449
398
 
450
399
  /** Most stop sequences a Chat Completions request may carry (OpenRouter chat-completion api-ref `maxItems`, OpenAI the same). */
451
400
  const MAX_CHAT_STOP = 4;
401
+ // True for a finite number; in: the generation-param mappers, out: a type guard.
452
402
  const finiteNumber = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v);
453
403
 
454
404
  /** Normalizes the public `stop` option (`string | string[]`) to a clean array, or undefined. */
@@ -484,6 +434,7 @@ export function mapGenerationParamsToChat(params: GenerationParams | undefined,
484
434
  return out;
485
435
  }
486
436
 
437
+ // Warns that `stop`/`seed` have no parameter on this wire and are dropped; in: the OpenAI and Google mappers, out: provider_warning events.
487
438
  function warnUnsupportedStopSeed(provider: string, modelRef: string, params: GenerationParams, reasonSuffix: string): void {
488
439
  if (params.stop && params.stop.length > 0) {
489
440
  emitProviderWarning({
@@ -533,6 +484,7 @@ export function mapGenerationParamsToGoogle(
533
484
  // Structured outputs (canonical, pure, no I/O)
534
485
  // ---------------------------------------------------------------------------
535
486
 
487
+ // True when a value looks like a Zod schema (parse/safeParse/_def/~standard); in: structured-output normalization, out: a boolean.
536
488
  function isZodLike(value: unknown): boolean {
537
489
  if (!value || typeof value !== "object") return false;
538
490
  const v = value as Record<string, unknown>;
@@ -544,6 +496,7 @@ function isZodLike(value: unknown): boolean {
544
496
  );
545
497
  }
546
498
 
499
+ // True when a plain object has JSON Schema keywords; in: structured-output normalization, out: a boolean.
547
500
  function looksLikeJsonSchema(value: unknown): boolean {
548
501
  if (!isPlainObject(value)) return false;
549
502
  const v = value as Record<string, unknown>;
@@ -559,12 +512,14 @@ function looksLikeJsonSchema(value: unknown): boolean {
559
512
  );
560
513
  }
561
514
 
515
+ // A structured-output name limited to letters, digits, `_` and `-` (64 chars), default `structured_output`; in: normalizeStructuredOutput, out: the name.
562
516
  function sanitizeOutputName(raw: unknown): string {
563
517
  const base = typeof raw === "string" && raw.trim() ? raw.trim() : "structured_output";
564
518
  const cleaned = base.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64) || "structured_output";
565
519
  return cleaned;
566
520
  }
567
521
 
522
+ // A Zod schema or JSON Schema object as a JSON Schema object, else a ValidationError; in: normalizeStructuredOutput, out: the schema.
568
523
  function schemaToJsonSchema(schema: unknown, what: string): Record<string, unknown> {
569
524
  if (isZodLike(schema)) {
570
525
  try {
@@ -634,6 +589,7 @@ export function extractOutputValidator(output: unknown): { safeParse: (v: unknow
634
589
  return undefined;
635
590
  }
636
591
 
592
+ // Removes a surrounding ```json fence from a model answer; in: parseStructuredOutput, out: the bare text.
637
593
  function stripCodeFences(text: string): string {
638
594
  const trimmed = text.trim();
639
595
  const fenced = trimmed.match(/^```(?:json)?\s*\n([\s\S]*?)\n```\s*$/i);
@@ -0,0 +1,22 @@
1
+ # src/scheduler/
2
+
3
+ Scheduled actions: a worker that runs later (once or repeating) and saves its answer to a file. Off unless `dynamicSubagents.allowScheduledActions` is set.
4
+
5
+ | File | What it is |
6
+ | :-- | :-- |
7
+ | `scheduler.ts` | One `Scheduler` per home folder: a 1 s unref'd clock that runs only while something is pending, startup sweep, cook/deliver state machine, and the public functions (`createScheduledAction`, `list/update/run/skip/deleteScheduledAction`). |
8
+ | `store.ts` | Disk layer under `<home>/scheduled/`: `<id>/task.json`, `<id>/delivery.json`, run files, one short mutex per action; validation of records. |
9
+ | `time.ts` | Pure `DD:HH:MM` and local-clock maths. No timezone, DST or `Intl`; `now` is always passed in. |
10
+ | `tool.ts` + `scheduled-actions.md` | The model-facing `scheduled_actions` tool and `get_datetime`; the `.md` is the tool description. |
11
+
12
+ ## Invariants
13
+ - The files are the truth: every write re-reads first and goes through the durable writer. The file format is a stable public contract: see `docs/scheduled-action-files.md` and add a changelog row for any change.
14
+ - Write order when a run ends: run file, then `<id>/delivery.json`, then `<id>/task.json`. The startup sweep repairs a crash in between.
15
+ - `startCook` advances the next times BEFORE the run starts; a run still cooking when the next is due is skipped, never stacked.
16
+ - Runs are fresh stateless workers built by `buildDynamicWorkerConfig`; their spending guardrail is `workerBudget` only.
17
+ - The Agent registry holds `WeakRef`s by name: keep every Agent that owns actions referenced, or its runs become `missed`.
18
+ - Several processes may share a home (the file store is safe for it; the home lock is lifted in a later change of this release). Ownership: a process only starts, delivers or recovers actions whose Agent it registered. An action nobody here owns is left alone until its delivery time passed with no run started, then marked `missed` (`no_agent`).
19
+ - Exactly once: a scheduled start re-checks under the action's mutex that it is still `waiting` and due; `markMissed` only changes the state the caller saw; a delivery is emitted only by the process that removed its entry from `delivery.json`.
20
+ - A run in flight keeps `<id>/.heartbeat` (pid, host, token; mtime refreshed every 5 s, stale after 60 s), written before the record shows `cooking`. A cooking action whose owner is dead (pid gone, stale, or none) is recovered by a live process that owns its Agent, at start and every 15 s. `delete` of a run another live process is cooking is refused, even with `force`.
21
+ - Times come from `Date`, local clock only. Tests inject `scheduler.now` / `tickMs` and call `tick()`.
22
+ - Events: `scheduled_action.{created,updated,started,ready,failed,delivered,missed,skipped,deleted,invalid,store_corrupt,error}`.