Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/types/base.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* JSON-serializable value type.
* Represents any value that can be serialized to JSON.
*/
export type JsonValue =
| string
| number
| boolean
| null
| JsonValue[]
| { [key: string]: JsonValue };

/**
* JSON-serializable object type.
* Allows undefined values which will be omitted during JSON serialization.
*/
export type JsonObject = { [key: string]: JsonValue | undefined };

/**
* JSON-serializable array type.
*/
export type JsonArray = JsonValue[];
5 changes: 2 additions & 3 deletions src/types/logging/logger.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ import type {
ToolSpan,
WorkflowSpan,
AgentSpan,
Event,
JsonObject
Event
} from './span.types';
import type {
LlmSpanAllowedInputType,
LlmSpanAllowedOutputType,
RetrieverSpanAllowedOutputType
} from './step.types';
import type { AgentType, Payload, ProtectResponse } from '../new-api.types';

import type { JsonObject } from '../base.types';
export interface GalileoLoggerConfig {
projectName?: string;
logStreamName?: string;
Expand Down
31 changes: 7 additions & 24 deletions src/types/logging/span.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,7 @@ import {
import type { Document } from '../document.types';
import type { MetricValueType } from '../metrics.types';
import { AgentType } from '../new-api.types';

/**
* JSON-serializable value type.
* Represents any value that can be serialized to JSON.
*/
export type JsonValue =
| string
| number
| boolean
| null
| JsonValue[]
| { [key: string]: JsonValue };

/**
* JSON-serializable object type.
* Allows undefined values which will be omitted during JSON serialization.
*/
export type JsonObject = { [key: string]: JsonValue | undefined };

/**
* JSON-serializable array type.
*/
export type JsonArray = JsonValue[];
import type { JsonValue, JsonObject, JsonArray } from '../base.types';

/**
* Types of events that can appear in reasoning/multi-turn model outputs.
Expand Down Expand Up @@ -482,7 +460,12 @@ export class ToolSpan extends BaseStep {
}

// Type for all span types
export type Span = WorkflowSpan | LlmSpan | RetrieverSpan | ToolSpan;
export type Span =
| WorkflowSpan
| AgentSpan
| LlmSpan
| RetrieverSpan
| ToolSpan;

/**
* Type guard to validate if a value is a valid AgentType
Expand Down
2 changes: 1 addition & 1 deletion src/types/logging/step.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { components } from '../api.types';
import { Document } from '../document.types';
import { isMessage, type Message } from '../message.types';
import type { MetricValueType } from '../metrics.types';
import type { JsonArray } from './span.types';
import type { JsonArray } from '../base.types';

export type StepAllowedInputType =
| string
Expand Down
17 changes: 17 additions & 0 deletions src/types/streaming-adapter.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Token usage information from streaming responses
*/
export interface TokenUsage {
promptTokens?: number;
completionTokens?: number;
totalTokens?: number;
}

/**
* Result containing all streaming metrics
*/
export interface StreamingMetricsResult {
ttftNs: number | null;
durationNs: number;
tokenUsage: TokenUsage | null;
}
98 changes: 98 additions & 0 deletions src/utils/errors.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,101 @@
import { AxiosError } from 'axios';

/**
* Standardized error information
*/
export interface ErrorInfo {
statusCode: number;
statusMessage?: string;
message: string;
}

/**
* Manages error mapping and retry logic for various error types
*/
export class ErrorManager {
/**
* Map an error to standardized format
* @param error The error to map
* @returns Standardized error information
*/
mapError(error: unknown): ErrorInfo {
// Handle Axios errors (HTTP errors)
if (error instanceof AxiosError) {
return {
statusCode: error.response?.status || 500,
statusMessage: error.response?.statusText,
message: error.message
};
}

// Handle standard Error objects
if (error instanceof Error) {
// Map common error patterns to appropriate status codes
const message = error.message.toLowerCase();

if (message.includes('timeout') || message.includes('timed out')) {
return { statusCode: 408, message: error.message };
}

if (
message.includes('network') ||
message.includes('connection') ||
message.includes('econnrefused') ||
message.includes('enotfound')
) {
return { statusCode: 503, message: error.message };
}

if (
message.includes('unauthorized') ||
message.includes('authentication')
) {
return { statusCode: 401, message: error.message };
}

if (message.includes('forbidden')) {
return { statusCode: 403, message: error.message };
}

if (message.includes('not found')) {
return { statusCode: 404, message: error.message };
}

if (
message.includes('rate limit') ||
message.includes('too many requests')
) {
return { statusCode: 429, message: error.message };
}

// Default to 500 for unknown errors
return { statusCode: 500, message: error.message };
}

// Handle string errors
if (typeof error === 'string') {
return { statusCode: 500, message: error };
}

// Fallback for unknown error types
return {
statusCode: 500,
message: String(error)
};
}

/**
* Check if an error is retryable based on status code
* @param error The error to check
* @returns True if the error is retryable
*/
isRetryable(error: unknown): boolean {
const errorInfo = this.mapError(error);
const retryableStatusCodes = [408, 429, 500, 502, 503, 504];
return retryableStatusCodes.includes(errorInfo.statusCode);
}
}

/**
* Base exception class for all API errors.
* Attempts to parse error messages from API responses, extracting the "detail" field
Expand Down
15 changes: 12 additions & 3 deletions src/utils/galileo-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import {
type Span,
StepWithChildSpans,
ToolSpan,
WorkflowSpan,
type JsonObject
WorkflowSpan
} from '../types/logging/span.types';
import type { JsonObject } from '../types/base.types';
import { type SpanSchema, Trace } from '../types/logging/trace.types';
import {
type RetrieverSpanAllowedOutputType,
Expand Down Expand Up @@ -107,7 +107,7 @@ class GalileoLogger implements IGalileoLogger {
*
* @param config - Logger configuration
* @returns Promise that resolves to a fully initialized logger
* @throws Error if trace or span initialization fails
* @throws Error if config validation fails or trace/span initialization fails
*/
static async create(
config: GalileoLoggerConfigExtended = {}
Expand All @@ -126,6 +126,8 @@ class GalileoLogger implements IGalileoLogger {
if (config.spanId) {
await logger.initSpan(config.spanId);
}
} else if (config.traceId || config.spanId) {
throw new Error('traceId and spanId can only be used in streaming mode.');
}

return logger;
Expand Down Expand Up @@ -1207,6 +1209,13 @@ class GalileoLogger implements IGalileoLogger {
*/
async flush(): Promise<Trace[]> {
try {
if (this.mode === 'streaming') {
console.warn(
'Flushing in streaming mode is not supported. Traces are automatically ingested as they are created.'
);
return [];
}

if (!this.traces.length) {
console.warn('No traces to flush.');
return [];
Expand Down
Loading
Loading