@anvia/studio 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Indra Zulfi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @anvia/studio
2
+
3
+ Studio UI and HTTP runtime for Anvia agents.
4
+
5
+ Use this package to serve local agents over HTTP, inspect sessions and traces in the browser UI, and exercise tool approval workflows during development.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ pnpm add @anvia/studio @anvia/core
11
+ ```
12
+
13
+ In this monorepo, the package is available through the workspace:
14
+
15
+ ```sh
16
+ pnpm --filter @anvia/studio build
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```ts
22
+ import { AgentBuilder } from "@anvia/core";
23
+ import { OpenAIClient } from "@anvia/openai";
24
+ import { Studio } from "@anvia/studio";
25
+
26
+ const client = new OpenAIClient({
27
+ apiKey,
28
+ });
29
+
30
+ const agent = new AgentBuilder("support", client.completionModel())
31
+ .name("Support")
32
+ .description("Answers support questions.")
33
+ .instructions("Answer support questions clearly.")
34
+ .build();
35
+
36
+ new Studio([agent]).start({
37
+ port: 4021,
38
+ });
39
+ ```
40
+
41
+ Then open:
42
+
43
+ ```txt
44
+ http://localhost:4021/playground
45
+ ```
46
+
47
+ ## Session Storage
48
+
49
+ Studio uses a local SQLite store by default so sessions and traces can persist across process restarts. If you omit the port, Studio uses `RUNNER_PORT` and then falls back to `4021`.
50
+
51
+ Set `ANVIA_STUDIO_DB` to control the database path:
52
+
53
+ ```sh
54
+ ANVIA_STUDIO_DB=.anvia/studio.sqlite node ./dist/server.js
55
+ ```
56
+
57
+ ## Exports
58
+
59
+ - `Studio`
60
+ - `createSqliteSessionStore`
61
+ - Studio session, trace, approval, and runtime types
62
+
63
+ ## Development
64
+
65
+ ```sh
66
+ pnpm --filter @anvia/studio typecheck
67
+ pnpm --filter @anvia/studio test
68
+ pnpm --filter @anvia/studio build
69
+ ```
@@ -0,0 +1,344 @@
1
+ import { Message, JsonObject, AgentTraceOptions, PromptResponse, AgentStreamEvent, JsonValue, Usage, AgentTraceInfo, Agent, AgentObserver, AgentRunStartArgs, AgentRunObserver } from '@anvia/core';
2
+ import { Hono } from 'hono';
3
+
4
+ type StudioCapability = "agents" | "approvals" | "knowledge" | "observability" | "sessions" | "traces";
5
+ type StudioAgent = {
6
+ id: string;
7
+ agent: Agent;
8
+ name?: string;
9
+ description?: string;
10
+ quickPrompts?: string[];
11
+ metadata?: JsonObject;
12
+ };
13
+ type StudioAgentConfig = {
14
+ id: string;
15
+ name?: string;
16
+ description?: string;
17
+ quickPrompts: string[];
18
+ metadata?: JsonObject;
19
+ };
20
+ type StudioCapabilityConfig = {
21
+ enabled: boolean;
22
+ reason?: string;
23
+ };
24
+ type StudioConfig = {
25
+ id: string;
26
+ name?: string;
27
+ description?: string;
28
+ version?: string;
29
+ agents: StudioAgentConfig[];
30
+ chat: {
31
+ quickPrompts: Record<string, string[]>;
32
+ };
33
+ capabilities: Partial<Record<StudioCapability, StudioCapabilityConfig>>;
34
+ unsupportedCapabilities: StudioCapability[];
35
+ };
36
+ type StudioTranscriptChatEntry = {
37
+ entryId: number;
38
+ kind: "message";
39
+ role: "user" | "assistant";
40
+ text: string;
41
+ traceId?: string;
42
+ };
43
+ type StudioTranscriptReasoningEntry = {
44
+ entryId: number;
45
+ kind: "reasoning";
46
+ reasoningId?: string;
47
+ text: string;
48
+ };
49
+ type StudioTranscriptToolEntry = {
50
+ entryId: number;
51
+ kind: "tool";
52
+ toolName: string;
53
+ callId?: string;
54
+ args?: string;
55
+ result?: string;
56
+ approval?: StudioToolApprovalTranscript;
57
+ question?: StudioToolQuestionTranscript;
58
+ };
59
+ type StudioTranscriptEntry = StudioTranscriptChatEntry | StudioTranscriptReasoningEntry | StudioTranscriptToolEntry;
60
+ type StudioSessionSummary = {
61
+ id: string;
62
+ agentId: string;
63
+ title?: string;
64
+ createdAt: string;
65
+ updatedAt: string;
66
+ messageCount: number;
67
+ metadata?: JsonObject;
68
+ };
69
+ type StudioSession = StudioSessionSummary & {
70
+ messages: Message[];
71
+ transcript: StudioTranscriptEntry[];
72
+ };
73
+ type StudioSessionCreateInput = {
74
+ id: string;
75
+ agentId: string;
76
+ title?: string;
77
+ metadata?: JsonObject;
78
+ };
79
+ type StudioSessionListOptions = {
80
+ agentId?: string;
81
+ limit: number;
82
+ };
83
+ type StudioSessionAppendInput = {
84
+ id: string;
85
+ title?: string;
86
+ messages: Message[];
87
+ transcript: StudioTranscriptEntry[];
88
+ };
89
+ type StudioSessionStore = {
90
+ readonly kind?: string;
91
+ listSessions(options: StudioSessionListOptions): StudioSessionSummary[] | Promise<StudioSessionSummary[]>;
92
+ createSession(input: StudioSessionCreateInput): StudioSessionSummary | Promise<StudioSessionSummary>;
93
+ getSession(id: string): StudioSession | undefined | Promise<StudioSession | undefined>;
94
+ appendSessionRun(input: StudioSessionAppendInput): StudioSession | undefined | Promise<StudioSession | undefined>;
95
+ deleteSession?(id: string): boolean | Promise<boolean>;
96
+ };
97
+ type StudioTraceStatus = "running" | "success" | "error";
98
+ type StudioTraceObservationKind = "generation" | "tool";
99
+ type StudioTraceObservation = {
100
+ id: string;
101
+ kind: StudioTraceObservationKind;
102
+ name: string;
103
+ status: StudioTraceStatus;
104
+ turn: number;
105
+ startedAt: string;
106
+ endedAt?: string;
107
+ durationMs?: number;
108
+ input?: JsonValue;
109
+ output?: JsonValue;
110
+ error?: JsonValue;
111
+ metadata?: JsonObject;
112
+ };
113
+ type StudioTraceSummary = {
114
+ id: string;
115
+ sessionId: string;
116
+ name?: string;
117
+ status: StudioTraceStatus;
118
+ startedAt: string;
119
+ endedAt?: string;
120
+ durationMs?: number;
121
+ output?: string;
122
+ error?: JsonValue;
123
+ usage?: Usage;
124
+ metadata?: JsonObject;
125
+ observationCount: number;
126
+ };
127
+ type StudioTrace = StudioTraceSummary & {
128
+ trace?: AgentTraceInfo;
129
+ input?: JsonValue;
130
+ observations: StudioTraceObservation[];
131
+ };
132
+ type StudioTraceListOptions = {
133
+ limit: number;
134
+ agentId?: string;
135
+ sessionId?: string;
136
+ status?: StudioTraceStatus;
137
+ };
138
+ type StudioSessionTraceListOptions = {
139
+ sessionId: string;
140
+ limit: number;
141
+ };
142
+ type StudioTraceStore = {
143
+ readonly kind?: string;
144
+ listTraces?(options: StudioTraceListOptions): StudioTraceSummary[] | Promise<StudioTraceSummary[]>;
145
+ listSessionTraces(options: StudioSessionTraceListOptions): StudioTraceSummary[] | Promise<StudioTraceSummary[]>;
146
+ getTrace(id: string): StudioTrace | undefined | Promise<StudioTrace | undefined>;
147
+ saveTrace(trace: StudioTrace): StudioTrace | Promise<StudioTrace>;
148
+ };
149
+ type StudioKnowledgeSourceKind = "static_context" | "dynamic_context" | "dynamic_tools";
150
+ type StudioKnowledgeSourceSummary = {
151
+ kind: StudioKnowledgeSourceKind;
152
+ count: number;
153
+ };
154
+ type StudioStaticKnowledgeDocument = {
155
+ id: string;
156
+ text: string;
157
+ additionalProps?: JsonObject;
158
+ };
159
+ type StudioKnowledgeEvidenceDocument = {
160
+ id?: string;
161
+ text?: string;
162
+ additionalProps?: JsonObject;
163
+ };
164
+ type StudioKnowledgeEvidence = {
165
+ traceId: string;
166
+ sessionId: string;
167
+ observationId: string;
168
+ observationName: string;
169
+ turn: number;
170
+ startedAt: string;
171
+ query?: string;
172
+ documentCount: number;
173
+ toolCount: number;
174
+ documents: StudioKnowledgeEvidenceDocument[];
175
+ tools: string[];
176
+ };
177
+ type StudioAgentKnowledgeConfig = {
178
+ agentId: string;
179
+ agentName?: string;
180
+ sources: StudioKnowledgeSourceSummary[];
181
+ staticContext: StudioStaticKnowledgeDocument[];
182
+ };
183
+ type StudioKnowledgeSummary = {
184
+ agents: StudioAgentKnowledgeConfig[];
185
+ evidence: StudioKnowledgeEvidence[];
186
+ };
187
+ type StudioStores = {
188
+ sessions?: StudioSessionStore | false;
189
+ traces?: StudioTraceStore;
190
+ };
191
+ type StudioUiOptions = {
192
+ path?: string;
193
+ rootRoutes?: boolean;
194
+ title?: string;
195
+ redirectRoot?: boolean;
196
+ clientScript?: string;
197
+ protectShell?: boolean;
198
+ };
199
+ type StudioOptions = {
200
+ quickPrompts?: Record<string, string[]>;
201
+ };
202
+ type StudioServeOptions = {
203
+ port?: number;
204
+ hostname?: string;
205
+ log?: boolean;
206
+ };
207
+ type StudioToolApprovalDecision = {
208
+ approved: boolean;
209
+ reason?: string;
210
+ };
211
+ type StudioToolApprovalStatus = "pending" | "approved" | "rejected" | "timed_out";
212
+ type StudioToolApproval = {
213
+ id: string;
214
+ runId: string;
215
+ agentId: string;
216
+ sessionId?: string;
217
+ toolName: string;
218
+ callId?: string;
219
+ internalCallId: string;
220
+ args: string;
221
+ status: StudioToolApprovalStatus;
222
+ requestedAt: string;
223
+ resolvedAt?: string;
224
+ reason?: string;
225
+ };
226
+ type StudioToolApprovalTranscript = {
227
+ id: string;
228
+ status: StudioToolApprovalStatus;
229
+ requestedAt: string;
230
+ resolvedAt?: string;
231
+ reason?: string;
232
+ };
233
+ type StudioToolApprovalRequestEvent = {
234
+ type: "tool_approval_request";
235
+ approval: StudioToolApproval;
236
+ };
237
+ type StudioToolApprovalResultEvent = {
238
+ type: "tool_approval_result";
239
+ approval: StudioToolApproval;
240
+ };
241
+ type StudioToolQuestionChoice = {
242
+ label: string;
243
+ value: string;
244
+ };
245
+ type StudioToolQuestionPrompt = {
246
+ id: string;
247
+ question: string;
248
+ choices: StudioToolQuestionChoice[];
249
+ };
250
+ type StudioToolQuestionAnswer = {
251
+ questionId: string;
252
+ answer: string;
253
+ choice?: string;
254
+ custom?: boolean;
255
+ };
256
+ type StudioToolQuestionStatus = "pending" | "answered";
257
+ type StudioToolQuestion = {
258
+ id: string;
259
+ runId: string;
260
+ agentId: string;
261
+ sessionId?: string;
262
+ toolName: string;
263
+ callId?: string;
264
+ internalCallId: string;
265
+ args: string;
266
+ questions: StudioToolQuestionPrompt[];
267
+ status: StudioToolQuestionStatus;
268
+ requestedAt: string;
269
+ answeredAt?: string;
270
+ answers?: StudioToolQuestionAnswer[];
271
+ };
272
+ type StudioToolQuestionTranscript = {
273
+ id: string;
274
+ status: StudioToolQuestionStatus;
275
+ requestedAt: string;
276
+ answeredAt?: string;
277
+ questions: StudioToolQuestionPrompt[];
278
+ answers?: StudioToolQuestionAnswer[];
279
+ };
280
+ type StudioToolQuestionRequestEvent = {
281
+ type: "tool_question_request";
282
+ question: StudioToolQuestion;
283
+ };
284
+ type StudioToolQuestionResultEvent = {
285
+ type: "tool_question_result";
286
+ question: StudioToolQuestion;
287
+ };
288
+ type AgentRunRequest = {
289
+ message: string | Message;
290
+ history?: Message[];
291
+ sessionId?: string;
292
+ stream?: boolean;
293
+ maxTurns?: number;
294
+ toolConcurrency?: number;
295
+ metadata?: JsonObject;
296
+ trace?: AgentTraceOptions;
297
+ };
298
+ type AgentRunResponse = PromptResponse;
299
+ type AgentRunStreamEvent = AgentStreamEvent | StudioToolApprovalRequestEvent | StudioToolApprovalResultEvent | StudioToolQuestionRequestEvent | StudioToolQuestionResultEvent;
300
+ type StudioErrorCode = "bad_request" | "conflict" | "not_found" | "unsupported_capability" | "internal_error";
301
+ type StudioErrorResponse = {
302
+ error: {
303
+ code: StudioErrorCode;
304
+ message: string;
305
+ details?: JsonValue;
306
+ };
307
+ };
308
+ type AnviaStudio = {
309
+ readonly app: Hono;
310
+ fetch(request: Request): Response | Promise<Response>;
311
+ config(): StudioConfig;
312
+ close(): void;
313
+ };
314
+
315
+ type StudioTraceObserverOptions = {
316
+ store: StudioTraceStore | (() => StudioTraceStore | undefined) | undefined;
317
+ };
318
+ declare class StudioTraceObserver implements AgentObserver {
319
+ private readonly options;
320
+ constructor(options: StudioTraceObserverOptions);
321
+ startRun(args: AgentRunStartArgs): AgentRunObserver;
322
+ private store;
323
+ }
324
+
325
+ declare class Studio implements AnviaStudio {
326
+ private readonly options;
327
+ private studio;
328
+ private server;
329
+ private sigintHandler;
330
+ constructor(agents?: Agent[], options?: StudioOptions);
331
+ get app(): Hono;
332
+ fetch(request: Request): Response | Promise<Response>;
333
+ config(): StudioConfig;
334
+ traceObserver(): StudioTraceObserver;
335
+ start(serveOptions?: StudioServeOptions): this;
336
+ close(): void;
337
+ }
338
+
339
+ type SqliteSessionStoreOptions = {
340
+ path?: string;
341
+ };
342
+ declare function createSqliteSessionStore(options?: SqliteSessionStoreOptions): StudioSessionStore & StudioTraceStore;
343
+
344
+ export { type AgentRunRequest, type AgentRunResponse, type AgentRunStreamEvent, type AnviaStudio, type SqliteSessionStoreOptions, Studio, type StudioAgent, type StudioAgentConfig, type StudioAgentKnowledgeConfig, type StudioCapability, type StudioCapabilityConfig, type StudioConfig, type StudioErrorCode, type StudioErrorResponse, type StudioKnowledgeEvidence, type StudioKnowledgeEvidenceDocument, type StudioKnowledgeSourceKind, type StudioKnowledgeSourceSummary, type StudioKnowledgeSummary, type StudioOptions, type StudioServeOptions, type StudioSession, type StudioSessionAppendInput, type StudioSessionCreateInput, type StudioSessionListOptions, type StudioSessionStore, type StudioSessionSummary, type StudioSessionTraceListOptions, type StudioStaticKnowledgeDocument, type StudioStores, type StudioToolApproval, type StudioToolApprovalDecision, type StudioToolApprovalRequestEvent, type StudioToolApprovalResultEvent, type StudioToolApprovalStatus, type StudioToolApprovalTranscript, type StudioToolQuestion, type StudioToolQuestionAnswer, type StudioToolQuestionChoice, type StudioToolQuestionPrompt, type StudioToolQuestionRequestEvent, type StudioToolQuestionResultEvent, type StudioToolQuestionStatus, type StudioToolQuestionTranscript, type StudioTrace, type StudioTraceListOptions, type StudioTraceObservation, type StudioTraceObservationKind, StudioTraceObserver, type StudioTraceObserverOptions, type StudioTraceStatus, type StudioTraceStore, type StudioTraceSummary, type StudioTranscriptChatEntry, type StudioTranscriptEntry, type StudioTranscriptReasoningEntry, type StudioTranscriptToolEntry, type StudioUiOptions, createSqliteSessionStore };