mirror of
https://github.com/hanzoai/java-sdk.git
synced 2026-10-30 15:07:36 +00:00
The 09-06 regeneration renamed AgentsApi and ToolsApi to AgentApi and ToolApi and the examples kept the old names, so examples-build failed on main. hanzoai/ci gates a client-lane move on that same test, so every release dispatch since has stopped before regenerating and the jar stayed at 8.5.156, a client with no postDecisions. The client is regenerated from the document api.hanzo.ai serves (hanzo-inc/cloud 151878a3c, sha256 00564264), which now namespaces its schemas (AgentAgentView, ProvisioningProvisionRequest, ToolToolList) and types chat completions, so the examples are rewritten against it: agent, store and tools use the new names and paths, and chat sends a prompt and prints the reply instead of a status. .spec-lock is left to the lane, whose next move records the ref it was handed. hanzo.yml now names where the version lives, scripts/version, so the cut rewrites build.gradle to the release number and the push to main publishes it through release.yml; without it the cut tagged a build.gradle Central already served and nothing published. The README names the 8.5 line (8.5.+, [8.5,8.6)) rather than a patch, because each release cuts a patch into build.gradle alone, and scripts/readme checks the line instead of a number that goes stale. Co-authored-by: Hanzo Dev <[email protected]>
107 lines
4.3 KiB
Java
107 lines
4.3 KiB
Java
package ai.hanzo.cloud.examples;
|
|
|
|
import ai.hanzo.Hanzo;
|
|
import ai.hanzo.cloud.ApiException;
|
|
import ai.hanzo.cloud.api.AgentApi;
|
|
import ai.hanzo.cloud.model.AgentAgentRunView;
|
|
import ai.hanzo.cloud.model.AgentAgentView;
|
|
import ai.hanzo.cloud.model.AgentCreateAgentIn;
|
|
import ai.hanzo.cloud.model.AgentRunList;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* agent — create one, run it, watch the run land.
|
|
*
|
|
* <p>Operations: {@code post_agent} — POST /v1/agent,
|
|
* {@code post_agent_by_ref_run} — POST /v1/agent/{ref}/run,
|
|
* {@code get_agent_by_ref_runs} — GET /v1/agent/{ref}/runs.
|
|
*
|
|
* <p>{@code ref} accepts the public id or the org-unique name, so the run and
|
|
* the read both use the name just created. Names are org-unique, so this makes
|
|
* a fresh one rather than hardcoding it.
|
|
*
|
|
* <p>The run route carries neither a body nor an acknowledgement in the
|
|
* document, so the input the agent works on is its {@code instructions} and the
|
|
* only evidence a run started is the RUN LIST. That is why the example records
|
|
* the run ids that existed beforehand and polls until the one that appeared is
|
|
* terminal — the last step is the list, not the agent read.
|
|
*
|
|
* <p>Agents are org-scoped: without {@code X-Org-Id} these are
|
|
* 403 {@code "X-Org-Id required"}.
|
|
*
|
|
* <pre>
|
|
* HANZO_API_KEY=hk-... HANZO_ORG_ID=my-org ./gradlew :examples:agent
|
|
* </pre>
|
|
*/
|
|
public final class Agent {
|
|
|
|
/** Anything not still moving is done; the document does not enumerate the vocabulary. */
|
|
private static final Set<String> RUNNING = Set.of("queued", "pending", "running", "in_progress", "starting");
|
|
|
|
private static final int POLL_ATTEMPTS = 60;
|
|
private static final long POLL_INTERVAL_MS = 1000L;
|
|
|
|
/** The only flow that names a model. {@code HANZO_MODEL} overrides it. */
|
|
private static final String DEFAULT_MODEL = "zen5";
|
|
|
|
public static void main(String[] args) throws InterruptedException {
|
|
AgentApi agents = new AgentApi(Hanzo.client());
|
|
String name = "sdk-example-" + UUID.randomUUID().toString().substring(0, 8);
|
|
|
|
try {
|
|
AgentAgentView created = agents.postAgent(new AgentCreateAgentIn()
|
|
.name(name)
|
|
.model(model())
|
|
.instructions("Answer in exactly one sentence: what is the capital of Japan?"));
|
|
System.out.printf("created %s (%s)%n", created.getName(), created.getId());
|
|
|
|
Set<String> before = runIds(agents.getAgentByRefRuns(name, 100L));
|
|
|
|
agents.postAgentByRefRun(name);
|
|
System.out.printf("ran %s%n", name);
|
|
|
|
for (int attempt = 0; attempt < POLL_ATTEMPTS; attempt++) {
|
|
AgentAgentRunView run = started(agents.getAgentByRefRuns(name, 100L), before);
|
|
if (run != null && !RUNNING.contains(String.valueOf(run.getStatus()))) {
|
|
System.out.printf("run %s %s%n", run.getId(), run.getStatus());
|
|
System.out.printf("output %s%n", run.getOutput());
|
|
return;
|
|
}
|
|
Thread.sleep(POLL_INTERVAL_MS);
|
|
}
|
|
System.err.printf("run did not finish within %ds%n", POLL_ATTEMPTS * POLL_INTERVAL_MS / 1000);
|
|
System.exit(1);
|
|
} catch (ApiException e) {
|
|
System.err.printf("agent failed: HTTP %d %s%n", e.getCode(), e.getResponseBody());
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
private static String model() {
|
|
String model = System.getenv("HANZO_MODEL");
|
|
return model == null || model.trim().isEmpty() ? DEFAULT_MODEL : model;
|
|
}
|
|
|
|
private static Set<String> runIds(AgentRunList list) {
|
|
Set<String> ids = new HashSet<>();
|
|
List<AgentAgentRunView> runs = list == null ? null : list.getRuns();
|
|
if (runs != null) {
|
|
runs.forEach(run -> ids.add(run.getId()));
|
|
}
|
|
return ids;
|
|
}
|
|
|
|
/** The run this example started: the one that was not there before. */
|
|
private static AgentAgentRunView started(AgentRunList list, Set<String> before) {
|
|
List<AgentAgentRunView> runs = list == null ? null : list.getRuns();
|
|
if (runs == null) {
|
|
return null;
|
|
}
|
|
return runs.stream().filter(run -> !before.contains(run.getId())).findFirst().orElse(null);
|
|
}
|
|
}
|