Skip to content
Closed
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
42 changes: 42 additions & 0 deletions src/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ export class OpenRouterChatLanguageModel implements LanguageModelV2 {
model: this.modelId,
models: this.settings.models,

...(this.modelId.endsWith(':online') && !this.settings.plugins && {
plugins: [{ type: 'web' as const }]
}),
Comment on lines +96 to +98
Copy link
Member Author

Choose a reason for hiding this comment

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

remove this


// model specific settings:
logit_bias: this.settings.logitBias,
logprobs:
Expand Down Expand Up @@ -131,6 +135,13 @@ export class OpenRouterChatLanguageModel implements LanguageModelV2 {
reasoning: this.settings.reasoning,
usage: this.settings.usage,

// Web search settings:
plugins: this.settings.plugins,
web_search_options: this.settings.web_search_options,

// Provider routing settings:
provider: this.settings.provider,

// extra body:
...this.config.extraBody,
...this.settings.extraBody,
Expand Down Expand Up @@ -318,6 +329,17 @@ export class OpenRouterChatLanguageModel implements LanguageModelV2 {
}
}

if (choice.message.annotations) {
for (const annotation of choice.message.annotations) {
if (annotation.type === 'url_citation') {
content.push({
type: 'text' as const,
text: `[Citation: ${annotation.title || annotation.url}](${annotation.url})`,
});
}
}
}
Comment on lines +332 to +341
Copy link
Member Author

Choose a reason for hiding this comment

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

Check if the aisdk has better data type for citation/annotation


return {
content,
finishReason: mapOpenRouterFinishReason(choice.finish_reason),
Expand Down Expand Up @@ -590,6 +612,26 @@ export class OpenRouterChatLanguageModel implements LanguageModelV2 {
});
}

if (delta.annotations) {
for (const annotation of delta.annotations) {
if (annotation.type === 'url_citation') {
if (!textStarted) {
textId = openrouterResponseId || generateId();
controller.enqueue({
type: 'text-start',
id: textId,
});
textStarted = true;
}
controller.enqueue({
type: 'text-delta',
delta: `[Citation: ${annotation.title || annotation.url}](${annotation.url})`,
id: textId || generateId(),
});
}
}
}

if (delta.tool_calls != null) {
for (const toolCallDelta of delta.tool_calls) {
const index = toolCallDelta.index ?? toolCalls.length - 1;
Expand Down
28 changes: 28 additions & 0 deletions src/chat/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ export const OpenRouterNonStreamChatCompletionResponseSchema =
}),
)
.optional(),

/**
* Web search annotations containing citation information
*/
annotations: z.array(
z.object({
type: z.literal('url_citation'),
url: z.string(),
title: z.string().optional(),
content: z.string().optional(),
start_index: z.number().optional(),
end_index: z.number().optional(),
})
).optional(),
}),
index: z.number().nullish(),
logprobs: z
Expand Down Expand Up @@ -103,6 +117,20 @@ export const OpenRouterStreamChatCompletionChunkSchema = z.union([
}),
)
.nullish(),

/**
* Web search annotations containing citation information
*/
annotations: z.array(
z.object({
type: z.literal('url_citation'),
url: z.string(),
title: z.string().optional(),
content: z.string().optional(),
start_index: z.number().optional(),
end_index: z.number().optional(),
Comment on lines +127 to +131
Copy link
Member Author

Choose a reason for hiding this comment

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

wrong schema -- this should be:

  url_citation: z.object({
    end_index: z.number(),
    start_index: z.number(),
    title: z.string(),
    url: z.string(),
    content: z.string().optional(),
  }),

})
).optional(),
})
.nullish(),
logprobs: z
Expand Down
77 changes: 77 additions & 0 deletions src/types/openrouter-chat-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,81 @@ A unique identifier representing your end-user, which can help OpenRouter to
monitor and detect abuse. Learn more.
*/
user?: string;

/**
* Web search plugin configuration for enabling web search capabilities
*/
plugins?: Array<{
type: 'web';
/**
* Maximum number of search results to include (default: 5)
*/
max_results?: number;
/**
* Custom search prompt to guide the search query
*/
search_prompt?: string;
}>;

/**
* Built-in web search options for models that support native web search
*/
web_search_options?: {
/**
* Maximum number of search results to include
*/
max_results?: number;
/**
* Custom search prompt to guide the search query
*/
search_prompt?: string;
};

/**
* Provider routing preferences to control request routing behavior
*/
provider?: {
/**
* List of provider slugs to try in order (e.g. ["anthropic", "openai"])
*/
order?: string[];
/**
* Whether to allow backup providers when primary is unavailable (default: true)
*/
allow_fallbacks?: boolean;
/**
* Only use providers that support all parameters in your request (default: false)
*/
require_parameters?: boolean;
/**
* Control whether to use providers that may store data
*/
data_collection?: 'allow' | 'deny';
/**
* List of provider slugs to allow for this request
*/
only?: string[];
/**
* List of provider slugs to skip for this request
*/
ignore?: string[];
/**
* List of quantization levels to filter by (e.g. ["int4", "int8"])
*/
quantizations?: Array<'int4' | 'int8' | 'fp4' | 'fp6' | 'fp8' | 'fp16' | 'bf16' | 'fp32' | 'unknown'>;
/**
* Sort providers by price, throughput, or latency
*/
sort?: 'price' | 'throughput' | 'latency';
/**
* Maximum pricing you want to pay for this request
*/
max_price?: {
prompt?: number | string;
completion?: number | string;
image?: number | string;
audio?: number | string;
request?: number | string;
};
};
} & OpenRouterSharedSettings;