@salesforce/sfdx-agent-sdk 0.1.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/LICENSE.txt +21 -0
- package/README.md +508 -0
- package/dist/agent-connectivity-resolver.d.ts +62 -0
- package/dist/agent-connectivity-resolver.js +47 -0
- package/dist/agent-connectivity-resolver.js.map +1 -0
- package/dist/agent-manager.d.ts +134 -0
- package/dist/agent-manager.js +266 -0
- package/dist/agent-manager.js.map +1 -0
- package/dist/agent.d.ts +218 -0
- package/dist/agent.js +313 -0
- package/dist/agent.js.map +1 -0
- package/dist/chat-session.d.ts +298 -0
- package/dist/chat-session.js +407 -0
- package/dist/chat-session.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -0
- package/dist/harness/agent-harness.d.ts +200 -0
- package/dist/harness/agent-harness.js +6 -0
- package/dist/harness/agent-harness.js.map +1 -0
- package/dist/harness/harness-bus-owner.d.ts +34 -0
- package/dist/harness/harness-bus-owner.js +78 -0
- package/dist/harness/harness-bus-owner.js.map +1 -0
- package/dist/harness/harness-config.d.ts +89 -0
- package/dist/harness/harness-config.js +26 -0
- package/dist/harness/harness-config.js.map +1 -0
- package/dist/harness/harness-factory.d.ts +21 -0
- package/dist/harness/harness-factory.js +6 -0
- package/dist/harness/harness-factory.js.map +1 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.js +6 -0
- package/dist/harness/index.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/telemetry-router.d.ts +41 -0
- package/dist/internal/telemetry-router.js +128 -0
- package/dist/internal/telemetry-router.js.map +1 -0
- package/dist/mcp-auth.d.ts +20 -0
- package/dist/mcp-auth.js +40 -0
- package/dist/mcp-auth.js.map +1 -0
- package/dist/mcp-config.d.ts +52 -0
- package/dist/mcp-config.js +13 -0
- package/dist/mcp-config.js.map +1 -0
- package/dist/test/tsconfig.tsbuildinfo +1 -0
- package/dist/types/events.d.ts +151 -0
- package/dist/types/events.js +6 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/messages.d.ts +60 -0
- package/dist/types/messages.js +6 -0
- package/dist/types/messages.js.map +1 -0
- package/dist/types/telemetry-events.d.ts +93 -0
- package/dist/types/telemetry-events.js +6 -0
- package/dist/types/telemetry-events.js.map +1 -0
- package/dist/types/tools.d.ts +57 -0
- package/dist/types/tools.js +6 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types/usage.d.ts +31 -0
- package/dist/types/usage.js +6 -0
- package/dist/types/usage.js.map +1 -0
- package/dist/workspace.d.ts +15 -0
- package/dist/workspace.js +48 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ToolCallInfo, ToolResultInfo } from './tools.js';
|
|
2
|
+
import type { FinishReason, UsageMetadata } from './usage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Discriminated union of all events emitted during a streaming chat interaction.
|
|
5
|
+
*
|
|
6
|
+
* Event type names are aligned with the Vercel AI SDK `TextStreamPart` naming
|
|
7
|
+
* convention, with the addition of `tool-approval-request` for human-in-the-loop
|
|
8
|
+
* tool approval flows.
|
|
9
|
+
*/
|
|
10
|
+
export type ChatEvent = StartEvent | TextDeltaEvent | ReasoningDeltaEvent | ToolCallEvent | ToolApprovalRequestEvent | ToolResultEvent | StepStartEvent | StepFinishEvent | ErrorEvent | FinishEvent | UnmappedChunkEvent;
|
|
11
|
+
/**
|
|
12
|
+
* The stream has begun. Symmetric counterpart to {@link FinishEvent}.
|
|
13
|
+
*
|
|
14
|
+
* Aligned with the AI SDK `start` stream event. Emitted once at the very
|
|
15
|
+
* beginning of the event stream before any content events.
|
|
16
|
+
*/
|
|
17
|
+
export type StartEvent = {
|
|
18
|
+
type: 'start';
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* An incremental text fragment (chunk) from the model's response.
|
|
22
|
+
*
|
|
23
|
+
* Concatenate successive `text-delta` events to build the full response text.
|
|
24
|
+
* The `textStream` on {@link ChatStreamResult} yields these as plain strings.
|
|
25
|
+
*/
|
|
26
|
+
export type TextDeltaEvent = {
|
|
27
|
+
type: 'text-delta';
|
|
28
|
+
/** The text fragment. */
|
|
29
|
+
text: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* An incremental reasoning/thought fragment (chunk) from the model's chain-of-thought.
|
|
33
|
+
*
|
|
34
|
+
* Concatenate successive `reasoning-delta` events to build the full reasoning text.
|
|
35
|
+
* These are excluded from `textStream`.
|
|
36
|
+
*/
|
|
37
|
+
export type ReasoningDeltaEvent = {
|
|
38
|
+
type: 'reasoning-delta';
|
|
39
|
+
/** The reasoning text fragment. */
|
|
40
|
+
text: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* A real-time stream event indicating the model has invoked a tool.
|
|
44
|
+
* When the harness supports native tool execution, the tool runs automatically
|
|
45
|
+
* and a {@link ToolResultEvent} follows. When the harness does not, the consumer
|
|
46
|
+
* must call `submitToolResult()`.
|
|
47
|
+
*
|
|
48
|
+
* Extends {@link ToolCallInfo} with a discriminator type for use in the
|
|
49
|
+
* {@link ChatEvent} discriminated union.
|
|
50
|
+
*/
|
|
51
|
+
export type ToolCallEvent = ToolCallInfo & {
|
|
52
|
+
type: 'tool-call';
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The harness is requesting approval before executing a tool call.
|
|
56
|
+
* The stream suspends until the consumer calls `approveToolCall()` or
|
|
57
|
+
* `declineToolCall()`. Maps to ACP's `awaiting` run state.
|
|
58
|
+
*
|
|
59
|
+
* Uses nested composition (`toolCall: ToolCallInfo`) rather than flat
|
|
60
|
+
* inheritance because this event is *about* a tool call, not *a* tool call.
|
|
61
|
+
* This leaves room for approval-specific metadata (e.g., `reason`, `policy`)
|
|
62
|
+
* without polluting the tool call fields.
|
|
63
|
+
*/
|
|
64
|
+
export type ToolApprovalRequestEvent = {
|
|
65
|
+
type: 'tool-approval-request';
|
|
66
|
+
/** The tool call awaiting approval. */
|
|
67
|
+
toolCall: ToolCallInfo;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* A real-time stream event indicating a tool execution has completed.
|
|
71
|
+
*
|
|
72
|
+
* Extends {@link ToolResultInfo} with a discriminator type for use in the
|
|
73
|
+
* {@link ChatEvent} discriminated union.
|
|
74
|
+
*/
|
|
75
|
+
export type ToolResultEvent = ToolResultInfo & {
|
|
76
|
+
type: 'tool-result';
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Marks the beginning of a new LLM invocation within a multi-step agentic loop.
|
|
80
|
+
*
|
|
81
|
+
* A single `chat()` call may trigger multiple steps — e.g., step 0 generates a tool call,
|
|
82
|
+
* step 1 processes the tool result and generates the final response. Each step is one
|
|
83
|
+
* round-trip to the LLM.
|
|
84
|
+
*/
|
|
85
|
+
export type StepStartEvent = {
|
|
86
|
+
type: 'step-start';
|
|
87
|
+
/** Zero-based index of this step within the current stream. */
|
|
88
|
+
stepIndex: number;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Marks the completion of an LLM invocation within a multi-step agentic loop.
|
|
92
|
+
*
|
|
93
|
+
* Carries per-step `usage` (token counts) and `finishReason`, enabling consumers to track
|
|
94
|
+
* cost and behavior per LLM call. The final {@link FinishEvent} carries aggregate usage
|
|
95
|
+
* across all steps.
|
|
96
|
+
*/
|
|
97
|
+
export type StepFinishEvent = {
|
|
98
|
+
type: 'step-finish';
|
|
99
|
+
/** Zero-based index of the completed step. */
|
|
100
|
+
stepIndex: number;
|
|
101
|
+
/** Why this step stopped generating. */
|
|
102
|
+
finishReason: FinishReason;
|
|
103
|
+
/** Token usage for this step. */
|
|
104
|
+
usage?: UsageMetadata;
|
|
105
|
+
};
|
|
106
|
+
/** An error occurred during streaming. */
|
|
107
|
+
export type ErrorEvent = {
|
|
108
|
+
type: 'error';
|
|
109
|
+
/** The error that occurred. */
|
|
110
|
+
error: Error;
|
|
111
|
+
/** Machine-readable error code (e.g., `'insufficient-tokens'`). */
|
|
112
|
+
code?: string;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* A stream chunk from the underlying harness that has no `ChatEvent` counterpart.
|
|
116
|
+
*
|
|
117
|
+
* Returned instead of silently discarding the chunk, so consumers can log or
|
|
118
|
+
* monitor unhandled harness events for observability.
|
|
119
|
+
*/
|
|
120
|
+
export type UnmappedChunkEvent = {
|
|
121
|
+
type: 'unmapped-chunk';
|
|
122
|
+
/** The original harness chunk type string (e.g., `'tool-call-suspended'`, `'raw'`). */
|
|
123
|
+
chunkType: string;
|
|
124
|
+
/** The raw chunk object, preserved for diagnostic logging. */
|
|
125
|
+
rawChunk: unknown;
|
|
126
|
+
};
|
|
127
|
+
/** The entire stream has completed. */
|
|
128
|
+
export type FinishEvent = {
|
|
129
|
+
type: 'finish';
|
|
130
|
+
/** Why the model stopped generating. */
|
|
131
|
+
finishReason: FinishReason;
|
|
132
|
+
/** Aggregate token usage for the entire interaction. */
|
|
133
|
+
usage?: UsageMetadata;
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Result of a streaming chat interaction.
|
|
137
|
+
* Provides multiple ways to consume the stream, aligned with the AI SDK
|
|
138
|
+
* and Mastra patterns.
|
|
139
|
+
*/
|
|
140
|
+
export type ChatStreamResult = {
|
|
141
|
+
/**
|
|
142
|
+
* Full stream of all lifecycle events.
|
|
143
|
+
* Interleaves text tokens, tool calls, tool results, and step metadata.
|
|
144
|
+
*/
|
|
145
|
+
eventStream: AsyncGenerator<ChatEvent>;
|
|
146
|
+
/**
|
|
147
|
+
* Convenience stream yielding only the text tokens as plain strings.
|
|
148
|
+
* Ignores tool calls and metadata.
|
|
149
|
+
*/
|
|
150
|
+
textStream: AsyncGenerator<string>;
|
|
151
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { Message, MessageRole, MessagePart, TextPart, ReasoningPart, ToolCallPart, ToolResultPart, } from './messages.js';
|
|
2
|
+
export type { ChatEvent, StartEvent, TextDeltaEvent, ReasoningDeltaEvent, ToolCallEvent, ToolApprovalRequestEvent, ToolResultEvent, StepStartEvent, StepFinishEvent, ErrorEvent, FinishEvent, ChatStreamResult, } from './events.js';
|
|
3
|
+
export type { ToolDefinition, ToolCallInfo, ToolResultInfo } from './tools.js';
|
|
4
|
+
export type { UsageMetadata, FinishReason } from './usage.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ToolCallInfo, ToolResultInfo } from './tools.js';
|
|
2
|
+
/**
|
|
3
|
+
* Role of a message in a conversation. Aligned with AI SDK `ModelMessage` roles.
|
|
4
|
+
*
|
|
5
|
+
* - `system` -- Instructions to the model (not visible to end users)
|
|
6
|
+
* - `user` -- Messages from the human user
|
|
7
|
+
* - `assistant` -- Messages generated by the model
|
|
8
|
+
* - `tool` -- Results from tool executions
|
|
9
|
+
*/
|
|
10
|
+
export type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
11
|
+
/**
|
|
12
|
+
* A single message in a conversation thread.
|
|
13
|
+
*
|
|
14
|
+
* Content can be a plain string (shorthand for a single text part) or an
|
|
15
|
+
* array of typed {@link MessagePart} objects for rich multi-part messages
|
|
16
|
+
* containing text, reasoning, tool calls, and tool results.
|
|
17
|
+
*
|
|
18
|
+
* Structurally compatible with AI SDK `ModelMessage`.
|
|
19
|
+
*/
|
|
20
|
+
export type Message = {
|
|
21
|
+
/** Unique identifier for the message. */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Role of the message author. */
|
|
24
|
+
role: MessageRole;
|
|
25
|
+
/** Message content — plain text or structured parts. */
|
|
26
|
+
content: string | MessagePart[];
|
|
27
|
+
/** Optional timestamp of when the message was created. */
|
|
28
|
+
createdAt?: Date;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Discriminated union of message content parts.
|
|
32
|
+
* Aligned with AI SDK `TextPart`, `ReasoningPart`, `ToolCallPart`, `ToolResultPart`.
|
|
33
|
+
*/
|
|
34
|
+
export type MessagePart = TextPart | ReasoningPart | ToolCallPart | ToolResultPart;
|
|
35
|
+
/** A plain text content segment. */
|
|
36
|
+
export type TextPart = {
|
|
37
|
+
type: 'text';
|
|
38
|
+
/** The text content. */
|
|
39
|
+
text: string;
|
|
40
|
+
};
|
|
41
|
+
/** A reasoning/thought content segment produced by the model's chain-of-thought. */
|
|
42
|
+
export type ReasoningPart = {
|
|
43
|
+
type: 'reasoning';
|
|
44
|
+
/** The reasoning text. */
|
|
45
|
+
text: string;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* A tool invocation recorded as a content part within a persisted {@link Message}.
|
|
49
|
+
* Extends {@link ToolCallInfo} with a discriminator type.
|
|
50
|
+
*/
|
|
51
|
+
export type ToolCallPart = ToolCallInfo & {
|
|
52
|
+
type: 'tool-call';
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* A tool result recorded as a content part within a persisted {@link Message}.
|
|
56
|
+
* Extends {@link ToolResultInfo} with a discriminator type.
|
|
57
|
+
*/
|
|
58
|
+
export type ToolResultPart = ToolResultInfo & {
|
|
59
|
+
type: 'tool-result';
|
|
60
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/types/messages.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { EventBus } from '@salesforce/agentic-common';
|
|
2
|
+
import type { UsageMetadata } from './usage.js';
|
|
3
|
+
/**
|
|
4
|
+
* Telemetry events emitted by the Agent SDK.
|
|
5
|
+
*
|
|
6
|
+
* The union is stable public API; consumers subscribe via `onTelemetry()` on `AgentManager`, `Agent`, or
|
|
7
|
+
* `ChatSession`. Routing fields (`agentId`, `threadId`) are typed on the variants that carry them so
|
|
8
|
+
* internal dispatch does not need to reach into a context bag.
|
|
9
|
+
*/
|
|
10
|
+
type Base<T extends string> = {
|
|
11
|
+
type: T;
|
|
12
|
+
timestamp: Date;
|
|
13
|
+
};
|
|
14
|
+
export type AgentCreatedEvent = Base<'agent-created'> & {
|
|
15
|
+
agentId: string;
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
modelName: string;
|
|
18
|
+
};
|
|
19
|
+
export type AgentDestroyedEvent = Base<'agent-destroyed'> & {
|
|
20
|
+
agentId: string;
|
|
21
|
+
};
|
|
22
|
+
export type SessionCreatedEvent = Base<'session-created'> & {
|
|
23
|
+
agentId: string;
|
|
24
|
+
threadId: string;
|
|
25
|
+
};
|
|
26
|
+
export type SessionDestroyedEvent = Base<'session-destroyed'> & {
|
|
27
|
+
agentId: string;
|
|
28
|
+
threadId: string;
|
|
29
|
+
};
|
|
30
|
+
export type ChatStreamTrigger = 'chat' | 'submit-tool-result' | 'approve-tool-call' | 'decline-tool-call';
|
|
31
|
+
export type ChatStreamStartedEvent = Base<'chat-stream-started'> & {
|
|
32
|
+
agentId: string;
|
|
33
|
+
threadId: string;
|
|
34
|
+
trigger: ChatStreamTrigger;
|
|
35
|
+
};
|
|
36
|
+
export type ChatStreamCompletedEvent = Base<'chat-stream-completed'> & {
|
|
37
|
+
agentId: string;
|
|
38
|
+
threadId: string;
|
|
39
|
+
durationMs: number;
|
|
40
|
+
usage?: UsageMetadata;
|
|
41
|
+
};
|
|
42
|
+
export type ChatStreamErrorEvent = Base<'chat-stream-error'> & {
|
|
43
|
+
agentId: string;
|
|
44
|
+
threadId: string;
|
|
45
|
+
durationMs: number;
|
|
46
|
+
error: Error;
|
|
47
|
+
};
|
|
48
|
+
export type ToolExecutionStartedEvent = Base<'tool-execution-started'> & {
|
|
49
|
+
agentId: string;
|
|
50
|
+
threadId: string;
|
|
51
|
+
toolCallId: string;
|
|
52
|
+
toolName: string;
|
|
53
|
+
};
|
|
54
|
+
export type ToolExecutionCompletedEvent = Base<'tool-execution-completed'> & {
|
|
55
|
+
agentId: string;
|
|
56
|
+
threadId: string;
|
|
57
|
+
toolCallId: string;
|
|
58
|
+
toolName: string;
|
|
59
|
+
durationMs: number;
|
|
60
|
+
isError: boolean;
|
|
61
|
+
};
|
|
62
|
+
export type ToolApprovalRequestedEvent = Base<'tool-approval-requested'> & {
|
|
63
|
+
agentId: string;
|
|
64
|
+
threadId: string;
|
|
65
|
+
toolCallId: string;
|
|
66
|
+
toolName: string;
|
|
67
|
+
};
|
|
68
|
+
export type ToolApprovalResolvedEvent = Base<'tool-approval-resolved'> & {
|
|
69
|
+
agentId: string;
|
|
70
|
+
threadId: string;
|
|
71
|
+
toolCallId: string;
|
|
72
|
+
approved: boolean;
|
|
73
|
+
};
|
|
74
|
+
export type McpServerDiscoveryStartedEvent = Base<'mcp-server-discovery-started'> & {
|
|
75
|
+
agentId: string;
|
|
76
|
+
serverName: string;
|
|
77
|
+
};
|
|
78
|
+
export type McpServerDiscoveryCompletedEvent = Base<'mcp-server-discovery-completed'> & {
|
|
79
|
+
agentId: string;
|
|
80
|
+
serverName: string;
|
|
81
|
+
toolCount: number;
|
|
82
|
+
durationMs: number;
|
|
83
|
+
};
|
|
84
|
+
export type McpServerDiscoveryFailedEvent = Base<'mcp-server-discovery-failed'> & {
|
|
85
|
+
agentId: string;
|
|
86
|
+
serverName: string;
|
|
87
|
+
durationMs: number;
|
|
88
|
+
error: Error;
|
|
89
|
+
};
|
|
90
|
+
export type TelemetryEvent = AgentCreatedEvent | AgentDestroyedEvent | SessionCreatedEvent | SessionDestroyedEvent | ChatStreamStartedEvent | ChatStreamCompletedEvent | ChatStreamErrorEvent | ToolExecutionStartedEvent | ToolExecutionCompletedEvent | ToolApprovalRequestedEvent | ToolApprovalResolvedEvent | McpServerDiscoveryStartedEvent | McpServerDiscoveryCompletedEvent | McpServerDiscoveryFailedEvent;
|
|
91
|
+
export type TelemetryEventCallback = (event: TelemetryEvent) => void;
|
|
92
|
+
export type TelemetryBus = EventBus<TelemetryEvent>;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-events.js","sourceRoot":"","sources":["../../src/types/telemetry-events.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Declares a consumer-executed tool that an agent can invoke.
|
|
3
|
+
*
|
|
4
|
+
* Tools declared here are schema-only: the harness registers the name,
|
|
5
|
+
* description, and input schema with the model so it can generate tool-call
|
|
6
|
+
* chunks, but the harness never executes these tools itself. When the model
|
|
7
|
+
* calls one, the stream ends with `finishReason: 'tool-calls'` and the
|
|
8
|
+
* consumer is responsible for running the tool locally and feeding the result
|
|
9
|
+
* back via `ChatSession.submitToolResult()`.
|
|
10
|
+
*
|
|
11
|
+
* For harness-executed (native) tools such as MCP tools, use
|
|
12
|
+
* `AgentConfig.mcpServers`. To gate native tool calls with human approval,
|
|
13
|
+
* use `StreamOptions.requireToolApproval`.
|
|
14
|
+
*
|
|
15
|
+
* Structurally compatible with AI SDK `LanguageModelV4FunctionTool`.
|
|
16
|
+
*/
|
|
17
|
+
export type ToolDefinition = {
|
|
18
|
+
/** Unique name identifying the tool. */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Human-readable description shown to the model. */
|
|
21
|
+
description?: string;
|
|
22
|
+
/**
|
|
23
|
+
* JSON Schema describing the tool's expected input.
|
|
24
|
+
* Harnesses use this to validate arguments before execution.
|
|
25
|
+
*/
|
|
26
|
+
inputSchema: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Base shape for a tool call.
|
|
30
|
+
*
|
|
31
|
+
* Used as the parameter to {@link ChatSession.submitToolResult} for client-side tool execution.
|
|
32
|
+
* Extended by {@link ToolCallPart} (message content) and {@link ToolCallEvent} (stream event).
|
|
33
|
+
* Also referenced by {@link ToolApprovalRequestEvent}.
|
|
34
|
+
*/
|
|
35
|
+
export type ToolCallInfo = {
|
|
36
|
+
/** Unique identifier for this tool call instance. */
|
|
37
|
+
toolCallId: string;
|
|
38
|
+
/** Name of the tool being called. */
|
|
39
|
+
toolName: string;
|
|
40
|
+
/** Arguments the model passed to the tool. */
|
|
41
|
+
args: Record<string, unknown>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Base shape for a tool result.
|
|
45
|
+
*
|
|
46
|
+
* Extended by {@link ToolResultPart} (message content) and {@link ToolResultEvent} (stream event).
|
|
47
|
+
*/
|
|
48
|
+
export type ToolResultInfo = {
|
|
49
|
+
/** Identifier linking this result to the originating tool call. */
|
|
50
|
+
toolCallId: string;
|
|
51
|
+
/** Name of the tool that produced this result. */
|
|
52
|
+
toolName: string;
|
|
53
|
+
/** The tool's output value. */
|
|
54
|
+
result: unknown;
|
|
55
|
+
/** Whether the tool execution resulted in an error. */
|
|
56
|
+
isError?: boolean;
|
|
57
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token usage statistics for an LLM interaction.
|
|
3
|
+
* Structurally compatible with AI SDK `LanguageModelUsage`.
|
|
4
|
+
*/
|
|
5
|
+
export type UsageMetadata = {
|
|
6
|
+
/** Number of tokens in the input prompt. */
|
|
7
|
+
inputTokens?: number;
|
|
8
|
+
/** Number of tokens generated in the output. */
|
|
9
|
+
outputTokens?: number;
|
|
10
|
+
/** Sum of input and output tokens. */
|
|
11
|
+
totalTokens?: number;
|
|
12
|
+
/** Tokens consumed by the model's reasoning/thinking phase. */
|
|
13
|
+
reasoningTokens?: number;
|
|
14
|
+
/** Input tokens served from provider cache (reduces cost). */
|
|
15
|
+
cachedInputTokens?: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Reason the model stopped generating.
|
|
19
|
+
* Aligned with AI SDK `LanguageModelV2FinishReason`.
|
|
20
|
+
*
|
|
21
|
+
* - `stop` — The model finished generating naturally (complete response).
|
|
22
|
+
* - `length` — The model hit the maximum output token limit; the response was truncated mid-generation.
|
|
23
|
+
* - `tool-calls` — The model stopped generating text to invoke one or more tools. Normal in multi-step agentic loops.
|
|
24
|
+
* - `content-filter` — The provider's safety/moderation filter blocked the response.
|
|
25
|
+
* - `error` — An error occurred during generation.
|
|
26
|
+
* - `max-steps` — The agentic loop was terminated because it reached the maximum step count.
|
|
27
|
+
* The model wanted to continue (e.g., it was requesting more tool calls) but the loop was forcibly stopped.
|
|
28
|
+
* This is distinct from `tool-calls` which in a step-finish context indicates normal mid-loop progress.
|
|
29
|
+
* - `other` — Provider-specific reason that doesn't map to the standard values.
|
|
30
|
+
*/
|
|
31
|
+
export type FinishReason = 'stop' | 'length' | 'tool-calls' | 'content-filter' | 'error' | 'max-steps' | 'other';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/types/usage.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validated project path with normalization.
|
|
3
|
+
*
|
|
4
|
+
* A convenience class for async path validation + normalization.
|
|
5
|
+
*/
|
|
6
|
+
export declare class Workspace {
|
|
7
|
+
readonly projectPath: string;
|
|
8
|
+
private constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Creates a validated Workspace.
|
|
11
|
+
* @param projectPath - Project folder the agent can manipulate files from.
|
|
12
|
+
* @throws If projectPath does not exist or is not a directory.
|
|
13
|
+
*/
|
|
14
|
+
static create(projectPath: string): Promise<Workspace>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026, Salesforce, Inc. All rights reserved.
|
|
3
|
+
* See LICENSE.txt for license terms.
|
|
4
|
+
*/
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import * as fs from 'node:fs';
|
|
7
|
+
/**
|
|
8
|
+
* Validated project path with normalization.
|
|
9
|
+
*
|
|
10
|
+
* A convenience class for async path validation + normalization.
|
|
11
|
+
*/
|
|
12
|
+
export class Workspace {
|
|
13
|
+
projectPath;
|
|
14
|
+
constructor(projectPath) {
|
|
15
|
+
this.projectPath = projectPath;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a validated Workspace.
|
|
19
|
+
* @param projectPath - Project folder the agent can manipulate files from.
|
|
20
|
+
* @throws If projectPath does not exist or is not a directory.
|
|
21
|
+
*/
|
|
22
|
+
static async create(projectPath) {
|
|
23
|
+
const absPath = await validateFolder(projectPath);
|
|
24
|
+
return new Workspace(absPath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function validateFolder(folder) {
|
|
28
|
+
const absFolder = toAbsolutePath(folder);
|
|
29
|
+
try {
|
|
30
|
+
const stats = await fs.promises.stat(absFolder);
|
|
31
|
+
if (!stats.isDirectory()) {
|
|
32
|
+
throw new Error(`Path exists but is not a directory: "${absFolder}"`);
|
|
33
|
+
}
|
|
34
|
+
return await fs.promises.realpath(absFolder);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
|
|
38
|
+
throw new Error(`Directory not found: "${absFolder}"`, { cause: err });
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function toAbsolutePath(pathValue) {
|
|
44
|
+
// Convert slashes to platform specific slashes and then convert to absolute path
|
|
45
|
+
pathValue = pathValue.replace(/[\\/]/g, path.sep);
|
|
46
|
+
return path.resolve(pathValue);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B;;;;GAIG;AACH,MAAM,OAAO,SAAS;IACT,WAAW,CAAS;IAE7B,YAAoB,WAAmB;QACnC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,WAAmB;QACnC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,CAAC;QAClD,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,CAAC;CACJ;AAED,KAAK,UAAU,cAAc,CAAC,MAAc;IACxC,MAAM,SAAS,GAAW,cAAc,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wCAAwC,SAAS,GAAG,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,GAAG,YAAY,KAAK,IAAI,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjE,MAAM,IAAI,KAAK,CAAC,yBAAyB,SAAS,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,GAAG,CAAC;IACd,CAAC;AACL,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB;IACrC,iFAAiF;IACjF,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@salesforce/sfdx-agent-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Harness-agnostic agentic infrastructure for Salesforce developer experience tooling",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/forcedotcom/agentic-dx.git"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc --build",
|
|
14
|
+
"clean": "tsc --build --clean",
|
|
15
|
+
"clean:all": "npm run clean && rimraf node_modules",
|
|
16
|
+
"postclean": "rimraf coverage && rimraf dist",
|
|
17
|
+
"format": "prettier --write .",
|
|
18
|
+
"lint": "eslint .",
|
|
19
|
+
"lint:fix": "eslint . --fix",
|
|
20
|
+
"showcoverage": "open ./coverage/lcov-report/index.html",
|
|
21
|
+
"test": "tsc --build ./test/tsconfig.json && vitest run --coverage",
|
|
22
|
+
"test:e2e": "tsc --build ./test/tsconfig.json && vitest run -c ./test/e2e/vitest.config.ts",
|
|
23
|
+
"test:e2e:local": "node scripts/local-e2e.mjs",
|
|
24
|
+
"test:e2e:local:cleanup": "node scripts/local-e2e-cleanup.mjs",
|
|
25
|
+
"verify": "tsx scripts/verify.ts"
|
|
26
|
+
},
|
|
27
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"LICENSE.txt"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@salesforce/agentic-common": "0.1.0",
|
|
34
|
+
"@salesforce/llm-gateway-sdk": "0.1.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@eslint/js": "^10.0.1",
|
|
38
|
+
"@salesforce/sfdx-agent-harness-mastra": "0.1.0",
|
|
39
|
+
"@types/node": "^22.19.17",
|
|
40
|
+
"@vitest/coverage-istanbul": "^4.1.5",
|
|
41
|
+
"@vitest/eslint-plugin": "^1.6.16",
|
|
42
|
+
"eslint": "^10.2.1",
|
|
43
|
+
"eslint-config-prettier": "^10.1.8",
|
|
44
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
45
|
+
"eslint-plugin-import": "^2.32.0",
|
|
46
|
+
"eslint-plugin-n": "^18.0.1",
|
|
47
|
+
"globals": "^17.6.0",
|
|
48
|
+
"lint-staged": "^17.0.4",
|
|
49
|
+
"prettier": "^3.8.3",
|
|
50
|
+
"rimraf": "^6.1.3",
|
|
51
|
+
"tsx": "^4.21.0",
|
|
52
|
+
"typescript": "^6.0.3",
|
|
53
|
+
"typescript-eslint": "^8.59.1",
|
|
54
|
+
"vitest": "^4.1.5"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=22.19.0"
|
|
58
|
+
},
|
|
59
|
+
"lint-staged": {
|
|
60
|
+
"*.{js,jsx,ts,tsx,json,md}": [
|
|
61
|
+
"prettier --write"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|