@salesforce/sfdx-agent-sdk 0.40.0 → 0.41.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.
- package/CHANGELOG.md +5 -0
- package/README.md +7 -0
- package/dist/agent-manager.js +10 -2
- package/dist/agent.js +16 -2
- package/dist/chat-session.js +81 -5
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
All notable changes to `@salesforce/sfdx-agent-sdk` are documented in this file.
|
|
4
4
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
5
|
|
|
6
|
+
## [0.41.0] - 2026-08-03
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
- **agent-sdk,harnesses**: emit Tier-1 logBus siblings for lifecycle telemetry @W-23547150@ ([#716](https://github.com/forcedotcom/agentic-dx/pull/716))
|
|
10
|
+
|
|
6
11
|
## [0.40.0] - 2026-08-03
|
|
7
12
|
|
|
8
13
|
### Features
|
package/README.md
CHANGED
|
@@ -1546,6 +1546,13 @@ Abandoning the iterator mid-stream emits no terminal telemetry — the stream di
|
|
|
1546
1546
|
Harness implementations may emit additional structured logs through their own `LogBus`. Those records surface to
|
|
1547
1547
|
consumers via the same `onLog` channel.
|
|
1548
1548
|
|
|
1549
|
+
Selected lifecycle moments are reported on **both** channels: the typed telemetry event, plus a log record carrying the
|
|
1550
|
+
same facts for log sinks. On those records `message` is human-readable prose intended for display and may be reworded;
|
|
1551
|
+
`context.event_type` carries the matching `TelemetryEvent` type and is the stable field to filter, alert, and join on.
|
|
1552
|
+
Records paired this way today are `agent-created`, `agent-destroyed`, `session-created`, `session-destroyed`,
|
|
1553
|
+
`chat-stream-completed`, `chat-stream-error`, `tool-execution-completed` (only when `isError` is true), and the harness
|
|
1554
|
+
MCP events `mcp-server-discovery-completed`, `mcp-server-discovery-failed`, and `mcp-server-status-changed`.
|
|
1555
|
+
|
|
1549
1556
|
## Development
|
|
1550
1557
|
|
|
1551
1558
|
See [DEVELOPING.md](DEVELOPING.md) for build-from-source setup, scripts, E2E testing, and packaging.
|
package/dist/agent-manager.js
CHANGED
|
@@ -189,12 +189,20 @@ export class DefaultAgentManager {
|
|
|
189
189
|
this.wireRouter.registerAgent(agentId);
|
|
190
190
|
const agent = new DefaultAgent(this.harness, agentId, projectRoot, config, runtime.modelConnectivityInfo, runtime.orgConnection, runtime.orgJwt, this.agentConnectivityResolver, this.harnessSupportedProviderHints, this.hooksForAgent, this.identityStore, this.router, agentSlice, { telemetry: this.telemetryBus, log: this.logBus }, this.clock, this.agentIdGenerator);
|
|
191
191
|
this.agents.set(agentId, agent);
|
|
192
|
+
const agentCreatedAt = this.clock.now();
|
|
193
|
+
const modelName = runtime.modelConnectivityInfo.model.name;
|
|
192
194
|
this.telemetryBus.emit({
|
|
193
195
|
type: 'agent-created',
|
|
194
|
-
timestamp:
|
|
196
|
+
timestamp: agentCreatedAt,
|
|
195
197
|
agentId,
|
|
196
198
|
projectRoot,
|
|
197
|
-
modelName
|
|
199
|
+
modelName,
|
|
200
|
+
});
|
|
201
|
+
this.logBus.emit({
|
|
202
|
+
level: 'info',
|
|
203
|
+
message: 'Agent created',
|
|
204
|
+
timestamp: agentCreatedAt,
|
|
205
|
+
context: { event_type: 'agent-created', agentId, projectRoot, modelName },
|
|
198
206
|
});
|
|
199
207
|
if (options.rehydrateThreads) {
|
|
200
208
|
// If thread enumeration or session attachment fails, the restore is a full failure
|
package/dist/agent.js
CHANGED
|
@@ -283,11 +283,18 @@ export class DefaultAgent {
|
|
|
283
283
|
}
|
|
284
284
|
this.sessions.clear();
|
|
285
285
|
await this.harness.destroyAgent(this.agentId);
|
|
286
|
+
const agentDestroyedAt = this.clock.now();
|
|
286
287
|
this.telemetryBus.emit({
|
|
287
288
|
type: 'agent-destroyed',
|
|
288
|
-
timestamp:
|
|
289
|
+
timestamp: agentDestroyedAt,
|
|
289
290
|
agentId: this.agentId,
|
|
290
291
|
});
|
|
292
|
+
this.logBus.emit({
|
|
293
|
+
level: 'info',
|
|
294
|
+
message: 'Agent destroyed',
|
|
295
|
+
timestamp: agentDestroyedAt,
|
|
296
|
+
context: { event_type: 'agent-destroyed', agentId: this.agentId },
|
|
297
|
+
});
|
|
291
298
|
for (const unsub of this.inboundUnsubs)
|
|
292
299
|
unsub();
|
|
293
300
|
for (const unsub of this.parentUnsubs)
|
|
@@ -347,12 +354,19 @@ export class DefaultAgent {
|
|
|
347
354
|
}, getContextWindow, { clock: this.clock, idGenerator: this.idGenerator, persistRememberedRule });
|
|
348
355
|
this.sessions.set(threadId, session);
|
|
349
356
|
this.sessionSliceUnregisters.set(threadId, () => this.router.unregisterSession(threadId));
|
|
357
|
+
const sessionCreatedAt = this.clock.now();
|
|
350
358
|
this.telemetryBus.emit({
|
|
351
359
|
type: 'session-created',
|
|
352
|
-
timestamp:
|
|
360
|
+
timestamp: sessionCreatedAt,
|
|
353
361
|
agentId: this.agentId,
|
|
354
362
|
threadId,
|
|
355
363
|
});
|
|
364
|
+
this.logBus.emit({
|
|
365
|
+
level: 'info',
|
|
366
|
+
message: 'Chat session created',
|
|
367
|
+
timestamp: sessionCreatedAt,
|
|
368
|
+
context: { event_type: 'session-created', agentId: this.agentId, threadId },
|
|
369
|
+
});
|
|
356
370
|
return session;
|
|
357
371
|
}
|
|
358
372
|
detachSession(threadId, session) {
|
package/dist/chat-session.js
CHANGED
|
@@ -237,6 +237,18 @@ export class DefaultChatSession {
|
|
|
237
237
|
durationMs,
|
|
238
238
|
error: lastError,
|
|
239
239
|
});
|
|
240
|
+
this.logBus.emit({
|
|
241
|
+
level: 'error',
|
|
242
|
+
message: 'Chat stream failed',
|
|
243
|
+
timestamp: finishedAt,
|
|
244
|
+
context: {
|
|
245
|
+
event_type: 'chat-stream-error',
|
|
246
|
+
agentId: this.agentId,
|
|
247
|
+
threadId: this.threadId,
|
|
248
|
+
durationMs,
|
|
249
|
+
},
|
|
250
|
+
error: lastError,
|
|
251
|
+
});
|
|
240
252
|
}
|
|
241
253
|
else {
|
|
242
254
|
this.telemetryBus.emit({
|
|
@@ -247,6 +259,18 @@ export class DefaultChatSession {
|
|
|
247
259
|
durationMs,
|
|
248
260
|
usage: finishUsage,
|
|
249
261
|
});
|
|
262
|
+
this.logBus.emit({
|
|
263
|
+
level: 'info',
|
|
264
|
+
message: 'Chat stream completed',
|
|
265
|
+
timestamp: finishedAt,
|
|
266
|
+
context: {
|
|
267
|
+
event_type: 'chat-stream-completed',
|
|
268
|
+
agentId: this.agentId,
|
|
269
|
+
threadId: this.threadId,
|
|
270
|
+
durationMs,
|
|
271
|
+
...(finishUsage !== undefined ? { usage: finishUsage } : {}),
|
|
272
|
+
},
|
|
273
|
+
});
|
|
250
274
|
}
|
|
251
275
|
}
|
|
252
276
|
/**
|
|
@@ -420,12 +444,23 @@ export class DefaultChatSession {
|
|
|
420
444
|
if (this.disposed) {
|
|
421
445
|
return;
|
|
422
446
|
}
|
|
447
|
+
const sessionDestroyedAt = this.clock.now();
|
|
423
448
|
this.telemetryBus.emit({
|
|
424
449
|
type: 'session-destroyed',
|
|
425
|
-
timestamp:
|
|
450
|
+
timestamp: sessionDestroyedAt,
|
|
426
451
|
agentId: this.agentId,
|
|
427
452
|
threadId: this.threadId,
|
|
428
453
|
});
|
|
454
|
+
this.logBus.emit({
|
|
455
|
+
level: 'info',
|
|
456
|
+
message: 'Chat session destroyed',
|
|
457
|
+
timestamp: sessionDestroyedAt,
|
|
458
|
+
context: {
|
|
459
|
+
event_type: 'session-destroyed',
|
|
460
|
+
agentId: this.agentId,
|
|
461
|
+
threadId: this.threadId,
|
|
462
|
+
},
|
|
463
|
+
});
|
|
429
464
|
for (const unsub of this.inboundUnsubs)
|
|
430
465
|
unsub();
|
|
431
466
|
for (const unsub of this.parentUnsubs)
|
|
@@ -436,6 +471,8 @@ export class DefaultChatSession {
|
|
|
436
471
|
this.disposed = true;
|
|
437
472
|
}
|
|
438
473
|
emitToolApprovalResolved(toolCallId, approved, policyWritten) {
|
|
474
|
+
// No Tier-1 logBus sibling: tool-approval-resolved fires per gated
|
|
475
|
+
// tool call — interactive-UI signal, not on-call triage
|
|
439
476
|
this.telemetryBus.emit({
|
|
440
477
|
type: 'tool-approval-resolved',
|
|
441
478
|
timestamp: this.clock.now(),
|
|
@@ -476,6 +513,8 @@ export class DefaultChatSession {
|
|
|
476
513
|
deriveToolTelemetry(event) {
|
|
477
514
|
if (event.type === 'tool-call') {
|
|
478
515
|
this.toolStartMs.set(event.toolCallId, this.clock.now().getTime());
|
|
516
|
+
// No Tier-1 logBus sibling: tool-execution-started pairs 1:1 with
|
|
517
|
+
// tool-execution-completed; the completion (isError=true) is the triage signal
|
|
479
518
|
this.telemetryBus.emit({
|
|
480
519
|
type: 'tool-execution-started',
|
|
481
520
|
timestamp: this.clock.now(),
|
|
@@ -492,19 +531,42 @@ export class DefaultChatSession {
|
|
|
492
531
|
if (start === undefined)
|
|
493
532
|
return;
|
|
494
533
|
this.toolStartMs.delete(event.toolCallId);
|
|
534
|
+
const completedAt = this.clock.now();
|
|
535
|
+
const durationMs = completedAt.getTime() - start;
|
|
536
|
+
const isError = event.isError === true;
|
|
495
537
|
this.telemetryBus.emit({
|
|
496
538
|
type: 'tool-execution-completed',
|
|
497
|
-
timestamp:
|
|
539
|
+
timestamp: completedAt,
|
|
498
540
|
agentId: this.agentId,
|
|
499
541
|
threadId: this.threadId,
|
|
500
542
|
toolCallId: event.toolCallId,
|
|
501
543
|
toolName: event.toolName,
|
|
502
|
-
durationMs
|
|
503
|
-
isError
|
|
544
|
+
durationMs,
|
|
545
|
+
isError,
|
|
504
546
|
...(event.error ? { error: event.error } : {}),
|
|
505
547
|
...(event.annotations ? { annotations: event.annotations } : {}),
|
|
506
548
|
...(event.serverName ? { serverName: event.serverName } : {}),
|
|
507
549
|
});
|
|
550
|
+
// Tier-1 logBus sibling only when isError=true.
|
|
551
|
+
if (isError) {
|
|
552
|
+
this.logBus.emit({
|
|
553
|
+
level: 'error',
|
|
554
|
+
message: 'Tool execution failed',
|
|
555
|
+
timestamp: completedAt,
|
|
556
|
+
context: {
|
|
557
|
+
event_type: 'tool-execution-completed',
|
|
558
|
+
agentId: this.agentId,
|
|
559
|
+
threadId: this.threadId,
|
|
560
|
+
toolCallId: event.toolCallId,
|
|
561
|
+
toolName: event.toolName,
|
|
562
|
+
durationMs,
|
|
563
|
+
isError: true,
|
|
564
|
+
...(event.annotations ? { annotations: event.annotations } : {}),
|
|
565
|
+
...(event.serverName ? { serverName: event.serverName } : {}),
|
|
566
|
+
},
|
|
567
|
+
...(event.error ? { error: event.error } : {}),
|
|
568
|
+
});
|
|
569
|
+
}
|
|
508
570
|
}
|
|
509
571
|
else if (event.type === 'tool-approval-request') {
|
|
510
572
|
// Record the (toolName, serverName?) so a later settle with
|
|
@@ -574,6 +636,7 @@ export class DefaultChatSession {
|
|
|
574
636
|
*/
|
|
575
637
|
emitChatStreamStarted(trigger) {
|
|
576
638
|
const startedAt = this.clock.now();
|
|
639
|
+
// chat-stream-started pairs 1:1 with chat-stream-completed, which already carries outcomes
|
|
577
640
|
this.telemetryBus.emit({
|
|
578
641
|
type: 'chat-stream-started',
|
|
579
642
|
timestamp: startedAt,
|
|
@@ -597,12 +660,25 @@ export class DefaultChatSession {
|
|
|
597
660
|
this.chatEventBus.emit({ type: 'error', error });
|
|
598
661
|
this.chatEventBus.emit({ type: 'finish', finishReason: 'error' });
|
|
599
662
|
const finishedAt = this.clock.now();
|
|
663
|
+
const durationMs = finishedAt.getTime() - startedAt.getTime();
|
|
600
664
|
this.telemetryBus.emit({
|
|
601
665
|
type: 'chat-stream-error',
|
|
602
666
|
timestamp: finishedAt,
|
|
603
667
|
agentId: this.agentId,
|
|
604
668
|
threadId: this.threadId,
|
|
605
|
-
durationMs
|
|
669
|
+
durationMs,
|
|
670
|
+
error,
|
|
671
|
+
});
|
|
672
|
+
this.logBus.emit({
|
|
673
|
+
level: 'error',
|
|
674
|
+
message: 'Chat stream failed',
|
|
675
|
+
timestamp: finishedAt,
|
|
676
|
+
context: {
|
|
677
|
+
event_type: 'chat-stream-error',
|
|
678
|
+
agentId: this.agentId,
|
|
679
|
+
threadId: this.threadId,
|
|
680
|
+
durationMs,
|
|
681
|
+
},
|
|
606
682
|
error,
|
|
607
683
|
});
|
|
608
684
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/js": "^10.0.1",
|
|
50
|
-
"@salesforce/sfdx-agent-harness-claude": "0.
|
|
51
|
-
"@salesforce/sfdx-agent-harness-mastra": "0.
|
|
52
|
-
"@salesforce/sfdx-agent-harness-openai": "0.
|
|
50
|
+
"@salesforce/sfdx-agent-harness-claude": "0.37.0",
|
|
51
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.40.0",
|
|
52
|
+
"@salesforce/sfdx-agent-harness-openai": "0.6.0",
|
|
53
53
|
"@types/node": "^22.20.0",
|
|
54
54
|
"@vitest/coverage-istanbul": "^4.1.10",
|
|
55
55
|
"@vitest/eslint-plugin": "^1.6.22",
|