@earendil-works/pi-server 0.84.1 → 0.84.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [Unreleased]
4
+
5
+ ## [0.84.3] - 2026-08-24
6
+
7
+ ## [0.84.2] - 2026-08-14
8
+
3
9
  ## [0.84.1] - 2026-08-07
4
10
 
5
11
  ## [0.84.0] - 2026-08-06
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,KAAK,IAAI,OAAO,EACrB,KAAK,GAAG,EACR,KAAK,gBAAgB,EAErB,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,uBAAuB,EACvB,SAAS,EACT,aAAa,EAEb,kBAAkB,EAClB,KAAK,EACL,kBAAkB,EAClB,MAAM,6BAA6B,CAAC;AAqFrC,MAAM,WAAW,0BAA0B;IAC1C,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;CACf;AAsBD,uGAAuG;AACvG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,cAAoB,GAAG,SAAS,CAqBvF;AAED,yFAAyF;AACzF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,cAAoB,GAAG,SAAS,GAAG,SAAS,CAoBvG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAmB7E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,OAAO,GAAG,aAAa,CAoBhG;AAkBD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CAQ9G;AA4BD,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,0BAA0B,GACjC,uBAAuB,CAmDzB;AAiBD,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,qBAAqB,GAC5B,kBAAkB,CAyBpB","sourcesContent":["import {\n\ttype ImageContent as AiImageContent,\n\ttype TextContent as AiTextContent,\n\ttype Usage as AiUsage,\n\ttype Api,\n\ttype AssistantMessage,\n\tgetSupportedThinkingLevels,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype ToolCall,\n\ttype ToolResultMessage,\n\ttype UserMessage,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAssistantTranscriptItem,\n\tJsonValue,\n\tModelMetadata,\n\tThinkingLevel,\n\tToolTranscriptItem,\n\tUsage,\n\tUserTranscriptItem,\n} from \"@earendil-works/pi-protocol\";\n\ntype Assert<T extends true> = T;\ntype ExactKeys<T, Keys extends keyof T> = keyof T extends Keys ? true : false;\ntype _AiThinkingLevelsFitProtocol = Assert<ModelThinkingLevel extends ThinkingLevel ? true : false>;\ntype _ProtocolThinkingLevelsFitAi = Assert<ThinkingLevel extends ModelThinkingLevel ? true : false>;\ntype AiModelInput = Model<Api>[\"input\"][number];\ntype ProtocolModelInput = ModelMetadata[\"input\"][number];\ntype _AiModelInputsFitProtocol = Assert<AiModelInput extends ProtocolModelInput ? true : false>;\ntype _ProtocolModelInputsFitAi = Assert<ProtocolModelInput extends AiModelInput ? true : false>;\n/**\n * Enumerate mapped and intentionally omitted pi-ai fields so additions fail compilation here.\n * Provider replay metadata, diagnostics, cache-write retention splits, model transport settings,\n * model sampling defaults, pricing tiers, and deferred-tool availability remain intentionally\n * server-side.\n */\ntype _AiTextContentFieldsAccountedFor = Assert<ExactKeys<AiTextContent, \"type\" | \"text\" | \"textSignature\">>;\ntype _AiThinkingContentFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tExtract<AssistantMessage[\"content\"][number], { type: \"thinking\" }>,\n\t\t\"type\" | \"thinking\" | \"thinkingSignature\" | \"redacted\"\n\t>\n>;\ntype _AiImageContentFieldsAccountedFor = Assert<ExactKeys<AiImageContent, \"type\" | \"data\" | \"mimeType\">>;\ntype _AiToolCallFieldsAccountedFor = Assert<\n\tExactKeys<ToolCall, \"type\" | \"id\" | \"name\" | \"arguments\" | \"thoughtSignature\">\n>;\ntype _AiUsageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAiUsage,\n\t\t\"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"cacheWrite1h\" | \"reasoning\" | \"totalTokens\" | \"cost\"\n\t>\n>;\ntype _AiUsageCostFieldsAccountedFor = Assert<\n\tExactKeys<AiUsage[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"total\">\n>;\ntype _AiModelFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tModel<Api>,\n\t\t| \"id\"\n\t\t| \"name\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"baseUrl\"\n\t\t| \"reasoning\"\n\t\t| \"thinkingLevelMap\"\n\t\t| \"input\"\n\t\t| \"cost\"\n\t\t| \"contextWindow\"\n\t\t| \"maxTokens\"\n\t\t| \"samplingParams\"\n\t\t| \"headers\"\n\t\t| \"compat\"\n\t>\n>;\ntype _AiModelCostFieldsAccountedFor = Assert<\n\tExactKeys<Model<Api>[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"tiers\">\n>;\ntype _AiUserMessageFieldsAccountedFor = Assert<ExactKeys<UserMessage, \"role\" | \"content\" | \"timestamp\">>;\ntype _AiAssistantMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAssistantMessage,\n\t\t| \"role\"\n\t\t| \"content\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"model\"\n\t\t| \"responseModel\"\n\t\t| \"responseId\"\n\t\t| \"diagnostics\"\n\t\t| \"usage\"\n\t\t| \"stopReason\"\n\t\t| \"deferred\"\n\t\t| \"errorMessage\"\n\t\t| \"rawStopReason\"\n\t\t| \"timestamp\"\n\t>\n>;\ntype _AiToolResultMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tToolResultMessage,\n\t\t\"role\" | \"toolCallId\" | \"toolName\" | \"content\" | \"details\" | \"usage\" | \"addedToolNames\" | \"isError\" | \"timestamp\"\n\t>\n>;\n\nexport interface AssistantTranscriptOptions {\n\tid: string;\n}\n\nexport interface UserTranscriptOptions {\n\tid: string;\n}\n\nexport interface ToolTranscriptOptions {\n\tid: string;\n\tcall: ToolCall;\n}\n\nfunction nonNegativeInteger(value: number | undefined): number | undefined {\n\tif (value === undefined || !Number.isFinite(value)) return undefined;\n\treturn Math.max(0, Math.floor(value));\n}\n\nfunction nonNegativeNumber(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction identifier(value: string, label: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction timestamp(value: number): number {\n\tif (!Number.isSafeInteger(value) || value < 0)\n\t\tthrow new TypeError(\"Protocol timestamps must be non-negative integers\");\n\treturn value;\n}\n\n/** Validate and copy a value from an execution boundary into the protocol's JSON-compatible subset. */\nexport function toProtocolJsonValue(value: unknown, seen = new Set<object>()): JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new TypeError(\"Protocol JSON numbers must be finite\");\n\t\treturn value;\n\t}\n\tif (typeof value !== \"object\") throw new TypeError(`Unsupported protocol JSON value: ${typeof value}`);\n\tif (seen.has(value)) throw new TypeError(\"Protocol JSON values must not contain circular references\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n\t\tthrow new TypeError(\"Protocol JSON objects must be plain objects\");\n\t}\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => toProtocolJsonValue(entry, seen));\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) result[key] = toProtocolJsonValue(entry, seen);\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Lossily sanitize diagnostic tool details that must not affect execution semantics. */\nexport function sanitizeProtocolDetails(value: unknown, seen = new Set<object>()): JsonValue | undefined {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : String(value);\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (value === undefined || typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value !== \"object\") return String(value);\n\tif (seen.has(value)) return \"[Circular]\";\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => sanitizeProtocolDetails(entry, seen) ?? null);\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tconst normalized = sanitizeProtocolDetails(entry, seen);\n\t\t\tif (normalized !== undefined) result[key] = normalized;\n\t\t}\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\nexport function toProtocolUsage(usage: AiUsage | undefined): Usage | undefined {\n\tif (!usage) return undefined;\n\tconst reasoning = nonNegativeInteger(usage.reasoning);\n\tconst result = {\n\t\tinput: nonNegativeInteger(usage.input) ?? 0,\n\t\toutput: nonNegativeInteger(usage.output) ?? 0,\n\t\tcacheRead: nonNegativeInteger(usage.cacheRead) ?? 0,\n\t\tcacheWrite: nonNegativeInteger(usage.cacheWrite) ?? 0,\n\t\t...(reasoning === undefined ? {} : { reasoning }),\n\t\ttotalTokens: nonNegativeInteger(usage.totalTokens) ?? 0,\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(usage.cost.input),\n\t\t\toutput: nonNegativeNumber(usage.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(usage.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(usage.cost.cacheWrite),\n\t\t\ttotal: nonNegativeNumber(usage.cost.total),\n\t\t},\n\t} satisfies Usage;\n\treturn result;\n}\n\nexport function toProtocolModelMetadata(model: Model<Api>, authenticated: boolean): ModelMetadata {\n\tconst result = {\n\t\tprovider: identifier(model.provider, \"Model provider\"),\n\t\tid: identifier(model.id, \"Model id\"),\n\t\tname: identifier(model.name, \"Model name\"),\n\t\tapi: identifier(model.api, \"Model API\"),\n\t\treasoning: model.reasoning,\n\t\tinput: [...model.input],\n\t\tcontextWindow: Math.max(1, Math.floor(model.contextWindow)),\n\t\tmaxTokens: Math.max(1, Math.floor(model.maxTokens)),\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(model.cost.input),\n\t\t\toutput: nonNegativeNumber(model.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(model.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(model.cost.cacheWrite),\n\t\t},\n\t\tsupportedThinkingLevels: getSupportedThinkingLevels(model),\n\t\tauthenticated,\n\t} satisfies ModelMetadata;\n\treturn result;\n}\n\nfunction toProtocolUserContent(content: UserMessage[\"content\"]): UserTranscriptItem[\"content\"] {\n\tif (typeof content === \"string\") return [{ type: \"text\", text: content }];\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolUserMessage(message: UserMessage, options: UserTranscriptOptions): UserTranscriptItem {\n\tconst result = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"user\",\n\t\tcontent: toProtocolUserContent(message.content),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} satisfies UserTranscriptItem;\n\treturn result;\n}\n\nfunction toProtocolAssistantContent(message: AssistantMessage): AssistantTranscriptItem[\"content\"] {\n\treturn message.content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"thinking\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\tthinking: part.thinking,\n\t\t\t\t\t...(part.redacted === undefined ? {} : { redacted: part.redacted }),\n\t\t\t\t};\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\ttoolCallId: identifier(part.id, \"Tool call id\"),\n\t\t\t\t\ttoolName: identifier(part.name, \"Tool call name\"),\n\t\t\t\t\tinput: toProtocolJsonValue(part.arguments),\n\t\t\t\t};\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolAssistantMessage(\n\tmessage: AssistantMessage,\n\toptions: AssistantTranscriptOptions,\n): AssistantTranscriptItem {\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"assistant\",\n\t\tcontent: toProtocolAssistantContent(message),\n\t\tmodel: {\n\t\t\tprovider: identifier(message.provider, \"Assistant provider\"),\n\t\t\tid: identifier(message.model, \"Assistant model\"),\n\t\t},\n\t\t...(message.responseModel === undefined\n\t\t\t? {}\n\t\t\t: { responseModel: identifier(message.responseModel, \"Assistant response model\") }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\tswitch (message.stopReason) {\n\t\tcase \"pending\":\n\t\t\treturn { ...common, status: \"streaming\" } satisfies AssistantTranscriptItem;\n\t\tcase \"stop\":\n\t\tcase \"length\":\n\t\tcase \"toolUse\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"deferred\":\n\t\t\tthrow new TypeError(\"Deferred assistant messages are not supported by protocol v1\");\n\t\tcase \"error\":\n\t\t\tif (message.errorMessage?.length === 0) {\n\t\t\t\tthrow new TypeError(\"Assistant error messages must not be empty\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tstopReason: \"error\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"aborted\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"aborted\",\n\t\t\t\tstopReason: \"aborted\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = message.stopReason;\n\t\t\treturn exhaustive;\n\t\t}\n\t}\n}\n\nfunction toProtocolToolContent(content: Array<AiTextContent | AiImageContent>): ToolTranscriptItem[\"content\"] {\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolToolResultMessage(\n\tmessage: ToolResultMessage,\n\toptions: ToolTranscriptOptions,\n): ToolTranscriptItem {\n\tconst callId = identifier(options.call.id, \"Tool call id\");\n\tconst callName = identifier(options.call.name, \"Tool call name\");\n\tif (identifier(message.toolCallId, \"Tool result call id\") !== callId) {\n\t\tthrow new TypeError(`Tool result ${message.toolCallId} does not match tool call ${callId}`);\n\t}\n\tif (identifier(message.toolName, \"Tool result name\") !== callName) {\n\t\tthrow new TypeError(`Tool result ${message.toolName} does not match tool call ${callName}`);\n\t}\n\tconst details = sanitizeProtocolDetails(message.details);\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"tool\",\n\t\ttoolCallId: callId,\n\t\ttoolName: callName,\n\t\tinput: toProtocolJsonValue(options.call.arguments),\n\t\tcontent: toProtocolToolContent(message.content),\n\t\t...(details === undefined ? {} : { details }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\treturn message.isError\n\t\t? ({ ...common, status: \"error\", isError: true } satisfies ToolTranscriptItem)\n\t\t: ({ ...common, status: \"complete\", isError: false } satisfies ToolTranscriptItem);\n}\n"]}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,KAAK,IAAI,OAAO,EACrB,KAAK,GAAG,EACR,KAAK,gBAAgB,EAErB,KAAK,KAAK,EAEV,KAAK,QAAQ,EACb,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EACX,uBAAuB,EACvB,SAAS,EACT,aAAa,EAEb,kBAAkB,EAClB,KAAK,EACL,kBAAkB,EAClB,MAAM,6BAA6B,CAAC;AAsFrC,MAAM,WAAW,0BAA0B;IAC1C,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,qBAAqB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;CACf;AAsBD,uGAAuG;AACvG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,cAAoB,GAAG,SAAS,CAqBvF;AAED,yFAAyF;AACzF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,cAAoB,GAAG,SAAS,GAAG,SAAS,CAoBvG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAmB7E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,OAAO,GAAG,aAAa,CAoBhG;AAkBD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CAQ9G;AA4BD,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,0BAA0B,GACjC,uBAAuB,CAmDzB;AAiBD,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,qBAAqB,GAC5B,kBAAkB,CAyBpB","sourcesContent":["import {\n\ttype ImageContent as AiImageContent,\n\ttype TextContent as AiTextContent,\n\ttype Usage as AiUsage,\n\ttype Api,\n\ttype AssistantMessage,\n\tgetSupportedThinkingLevels,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype ToolCall,\n\ttype ToolResultMessage,\n\ttype UserMessage,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAssistantTranscriptItem,\n\tJsonValue,\n\tModelMetadata,\n\tThinkingLevel,\n\tToolTranscriptItem,\n\tUsage,\n\tUserTranscriptItem,\n} from \"@earendil-works/pi-protocol\";\n\ntype Assert<T extends true> = T;\ntype ExactKeys<T, Keys extends keyof T> = keyof T extends Keys ? true : false;\ntype _AiThinkingLevelsFitProtocol = Assert<ModelThinkingLevel extends ThinkingLevel ? true : false>;\ntype _ProtocolThinkingLevelsFitAi = Assert<ThinkingLevel extends ModelThinkingLevel ? true : false>;\ntype AiModelInput = Model<Api>[\"input\"][number];\ntype ProtocolModelInput = ModelMetadata[\"input\"][number];\ntype _AiModelInputsFitProtocol = Assert<AiModelInput extends ProtocolModelInput ? true : false>;\ntype _ProtocolModelInputsFitAi = Assert<ProtocolModelInput extends AiModelInput ? true : false>;\n/**\n * Enumerate mapped and intentionally omitted pi-ai fields so additions fail compilation here.\n * Provider replay metadata, diagnostics, cache-write retention splits, model transport settings,\n * model sampling defaults, pricing tiers, and deferred-tool availability remain intentionally\n * server-side.\n */\ntype _AiTextContentFieldsAccountedFor = Assert<ExactKeys<AiTextContent, \"type\" | \"text\" | \"textSignature\">>;\ntype _AiThinkingContentFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tExtract<AssistantMessage[\"content\"][number], { type: \"thinking\" }>,\n\t\t\"type\" | \"thinking\" | \"thinkingSignature\" | \"redacted\"\n\t>\n>;\ntype _AiImageContentFieldsAccountedFor = Assert<ExactKeys<AiImageContent, \"type\" | \"data\" | \"mimeType\">>;\ntype _AiToolCallFieldsAccountedFor = Assert<\n\tExactKeys<ToolCall, \"type\" | \"id\" | \"name\" | \"arguments\" | \"thoughtSignature\" | \"namespace\">\n>;\ntype _AiUsageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAiUsage,\n\t\t\"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"cacheWrite1h\" | \"reasoning\" | \"totalTokens\" | \"cost\"\n\t>\n>;\ntype _AiUsageCostFieldsAccountedFor = Assert<\n\tExactKeys<AiUsage[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"total\">\n>;\ntype _AiModelFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tModel<Api>,\n\t\t| \"id\"\n\t\t| \"name\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"baseUrl\"\n\t\t| \"reasoning\"\n\t\t| \"thinkingLevelMap\"\n\t\t| \"input\"\n\t\t| \"cost\"\n\t\t| \"contextWindow\"\n\t\t| \"maxTokens\"\n\t\t| \"samplingParams\"\n\t\t| \"headers\"\n\t\t| \"compat\"\n\t>\n>;\ntype _AiModelCostFieldsAccountedFor = Assert<\n\tExactKeys<Model<Api>[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"tiers\">\n>;\ntype _AiUserMessageFieldsAccountedFor = Assert<ExactKeys<UserMessage, \"role\" | \"content\" | \"timestamp\">>;\ntype _AiAssistantMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAssistantMessage,\n\t\t| \"role\"\n\t\t| \"content\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"model\"\n\t\t| \"responseModel\"\n\t\t| \"responseId\"\n\t\t| \"diagnostics\"\n\t\t| \"usage\"\n\t\t| \"stopReason\"\n\t\t| \"deferred\"\n\t\t| \"errorMessage\"\n\t\t| \"rawStopReason\"\n\t\t| \"endTurn\"\n\t\t| \"timestamp\"\n\t>\n>;\ntype _AiToolResultMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tToolResultMessage,\n\t\t\"role\" | \"toolCallId\" | \"toolName\" | \"content\" | \"details\" | \"usage\" | \"addedToolNames\" | \"isError\" | \"timestamp\"\n\t>\n>;\n\nexport interface AssistantTranscriptOptions {\n\tid: string;\n}\n\nexport interface UserTranscriptOptions {\n\tid: string;\n}\n\nexport interface ToolTranscriptOptions {\n\tid: string;\n\tcall: ToolCall;\n}\n\nfunction nonNegativeInteger(value: number | undefined): number | undefined {\n\tif (value === undefined || !Number.isFinite(value)) return undefined;\n\treturn Math.max(0, Math.floor(value));\n}\n\nfunction nonNegativeNumber(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction identifier(value: string, label: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction timestamp(value: number): number {\n\tif (!Number.isSafeInteger(value) || value < 0)\n\t\tthrow new TypeError(\"Protocol timestamps must be non-negative integers\");\n\treturn value;\n}\n\n/** Validate and copy a value from an execution boundary into the protocol's JSON-compatible subset. */\nexport function toProtocolJsonValue(value: unknown, seen = new Set<object>()): JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new TypeError(\"Protocol JSON numbers must be finite\");\n\t\treturn value;\n\t}\n\tif (typeof value !== \"object\") throw new TypeError(`Unsupported protocol JSON value: ${typeof value}`);\n\tif (seen.has(value)) throw new TypeError(\"Protocol JSON values must not contain circular references\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n\t\tthrow new TypeError(\"Protocol JSON objects must be plain objects\");\n\t}\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => toProtocolJsonValue(entry, seen));\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) result[key] = toProtocolJsonValue(entry, seen);\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Lossily sanitize diagnostic tool details that must not affect execution semantics. */\nexport function sanitizeProtocolDetails(value: unknown, seen = new Set<object>()): JsonValue | undefined {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : String(value);\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (value === undefined || typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value !== \"object\") return String(value);\n\tif (seen.has(value)) return \"[Circular]\";\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => sanitizeProtocolDetails(entry, seen) ?? null);\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tconst normalized = sanitizeProtocolDetails(entry, seen);\n\t\t\tif (normalized !== undefined) result[key] = normalized;\n\t\t}\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\nexport function toProtocolUsage(usage: AiUsage | undefined): Usage | undefined {\n\tif (!usage) return undefined;\n\tconst reasoning = nonNegativeInteger(usage.reasoning);\n\tconst result = {\n\t\tinput: nonNegativeInteger(usage.input) ?? 0,\n\t\toutput: nonNegativeInteger(usage.output) ?? 0,\n\t\tcacheRead: nonNegativeInteger(usage.cacheRead) ?? 0,\n\t\tcacheWrite: nonNegativeInteger(usage.cacheWrite) ?? 0,\n\t\t...(reasoning === undefined ? {} : { reasoning }),\n\t\ttotalTokens: nonNegativeInteger(usage.totalTokens) ?? 0,\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(usage.cost.input),\n\t\t\toutput: nonNegativeNumber(usage.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(usage.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(usage.cost.cacheWrite),\n\t\t\ttotal: nonNegativeNumber(usage.cost.total),\n\t\t},\n\t} satisfies Usage;\n\treturn result;\n}\n\nexport function toProtocolModelMetadata(model: Model<Api>, authenticated: boolean): ModelMetadata {\n\tconst result = {\n\t\tprovider: identifier(model.provider, \"Model provider\"),\n\t\tid: identifier(model.id, \"Model id\"),\n\t\tname: identifier(model.name, \"Model name\"),\n\t\tapi: identifier(model.api, \"Model API\"),\n\t\treasoning: model.reasoning,\n\t\tinput: [...model.input],\n\t\tcontextWindow: Math.max(1, Math.floor(model.contextWindow)),\n\t\tmaxTokens: Math.max(1, Math.floor(model.maxTokens)),\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(model.cost.input),\n\t\t\toutput: nonNegativeNumber(model.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(model.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(model.cost.cacheWrite),\n\t\t},\n\t\tsupportedThinkingLevels: getSupportedThinkingLevels(model),\n\t\tauthenticated,\n\t} satisfies ModelMetadata;\n\treturn result;\n}\n\nfunction toProtocolUserContent(content: UserMessage[\"content\"]): UserTranscriptItem[\"content\"] {\n\tif (typeof content === \"string\") return [{ type: \"text\", text: content }];\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolUserMessage(message: UserMessage, options: UserTranscriptOptions): UserTranscriptItem {\n\tconst result = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"user\",\n\t\tcontent: toProtocolUserContent(message.content),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} satisfies UserTranscriptItem;\n\treturn result;\n}\n\nfunction toProtocolAssistantContent(message: AssistantMessage): AssistantTranscriptItem[\"content\"] {\n\treturn message.content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"thinking\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\tthinking: part.thinking,\n\t\t\t\t\t...(part.redacted === undefined ? {} : { redacted: part.redacted }),\n\t\t\t\t};\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\ttoolCallId: identifier(part.id, \"Tool call id\"),\n\t\t\t\t\ttoolName: identifier(part.name, \"Tool call name\"),\n\t\t\t\t\tinput: toProtocolJsonValue(part.arguments),\n\t\t\t\t};\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolAssistantMessage(\n\tmessage: AssistantMessage,\n\toptions: AssistantTranscriptOptions,\n): AssistantTranscriptItem {\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"assistant\",\n\t\tcontent: toProtocolAssistantContent(message),\n\t\tmodel: {\n\t\t\tprovider: identifier(message.provider, \"Assistant provider\"),\n\t\t\tid: identifier(message.model, \"Assistant model\"),\n\t\t},\n\t\t...(message.responseModel === undefined\n\t\t\t? {}\n\t\t\t: { responseModel: identifier(message.responseModel, \"Assistant response model\") }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\tswitch (message.stopReason) {\n\t\tcase \"pending\":\n\t\t\treturn { ...common, status: \"streaming\" } satisfies AssistantTranscriptItem;\n\t\tcase \"stop\":\n\t\tcase \"length\":\n\t\tcase \"toolUse\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"deferred\":\n\t\t\tthrow new TypeError(\"Deferred assistant messages are not supported by protocol v1\");\n\t\tcase \"error\":\n\t\t\tif (message.errorMessage?.length === 0) {\n\t\t\t\tthrow new TypeError(\"Assistant error messages must not be empty\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tstopReason: \"error\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"aborted\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"aborted\",\n\t\t\t\tstopReason: \"aborted\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = message.stopReason;\n\t\t\treturn exhaustive;\n\t\t}\n\t}\n}\n\nfunction toProtocolToolContent(content: Array<AiTextContent | AiImageContent>): ToolTranscriptItem[\"content\"] {\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolToolResultMessage(\n\tmessage: ToolResultMessage,\n\toptions: ToolTranscriptOptions,\n): ToolTranscriptItem {\n\tconst callId = identifier(options.call.id, \"Tool call id\");\n\tconst callName = identifier(options.call.name, \"Tool call name\");\n\tif (identifier(message.toolCallId, \"Tool result call id\") !== callId) {\n\t\tthrow new TypeError(`Tool result ${message.toolCallId} does not match tool call ${callId}`);\n\t}\n\tif (identifier(message.toolName, \"Tool result name\") !== callName) {\n\t\tthrow new TypeError(`Tool result ${message.toolName} does not match tool call ${callName}`);\n\t}\n\tconst details = sanitizeProtocolDetails(message.details);\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"tool\",\n\t\ttoolCallId: callId,\n\t\ttoolName: callName,\n\t\tinput: toProtocolJsonValue(options.call.arguments),\n\t\tcontent: toProtocolToolContent(message.content),\n\t\t...(details === undefined ? {} : { details }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\treturn message.isError\n\t\t? ({ ...common, status: \"error\", isError: true } satisfies ToolTranscriptItem)\n\t\t: ({ ...common, status: \"complete\", isError: false } satisfies ToolTranscriptItem);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ImageContent as AiImageContent,\n\ttype TextContent as AiTextContent,\n\ttype Usage as AiUsage,\n\ttype Api,\n\ttype AssistantMessage,\n\tgetSupportedThinkingLevels,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype ToolCall,\n\ttype ToolResultMessage,\n\ttype UserMessage,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAssistantTranscriptItem,\n\tJsonValue,\n\tModelMetadata,\n\tThinkingLevel,\n\tToolTranscriptItem,\n\tUsage,\n\tUserTranscriptItem,\n} from \"@earendil-works/pi-protocol\";\n\ntype Assert<T extends true> = T;\ntype ExactKeys<T, Keys extends keyof T> = keyof T extends Keys ? true : false;\ntype _AiThinkingLevelsFitProtocol = Assert<ModelThinkingLevel extends ThinkingLevel ? true : false>;\ntype _ProtocolThinkingLevelsFitAi = Assert<ThinkingLevel extends ModelThinkingLevel ? true : false>;\ntype AiModelInput = Model<Api>[\"input\"][number];\ntype ProtocolModelInput = ModelMetadata[\"input\"][number];\ntype _AiModelInputsFitProtocol = Assert<AiModelInput extends ProtocolModelInput ? true : false>;\ntype _ProtocolModelInputsFitAi = Assert<ProtocolModelInput extends AiModelInput ? true : false>;\n/**\n * Enumerate mapped and intentionally omitted pi-ai fields so additions fail compilation here.\n * Provider replay metadata, diagnostics, cache-write retention splits, model transport settings,\n * model sampling defaults, pricing tiers, and deferred-tool availability remain intentionally\n * server-side.\n */\ntype _AiTextContentFieldsAccountedFor = Assert<ExactKeys<AiTextContent, \"type\" | \"text\" | \"textSignature\">>;\ntype _AiThinkingContentFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tExtract<AssistantMessage[\"content\"][number], { type: \"thinking\" }>,\n\t\t\"type\" | \"thinking\" | \"thinkingSignature\" | \"redacted\"\n\t>\n>;\ntype _AiImageContentFieldsAccountedFor = Assert<ExactKeys<AiImageContent, \"type\" | \"data\" | \"mimeType\">>;\ntype _AiToolCallFieldsAccountedFor = Assert<\n\tExactKeys<ToolCall, \"type\" | \"id\" | \"name\" | \"arguments\" | \"thoughtSignature\">\n>;\ntype _AiUsageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAiUsage,\n\t\t\"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"cacheWrite1h\" | \"reasoning\" | \"totalTokens\" | \"cost\"\n\t>\n>;\ntype _AiUsageCostFieldsAccountedFor = Assert<\n\tExactKeys<AiUsage[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"total\">\n>;\ntype _AiModelFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tModel<Api>,\n\t\t| \"id\"\n\t\t| \"name\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"baseUrl\"\n\t\t| \"reasoning\"\n\t\t| \"thinkingLevelMap\"\n\t\t| \"input\"\n\t\t| \"cost\"\n\t\t| \"contextWindow\"\n\t\t| \"maxTokens\"\n\t\t| \"samplingParams\"\n\t\t| \"headers\"\n\t\t| \"compat\"\n\t>\n>;\ntype _AiModelCostFieldsAccountedFor = Assert<\n\tExactKeys<Model<Api>[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"tiers\">\n>;\ntype _AiUserMessageFieldsAccountedFor = Assert<ExactKeys<UserMessage, \"role\" | \"content\" | \"timestamp\">>;\ntype _AiAssistantMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAssistantMessage,\n\t\t| \"role\"\n\t\t| \"content\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"model\"\n\t\t| \"responseModel\"\n\t\t| \"responseId\"\n\t\t| \"diagnostics\"\n\t\t| \"usage\"\n\t\t| \"stopReason\"\n\t\t| \"deferred\"\n\t\t| \"errorMessage\"\n\t\t| \"rawStopReason\"\n\t\t| \"timestamp\"\n\t>\n>;\ntype _AiToolResultMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tToolResultMessage,\n\t\t\"role\" | \"toolCallId\" | \"toolName\" | \"content\" | \"details\" | \"usage\" | \"addedToolNames\" | \"isError\" | \"timestamp\"\n\t>\n>;\n\nexport interface AssistantTranscriptOptions {\n\tid: string;\n}\n\nexport interface UserTranscriptOptions {\n\tid: string;\n}\n\nexport interface ToolTranscriptOptions {\n\tid: string;\n\tcall: ToolCall;\n}\n\nfunction nonNegativeInteger(value: number | undefined): number | undefined {\n\tif (value === undefined || !Number.isFinite(value)) return undefined;\n\treturn Math.max(0, Math.floor(value));\n}\n\nfunction nonNegativeNumber(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction identifier(value: string, label: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction timestamp(value: number): number {\n\tif (!Number.isSafeInteger(value) || value < 0)\n\t\tthrow new TypeError(\"Protocol timestamps must be non-negative integers\");\n\treturn value;\n}\n\n/** Validate and copy a value from an execution boundary into the protocol's JSON-compatible subset. */\nexport function toProtocolJsonValue(value: unknown, seen = new Set<object>()): JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new TypeError(\"Protocol JSON numbers must be finite\");\n\t\treturn value;\n\t}\n\tif (typeof value !== \"object\") throw new TypeError(`Unsupported protocol JSON value: ${typeof value}`);\n\tif (seen.has(value)) throw new TypeError(\"Protocol JSON values must not contain circular references\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n\t\tthrow new TypeError(\"Protocol JSON objects must be plain objects\");\n\t}\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => toProtocolJsonValue(entry, seen));\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) result[key] = toProtocolJsonValue(entry, seen);\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Lossily sanitize diagnostic tool details that must not affect execution semantics. */\nexport function sanitizeProtocolDetails(value: unknown, seen = new Set<object>()): JsonValue | undefined {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : String(value);\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (value === undefined || typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value !== \"object\") return String(value);\n\tif (seen.has(value)) return \"[Circular]\";\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => sanitizeProtocolDetails(entry, seen) ?? null);\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tconst normalized = sanitizeProtocolDetails(entry, seen);\n\t\t\tif (normalized !== undefined) result[key] = normalized;\n\t\t}\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\nexport function toProtocolUsage(usage: AiUsage | undefined): Usage | undefined {\n\tif (!usage) return undefined;\n\tconst reasoning = nonNegativeInteger(usage.reasoning);\n\tconst result = {\n\t\tinput: nonNegativeInteger(usage.input) ?? 0,\n\t\toutput: nonNegativeInteger(usage.output) ?? 0,\n\t\tcacheRead: nonNegativeInteger(usage.cacheRead) ?? 0,\n\t\tcacheWrite: nonNegativeInteger(usage.cacheWrite) ?? 0,\n\t\t...(reasoning === undefined ? {} : { reasoning }),\n\t\ttotalTokens: nonNegativeInteger(usage.totalTokens) ?? 0,\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(usage.cost.input),\n\t\t\toutput: nonNegativeNumber(usage.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(usage.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(usage.cost.cacheWrite),\n\t\t\ttotal: nonNegativeNumber(usage.cost.total),\n\t\t},\n\t} satisfies Usage;\n\treturn result;\n}\n\nexport function toProtocolModelMetadata(model: Model<Api>, authenticated: boolean): ModelMetadata {\n\tconst result = {\n\t\tprovider: identifier(model.provider, \"Model provider\"),\n\t\tid: identifier(model.id, \"Model id\"),\n\t\tname: identifier(model.name, \"Model name\"),\n\t\tapi: identifier(model.api, \"Model API\"),\n\t\treasoning: model.reasoning,\n\t\tinput: [...model.input],\n\t\tcontextWindow: Math.max(1, Math.floor(model.contextWindow)),\n\t\tmaxTokens: Math.max(1, Math.floor(model.maxTokens)),\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(model.cost.input),\n\t\t\toutput: nonNegativeNumber(model.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(model.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(model.cost.cacheWrite),\n\t\t},\n\t\tsupportedThinkingLevels: getSupportedThinkingLevels(model),\n\t\tauthenticated,\n\t} satisfies ModelMetadata;\n\treturn result;\n}\n\nfunction toProtocolUserContent(content: UserMessage[\"content\"]): UserTranscriptItem[\"content\"] {\n\tif (typeof content === \"string\") return [{ type: \"text\", text: content }];\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolUserMessage(message: UserMessage, options: UserTranscriptOptions): UserTranscriptItem {\n\tconst result = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"user\",\n\t\tcontent: toProtocolUserContent(message.content),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} satisfies UserTranscriptItem;\n\treturn result;\n}\n\nfunction toProtocolAssistantContent(message: AssistantMessage): AssistantTranscriptItem[\"content\"] {\n\treturn message.content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"thinking\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\tthinking: part.thinking,\n\t\t\t\t\t...(part.redacted === undefined ? {} : { redacted: part.redacted }),\n\t\t\t\t};\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\ttoolCallId: identifier(part.id, \"Tool call id\"),\n\t\t\t\t\ttoolName: identifier(part.name, \"Tool call name\"),\n\t\t\t\t\tinput: toProtocolJsonValue(part.arguments),\n\t\t\t\t};\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolAssistantMessage(\n\tmessage: AssistantMessage,\n\toptions: AssistantTranscriptOptions,\n): AssistantTranscriptItem {\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"assistant\",\n\t\tcontent: toProtocolAssistantContent(message),\n\t\tmodel: {\n\t\t\tprovider: identifier(message.provider, \"Assistant provider\"),\n\t\t\tid: identifier(message.model, \"Assistant model\"),\n\t\t},\n\t\t...(message.responseModel === undefined\n\t\t\t? {}\n\t\t\t: { responseModel: identifier(message.responseModel, \"Assistant response model\") }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\tswitch (message.stopReason) {\n\t\tcase \"pending\":\n\t\t\treturn { ...common, status: \"streaming\" } satisfies AssistantTranscriptItem;\n\t\tcase \"stop\":\n\t\tcase \"length\":\n\t\tcase \"toolUse\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"deferred\":\n\t\t\tthrow new TypeError(\"Deferred assistant messages are not supported by protocol v1\");\n\t\tcase \"error\":\n\t\t\tif (message.errorMessage?.length === 0) {\n\t\t\t\tthrow new TypeError(\"Assistant error messages must not be empty\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tstopReason: \"error\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"aborted\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"aborted\",\n\t\t\t\tstopReason: \"aborted\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = message.stopReason;\n\t\t\treturn exhaustive;\n\t\t}\n\t}\n}\n\nfunction toProtocolToolContent(content: Array<AiTextContent | AiImageContent>): ToolTranscriptItem[\"content\"] {\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolToolResultMessage(\n\tmessage: ToolResultMessage,\n\toptions: ToolTranscriptOptions,\n): ToolTranscriptItem {\n\tconst callId = identifier(options.call.id, \"Tool call id\");\n\tconst callName = identifier(options.call.name, \"Tool call name\");\n\tif (identifier(message.toolCallId, \"Tool result call id\") !== callId) {\n\t\tthrow new TypeError(`Tool result ${message.toolCallId} does not match tool call ${callId}`);\n\t}\n\tif (identifier(message.toolName, \"Tool result name\") !== callName) {\n\t\tthrow new TypeError(`Tool result ${message.toolName} does not match tool call ${callName}`);\n\t}\n\tconst details = sanitizeProtocolDetails(message.details);\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"tool\",\n\t\ttoolCallId: callId,\n\t\ttoolName: callName,\n\t\tinput: toProtocolJsonValue(options.call.arguments),\n\t\tcontent: toProtocolToolContent(message.content),\n\t\t...(details === undefined ? {} : { details }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\treturn message.isError\n\t\t? ({ ...common, status: \"error\", isError: true } satisfies ToolTranscriptItem)\n\t\t: ({ ...common, status: \"complete\", isError: false } satisfies ToolTranscriptItem);\n}\n"]}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ImageContent as AiImageContent,\n\ttype TextContent as AiTextContent,\n\ttype Usage as AiUsage,\n\ttype Api,\n\ttype AssistantMessage,\n\tgetSupportedThinkingLevels,\n\ttype Model,\n\ttype ModelThinkingLevel,\n\ttype ToolCall,\n\ttype ToolResultMessage,\n\ttype UserMessage,\n} from \"@earendil-works/pi-ai\";\nimport type {\n\tAssistantTranscriptItem,\n\tJsonValue,\n\tModelMetadata,\n\tThinkingLevel,\n\tToolTranscriptItem,\n\tUsage,\n\tUserTranscriptItem,\n} from \"@earendil-works/pi-protocol\";\n\ntype Assert<T extends true> = T;\ntype ExactKeys<T, Keys extends keyof T> = keyof T extends Keys ? true : false;\ntype _AiThinkingLevelsFitProtocol = Assert<ModelThinkingLevel extends ThinkingLevel ? true : false>;\ntype _ProtocolThinkingLevelsFitAi = Assert<ThinkingLevel extends ModelThinkingLevel ? true : false>;\ntype AiModelInput = Model<Api>[\"input\"][number];\ntype ProtocolModelInput = ModelMetadata[\"input\"][number];\ntype _AiModelInputsFitProtocol = Assert<AiModelInput extends ProtocolModelInput ? true : false>;\ntype _ProtocolModelInputsFitAi = Assert<ProtocolModelInput extends AiModelInput ? true : false>;\n/**\n * Enumerate mapped and intentionally omitted pi-ai fields so additions fail compilation here.\n * Provider replay metadata, diagnostics, cache-write retention splits, model transport settings,\n * model sampling defaults, pricing tiers, and deferred-tool availability remain intentionally\n * server-side.\n */\ntype _AiTextContentFieldsAccountedFor = Assert<ExactKeys<AiTextContent, \"type\" | \"text\" | \"textSignature\">>;\ntype _AiThinkingContentFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tExtract<AssistantMessage[\"content\"][number], { type: \"thinking\" }>,\n\t\t\"type\" | \"thinking\" | \"thinkingSignature\" | \"redacted\"\n\t>\n>;\ntype _AiImageContentFieldsAccountedFor = Assert<ExactKeys<AiImageContent, \"type\" | \"data\" | \"mimeType\">>;\ntype _AiToolCallFieldsAccountedFor = Assert<\n\tExactKeys<ToolCall, \"type\" | \"id\" | \"name\" | \"arguments\" | \"thoughtSignature\" | \"namespace\">\n>;\ntype _AiUsageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAiUsage,\n\t\t\"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"cacheWrite1h\" | \"reasoning\" | \"totalTokens\" | \"cost\"\n\t>\n>;\ntype _AiUsageCostFieldsAccountedFor = Assert<\n\tExactKeys<AiUsage[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"total\">\n>;\ntype _AiModelFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tModel<Api>,\n\t\t| \"id\"\n\t\t| \"name\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"baseUrl\"\n\t\t| \"reasoning\"\n\t\t| \"thinkingLevelMap\"\n\t\t| \"input\"\n\t\t| \"cost\"\n\t\t| \"contextWindow\"\n\t\t| \"maxTokens\"\n\t\t| \"samplingParams\"\n\t\t| \"headers\"\n\t\t| \"compat\"\n\t>\n>;\ntype _AiModelCostFieldsAccountedFor = Assert<\n\tExactKeys<Model<Api>[\"cost\"], \"input\" | \"output\" | \"cacheRead\" | \"cacheWrite\" | \"tiers\">\n>;\ntype _AiUserMessageFieldsAccountedFor = Assert<ExactKeys<UserMessage, \"role\" | \"content\" | \"timestamp\">>;\ntype _AiAssistantMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tAssistantMessage,\n\t\t| \"role\"\n\t\t| \"content\"\n\t\t| \"api\"\n\t\t| \"provider\"\n\t\t| \"model\"\n\t\t| \"responseModel\"\n\t\t| \"responseId\"\n\t\t| \"diagnostics\"\n\t\t| \"usage\"\n\t\t| \"stopReason\"\n\t\t| \"deferred\"\n\t\t| \"errorMessage\"\n\t\t| \"rawStopReason\"\n\t\t| \"endTurn\"\n\t\t| \"timestamp\"\n\t>\n>;\ntype _AiToolResultMessageFieldsAccountedFor = Assert<\n\tExactKeys<\n\t\tToolResultMessage,\n\t\t\"role\" | \"toolCallId\" | \"toolName\" | \"content\" | \"details\" | \"usage\" | \"addedToolNames\" | \"isError\" | \"timestamp\"\n\t>\n>;\n\nexport interface AssistantTranscriptOptions {\n\tid: string;\n}\n\nexport interface UserTranscriptOptions {\n\tid: string;\n}\n\nexport interface ToolTranscriptOptions {\n\tid: string;\n\tcall: ToolCall;\n}\n\nfunction nonNegativeInteger(value: number | undefined): number | undefined {\n\tif (value === undefined || !Number.isFinite(value)) return undefined;\n\treturn Math.max(0, Math.floor(value));\n}\n\nfunction nonNegativeNumber(value: number): number {\n\treturn Number.isFinite(value) ? Math.max(0, value) : 0;\n}\n\nfunction identifier(value: string, label: string): string {\n\tif (typeof value !== \"string\" || value.length === 0) throw new TypeError(`${label} must be a non-empty string`);\n\treturn value;\n}\n\nfunction timestamp(value: number): number {\n\tif (!Number.isSafeInteger(value) || value < 0)\n\t\tthrow new TypeError(\"Protocol timestamps must be non-negative integers\");\n\treturn value;\n}\n\n/** Validate and copy a value from an execution boundary into the protocol's JSON-compatible subset. */\nexport function toProtocolJsonValue(value: unknown, seen = new Set<object>()): JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) throw new TypeError(\"Protocol JSON numbers must be finite\");\n\t\treturn value;\n\t}\n\tif (typeof value !== \"object\") throw new TypeError(`Unsupported protocol JSON value: ${typeof value}`);\n\tif (seen.has(value)) throw new TypeError(\"Protocol JSON values must not contain circular references\");\n\tconst prototype = Object.getPrototypeOf(value);\n\tif (!Array.isArray(value) && prototype !== Object.prototype && prototype !== null) {\n\t\tthrow new TypeError(\"Protocol JSON objects must be plain objects\");\n\t}\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => toProtocolJsonValue(entry, seen));\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) result[key] = toProtocolJsonValue(entry, seen);\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n/** Lossily sanitize diagnostic tool details that must not affect execution semantics. */\nexport function sanitizeProtocolDetails(value: unknown, seen = new Set<object>()): JsonValue | undefined {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : String(value);\n\tif (typeof value === \"bigint\") return value.toString();\n\tif (value === undefined || typeof value === \"function\" || typeof value === \"symbol\") return undefined;\n\tif (value instanceof Date) return value.toISOString();\n\tif (typeof value !== \"object\") return String(value);\n\tif (seen.has(value)) return \"[Circular]\";\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Array.from(value, (entry) => sanitizeProtocolDetails(entry, seen) ?? null);\n\t\tconst result: Record<string, JsonValue> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tconst normalized = sanitizeProtocolDetails(entry, seen);\n\t\t\tif (normalized !== undefined) result[key] = normalized;\n\t\t}\n\t\treturn result;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\nexport function toProtocolUsage(usage: AiUsage | undefined): Usage | undefined {\n\tif (!usage) return undefined;\n\tconst reasoning = nonNegativeInteger(usage.reasoning);\n\tconst result = {\n\t\tinput: nonNegativeInteger(usage.input) ?? 0,\n\t\toutput: nonNegativeInteger(usage.output) ?? 0,\n\t\tcacheRead: nonNegativeInteger(usage.cacheRead) ?? 0,\n\t\tcacheWrite: nonNegativeInteger(usage.cacheWrite) ?? 0,\n\t\t...(reasoning === undefined ? {} : { reasoning }),\n\t\ttotalTokens: nonNegativeInteger(usage.totalTokens) ?? 0,\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(usage.cost.input),\n\t\t\toutput: nonNegativeNumber(usage.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(usage.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(usage.cost.cacheWrite),\n\t\t\ttotal: nonNegativeNumber(usage.cost.total),\n\t\t},\n\t} satisfies Usage;\n\treturn result;\n}\n\nexport function toProtocolModelMetadata(model: Model<Api>, authenticated: boolean): ModelMetadata {\n\tconst result = {\n\t\tprovider: identifier(model.provider, \"Model provider\"),\n\t\tid: identifier(model.id, \"Model id\"),\n\t\tname: identifier(model.name, \"Model name\"),\n\t\tapi: identifier(model.api, \"Model API\"),\n\t\treasoning: model.reasoning,\n\t\tinput: [...model.input],\n\t\tcontextWindow: Math.max(1, Math.floor(model.contextWindow)),\n\t\tmaxTokens: Math.max(1, Math.floor(model.maxTokens)),\n\t\tcost: {\n\t\t\tinput: nonNegativeNumber(model.cost.input),\n\t\t\toutput: nonNegativeNumber(model.cost.output),\n\t\t\tcacheRead: nonNegativeNumber(model.cost.cacheRead),\n\t\t\tcacheWrite: nonNegativeNumber(model.cost.cacheWrite),\n\t\t},\n\t\tsupportedThinkingLevels: getSupportedThinkingLevels(model),\n\t\tauthenticated,\n\t} satisfies ModelMetadata;\n\treturn result;\n}\n\nfunction toProtocolUserContent(content: UserMessage[\"content\"]): UserTranscriptItem[\"content\"] {\n\tif (typeof content === \"string\") return [{ type: \"text\", text: content }];\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolUserMessage(message: UserMessage, options: UserTranscriptOptions): UserTranscriptItem {\n\tconst result = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"user\",\n\t\tcontent: toProtocolUserContent(message.content),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} satisfies UserTranscriptItem;\n\treturn result;\n}\n\nfunction toProtocolAssistantContent(message: AssistantMessage): AssistantTranscriptItem[\"content\"] {\n\treturn message.content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"thinking\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\tthinking: part.thinking,\n\t\t\t\t\t...(part.redacted === undefined ? {} : { redacted: part.redacted }),\n\t\t\t\t};\n\t\t\tcase \"toolCall\":\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\ttoolCallId: identifier(part.id, \"Tool call id\"),\n\t\t\t\t\ttoolName: identifier(part.name, \"Tool call name\"),\n\t\t\t\t\tinput: toProtocolJsonValue(part.arguments),\n\t\t\t\t};\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolAssistantMessage(\n\tmessage: AssistantMessage,\n\toptions: AssistantTranscriptOptions,\n): AssistantTranscriptItem {\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"assistant\",\n\t\tcontent: toProtocolAssistantContent(message),\n\t\tmodel: {\n\t\t\tprovider: identifier(message.provider, \"Assistant provider\"),\n\t\t\tid: identifier(message.model, \"Assistant model\"),\n\t\t},\n\t\t...(message.responseModel === undefined\n\t\t\t? {}\n\t\t\t: { responseModel: identifier(message.responseModel, \"Assistant response model\") }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\tswitch (message.stopReason) {\n\t\tcase \"pending\":\n\t\t\treturn { ...common, status: \"streaming\" } satisfies AssistantTranscriptItem;\n\t\tcase \"stop\":\n\t\tcase \"length\":\n\t\tcase \"toolUse\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"complete\",\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"deferred\":\n\t\t\tthrow new TypeError(\"Deferred assistant messages are not supported by protocol v1\");\n\t\tcase \"error\":\n\t\t\tif (message.errorMessage?.length === 0) {\n\t\t\t\tthrow new TypeError(\"Assistant error messages must not be empty\");\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"error\",\n\t\t\t\tstopReason: \"error\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tcase \"aborted\":\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tstatus: \"aborted\",\n\t\t\t\tstopReason: \"aborted\",\n\t\t\t\t...(message.errorMessage === undefined ? {} : { errorMessage: message.errorMessage }),\n\t\t\t} satisfies AssistantTranscriptItem;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = message.stopReason;\n\t\t\treturn exhaustive;\n\t\t}\n\t}\n}\n\nfunction toProtocolToolContent(content: Array<AiTextContent | AiImageContent>): ToolTranscriptItem[\"content\"] {\n\treturn content.map((part) => {\n\t\tswitch (part.type) {\n\t\t\tcase \"text\":\n\t\t\t\treturn { type: \"text\", text: part.text };\n\t\t\tcase \"image\":\n\t\t\t\treturn { type: \"image\", data: part.data, mimeType: part.mimeType };\n\t\t\tdefault: {\n\t\t\t\tconst exhaustive: never = part;\n\t\t\t\treturn exhaustive;\n\t\t\t}\n\t\t}\n\t});\n}\n\nexport function toProtocolToolResultMessage(\n\tmessage: ToolResultMessage,\n\toptions: ToolTranscriptOptions,\n): ToolTranscriptItem {\n\tconst callId = identifier(options.call.id, \"Tool call id\");\n\tconst callName = identifier(options.call.name, \"Tool call name\");\n\tif (identifier(message.toolCallId, \"Tool result call id\") !== callId) {\n\t\tthrow new TypeError(`Tool result ${message.toolCallId} does not match tool call ${callId}`);\n\t}\n\tif (identifier(message.toolName, \"Tool result name\") !== callName) {\n\t\tthrow new TypeError(`Tool result ${message.toolName} does not match tool call ${callName}`);\n\t}\n\tconst details = sanitizeProtocolDetails(message.details);\n\tconst usage = toProtocolUsage(message.usage);\n\tconst common = {\n\t\tid: identifier(options.id, \"Transcript item id\"),\n\t\trole: \"tool\",\n\t\ttoolCallId: callId,\n\t\ttoolName: callName,\n\t\tinput: toProtocolJsonValue(options.call.arguments),\n\t\tcontent: toProtocolToolContent(message.content),\n\t\t...(details === undefined ? {} : { details }),\n\t\t...(usage ? { usage } : {}),\n\t\ttimestamp: timestamp(message.timestamp),\n\t} as const;\n\treturn message.isError\n\t\t? ({ ...common, status: \"error\", isError: true } satisfies ToolTranscriptItem)\n\t\t: ({ ...common, status: \"complete\", isError: false } satisfies ToolTranscriptItem);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-server",
3
- "version": "0.84.1",
3
+ "version": "0.84.3",
4
4
  "description": "experimental server package for pi",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -47,8 +47,8 @@
47
47
  "node": ">=22.19.0"
48
48
  },
49
49
  "dependencies": {
50
- "@earendil-works/pi-ai": "^0.84.1",
51
- "@earendil-works/pi-protocol": "^0.84.1"
50
+ "@earendil-works/pi-ai": "^0.84.3",
51
+ "@earendil-works/pi-protocol": "^0.84.3"
52
52
  },
53
53
  "devDependencies": {
54
54
  "shx": "0.4.0",