Skip to content

Commit

Permalink
Make Schema a discriminated union (#296)
Browse files Browse the repository at this point in the history
* Make Schema a discriminated union

This leverages the type system to better describe the API's requirements for schemas. For example, rather than saying that any schema might have an optional `items` property, we're able to express that `items` is required on array schemas and forbidden on all others.

More info on discriminated unions: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions

* Update docs.
  • Loading branch information
rictic authored Nov 18, 2024
1 parent 6a99ed8 commit 3004d3b
Show file tree
Hide file tree
Showing 69 changed files with 892 additions and 337 deletions.
5 changes: 5 additions & 0 deletions .changeset/young-rivers-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@google/generative-ai": minor
---

The schema types are now more specific, using a [discriminated union](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions) based on the 'type' field to more accurately define which fields are allowed.
86 changes: 69 additions & 17 deletions common/api-review/generative-ai-server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@
```ts

// Warning: (ae-incompatible-release-tags) The symbol "ArraySchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface ArraySchema extends BaseSchema {
items: Schema;
maxItems?: number;
minItems?: number;
// (undocumented)
type: typeof SchemaType.ARRAY;
}

// Warning: (ae-internal-missing-underscore) The name "BaseSchema" should be prefixed with an underscore because the declaration is marked as @internal
//
// @internal
export interface BaseSchema {
description?: string;
nullable?: boolean;
}

// Warning: (ae-incompatible-release-tags) The symbol "BooleanSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface BooleanSchema extends BaseSchema {
// (undocumented)
type: typeof SchemaType.BOOLEAN;
}

// @public
export interface CachedContent extends CachedContentBase {
createTime?: string;
Expand Down Expand Up @@ -286,8 +313,7 @@ export interface FunctionDeclarationSchema {
}

// @public
export interface FunctionDeclarationSchemaProperty extends Schema {
}
export type FunctionDeclarationSchemaProperty = Schema;

// @public
export interface FunctionDeclarationsTool {
Expand Down Expand Up @@ -368,6 +394,15 @@ export interface InlineDataPart {
text?: never;
}

// Warning: (ae-incompatible-release-tags) The symbol "IntegerSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface IntegerSchema extends BaseSchema {
format?: "int32" | "int64";
// (undocumented)
type: typeof SchemaType.INTEGER;
}

// @public (undocumented)
export interface ListCacheResponse {
// (undocumented)
Expand All @@ -392,6 +427,27 @@ export interface ListParams {
pageToken?: string;
}

// Warning: (ae-incompatible-release-tags) The symbol "NumberSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface NumberSchema extends BaseSchema {
format?: "float" | "double";
// (undocumented)
type: typeof SchemaType.NUMBER;
}

// Warning: (ae-incompatible-release-tags) The symbol "ObjectSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface ObjectSchema extends BaseSchema {
properties: {
[k: string]: Schema;
};
required?: string[];
// (undocumented)
type: typeof SchemaType.OBJECT;
}

// @public
export enum Outcome {
OUTCOME_DEADLINE_EXCEEDED = "outcome_deadline_exceeded",
Expand All @@ -413,8 +469,7 @@ export interface RequestOptions {
}

// @public
export interface ResponseSchema extends Schema {
}
export type ResponseSchema = Schema;

// @public
export interface RpcStatus {
Expand All @@ -424,19 +479,7 @@ export interface RpcStatus {
}

// @public
export interface Schema {
description?: string;
enum?: string[];
example?: unknown;
format?: string;
items?: Schema;
nullable?: boolean;
properties?: {
[k: string]: Schema;
};
required?: string[];
type?: SchemaType;
}
export type Schema = StringSchema | NumberSchema | IntegerSchema | BooleanSchema | ArraySchema | ObjectSchema;

// @public
export enum SchemaType {
Expand All @@ -453,6 +496,15 @@ export interface SingleRequestOptions extends RequestOptions {
signal?: AbortSignal;
}

// Warning: (ae-incompatible-release-tags) The symbol "StringSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface StringSchema extends BaseSchema {
enum?: string[];
// (undocumented)
type: typeof SchemaType.STRING;
}

// @public
export interface TextPart {
// (undocumented)
Expand Down
86 changes: 69 additions & 17 deletions common/api-review/generative-ai.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
```ts

// Warning: (ae-incompatible-release-tags) The symbol "ArraySchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface ArraySchema extends BaseSchema {
items: Schema;
maxItems?: number;
minItems?: number;
// (undocumented)
type: typeof SchemaType.ARRAY;
}

// @public
export interface BaseParams {
// (undocumented)
Expand All @@ -12,6 +23,14 @@ export interface BaseParams {
safetySettings?: SafetySetting[];
}

// Warning: (ae-internal-missing-underscore) The name "BaseSchema" should be prefixed with an underscore because the declaration is marked as @internal
//
// @internal
export interface BaseSchema {
description?: string;
nullable?: boolean;
}

// @public
export interface BatchEmbedContentsRequest {
// (undocumented)
Expand All @@ -34,6 +53,14 @@ export enum BlockReason {
SAFETY = "SAFETY"
}

// Warning: (ae-incompatible-release-tags) The symbol "BooleanSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface BooleanSchema extends BaseSchema {
// (undocumented)
type: typeof SchemaType.BOOLEAN;
}

// @public
export interface CachedContent extends CachedContentBase {
createTime?: string;
Expand Down Expand Up @@ -355,8 +382,7 @@ export interface FunctionDeclarationSchema {
}

// @public
export interface FunctionDeclarationSchemaProperty extends Schema {
}
export type FunctionDeclarationSchemaProperty = Schema;

// @public
export interface FunctionDeclarationsTool {
Expand Down Expand Up @@ -645,6 +671,15 @@ export interface InlineDataPart {
text?: never;
}

// Warning: (ae-incompatible-release-tags) The symbol "IntegerSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface IntegerSchema extends BaseSchema {
format?: "int32" | "int64";
// (undocumented)
type: typeof SchemaType.INTEGER;
}

// @public
export interface LogprobsCandidate {
logProbability: number;
Expand Down Expand Up @@ -672,6 +707,27 @@ export interface ModelParams extends BaseParams {
tools?: Tool[];
}

// Warning: (ae-incompatible-release-tags) The symbol "NumberSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface NumberSchema extends BaseSchema {
format?: "float" | "double";
// (undocumented)
type: typeof SchemaType.NUMBER;
}

// Warning: (ae-incompatible-release-tags) The symbol "ObjectSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface ObjectSchema extends BaseSchema {
properties: {
[k: string]: Schema;
};
required?: string[];
// (undocumented)
type: typeof SchemaType.OBJECT;
}

// @public
export enum Outcome {
OUTCOME_DEADLINE_EXCEEDED = "outcome_deadline_exceeded",
Expand Down Expand Up @@ -706,8 +762,7 @@ export interface RequestOptions {
}

// @public
export interface ResponseSchema extends Schema {
}
export type ResponseSchema = Schema;

// @public
export interface RetrievalMetadata {
Expand All @@ -731,19 +786,7 @@ export interface SafetySetting {
}

// @public
export interface Schema {
description?: string;
enum?: string[];
example?: unknown;
format?: string;
items?: Schema;
nullable?: boolean;
properties?: {
[k: string]: Schema;
};
required?: string[];
type?: SchemaType;
}
export type Schema = StringSchema | NumberSchema | IntegerSchema | BooleanSchema | ArraySchema | ObjectSchema;

// @public
export enum SchemaType {
Expand Down Expand Up @@ -779,6 +822,15 @@ export interface StartChatParams extends BaseParams {
tools?: Tool[];
}

// Warning: (ae-incompatible-release-tags) The symbol "StringSchema" is marked as @public, but its signature references "BaseSchema" which is marked as @internal
//
// @public
export interface StringSchema extends BaseSchema {
enum?: string[];
// (undocumented)
type: typeof SchemaType.STRING;
}

// @public
export enum TaskType {
// (undocumented)
Expand Down
13 changes: 13 additions & 0 deletions docs/reference/main/generative-ai.arrayschema.items.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [ArraySchema](./generative-ai.arrayschema.md) &gt; [items](./generative-ai.arrayschema.items.md)

## ArraySchema.items property

A schema describing the entries in the array.

**Signature:**

```typescript
items: Schema;
```
13 changes: 13 additions & 0 deletions docs/reference/main/generative-ai.arrayschema.maxitems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [ArraySchema](./generative-ai.arrayschema.md) &gt; [maxItems](./generative-ai.arrayschema.maxitems.md)

## ArraySchema.maxItems property

The maximum number of items in the array.

**Signature:**

```typescript
maxItems?: number;
```
24 changes: 24 additions & 0 deletions docs/reference/main/generative-ai.arrayschema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [ArraySchema](./generative-ai.arrayschema.md)

## ArraySchema interface

Describes an array, an ordered list of values.

**Signature:**

```typescript
export interface ArraySchema extends BaseSchema
```
**Extends:** BaseSchema
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [items](./generative-ai.arrayschema.items.md) | | [Schema](./generative-ai.schema.md) | A schema describing the entries in the array. |
| [maxItems?](./generative-ai.arrayschema.maxitems.md) | | number | _(Optional)_ The maximum number of items in the array. |
| [minItems?](./generative-ai.arrayschema.minitems.md) | | number | _(Optional)_ The minimum number of items in the array. |
| [type](./generative-ai.arrayschema.type.md) | | typeof [SchemaType.ARRAY](./generative-ai.schematype.md) | |
13 changes: 13 additions & 0 deletions docs/reference/main/generative-ai.arrayschema.minitems.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [ArraySchema](./generative-ai.arrayschema.md) &gt; [minItems](./generative-ai.arrayschema.minitems.md)

## ArraySchema.minItems property

The minimum number of items in the array.

**Signature:**

```typescript
minItems?: number;
```
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [Schema](./generative-ai.schema.md) &gt; [enum](./generative-ai.schema.enum.md)
[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [ArraySchema](./generative-ai.arrayschema.md) &gt; [type](./generative-ai.arrayschema.type.md)

## Schema.enum property

Optional. The enum of the property.
## ArraySchema.type property

**Signature:**

```typescript
enum?: string[];
type: typeof SchemaType.ARRAY;
```
21 changes: 21 additions & 0 deletions docs/reference/main/generative-ai.booleanschema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [@google/generative-ai](./generative-ai.md) &gt; [BooleanSchema](./generative-ai.booleanschema.md)

## BooleanSchema interface

Describes a boolean, either 'true' or 'false'.

**Signature:**

```typescript
export interface BooleanSchema extends BaseSchema
```
**Extends:** BaseSchema
## Properties
| Property | Modifiers | Type | Description |
| --- | --- | --- | --- |
| [type](./generative-ai.booleanschema.type.md) | | typeof [SchemaType.BOOLEAN](./generative-ai.schematype.md) | |
Loading

0 comments on commit 3004d3b

Please sign in to comment.