pltbkd commented on code in PR #938: URL: https://github.com/apache/flink-agents/pull/938#discussion_r3702467332
########## api/src/main/java/org/apache/flink/agents/api/subagent/BaseSubagentCallable.java: ########## @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.flink.agents.api.subagent; + +import org.apache.flink.agents.api.context.DurableCallable; + +/** + * Convenience base for the {@link DurableCallable} returned by {@code asAsyncCallable}. + * + * <p>Keys the durable call by the framework-assigned identity as {@code sessionId#callId} (the + * {@link SubagentSetup} contract) and captures exceptions thrown by {@link #callInternal()} into + * {@link Result#error(Exception)}, so failures are reported through the result rather than thrown. + * Implementations only provide {@link #callInternal()}. + */ +public abstract class BaseSubagentCallable implements DurableCallable<Result> { + + private final String sessionId; + private final String callId; + + protected BaseSubagentCallable(String sessionId, String callId) { Review Comment: BaseSubagentCallable doesn't shield any DurableCallable convention — it inherits reconciler() as-is (default null) and only simplifies boilerplate (getId, getResultClass, call with exception capture). Without a reconciler, a crash between invocation and persistence causes replay to re-invoke the external agent — this is expected, identical to any DurableCallable, and typically fine for read-only or idempotent sub-agents. If side effects must not be replayed, the author should provide a reconciler per the existing DurableCallable contract. The question is whether to surface this option more visibly. Here are three options: 1. Add reconcilerInternal to BaseSubagentCallable — simplest, but just restates a convention DurableCallable already defines. 2. Remove BaseSubagentCallable — if the abstraction confuses developers into thinking it shields DurableCallable contracts, maybe we should remove it makes them implement DurableCallable directly. 3. Default reconciler + abstract querySuccess() — if the typical pattern is if (querySuccess()) return result; else return callInternal(), we can provide a default reconciler() that uses it. Enables the pending/reconcile path; developers can still override. Which do you prefer? -- 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]
