com.microsoft.semantickernel.contextvariables.ContextVariable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of semantickernel-api Show documentation
Show all versions of semantickernel-api Show documentation
Defines the public interface for the Semantic Kernel
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.contextvariables;
import com.azure.ai.openai.models.CompletionsUsage;
import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter.NoopConverter;
import com.microsoft.semantickernel.exceptions.SKException;
import java.time.OffsetDateTime;
import java.util.Collections;
import java.util.Objects;
import javax.annotation.Nullable;
/**
* A context variable wraps an arbitrary value and a {@code ContextVariableType}.
* {@code ContextVariableType} is used throughout the Semantic Kernel for passing arguments to
* functions and as function return types.
*
* @param the type of the context variable
*/
public class ContextVariable {
private final ContextVariableType type;
@Nullable
private final T value;
/**
* Creates a new instance of the {@link ContextVariable} class.
*
* @param type the type
* @param value the value
*/
public ContextVariable(
ContextVariableType type,
@Nullable T value) {
this.type = type;
this.value = value;
}
/**
* Converts the given value to the requested result type.
*
* @param the type of the requested result
* @param the type of the input value
* @param it the input value
* @param requestedResultType the requested result type
* @return the converted value
*/
public static ContextVariable convert(
@Nullable U it,
ContextVariableType requestedResultType) {
return convert(
it,
requestedResultType.getClazz(),
new ContextVariableTypes(
Collections.singletonList(requestedResultType.getConverter())));
}
/**
* Converts the given value to the requested result type. The {@code ContextVariableTypes}
* parameter is used to find the appropriate converter for the input value and the requested
* result type.
*
* @param the type of the requested result
* @param the type of the input value
* @param it the input value
* @param requestedResultType the requested result type
* @param contextVariableTypes the context variable types
* @return the converted value
* @throws SKException if a type converter cannot be found, or the input value cannot be
* converted to the requested result type
*/
public static ContextVariable convert(
@Nullable U it,
Class requestedResultType,
@Nullable ContextVariableTypes contextVariableTypes) {
if (contextVariableTypes == null) {
contextVariableTypes = new ContextVariableTypes();
}
if (it instanceof ContextVariable) {
it = (U) ((ContextVariable>) it).getValue();
}
if (it == null) {
return new ContextVariable<>(
contextVariableTypes.getVariableTypeForClass(requestedResultType),
null);
}
if (requestedResultType.isAssignableFrom(it.getClass())) {
try {
return contextVariableTypes
.getVariableTypeForClass(requestedResultType)
.of(requestedResultType.cast(it));
} catch (Exception e) {
return new ContextVariable<>(
new ContextVariableType<>(
new NoopConverter<>(requestedResultType),
requestedResultType),
requestedResultType.cast(it));
}
}
ContextVariableType requestedResultTypeVariable;
try {
requestedResultTypeVariable = contextVariableTypes.getVariableTypeForClass(
requestedResultType);
} catch (Exception e) {
throw new SKException("Unable to find variable type for " + requestedResultType, e);
}
ContextVariableType typeOfActualReturnedType = null;
try {
// First try to convert from type ? to T using the converter of ? and see if it can convert it to T.
typeOfActualReturnedType = contextVariableTypes
.getVariableTypeForClass((Class) it.getClass());
} catch (Exception e) {
try {
typeOfActualReturnedType = contextVariableTypes
.getVariableTypeForSuperClass((Class) it.getClass());
} catch (Exception e2) {
// ignore
}
}
if (typeOfActualReturnedType != null) {
// Try the to object
T converted = typeOfActualReturnedType.getConverter().toObject(contextVariableTypes, it,
requestedResultType, false);
if (converted != null) {
return contextVariableTypes.getVariableTypeForClass(requestedResultType)
.of(converted);
}
if (requestedResultType.isAssignableFrom(String.class)) {
// Try using toPromptString
String str = typeOfActualReturnedType.getConverter()
.toPromptString(
contextVariableTypes,
typeOfActualReturnedType.getClazz().cast(it));
return requestedResultTypeVariable.of(str);
}
}
// Try getting a converter of type T and see if it can convert ? to T.
if (requestedResultTypeVariable != null) {
// Try using from object
T result = requestedResultTypeVariable.getConverter().fromObject(it);
if (result != null) {
return requestedResultTypeVariable.of(result);
}
if (it.getClass().equals(String.class)) {
// Try using from prompt string
return requestedResultTypeVariable.of(
requestedResultTypeVariable.getConverter().fromPromptString((String) it));
}
}
throw new SKException("Unable to convert " + it.getClass() + " to " + requestedResultType);
}
/**
* Creates a new instance of the {@link ContextVariable} class without using strong typing.
*
* @param value the value
* @param clazz the class
* @param types the types
* @return the new instance
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static ContextVariable> untypedOf(
@Nullable Object value,
Class> clazz,
ContextVariableTypes types) {
ContextVariableType> type = types.getVariableTypeForClass(clazz);
return new ContextVariable(type, value);
}
/**
* Convenience method for creating a {@code ContextVariable} from the given
* {@code CompletionsUsage} instance.
*
* @param x the value
* @return the new instance
*/
public static ContextVariable of(CompletionsUsage x) {
return ofValue(x);
}
/**
* Convenience method for creating a {@code ContextVariable} from the given
* {@code OffsetDateTime} instance.
*
* @param x the value
* @return the new instance
*/
public static ContextVariable of(OffsetDateTime x) {
return ofValue(x);
}
/**
* Convenience method for creating a {@code ContextVariable} from the given {@code String}
* instance.
*
* @param value the value
* @return the new instance
*/
public static ContextVariable of(String value) {
return ofValue(value);
}
/**
* Convenience method for creating a {@code ContextVariable} from the given object.
*
* @param x the object
* @return the new instance
*/
public static ContextVariable