@naylence/agent-sdk 0.3.11 → 0.3.13

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 +30 -0
  2. package/dist/browser/index.js +3268 -1913
  3. package/dist/browser/index.js.map +1 -1
  4. package/dist/cjs/index.d.ts +1 -0
  5. package/dist/cjs/index.js +27 -2
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/cjs/naylence/agent/agent-proxy.js.map +1 -1
  8. package/dist/cjs/naylence/agent/agent.js.map +1 -1
  9. package/dist/cjs/naylence/agent/background-task-agent.js.map +1 -1
  10. package/dist/cjs/naylence/agent/base-agent.js.map +1 -1
  11. package/dist/cjs/naylence/agent/configs.d.ts +12 -0
  12. package/dist/cjs/naylence/agent/configs.js +12 -0
  13. package/dist/cjs/naylence/agent/configs.js.map +1 -1
  14. package/dist/cjs/public-api.d.ts +7 -0
  15. package/dist/cjs/public-api.js +26 -0
  16. package/dist/cjs/public-api.js.map +1 -0
  17. package/dist/cjs/version.d.ts +1 -1
  18. package/dist/cjs/version.js +1 -1
  19. package/dist/esm/index.d.ts +1 -0
  20. package/dist/esm/index.js +31 -2
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/naylence/agent/agent-proxy.d.ts +148 -0
  23. package/dist/esm/naylence/agent/agent-proxy.js +130 -0
  24. package/dist/esm/naylence/agent/agent-proxy.js.map +1 -1
  25. package/dist/esm/naylence/agent/agent.d.ts +194 -2
  26. package/dist/esm/naylence/agent/agent.js +123 -0
  27. package/dist/esm/naylence/agent/agent.js.map +1 -1
  28. package/dist/esm/naylence/agent/background-task-agent.d.ts +164 -0
  29. package/dist/esm/naylence/agent/background-task-agent.js +150 -0
  30. package/dist/esm/naylence/agent/background-task-agent.js.map +1 -1
  31. package/dist/esm/naylence/agent/base-agent.d.ts +171 -0
  32. package/dist/esm/naylence/agent/base-agent.js +170 -1
  33. package/dist/esm/naylence/agent/base-agent.js.map +1 -1
  34. package/dist/esm/naylence/agent/configs.d.ts +12 -0
  35. package/dist/esm/naylence/agent/configs.js +12 -0
  36. package/dist/esm/naylence/agent/configs.js.map +1 -1
  37. package/dist/esm/public-api.d.ts +15 -0
  38. package/dist/esm/public-api.js +16 -0
  39. package/dist/esm/public-api.js.map +1 -0
  40. package/dist/esm/version.d.ts +1 -1
  41. package/dist/esm/version.js +2 -2
  42. package/dist/types/index.d.ts +1 -0
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/naylence/agent/agent-proxy.d.ts +148 -0
  45. package/dist/types/naylence/agent/agent-proxy.d.ts.map +1 -1
  46. package/dist/types/naylence/agent/agent.d.ts +194 -2
  47. package/dist/types/naylence/agent/agent.d.ts.map +1 -1
  48. package/dist/types/naylence/agent/background-task-agent.d.ts +164 -0
  49. package/dist/types/naylence/agent/background-task-agent.d.ts.map +1 -1
  50. package/dist/types/naylence/agent/base-agent.d.ts +171 -0
  51. package/dist/types/naylence/agent/base-agent.d.ts.map +1 -1
  52. package/dist/types/naylence/agent/configs.d.ts +12 -0
  53. package/dist/types/naylence/agent/configs.d.ts.map +1 -1
  54. package/dist/types/public-api.d.ts +16 -0
  55. package/dist/types/public-api.d.ts.map +1 -0
  56. package/dist/types/version.d.ts +1 -1
  57. package/package.json +7 -2
@@ -1,3 +1,15 @@
1
+ /**
2
+ * Base class for implementing agents.
3
+ *
4
+ * {@link BaseAgent} provides the standard implementation of the {@link Agent} protocol
5
+ * with built-in support for state management, message handling, and task execution.
6
+ *
7
+ * @remarks
8
+ * Extend this class for request-response style agents. For long-running background
9
+ * work, consider extending {@link BackgroundTaskAgent} instead.
10
+ *
11
+ * @module
12
+ */
1
13
  import { type FameDeliveryContext, type FameEnvelope, type FameMessageResponse } from '@naylence/core';
2
14
  import { FameAddress, FameFabric, NodeLike, Registerable, type StorageProvider } from '@naylence/runtime';
3
15
  import { z } from 'zod';
@@ -5,6 +17,7 @@ import { Agent, type Payload } from './agent.js';
5
17
  import { type AgentCard, Task, type TaskArtifactUpdateEvent, TaskIdParams, TaskPushNotificationConfig, TaskQueryParams, TaskSendParams, TaskStatusUpdateEvent } from './a2a-types.js';
6
18
  import { TERMINAL_TASK_STATES } from './task-states.js';
7
19
  export { TERMINAL_TASK_STATES };
20
+ /** @internal */
8
21
  declare class StateContext<StateT extends BaseAgentState> {
9
22
  private readonly acquireLock;
10
23
  private readonly loadState;
@@ -133,16 +146,73 @@ export declare class BaseAgentState {
133
146
  */
134
147
  clone(): this;
135
148
  }
149
+ /** @internal */
136
150
  type StateModelCtor<T extends BaseAgentState> = new () => T;
151
+ /**
152
+ * Configuration options for {@link BaseAgent}.
153
+ */
137
154
  export interface BaseAgentOptions<StateT extends BaseAgentState> {
155
+ /** State model class for typed state management. */
138
156
  stateModel?: StateModelCtor<StateT> | null;
157
+ /** Namespace for state storage. Defaults to agent name. */
139
158
  stateNamespace?: string | null;
159
+ /** Key under which state is stored. Defaults to 'state'. */
140
160
  stateKey?: string;
161
+ /** Factory function to create initial state. */
141
162
  stateFactory?: (() => StateT) | null;
163
+ /** Custom storage provider for state persistence. */
142
164
  storageProvider?: StorageProvider | null;
143
165
  }
166
+ /**
167
+ * Standard implementation of the {@link Agent} protocol.
168
+ *
169
+ * Provides built-in state management, message handling, and task lifecycle support.
170
+ * Extend this class and override {@link BaseAgent.runTask} to implement your agent logic.
171
+ *
172
+ * @remarks
173
+ * BaseAgent handles:
174
+ * - JSON-RPC message routing
175
+ * - State persistence with optional Zod validation
176
+ * - Task creation from runTask results
177
+ * - Graceful shutdown via SIGINT/SIGTERM
178
+ *
179
+ * For background/async task execution, use {@link BackgroundTaskAgent} instead.
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * import { BaseAgent, Payload, BaseAgentState } from '@naylence/agent-sdk';
184
+ * import { z } from 'zod';
185
+ *
186
+ * const CounterSchema = z.object({ count: z.number() });
187
+ *
188
+ * class CounterState extends BaseAgentState {
189
+ * static readonly schema = CounterSchema;
190
+ * count = 0;
191
+ * }
192
+ *
193
+ * class CounterAgent extends BaseAgent<CounterState> {
194
+ * static STATE_MODEL = CounterState;
195
+ *
196
+ * async runTask(payload: Payload): Promise<number> {
197
+ * return await this.withState(async (state) => {
198
+ * state.count += 1;
199
+ * return state.count;
200
+ * });
201
+ * }
202
+ * }
203
+ *
204
+ * const agent = new CounterAgent('counter');
205
+ * await agent.serve('fame://counter');
206
+ * ```
207
+ *
208
+ * @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
209
+ */
144
210
  export declare class BaseAgent<StateT extends BaseAgentState = BaseAgentState> extends Agent implements Registerable {
145
211
  #private;
212
+ /**
213
+ * Default state model class. Override in subclasses to set state type.
214
+ * @internal
215
+ */
146
216
  static STATE_MODEL: StateModelCtor<BaseAgentState> | null;
147
217
  private _name;
148
218
  private _address;
@@ -158,12 +228,29 @@ export declare class BaseAgent<StateT extends BaseAgentState = BaseAgentState> e
158
228
  private _fabric;
159
229
  private _stateStore;
160
230
  private _stateCache;
231
+ /**
232
+ * Creates a new BaseAgent.
233
+ *
234
+ * @param name - Agent name. Defaults to snake_case of the class name.
235
+ * @param options - Configuration options for state and storage.
236
+ */
161
237
  constructor(name?: string | null, options?: BaseAgentOptions<StateT>);
238
+ /**
239
+ * Capabilities advertised by this agent.
240
+ * Includes the standard agent capability by default.
241
+ */
162
242
  get capabilities(): string[];
243
+ /** The agent's name. */
163
244
  get name(): string | null;
164
245
  get spec(): Record<string, unknown>;
246
+ /** The address this agent is registered at. */
165
247
  get address(): FameAddress | null;
248
+ /** @internal */
166
249
  set address(value: FameAddress | null);
250
+ /**
251
+ * Storage provider for state persistence.
252
+ * @throws Error if no storage provider is available.
253
+ */
167
254
  get storageProvider(): StorageProvider;
168
255
  /**
169
256
  * Returns the fabric this agent is registered with.
@@ -172,21 +259,74 @@ export declare class BaseAgent<StateT extends BaseAgentState = BaseAgentState> e
172
259
  */
173
260
  protected get fabric(): FameFabric | null;
174
261
  onRegister?(node: NodeLike): Promise<void>;
262
+ /** @internal */
175
263
  protected acquireStateLock(): Promise<() => void>;
264
+ /** @internal */
176
265
  private ensureStateModel;
266
+ /** @internal */
177
267
  private ensureStateStore;
268
+ /** @internal */
178
269
  private defaultStateNamespace;
270
+ /** @internal */
179
271
  protected loadStateInternal(): Promise<StateT>;
272
+ /** @internal */
180
273
  protected saveStateInternal(state: StateT): Promise<void>;
274
+ /**
275
+ * State context for lock-protected state access.
276
+ *
277
+ * @remarks
278
+ * Prefer using {@link BaseAgent.withState} for simpler access patterns.
279
+ *
280
+ * @throws Error if no state model is configured.
281
+ */
181
282
  get state(): StateContext<StateT>;
283
+ /**
284
+ * Executes a callback with exclusive access to the agent's state.
285
+ *
286
+ * State changes are automatically persisted after the callback completes.
287
+ *
288
+ * @param callback - Function receiving the current state.
289
+ * @returns The callback's return value.
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * const count = await this.withState(async (state) => {
294
+ * state.count += 1;
295
+ * return state.count;
296
+ * });
297
+ * ```
298
+ */
182
299
  withState<T>(callback: (state: StateT) => Promise<T>): Promise<T>;
300
+ /**
301
+ * Retrieves a snapshot of the current state.
302
+ *
303
+ * @remarks
304
+ * Returns a point-in-time copy. For modifications, use {@link BaseAgent.withState}.
305
+ */
183
306
  getState(): Promise<StateT>;
307
+ /**
308
+ * Deletes all persisted state for this agent.
309
+ */
184
310
  clearState(): Promise<void>;
311
+ /** @internal */
185
312
  private static isRpcRequest;
313
+ /** @internal */
186
314
  handleMessage(envelope: FameEnvelope, _context?: FameDeliveryContext): Promise<FameMessageResponse | AsyncIterable<FameMessageResponse> | null | void>;
315
+ /**
316
+ * Override to handle non-RPC messages.
317
+ *
318
+ * Called when the agent receives a message that is not a JSON-RPC request.
319
+ * The default implementation logs a warning and returns null.
320
+ *
321
+ * @param message - The decoded message payload.
322
+ * @returns Optional response to send back.
323
+ */
187
324
  onMessage(message: unknown): Promise<FameMessageResponse | null | void>;
325
+ /** @internal */
188
326
  private handleRpcMessage;
327
+ /** @internal */
189
328
  private startSubscriptionTask;
329
+ /** @internal */
190
330
  private streamSendSubscribe;
191
331
  authenticate(_credentials: unknown): boolean;
192
332
  registerPushEndpoint(_config: TaskPushNotificationConfig): Promise<TaskPushNotificationConfig>;
@@ -196,7 +336,38 @@ export declare class BaseAgent<StateT extends BaseAgentState = BaseAgentState> e
196
336
  cancelTask(_params: TaskIdParams): Promise<Task>;
197
337
  getAgentCard(): Promise<AgentCard>;
198
338
  getTaskStatus(_params: TaskQueryParams): Promise<Task>;
339
+ /**
340
+ * Override to implement task execution logic.
341
+ *
342
+ * This is the primary extension point for agent behavior. Return the task result
343
+ * or throw an error to fail the task.
344
+ *
345
+ * @param _payload - The task payload.
346
+ * @param _id - Optional task identifier.
347
+ * @returns The task result.
348
+ * @throws UnsupportedOperationException if not overridden.
349
+ *
350
+ * @example
351
+ * ```typescript
352
+ * async runTask(payload: Payload): Promise<string> {
353
+ * const input = typeof payload === 'string' ? payload : '';
354
+ * return `Hello, ${input}!`;
355
+ * }
356
+ * ```
357
+ */
199
358
  runTask(_payload: Payload, _id: string | null): Promise<unknown>;
359
+ /**
360
+ * Initiates a task and returns its status.
361
+ *
362
+ * @remarks
363
+ * If you override {@link BaseAgent.runTask}, this method automatically
364
+ * creates a Task from the result. Override this method for custom
365
+ * task lifecycle management.
366
+ *
367
+ * @param params - Task parameters including message and metadata.
368
+ * @returns The completed task with result.
369
+ * @throws Error if neither startTask nor runTask is implemented.
370
+ */
200
371
  startTask(params: TaskSendParams): Promise<Task>;
201
372
  aserve(address: FameAddress | string, options?: Parameters<Agent['aserve']>[1]): Promise<void>;
202
373
  }
@@ -4,6 +4,18 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _BaseAgent_instances, _BaseAgent_createTaskFromPayloadResponse;
7
+ /**
8
+ * Base class for implementing agents.
9
+ *
10
+ * {@link BaseAgent} provides the standard implementation of the {@link Agent} protocol
11
+ * with built-in support for state management, message handling, and task execution.
12
+ *
13
+ * @remarks
14
+ * Extend this class for request-response style agents. For long-running background
15
+ * work, consider extending {@link BackgroundTaskAgent} instead.
16
+ *
17
+ * @module
18
+ */
7
19
  import { AGENT_CAPABILITY, createFameEnvelope, createMessageResponse, } from '@naylence/core';
8
20
  import { AsyncLock, FameAddress, FameFabric, generateId, getFabricForNode, getLogger, } from '@naylence/runtime';
9
21
  import { z } from 'zod';
@@ -15,6 +27,7 @@ import { decodeFameDataPayload, makeTask } from './util.js';
15
27
  import { handleAgentRpcRequest } from './rpc-adapter.js';
16
28
  const logger = getLogger('naylence.agent.base_agent');
17
29
  export { TERMINAL_TASK_STATES };
30
+ /** @internal */
18
31
  class StateContext {
19
32
  constructor(acquireLock, loadState, saveState) {
20
33
  this.acquireLock = acquireLock;
@@ -246,17 +259,20 @@ export class BaseAgentState {
246
259
  * ```
247
260
  */
248
261
  BaseAgentState.schema = z.object({});
262
+ /** @internal */
249
263
  function camelToSnakeCase(name) {
250
264
  return name
251
265
  .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
252
266
  .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
253
267
  .toLowerCase();
254
268
  }
269
+ /** @internal */
255
270
  function sanitizeNamespace(ns) {
256
271
  const replaced = ns.replace(/[^A-Za-z0-9._-]+/g, '_').replace(/^[._-]+|[._-]+$/g, '');
257
272
  const safe = replaced.length > 0 ? replaced : 'ns';
258
273
  return safe.slice(0, 120);
259
274
  }
275
+ /** @internal */
260
276
  async function delay(ms) {
261
277
  await new Promise((resolve) => {
262
278
  const timeout = globalThis.setTimeout;
@@ -266,19 +282,71 @@ async function delay(ms) {
266
282
  timeout(resolve, ms);
267
283
  });
268
284
  }
285
+ /** @internal */
269
286
  function resolveRpcParams(params) {
270
287
  if (params && typeof params === 'object') {
271
288
  return params;
272
289
  }
273
290
  return {};
274
291
  }
292
+ /** @internal */
275
293
  function resolveReplyTarget(explicit, params) {
276
294
  const fromParams = params['reply_to'] ??
277
295
  params['replyTo'];
278
296
  const resolved = explicit ?? fromParams ?? null;
279
297
  return resolved === undefined ? null : resolved;
280
298
  }
299
+ /**
300
+ * Standard implementation of the {@link Agent} protocol.
301
+ *
302
+ * Provides built-in state management, message handling, and task lifecycle support.
303
+ * Extend this class and override {@link BaseAgent.runTask} to implement your agent logic.
304
+ *
305
+ * @remarks
306
+ * BaseAgent handles:
307
+ * - JSON-RPC message routing
308
+ * - State persistence with optional Zod validation
309
+ * - Task creation from runTask results
310
+ * - Graceful shutdown via SIGINT/SIGTERM
311
+ *
312
+ * For background/async task execution, use {@link BackgroundTaskAgent} instead.
313
+ *
314
+ * @example
315
+ * ```typescript
316
+ * import { BaseAgent, Payload, BaseAgentState } from '@naylence/agent-sdk';
317
+ * import { z } from 'zod';
318
+ *
319
+ * const CounterSchema = z.object({ count: z.number() });
320
+ *
321
+ * class CounterState extends BaseAgentState {
322
+ * static readonly schema = CounterSchema;
323
+ * count = 0;
324
+ * }
325
+ *
326
+ * class CounterAgent extends BaseAgent<CounterState> {
327
+ * static STATE_MODEL = CounterState;
328
+ *
329
+ * async runTask(payload: Payload): Promise<number> {
330
+ * return await this.withState(async (state) => {
331
+ * state.count += 1;
332
+ * return state.count;
333
+ * });
334
+ * }
335
+ * }
336
+ *
337
+ * const agent = new CounterAgent('counter');
338
+ * await agent.serve('fame://counter');
339
+ * ```
340
+ *
341
+ * @typeParam StateT - The state model type, defaults to {@link BaseAgentState}.
342
+ */
281
343
  export class BaseAgent extends Agent {
344
+ /**
345
+ * Creates a new BaseAgent.
346
+ *
347
+ * @param name - Agent name. Defaults to snake_case of the class name.
348
+ * @param options - Configuration options for state and storage.
349
+ */
282
350
  constructor(name = null, options = {}) {
283
351
  super();
284
352
  _BaseAgent_instances.add(this);
@@ -299,9 +367,14 @@ export class BaseAgent extends Agent {
299
367
  this._stateKey = options.stateKey ?? 'state';
300
368
  this._stateFactory = options.stateFactory ?? null;
301
369
  }
370
+ /**
371
+ * Capabilities advertised by this agent.
372
+ * Includes the standard agent capability by default.
373
+ */
302
374
  get capabilities() {
303
375
  return [...this._capabilities];
304
376
  }
377
+ /** The agent's name. */
305
378
  get name() {
306
379
  return this._name;
307
380
  }
@@ -310,12 +383,18 @@ export class BaseAgent extends Agent {
310
383
  address: this._address?.toString() ?? null,
311
384
  };
312
385
  }
386
+ /** The address this agent is registered at. */
313
387
  get address() {
314
388
  return this._address;
315
389
  }
390
+ /** @internal */
316
391
  set address(value) {
317
392
  this._address = value;
318
393
  }
394
+ /**
395
+ * Storage provider for state persistence.
396
+ * @throws Error if no storage provider is available.
397
+ */
319
398
  get storageProvider() {
320
399
  if (!this._storageProvider) {
321
400
  if (this._node) {
@@ -340,6 +419,7 @@ export class BaseAgent extends Agent {
340
419
  // Look up the fabric from the registry (set by InProcessFameFabric.start())
341
420
  this._fabric = getFabricForNode(node) ?? null;
342
421
  }
422
+ /** @internal */
343
423
  async acquireStateLock() {
344
424
  let acquiredResolve;
345
425
  const acquired = new Promise((resolve) => {
@@ -366,12 +446,14 @@ export class BaseAgent extends Agent {
366
446
  });
367
447
  };
368
448
  }
449
+ /** @internal */
369
450
  ensureStateModel() {
370
451
  if (this._stateModel) {
371
452
  return this._stateModel;
372
453
  }
373
454
  throw new Error("No state model configured. Provide via Generic, STATE_MODEL, constructor 'stateModel', or 'stateFactory'.");
374
455
  }
456
+ /** @internal */
375
457
  async ensureStateStore(modelType) {
376
458
  if (this._stateStore) {
377
459
  return;
@@ -384,12 +466,14 @@ export class BaseAgent extends Agent {
384
466
  const namespace = sanitizeNamespace(namespaceRaw);
385
467
  this._stateStore = await provider.getKeyValueStore(modelType, namespace);
386
468
  }
469
+ /** @internal */
387
470
  defaultStateNamespace() {
388
471
  if (!this._name) {
389
472
  throw new Error("Cannot derive default state namespace without agent name. Set 'name' or provide 'stateNamespace'.");
390
473
  }
391
474
  return `__agent_${this._name}`;
392
475
  }
476
+ /** @internal */
393
477
  async loadStateInternal() {
394
478
  if (this._stateCache) {
395
479
  return this._stateCache;
@@ -419,6 +503,7 @@ export class BaseAgent extends Agent {
419
503
  this._stateCache = state;
420
504
  return state;
421
505
  }
506
+ /** @internal */
422
507
  async saveStateInternal(state) {
423
508
  const modelType = this.ensureStateModel();
424
509
  await this.ensureStateStore(modelType);
@@ -430,15 +515,45 @@ export class BaseAgent extends Agent {
430
515
  await this._stateStore.set(this._stateKey, state);
431
516
  this._stateCache = state;
432
517
  }
518
+ /**
519
+ * State context for lock-protected state access.
520
+ *
521
+ * @remarks
522
+ * Prefer using {@link BaseAgent.withState} for simpler access patterns.
523
+ *
524
+ * @throws Error if no state model is configured.
525
+ */
433
526
  get state() {
434
527
  if (!this._stateModel && !this._stateFactory) {
435
528
  throw new Error('No state model configured');
436
529
  }
437
530
  return new StateContext(() => this.acquireStateLock(), () => this.loadStateInternal(), (state) => this.saveStateInternal(state));
438
531
  }
532
+ /**
533
+ * Executes a callback with exclusive access to the agent's state.
534
+ *
535
+ * State changes are automatically persisted after the callback completes.
536
+ *
537
+ * @param callback - Function receiving the current state.
538
+ * @returns The callback's return value.
539
+ *
540
+ * @example
541
+ * ```typescript
542
+ * const count = await this.withState(async (state) => {
543
+ * state.count += 1;
544
+ * return state.count;
545
+ * });
546
+ * ```
547
+ */
439
548
  async withState(callback) {
440
549
  return await this.state.use(callback);
441
550
  }
551
+ /**
552
+ * Retrieves a snapshot of the current state.
553
+ *
554
+ * @remarks
555
+ * Returns a point-in-time copy. For modifications, use {@link BaseAgent.withState}.
556
+ */
442
557
  async getState() {
443
558
  const release = await this.acquireStateLock();
444
559
  try {
@@ -448,6 +563,9 @@ export class BaseAgent extends Agent {
448
563
  release();
449
564
  }
450
565
  }
566
+ /**
567
+ * Deletes all persisted state for this agent.
568
+ */
451
569
  async clearState() {
452
570
  const release = await this.acquireStateLock();
453
571
  try {
@@ -460,6 +578,7 @@ export class BaseAgent extends Agent {
460
578
  release();
461
579
  }
462
580
  }
581
+ /** @internal */
463
582
  static isRpcRequest(payload) {
464
583
  if (!payload || typeof payload !== 'object') {
465
584
  return false;
@@ -474,6 +593,7 @@ export class BaseAgent extends Agent {
474
593
  }
475
594
  return true;
476
595
  }
596
+ /** @internal */
477
597
  async handleMessage(envelope, _context) {
478
598
  void _context;
479
599
  const frame = envelope.frame;
@@ -497,10 +617,20 @@ export class BaseAgent extends Agent {
497
617
  }
498
618
  return await this.handleRpcMessage(decoded, envelope);
499
619
  }
620
+ /**
621
+ * Override to handle non-RPC messages.
622
+ *
623
+ * Called when the agent receives a message that is not a JSON-RPC request.
624
+ * The default implementation logs a warning and returns null.
625
+ *
626
+ * @param message - The decoded message payload.
627
+ * @returns Optional response to send back.
628
+ */
500
629
  async onMessage(message) {
501
630
  logger.warning('unhandled_inbound_message', { message });
502
631
  return null;
503
632
  }
633
+ /** @internal */
504
634
  async handleRpcMessage(rpcRequest, envelope) {
505
635
  if (rpcRequest.method === 'tasks/sendSubscribe') {
506
636
  this.startSubscriptionTask(rpcRequest, envelope.replyTo ?? null);
@@ -537,6 +667,7 @@ export class BaseAgent extends Agent {
537
667
  }.bind(this);
538
668
  return generator();
539
669
  }
670
+ /** @internal */
540
671
  startSubscriptionTask(rpcRequest, replyTo) {
541
672
  const id = rpcRequest.id != null ? String(rpcRequest.id) : null;
542
673
  if (!id) {
@@ -561,6 +692,7 @@ export class BaseAgent extends Agent {
561
692
  });
562
693
  }
563
694
  }
695
+ /** @internal */
564
696
  async streamSendSubscribe(rpcRequest, replyTo, signal) {
565
697
  try {
566
698
  const params = resolveRpcParams(rpcRequest.params);
@@ -652,11 +784,42 @@ export class BaseAgent extends Agent {
652
784
  void _params;
653
785
  throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'getTaskStatus'`);
654
786
  }
787
+ /**
788
+ * Override to implement task execution logic.
789
+ *
790
+ * This is the primary extension point for agent behavior. Return the task result
791
+ * or throw an error to fail the task.
792
+ *
793
+ * @param _payload - The task payload.
794
+ * @param _id - Optional task identifier.
795
+ * @returns The task result.
796
+ * @throws UnsupportedOperationException if not overridden.
797
+ *
798
+ * @example
799
+ * ```typescript
800
+ * async runTask(payload: Payload): Promise<string> {
801
+ * const input = typeof payload === 'string' ? payload : '';
802
+ * return `Hello, ${input}!`;
803
+ * }
804
+ * ```
805
+ */
655
806
  async runTask(_payload, _id) {
656
807
  void _payload;
657
808
  void _id;
658
809
  throw new UnsupportedOperationException(`Agent ${this.constructor.name} does not support operation 'runTask'`);
659
810
  }
811
+ /**
812
+ * Initiates a task and returns its status.
813
+ *
814
+ * @remarks
815
+ * If you override {@link BaseAgent.runTask}, this method automatically
816
+ * creates a Task from the result. Override this method for custom
817
+ * task lifecycle management.
818
+ *
819
+ * @param params - Task parameters including message and metadata.
820
+ * @returns The completed task with result.
821
+ * @throws Error if neither startTask nor runTask is implemented.
822
+ */
660
823
  async startTask(params) {
661
824
  const ctor = this.constructor;
662
825
  const parts = params.message?.parts ?? [];
@@ -684,7 +847,9 @@ export class BaseAgent extends Agent {
684
847
  await super.aserve(address, options);
685
848
  }
686
849
  }
687
- _BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse = async function _BaseAgent_createTaskFromPayloadResponse(params, payload, runner) {
850
+ _BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse =
851
+ /** @internal */
852
+ async function _BaseAgent_createTaskFromPayloadResponse(params, payload, runner) {
688
853
  const responsePayload = await runner(payload, params.id ?? null);
689
854
  let sanitizedPayload = null;
690
855
  if (typeof responsePayload === 'string') {
@@ -700,6 +865,10 @@ _BaseAgent_instances = new WeakSet(), _BaseAgent_createTaskFromPayloadResponse =
700
865
  sessionId: params.sessionId ?? null,
701
866
  });
702
867
  };
868
+ /**
869
+ * Default state model class. Override in subclasses to set state type.
870
+ * @internal
871
+ */
703
872
  BaseAgent.STATE_MODEL = null;
704
873
  registerBaseAgentConstructor(BaseAgent);
705
874
  //# sourceMappingURL=base-agent.js.map