yunfengzhou-hub commented on code in PR #1271:
URL: https://github.com/apache/flink-agents/pull/1271#discussion_r4309968482
##########
docs/content/docs/get-started/quickstart/create-agent/single-agent.md:
##########
@@ -187,97 +225,101 @@ class ReviewAnalysisAgent(Agent):
*/
public class ReviewAnalysisAgent extends Agent {
- private static final ObjectMapper MAPPER = new ObjectMapper();
+private static final ObjectMapper MAPPER = new ObjectMapper();
- @Prompt
- public static org.apache.flink.agents.api.prompt.Prompt
reviewAnalysisPrompt() {
- return REVIEW_ANALYSIS_PROMPT;
- }
+@Prompt
+public static org.apache.flink.agents.api.prompt.Prompt reviewAnalysisPrompt()
{
+ return REVIEW_ANALYSIS_PROMPT;
+}
- @ChatModelSetup
- public static ResourceDescriptor reviewAnalysisModel() {
- return
ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.OLLAMA_SETUP)
- .addInitialArgument("connection", "ollamaChatModelConnection")
- .addInitialArgument("model", "qwen3:8b")
- .addInitialArgument("prompt", "reviewAnalysisPrompt")
- .addInitialArgument("tools",
Collections.singletonList("notifyShippingManager"))
- .addInitialArgument("extract_reasoning", true)
- .build();
- }
+@ChatModelSetup
+public static ResourceDescriptor reviewAnalysisModel() {
+ return
ResourceDescriptor.Builder.newBuilder(ResourceName.ChatModel.OLLAMA_SETUP)
+ .addInitialArgument("connection", "ollamaChatModelConnection")
+ .addInitialArgument("model", "qwen3:8b")
+ .addInitialArgument("prompt", "reviewAnalysisPrompt")
+ .addInitialArgument("tools",
Collections.singletonList("notifyShippingManager"))
+ .addInitialArgument("extract_reasoning", true)
+ .build();
+}
- /**
- * Tool for notifying the shipping manager when product received a
negative review due to
- * shipping damage.
- *
- * @param id The id of the product that received a negative review due to
shipping damage
- * @param review The negative review content
- */
- @Tool(
- description =
- "Notify the shipping manager when product received a
negative review due to shipping damage.")
- public static void notifyShippingManager(
- @ToolParam(name = "id") String id, @ToolParam(name = "review")
String review) {
- CustomTypesAndResources.notifyShippingManager(id, review);
- }
+/**
+ * Tool for notifying the shipping manager when product received a negative
review due to
+ * shipping damage.
+ *
+ * @param id The id of the product that received a negative review due to
shipping damage
+ * @param review The negative review content
+ */
+@Tool(
+ description =
+ "Notify the shipping manager when product received a negative
review due to shipping damage.")
+public static void notifyShippingManager(
+ @ToolParam(name = "id") String id, @ToolParam(name = "review") String
review) {
+ CustomTypesAndResources.notifyShippingManager(id, review);
+}
- /** Process input event and send chat request for review analysis. */
- @Action(EventType.InputEvent)
- public static void processInput(Event event, RunnerContext ctx) throws
Exception {
- InputEvent inputEvent = InputEvent.fromEvent(event);
- String input = (String) inputEvent.getInput();
- MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
- CustomTypesAndResources.ProductReview inputObj =
- MAPPER.readValue(input,
CustomTypesAndResources.ProductReview.class);
-
- ctx.getShortTermMemory().set("id", inputObj.getId());
-
- String content =
- String.format(
- "{\n" + "\"id\": %s,\n" + "\"review\": \"%s\"\n" + "}",
- inputObj.getId(), inputObj.getReview());
- ChatMessage msg = new ChatMessage(MessageRole.USER, "");
-
- ctx.sendEvent(
- new ChatRequestEvent(
- "reviewAnalysisModel", List.of(msg), Map.of("input",
content), null));
- }
+/** Process input event and send chat request for review analysis. */
+@Action(EventType.InputEvent)
+public static void processInput(Event event, RunnerContext ctx) throws
Exception {
+ InputEvent inputEvent = (InputEvent) event;
+ String input = (String) inputEvent.getInput();
+ MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ CustomTypesAndResources.ProductReview inputObj =
+ MAPPER.readValue(input,
CustomTypesAndResources.ProductReview.class);
+
+ ctx.getShortTermMemory().set("id", inputObj.getId());
+
+ String content =
+ String.format(
+ "{\n" + "\"id\": %s,\n" + "\"review\": \"%s\"\n" + "}",
+ inputObj.getId(), inputObj.getReview());
+ ChatMessage msg = new ChatMessage(MessageRole.USER, "");
+
+ ctx.sendEvent(
+ new ChatRequestEvent(
+ "reviewAnalysisModel", List.of(msg), Map.of("input",
content), null));
+}
- @Action(EventType.ChatResponseEvent)
- public static void processChatResponse(Event event, RunnerContext ctx)
- throws Exception {
- ChatResponseEvent chatResponse = ChatResponseEvent.fromEvent(event);
- JsonNode jsonNode =
MAPPER.readTree(chatResponse.getResponse().getText());
- JsonNode scoreNode = jsonNode.findValue("score");
- JsonNode reasonsNode = jsonNode.findValue("reasons");
- if (scoreNode == null || reasonsNode == null) {
- throw new IllegalStateException(
- "Invalid response from LLM: missing 'score' or 'reasons'
field.");
- }
- List<String> result = new ArrayList<>();
- if (reasonsNode.isArray()) {
- for (JsonNode node : reasonsNode) {
- result.add(node.asText());
- }
+@Action(EventType.ChatResponseEvent)
+public static void processChatResponse(Event event, RunnerContext ctx) throws
Exception {
+ ChatResponseEvent chatResponse = (ChatResponseEvent) event;
+ // Fail fast on a malformed LLM response: a parse error here propagates
and fails the
+ // agent, so a dropped input is surfaced instead of silently lost. In
production, choose
+ // the handling that fits your pipeline: raise to fail the input (as
below), emit an
+ // OutputEvent carrying an error sentinel, or send a custom error event so
downstream
+ // operators can detect the failure.
+ JsonNode jsonNode = MAPPER.readTree(chatResponse.getResponse().getText());
+ JsonNode scoreNode = jsonNode.findValue("score");
+ JsonNode reasonsNode = jsonNode.findValue("reasons");
+ if (scoreNode == null || reasonsNode == null) {
+ throw new IllegalStateException(
+ "Invalid response from LLM: missing 'score' or 'reasons'
field.");
+ }
+ List<String> result = new ArrayList<>();
+ if (reasonsNode.isArray()) {
+ for (JsonNode node : reasonsNode) {
+ result.add(node.asText());
}
-
- ctx.sendEvent(
- new OutputEvent(
- new CustomTypesAndResources.ProductReviewAnalysisRes(
-
ctx.getShortTermMemory().get("id").getValue().toString(),
- scoreNode.asInt(),
- result)));
}
+
+ ctx.sendEvent(
+ new OutputEvent(
+ new CustomTypesAndResources.ProductReviewAnalysisRes(
+
ctx.getShortTermMemory().get("id").getValue().toString(),
+ scoreNode.asInt(),
+ result)));
}
-```
+}```
Review Comment:
Fixed in bbb37f13 - the closing fence is on its own line now. I checked the
rest of the docs for the same pattern and this was the only occurrence.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]