chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:20:55 +08:00
commit d25d482dc2
13754 changed files with 4996608 additions and 0 deletions
+311
View File
@@ -0,0 +1,311 @@
import { createLogger } from '@sim/logger'
import { ChartBarIcon } from '@/components/icons'
import type { BlockConfig, ParamType } from '@/blocks/types'
import {
getModelOptions,
getProviderCredentialSubBlocks,
PROVIDER_CREDENTIAL_INPUTS,
} from '@/blocks/utils'
import { getBaseModelProviders } from '@/providers/models'
import type { ProviderId } from '@/providers/types'
import type { ToolResponse } from '@/tools/types'
const logger = createLogger('EvaluatorBlock')
interface Metric {
name: string
description: string
range: {
min: number
max: number
}
}
interface EvaluatorResponse extends ToolResponse {
output: {
content: string
model: string
tokens?: {
prompt?: number
completion?: number
total?: number
}
cost?: {
input: number
output: number
total: number
}
[metricName: string]: any // Allow dynamic metric fields
}
}
export const generateEvaluatorPrompt = (metrics: Metric[], content: string): string => {
// Filter out invalid/incomplete metrics first
const validMetrics = metrics.filter((m) => m?.name && m.range)
// Create a clear metrics description with name, range, and description
const metricsDescription = validMetrics
.map(
(metric) =>
`"${metric.name}" (${metric.range.min}-${metric.range.max}): ${metric.description || ''}` // Handle potentially missing description
)
.join('\n')
// Format the content properly - try to detect and format JSON
let formattedContent = content
try {
// If content looks like JSON (starts with { or [)
if (
typeof content === 'string' &&
(content.trim().startsWith('{') || content.trim().startsWith('['))
) {
// Try to parse and pretty-print
const parsedContent = JSON.parse(content)
formattedContent = JSON.stringify(parsedContent, null, 2)
}
// If it's already an object (shouldn't happen here but just in case)
else if (typeof content === 'object') {
formattedContent = JSON.stringify(content, null, 2)
}
} catch (e) {
logger.warn('Warning: Content may not be valid JSON, using as-is', { e })
formattedContent = content
}
// Generate an example of the expected output format using only valid metrics
const exampleOutput = validMetrics.reduce(
(acc, metric) => {
// Ensure metric and name are valid before using them
if (metric?.name) {
acc[metric.name.toLowerCase()] = Math.floor((metric.range.min + metric.range.max) / 2) // Use middle of range as example
} else {
logger.warn('Skipping invalid metric during example generation:', metric)
}
return acc
},
{} as Record<string, number>
)
return `You are an objective evaluation agent. Analyze the content against the provided metrics and provide detailed scoring.
Evaluation Instructions:
- You MUST evaluate the content against each metric
- For each metric, provide a numeric score within the specified range
- Your response MUST be a valid JSON object with each metric name as a key and a numeric score as the value
- IMPORTANT: Use lowercase versions of the metric names as keys in your JSON response
- Follow the exact schema of the response format provided to you
- Do not include explanations in the JSON - only numeric scores
- Do not add any additional fields not specified in the schema
- Do not include ANY text before or after the JSON object
Metrics to evaluate:
${metricsDescription}
Content to evaluate:
${formattedContent}
Example of expected response format (with different scores):
${JSON.stringify(exampleOutput, null, 2)}
Remember: Your response MUST be a valid JSON object containing only the lowercase metric names as keys with their numeric scores as values. No text explanations.`
}
// Simplified response format generator that matches the agent block schema structure
const generateResponseFormat = (metrics: Metric[]) => {
// Filter out invalid/incomplete metrics first
const validMetrics = metrics.filter((m) => m?.name)
// Create properties for each metric
const properties: Record<string, any> = {}
// Add each metric as a property
validMetrics.forEach((metric) => {
// We've already filtered, but double-check just in case
if (metric?.name) {
properties[metric.name.toLowerCase()] = {
type: 'number',
description: `${metric.description || ''} (Score between ${metric.range?.min ?? 0}-${metric.range?.max ?? 'N/A'})`, // Safely access range
}
} else {
logger.warn('Skipping invalid metric during response format property generation:', metric)
}
})
// Return a proper JSON Schema format
return {
name: 'evaluation_response',
schema: {
type: 'object',
properties,
// Use only valid, lowercase metric names for the required array
required: validMetrics
.filter((metric) => metric?.name)
.map((metric) => metric.name.toLowerCase()),
additionalProperties: false,
},
strict: true,
}
}
export const EvaluatorBlock: BlockConfig<EvaluatorResponse> = {
type: 'evaluator',
name: 'Evaluator',
description: 'Evaluate content',
longDescription:
'This is a core workflow block. Assess content quality using customizable evaluation metrics and scoring criteria. Create objective evaluation frameworks with numeric scoring to measure performance across multiple dimensions.',
docsLink: 'https://docs.sim.ai/workflows/blocks/evaluator',
category: 'blocks',
bgColor: '#4D5FFF',
icon: ChartBarIcon,
subBlocks: [
{
id: 'metrics',
title: 'Evaluation Metrics',
type: 'eval-input',
required: true,
},
{
id: 'content',
title: 'Content',
type: 'long-input',
placeholder: 'Enter the content to evaluate',
required: true,
},
{
id: 'model',
title: 'Model',
type: 'combobox',
placeholder: 'Type or select a model...',
required: true,
defaultValue: 'claude-sonnet-5',
options: getModelOptions,
},
...getProviderCredentialSubBlocks(),
{
id: 'temperature',
title: 'Temperature',
type: 'slider',
min: 0,
max: 2,
hidden: true,
},
{
id: 'systemPrompt',
title: 'System Prompt',
type: 'code',
hidden: true,
value: (params: Record<string, any>) => {
try {
const metrics = params.metrics || []
// Process content safely
let processedContent = ''
if (typeof params.content === 'object') {
processedContent = JSON.stringify(params.content, null, 2)
} else {
processedContent = String(params.content || '')
}
// Generate prompt and response format directly
const promptText = generateEvaluatorPrompt(metrics, processedContent)
const responseFormatObj = generateResponseFormat(metrics)
// Create a clean, simple JSON object
const result = {
systemPrompt: promptText,
responseFormat: responseFormatObj,
}
return JSON.stringify(result)
} catch (e) {
logger.error('Error in systemPrompt value function:', { e })
// Return a minimal valid JSON as fallback
return JSON.stringify({
systemPrompt: 'Evaluate the content and return a JSON with metric scores.',
responseFormat: {
schema: {
type: 'object',
properties: {},
additionalProperties: true,
},
},
})
}
},
},
],
tools: {
access: [
'openai_chat',
'anthropic_chat',
'google_chat',
'xai_chat',
'deepseek_chat',
'deepseek_reasoner',
],
config: {
tool: (params: Record<string, any>) => {
const model = params.model || 'gpt-4o'
if (!model) {
throw new Error('No model selected')
}
const tool = getBaseModelProviders()[model as ProviderId]
if (!tool) {
throw new Error(`Invalid model selected: ${model}`)
}
return tool
},
},
},
inputs: {
metrics: {
type: 'json' as ParamType,
description: 'Evaluation metrics configuration',
schema: {
type: 'array',
properties: {},
items: {
type: 'object',
properties: {
name: {
type: 'string',
description: 'Name of the metric',
},
description: {
type: 'string',
description: 'Description of what this metric measures',
},
range: {
type: 'object',
properties: {
min: {
type: 'number',
description: 'Minimum possible score',
},
max: {
type: 'number',
description: 'Maximum possible score',
},
},
required: ['min', 'max'],
},
},
required: ['name', 'description', 'range'],
},
},
},
model: { type: 'string' as ParamType, description: 'AI model to use' },
...PROVIDER_CREDENTIAL_INPUTS,
temperature: {
type: 'number' as ParamType,
description: 'Response randomness level (low for consistent evaluation)',
},
content: { type: 'string' as ParamType, description: 'Content to evaluate' },
},
outputs: {
content: { type: 'string', description: 'Evaluation results' },
model: { type: 'string', description: 'Model used' },
tokens: { type: 'json', description: 'Token usage' },
cost: { type: 'json', description: 'Cost information' },
} as any,
}