@agentuity/runtime 0.1.23 → 0.1.25
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/dist/_standalone.d.ts.map +1 -1
- package/dist/_standalone.js +11 -10
- package/dist/_standalone.js.map +1 -1
- package/dist/_tokens.d.ts.map +1 -1
- package/dist/_tokens.js +9 -8
- package/dist/_tokens.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +228 -196
- package/dist/agent.js.map +1 -1
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +29 -6
- package/dist/middleware.js.map +1 -1
- package/dist/otel/fetch.js +1 -1
- package/dist/otel/fetch.js.map +1 -1
- package/dist/otel/otel.d.ts.map +1 -1
- package/dist/otel/otel.js +2 -29
- package/dist/otel/otel.js.map +1 -1
- package/dist/services/evalrun/http.d.ts.map +1 -1
- package/dist/services/evalrun/http.js +31 -2
- package/dist/services/evalrun/http.js.map +1 -1
- package/dist/services/local/keyvalue.d.ts.map +1 -1
- package/dist/services/local/keyvalue.js.map +1 -1
- package/dist/services/local/vector.d.ts.map +1 -1
- package/dist/services/local/vector.js.map +1 -1
- package/dist/services/session/http.d.ts.map +1 -1
- package/dist/services/session/http.js +58 -19
- package/dist/services/session/http.js.map +1 -1
- package/package.json +7 -9
- package/src/_standalone.ts +36 -10
- package/src/_tokens.ts +14 -12
- package/src/agent.ts +260 -259
- package/src/middleware.ts +39 -6
- package/src/otel/fetch.ts +1 -1
- package/src/otel/otel.ts +2 -30
- package/src/services/evalrun/http.ts +45 -10
- package/src/services/local/keyvalue.ts +3 -1
- package/src/services/local/vector.ts +3 -1
- package/src/services/session/http.ts +78 -33
package/src/middleware.ts
CHANGED
|
@@ -290,7 +290,7 @@ export function createOtelMiddleware() {
|
|
|
290
290
|
await context.with(extractedContext, async (): Promise<void> => {
|
|
291
291
|
const tracer = trace.getTracer('http-server');
|
|
292
292
|
await tracer.startActiveSpan(
|
|
293
|
-
|
|
293
|
+
`${method} ${url.pathname}`,
|
|
294
294
|
{
|
|
295
295
|
kind: SpanKind.SERVER,
|
|
296
296
|
attributes: {
|
|
@@ -373,8 +373,13 @@ export function createOtelMiddleware() {
|
|
|
373
373
|
}
|
|
374
374
|
|
|
375
375
|
// Factor out finalization logic so it can run synchronously or deferred
|
|
376
|
-
const finalizeSession = async (statusCode?: number) => {
|
|
377
|
-
internal.info(
|
|
376
|
+
const finalizeSession = async (statusCode?: number, error?: string) => {
|
|
377
|
+
internal.info(
|
|
378
|
+
'[session] saving session %s (thread: %s) (error: %s)',
|
|
379
|
+
sessionId,
|
|
380
|
+
thread.id,
|
|
381
|
+
error
|
|
382
|
+
);
|
|
378
383
|
await sessionProvider.save(session);
|
|
379
384
|
internal.info('[session] session saved, now saving thread');
|
|
380
385
|
await threadProvider.save(thread);
|
|
@@ -397,12 +402,16 @@ export function createOtelMiddleware() {
|
|
|
397
402
|
id: sessionId,
|
|
398
403
|
threadId: isEmpty ? null : thread.id,
|
|
399
404
|
statusCode: statusCode ?? c.res?.status ?? 200,
|
|
405
|
+
error,
|
|
400
406
|
agentIds: agentIds?.length ? agentIds : undefined,
|
|
401
407
|
userData,
|
|
402
408
|
});
|
|
403
409
|
internal.info('[session] session complete event sent');
|
|
404
410
|
} catch (ex) {
|
|
405
|
-
internal.info(
|
|
411
|
+
internal.info(
|
|
412
|
+
'[session] session complete event failed: %s',
|
|
413
|
+
ex instanceof Error ? ex.message : ex
|
|
414
|
+
);
|
|
406
415
|
// Silently ignore session complete errors - don't block response
|
|
407
416
|
}
|
|
408
417
|
}
|
|
@@ -419,6 +428,13 @@ export function createOtelMiddleware() {
|
|
|
419
428
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
420
429
|
const isStreaming = Boolean((c as any).get(IS_STREAMING_RESPONSE_KEY));
|
|
421
430
|
|
|
431
|
+
// Check if Hono caught an error (c.error is set by Hono's error handler)
|
|
432
|
+
// or if the response status indicates an error
|
|
433
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
434
|
+
const honoError = (c as any).error as Error | undefined;
|
|
435
|
+
const responseStatus = c.res?.status ?? 200;
|
|
436
|
+
const isError = honoError || responseStatus >= 500;
|
|
437
|
+
|
|
422
438
|
if (isStreaming && streamDone) {
|
|
423
439
|
// Defer session/thread saving until stream completes
|
|
424
440
|
// This ensures thread state changes made during streaming are persisted
|
|
@@ -445,8 +461,21 @@ export function createOtelMiddleware() {
|
|
|
445
461
|
});
|
|
446
462
|
|
|
447
463
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
464
|
+
} else if (isError) {
|
|
465
|
+
// Hono caught an error or response is 5xx - report as error
|
|
466
|
+
const errorMessage = honoError
|
|
467
|
+
? (honoError.stack ?? honoError.message)
|
|
468
|
+
: `HTTP ${responseStatus}`;
|
|
469
|
+
span.setStatus({
|
|
470
|
+
code: SpanStatusCode.ERROR,
|
|
471
|
+
message: honoError?.message ?? errorMessage,
|
|
472
|
+
});
|
|
473
|
+
if (honoError) {
|
|
474
|
+
span.recordException(honoError);
|
|
475
|
+
}
|
|
476
|
+
await finalizeSession(responseStatus, errorMessage);
|
|
448
477
|
} else {
|
|
449
|
-
// Non-streaming: save session/thread synchronously
|
|
478
|
+
// Non-streaming success: save session/thread synchronously
|
|
450
479
|
await finalizeSession();
|
|
451
480
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
452
481
|
}
|
|
@@ -454,10 +483,14 @@ export function createOtelMiddleware() {
|
|
|
454
483
|
if (ex instanceof Error) {
|
|
455
484
|
span.recordException(ex);
|
|
456
485
|
}
|
|
486
|
+
const errorMessage = ex instanceof Error ? (ex.stack ?? ex.message) : String(ex);
|
|
457
487
|
span.setStatus({
|
|
458
488
|
code: SpanStatusCode.ERROR,
|
|
459
|
-
message:
|
|
489
|
+
message: ex instanceof Error ? ex.message : String(ex),
|
|
460
490
|
});
|
|
491
|
+
|
|
492
|
+
await finalizeSession(500, errorMessage);
|
|
493
|
+
|
|
461
494
|
throw ex;
|
|
462
495
|
} finally {
|
|
463
496
|
const headers: Record<string, string> = {};
|
package/src/otel/fetch.ts
CHANGED
package/src/otel/otel.ts
CHANGED
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
|
|
25
25
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
26
26
|
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
|
|
27
|
-
import { initialize } from '@traceloop/node-server-sdk';
|
|
28
27
|
import type { Logger } from '../logger';
|
|
29
28
|
import { ConsoleLogRecordExporter, DebugSpanExporter } from './console';
|
|
30
29
|
import { instrumentFetch } from './fetch';
|
|
@@ -308,35 +307,8 @@ export function registerOtel(config: OtelConfig): OtelResponse {
|
|
|
308
307
|
instrumentationSDK.start();
|
|
309
308
|
hostMetrics?.start();
|
|
310
309
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
const orgId = config.orgId || '';
|
|
314
|
-
const appName = `${orgId}:${projectName}`;
|
|
315
|
-
|
|
316
|
-
const traceloopHeaders: Record<string, string> = {};
|
|
317
|
-
if (bearerToken) {
|
|
318
|
-
traceloopHeaders.Authorization = `Bearer ${bearerToken}`;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
initialize({
|
|
322
|
-
appName,
|
|
323
|
-
baseUrl: url,
|
|
324
|
-
headers: traceloopHeaders,
|
|
325
|
-
disableBatch: devmode,
|
|
326
|
-
propagator,
|
|
327
|
-
silenceInitializationMessage: true,
|
|
328
|
-
traceloopSyncEnabled: false,
|
|
329
|
-
tracingEnabled: false, // Disable traceloop's own tracing (equivalent to Python's telemetryEnabled: false)
|
|
330
|
-
// Note: JavaScript SDK doesn't support resourceAttributes like Python
|
|
331
|
-
});
|
|
332
|
-
logger.debug(`Telemetry initialized with app_name: ${appName}`);
|
|
333
|
-
logger.debug('Telemetry configured successfully');
|
|
334
|
-
logger.debug('Sending telemetry data to %s', url);
|
|
335
|
-
} catch (error) {
|
|
336
|
-
logger.warn('Telemetry not available, skipping automatic instrumentation', {
|
|
337
|
-
error: error instanceof Error ? error.message : String(error),
|
|
338
|
-
});
|
|
339
|
-
}
|
|
310
|
+
logger.debug('Telemetry configured successfully');
|
|
311
|
+
logger.debug('Sending telemetry data to %s', url);
|
|
340
312
|
running = true;
|
|
341
313
|
}
|
|
342
314
|
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
type Logger,
|
|
14
14
|
StructuredError,
|
|
15
15
|
} from '@agentuity/core';
|
|
16
|
+
import { context, trace, SpanStatusCode } from '@opentelemetry/api';
|
|
16
17
|
import { internal } from '../../logger/internal';
|
|
17
18
|
|
|
18
19
|
const EvalRunResponseError = StructuredError('EvalRunResponseError');
|
|
@@ -37,6 +38,10 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
37
38
|
* @param event EvalRunStartEvent
|
|
38
39
|
*/
|
|
39
40
|
async start(event: EvalRunStartEvent): Promise<void> {
|
|
41
|
+
const tracer = trace.getTracer('evalrun');
|
|
42
|
+
const currentContext = context.active();
|
|
43
|
+
const span = tracer.startSpan('Eval Start', {}, currentContext);
|
|
44
|
+
|
|
40
45
|
const endpoint = '/evalrun/2025-03-17';
|
|
41
46
|
const fullUrl = `${this.baseUrl}${endpoint}`;
|
|
42
47
|
|
|
@@ -57,18 +62,24 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
57
62
|
internal.info('[EVALRUN HTTP] ============================================');
|
|
58
63
|
|
|
59
64
|
try {
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const spanContext = trace.setSpan(currentContext, span);
|
|
66
|
+
const resp = await context.with(spanContext, () =>
|
|
67
|
+
this.apiClient.post(
|
|
68
|
+
endpoint,
|
|
69
|
+
payload,
|
|
70
|
+
APIResponseSchemaNoData(),
|
|
71
|
+
EvalRunStartEventDelayedSchema
|
|
72
|
+
)
|
|
65
73
|
);
|
|
74
|
+
|
|
66
75
|
if (resp.success) {
|
|
67
76
|
this.logger.debug('[EVALRUN HTTP] Start event sent successfully: %s', event.id);
|
|
77
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
68
78
|
return;
|
|
69
79
|
}
|
|
70
80
|
const errorMsg = resp.message || 'Unknown error';
|
|
71
81
|
this.logger.error('[EVALRUN HTTP] Start event failed: %s, error: %s', event.id, errorMsg);
|
|
82
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: errorMsg });
|
|
72
83
|
throw new EvalRunResponseError({ message: errorMsg });
|
|
73
84
|
} catch (error) {
|
|
74
85
|
this.logger.error(
|
|
@@ -86,7 +97,14 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
86
97
|
JSON.stringify(error.issues, null, 2)
|
|
87
98
|
);
|
|
88
99
|
}
|
|
100
|
+
span.recordException(error as Error);
|
|
101
|
+
span.setStatus({
|
|
102
|
+
code: SpanStatusCode.ERROR,
|
|
103
|
+
message: error instanceof Error ? error.message : String(error),
|
|
104
|
+
});
|
|
89
105
|
throw error;
|
|
106
|
+
} finally {
|
|
107
|
+
span.end();
|
|
90
108
|
}
|
|
91
109
|
}
|
|
92
110
|
|
|
@@ -96,6 +114,10 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
96
114
|
* @param event EvalRunCompleteEvent
|
|
97
115
|
*/
|
|
98
116
|
async complete(event: EvalRunCompleteEvent): Promise<void> {
|
|
117
|
+
const tracer = trace.getTracer('evalrun');
|
|
118
|
+
const currentContext = context.active();
|
|
119
|
+
const span = tracer.startSpan('Eval End', {}, currentContext);
|
|
120
|
+
|
|
99
121
|
const endpoint = '/evalrun/2025-03-17';
|
|
100
122
|
const fullUrl = `${this.baseUrl}${endpoint}`;
|
|
101
123
|
this.logger.debug('[EVALRUN HTTP] Sending eval run complete event: %s', event.id);
|
|
@@ -103,14 +125,19 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
103
125
|
this.logger.debug('[EVALRUN HTTP] Base URL: %s', this.baseUrl);
|
|
104
126
|
|
|
105
127
|
try {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
128
|
+
const spanContext = trace.setSpan(currentContext, span);
|
|
129
|
+
const resp = await context.with(spanContext, () =>
|
|
130
|
+
this.apiClient.put(
|
|
131
|
+
endpoint,
|
|
132
|
+
{ ...event, timestamp: Date.now() },
|
|
133
|
+
APIResponseSchemaNoData(),
|
|
134
|
+
EvalRunCompleteEventDelayedSchema
|
|
135
|
+
)
|
|
111
136
|
);
|
|
137
|
+
|
|
112
138
|
if (resp.success) {
|
|
113
139
|
this.logger.debug('[EVALRUN HTTP] Complete event sent successfully: %s', event.id);
|
|
140
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
114
141
|
return;
|
|
115
142
|
}
|
|
116
143
|
const errorMsg = resp.message || 'Unknown error';
|
|
@@ -119,6 +146,7 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
119
146
|
event.id,
|
|
120
147
|
errorMsg
|
|
121
148
|
);
|
|
149
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: errorMsg });
|
|
122
150
|
throw new EvalRunResponseError({ message: errorMsg });
|
|
123
151
|
} catch (error) {
|
|
124
152
|
this.logger.error(
|
|
@@ -126,7 +154,14 @@ export class HTTPEvalRunEventProvider implements EvalRunEventProvider {
|
|
|
126
154
|
event.id,
|
|
127
155
|
error instanceof Error ? error.message : String(error)
|
|
128
156
|
);
|
|
157
|
+
span.recordException(error as Error);
|
|
158
|
+
span.setStatus({
|
|
159
|
+
code: SpanStatusCode.ERROR,
|
|
160
|
+
message: error instanceof Error ? error.message : String(error),
|
|
161
|
+
});
|
|
129
162
|
throw error;
|
|
163
|
+
} finally {
|
|
164
|
+
span.end();
|
|
130
165
|
}
|
|
131
166
|
}
|
|
132
167
|
}
|
|
@@ -137,7 +137,9 @@ export class LocalKeyValueStorage implements KeyValueStorage {
|
|
|
137
137
|
throw new Error('getStats not implemented for local storage');
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
async getAllStats(
|
|
140
|
+
async getAllStats(
|
|
141
|
+
_params?: GetAllStatsParams
|
|
142
|
+
): Promise<Record<string, KeyValueStats> | KeyValueStatsPaginated> {
|
|
141
143
|
throw new Error('getAllStats not implemented for local storage');
|
|
142
144
|
}
|
|
143
145
|
|
|
@@ -347,7 +347,9 @@ export class LocalVectorStorage implements VectorStorage {
|
|
|
347
347
|
};
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
async getAllStats(
|
|
350
|
+
async getAllStats(
|
|
351
|
+
_params?: VectorGetAllStatsParams
|
|
352
|
+
): Promise<Record<string, VectorNamespaceStats> | VectorStatsPaginated> {
|
|
351
353
|
const query = this.#db.query(`
|
|
352
354
|
SELECT name, embedding, document
|
|
353
355
|
FROM vector_storage
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
type Logger,
|
|
9
9
|
StructuredError,
|
|
10
10
|
} from '@agentuity/core';
|
|
11
|
+
import { context, trace, SpanStatusCode } from '@opentelemetry/api';
|
|
11
12
|
import { internal } from '../../logger/internal';
|
|
12
13
|
|
|
13
14
|
const SessionResponseError = StructuredError('SessionResponseError');
|
|
@@ -54,22 +55,44 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
const tracer = trace.getTracer('session');
|
|
59
|
+
const currentContext = context.active();
|
|
60
|
+
const span = tracer.startSpan('Session Start', {}, currentContext);
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
internal.info('[session-http] sending start event: %s', event.id);
|
|
64
|
+
this.logger.debug('Sending session start event: %s', event.id);
|
|
65
|
+
|
|
66
|
+
const spanContext = trace.setSpan(currentContext, span);
|
|
67
|
+
const resp = await context.with(spanContext, () =>
|
|
68
|
+
this.apiClient.post(
|
|
69
|
+
'/session/2025-03-17',
|
|
70
|
+
{ ...event, timestamp: Date.now() },
|
|
71
|
+
APIResponseSchemaNoData(),
|
|
72
|
+
SessionStartEventDelayedSchema
|
|
73
|
+
)
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
if (resp.success) {
|
|
77
|
+
internal.info('[session-http] start event sent successfully: %s', event.id);
|
|
78
|
+
this.logger.debug('Session start event sent successfully: %s', event.id);
|
|
79
|
+
this.startedSessions.add(event.id);
|
|
80
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
internal.info('[session-http] start event failed: %s - %s', event.id, resp.message);
|
|
84
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: resp.message });
|
|
85
|
+
throw new SessionResponseError({ message: resp.message });
|
|
86
|
+
} catch (error) {
|
|
87
|
+
span.recordException(error as Error);
|
|
88
|
+
span.setStatus({
|
|
89
|
+
code: SpanStatusCode.ERROR,
|
|
90
|
+
message: error instanceof Error ? error.message : String(error),
|
|
91
|
+
});
|
|
92
|
+
throw error;
|
|
93
|
+
} finally {
|
|
94
|
+
span.end();
|
|
70
95
|
}
|
|
71
|
-
internal.info('[session-http] start event failed: %s - %s', event.id, resp.message);
|
|
72
|
-
throw new SessionResponseError({ message: resp.message });
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
/**
|
|
@@ -91,24 +114,46 @@ export class HTTPSessionEventProvider implements SessionEventProvider {
|
|
|
91
114
|
}
|
|
92
115
|
this.startedSessions.delete(event.id);
|
|
93
116
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
const tracer = trace.getTracer('session');
|
|
118
|
+
const currentContext = context.active();
|
|
119
|
+
const span = tracer.startSpan('Session End', {}, currentContext);
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
internal.info(
|
|
123
|
+
'[session-http] sending complete event: %s, userData: %s',
|
|
124
|
+
event.id,
|
|
125
|
+
event.userData ? `${event.userData.length} bytes` : 'none'
|
|
126
|
+
);
|
|
127
|
+
this.logger.debug('Sending session complete event: %s', event.id);
|
|
128
|
+
|
|
129
|
+
const spanContext = trace.setSpan(currentContext, span);
|
|
130
|
+
const resp = await context.with(spanContext, () =>
|
|
131
|
+
this.apiClient.put(
|
|
132
|
+
'/session/2025-03-17',
|
|
133
|
+
{ ...event, timestamp: Date.now() },
|
|
134
|
+
APIResponseSchemaNoData(),
|
|
135
|
+
SessionCompleteEventDelayedSchema
|
|
136
|
+
)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (resp.success) {
|
|
140
|
+
internal.info('[session-http] complete event sent successfully: %s', event.id);
|
|
141
|
+
this.logger.debug('Session complete event sent successfully: %s', event.id);
|
|
142
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
internal.info('[session-http] complete event failed: %s - %s', event.id, resp.message);
|
|
146
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: resp.message });
|
|
147
|
+
throw new SessionResponseError({ message: resp.message });
|
|
148
|
+
} catch (error) {
|
|
149
|
+
span.recordException(error as Error);
|
|
150
|
+
span.setStatus({
|
|
151
|
+
code: SpanStatusCode.ERROR,
|
|
152
|
+
message: error instanceof Error ? error.message : String(error),
|
|
153
|
+
});
|
|
154
|
+
throw error;
|
|
155
|
+
} finally {
|
|
156
|
+
span.end();
|
|
110
157
|
}
|
|
111
|
-
internal.info('[session-http] complete event failed: %s - %s', event.id, resp.message);
|
|
112
|
-
throw new SessionResponseError({ message: resp.message });
|
|
113
158
|
}
|
|
114
159
|
}
|