Skip to content

Add SDK v1.23 agent-server API parity helpers#177

Merged
neubig merged 1 commit into
mainfrom
codex/sdk-123-api-parity
May 23, 2026
Merged

Add SDK v1.23 agent-server API parity helpers#177
neubig merged 1 commit into
mainfrom
codex/sdk-123-api-parity

Conversation

@neubig
Copy link
Copy Markdown
Member

@neubig neubig commented May 23, 2026

Summary

  • add typed clients for SDK v1.23.0 agent-server endpoints: hooks, MCP test, and cloud proxy
  • extend existing conversation, settings, file, and workspace helpers for v1.23.0 routes
  • expose the new helpers from the client barrels and add endpoint-mapping tests

Verification

  • npm run build
  • npm test
  • npm run format:check
  • npm run lint (passes with existing warnings)

Copy link
Copy Markdown

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Acceptable - Solid implementation of SDK v1.23.0 API parity with comprehensive test coverage. A few code quality improvements would strengthen type safety and consistency.


Was this automated review useful? React with 👍 or 👎 to this review to help us measure review quality.
Workflow run: https://github.com/OpenHands/typescript-client/actions/runs/26332377297

Comment thread src/types/base.ts
export interface ConfirmationPolicyBase {
type: string;
kind?: string;
type?: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 Important: Dual naming convention creates ambiguity. ConfirmationPolicyBase has both kind? and type? fields, forcing downstream code to check both with fallbacks like policy.type ?? policy.kind. This suggests an incomplete migration between naming conventions.

Suggestion: Pick one field name and deprecate the other, or document which field takes precedence and when each should be used.

this._state.confirmationPolicy = policy as ConfirmationPolicy;
} else {
// Create a simple wrapper
const policyType = (policy as ConfirmationPolicyBase).type ?? policy.kind ?? 'never';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Triple fallback policy.type ?? policy.kind ?? 'never' is fragile and masks the dual-naming inconsistency in ConfirmationPolicyBase. If the base type is fixed to use a single field, this simplifies to a single access.

type: (policy as ConfirmationPolicyBase).type,
requiresConfirmation: () => (policy as ConfirmationPolicyBase).type === 'always',
type: policyType,
requiresConfirmation: () => policyType === 'always' || policyType === 'AlwaysConfirm',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: String literal comparison against both 'always' and 'AlwaysConfirm' suggests another naming inconsistency. Consider defining these as const enums or union types to enforce consistency:

type ConfirmationPolicyKind = 'never' | 'always' | 'NeverConfirm' | 'AlwaysConfirm';

Or normalize to a single convention (e.g., always use PascalCase or always use lowercase).

policyOrRequest: ConfirmationPolicyBase | SetConfirmationPolicyRequest
): Promise<Success> {
const request =
'policy' in policyOrRequest ? policyOrRequest : ({ policy: policyOrRequest } as const);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: Runtime check 'policy' in policyOrRequest works but bypasses TypeScript's type system. Consider a proper type guard:

function isSetConfirmationPolicyRequest(
  value: unknown
): value is SetConfirmationPolicyRequest {
  return typeof value === 'object' && value !== null && 'policy' in value;
}

This makes the intent clearer and is reusable.

conversationId: string,
securityAnalyzerOrRequest: unknown | SetSecurityAnalyzerRequest | null
): Promise<Success> {
const request = isSetSecurityAnalyzerRequest(securityAnalyzerOrRequest)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: The type guard isSetSecurityAnalyzerRequest is defined at the bottom of the file (line 292). Consider moving helper functions near the top of the file after imports, or co-locating them with the methods that use them for better discoverability.

});
}

async loadHooks(request: HooksRequest = {}): Promise<HooksResponse> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: New clients (HooksClient, MCPClient, CloudProxyClient) don't check agent-server version compatibility, unlike WorkspacesClient which calls assertAgentServerSupports(). If these endpoints are v1.23.0+, consider adding version checks or documenting that they'll gracefully fail with 404 on older servers.

Comment thread src/models/api.ts
deleted: boolean;
}

export type SecretValueResponse = string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Suggestion: SecretValueResponse = string is just a type alias for string. Unless you plan to make it a richer type later (e.g., { value: string, encrypted: boolean }), using string directly is simpler and reduces indirection.

Comment on lines +129 to +135
* @deprecated v1.23.0 agent servers use `url` and optional `headers`.
*/
source?: string;
/**
* @deprecated v1.23.0 agent servers use `url` and optional `headers`.
*/
key?: string;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Good: Clear deprecation notices for source and key fields in LookupSecret. The JSDoc comments are helpful for developers migrating from older code.

@all-hands-bot
Copy link
Copy Markdown

Additional Review Analysis

[RISK ASSESSMENT]

  • [Overall PR] ⚠️ Risk Assessment: 🟡 MEDIUM

This PR changes the request format for setConfirmationPolicy from sending the policy object directly to wrapping it in { policy }. While this appears intentional for SDK v1.23.0 API parity (as evidenced by the test expectations and PR description), it introduces backward incompatibility with older agent-server versions that may expect the unwrapped format.

Key risk factors:

  • API contract change: Request body format modified for existing endpoints
  • No runtime version checks: New clients (HooksClient, MCPClient, CloudProxyClient) don't verify server version before making requests
  • Mitigation: Repository is marked as ALPHA software with explicit breaking-changes-expected warning
  • Test coverage: Comprehensive test suite validates new behavior
  • Documentation: Changes are well-documented in test names and PR description

VERDICT:
Worth merging: Adds necessary v1.23.0 API support with solid test coverage. Type consistency issues are minor and don't block functionality.

KEY INSIGHT:
The dual kind/type naming convention in ConfirmationPolicyBase creates cascading complexity - triple fallbacks in LocalConversation, dual string checks, and unclear precedence rules. Consolidating to a single field name would eliminate this technical debt across the codebase.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.
  2. Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
  3. When your PR is merged, the guideline file goes through normal code review by repository maintainers.

Resolve with AI? Install the iterate skill in your agent and run /iterate to automatically drive this PR through CI, review, and QA until it's merge-ready.

Was this review helpful? React with 👍 or 👎 to give feedback.

@neubig neubig force-pushed the codex/sdk-123-api-parity branch from 8024197 to 30d09ba Compare May 23, 2026 12:23
@neubig neubig merged commit 21f71e0 into main May 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants