Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(client): typedoc docs gen for phoenix-client #6504

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/typescript-packages-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ jobs:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: Release docs
# Run pnpm run docs in js/packages/phoenix-client
# Deploy the static files in js/packages/phoenix-client/docs to github pages
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ sdist
# Server static files
/src/phoenix/server/static/*

# Docgen
/js/**/docs

# Data files
*.csv
!tests/**/fixtures/*.csv
Expand Down
1 change: 1 addition & 0 deletions js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"prettier:write": "prettier --write .",
"type:check": "pnpm run -r type:check",
"lint": "eslint . --ext .ts",
"build": "pnpm run -r build",
"ci:version": "pnpm changeset version",
"ci:publish": "pnpm run -r build && pnpm publish -r --access public --provenance"
},
Expand Down
5 changes: 4 additions & 1 deletion js/packages/phoenix-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
"build": "tsc --build tsconfig.json tsconfig.esm.json && tsc-alias -p tsconfig.esm.json",
"postbuild": "echo '{\"type\": \"module\"}' > ./dist/esm/package.json && rimraf dist/test dist/examples",
"type:check": "tsc --noEmit",
"test": "vitest --typecheck"
"test": "vitest --typecheck",
"docs": "typedoc",
"docs:preview": "pnpx http-server ./docs -p 8080 -o"
},
"keywords": [],
"author": "",
Expand All @@ -52,6 +54,7 @@
"openai": "^4.77.0",
"openapi-typescript": "^7.4.1",
"tsx": "^4.19.1",
"typedoc": "^0.27.7",
"vitest": "^2.1.8"
},
"dependencies": {
Expand Down
30 changes: 24 additions & 6 deletions js/packages/phoenix-client/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import createOpenApiClient, { ClientOptions } from "openapi-fetch";
import createOpenApiClient, { type ClientOptions } from "openapi-fetch";
import type {
paths as oapiPathsV1,
components as oapiComponentsV1,
Expand All @@ -14,7 +14,7 @@ type componentsV1 = oapiComponentsV1;
type operationsV1 = oapiOperationsV1;

/**
* Generated openapi types for the Phoenix client
* Generated openapi types for the Phoenix client, by API version.
*/
export type Types = {
V1: {
Expand All @@ -29,6 +29,9 @@ export type Types = {
* defaults < environment < explicit options
*
* Headers are simply replaced, not merged.
*
* You can call this function before instantiating the client if you need to retain access
* to the options that were passed in to the client.
*/
export const getMergedOptions = ({
options = {},
Expand All @@ -49,10 +52,25 @@ export const getMergedOptions = ({
/**
* Create a Phoenix client.
*
* The client is strongly typed and uses generated openapi types.
*
* @example
* ```ts
* import { createClient } from "@arize/phoenix-client";
*
* const client = createClient();
*
* const response = await client.GET("/v1/traces");
* // ^ path string is strongly typed, and completion works with autocomplete
* // path parameters, query parameters, and request body are also strongly typed based on the openapi spec,
* // the path, and the method.
* ```
*
* @param config - The configuration to use for the client.
* @param config.options - The options to use for the client's OpenAPI Fetch wrapper.
* @param config.getEnvironmentOptions - The function to use to get the environment options.
* @returns The Phoenix client.
* @param config.options - The options to use for [openapi-fetch.createOpenApiClient](https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch).
* @param config.getEnvironmentOptions - The function to use to get the environment options. By default, a function that
* returns `process.env` is used.
* @returns The Phoenix client as a strongly typed [openapi-fetch](https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch) client.
*/
export const createClient = (
config: {
Expand All @@ -65,6 +83,6 @@ export const createClient = (
};

/**
* The type of the Phoenix client
* Resolved type of the Phoenix client
*/
export type PhoenixClient = ReturnType<typeof createClient>;
12 changes: 9 additions & 3 deletions js/packages/phoenix-client/src/experiments/runExperiment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ import { promisifyResult } from "../utils/promisifyResult";
import invariant from "tiny-invariant";
import { pluralize } from "../utils/pluralize";
import { ClientFn } from "../types/core";
import { getDatasetLike } from "../utils/getDatasetLike";
import { getDatasetBySelector } from "../utils/getDatasetBySelector";
import { type Logger } from "../types/logger";

/**
* Parameters for running an experiment.
*
* @experimental This feature is not complete, and will change in the future.
* @deprecated This function will be un-marked as deprecated once the experimental feature flag is removed.
*/
export type RunExperimentParams = ClientFn & {
/**
* An optional name for the experiment.
Expand Down Expand Up @@ -70,7 +76,7 @@ export async function runExperiment({
record = true,
}: RunExperimentParams): Promise<RanExperiment> {
const client = _client ?? createClient();
const dataset = await getDatasetLike({ dataset: _dataset, client });
const dataset = await getDatasetBySelector({ dataset: _dataset, client });
invariant(dataset, `Dataset not found`);
invariant(dataset.examples.length > 0, `Dataset has no examples`);
const experimentName =
Expand Down Expand Up @@ -223,7 +229,7 @@ export async function evaluateExperiment({
logger: Logger;
}): Promise<RanExperiment> {
const client = _client ?? createClient();
const dataset = await getDatasetLike({
const dataset = await getDatasetBySelector({
dataset: experiment.datasetId,
client,
});
Expand Down
2 changes: 1 addition & 1 deletion js/packages/phoenix-client/src/prompts/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { PromptModelProvider } from "../types/prompts";

/**
* A mapping of ModelProvider to a human-readable string
* A mapping of PromptModelProvider to a human-readable string
*/
export const PromptModelProviders: Record<PromptModelProvider, string> = {
OPENAI: "OpenAI",
Expand Down
25 changes: 20 additions & 5 deletions js/packages/phoenix-client/src/prompts/createPrompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import {
import { assertUnreachable } from "../utils/assertUnreachable";

/**
* Parameters to crate a prompt
* Parameters to create a prompt
*/
export interface CreatePromptParams extends ClientFn, PromptData {
/**
* The name of the promt
* The name of the prompt
*/
name: string;
/**
Expand All @@ -31,8 +31,12 @@ export interface CreatePromptParams extends ClientFn, PromptData {
}

/**
* Create a prompt and store it in Phoenix
* If a prompt with the same name exists, a new version of the prompt will be appended to the history
* Create a prompt and store it in Phoenix.
*
* If a prompt with the same name exists, a new version of the prompt will be appended to the history.
*
* @param params - The parameters to create a prompt.
* @returns The created prompt version.
*/
export async function createPrompt({
client: _client,
Expand All @@ -54,7 +58,13 @@ export async function createPrompt({
}

interface PromptVersionInputBase {
/**
* The description of the prompt version.
*/
description?: string;
/**
* The name of the model to use for the prompt version.
*/
modelName: PromptVersionData["model_name"];
/**
* The template for the prompt version.
Expand Down Expand Up @@ -99,7 +109,12 @@ type PromptVersionInput =
| GooglePromptVersionInput;

/**
* A helper function to construct a prompt version declaratively
* A helper function to construct a prompt version declaratively.
*
* The output of this function can be used to create a prompt version in Phoenix.
*
* @param params - The parameters to create a prompt version.
* @returns Structured prompt version data, not yet persisted to Phoenix.
*/
export function promptVersion(params: PromptVersionInput): PromptVersionData {
const {
Expand Down
7 changes: 5 additions & 2 deletions js/packages/phoenix-client/src/prompts/getPrompt.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createClient } from "../client";
import { ClientFn } from "../types/core";
import { PromptSelector, PromptVersion } from "../types/prompts";
import { getPromptBySelector } from "../utils/getPromptVersionLike";
import { getPromptBySelector } from "../utils/getPromptBySelector";

/**
* Parameters for the getPrompt function
* Parameters for getting a prompt from Phoenix.
*/
export interface GetPromptParams extends ClientFn {
/**
Expand All @@ -15,6 +15,9 @@ export interface GetPromptParams extends ClientFn {

/**
* Get a prompt from the Phoenix API.
*
* @param params - The parameters to get a prompt.
* @returns The prompt version, or null if it does not exist.
*/
export async function getPrompt({
client: _client,
Expand Down
13 changes: 12 additions & 1 deletion js/packages/phoenix-client/src/prompts/sdks/toSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,23 @@ type ToSDKParams<T extends SupportedSDK, V extends Variables = Variables> = {
/**
* Convert a Phoenix prompt to a specific SDK's parameters
*
* @example
* @example quickstart
* ```ts
* // Get a prompt from Phoenix, use it via openai sdk
* const prompt = await getPrompt({ prompt: { name: "my-prompt" } });
* const openaiParams = toSDK({ sdk: "openai", prompt });
* const response = await openai.chat.completions.create(openaiParams);
* ```
*
* @example type safety
* ```ts
* // Enforce variable types via Generic argument
* const prompt = await getPrompt({ prompt: { name: "my-prompt" } });
* const openaiParams = toSDK<"openai", { name: string }>({ sdk: "openai", prompt, variables: { name: "John" } });
* ```
*
* @param params - The parameters to convert a prompt to an SDK's parameters
* @returns The SDK's parameters
*/
export const toSDK = <T extends SupportedSDK, V extends Variables = Variables>({
sdk: _sdk,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { Dataset } from "../types/datasets";
* Parameters for the getDatasetLike function
*/
export type GetDatasetLikeParams = {
/**
* The dataset to get. Can be in the form of a dataset id, an array of examples, or a dataset object.
*/
dataset: Dataset | string | Example[];
client: PhoenixClient;
};
Expand All @@ -19,10 +22,10 @@ export type GetDatasetLikeParams = {
* If the input is an array of examples, create a new dataset from the examples then return it.
* If the input is a dataset, return it as is.
*
* @param dataset - The dataset to get.
* @param params - The parameters to get a dataset.
* @returns The dataset.
*/
export async function getDatasetLike({
export async function getDatasetBySelector({
dataset,
client,
}: GetDatasetLikeParams): Promise<Dataset | null> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import { createClient } from "../client";
* Parameters for the getPromptBySelector function
*/
export type GetPromptBySelectorParams = ClientFn & {
/**
* The prompt to get. Can be in the form of a prompt id, a prompt version id, a prompt name, or a prompt name + tag.
*/
prompt: PromptSelector;
};

Expand All @@ -17,6 +20,9 @@ export type GetPromptBySelectorParams = ClientFn & {
* if the input is a prompt version id, fetch that prompt version.
* if the input is a prompt tag and name, fetch the prompt version that has that tag and name.
* if the input is a prompt name, fetch the latest prompt version from the client.
*
* @param params - The parameters to get a prompt.
* @returns The nearest prompt version that matches the selector, or null if it does not exist.
*/
export async function getPromptBySelector({
client: _client,
Expand Down
34 changes: 34 additions & 0 deletions js/packages/phoenix-client/typedoc.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "ArizeAI Phoenix Client",
// We have to manually keep this in sync with the entry points in the package.json
// Other projects seem to use one large entry point, but we have a lot of small ones
// The jury is out on which is better
"entryPoints": ["src/**/index.ts", "src/utils/*.ts", "src/types/*.ts"],
// Default kind sort order, but with "Function" first
// https://typedoc.org/documents/Options.Organization.html#kindsortorder
"kindSortOrder": [
"Function",
"Reference",
"Project",
"Module",
"Namespace",
"Enum",
"EnumMember",
"Class",
"Interface",
"TypeAlias",
"Constructor",
"Property",
"Variable",
"Accessor",
"Method",
"Parameter",
"TypeParameter",
"TypeLiteral",
"CallSignature",
"ConstructorSignature",
"IndexSignature",
"GetSignature",
"SetSignature",
],
}
Loading