@firstflow/core 0.0.5
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/README.md +130 -0
- package/dist/anthropic.d.mts +19 -0
- package/dist/anthropic.d.ts +19 -0
- package/dist/anthropic.js +1810 -0
- package/dist/anthropic.mjs +11 -0
- package/dist/chunk-RZMKPIBO.mjs +17 -0
- package/dist/chunk-X3T7X4JQ.mjs +1758 -0
- package/dist/index.d.mts +257 -0
- package/dist/index.d.ts +257 -0
- package/dist/index.js +1865 -0
- package/dist/index.mjs +80 -0
- package/dist/openai.d.mts +19 -0
- package/dist/openai.d.ts +19 -0
- package/dist/openai.js +1810 -0
- package/dist/openai.mjs +11 -0
- package/package.json +78 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/** A recent conversation turn forwarded as sliding-window context. */
|
|
2
|
+
type RecentMessage = {
|
|
3
|
+
role: "user" | "assistant";
|
|
4
|
+
content: string;
|
|
5
|
+
};
|
|
6
|
+
/** LLM call metadata captured automatically by the proxy wrapper. */
|
|
7
|
+
type LlmCallMeta = {
|
|
8
|
+
model?: string;
|
|
9
|
+
provider?: "openai" | "anthropic";
|
|
10
|
+
inputTokens?: number;
|
|
11
|
+
outputTokens?: number;
|
|
12
|
+
cacheReadTokens?: number;
|
|
13
|
+
cacheCreationTokens?: number;
|
|
14
|
+
latencyMs?: number;
|
|
15
|
+
timeToFirstTokenMs?: number;
|
|
16
|
+
finishReason?: string;
|
|
17
|
+
isError?: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
inputCostUsd?: number;
|
|
20
|
+
outputCostUsd?: number;
|
|
21
|
+
totalCostUsd?: number;
|
|
22
|
+
httpStatus?: number;
|
|
23
|
+
};
|
|
24
|
+
type ObserveArgs = {
|
|
25
|
+
/** The agent this message is attributed to. Primary routing key. */
|
|
26
|
+
agentId: string;
|
|
27
|
+
conversationId: string;
|
|
28
|
+
userId: string;
|
|
29
|
+
role: "user" | "assistant" | "tool";
|
|
30
|
+
content: string;
|
|
31
|
+
/**
|
|
32
|
+
* Bounded sliding window of recent turns (from the LLM request). Sent with an
|
|
33
|
+
* assistant observe so the backend can give classify nodes / widget
|
|
34
|
+
* composition real conversation context. Never the full transcript.
|
|
35
|
+
*/
|
|
36
|
+
recentMessages?: RecentMessage[];
|
|
37
|
+
/** Arbitrary metadata forwarded alongside the message (e.g. plan tier, A/B variant). */
|
|
38
|
+
properties?: Record<string, unknown>;
|
|
39
|
+
} & LlmCallMeta;
|
|
40
|
+
type SpanType = "generation" | "tool_call" | "retrieval" | "embedding" | "span";
|
|
41
|
+
type SpanInput = {
|
|
42
|
+
spanId?: string;
|
|
43
|
+
parentSpanId?: string;
|
|
44
|
+
type?: SpanType;
|
|
45
|
+
name?: string;
|
|
46
|
+
model?: string;
|
|
47
|
+
provider?: string;
|
|
48
|
+
/** Full input payload (messages array, prompt, etc.) */
|
|
49
|
+
input?: unknown;
|
|
50
|
+
/** Raw LLM response or tool output */
|
|
51
|
+
output?: unknown;
|
|
52
|
+
inputTokens?: number;
|
|
53
|
+
outputTokens?: number;
|
|
54
|
+
cacheReadTokens?: number;
|
|
55
|
+
cacheCreationTokens?: number;
|
|
56
|
+
latencyMs?: number;
|
|
57
|
+
timeToFirstTokenMs?: number;
|
|
58
|
+
finishReason?: string;
|
|
59
|
+
isError?: boolean;
|
|
60
|
+
error?: string;
|
|
61
|
+
inputCostUsd?: number;
|
|
62
|
+
outputCostUsd?: number;
|
|
63
|
+
totalCostUsd?: number;
|
|
64
|
+
toolsCalled?: string[];
|
|
65
|
+
toolCallCount?: number;
|
|
66
|
+
inputState?: unknown;
|
|
67
|
+
outputState?: unknown;
|
|
68
|
+
httpStatus?: number;
|
|
69
|
+
properties?: Record<string, unknown>;
|
|
70
|
+
startedAt?: Date | string;
|
|
71
|
+
endedAt?: Date | string;
|
|
72
|
+
};
|
|
73
|
+
type TraceInput = {
|
|
74
|
+
traceId?: string;
|
|
75
|
+
/** Link this trace to a conversation — pass the same session id used on the LLM call. */
|
|
76
|
+
sessionId?: string;
|
|
77
|
+
userId?: string;
|
|
78
|
+
name?: string;
|
|
79
|
+
inputState?: unknown;
|
|
80
|
+
outputState?: unknown;
|
|
81
|
+
latencyMs?: number;
|
|
82
|
+
isError?: boolean;
|
|
83
|
+
error?: string;
|
|
84
|
+
properties?: Record<string, unknown>;
|
|
85
|
+
startedAt?: Date | string;
|
|
86
|
+
endedAt?: Date | string;
|
|
87
|
+
spans?: SpanInput[];
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The outcome of a user session with the AI agent.
|
|
91
|
+
* Built-in values: 'completed', 'abandoned', 'escalated'.
|
|
92
|
+
* Any custom string is also accepted (e.g. 'onboarding-finished', 'support-needed').
|
|
93
|
+
*/
|
|
94
|
+
type SessionOutcome = "completed" | "abandoned" | "escalated" | (string & {});
|
|
95
|
+
/** Arguments for `outcome()` — signals what happened at the end of a session. */
|
|
96
|
+
type OutcomeInput = {
|
|
97
|
+
/** The agent this outcome is attributed to. */
|
|
98
|
+
firstflowAgentId: string;
|
|
99
|
+
/** The session/conversation id (same value passed on the LLM call). */
|
|
100
|
+
sessionId: string;
|
|
101
|
+
/** The end-user this session belongs to. */
|
|
102
|
+
userId: string;
|
|
103
|
+
/**
|
|
104
|
+
* What happened at the end of the session.
|
|
105
|
+
* Use 'completed' (user accomplished their goal), 'abandoned' (user left without finishing),
|
|
106
|
+
* 'escalated' (handed off to human support), or any custom label.
|
|
107
|
+
*/
|
|
108
|
+
outcome?: SessionOutcome;
|
|
109
|
+
/**
|
|
110
|
+
* What the user was trying to accomplish. Free-form label grouped in analytics.
|
|
111
|
+
* e.g. 'onboarding-setup', 'billing-question', 'how-to', 'troubleshooting'.
|
|
112
|
+
*/
|
|
113
|
+
intent?: string;
|
|
114
|
+
};
|
|
115
|
+
/** Arguments for `feedback()` — records thumbs-up or thumbs-down for a session. */
|
|
116
|
+
type FeedbackInput = {
|
|
117
|
+
/** The agent this feedback is attributed to. */
|
|
118
|
+
firstflowAgentId: string;
|
|
119
|
+
/** The session/conversation id this feedback belongs to. */
|
|
120
|
+
sessionId: string;
|
|
121
|
+
/** The end-user who submitted the feedback. */
|
|
122
|
+
userId: string;
|
|
123
|
+
/** 1 = thumbs up, -1 = thumbs down. */
|
|
124
|
+
rating: 1 | -1;
|
|
125
|
+
/** Optional free-text comment from the user. Max 500 chars. */
|
|
126
|
+
comment?: string;
|
|
127
|
+
/** Optional: the specific message the feedback applies to. */
|
|
128
|
+
messageId?: string;
|
|
129
|
+
};
|
|
130
|
+
/** Arguments for `track()`. */
|
|
131
|
+
type TrackArgs = {
|
|
132
|
+
/** The agent this event is attributed to. */
|
|
133
|
+
firstflowAgentId: string;
|
|
134
|
+
/** The end-user who triggered the event. */
|
|
135
|
+
userId: string;
|
|
136
|
+
event: string;
|
|
137
|
+
properties?: Record<string, unknown>;
|
|
138
|
+
};
|
|
139
|
+
/** Arguments for `identify()`. */
|
|
140
|
+
type IdentifyArgs = {
|
|
141
|
+
/** The agent this identity is attributed to. */
|
|
142
|
+
firstflowAgentId: string;
|
|
143
|
+
/** The end-user being identified. */
|
|
144
|
+
userId: string;
|
|
145
|
+
traits?: Record<string, unknown>;
|
|
146
|
+
};
|
|
147
|
+
/** Arguments for `trace()` — an agent-scoped trace with optional nested spans. */
|
|
148
|
+
type TraceArgs = TraceInput & {
|
|
149
|
+
/** The agent this trace is attributed to. */
|
|
150
|
+
firstflowAgentId: string;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Arguments for the standalone `observe()` — record a single conversation turn.
|
|
154
|
+
* For integrations that don't use the pre-wrapped `OpenAI` / `Anthropic`
|
|
155
|
+
* clients (e.g. the Vercel AI SDK, LangChain, or a custom gateway).
|
|
156
|
+
*/
|
|
157
|
+
type ObserveInput = {
|
|
158
|
+
/** The agent this message is attributed to. */
|
|
159
|
+
firstflowAgentId: string;
|
|
160
|
+
/** The session / conversation id this message belongs to. */
|
|
161
|
+
sessionId: string;
|
|
162
|
+
/** The end-user this message belongs to. */
|
|
163
|
+
userId: string;
|
|
164
|
+
role: "user" | "assistant" | "tool";
|
|
165
|
+
content: string;
|
|
166
|
+
recentMessages?: RecentMessage[];
|
|
167
|
+
properties?: Record<string, unknown>;
|
|
168
|
+
} & LlmCallMeta;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Record a single conversation turn. Use this when you can't use the
|
|
172
|
+
* pre-wrapped `OpenAI` / `Anthropic` clients (e.g. the Vercel AI SDK or a
|
|
173
|
+
* custom LLM gateway). Fire-and-forget — never throws.
|
|
174
|
+
*/
|
|
175
|
+
declare function observe(input: ObserveInput): void;
|
|
176
|
+
/** Signal what happened at the end of a session (completed / abandoned / escalated / custom). */
|
|
177
|
+
declare function outcome(input: OutcomeInput): void;
|
|
178
|
+
/** Record explicit thumbs-up (+1) or thumbs-down (-1) feedback for a session. */
|
|
179
|
+
declare function feedback(input: FeedbackInput): void;
|
|
180
|
+
/** Record an analytics event for a user under an agent. */
|
|
181
|
+
declare function track(args: TrackArgs): void;
|
|
182
|
+
/** Attach traits to a user under an agent. */
|
|
183
|
+
declare function identify(args: IdentifyArgs): void;
|
|
184
|
+
/** Record a trace (with optional nested spans) for detailed LLM observability. */
|
|
185
|
+
declare function trace(args: TraceArgs): void;
|
|
186
|
+
|
|
187
|
+
type WrapContext = {
|
|
188
|
+
apiKey: string;
|
|
189
|
+
baseUrl: string;
|
|
190
|
+
onAssistantComplete?: (args: ObserveArgs) => void;
|
|
191
|
+
/** Fired once per user turn (when the LLM request ends with a user message). */
|
|
192
|
+
onUserMessage?: (args: ObserveArgs) => void;
|
|
193
|
+
/** Fired when the LLM call throws. Re-throws after firing; never swallows errors. */
|
|
194
|
+
onError?: (args: Pick<ObserveArgs, "agentId" | "conversationId" | "userId"> & LlmCallMeta) => void;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Transparent `Proxy` over an OpenAI or Anthropic SDK client. Strips `firstflow`
|
|
198
|
+
* from request bodies, threads `firstflow.user_id` baggage for OTel, and fires
|
|
199
|
+
* observe hooks with full LLM metadata (model, tokens, latency, cost) once each
|
|
200
|
+
* call completes.
|
|
201
|
+
*/
|
|
202
|
+
declare function wrapClient<T extends object>(client: T, ctx: WrapContext): T;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Default Firstflow Cloud base URL. The host is intentional and matches
|
|
206
|
+
* production. To verify if a future regression is suspected:
|
|
207
|
+
*
|
|
208
|
+
* $ nslookup api.firstflow.app
|
|
209
|
+
*
|
|
210
|
+
* To override per-instance, pass `baseUrl` to `new Firstflow({...})`.
|
|
211
|
+
*/
|
|
212
|
+
declare const DEFAULT_FIRSTFLOW_BASE_URL = "https://api.firstflow.app";
|
|
213
|
+
declare const FIRSTFLOW_SERVER_PACKAGE_VERSION: "0.0.1-alpha.0";
|
|
214
|
+
|
|
215
|
+
type AccessibleAgent = {
|
|
216
|
+
id: string;
|
|
217
|
+
name: string | null;
|
|
218
|
+
};
|
|
219
|
+
type AccessibleAgentsResult = {
|
|
220
|
+
/** Agents this API key has access to. */
|
|
221
|
+
agents: AccessibleAgent[];
|
|
222
|
+
/**
|
|
223
|
+
* The workspace (Clerk org) that owns this API key.
|
|
224
|
+
* Returned by the backend from the API key's subject — no extra env var needed.
|
|
225
|
+
*/
|
|
226
|
+
workspaceId: string;
|
|
227
|
+
/**
|
|
228
|
+
* The workspace's browser-safe publishable key (`pk_live_...`).
|
|
229
|
+
* Pass directly as `publishableKey` on `<FirstflowProvider />`.
|
|
230
|
+
* May be `null` if the backend does not yet support this field.
|
|
231
|
+
*/
|
|
232
|
+
publishableKey: string | null;
|
|
233
|
+
};
|
|
234
|
+
type ListAccessibleAgentsOptions = {
|
|
235
|
+
/**
|
|
236
|
+
* Clerk-backed API key that carries `agent:<id>` scopes.
|
|
237
|
+
* Secret — never expose to the browser.
|
|
238
|
+
*/
|
|
239
|
+
apiKey: string;
|
|
240
|
+
/**
|
|
241
|
+
* Override the Firstflow Cloud base URL.
|
|
242
|
+
* Defaults to `https://api.firstflow.app`.
|
|
243
|
+
*/
|
|
244
|
+
baseUrl?: string;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Returns the agents this API key has access to, plus the workspace ID
|
|
248
|
+
* derived from the key itself — no extra env var required.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* const { agents, workspaceId } = await Firstflow.listAccessibleAgents({
|
|
252
|
+
* apiKey: process.env.FIRSTFLOW_API_KEY!,
|
|
253
|
+
* });
|
|
254
|
+
*/
|
|
255
|
+
declare function listAccessibleAgents(opts: ListAccessibleAgentsOptions): Promise<AccessibleAgentsResult>;
|
|
256
|
+
|
|
257
|
+
export { type AccessibleAgent, type AccessibleAgentsResult, DEFAULT_FIRSTFLOW_BASE_URL, FIRSTFLOW_SERVER_PACKAGE_VERSION, type FeedbackInput, type IdentifyArgs, type ListAccessibleAgentsOptions, type LlmCallMeta, type ObserveArgs, type ObserveInput, type OutcomeInput, type RecentMessage, type SessionOutcome, type SpanInput, type SpanType, type TraceArgs, type TraceInput, type TrackArgs, type WrapContext, feedback, identify, listAccessibleAgents, observe, outcome, trace, track, wrapClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/** A recent conversation turn forwarded as sliding-window context. */
|
|
2
|
+
type RecentMessage = {
|
|
3
|
+
role: "user" | "assistant";
|
|
4
|
+
content: string;
|
|
5
|
+
};
|
|
6
|
+
/** LLM call metadata captured automatically by the proxy wrapper. */
|
|
7
|
+
type LlmCallMeta = {
|
|
8
|
+
model?: string;
|
|
9
|
+
provider?: "openai" | "anthropic";
|
|
10
|
+
inputTokens?: number;
|
|
11
|
+
outputTokens?: number;
|
|
12
|
+
cacheReadTokens?: number;
|
|
13
|
+
cacheCreationTokens?: number;
|
|
14
|
+
latencyMs?: number;
|
|
15
|
+
timeToFirstTokenMs?: number;
|
|
16
|
+
finishReason?: string;
|
|
17
|
+
isError?: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
inputCostUsd?: number;
|
|
20
|
+
outputCostUsd?: number;
|
|
21
|
+
totalCostUsd?: number;
|
|
22
|
+
httpStatus?: number;
|
|
23
|
+
};
|
|
24
|
+
type ObserveArgs = {
|
|
25
|
+
/** The agent this message is attributed to. Primary routing key. */
|
|
26
|
+
agentId: string;
|
|
27
|
+
conversationId: string;
|
|
28
|
+
userId: string;
|
|
29
|
+
role: "user" | "assistant" | "tool";
|
|
30
|
+
content: string;
|
|
31
|
+
/**
|
|
32
|
+
* Bounded sliding window of recent turns (from the LLM request). Sent with an
|
|
33
|
+
* assistant observe so the backend can give classify nodes / widget
|
|
34
|
+
* composition real conversation context. Never the full transcript.
|
|
35
|
+
*/
|
|
36
|
+
recentMessages?: RecentMessage[];
|
|
37
|
+
/** Arbitrary metadata forwarded alongside the message (e.g. plan tier, A/B variant). */
|
|
38
|
+
properties?: Record<string, unknown>;
|
|
39
|
+
} & LlmCallMeta;
|
|
40
|
+
type SpanType = "generation" | "tool_call" | "retrieval" | "embedding" | "span";
|
|
41
|
+
type SpanInput = {
|
|
42
|
+
spanId?: string;
|
|
43
|
+
parentSpanId?: string;
|
|
44
|
+
type?: SpanType;
|
|
45
|
+
name?: string;
|
|
46
|
+
model?: string;
|
|
47
|
+
provider?: string;
|
|
48
|
+
/** Full input payload (messages array, prompt, etc.) */
|
|
49
|
+
input?: unknown;
|
|
50
|
+
/** Raw LLM response or tool output */
|
|
51
|
+
output?: unknown;
|
|
52
|
+
inputTokens?: number;
|
|
53
|
+
outputTokens?: number;
|
|
54
|
+
cacheReadTokens?: number;
|
|
55
|
+
cacheCreationTokens?: number;
|
|
56
|
+
latencyMs?: number;
|
|
57
|
+
timeToFirstTokenMs?: number;
|
|
58
|
+
finishReason?: string;
|
|
59
|
+
isError?: boolean;
|
|
60
|
+
error?: string;
|
|
61
|
+
inputCostUsd?: number;
|
|
62
|
+
outputCostUsd?: number;
|
|
63
|
+
totalCostUsd?: number;
|
|
64
|
+
toolsCalled?: string[];
|
|
65
|
+
toolCallCount?: number;
|
|
66
|
+
inputState?: unknown;
|
|
67
|
+
outputState?: unknown;
|
|
68
|
+
httpStatus?: number;
|
|
69
|
+
properties?: Record<string, unknown>;
|
|
70
|
+
startedAt?: Date | string;
|
|
71
|
+
endedAt?: Date | string;
|
|
72
|
+
};
|
|
73
|
+
type TraceInput = {
|
|
74
|
+
traceId?: string;
|
|
75
|
+
/** Link this trace to a conversation — pass the same session id used on the LLM call. */
|
|
76
|
+
sessionId?: string;
|
|
77
|
+
userId?: string;
|
|
78
|
+
name?: string;
|
|
79
|
+
inputState?: unknown;
|
|
80
|
+
outputState?: unknown;
|
|
81
|
+
latencyMs?: number;
|
|
82
|
+
isError?: boolean;
|
|
83
|
+
error?: string;
|
|
84
|
+
properties?: Record<string, unknown>;
|
|
85
|
+
startedAt?: Date | string;
|
|
86
|
+
endedAt?: Date | string;
|
|
87
|
+
spans?: SpanInput[];
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The outcome of a user session with the AI agent.
|
|
91
|
+
* Built-in values: 'completed', 'abandoned', 'escalated'.
|
|
92
|
+
* Any custom string is also accepted (e.g. 'onboarding-finished', 'support-needed').
|
|
93
|
+
*/
|
|
94
|
+
type SessionOutcome = "completed" | "abandoned" | "escalated" | (string & {});
|
|
95
|
+
/** Arguments for `outcome()` — signals what happened at the end of a session. */
|
|
96
|
+
type OutcomeInput = {
|
|
97
|
+
/** The agent this outcome is attributed to. */
|
|
98
|
+
firstflowAgentId: string;
|
|
99
|
+
/** The session/conversation id (same value passed on the LLM call). */
|
|
100
|
+
sessionId: string;
|
|
101
|
+
/** The end-user this session belongs to. */
|
|
102
|
+
userId: string;
|
|
103
|
+
/**
|
|
104
|
+
* What happened at the end of the session.
|
|
105
|
+
* Use 'completed' (user accomplished their goal), 'abandoned' (user left without finishing),
|
|
106
|
+
* 'escalated' (handed off to human support), or any custom label.
|
|
107
|
+
*/
|
|
108
|
+
outcome?: SessionOutcome;
|
|
109
|
+
/**
|
|
110
|
+
* What the user was trying to accomplish. Free-form label grouped in analytics.
|
|
111
|
+
* e.g. 'onboarding-setup', 'billing-question', 'how-to', 'troubleshooting'.
|
|
112
|
+
*/
|
|
113
|
+
intent?: string;
|
|
114
|
+
};
|
|
115
|
+
/** Arguments for `feedback()` — records thumbs-up or thumbs-down for a session. */
|
|
116
|
+
type FeedbackInput = {
|
|
117
|
+
/** The agent this feedback is attributed to. */
|
|
118
|
+
firstflowAgentId: string;
|
|
119
|
+
/** The session/conversation id this feedback belongs to. */
|
|
120
|
+
sessionId: string;
|
|
121
|
+
/** The end-user who submitted the feedback. */
|
|
122
|
+
userId: string;
|
|
123
|
+
/** 1 = thumbs up, -1 = thumbs down. */
|
|
124
|
+
rating: 1 | -1;
|
|
125
|
+
/** Optional free-text comment from the user. Max 500 chars. */
|
|
126
|
+
comment?: string;
|
|
127
|
+
/** Optional: the specific message the feedback applies to. */
|
|
128
|
+
messageId?: string;
|
|
129
|
+
};
|
|
130
|
+
/** Arguments for `track()`. */
|
|
131
|
+
type TrackArgs = {
|
|
132
|
+
/** The agent this event is attributed to. */
|
|
133
|
+
firstflowAgentId: string;
|
|
134
|
+
/** The end-user who triggered the event. */
|
|
135
|
+
userId: string;
|
|
136
|
+
event: string;
|
|
137
|
+
properties?: Record<string, unknown>;
|
|
138
|
+
};
|
|
139
|
+
/** Arguments for `identify()`. */
|
|
140
|
+
type IdentifyArgs = {
|
|
141
|
+
/** The agent this identity is attributed to. */
|
|
142
|
+
firstflowAgentId: string;
|
|
143
|
+
/** The end-user being identified. */
|
|
144
|
+
userId: string;
|
|
145
|
+
traits?: Record<string, unknown>;
|
|
146
|
+
};
|
|
147
|
+
/** Arguments for `trace()` — an agent-scoped trace with optional nested spans. */
|
|
148
|
+
type TraceArgs = TraceInput & {
|
|
149
|
+
/** The agent this trace is attributed to. */
|
|
150
|
+
firstflowAgentId: string;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Arguments for the standalone `observe()` — record a single conversation turn.
|
|
154
|
+
* For integrations that don't use the pre-wrapped `OpenAI` / `Anthropic`
|
|
155
|
+
* clients (e.g. the Vercel AI SDK, LangChain, or a custom gateway).
|
|
156
|
+
*/
|
|
157
|
+
type ObserveInput = {
|
|
158
|
+
/** The agent this message is attributed to. */
|
|
159
|
+
firstflowAgentId: string;
|
|
160
|
+
/** The session / conversation id this message belongs to. */
|
|
161
|
+
sessionId: string;
|
|
162
|
+
/** The end-user this message belongs to. */
|
|
163
|
+
userId: string;
|
|
164
|
+
role: "user" | "assistant" | "tool";
|
|
165
|
+
content: string;
|
|
166
|
+
recentMessages?: RecentMessage[];
|
|
167
|
+
properties?: Record<string, unknown>;
|
|
168
|
+
} & LlmCallMeta;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Record a single conversation turn. Use this when you can't use the
|
|
172
|
+
* pre-wrapped `OpenAI` / `Anthropic` clients (e.g. the Vercel AI SDK or a
|
|
173
|
+
* custom LLM gateway). Fire-and-forget — never throws.
|
|
174
|
+
*/
|
|
175
|
+
declare function observe(input: ObserveInput): void;
|
|
176
|
+
/** Signal what happened at the end of a session (completed / abandoned / escalated / custom). */
|
|
177
|
+
declare function outcome(input: OutcomeInput): void;
|
|
178
|
+
/** Record explicit thumbs-up (+1) or thumbs-down (-1) feedback for a session. */
|
|
179
|
+
declare function feedback(input: FeedbackInput): void;
|
|
180
|
+
/** Record an analytics event for a user under an agent. */
|
|
181
|
+
declare function track(args: TrackArgs): void;
|
|
182
|
+
/** Attach traits to a user under an agent. */
|
|
183
|
+
declare function identify(args: IdentifyArgs): void;
|
|
184
|
+
/** Record a trace (with optional nested spans) for detailed LLM observability. */
|
|
185
|
+
declare function trace(args: TraceArgs): void;
|
|
186
|
+
|
|
187
|
+
type WrapContext = {
|
|
188
|
+
apiKey: string;
|
|
189
|
+
baseUrl: string;
|
|
190
|
+
onAssistantComplete?: (args: ObserveArgs) => void;
|
|
191
|
+
/** Fired once per user turn (when the LLM request ends with a user message). */
|
|
192
|
+
onUserMessage?: (args: ObserveArgs) => void;
|
|
193
|
+
/** Fired when the LLM call throws. Re-throws after firing; never swallows errors. */
|
|
194
|
+
onError?: (args: Pick<ObserveArgs, "agentId" | "conversationId" | "userId"> & LlmCallMeta) => void;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Transparent `Proxy` over an OpenAI or Anthropic SDK client. Strips `firstflow`
|
|
198
|
+
* from request bodies, threads `firstflow.user_id` baggage for OTel, and fires
|
|
199
|
+
* observe hooks with full LLM metadata (model, tokens, latency, cost) once each
|
|
200
|
+
* call completes.
|
|
201
|
+
*/
|
|
202
|
+
declare function wrapClient<T extends object>(client: T, ctx: WrapContext): T;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Default Firstflow Cloud base URL. The host is intentional and matches
|
|
206
|
+
* production. To verify if a future regression is suspected:
|
|
207
|
+
*
|
|
208
|
+
* $ nslookup api.firstflow.app
|
|
209
|
+
*
|
|
210
|
+
* To override per-instance, pass `baseUrl` to `new Firstflow({...})`.
|
|
211
|
+
*/
|
|
212
|
+
declare const DEFAULT_FIRSTFLOW_BASE_URL = "https://api.firstflow.app";
|
|
213
|
+
declare const FIRSTFLOW_SERVER_PACKAGE_VERSION: "0.0.1-alpha.0";
|
|
214
|
+
|
|
215
|
+
type AccessibleAgent = {
|
|
216
|
+
id: string;
|
|
217
|
+
name: string | null;
|
|
218
|
+
};
|
|
219
|
+
type AccessibleAgentsResult = {
|
|
220
|
+
/** Agents this API key has access to. */
|
|
221
|
+
agents: AccessibleAgent[];
|
|
222
|
+
/**
|
|
223
|
+
* The workspace (Clerk org) that owns this API key.
|
|
224
|
+
* Returned by the backend from the API key's subject — no extra env var needed.
|
|
225
|
+
*/
|
|
226
|
+
workspaceId: string;
|
|
227
|
+
/**
|
|
228
|
+
* The workspace's browser-safe publishable key (`pk_live_...`).
|
|
229
|
+
* Pass directly as `publishableKey` on `<FirstflowProvider />`.
|
|
230
|
+
* May be `null` if the backend does not yet support this field.
|
|
231
|
+
*/
|
|
232
|
+
publishableKey: string | null;
|
|
233
|
+
};
|
|
234
|
+
type ListAccessibleAgentsOptions = {
|
|
235
|
+
/**
|
|
236
|
+
* Clerk-backed API key that carries `agent:<id>` scopes.
|
|
237
|
+
* Secret — never expose to the browser.
|
|
238
|
+
*/
|
|
239
|
+
apiKey: string;
|
|
240
|
+
/**
|
|
241
|
+
* Override the Firstflow Cloud base URL.
|
|
242
|
+
* Defaults to `https://api.firstflow.app`.
|
|
243
|
+
*/
|
|
244
|
+
baseUrl?: string;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Returns the agents this API key has access to, plus the workspace ID
|
|
248
|
+
* derived from the key itself — no extra env var required.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* const { agents, workspaceId } = await Firstflow.listAccessibleAgents({
|
|
252
|
+
* apiKey: process.env.FIRSTFLOW_API_KEY!,
|
|
253
|
+
* });
|
|
254
|
+
*/
|
|
255
|
+
declare function listAccessibleAgents(opts: ListAccessibleAgentsOptions): Promise<AccessibleAgentsResult>;
|
|
256
|
+
|
|
257
|
+
export { type AccessibleAgent, type AccessibleAgentsResult, DEFAULT_FIRSTFLOW_BASE_URL, FIRSTFLOW_SERVER_PACKAGE_VERSION, type FeedbackInput, type IdentifyArgs, type ListAccessibleAgentsOptions, type LlmCallMeta, type ObserveArgs, type ObserveInput, type OutcomeInput, type RecentMessage, type SessionOutcome, type SpanInput, type SpanType, type TraceArgs, type TraceInput, type TrackArgs, type WrapContext, feedback, identify, listAccessibleAgents, observe, outcome, trace, track, wrapClient };
|