configure
Version:
Identity layer SDK for AI agents
446 lines (436 loc) • 21 kB
text/typescript
import { OtpStartResponse, OtpVerifyResponse, ImportProfilesRequest, ImportJob, ListConnectorsResponse, ConnectorType, ConnectConnectorResponse, ConfirmConnectorResponse, SyncConnectorResponse, SearchOptions, SearchEmailsResponse, SearchCalendarResponse, SearchFilesResponse, SearchNotesResponse, SearchWebResponse, FetchUrlResponse, CreateEventResponse, SendEmailResponse, ProfileRuntimeOptions, ProfileReadOptions, ProfileReadResult, ProfileSearchOptions, ProfileSearchResult, RememberResponse, ProfileCommitInput, ProfileCommitResult, GenerateDocumentsResponse, ProfileToolsOptions, ConfigureToolDefinition, ConfigureToolCall, ConfigureOptions } from './types.mjs';
export { ActionName, Connector, ConnectorName, ImportCaps, ImportConversation, ImportJobStatus, ImportMessage, ImportMode, ImportProfileUser, ImportQuotaState, ProfileSearchHit, UIResult, UserIdentity, UserProfile } from './types.mjs';
export { getActionTools, getAdvancedTools, getConnectorTools, getDefaultProfileTools, getToolsForOptions, getUITools, toOpenAIFunctions } from './tool-definitions.mjs';
export { ConfigureAccessRequestOptions, ConfigureConfirmationOptions, ConfigureConnectionsOptions, ConfigureController, ConfigureFrame, ConfigureHostedEvent, ConfigureHostedPresentation, ConfigureHostedSurface, ConfigureHostedTheme, ConfigureLinkOptions, ConfigureMemoryCardOptions, ConfigureMemoryImportOptions, ConfigureMountOptions, ConfigurePersonalizationButtonOptions, ConfigurePersonalizationEntry, ConfigureProfileEditorOptions, ConfigureSingleConnectorOptions, ConfigureToolApprovalOptions, ConfigureWindow } from './window.mjs';
/**
* Authentication module for OTP-based authentication
*/
declare class AuthModule {
private baseUrl;
private appKey;
private fetchFn;
private timeout?;
private agent?;
constructor(baseUrl: string, appKey: string, fetchFn: typeof fetch, timeout?: number, agent?: string);
private createAbortSignal;
/**
* Server/headless OTP method. Browser integrations should use `Configure.link()`
* from the hosted iframe script instead.
*
* Sends an OTP to a phone number.
* @param phone - Phone number in E.164 format (e.g., "+14155551234")
*/
sendOtp(phone: string): Promise<OtpStartResponse>;
/**
* Server/headless OTP method. Browser integrations should use `Configure.link()`
* from the hosted iframe script instead.
*
* Verifies an OTP code.
* @param phone - Phone number in E.164 format
* @param code - 6-digit OTP code
*/
verifyOtp(phone: string, code: string, options?: {
externalId?: string;
embed?: boolean;
}): Promise<OtpVerifyResponse>;
/**
* Get a demo authentication token (for development only)
* @returns Promise resolving to demo token
*/
getDemo(): Promise<string>;
}
interface FileEntry {
path: string;
type: 'markdown' | 'json' | 'ref';
metadata: Record<string, unknown>;
updated_at: string;
}
interface FileListResult {
entries: FileEntry[];
count: number;
}
interface FileListOperationOptions {
/** Listing depth (default: 1) */
depth?: number;
/** Max entries (default: 100) */
limit?: number;
}
interface FileReadResult {
path: string;
content: string;
type: 'markdown' | 'json' | 'ref';
metadata: Record<string, unknown>;
tokens: number;
is_directory: boolean;
}
interface FileWriteOperationOptions {
/** Content type (default: 'markdown') */
type?: 'markdown' | 'json';
/** Write mode (default: 'overwrite') */
mode?: 'overwrite' | 'append' | 'merge';
}
interface FileWriteResult {
path: string;
created: boolean;
tokens: number;
}
interface FileSearchHit {
path: string;
type: 'markdown' | 'json' | 'ref';
snippet?: string;
score: number;
}
interface FileSearchResult {
results: FileSearchHit[];
count: number;
}
interface FileSearchOperationOptions {
/** Limit to path prefix (default: '/') */
scope?: string;
/** Max results (default: 10) */
limit?: number;
/** Return only matching paths without snippets (default: false) */
filesOnly?: boolean;
}
interface FileDeleteResult {
deleted: number;
}
type FileUserOptions = {
token?: string;
/** Developer app-local user ID for unlinked profiles. */
externalId?: string;
/** Advanced raw file routes may still require an explicit Configure user id. */
userId?: string;
};
type FileReadOptions = FileUserOptions & {
path: string;
};
type FileWriteOptions = FileUserOptions & FileWriteOperationOptions & {
path: string;
content: string;
};
type FileListOptions = FileUserOptions & FileListOperationOptions & {
path?: string;
};
type FileSearchOptions = FileUserOptions & FileSearchOperationOptions & {
path?: string;
query: string;
};
type FileDeleteOptions = FileUserOptions & {
path: string;
};
declare class FilesModule {
private baseUrl;
private appKey;
private fetchFn;
private timeout?;
private defaultExternalId?;
constructor(baseUrl: string, appKey: string, fetchFn: typeof fetch, timeout?: number | undefined, defaultExternalId?: string | undefined);
private getHeaders;
private resolveUserId;
private profileUrl;
private createAbortSignal;
list(options?: FileListOptions): Promise<FileListResult>;
read(options: FileReadOptions): Promise<FileReadResult | null>;
write(options: FileWriteOptions): Promise<FileWriteResult>;
search(options: FileSearchOptions): Promise<FileSearchResult>;
delete(options: FileDeleteOptions): Promise<FileDeleteResult>;
}
declare class ImportRequester {
private baseUrl;
private apiKey;
private fetchFn;
private timeout?;
constructor(baseUrl: string, apiKey: string, fetchFn: typeof fetch, timeout?: number | undefined);
importProfiles(input: ImportProfilesRequest): Promise<ImportJob>;
getJob(jobId: string): Promise<ImportJob>;
private request;
private createAbortSignal;
}
declare class ImportJobsModule {
private requester;
constructor(requester: ImportRequester);
get(jobId: string): Promise<ImportJob>;
}
/**
* Connector module for managing connected services and live external operations
* Handles Gmail, Calendar, Drive, Notion integrations + search/action methods
*/
declare class ConnectorsModule {
private baseUrl;
private appKey;
private fetchFn;
private timeout?;
constructor(baseUrl: string, appKey: string, fetchFn: typeof fetch, timeout?: number);
private getHeaders;
private createAbortSignal;
/**
* List all available connectors and their connection status
*/
list(authToken: string): Promise<ListConnectorsResponse>;
/**
* Start connecting a connector (initiates OAuth flow)
*
* @example
* ```typescript
* const { url, connectionRequestId } = await configure.connectors.connect(token, 'gmail', 'myapp://callback');
* ```
*/
connect(authToken: string, connector: ConnectorType, callbackUrl?: string, forceNew?: boolean): Promise<ConnectConnectorResponse>;
/**
* Confirm connector connection after OAuth callback
*/
confirm(authToken: string, connector: ConnectorType, connectionRequestId: string): Promise<ConfirmConnectorResponse>;
/**
* Sync a connected connector to refresh data
*/
sync(authToken: string, connector: ConnectorType): Promise<SyncConnectorResponse>;
/**
* Sync all connected connectors to refresh profile data.
* Triggers data pull from Gmail, Calendar, Drive, Notion into the user's profile.
*/
syncAll(authToken: string, connectors?: ConnectorType[]): Promise<{
userId: string;
synced: Record<string, unknown>;
}>;
/**
* Disconnect a connector
*/
disconnect(authToken: string, connector: ConnectorType): Promise<void>;
/**
* Disconnect all connectors
*/
disconnectAll(authToken: string): Promise<void>;
/**
* Search the user's Gmail
* Results are automatically saved to the user's profile.
*
* @example
* ```typescript
* const results = await configure.connectors.searchEmails(token, 'flight confirmation');
* ```
*/
searchEmails(authToken: string, query: string, options?: SearchOptions): Promise<SearchEmailsResponse>;
/**
* Get the user's calendar events
* Results are automatically saved to the user's profile.
*/
getCalendar(authToken: string, range?: 'today' | 'tomorrow' | 'week' | 'month'): Promise<SearchCalendarResponse>;
/**
* Search the user's Google Drive files
* Results are automatically saved to the user's profile.
*/
searchFiles(authToken: string, query: string, options?: SearchOptions): Promise<SearchFilesResponse>;
/**
* Search the user's Notion pages
* Results are automatically saved to the user's profile.
*/
searchNotes(authToken: string, query: string, options?: SearchOptions): Promise<SearchNotesResponse>;
/**
* Search the web.
* Results are automatically saved to the user's profile.
* No user connection required — works for all authenticated users.
*/
searchWeb(authToken: string, query: string, options?: SearchOptions): Promise<SearchWebResponse>;
/**
* Fetch a web page's content by URL.
* Returns the page title and readable text content.
* No user connection required — works for all authenticated users.
*/
fetchUrl(authToken: string, url: string, options?: {
maxLength?: number;
}): Promise<FetchUrlResponse>;
/**
* Create a calendar event for the user
* Requires the user to have Google Calendar connected.
*/
createCalendarEvent(authToken: string, event: {
title: string;
startTime: string;
endTime: string;
description?: string;
location?: string;
}): Promise<CreateEventResponse>;
/**
* Send an email on behalf of the user
* Requires the user to have Gmail connected.
*/
sendEmail(authToken: string, email: {
to: string;
subject: string;
body: string;
}): Promise<SendEmailResponse>;
}
interface PrivateRuntimeCorrelation {
sessionId: string;
runtimeScopeId: string;
readId?: string;
}
declare class ProfileRequester {
private baseUrl;
private appKey;
private fetchFn;
private timeout?;
private defaultExternalId?;
constructor(baseUrl: string, appKey: string, fetchFn: typeof fetch, timeout?: number | undefined, defaultExternalId?: string | undefined);
private getHeaders;
private resolveSubject;
private createAbortSignal;
read(runtime: ProfileRuntimeOptions, options?: ProfileReadOptions, correlation?: PrivateRuntimeCorrelation): Promise<ProfileReadResult>;
search(runtime: ProfileRuntimeOptions, options?: ProfileSearchOptions | string, correlation?: PrivateRuntimeCorrelation): Promise<ProfileSearchResult>;
remember(runtime: ProfileRuntimeOptions, fact: string): Promise<RememberResponse>;
commit(runtime: ProfileRuntimeOptions, input: ProfileCommitInput, correlation?: PrivateRuntimeCorrelation): Promise<ProfileCommitResult>;
generateDocuments(runtime: ProfileRuntimeOptions, documents?: ('user.md' | 'soul.md' | 'preferences.md' | 'context.md' | 'all')[]): Promise<GenerateDocumentsResponse>;
}
declare class ProfileRuntime {
private requester;
private connectorRequester;
private filesRequester;
private runtime;
private enabledToolNames;
private readonly sessionId;
private runtimeScopeId;
private pendingReadIds;
constructor(requester: ProfileRequester, connectorRequester: ConnectorsModule, filesRequester: FilesModule, runtime: ProfileRuntimeOptions);
read: (options?: ProfileReadOptions) => Promise<ProfileReadResult>;
search: (options?: ProfileSearchOptions | string) => Promise<ProfileSearchResult>;
remember: (fact: string) => Promise<RememberResponse>;
commit: (input: ProfileCommitInput) => Promise<ProfileCommitResult>;
tools: (options?: ProfileToolsOptions) => ConfigureToolDefinition[];
executeTool: (toolCall: ConfigureToolCall) => Promise<unknown>;
private correlation;
private recordObligations;
}
declare function validateAgentHandle(agent: string): string;
declare class Configure {
/** Server/headless authentication helpers. Browser integrations should use Configure Link. */
readonly auth: AuthModule;
/** Connector management and direct connector operations. */
readonly connectors: ConnectorsModule;
/** Advanced raw profile file operations. */
readonly files: FilesModule;
/** Server-side profile import/backfill job status helpers. */
readonly importJobs: ImportJobsModule;
private readonly profileRequester;
private readonly importRequester;
constructor(options?: ConfigureOptions);
profile(options?: ProfileRuntimeOptions): ProfileRuntime;
importProfiles(input: ImportProfilesRequest): Promise<ImportJob>;
}
/**
* Error codes returned by SDK methods.
* Use these to programmatically handle specific failure modes.
*
* @example
* ```typescript
* import { ConfigureError, ErrorCode } from 'configure';
*
* try {
* await profile.read();
* } catch (e) {
* if (e instanceof ConfigureError && e.code === ErrorCode.AUTH_REQUIRED) {
* // Token expired — re-authenticate
* }
* }
* ```
*/
declare const ErrorCode: {
/** No API key provided to Configure */
readonly API_KEY_MISSING: "API_KEY_MISSING";
/** Token is missing, invalid, or expired (HTTP 401/403) */
readonly AUTH_REQUIRED: "AUTH_REQUIRED";
/** Input failed validation before reaching the API */
readonly INVALID_INPUT: "INVALID_INPUT";
/** The requested tool is not connected for this user (HTTP 400) */
readonly TOOL_NOT_CONNECTED: "TOOL_NOT_CONNECTED";
/** Network request failed (DNS, connection refused, etc.) */
readonly NETWORK_ERROR: "NETWORK_ERROR";
/** Too many requests (HTTP 429) */
readonly RATE_LIMITED: "RATE_LIMITED";
/** Resource not found (HTTP 404) */
readonly NOT_FOUND: "NOT_FOUND";
/** Server error (HTTP 5xx) */
readonly SERVER_ERROR: "SERVER_ERROR";
/** Request timed out */
readonly TIMEOUT: "TIMEOUT";
/** Not authorized for this resource (HTTP 403, distinct from AUTH_REQUIRED) */
readonly ACCESS_DENIED: "ACCESS_DENIED";
/** Tool operation failed (provider error, misconfiguration) */
readonly TOOL_ERROR: "TOOL_ERROR";
/** Billing/quota limit reached (HTTP 402) */
readonly PAYMENT_REQUIRED: "PAYMENT_REQUIRED";
/** A prior portable profile read must be committed before another portable read. */
readonly COMMIT_REQUIRED: "COMMIT_REQUIRED";
};
type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
/** Optional structured error details from a backend response. */
interface ErrorDetails {
type?: string;
param?: string | null;
retryable?: boolean;
suggestedAction?: string | null;
docUrl?: string | null;
retryAfter?: number | null;
requestId?: string;
}
/**
* Typed error thrown by all SDK methods.
* Always has a `code` property for programmatic handling.
*/
declare class ConfigureError extends Error {
/** Machine-readable error code (see {@link ErrorCode}) */
readonly code: ErrorCodeValue;
/** HTTP status code from the API response, if applicable */
readonly statusCode?: number;
/** Backend error type (e.g., "authentication_error", "tool_error") */
readonly type?: string;
/** The field or parameter that caused the error, if applicable */
readonly param?: string | null;
/** Whether the same request might succeed if retried */
readonly retryable?: boolean;
/** Machine-readable suggested next action (e.g., "reauthenticate", "connect_tool") */
readonly suggestedAction?: string | null;
/** Link to error documentation */
readonly docUrl?: string | null;
/** Seconds to wait before retrying (rate limits) */
readonly retryAfter?: number | null;
/** Request ID from the backend response */
readonly requestId?: string;
constructor(code: ErrorCodeValue, message: string, statusCode?: number, details?: ErrorDetails);
/**
* Create a ConfigureError from an HTTP response body.
* Parses structured error responses ({ error: { type, code, message, ... } })
* and falls back to status-code mapping for legacy string responses.
*/
static fromResponse(status: number, body: Record<string, unknown>): ConfigureError;
/**
* Create a ConfigureError from a caught exception (network failures, timeouts).
*/
static fromCatch(error: unknown, fallbackMessage: string): ConfigureError;
}
/**
* Classify any caught error into a ConfigureError.
* Works with SDK errors, Anthropic errors, network errors, or plain strings.
* Use in agent catch blocks for errors from any source.
*/
declare function classifyError(error: unknown): ConfigureError;
/**
* Best-practice prompt guidelines for agents handling personal data through Configure.
*
* Append to your system prompt, or use `profile.format({ guidelines: true })` to
* include them automatically after the profile context.
*
* @example
* ```typescript
* import { Configure, CONFIGURE_GUIDELINES } from 'configure';
*
* const configure = new Configure({ apiKey: process.env.CONFIGURE_API_KEY, agent: 'your-agent' });
* const runtime = configure.profile({ token });
* const { profile } = await runtime.read();
* const context = profile.format(); // or profile.format({ guidelines: true })
*
* const systemPrompt = `You are TravelBot.\n\n${context}\n\n${CONFIGURE_GUIDELINES}`;
* ```
*/
declare const CONFIGURE_GUIDELINES = "CONFIGURE GUIDELINES \u2014 handling personal data responsibly\n\nGROUNDING:\n- Only state specific facts (dates, names, amounts, locations) if they appear in the user's profile context or tool results.\n- Never fabricate or assume personal information. If you lack data, say so.\n- If the profile context seems incomplete, use profile or connector tools to retrieve data \u2014 do not guess.\n- Resolve relative dates like \"yesterday\", \"last week\", and \"last month\" against the runtime's current date/time before searching profile or connector data.\n\nTRANSPARENCY:\n- When referencing personal data, briefly cite your source: \"from your profile\", \"from another agent\", \"from your Gmail\", \"from your calendar\", etc.\n- If the user asks how you know something, explain clearly \u2014 you found it in their connected data.\n- When using web search results, include source URLs so users can verify.\n\nPROFILE SOURCES:\n- For \"what does <agent/source> know about me?\", use configure_profile_search with query \"*\" and the explicit source handle.\n- For \"what did I talk about last week/month/yesterday?\", search with date filters after resolving the date range.\n- For \"what agents have profile data about me?\", use configure_profile_read with sections [\"agents\"] or list-style configure_profile_search with query \"*\".\n- If results are filtered or hiddenSources is present, do not reveal hidden contents. It is okay to say that a source exists but is hidden from this agent.\n- Do not confuse profile sources with connectors. Profile sources are agents that wrote profile data; connectors are external accounts like Gmail, Calendar, Drive, and Notion.\n\nCONNECTORS:\n- When a connector-backed tool returns a connection error or \"not connected\" status, do not echo the error. Let the user know naturally \u2014 e.g. \"I'd need access to your calendar for that \u2014 would you like to connect it?\"\n- Do not repeatedly prompt the user to connect accounts they have already declined or been asked about.\n\nCONVERSATION EFFICIENCY:\n- Check conversation history before re-searching \u2014 you may have already retrieved the data.\n- If a search didn't find what the user needs, try different queries with synonyms or alternative phrasing.";
export { CONFIGURE_GUIDELINES, Configure, ConfigureError, ConfigureOptions, ConfigureToolCall, ConfigureToolDefinition, ConfirmConnectorResponse, ConnectConnectorResponse, ConnectorType, ErrorCode, type ErrorCodeValue, type FileDeleteOptions, type FileDeleteResult, type FileEntry, type FileListOperationOptions, type FileListOptions, type FileListResult, type FileReadOptions, type FileReadResult, type FileSearchHit, type FileSearchOperationOptions, type FileSearchOptions, type FileSearchResult, type FileWriteOperationOptions, type FileWriteOptions, type FileWriteResult, ImportJob, ImportProfilesRequest, ListConnectorsResponse, ProfileCommitInput, ProfileCommitResult, ProfileReadOptions, ProfileReadResult, ProfileRuntimeOptions, ProfileSearchOptions, ProfileSearchResult, ProfileToolsOptions, SyncConnectorResponse, classifyError, validateAgentHandle };