@aeye/core 0.5.4 → 0.7.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 (124) hide show
  1. package/README.md +790 -724
  2. package/aeye-core-prompts.md +179 -178
  3. package/aeye-core-schema.md +43 -16
  4. package/aeye-core-tools.md +179 -177
  5. package/aeye-core-types.md +1 -0
  6. package/dist/common.d.ts +30 -5
  7. package/dist/common.d.ts.map +1 -1
  8. package/dist/common.js +134 -129
  9. package/dist/common.js.map +1 -1
  10. package/dist/delivery.d.ts +39 -0
  11. package/dist/delivery.d.ts.map +1 -0
  12. package/dist/delivery.js +127 -0
  13. package/dist/delivery.js.map +1 -0
  14. package/dist/errors.d.ts +60 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +84 -0
  17. package/dist/errors.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/prompt.d.ts +134 -15
  23. package/dist/prompt.d.ts.map +1 -1
  24. package/dist/prompt.js +220 -164
  25. package/dist/prompt.js.map +1 -1
  26. package/dist/schema/analyze.d.ts +94 -0
  27. package/dist/schema/analyze.d.ts.map +1 -0
  28. package/dist/schema/analyze.js +221 -0
  29. package/dist/schema/analyze.js.map +1 -0
  30. package/dist/schema/any-value.d.ts +32 -0
  31. package/dist/schema/any-value.d.ts.map +1 -0
  32. package/dist/schema/any-value.js +77 -0
  33. package/dist/schema/any-value.js.map +1 -0
  34. package/dist/schema/budget.d.ts +114 -0
  35. package/dist/schema/budget.d.ts.map +1 -0
  36. package/dist/schema/budget.js +223 -0
  37. package/dist/schema/budget.js.map +1 -0
  38. package/dist/schema/check-bag.d.ts +28 -0
  39. package/dist/schema/check-bag.d.ts.map +1 -0
  40. package/dist/schema/check-bag.js +129 -0
  41. package/dist/schema/check-bag.js.map +1 -0
  42. package/dist/schema/consistency.d.ts +27 -0
  43. package/dist/schema/consistency.d.ts.map +1 -0
  44. package/dist/schema/consistency.js +110 -0
  45. package/dist/schema/consistency.js.map +1 -0
  46. package/dist/schema/cycle-breaker.d.ts +14 -0
  47. package/dist/schema/cycle-breaker.d.ts.map +1 -0
  48. package/dist/schema/cycle-breaker.js +157 -0
  49. package/dist/schema/cycle-breaker.js.map +1 -0
  50. package/dist/schema/decode.d.ts +31 -0
  51. package/dist/schema/decode.d.ts.map +1 -0
  52. package/dist/schema/decode.js +207 -0
  53. package/dist/schema/decode.js.map +1 -0
  54. package/dist/schema/descriptor.d.ts +300 -0
  55. package/dist/schema/descriptor.d.ts.map +1 -0
  56. package/dist/schema/descriptor.js +15 -0
  57. package/dist/schema/descriptor.js.map +1 -0
  58. package/dist/schema/dialects/anthropic.d.ts +34 -0
  59. package/dist/schema/dialects/anthropic.d.ts.map +1 -0
  60. package/dist/schema/dialects/anthropic.js +77 -0
  61. package/dist/schema/dialects/anthropic.js.map +1 -0
  62. package/dist/schema/dialects/google.d.ts +47 -0
  63. package/dist/schema/dialects/google.d.ts.map +1 -0
  64. package/dist/schema/dialects/google.js +91 -0
  65. package/dist/schema/dialects/google.js.map +1 -0
  66. package/dist/schema/dialects/lenient.d.ts +4 -0
  67. package/dist/schema/dialects/lenient.d.ts.map +1 -0
  68. package/dist/schema/dialects/lenient.js +26 -0
  69. package/dist/schema/dialects/lenient.js.map +1 -0
  70. package/dist/schema/dialects/openai.d.ts +40 -0
  71. package/dist/schema/dialects/openai.d.ts.map +1 -0
  72. package/dist/schema/dialects/openai.js +81 -0
  73. package/dist/schema/dialects/openai.js.map +1 -0
  74. package/dist/schema/dialects/xai.d.ts +23 -0
  75. package/dist/schema/dialects/xai.d.ts.map +1 -0
  76. package/dist/schema/dialects/xai.js +53 -0
  77. package/dist/schema/dialects/xai.js.map +1 -0
  78. package/dist/schema/enum-values.d.ts +44 -0
  79. package/dist/schema/enum-values.d.ts.map +1 -0
  80. package/dist/schema/enum-values.js +56 -0
  81. package/dist/schema/enum-values.js.map +1 -0
  82. package/dist/schema/expressible.d.ts +59 -0
  83. package/dist/schema/expressible.d.ts.map +1 -0
  84. package/dist/schema/expressible.js +161 -0
  85. package/dist/schema/expressible.js.map +1 -0
  86. package/dist/schema/index.d.ts +20 -0
  87. package/dist/schema/index.d.ts.map +1 -0
  88. package/dist/schema/index.js +20 -0
  89. package/dist/schema/index.js.map +1 -0
  90. package/dist/schema/json-schema.d.ts +64 -0
  91. package/dist/schema/json-schema.d.ts.map +1 -0
  92. package/dist/schema/json-schema.js +2 -0
  93. package/dist/schema/json-schema.js.map +1 -0
  94. package/dist/schema/registry.d.ts +73 -0
  95. package/dist/schema/registry.d.ts.map +1 -0
  96. package/dist/schema/registry.js +135 -0
  97. package/dist/schema/registry.js.map +1 -0
  98. package/dist/schema/strictify.d.ts +19 -0
  99. package/dist/schema/strictify.d.ts.map +1 -0
  100. package/dist/schema/strictify.js +237 -0
  101. package/dist/schema/strictify.js.map +1 -0
  102. package/dist/schema/to-json-schema.d.ts +29 -0
  103. package/dist/schema/to-json-schema.d.ts.map +1 -0
  104. package/dist/schema/to-json-schema.js +692 -0
  105. package/dist/schema/to-json-schema.js.map +1 -0
  106. package/dist/schema/walk-key.d.ts +24 -0
  107. package/dist/schema/walk-key.d.ts.map +1 -0
  108. package/dist/schema/walk-key.js +33 -0
  109. package/dist/schema/walk-key.js.map +1 -0
  110. package/dist/to.js +1 -1
  111. package/dist/to.js.map +1 -1
  112. package/dist/tool.d.ts +38 -4
  113. package/dist/tool.d.ts.map +1 -1
  114. package/dist/tool.js +52 -8
  115. package/dist/tool.js.map +1 -1
  116. package/dist/types.d.ts +265 -8
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +4 -1
  119. package/dist/types.js.map +1 -1
  120. package/package.json +2 -2
  121. package/dist/schema.d.ts +0 -840
  122. package/dist/schema.d.ts.map +0 -1
  123. package/dist/schema.js +0 -2478
  124. package/dist/schema.js.map +0 -1
@@ -1,177 +1,179 @@
1
- # @aeye/core — Tool & Agent
2
-
3
- Both are `Component`s. A **Tool** is a single callable function exposed to the model (or invoked directly). An **Agent** is plain orchestration code that composes other components — no LLM loop of its own.
4
-
5
- ## Tool
6
-
7
- ```typescript
8
- class Tool<TContext = {}, TMetadata = {}, TName extends string = string,
9
- TParams extends object = {}, TOutput = string,
10
- TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = [],
11
- TDecoded extends unknown = TParams>
12
- implements Component<...>
13
- ```
14
-
15
- `TDecoded` is the decoded type a custom `parse` produces from the raw wire args — **any** value (a built class instance, a number, a `Date`, …), not just an object; it types `call`, `validate`, and `metadataFn`. It defaults to the wire `TParams` when no custom `parse` is supplied — `schema` always stays the wire type.
16
-
17
- ### `ToolInput` (constructor config)
18
-
19
- | Field | Type | Notes |
20
- |------|------|-------|
21
- | `name` | `TName` | Shown to the model; unique per request. |
22
- | `description` | `string` | Shown to the model. |
23
- | `descriptionFn?` | `Fn<string, [ctx]>` | Refine description from context. |
24
- | `instructions?` | `string` | Handlebars usage instructions. |
25
- | `instructionsFn?` | `Fn<string, [ctx]>` | Context-derived instructions. |
26
- | `input?` | `Fn<Record<string,any>, [ctx]>` | Variables for the instructions template. |
27
- | `schema` | `Fn<ZodType<TParams> \| undefined, [ctx]>` | **Required.** Param schema; may depend on ctx. `undefined` ⇒ unavailable. |
28
- | `strict?` | `boolean \| number` | Strict-mode policy, default `1`. See [schema doc](./aeye-core-schema.md). |
29
- | `refs?` | `TRefs` | Components passed positionally to `call`. |
30
- | `call` | `(input: TParams, refs: TRefs, ctx) => TOutput` | **Required.** Implementation (sync or async). |
31
- | `validate?` | `(input, ctx) => void \| Promise<void>` | Runs after Zod parse; throw to re-prompt. |
32
- | `maxArgsLength?` | `number` | Reject raw args string over N chars before `JSON.parse` (guards against providers that corrupt large tool args). |
33
- | `applicable?` | `(ctx) => boolean \| Promise<boolean>` | Availability check. |
34
- | `metadata?` / `metadataFn?` | `TMetadata` / fn | Execution metadata. |
35
-
36
- ### Methods
37
-
38
- ```typescript
39
- run(input?: TParams, ctx?: Context): TOutput // call directly
40
- compile(ctx): Promise<readonly [string, ToolDefinition] | undefined> // build AI tool def
41
- parse(ctx, args, schema?, descriptor?, onRepairAttempt?): Promise<...> // validate raw JSON args
42
- applicable(ctx?): Promise<boolean>
43
- metadata(input?, ctx?): TMetadata | Promise<TMetadata>
44
- ```
45
-
46
- `compile` returns `undefined` when the tool isn't applicable / has no schema for the context. `parse` validates the model's JSON `arguments` string against the (descriptor-strictified) schema and runs `validate`; it tolerates one provider misbehavior — top-level JSON-stringified fields are re-parsed and `onRepairAttempt` fires for telemetry. When a custom `parse` is supplied (it REPLACES Zod validation), core first wire-decodes the args to the conceptual shape with the request's `FormatDescriptor` (`decodeWire` — array-of-pairs→record, null→undefined, numeric-key→tuple, …), so a custom parser is provider-agnostic and never sees a model family's wire quirks.
47
-
48
- ### Basic tool
49
-
50
- ```typescript
51
- import { Tool } from '@aeye/core';
52
- import z from 'zod';
53
-
54
- const getWeather = new Tool({
55
- name: 'getWeather',
56
- description: 'Get current weather for a location',
57
- instructions: 'Use this to look up weather for {{location}}.',
58
- schema: z.object({
59
- location: z.string().describe('City name'),
60
- units: z.enum(['celsius', 'fahrenheit']).default('celsius'),
61
- }),
62
- call: async (input, _refs, _ctx) => {
63
- const data = await fetchWeather(input.location, input.units);
64
- return { temperature: data.temp, condition: data.condition };
65
- },
66
- });
67
-
68
- // Direct invocation (no model needed):
69
- const w = await getWeather.run({ location: 'Paris' }, {});
70
- ```
71
-
72
- ### Context-aware schema & applicability
73
-
74
- ```typescript
75
- const manageData = new Tool({
76
- name: 'manageData',
77
- description: 'Manage data records',
78
- schema: (ctx: Context<MyCtx, {}>) =>
79
- ctx.userRole === 'admin'
80
- ? z.object({ action: z.enum(['read', 'write', 'delete']) })
81
- : z.object({ action: z.enum(['read']) }),
82
- applicable: (ctx) => ctx.isAuthenticated,
83
- call: async (input, _refs, ctx) => ({ action: input.action, by: ctx.userRole }),
84
- });
85
- ```
86
-
87
- ### Business-logic validation
88
-
89
- ```typescript
90
- const placeOrder = new Tool({
91
- name: 'placeOrder',
92
- description: 'Place a product order',
93
- schema: z.object({ itemId: z.string(), quantity: z.number().int().min(1) }),
94
- validate: async (input) => {
95
- const inStock = await checkInventory(input.itemId);
96
- if (inStock < input.quantity) throw new Error(`Only ${inStock} available.`);
97
- },
98
- call: async (input) => ({ orderId: crypto.randomUUID(), ...input }),
99
- });
100
- ```
101
-
102
- ### Control-flow errors
103
-
104
- - `ToolInterrupt(message?)` — stop the prompt loop and return control to the caller. With `toolsComplete` a synthetic `[interrupted]` result is paired so the next round-trip is valid.
105
- - `PromptSuspend(message?)` — suspend without writing a tool result, for human-in-the-loop. See [prompts doc](./aeye-core-prompts.md#suspend--resume-human-in-the-loop). Never auto-paired.
106
-
107
- ```typescript
108
- import { PromptSuspend } from '@aeye/core';
109
-
110
- call: async (input, _refs, ctx) => {
111
- if (await needsApproval(input)) throw new PromptSuspend('awaiting approval');
112
- return performAction(input);
113
- }
114
- ```
115
-
116
- Also exported: `AnyTool`, `ToolCompatible<TContext, TMetadata>`.
117
-
118
- ## Agent
119
-
120
- ```typescript
121
- class Agent<TContext = {}, TMetadata = {}, TName extends string = string,
122
- TInput extends object = {}, TOutput = string,
123
- TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = []>
124
- implements Component<...>
125
- ```
126
-
127
- An Agent is just typed orchestration — its `call` receives the resolved `refs` tuple positionally and wires components together however you like.
128
-
129
- ### `AgentInput`
130
-
131
- | Field | Type | Notes |
132
- |------|------|-------|
133
- | `name` | `TName` | Identifier. |
134
- | `description` | `string` | Informational. |
135
- | `refs` | `TRefs` | **Required.** Components this agent uses. |
136
- | `call` | `(input: TInput, refs: TRefs, ctx) => TOutput` | **Required.** Orchestration logic. |
137
- | `applicable?` | `(ctx) => boolean \| Promise<boolean>` | Defaults to "any ref is applicable" (or `true` when no refs). |
138
- | `metadata?` / `metadataFn?` | `TMetadata` / fn | Execution metadata. |
139
-
140
- ### Methods
141
-
142
- ```typescript
143
- run(input?: TInput, ctx?: Context): TOutput
144
- applicable(ctx?): Promise<boolean>
145
- metadata(input?, ctx?): TMetadata | Promise<TMetadata>
146
- ```
147
-
148
- ### Example
149
-
150
- ```typescript
151
- import { Agent } from '@aeye/core';
152
-
153
- const researchAgent = new Agent({
154
- name: 'researcher',
155
- description: 'Researches a topic',
156
- refs: [searchTool, summarizePrompt, analyzePrompt] as const,
157
- call: async (input: { topic: string }, [search, summarize, analyze], ctx) => {
158
- const results = await search.run({ query: input.topic, limit: 5 }, ctx);
159
- const summaries: string[] = [];
160
- for (const r of results.items) {
161
- const s = await summarize.get('result', { text: r.content }, ctx);
162
- summaries.push(s?.summary ?? '');
163
- }
164
- return await analyze.get('result', { topic: input.topic, sources: summaries }, ctx);
165
- },
166
- });
167
-
168
- const out = await researchAgent.run({ topic: 'Quantum Computing' }, { execute, messages: [] });
169
- ```
170
-
171
- ## Gotchas
172
-
173
- - Pass `refs` `as const` to keep the tuple's element types (so destructuring is correctly typed).
174
- - An Agent does **no** AI on its own — any model calls come from the prompts/tools it invokes, which need `execute`/`stream` on the forwarded `ctx`.
175
- - Tool `schema` returning `undefined` (or `applicable` false) excludes the tool from `compile()` output, so the model never sees it for that context.
176
- - `call` can be sync or async; `TOutput` flows through `Resolved<>` where the framework awaits it (e.g. tool results in prompt events).
177
- - A tool's return value is what the model sees by default (strings verbatim, otherwise `JSON.stringify`-d). To transform per-prompt what a tool result looks like to the model without changing the tool, use the prompt's [`onToolResult`](./aeye-core-prompts.md#tool-result-transformer) transformer (model-facing only; the raw result stays on `get('tools')`/`streamTools`).
1
+ # @aeye/core — Tool & Agent
2
+
3
+ Both are `Component`s. A **Tool** is a single callable function exposed to the model (or invoked directly). An **Agent** is plain orchestration code that composes other components — no LLM loop of its own.
4
+
5
+ ## Tool
6
+
7
+ ```typescript
8
+ class Tool<TContext = {}, TMetadata = {}, TName extends string = string,
9
+ TParams extends object = {}, TOutput = string,
10
+ TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = [],
11
+ TDecoded extends unknown = TParams>
12
+ implements Component<...>
13
+ ```
14
+
15
+ `TDecoded` is the decoded type a custom `parse` produces from the raw wire args — **any** value (a built class instance, a number, a `Date`, …), not just an object; it types `call`, `validate`, and `metadataFn`. It defaults to the wire `TParams` when no custom `parse` is supplied — `schema` always stays the wire type.
16
+
17
+ ### `ToolInput` (constructor config)
18
+
19
+ | Field | Type | Notes |
20
+ |------|------|-------|
21
+ | `name` | `TName` | Shown to the model; unique per request. |
22
+ | `description` | `string` | Shown to the model. |
23
+ | `descriptionFn?` | `Fn<string, [ctx]>` | Refine description from context. |
24
+ | `instructions?` | `string` | Handlebars usage instructions. Optional: a tool without them is still offered (from its description and schema) and adds nothing to the prompt's tools section. |
25
+ | `instructionsFn?` | `Fn<string, [ctx]>` | Context-derived instructions. |
26
+ | `input?` | `Fn<Record<string,any>, [ctx]>` | Variables for the instructions template. |
27
+ | `schema` | `Fn<ZodType<TParams> \| undefined, [ctx]>` | **Required.** Param schema; may depend on ctx. `undefined` ⇒ unavailable. |
28
+ | `strict?` | `boolean \| number` | Strict-mode policy, default `1`. See [schema doc](./aeye-core-schema.md). |
29
+ | `refs?` | `TRefs` | Components passed positionally to `call`. |
30
+ | `call` | `(input: TParams, refs: TRefs, ctx) => TOutput` | **Required.** Implementation (sync or async). |
31
+ | `validate?` | `(input, ctx) => void \| Promise<void>` | Runs after Zod parse; throw to re-prompt. |
32
+ | `maxArgsLength?` | `number` | Reject raw args string over N chars before `JSON.parse` (guards against providers that corrupt large tool args). |
33
+ | `applicable?` | `(ctx) => boolean \| Promise<boolean>` | Availability check. |
34
+ | `metadata?` / `metadataFn?` | `TMetadata` / fn | Execution metadata. |
35
+
36
+ ### Methods
37
+
38
+ ```typescript
39
+ run(input?: TParams, ctx?: Context): TOutput // call directly
40
+ compile(ctx): Promise<readonly [string, ToolDefinition] | undefined> // build AI tool def
41
+ parse(ctx, args, schema?, descriptor?, onRepairAttempt?): Promise<...> // validate raw JSON args
42
+ applicable(ctx?): Promise<boolean>
43
+ metadata(input?, ctx?): TMetadata | Promise<TMetadata>
44
+ ```
45
+
46
+ `compile` returns `undefined` when the tool isn't applicable / has no schema for the context. `parse` validates the model's JSON `arguments` string against the (descriptor-strictified) schema and runs `validate`; it tolerates one provider misbehavior — top-level JSON-stringified fields are re-parsed and `onRepairAttempt` fires for telemetry. When a custom `parse` is supplied (it REPLACES Zod validation), core first wire-decodes the args to the conceptual shape with the request's `FormatDescriptor` (`decodeWire` — array-of-pairs→record, null→undefined, numeric-key→tuple, …), so a custom parser is provider-agnostic and never sees a model family's wire quirks.
47
+
48
+ A tool with `format` (free text, optionally grammar-constrained) takes `TEXT_TOOL_SCHEMA` (`{ input: string }`). Providers without free-text tools send it as that one-field function and use `describeTool(definition)` for its description, which appends the grammar for a `{ type: 'grammar' }` format.
49
+
50
+ ### Basic tool
51
+
52
+ ```typescript
53
+ import { Tool } from '@aeye/core';
54
+ import z from 'zod';
55
+
56
+ const getWeather = new Tool({
57
+ name: 'getWeather',
58
+ description: 'Get current weather for a location',
59
+ instructions: 'Use this to look up weather for {{location}}.',
60
+ schema: z.object({
61
+ location: z.string().describe('City name'),
62
+ units: z.enum(['celsius', 'fahrenheit']).default('celsius'),
63
+ }),
64
+ call: async (input, _refs, _ctx) => {
65
+ const data = await fetchWeather(input.location, input.units);
66
+ return { temperature: data.temp, condition: data.condition };
67
+ },
68
+ });
69
+
70
+ // Direct invocation (no model needed):
71
+ const w = await getWeather.run({ location: 'Paris' }, {});
72
+ ```
73
+
74
+ ### Context-aware schema & applicability
75
+
76
+ ```typescript
77
+ const manageData = new Tool({
78
+ name: 'manageData',
79
+ description: 'Manage data records',
80
+ schema: (ctx: Context<MyCtx, {}>) =>
81
+ ctx.userRole === 'admin'
82
+ ? z.object({ action: z.enum(['read', 'write', 'delete']) })
83
+ : z.object({ action: z.enum(['read']) }),
84
+ applicable: (ctx) => ctx.isAuthenticated,
85
+ call: async (input, _refs, ctx) => ({ action: input.action, by: ctx.userRole }),
86
+ });
87
+ ```
88
+
89
+ ### Business-logic validation
90
+
91
+ ```typescript
92
+ const placeOrder = new Tool({
93
+ name: 'placeOrder',
94
+ description: 'Place a product order',
95
+ schema: z.object({ itemId: z.string(), quantity: z.number().int().min(1) }),
96
+ validate: async (input) => {
97
+ const inStock = await checkInventory(input.itemId);
98
+ if (inStock < input.quantity) throw new Error(`Only ${inStock} available.`);
99
+ },
100
+ call: async (input) => ({ orderId: crypto.randomUUID(), ...input }),
101
+ });
102
+ ```
103
+
104
+ ### Control-flow errors
105
+
106
+ - `ToolInterrupt(message?)` — stop the prompt loop and return control to the caller. With `toolsComplete` a synthetic `[interrupted]` result is paired so the next round-trip is valid.
107
+ - `PromptSuspend(message?)` — suspend without writing a tool result, for human-in-the-loop. See [prompts doc](./aeye-core-prompts.md#suspend--resume-human-in-the-loop). Never auto-paired.
108
+
109
+ ```typescript
110
+ import { PromptSuspend } from '@aeye/core';
111
+
112
+ call: async (input, _refs, ctx) => {
113
+ if (await needsApproval(input)) throw new PromptSuspend('awaiting approval');
114
+ return performAction(input);
115
+ }
116
+ ```
117
+
118
+ Also exported: `AnyTool`, `ToolCompatible<TContext, TMetadata>`.
119
+
120
+ ## Agent
121
+
122
+ ```typescript
123
+ class Agent<TContext = {}, TMetadata = {}, TName extends string = string,
124
+ TInput extends object = {}, TOutput = string,
125
+ TRefs extends Tuple<ComponentCompatible<TContext, TMetadata>> = []>
126
+ implements Component<...>
127
+ ```
128
+
129
+ An Agent is just typed orchestration — its `call` receives the resolved `refs` tuple positionally and wires components together however you like.
130
+
131
+ ### `AgentInput`
132
+
133
+ | Field | Type | Notes |
134
+ |------|------|-------|
135
+ | `name` | `TName` | Identifier. |
136
+ | `description` | `string` | Informational. |
137
+ | `refs` | `TRefs` | **Required.** Components this agent uses. |
138
+ | `call` | `(input: TInput, refs: TRefs, ctx) => TOutput` | **Required.** Orchestration logic. |
139
+ | `applicable?` | `(ctx) => boolean \| Promise<boolean>` | Defaults to "any ref is applicable" (or `true` when no refs). |
140
+ | `metadata?` / `metadataFn?` | `TMetadata` / fn | Execution metadata. |
141
+
142
+ ### Methods
143
+
144
+ ```typescript
145
+ run(input?: TInput, ctx?: Context): TOutput
146
+ applicable(ctx?): Promise<boolean>
147
+ metadata(input?, ctx?): TMetadata | Promise<TMetadata>
148
+ ```
149
+
150
+ ### Example
151
+
152
+ ```typescript
153
+ import { Agent } from '@aeye/core';
154
+
155
+ const researchAgent = new Agent({
156
+ name: 'researcher',
157
+ description: 'Researches a topic',
158
+ refs: [searchTool, summarizePrompt, analyzePrompt] as const,
159
+ call: async (input: { topic: string }, [search, summarize, analyze], ctx) => {
160
+ const results = await search.run({ query: input.topic, limit: 5 }, ctx);
161
+ const summaries: string[] = [];
162
+ for (const r of results.items) {
163
+ const s = await summarize.get('result', { text: r.content }, ctx);
164
+ summaries.push(s?.summary ?? '');
165
+ }
166
+ return await analyze.get('result', { topic: input.topic, sources: summaries }, ctx);
167
+ },
168
+ });
169
+
170
+ const out = await researchAgent.run({ topic: 'Quantum Computing' }, { execute, messages: [] });
171
+ ```
172
+
173
+ ## Gotchas
174
+
175
+ - Pass `refs` `as const` to keep the tuple's element types (so destructuring is correctly typed).
176
+ - An Agent does **no** AI on its own — any model calls come from the prompts/tools it invokes, which need `execute`/`stream` on the forwarded `ctx`.
177
+ - Tool `schema` returning `undefined` (or `applicable` false) excludes the tool from `compile()` output, so the model never sees it for that context.
178
+ - `call` can be sync or async; `TOutput` flows through `Resolved<>` where the framework awaits it (e.g. tool results in prompt events).
179
+ - A tool's return value is what the model sees by default (strings verbatim, otherwise `JSON.stringify`-d). To transform per-prompt what a tool result looks like to the model without changing the tool, use the prompt's [`onToolResult`](./aeye-core-prompts.md#tool-result-transformer) transformer (model-facing only; the raw result stays on `get('tools')`/`streamTools`).
@@ -38,6 +38,7 @@ type Context<TContext, TMetadata> = TContext & {
38
38
  contextWindow?: number; // override window size for trimming
39
39
  outputRetries?: number; // default 2
40
40
  forgetRetries?: number; // context-trim retries, default 1
41
+ userTurn?: string; // user message a prompt adds with no conversation; default DEFAULT_USER_TURN ('Begin.')
41
42
  toolRetries?: number; // default 2
42
43
  instance?: Instance<any>; // current execution instance
43
44
  runner?: Runner; // override how components execute (see withEvents)
package/dist/common.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Chunk, Events, Model, ModelInput, Reasoning, Response, Runner, Usage } from "./types";
1
+ import { Chunk, Events, GeneratedAudio, Model, ModelInput, Reasoning, Response, Runner, Usage } from "./types";
2
2
  /**
3
3
  * A flexible function type that can be:
4
4
  * - A direct value of type R
@@ -145,6 +145,14 @@ export declare function getModel(input: ModelInput | undefined): Model | undefin
145
145
  * @returns The aggregated Response object.
146
146
  */
147
147
  export declare function getResponseFromChunks(chunks: Chunk[], model?: ModelInput): Response;
148
+ /**
149
+ * Appends a partial audio chunk onto accumulated audio.
150
+ *
151
+ * @param target - The audio accumulated so far.
152
+ * @param add - The partial audio to append.
153
+ * @returns The combined audio.
154
+ */
155
+ export declare function accumulateAudio(target: GeneratedAudio | undefined, add: GeneratedAudio): GeneratedAudio;
148
156
  /**
149
157
  * Generates a plain text representation of reasoning data.
150
158
  *
@@ -153,13 +161,30 @@ export declare function getResponseFromChunks(chunks: Chunk[], model?: ModelInpu
153
161
  */
154
162
  export declare function getReasoningText(reasoning: Reasoning | undefined): string;
155
163
  /**
156
- * Accumulates reasoning data by merging an additional Reasoning object into a target Reasoning object.
164
+ * Accumulates streamed reasoning: the reasoning so far with the next part
165
+ * appended, as a new object that shares nothing mutable with either input.
166
+ *
167
+ * Providers stream reasoning as deltas, never repeating what was sent, so
168
+ * `content` and each detail's `text`, `summary` and `data` concatenate. A
169
+ * detail continues an earlier one of the same type with the same id (when
170
+ * both have one) or index: OpenRouter sends a block's text and later its
171
+ * signature at one index, and Gemini's text and encrypted reasoning share
172
+ * index 0 under different types. The provider is whichever part names it.
157
173
  *
158
- * @param target - The target Reasoning object to accumulate into.
159
- * @param add - The Reasoning object to add from.
160
- * @returns - The updated Reasoning object.
174
+ * @param target - The reasoning accumulated so far.
175
+ * @param add - The reasoning to append.
176
+ * @returns - The accumulated reasoning.
161
177
  */
162
178
  export declare function accumulateReasoning(target: Reasoning | undefined, add?: Reasoning): Reasoning | undefined;
179
+ /**
180
+ * Whether reasoning goes back to a provider: it came from there, or names no
181
+ * provider. Signed and encrypted reasoning only verifies where it was made.
182
+ *
183
+ * @param reasoning - The reasoning of an earlier assistant turn.
184
+ * @param provider - The provider the conversation goes to.
185
+ * @returns - Whether to replay the reasoning.
186
+ */
187
+ export declare function replaysTo(reasoning: Reasoning | undefined, provider: string): reasoning is Reasoning;
163
188
  /**
164
189
  * Converts a Response object into an array of Chunk objects.
165
190
  *
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}