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
1 change: 1 addition & 0 deletions docs/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- [Orchestration] Added `GPT_52` model for `OrchestrationAiModel`.
- [OpenAi] Added `GPT_52` model from `OpenAiModel`.
- [Orchestration] Added `GEMINI_EMBEDDING` model for `OrchestrationEmbeddingModel`.
- [Orchestration] Added citations for Perplexity `SONAR` model in `client.chatCompletion().getOriginalResponse().getFinalResult().getCitations()`

### 📈 Improvements

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.sap.ai.sdk.orchestration.OrchestrationFilterException;
import com.sap.ai.sdk.orchestration.model.AzureContentSafetyInput;
import com.sap.ai.sdk.orchestration.model.AzureContentSafetyOutput;
import com.sap.ai.sdk.orchestration.model.Citation;
import com.sap.ai.sdk.orchestration.model.DPIEntities;
import com.sap.cloud.sdk.cloudplatform.thread.ThreadContextExecutors;
import java.io.IOException;
Expand Down Expand Up @@ -408,4 +409,27 @@ Object completionWithFallback(
}
return response.getContent();
}

@GetMapping("/citations")
@Nonnull
Object citations(
@Nullable @RequestParam(value = "format", required = false) final String format) {
final var response = service.citations();
if ("json".equals(format)) {
return response;
}

final StringBuilder content = new StringBuilder(response.getContent().replaceAll("\n", "<br>"));
final var citations = response.getOriginalResponse().getFinalResult().getCitations();

if (!citations.isEmpty()) {
content.append("<br><br>Citations:");
for (final Citation citation : citations) {
content.append(
"<br>%d. <a href=\"%s\">%s</a>"
.formatted(citation.getRefId(), citation.getUrl(), citation.getTitle()));
}
}
return content.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_41_NANO;
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.GPT_5_MINI;
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.Parameter.TEMPERATURE;
import static com.sap.ai.sdk.orchestration.OrchestrationAiModel.SONAR;
import static com.sap.ai.sdk.orchestration.OrchestrationEmbeddingModel.TEXT_EMBEDDING_3_SMALL;
import static com.sap.ai.sdk.orchestration.OrchestrationTemplateReference.ScopeEnum.RESOURCE_GROUP;

Expand Down Expand Up @@ -857,4 +858,16 @@ public OrchestrationChatResponse completionWithFallbackAllFail(
.withLlmConfig(new OrchestrationAiModel("broken_name_2", Map.of(), "latest"));
return client.chatCompletion(prompt, brokenConfig, secondBrokenConfig);
}

/**
* Chat request using the SONAR model which provides citations.
*
* @return the assistant response object with citations
*/
@Nonnull
public OrchestrationChatResponse citations() {
val prompt = new OrchestrationPrompt("Where does \"Hello World\" come from?");
val sonarConfig = new OrchestrationModuleConfig().withLlmConfig(SONAR);
return client.chatCompletion(prompt, sonarConfig);
}
}
13 changes: 13 additions & 0 deletions sample-code/spring-app/src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,19 @@ <h2>Orchestration</h2>
</div>
</div>
</li>
<!-- citation -->
<li class="list-group-item">
<div class="info-tooltip">
<button type="submit"
formaction="/orchestration/citations"
class="link-offset-2-hover link-underline link-underline-opacity-0 link-underline-opacity-75-hover endpoint">
<code>/orchestration/citations</code>
</button>
<div class="tooltip-content">
Chat request to an LLM through the Orchestration service
with citations from Perplexity Sonar.
</div>
</div>
</ul>
</details>
<br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,4 +595,10 @@ void testCompletionWithFallbackAllFail() {
.isInstanceOf(OrchestrationClientException.class)
.hasMessageContaining("Model broken_name_2 not supported.");
}

@Test
void testCitations() {
val result = service.citations();
assertThat(result.getOriginalResponse().getFinalResult().getCitations()).isNotEmpty();
}
}
Loading