continuation-scenarios.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {
  2. LLM,
  3. Message,
  4. ToolCallPart,
  5. ToolDefinition,
  6. ToolResultPart,
  7. type ContentPart,
  8. type LanguageModel,
  9. } from "../src/index.js"
  10. export const basicContinuation = ["system", "user-text", "assistant-text", "user-follow-up"] as const
  11. export const toolContinuation = ["tool-call", "tool-result"] as const
  12. export const reasoningContinuation = ["assistant-reasoning", "encrypted-reasoning"] as const
  13. export const mediaContinuation = ["user-image"] as const
  14. export const maximalContinuation = [
  15. ...basicContinuation,
  16. ...toolContinuation,
  17. ...reasoningContinuation,
  18. ...mediaContinuation,
  19. ] as const
  20. export type ContinuationFeature = (typeof maximalContinuation)[number]
  21. export const nativeOpenAIResponsesContinuation = [
  22. ...basicContinuation,
  23. ...toolContinuation,
  24. "encrypted-reasoning",
  25. ...mediaContinuation,
  26. ] as const satisfies ReadonlyArray<ContinuationFeature>
  27. export const nativeAnthropicMessagesContinuation = [
  28. ...basicContinuation,
  29. ...toolContinuation,
  30. "assistant-reasoning",
  31. ...mediaContinuation,
  32. ] as const satisfies ReadonlyArray<ContinuationFeature>
  33. export const continuationTool = ToolDefinition.make({
  34. name: "get_weather",
  35. description: "Get current weather for a city.",
  36. inputSchema: {
  37. type: "object",
  38. properties: { city: { type: "string" } },
  39. required: ["city"],
  40. additionalProperties: false,
  41. },
  42. })
  43. export function continuationRequest(input: {
  44. readonly id: string
  45. readonly model: LanguageModel
  46. readonly features: ReadonlyArray<ContinuationFeature>
  47. readonly image?: string
  48. }) {
  49. const features = new Set(input.features)
  50. const messages = []
  51. const firstUser: ContentPart[] = []
  52. const firstAssistant: ContentPart[] = []
  53. if (features.has("user-text")) firstUser.push({ type: "text", text: "What is shown here?" })
  54. if (features.has("user-image"))
  55. firstUser.push({ type: "media", mediaType: "image/png", data: input.image ?? "AAECAw==" })
  56. if (firstUser.length > 0) messages.push(Message.user(firstUser))
  57. if (features.has("assistant-reasoning"))
  58. firstAssistant.push({
  59. type: "reasoning",
  60. text: "I inspected the previous turn.",
  61. providerMetadata: { anthropic: { signature: "sig_continuation_1" } },
  62. })
  63. if (features.has("encrypted-reasoning"))
  64. firstAssistant.push({
  65. type: "reasoning",
  66. text: "I inspected the previous turn.",
  67. providerMetadata: {
  68. openai: {
  69. itemId: "rs_continuation_1",
  70. reasoningEncryptedContent: "encrypted-continuation-state",
  71. },
  72. },
  73. })
  74. if (features.has("assistant-text")) firstAssistant.push({ type: "text", text: "It shows a small test image." })
  75. if (firstAssistant.length > 0) messages.push(Message.assistant(firstAssistant))
  76. if (features.has("tool-call")) {
  77. messages.push(Message.user("Check the weather in Paris before continuing."))
  78. messages.push(
  79. Message.assistant([ToolCallPart.make({ id: "call_weather_1", name: "get_weather", input: { city: "Paris" } })]),
  80. )
  81. }
  82. if (features.has("tool-result")) {
  83. messages.push(
  84. Message.tool(ToolResultPart.make({ id: "call_weather_1", name: "get_weather", result: { temperature: 22 } })),
  85. )
  86. if (features.has("assistant-text")) messages.push(Message.assistant("Paris is 22 degrees."))
  87. }
  88. if (features.has("user-follow-up"))
  89. messages.push(Message.user("Continue from this conversation in one short sentence."))
  90. return LLM.request({
  91. id: input.id,
  92. model: input.model,
  93. system: features.has("system") ? "You are concise. Continue from the provided history." : undefined,
  94. messages,
  95. tools: features.has("tool-call") ? [continuationTool] : [],
  96. cache: "none",
  97. providerOptions: features.has("encrypted-reasoning")
  98. ? { openai: { store: false, include: ["reasoning.encrypted_content"], reasoningSummary: "auto" } }
  99. : undefined,
  100. generation: { maxTokens: 80, temperature: 0 },
  101. })
  102. }