import { CodeTabs } from '../views/docs/CodeTabs';
import { Callout, NextLink } from '../views/docs/prose';
export const DATETIME_FILTER_SIG_PY = `from guava.helpers.openai import DatetimeFilter

DatetimeFilter(source_list: list[str], client: openai.OpenAI | None = None)
dt_filter.filter(query: str, max_results: int = 5) -> tuple[list[str], list[str]]`;

export const DATETIME_FILTER_SIG_TS = `import { DatetimeFilter } from "@guava-ai/guava-sdk/helpers/openai";

const dtFilter = new DatetimeFilter({ sourceList: string[] });
dtFilter.filter(query: string, maxResults?: number): Promise<[string[], string[]]>`;

export const DATETIME_FILTER_EX_PY = `from guava.helpers.openai import DatetimeFilter

AVAILABLE_SLOTS = [
    "2026-04-16T09:00:00",
    "2026-04-16T10:30:00",
    "2026-04-17T14:00:00",
    "2026-04-18T09:00:00",
]

dt_filter = DatetimeFilter(source_list=AVAILABLE_SLOTS)

matches, suggestions = dt_filter.filter("tomorrow morning", max_results=3)
# matches     == ["2026-04-16T09:00:00", "2026-04-16T10:30:00"]
# suggestions == []  (not needed — matches were found)

matches, suggestions = dt_filter.filter("this Friday at noon", max_results=3)
# matches     == []  (no Friday noon slot exists)
# suggestions == ["2026-04-17T14:00:00", ...]  (nearby alternatives offered)`;

export const DATETIME_FILTER_EX_TS = `import { DatetimeFilter } from "@guava-ai/guava-sdk/helpers/openai";

const AVAILABLE_SLOTS = [
  "2026-04-16T09:00:00",
  "2026-04-16T10:30:00",
  "2026-04-17T14:00:00",
  "2026-04-18T09:00:00",
];

const dtFilter = new DatetimeFilter({ sourceList: AVAILABLE_SLOTS });

const [matches, suggestions] = await dtFilter.filter("tomorrow morning", 3);
// matches     == ["2026-04-16T09:00:00", "2026-04-16T10:30:00"]
// suggestions == []  (not needed — matches were found)`;

export const DATETIME_FILTER_FIELD_EX_PY = `import guava
from guava import Agent
from guava.helpers.openai import DatetimeFilter

agent = Agent(
    name="Scheduler",
    organization="Acme Corp",
    purpose="Help callers schedule appointments.",
)

datetime_filter = DatetimeFilter(source_list=AVAILABLE_SLOTS)

@agent.on_call_start
def on_call_start(call: guava.Call):
    call.set_task(
        "schedule_appointment",
        checklist=[
            guava.Field(
                key="appointment_time",
                field_type="calendar_slot",
                description="Find a time that works for the caller",
                searchable=True,
            ),
        ],
    )

@agent.on_search_query("appointment_time")
def search_appointments(call: guava.Call, query: str):
    return datetime_filter.filter(query, max_results=3)`;

export const DATETIME_FILTER_FIELD_EX_TS = `import * as guava from "@guava-ai/guava-sdk";
import { DatetimeFilter } from "@guava-ai/guava-sdk/helpers/openai";

const agent = new guava.Agent({
  name: "Scheduler",
  organization: "Acme Corp",
  purpose: "Help callers schedule appointments.",
});

const datetimeFilter = new DatetimeFilter({ sourceList: AVAILABLE_SLOTS });

agent.onCallStart(async (call: guava.Call) => {
  await call.setTask({
    taskId: "schedule_appointment",
    checklist: [
      guava.Field({
        key: "appointment_time",
        fieldType: "calendar_slot",
        description: "Find a time that works for the caller",
        searchable: true,
      }),
    ],
  });
});

agent.onSearchQuery("appointment_time", async (_call, query) => {
  return datetimeFilter.filter(query, { maxResults: 3 });
})`;

## DatetimeFilter

`DatetimeFilter` filters a list of ISO 8601 datetime strings to find entries matching a natural-language query (e.g. "tomorrow afternoon"). Returns both matching datetimes and fallback suggestions when no exact match exists.

### Constructor

<CodeTabs
  python={{ code: DATETIME_FILTER_SIG_PY, filename: "signature" }}
  typescript={{ code: DATETIME_FILTER_SIG_TS, filename: "signature" }}
/>

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `source_list` | `list[str]` | Yes | The pool of available appointment datetimes in ISO 8601 format (e.g. `"2026-03-02T09:00:00"`). The model will only return values present in this list. |
| `client` | `openai.OpenAI` | No | An OpenAI client to use. If omitted, a client is created automatically. |

### Methods

**`filter(query: str, max_results: int = 5) -> tuple[list[str], list[str]]`**

Returns a 2-tuple `(matching_appointments, other_appointments)`:
- `matching_appointments`: datetimes from `source_list` that match `query`, capped at `max_results`.
- `other_appointments`: alternative datetimes to suggest when `matching_appointments` is empty, also capped at `max_results`.

### Edge Cases

- Raises `AssertionError` if `max_results` is not an `int`.
- Both output lists are guaranteed to contain only values drawn from `source_list` — the model is explicitly instructed never to hallucinate datetimes.
- Today's date is injected into the prompt automatically, so relative queries like "tomorrow" and "next week" resolve correctly without any date math on the caller's side.
- `other_appointments` may be non-empty even when `matching_appointments` is empty — use it to offer the caller nearby alternatives.

<Callout>
  <span className="text-primary font-semibold">Model details:</span> `DatetimeFilter` uses `gpt-5-mini` with `reasoning.effort = "medium"`. These settings are not configurable.
</Callout>

### Basic Usage

<CodeTabs
  python={{ code: DATETIME_FILTER_EX_PY, filename: "datetime_filter.py" }}
  typescript={{ code: DATETIME_FILTER_EX_TS, filename: "datetime_filter.ts" }}
/>

### Using with `Field` and `on_search_query`

A common pattern is to pair `DatetimeFilter` with a `Field` of type `"calendar_slot"` with `searchable=True`, and wire the filter into the `on_search_query` callback:

<CodeTabs
  python={{ code: DATETIME_FILTER_FIELD_EX_PY, filename: "scheduling_agent.py" }}
  typescript={{ code: DATETIME_FILTER_FIELD_EX_TS, filename: "scheduling_agent.ts" }}
/>

<NextLink section="vector-stores" label="Vector Stores" />
