Skip to content
Open
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
4 changes: 2 additions & 2 deletions orchestration/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
<coverage.complexity>82%</coverage.complexity>
<coverage.line>94%</coverage.line>
<coverage.instruction>93%</coverage.instruction>
<coverage.branch>75%</coverage.branch>
<coverage.method>94%</coverage.method>
<coverage.branch>77%</coverage.branch>
<coverage.method>95%</coverage.method>
<coverage.class>100%</coverage.class>
</properties>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import com.sap.ai.sdk.orchestration.model.PromptTemplatingModuleConfig;
import com.sap.ai.sdk.orchestration.model.PromptTemplatingModuleConfigPrompt;
import com.sap.ai.sdk.orchestration.model.Template;
import com.sap.ai.sdk.orchestration.model.TemplateRef;
import com.sap.ai.sdk.orchestration.model.TranslationModuleConfig;
import io.vavr.control.Option;
import java.util.ArrayList;
Expand Down Expand Up @@ -81,9 +80,6 @@ static PromptTemplatingModuleConfigPrompt toTemplateModuleConfig(
* In this case, the request will fail, since the templating module will try to resolve the parameter.
* To be fixed with https://github.tools.sap/AI/llm-orchestration/issues/662
*/
if (config instanceof TemplateRef) {
return config;
}

val template = config instanceof Template t ? t : Template.create().template();
val messages = template.getTemplate();
Expand Down Expand Up @@ -249,4 +245,25 @@ static CompletionPostRequest fromReferenceToCompletionPostRequest(
return request;
}
}

@Nonnull
static CompletionRequestConfiguration fromTemplateRefToCompletionPostRequest(
@Nonnull final OrchestrationModuleConfig configWithRef) {
final OrchestrationTemplateReference templateRef = configWithRef.getTemplateRef();
final var messageHistory =
templateRef.getMessagesHistory().stream().map(Message::createChatMessage).toList();
final var placeholders = templateRef.getTemplateParameters();

final OrchestrationModuleConfig inner =
configWithRef.withTemplateConfig(templateRef.toLowLevel());

val requestConfig =
OrchestrationConfig.create().modules(toModuleConfigs(inner)).stream(
configWithRef.getGlobalStreamOptions());

return CompletionRequestConfiguration.create()
.config(requestConfig)
.placeholderValues(placeholders)
.messagesHistory(messageHistory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,24 @@ public OrchestrationChatResponse chatCompletionUsingReference(
return new OrchestrationChatResponse(response);
}

/**
* Generate a completion using a module configuration containing a template reference Per-request
* history and parameters must be set on the template reference via {@link
* OrchestrationTemplateReference#withMessageHistory} and {@link
* OrchestrationTemplateReference#withTemplateParameters}.
*
* @param config A module configuration wrapping an {@link OrchestrationTemplateReference}.
* @return The completion output.
* @since 1.26.0
*/
@Nonnull
public OrchestrationChatResponse chatCompletionUsingTemplateRef(
@Nonnull final OrchestrationModuleConfig config) {
val request = ConfigToRequestTransformer.fromTemplateRefToCompletionPostRequest(config);
val response = executeRequest(request);
return new OrchestrationChatResponse(response);
}

/**
* Perform a request to the orchestration service using a module configuration provided as JSON
* string. This can be useful when building a configuration in the AI Launchpad UI and exporting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ public class OrchestrationModuleConfig {
@Nullable
SAPDocumentTranslationOutput outputTranslationConfig;

@Nullable OrchestrationTemplateReference templateRef;

/** Configuration of optional streaming options for output filtering. */
@With(AccessLevel.NONE) // may be exposed to public in the future
@Getter(AccessLevel.PACKAGE)
Expand Down Expand Up @@ -304,6 +306,7 @@ OrchestrationModuleConfig withOutputFilteringStreamOptions(
this.groundingConfig,
this.inputTranslationConfig,
this.outputTranslationConfig,
this.templateRef,
outputFilteringStreamOptions,
this.globalStreamOptions);
}
Expand Down Expand Up @@ -340,6 +343,31 @@ public OrchestrationModuleConfig withTemplateConfig(
return this.withTemplateConfig(templateConfig.toLowLevel());
}

/**
* Creates a new configuration with the given template reference. The template reference is the
* only source of prompt input
*
* @param templateRef The template reference to use.
* @return A new {@link OrchestrationModuleConfig} wrapping this config.
* @since 1.26.0
*/
@Tolerate
@Nonnull
public OrchestrationModuleConfig withTemplateConfig(
@Nonnull final OrchestrationTemplateReference templateRef) {
return new OrchestrationModuleConfig(
this.llmConfig,
this.templateConfig,
this.maskingConfig,
this.filteringConfig,
this.groundingConfig,
this.inputTranslationConfig,
this.outputTranslationConfig,
templateRef,
outputFilteringStreamOptions,
this.globalStreamOptions);
}

/**
* Configure input translation using a high-level TranslationConfig.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
import com.sap.ai.sdk.orchestration.model.TemplateRefByID;
import com.sap.ai.sdk.orchestration.model.TemplateRefByScenarioNameVersion;
import com.sap.ai.sdk.orchestration.model.TemplateRefTemplateRef;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Value;
import lombok.With;

Expand All @@ -28,6 +31,46 @@ public class OrchestrationTemplateReference extends TemplateConfig {
/** The scope of the template reference. */
@With @Nonnull ScopeEnum scope;

@Getter(AccessLevel.PACKAGE)
@Nonnull
List<Message> messagesHistory;

@Getter(AccessLevel.PACKAGE)
@Nonnull
Map<String, String> templateParameters;

/** Build a template reference with scope only. */
OrchestrationTemplateReference(
@Nonnull final TemplateRefTemplateRef reference, @Nonnull final ScopeEnum scope) {
this(reference, scope, List.of(), Map.of());
}

/**
* Set the chat history.
*
* @param messagesHistory The chat history to set.
* @return A new instance with the specified chat history.
*/
@Nonnull
public OrchestrationTemplateReference withMessageHistory(
@Nonnull final List<Message> messagesHistory) {
return new OrchestrationTemplateReference(
reference, scope, messagesHistory, templateParameters);
}

/**
* Set the template parameters.
*
* @param templateParameters The template parameters to set.
* @return A new instance with the specified template parameters.
*/
@Nonnull
public OrchestrationTemplateReference withTemplateParameters(
@Nonnull final Map<String, String> templateParameters) {
return new OrchestrationTemplateReference(
reference, scope, messagesHistory, templateParameters);
}

/**
* Create a low-level representation of the template.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,22 @@ void testUserMessageHistory() {

assertThat(actual.getMessagesHistory()).containsExactly(userMessage.createChatMessage());
}

@Test
void testToCompletionPostRequestWithRef() {
var ref =
TemplateConfig.reference()
.byId("test-id")
.withTemplateParameters(Map.of("lang", "DE"))
.withMessageHistory(List.of(new UserMessage("prev")));
var config =
new OrchestrationModuleConfig()
.withLlmConfig(OrchestrationAiModel.GPT_4O)
.withTemplateConfig(ref);

var request = ConfigToRequestTransformer.fromTemplateRefToCompletionPostRequest(config);

assertThat(request.getPlaceholderValues()).containsEntry("lang", "DE");
assertThat(request.getMessagesHistory()).hasSize(1);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,27 @@ void testResponseFormatOverwrittenByNewTemplateRef() {
TemplateRef.create().templateRef(TemplateRefByID.create().id("123")));
assertThat(config.getTemplateConfig()).isInstanceOf(TemplateRef.class);
}

@Test
void withTemplateConfigReturnsWrapperWithRef() {
var ref = TemplateConfig.reference().byId("abc");
OrchestrationModuleConfig withRef =
new OrchestrationModuleConfig()
.withLlmConfig(OrchestrationAiModel.GPT_4O)
.withTemplateConfig(ref);

assertThat(withRef.getTemplateRef()).isSameAs(ref);
}

@Test
void templateRefCarriesHistoryAndParams() {
var ref =
TemplateConfig.reference()
.byId("abc")
.withMessageHistory(List.of(new UserMessage("hi")))
.withTemplateParameters(Map.of("k", "v"));

assertThat(ref.getMessagesHistory()).hasSize(1);
assertThat(ref.getTemplateParameters()).containsEntry("k", "v");
}
}
Loading