mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-10-07 14:58:39 +08:00
chore(deps): bump typescript-client 1.27.0 + agent-server/openhands-sdk 1.29.0 (#1486)
* chore(deps): bump @openhands/typescript-client to 1.27.0 * test: update ACP provider/model fixtures for typescript-client 1.27.0 1.27.0 refreshed the claude-code/codex ACP registry data: provider command versions (claude-agent-acp 0.30.0->0.44.0, codex-acp 0.15.0->0.16.0), claude-code model ids (claude-opus-4-8->opus[1m], claude-sonnet-4-6->sonnet, claude-haiku-4-5->haiku) plus a new well-labeled "default" option, and the codex default (gpt-5.5/medium->gpt-5.5). Canvas sources these lists from the client registry (closes #740), so the source was already correct -- only the hardcoded test expectations were stale. Also relaxed the acp-providers placeholder guard to accept the SDK's intentional "Default (recommended)" entry. * chore(deps): bump agent-server/openhands-sdk to 1.29.0 Align the spawned agent-server SDK release train (openhands-sdk, openhands-tools, openhands-workspace, openhands-agent-server) with the version @openhands/typescript-client 1.27.0 is validated against (agent-server 1.29.0-python). Bump the coupled openhands-automation pin to 1.0.0a12, whose SDK deps resolve to 1.29.0, to satisfy the check-sdk-version-sync gate. minimumAgentServer compat floor unchanged. Doc/JSDoc/test references updated to keep docs-version-sync green.
This commit is contained in:
@@ -517,10 +517,10 @@ When adding code that needs a new string, decide up front which rule it falls un
|
||||
- `scripts/dev-safe.mjs` uses `uvx` for temporary agent-server installation — no permanent `uv tool install` needed. Environment variables (highest precedence first):
|
||||
- `OH_AGENT_SERVER_LOCAL_PATH` — absolute path to a local `software-agent-sdk` checkout. Runs the local checkout via `uvx` with `--with-editable` for `openhands-sdk`/`openhands-tools`/`openhands-workspace` and `--reinstall` for `openhands-agent-server`, so SDK edits are picked up on restart. Highest precedence.
|
||||
- `OH_AGENT_SERVER_GIT_REF` — git commit SHA or branch name (takes precedence over version)
|
||||
- `OH_AGENT_SERVER_VERSION` — specific PyPI version (e.g., "1.28.1")
|
||||
- `OH_AGENT_SERVER_VERSION` — specific PyPI version (e.g., "1.29.0")
|
||||
- `OH_SECRET_KEY` — secret key for settings encryption; auto-generated and persisted to `~/.openhands/agent-canvas/secret-key.txt` on first run (same file Docker uses), ensuring dev mode and Docker share the same key when both mount the same `~/.openhands` directory. Override with the env var to pin a specific key.
|
||||
- `SESSION_API_KEY` / `OH_SESSION_API_KEYS_0` / `VITE_SESSION_API_KEY` — session API key for agent-server authentication; auto-generated using `crypto.randomBytes(32)` if not set, passed to both agent-server (`OH_SESSION_API_KEYS_0`) and frontend (`VITE_SESSION_API_KEY`)
|
||||
- Default: released PyPI version `1.28.1` for agent-server SDK libraries
|
||||
- Default: released PyPI version `1.29.0` for agent-server SDK libraries
|
||||
|
||||
- Security: `scripts/dev-safe.mjs` and `scripts/dev-with-automation.mjs` auto-generate random API keys when needed and persist the defaults so static builds, localStorage, and restarted services stay in sync:
|
||||
- `SESSION_API_KEY` — 64-character hex (256-bit) for agent-server API authentication; persisted at `~/.openhands/agent-canvas/session-api-key.txt` unless overridden via env var
|
||||
|
||||
@@ -128,9 +128,9 @@ describe("buildStartConversationRequest", () => {
|
||||
});
|
||||
// Bundled public skills are injected into agent_context.skills so the
|
||||
// SDK can perform trigger matching without cloning the extensions repo.
|
||||
expect(
|
||||
Array.isArray(payload.agent_settings.agent_context.skills),
|
||||
).toBe(true);
|
||||
expect(Array.isArray(payload.agent_settings.agent_context.skills)).toBe(
|
||||
true,
|
||||
);
|
||||
const skills = payload.agent_settings.agent_context.skills as Record<
|
||||
string,
|
||||
unknown
|
||||
@@ -618,9 +618,9 @@ describe("buildStartConversationRequest", () => {
|
||||
tool_module_qualnames?: Record<string, string>;
|
||||
};
|
||||
|
||||
expect(payload.agent_settings.tools.map((tool) => tool.name)).not.toContain(
|
||||
"canvas_ui",
|
||||
);
|
||||
expect(
|
||||
payload.agent_settings.tools.map((tool) => tool.name),
|
||||
).not.toContain("canvas_ui");
|
||||
expect(payload.tool_module_qualnames).toBeUndefined();
|
||||
});
|
||||
|
||||
@@ -1164,9 +1164,9 @@ describe("agent_settings runtime services suffix", () => {
|
||||
load_user_skills: true,
|
||||
load_project_skills: true,
|
||||
});
|
||||
expect(
|
||||
Array.isArray(payload.agent_settings.agent_context.skills),
|
||||
).toBe(true);
|
||||
expect(Array.isArray(payload.agent_settings.agent_context.skills)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it("sets system_message_suffix when runtime info is provided", () => {
|
||||
@@ -1232,7 +1232,7 @@ describe("buildStartConversationRequest — ACP discriminator", () => {
|
||||
expect(payload.agent_settings.acp_command).toEqual([
|
||||
"npx",
|
||||
"-y",
|
||||
"@agentclientprotocol/claude-agent-acp@0.30.0",
|
||||
"@agentclientprotocol/claude-agent-acp@0.44.0",
|
||||
]);
|
||||
expect(payload.agent_settings.acp_model).toBe("claude-opus-4-5");
|
||||
// LLM-only fields must not leak into the ACP settings payload.
|
||||
@@ -1381,7 +1381,7 @@ describe("buildStartConversationRequest — ACP discriminator", () => {
|
||||
expect(payload.agent_settings.acp_command).toEqual([
|
||||
"npx",
|
||||
"-y",
|
||||
"@agentclientprotocol/claude-agent-acp@0.30.0",
|
||||
"@agentclientprotocol/claude-agent-acp@0.44.0",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1403,7 +1403,7 @@ describe("buildStartConversationRequest — ACP discriminator", () => {
|
||||
expect(payload.agent_settings.acp_command).toEqual([
|
||||
"npx",
|
||||
"-y",
|
||||
"@zed-industries/codex-acp@0.15.0",
|
||||
"@zed-industries/codex-acp@0.16.0",
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1468,7 +1468,7 @@ describe("buildStartConversationRequest — ACP discriminator", () => {
|
||||
agent_settings: Record<string, unknown> & { acp_model?: unknown };
|
||||
};
|
||||
|
||||
expect(payload.agent_settings.acp_model).toBe("claude-opus-4-8");
|
||||
expect(payload.agent_settings.acp_model).toBe("opus[1m]");
|
||||
});
|
||||
|
||||
it("omits acp_model for the custom preset when none is configured", () => {
|
||||
@@ -1550,7 +1550,7 @@ describe("buildStartConversationRequest — ACP discriminator", () => {
|
||||
expect(acpPayload.agent_settings.acp_command).toEqual([
|
||||
"npx",
|
||||
"-y",
|
||||
"@agentclientprotocol/claude-agent-acp@0.30.0",
|
||||
"@agentclientprotocol/claude-agent-acp@0.44.0",
|
||||
]);
|
||||
expect(acpPayload.agent_settings.acp_model).toBe("claude-opus-4-5");
|
||||
// acp_env is no longer a forwarded ACP setting — a stale value on saved
|
||||
|
||||
@@ -89,7 +89,7 @@ describe("ChatInputModel", () => {
|
||||
conversation_id: "test-conversation-id",
|
||||
agent_kind: "acp",
|
||||
acp_server: "claude-code",
|
||||
llm_model: "claude-sonnet-4-6",
|
||||
llm_model: "sonnet",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -216,10 +216,10 @@ describe("ChatInputModel", () => {
|
||||
renderWithProviders(<ChatInputModel />);
|
||||
|
||||
const model = screen.getByTestId("chat-input-llm-model");
|
||||
// Claude Code's registered default (``claude-opus-4-8``), shown as its
|
||||
// Claude Code's registered default (``opus[1m]``), shown as its
|
||||
// human label to match the conversation list chip. See CLAUDE_MODELS in
|
||||
// acp-providers.ts.
|
||||
expect(model).toHaveAttribute("title", "Claude Opus 4.8");
|
||||
expect(model).toHaveAttribute("title", "Claude Opus 4.8 (1M)");
|
||||
fireEvent.click(model);
|
||||
expect(screen.getByRole("link")).toHaveAttribute("href", "/settings/agent");
|
||||
});
|
||||
@@ -230,7 +230,7 @@ describe("ChatInputModel", () => {
|
||||
conversation_id: "test-conversation-id",
|
||||
agent_kind: "acp",
|
||||
acp_server: "claude-code",
|
||||
llm_model: "claude-sonnet-4-6",
|
||||
llm_model: "sonnet",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -239,14 +239,14 @@ describe("ChatInputModel", () => {
|
||||
fireEvent.click(screen.getByTestId("chat-input-llm-model"));
|
||||
|
||||
// Every registered Claude Code model is offered as a row, and the running
|
||||
// one (claude-sonnet-4-6) is marked selected.
|
||||
// one (sonnet) is marked selected.
|
||||
const selectedRow = screen.getByTestId(
|
||||
"chat-input-acp-model-option-claude-sonnet-4-6",
|
||||
"chat-input-acp-model-option-sonnet",
|
||||
);
|
||||
expect(selectedRow).toBeInTheDocument();
|
||||
expect(selectedRow).toHaveTextContent("Claude Sonnet 4.6");
|
||||
expect(
|
||||
screen.getByTestId("chat-input-acp-model-option-claude-opus-4-8"),
|
||||
screen.getByTestId("chat-input-acp-model-option-opus[1m]"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
@@ -256,22 +256,20 @@ describe("ChatInputModel", () => {
|
||||
conversation_id: "test-conversation-id",
|
||||
agent_kind: "acp",
|
||||
acp_server: "claude-code",
|
||||
llm_model: "claude-sonnet-4-6",
|
||||
llm_model: "sonnet",
|
||||
},
|
||||
});
|
||||
|
||||
renderWithProviders(<ChatInputModel />);
|
||||
|
||||
fireEvent.click(screen.getByTestId("chat-input-llm-model"));
|
||||
fireEvent.click(
|
||||
screen.getByTestId("chat-input-acp-model-option-claude-opus-4-8"),
|
||||
);
|
||||
fireEvent.click(screen.getByTestId("chat-input-acp-model-option-opus[1m]"));
|
||||
|
||||
// Active conversation → live switch keyed by the conversation id from the
|
||||
// navigation context (test-conversation-id), default-write NOT used.
|
||||
expect(switchAcpModelMutate).toHaveBeenCalledWith({
|
||||
conversationId: "test-conversation-id",
|
||||
model: "claude-opus-4-8",
|
||||
model: "opus[1m]",
|
||||
});
|
||||
// Popover closes after a selection.
|
||||
expect(
|
||||
@@ -291,15 +289,13 @@ describe("ChatInputModel", () => {
|
||||
renderWithProviders(<ChatInputModel />);
|
||||
|
||||
fireEvent.click(screen.getByTestId("chat-input-llm-model"));
|
||||
fireEvent.click(
|
||||
screen.getByTestId("chat-input-acp-model-option-claude-sonnet-4-6"),
|
||||
);
|
||||
fireEvent.click(screen.getByTestId("chat-input-acp-model-option-sonnet"));
|
||||
|
||||
// Home / no session → null conversationId routes the hook to the
|
||||
// settings-default write path.
|
||||
expect(switchAcpModelMutate).toHaveBeenCalledWith({
|
||||
conversationId: null,
|
||||
model: "claude-sonnet-4-6",
|
||||
model: "sonnet",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -310,7 +306,7 @@ describe("ChatInputModel", () => {
|
||||
conversation_id: "test-conversation-id",
|
||||
agent_kind: "acp",
|
||||
acp_server: "claude-code",
|
||||
llm_model: "claude-sonnet-4-6",
|
||||
llm_model: "sonnet",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -321,12 +317,12 @@ describe("ChatInputModel", () => {
|
||||
// Cloud ACP conversations support mid-conversation model switching,
|
||||
// so selectable model rows are shown.
|
||||
const selectedRow = screen.getByTestId(
|
||||
"chat-input-acp-model-option-claude-sonnet-4-6",
|
||||
"chat-input-acp-model-option-sonnet",
|
||||
);
|
||||
expect(selectedRow).toBeInTheDocument();
|
||||
expect(selectedRow).toHaveTextContent("Claude Sonnet 4.6");
|
||||
expect(
|
||||
screen.getByTestId("chat-input-acp-model-option-claude-opus-4-8"),
|
||||
screen.getByTestId("chat-input-acp-model-option-opus[1m]"),
|
||||
).toBeInTheDocument();
|
||||
const popover = screen.getByTestId("chat-input-llm-model-popover");
|
||||
expect(popover).toHaveTextContent("Claude Sonnet 4.6");
|
||||
|
||||
@@ -655,13 +655,13 @@ describe("ConversationCard", () => {
|
||||
showLlmProfiles
|
||||
agentKind="acp"
|
||||
acpServer="claude-code"
|
||||
llmModel="sonnet"
|
||||
llmModel="raw-model-id"
|
||||
/>,
|
||||
);
|
||||
|
||||
const chip = screen.getByTestId("conversation-card-agent-chip");
|
||||
expect(chip).toHaveTextContent("sonnet");
|
||||
expect(chip).toHaveAttribute("title", "Claude Code · sonnet");
|
||||
expect(chip).toHaveTextContent("raw-model-id");
|
||||
expect(chip).toHaveAttribute("title", "Claude Code · raw-model-id");
|
||||
expect(
|
||||
within(chip).getByTestId("agent-brand-icon-claude-code"),
|
||||
).toBeInTheDocument();
|
||||
@@ -669,7 +669,7 @@ describe("ConversationCard", () => {
|
||||
|
||||
it("shows the provider's picker label for a known model ID", () => {
|
||||
// When ``llm_model`` is a registry-known ID, the chip renders the
|
||||
// human label ("Claude Opus 4.8") instead of the raw ID — matching
|
||||
// human label ("Claude Opus 4.8 (1M)") instead of the raw ID — matching
|
||||
// what the Settings → Agent picker shows for the same value.
|
||||
renderWithProviders(
|
||||
<ConversationCard
|
||||
@@ -679,13 +679,16 @@ describe("ConversationCard", () => {
|
||||
showLlmProfiles
|
||||
agentKind="acp"
|
||||
acpServer="claude-code"
|
||||
llmModel="claude-opus-4-8"
|
||||
llmModel="opus[1m]"
|
||||
/>,
|
||||
);
|
||||
|
||||
const chip = screen.getByTestId("conversation-card-agent-chip");
|
||||
expect(chip).toHaveTextContent("Claude Opus 4.8");
|
||||
expect(chip).toHaveAttribute("title", "Claude Code · Claude Opus 4.8");
|
||||
expect(chip).toHaveTextContent("Claude Opus 4.8 (1M)");
|
||||
expect(chip).toHaveAttribute(
|
||||
"title",
|
||||
"Claude Code · Claude Opus 4.8 (1M)",
|
||||
);
|
||||
});
|
||||
|
||||
it("falls back to the provider display name for an ACP conversation with no model", () => {
|
||||
|
||||
@@ -171,7 +171,7 @@ describe("ChooseAgentStep", () => {
|
||||
// ``acp_args`` can't survive and concatenate onto the spawn
|
||||
// command at conversation-create time.
|
||||
acp_args: [],
|
||||
acp_model: "claude-opus-4-8",
|
||||
acp_model: "opus[1m]",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -54,10 +54,18 @@ describe("ACP provider registry", () => {
|
||||
});
|
||||
|
||||
it("does not suggest generic default model placeholders", () => {
|
||||
// Model lists are SDK-owned (see ACP_PROVIDERS) — Canvas no longer hand-keeps
|
||||
// them. The claude-code registry intentionally offers an id ``default``
|
||||
// labeled "Default (recommended)", a legitimate, well-labeled choice. Guard
|
||||
// against genuinely empty ids and bare placeholder labels, not the qualified
|
||||
// "Default (recommended)" entry.
|
||||
for (const provider of ACP_PROVIDERS) {
|
||||
for (const model of provider.available_models ?? []) {
|
||||
expect(model.id.toLowerCase()).not.toBe("default");
|
||||
expect(model.label.toLowerCase()).not.toContain("default");
|
||||
expect(model.id.trim(), provider.key).toBeTruthy();
|
||||
expect(
|
||||
model.label.trim().toLowerCase(),
|
||||
`${provider.key}:${model.id}`,
|
||||
).not.toBe("default");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ describe("useChatInputModelState", () => {
|
||||
conversation_id: "c1",
|
||||
agent_kind: "acp",
|
||||
acp_server: "claude-code",
|
||||
llm_model: "claude-sonnet-4-6",
|
||||
llm_model: "sonnet",
|
||||
},
|
||||
});
|
||||
useOptionalConversationIdMock.mockReturnValue({ conversationId: "c1" });
|
||||
@@ -123,7 +123,7 @@ describe("useChatInputModelState", () => {
|
||||
const { result } = renderHook(() => useChatInputModelState());
|
||||
|
||||
expect(result.current.isAcpContext).toBe(true);
|
||||
expect(result.current.currentModelId).toBe("claude-sonnet-4-6");
|
||||
expect(result.current.currentModelId).toBe("sonnet");
|
||||
// Human label resolved from the registry (matches the conversation chip).
|
||||
expect(result.current.displayModel).toBe("Claude Sonnet 4.6");
|
||||
expect(result.current.availableAcpModels).toEqual(
|
||||
|
||||
@@ -266,7 +266,7 @@ describe("AgentSettingsScreen", () => {
|
||||
|
||||
await screen.findByTestId("agent-command-input");
|
||||
expect(screen.getByLabelText("SETTINGS$AGENT_MODEL")).toHaveValue(
|
||||
"Claude Opus 4.8",
|
||||
"Claude Opus 4.8 (1M)",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -297,7 +297,7 @@ describe("AgentSettingsScreen", () => {
|
||||
const call = save.mock.calls[0]?.[0] as {
|
||||
agent_settings_diff?: Record<string, unknown>;
|
||||
};
|
||||
expect(call.agent_settings_diff?.acp_model).toBe("claude-haiku-4-5");
|
||||
expect(call.agent_settings_diff?.acp_model).toBe("haiku");
|
||||
});
|
||||
|
||||
it("clears the model when switching from a built-in provider to Custom", async () => {
|
||||
@@ -324,7 +324,7 @@ describe("AgentSettingsScreen", () => {
|
||||
await screen.findByTestId("agent-command-input");
|
||||
// Form loads with the Claude Code default visible.
|
||||
expect(screen.getByLabelText("SETTINGS$AGENT_MODEL")).toHaveValue(
|
||||
"Claude Opus 4.8",
|
||||
"Claude Opus 4.8 (1M)",
|
||||
);
|
||||
|
||||
// Switch to the Custom preset, then enter a different command — the
|
||||
@@ -380,18 +380,18 @@ describe("AgentSettingsScreen", () => {
|
||||
renderAgentSettingsScreen();
|
||||
await screen.findByTestId("agent-command-input");
|
||||
expect(screen.getByLabelText("SETTINGS$AGENT_MODEL")).toHaveValue(
|
||||
"Claude Opus 4.8",
|
||||
"Claude Opus 4.8 (1M)",
|
||||
);
|
||||
|
||||
const commandInput = screen.getByTestId(
|
||||
"agent-command-input",
|
||||
) as HTMLTextAreaElement;
|
||||
await user.clear(commandInput);
|
||||
await user.type(commandInput, "npx -y @zed-industries/codex-acp@0.15.0");
|
||||
await user.type(commandInput, "npx -y @zed-industries/codex-acp@0.16.0");
|
||||
|
||||
// The model field now reflects the Codex default, not the stale Claude one.
|
||||
expect(screen.getByLabelText("SETTINGS$AGENT_MODEL")).toHaveValue(
|
||||
"GPT-5.5 (medium)",
|
||||
"GPT-5.5",
|
||||
);
|
||||
|
||||
await user.click(screen.getByTestId("agent-save-button"));
|
||||
@@ -403,7 +403,7 @@ describe("AgentSettingsScreen", () => {
|
||||
agent_settings_diff?: Record<string, unknown>;
|
||||
};
|
||||
expect(call.agent_settings_diff?.acp_server).toBe("codex");
|
||||
expect(call.agent_settings_diff?.acp_model).toBe("gpt-5.5/medium");
|
||||
expect(call.agent_settings_diff?.acp_model).toBe("gpt-5.5");
|
||||
});
|
||||
|
||||
it("saves an ACP diff when switching to ACP + Claude Code", async () => {
|
||||
@@ -432,10 +432,10 @@ describe("AgentSettingsScreen", () => {
|
||||
"agent-command-input",
|
||||
)) as HTMLTextAreaElement;
|
||||
expect(commandInput.value).toBe(
|
||||
"npx -y @agentclientprotocol/claude-agent-acp@0.30.0",
|
||||
"npx -y @agentclientprotocol/claude-agent-acp@0.44.0",
|
||||
);
|
||||
expect(screen.getByLabelText("SETTINGS$AGENT_MODEL")).toHaveValue(
|
||||
"Claude Opus 4.8",
|
||||
"Claude Opus 4.8 (1M)",
|
||||
);
|
||||
|
||||
await user.click(screen.getByTestId("agent-save-button"));
|
||||
@@ -457,7 +457,7 @@ describe("AgentSettingsScreen", () => {
|
||||
// ``acp_args`` can't survive and concatenate onto the spawn
|
||||
// command at conversation-create time.
|
||||
acp_args: [],
|
||||
acp_model: "claude-opus-4-8",
|
||||
acp_model: "opus[1m]",
|
||||
});
|
||||
});
|
||||
|
||||
@@ -625,7 +625,7 @@ describe("AgentSettingsScreen", () => {
|
||||
"agent-command-input",
|
||||
)) as HTMLTextAreaElement;
|
||||
expect(cmd.value).toBe(
|
||||
"npx -y @agentclientprotocol/claude-agent-acp@0.30.0 --extra-arg",
|
||||
"npx -y @agentclientprotocol/claude-agent-acp@0.44.0 --extra-arg",
|
||||
);
|
||||
|
||||
// Touch the form to mark it dirty (Save is disabled until isDirty),
|
||||
@@ -647,7 +647,7 @@ describe("AgentSettingsScreen", () => {
|
||||
expect(call.agent_settings_diff?.acp_command).toEqual([
|
||||
"npx",
|
||||
"-y",
|
||||
"@agentclientprotocol/claude-agent-acp@0.30.0",
|
||||
"@agentclientprotocol/claude-agent-acp@0.44.0",
|
||||
"--extra-arg",
|
||||
]);
|
||||
// ``acp_args: []`` resets the API-set args so they don't double up
|
||||
|
||||
@@ -389,16 +389,16 @@ describe("buildAgentServerCommand", () => {
|
||||
// Defaults to the released PyPI version with all SDK packages pinned to same version
|
||||
expect(cmd.args).toEqual([
|
||||
"--from",
|
||||
"openhands-agent-server==1.28.1",
|
||||
"openhands-agent-server==1.29.0",
|
||||
"--with",
|
||||
"openhands-sdk==1.28.1",
|
||||
"openhands-sdk==1.29.0",
|
||||
"--with",
|
||||
"openhands-tools==1.28.1",
|
||||
"openhands-tools==1.29.0",
|
||||
"--with",
|
||||
"openhands-workspace==1.28.1",
|
||||
"openhands-workspace==1.29.0",
|
||||
"agent-server",
|
||||
]);
|
||||
expect(cmd.source).toBe("PyPI (1.28.1, default)");
|
||||
expect(cmd.source).toBe("PyPI (1.29.0, default)");
|
||||
});
|
||||
|
||||
it("uses specific PyPI version when OH_AGENT_SERVER_VERSION is set with all packages pinned", () => {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
"_comment": "Single source of truth for version pins, ports, paths, and defaults shared across the npm and Docker install paths. Read by scripts/dev-safe.mjs, scripts/dev-with-automation.mjs, docker/entrypoint.sh (via generated defaults.env), and .github/workflows/docker.yml.",
|
||||
|
||||
"versions": {
|
||||
"agentServer": "1.28.1",
|
||||
"agentServer": "1.29.0",
|
||||
"agentCanvas": "1.0.0-rc.11",
|
||||
"automation": "1.0.0a10"
|
||||
"automation": "1.0.0a12"
|
||||
},
|
||||
|
||||
"compatibility": {
|
||||
|
||||
Generated
+5
-4
@@ -13,7 +13,7 @@
|
||||
"@microlink/react-json-view": "1.31.20",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@openhands/extensions": "0.6.0",
|
||||
"@openhands/typescript-client": "1.25.0",
|
||||
"@openhands/typescript-client": "1.27.0",
|
||||
"@react-router/node": "7.17.0",
|
||||
"@react-router/serve": "7.17.0",
|
||||
"@tailwindcss/vite": "4.2.4",
|
||||
@@ -3481,9 +3481,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@openhands/typescript-client": {
|
||||
"version": "1.25.0",
|
||||
"resolved": "https://registry.npmjs.org/@openhands/typescript-client/-/typescript-client-1.25.0.tgz",
|
||||
"integrity": "sha512-Xjqg3/aZi+20CYN7ZLzIiH4CqwThFIAvyp8vziu97UDaVIBrZgfXGlSI42/vNh8Dm1y33STMIKfYarMu17n9AQ==",
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/@openhands/typescript-client/-/typescript-client-1.27.0.tgz",
|
||||
"integrity": "sha512-JbDRAN1uqLRvHfty++cxHy2gyXzSG1TpdsN+R+ANMUMpV13fjAW2jOyY4gD7XhZp19PUYqvSfpeE1zXrNeTxvw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@openrouter/sdk": "^0.12.35",
|
||||
"ws": "^8.20.0"
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
"@microlink/react-json-view": "1.31.20",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@openhands/extensions": "0.6.0",
|
||||
"@openhands/typescript-client": "1.25.0",
|
||||
"@openhands/typescript-client": "1.27.0",
|
||||
"@react-router/node": "7.17.0",
|
||||
"@react-router/serve": "7.17.0",
|
||||
"@tailwindcss/vite": "4.2.4",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/check-sdk-version-sync.mjs
|
||||
* EXPECTED_SDK_VERSION=1.28.1 node scripts/check-sdk-version-sync.mjs
|
||||
* EXPECTED_SDK_VERSION=1.29.0 node scripts/check-sdk-version-sync.mjs
|
||||
* node scripts/check-sdk-version-sync.mjs --check-pypi
|
||||
*
|
||||
* Environment variables:
|
||||
@@ -78,7 +78,7 @@ Triggering from other repos:
|
||||
-H "Authorization: token \$GITHUB_TOKEN" \\
|
||||
-H "Accept: application/vnd.github.v3+json" \\
|
||||
https://api.github.com/repos/OpenHands/agent-canvas/dispatches \\
|
||||
-d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.28.1"}}'
|
||||
-d '{"event_type": "sdk-version-check", "client_payload": {"version": "1.29.0"}}'
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
@@ -260,9 +260,9 @@ async function fetchPyPIDependencies(packageName, version) {
|
||||
* Parse PyPI requires_dist array and extract SDK package versions
|
||||
*
|
||||
* PyPI returns dependencies in PEP 508 format like:
|
||||
* "openhands-sdk>=1.28.1,<2.0.0"
|
||||
* "openhands-tools==1.28.1"
|
||||
* "openhands-workspace (>=1.28.1)"
|
||||
* "openhands-sdk>=1.29.0,<2.0.0"
|
||||
* "openhands-tools==1.29.0"
|
||||
* "openhands-workspace (>=1.29.0)"
|
||||
*/
|
||||
function parseSdkVersionsFromRequiresDist(requiresDist) {
|
||||
const versions = {};
|
||||
@@ -276,7 +276,7 @@ function parseSdkVersionsFromRequiresDist(requiresDist) {
|
||||
}
|
||||
|
||||
// Extract the version number - look for patterns like:
|
||||
// ">=1.28.1", "==1.28.1", "(>=1.28.1)", "~=1.28.1"
|
||||
// ">=1.29.0", "==1.29.0", "(>=1.29.0)", "~=1.29.0"
|
||||
// After the package name and before any comma or closing paren
|
||||
const versionPattern = /[><=~!]+\s*([0-9]+(?:\.[0-9]+)*)/;
|
||||
const match = dep.match(versionPattern);
|
||||
|
||||
@@ -394,7 +394,7 @@ export function validateFrontendDependencies(
|
||||
* edits are picked up without a manual reinstall. The agent-server itself
|
||||
* is rebuilt from local source on each invocation (--reinstall).
|
||||
* - OH_AGENT_SERVER_GIT_REF: Git commit SHA or branch name
|
||||
* - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.28.1")
|
||||
* - OH_AGENT_SERVER_VERSION: Specific PyPI version (e.g., "1.29.0")
|
||||
*
|
||||
* If none are set, defaults to the released version specified by
|
||||
* DEFAULT_AGENT_SERVER_VERSION. Set OH_AGENT_SERVER_GIT_REF to use a
|
||||
|
||||
@@ -619,7 +619,7 @@ const MOCK_VERIFIED_MODELS_BY_PROVIDER = MOCK_MODELS.reduce<
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const MOCK_AGENT_SERVER_VERSION = "1.28.1";
|
||||
const MOCK_AGENT_SERVER_VERSION = "1.29.0";
|
||||
|
||||
// --- Handlers for options/config/settings ---
|
||||
// Uses wildcard "*" prefix to match both relative paths and absolute URLs
|
||||
|
||||
Reference in New Issue
Block a user