@prismshadow/penguin-core 0.0.1
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/LICENSE +201 -0
- package/README.md +41 -0
- package/dist/chunk-FX4CCIN7.js +379 -0
- package/dist/chunk-FX4CCIN7.js.map +1 -0
- package/dist/chunk-HRIXWKKE.js +1 -0
- package/dist/chunk-HRIXWKKE.js.map +1 -0
- package/dist/chunk-JC6SC6KF.js +336 -0
- package/dist/chunk-JC6SC6KF.js.map +1 -0
- package/dist/index.d.ts +1462 -0
- package/dist/index.js +5187 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces-CMSN7-pO.d.ts +487 -0
- package/dist/interfaces.d.ts +2 -0
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/model-catalog-DTu0IPjs.d.ts +266 -0
- package/dist/omnimessage/index.d.ts +110 -0
- package/dist/omnimessage/index.js +69 -0
- package/dist/omnimessage/index.js.map +1 -0
- package/dist/state/model-catalog.d.ts +1 -0
- package/dist/state/model-catalog.js +19 -0
- package/dist/state/model-catalog.js.map +1 -0
- package/dist/types-D6FERSdT.d.ts +293 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/state/model-catalog.ts"],"sourcesContent":["/**\n * Built-in model catalog (single source of truth): official chat models that AgentHub can\n * auto-route, shared by core's default config, server's initial config, and web/cli display.\n * Data verified as of 2026-07-10.\n * Docs: packages/docs/content/models.{zh,en}.md (site path /docs/models) documents the\n * provider groups and credential resolution described here.\n *\n * Three-bucket pricing convention (USD per million tokens, matching usageToTokenCounts'\n * token-to-bucket mapping):\n * - cache_read: the vendor's \"cache hit\" price;\n * - cache_write: the vendor's \"cache write\" price (e.g. Anthropic uses 1.25 x input); vendors\n * without a separate cache-write fee use the standard input price;\n * - output: output price (thinking + reply).\n * OpenAI charges extra for >272K input and Gemini 3.1 Pro for >200K input under official\n * long-context pricing; this catalog only records the base tier (the cost center uses a\n * single rate, so long-context usage will be underestimated).\n *\n * Scope: excludes deepseek-chat / deepseek-reasoner legacy aliases that AgentHub cannot\n * auto-route (deprecated 2026-07-24), glm-5v-turbo (image input unsupported by AgentHub's GLM\n * client), non-chat models (embedding / image generation / TTS), and Bedrock plus\n * OpenRouter / SiliconFlow gateway mirror ids. Every model id in this catalog can be\n * auto-routed by AgentHub via substring matching, so none set client_type; only custom\n * OpenAI-protocol models need `client_type: \"openai\"`.\n *\n * This file imports no Node built-ins (type-only imports only), so it can be bundled directly\n * for the browser.\n */\nimport type { ModelEntry, ModelPricing } from \"./project-config.js\";\n\n/** Model provider info (used for web grouping/logo and the \"API key blank falls back to env var\" hint). */\nexport interface ModelProviderInfo {\n id: string;\n /** Display name (brand name, shared by Chinese and English UI). */\n label: string;\n /** API key env var name (AgentHub reads this automatically when credential is blank). */\n envKey: string;\n /** base URL env var name. */\n envBaseUrlKey: string;\n /** Console URL for obtaining an API key (frontend links this in the group header); none for custom. */\n apiKeyUrl?: string;\n /** Vendor's model list / docs page URL (frontend's \"add model\" dialog links this as \"get model id\"); none for custom. */\n modelsUrl?: string;\n /**\n * Gateway's OpenAI-compatible endpoint (openrouter / siliconflow): used by the frontend's\n * \"add model\" dialog to prefill base URL by group; left blank for direct vendors and custom.\n */\n gatewayBaseUrl?: string;\n}\n\n/** A single built-in model's catalog entry (`modelId` is the upstream id; paired with `provider` it forms the catalog's unique key). */\nexport interface ModelCatalogEntry {\n modelId: string;\n displayName: string;\n /** Provider id (one of MODEL_PROVIDERS). */\n provider: string;\n contextWindow?: number;\n pricing?: ModelPricing;\n /** Whether image input (vision modality) is supported. */\n supportsVision: boolean;\n /** AgentHub client protocol: required for models whose id can't be auto-routed (e.g. OpenRouter gateway models). */\n clientType?: string;\n /** Preset base URL (gateway models): inlined into the model entry so the user only needs to supply an API key. */\n baseUrl?: string;\n}\n\n/** Each gateway's OpenAI-compatible endpoint (preset base URL for gateway models; also used as the provider's gatewayBaseUrl). */\nconst OPENROUTER_BASE_URL = \"https://openrouter.ai/api/v1\";\nconst SILICONFLOW_BASE_URL = \"https://api.siliconflow.cn/v1\";\n\n/**\n * Provider list (web model page groups in this order): DeepSeek first (the default model's\n * provider), followed by the OpenRouter and SiliconFlow gateways, then Google Gemini before\n * Anthropic; custom groups custom OpenAI-protocol models and comes last.\n */\nexport const MODEL_PROVIDERS: ModelProviderInfo[] = [\n {\n id: \"deepseek\",\n label: \"DeepSeek\",\n envKey: \"DEEPSEEK_API_KEY\",\n envBaseUrlKey: \"DEEPSEEK_BASE_URL\",\n apiKeyUrl: \"https://platform.deepseek.com/api_keys\",\n modelsUrl: \"https://api-docs.deepseek.com/quick_start/pricing\",\n },\n // Gateways (their model ids can't be auto-routed by AgentHub, so they always use\n // client_type=openai + a preset base URL): they go through AgentHub's OpenAI client, so when\n // credential is blank the SDK reads **OPENAI_API_KEY / OPENAI_BASE_URL** (not the provider's\n // own var names) - the env fallback hint must reflect that accurately.\n {\n id: \"openrouter\",\n label: \"OpenRouter\",\n envKey: \"OPENAI_API_KEY\",\n envBaseUrlKey: \"OPENAI_BASE_URL\",\n apiKeyUrl: \"https://openrouter.ai/workspaces/default/keys\",\n modelsUrl: \"https://openrouter.ai/models\",\n gatewayBaseUrl: OPENROUTER_BASE_URL,\n },\n {\n id: \"siliconflow\",\n label: \"SiliconFlow\",\n envKey: \"OPENAI_API_KEY\",\n envBaseUrlKey: \"OPENAI_BASE_URL\",\n apiKeyUrl: \"https://cloud.siliconflow.cn/me/account/ak\",\n modelsUrl: \"https://cloud.siliconflow.cn/models\",\n gatewayBaseUrl: SILICONFLOW_BASE_URL,\n },\n {\n id: \"google\",\n label: \"Google Gemini\",\n envKey: \"GEMINI_API_KEY\",\n envBaseUrlKey: \"GEMINI_BASE_URL\",\n apiKeyUrl: \"https://aistudio.google.com/api-keys\",\n modelsUrl: \"https://ai.google.dev/gemini-api/docs/models\",\n },\n {\n id: \"anthropic\",\n label: \"Anthropic\",\n envKey: \"ANTHROPIC_API_KEY\",\n envBaseUrlKey: \"ANTHROPIC_BASE_URL\",\n apiKeyUrl: \"https://platform.claude.com/settings/keys\",\n modelsUrl: \"https://docs.claude.com/en/docs/about-claude/models/overview\",\n },\n {\n id: \"openai\",\n label: \"OpenAI\",\n envKey: \"OPENAI_API_KEY\",\n envBaseUrlKey: \"OPENAI_BASE_URL\",\n apiKeyUrl: \"https://platform.openai.com/api-keys\",\n modelsUrl: \"https://platform.openai.com/docs/models\",\n },\n {\n id: \"zhipu\",\n label: \"Z.AI (GLM)\",\n envKey: \"ZAI_API_KEY\",\n envBaseUrlKey: \"ZAI_BASE_URL\",\n apiKeyUrl: \"https://open.bigmodel.cn/apikey/platform\",\n modelsUrl: \"https://docs.z.ai/guides/overview/pricing\",\n },\n {\n id: \"moonshot\",\n label: \"Moonshot (Kimi)\",\n envKey: \"MOONSHOT_API_KEY\",\n envBaseUrlKey: \"MOONSHOT_BASE_URL\",\n apiKeyUrl: \"https://platform.kimi.com/console/api-keys\",\n modelsUrl: \"https://platform.kimi.com/docs/pricing\",\n },\n { id: \"custom\", label: \"Custom\", envKey: \"OPENAI_API_KEY\", envBaseUrlKey: \"OPENAI_BASE_URL\" },\n];\n\n/** Three-bucket price literal (unit fixed to usd_per_mtok). */\n/**\n * Converts official CNY pricing to USD for storage (prices are always persisted in USD). The\n * conversion rate matches the web display's 7:1 convention, so switching the UI to CNY shows\n * exactly the vendor's official CNY price.\n */\nfunction cny(cacheRead: number, cacheWrite: number, output: number): ModelPricing {\n const r = (v: number): number => Math.round((v / 7) * 1e6) / 1e6;\n return usd(r(cacheRead), r(cacheWrite), r(output));\n}\n\nfunction usd(cacheRead: number, cacheWrite: number, output: number): ModelPricing {\n return { unit: \"usd_per_mtok\", cache_read: cacheRead, cache_write: cacheWrite, output };\n}\n\n/** Built-in model catalog (clustered by provider; within each provider, ordered by capability/price, highest first). */\nexport const MODEL_CATALOG: ModelCatalogEntry[] = [\n // -- DeepSeek (official CNY pricing: cache hit / cache miss / output) --\n {\n modelId: \"deepseek-v4-pro\",\n displayName: \"DeepSeek V4 Pro\",\n provider: \"deepseek\",\n contextWindow: 1000000,\n pricing: cny(0.025, 3, 6),\n supportsVision: false,\n },\n {\n modelId: \"deepseek-v4-flash\",\n displayName: \"DeepSeek V4 Flash\",\n provider: \"deepseek\",\n contextWindow: 1000000,\n pricing: cny(0.02, 1, 2),\n supportsVision: false,\n },\n // —— Anthropic ——\n {\n modelId: \"claude-opus-4-8\",\n displayName: \"Claude Opus 4.8\",\n provider: \"anthropic\",\n contextWindow: 1000000,\n pricing: usd(0.5, 6.25, 25),\n supportsVision: true,\n },\n {\n modelId: \"claude-opus-4-7\",\n displayName: \"Claude Opus 4.7\",\n provider: \"anthropic\",\n contextWindow: 1000000,\n pricing: usd(0.5, 6.25, 25),\n supportsVision: true,\n },\n {\n modelId: \"claude-sonnet-4-6\",\n displayName: \"Claude Sonnet 4.6\",\n provider: \"anthropic\",\n contextWindow: 1000000,\n pricing: usd(0.3, 3.75, 15),\n supportsVision: true,\n },\n // —— OpenAI ——\n {\n modelId: \"gpt-5.5\",\n displayName: \"GPT-5.5\",\n provider: \"openai\",\n contextWindow: 1050000,\n pricing: usd(0.5, 5, 30),\n supportsVision: true,\n },\n {\n // No official cache discount: cache_read uses the standard input price.\n modelId: \"gpt-5.5-pro\",\n displayName: \"GPT-5.5 Pro\",\n provider: \"openai\",\n contextWindow: 1050000,\n pricing: usd(30, 30, 180),\n supportsVision: true,\n },\n {\n modelId: \"gpt-5.4\",\n displayName: \"GPT-5.4\",\n provider: \"openai\",\n contextWindow: 1050000,\n pricing: usd(0.25, 2.5, 15),\n supportsVision: true,\n },\n {\n modelId: \"gpt-5.4-mini\",\n displayName: \"GPT-5.4 mini\",\n provider: \"openai\",\n contextWindow: 400000,\n pricing: usd(0.075, 0.75, 4.5),\n supportsVision: true,\n },\n {\n modelId: \"gpt-5.4-nano\",\n displayName: \"GPT-5.4 nano\",\n provider: \"openai\",\n contextWindow: 400000,\n pricing: usd(0.02, 0.2, 1.25),\n supportsVision: true,\n },\n {\n // No official cache discount: cache_read uses the standard input price.\n modelId: \"gpt-5.4-pro\",\n displayName: \"GPT-5.4 Pro\",\n provider: \"openai\",\n contextWindow: 1050000,\n pricing: usd(30, 30, 180),\n supportsVision: true,\n },\n // —— Google Gemini ——\n {\n // ≤200K input tier; >200K has official surcharge pricing (see file header comment).\n modelId: \"gemini-3.1-pro-preview\",\n displayName: \"Gemini 3.1 Pro (Preview)\",\n provider: \"google\",\n contextWindow: 1048576,\n pricing: usd(0.2, 2, 12),\n supportsVision: true,\n },\n {\n modelId: \"gemini-3.5-flash\",\n displayName: \"Gemini 3.5 Flash\",\n provider: \"google\",\n contextWindow: 1048576,\n pricing: usd(0.15, 1.5, 9),\n supportsVision: true,\n },\n {\n modelId: \"gemini-3-flash-preview\",\n displayName: \"Gemini 3 Flash (Preview)\",\n provider: \"google\",\n contextWindow: 1048576,\n pricing: usd(0.05, 0.5, 3),\n supportsVision: true,\n },\n {\n modelId: \"gemini-3.1-flash-lite\",\n displayName: \"Gemini 3.1 Flash-Lite\",\n provider: \"google\",\n contextWindow: 1048576,\n pricing: usd(0.025, 0.25, 1.5),\n supportsVision: true,\n },\n // —— Z.AI (GLM) ——\n {\n modelId: \"glm-5.2\",\n displayName: \"GLM-5.2\",\n provider: \"zhipu\",\n contextWindow: 1000000,\n pricing: usd(0.26, 1.4, 4.4),\n supportsVision: false,\n },\n {\n modelId: \"glm-5.1\",\n displayName: \"GLM-5.1\",\n provider: \"zhipu\",\n contextWindow: 200000,\n pricing: usd(0.26, 1.4, 4.4),\n supportsVision: false,\n },\n {\n modelId: \"glm-5\",\n displayName: \"GLM-5\",\n provider: \"zhipu\",\n contextWindow: 200000,\n pricing: usd(0.2, 1, 3.2),\n supportsVision: false,\n },\n // -- Moonshot (Kimi) (official CNY pricing) --\n {\n modelId: \"kimi-k2.6\",\n displayName: \"Kimi K2.6\",\n provider: \"moonshot\",\n contextWindow: 262144,\n pricing: cny(1.1, 6.5, 27),\n supportsVision: true,\n },\n {\n modelId: \"kimi-k2.5\",\n displayName: \"Kimi K2.5\",\n provider: \"moonshot\",\n contextWindow: 262144,\n pricing: cny(0.7, 4, 21),\n supportsVision: true,\n },\n // -- OpenRouter (gateway: uses OpenAI-compatible protocol, preset base URL) --\n {\n modelId: \"xiaomi/mimo-v2.5\",\n displayName: \"MiMo-V2.5\",\n provider: \"openrouter\",\n contextWindow: 1048576,\n pricing: usd(0.0028, 0.14, 0.28),\n supportsVision: true,\n clientType: \"openai\",\n baseUrl: OPENROUTER_BASE_URL,\n },\n {\n modelId: \"tencent/hy3\",\n displayName: \"Hy3\",\n provider: \"openrouter\",\n contextWindow: 262144,\n pricing: usd(0.035, 0.14, 0.58),\n supportsVision: false,\n clientType: \"openai\",\n baseUrl: OPENROUTER_BASE_URL,\n },\n {\n // No official separate cache price published: cache_read uses the standard input price (no discount assumed).\n modelId: \"minimax/minimax-m3\",\n displayName: \"MiniMax M3\",\n provider: \"openrouter\",\n contextWindow: 1048576,\n pricing: usd(0.06, 0.3, 1.2),\n supportsVision: true,\n clientType: \"openai\",\n baseUrl: OPENROUTER_BASE_URL,\n },\n {\n // No official separate cache price published: cache_read uses the standard input price.\n modelId: \"stepfun/step-3.7-flash\",\n displayName: \"Step 3.7 Flash\",\n provider: \"openrouter\",\n contextWindow: 256000,\n pricing: usd(0.04, 0.2, 1.15),\n supportsVision: true,\n clientType: \"openai\",\n baseUrl: OPENROUTER_BASE_URL,\n },\n // -- SiliconFlow (gateway, official CNY pricing: cache hit / input / output) --\n {\n modelId: \"zai-org/GLM-5.2\",\n displayName: \"GLM-5.2\",\n provider: \"siliconflow\",\n contextWindow: 1000000,\n pricing: cny(2, 8, 28),\n supportsVision: false,\n clientType: \"openai\",\n baseUrl: SILICONFLOW_BASE_URL,\n },\n {\n modelId: \"deepseek-ai/DeepSeek-V4-Pro\",\n displayName: \"DeepSeek V4 Pro\",\n provider: \"siliconflow\",\n contextWindow: 1000000,\n pricing: cny(0.1, 12, 24),\n supportsVision: false,\n clientType: \"openai\",\n baseUrl: SILICONFLOW_BASE_URL,\n },\n {\n modelId: \"meituan-longcat/LongCat-2.0\",\n displayName: \"LongCat 2.0\",\n provider: \"siliconflow\",\n contextWindow: 1000000,\n pricing: cny(0.1, 5, 20),\n supportsVision: false,\n clientType: \"openai\",\n baseUrl: SILICONFLOW_BASE_URL,\n },\n];\n\n/** Looks up a catalog entry by (provider, upstream id) pair (**the sole catalog-matching entry point**); returns undefined if not in the catalog. */\nexport function catalogEntryFor(\n provider: string,\n upstreamId: string,\n): ModelCatalogEntry | undefined {\n return MODEL_CATALOG.find((m) => m.provider === provider && m.modelId === upstreamId);\n}\n\n/**\n * Infers the provider for an upstream id from the built-in catalog (used to default\n * `provider` on `model add`): if it matches a catalog entry, use that entry's provider\n * (upstream ids are globally unique within the catalog); otherwise custom.\n */\nexport function inferProviderForUpstream(upstreamId: string): string {\n return MODEL_CATALOG.find((m) => m.modelId === upstreamId)?.provider ?? \"custom\";\n}\n\n/** Looks up provider info by provider id; returns undefined for an unknown id. */\nexport function providerInfo(providerId: string): ModelProviderInfo | undefined {\n return MODEL_PROVIDERS.find((p) => p.id === providerId);\n}\n\n/** Env var fallback for a single model (the var names AgentHub's client actually reads when api_key / base_url is blank). */\nexport interface ModelEnvInfo {\n envKey: string;\n envBaseUrlKey: string;\n}\n\n/**\n * Resolves the env var fallback for a model: mirrors AgentHub's\n * AutoLLMClient routing rules (verified against agenthub v0.3.3 autoClient.ts) - an explicit\n * client_type takes priority, otherwise routes to a client by lowercase substring match on\n * model_id, returning the var pair that client reads; branch order matches AutoLLMClient.\n * Returns undefined on no match (AgentHub will reject that id: it needs an explicit\n * client_type, or should be added under custom / a self-built group via the OpenAI protocol).\n */\nexport function resolveModelEnv(modelId: string, clientType?: string): ModelEnvInfo | undefined {\n const t = (clientType || modelId).toLowerCase();\n const env = (prefix: string): ModelEnvInfo => ({\n envKey: `${prefix}_API_KEY`,\n envBaseUrlKey: `${prefix}_BASE_URL`,\n });\n if (t.includes(\"gemini-3\") || t.includes(\"gemini-embedding\")) return env(\"GEMINI\");\n if (\n t.includes(\"claude\") &&\n (t.includes(\"4-7\") || t.includes(\"4-8\") || t.includes(\"-5\") || t.includes(\"4-6\"))\n ) {\n return env(\"ANTHROPIC\");\n }\n if (t.includes(\"gpt-5.4\") || t.includes(\"gpt-5.5\")) return env(\"OPENAI\");\n if (t.includes(\"glm-5\")) return env(\"ZAI\");\n if (t.includes(\"kimi-k2.5\") || t.includes(\"kimi-k2.6\")) return env(\"MOONSHOT\");\n if (t.includes(\"deepseek-v4\")) return env(\"DEEPSEEK\");\n if (t.includes(\"openai\")) return env(\"OPENAI\");\n return undefined;\n}\n\n/**\n * Catalog -> preset ModelEntry list (shared by defaultProjectConfig and the server's initial\n * config, avoiding duplicate hand-written copies). `provider` and `model_id` are persisted as\n * separate fields (`model_id` is the plain upstream id); models whose upstream id can be\n * auto-routed by AgentHub leave client_type unset; gateway models (OpenRouter / SiliconFlow)\n * explicitly set client_type=openai and inline a preset base_url (no secrets included, so the\n * user only needs to supply an API key).\n */\nexport function presetModelEntries(): ModelEntry[] {\n return MODEL_CATALOG.map((m) => ({\n provider: m.provider,\n model_id: m.modelId,\n ...(m.contextWindow !== undefined ? { context_window: m.contextWindow } : {}),\n ...(m.clientType !== undefined ? { client_type: m.clientType } : {}),\n ...(m.pricing ? { pricing: { ...m.pricing } } : {}),\n // ModelEntry.vision defaults to supported: only models that don't support images\n // explicitly persist false (drives the read_image / describe_image choice and input\n // image hand-off, see project-config.ts).\n ...(m.supportsVision ? {} : { vision: false }),\n ...(m.baseUrl !== undefined ? { base_url: m.baseUrl } : {}),\n }));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-HRIXWKKE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
// src/omnimessage/types.ts
|
|
2
|
+
var PARTIAL_PAYLOAD_TYPES = [
|
|
3
|
+
"partial_text",
|
|
4
|
+
"partial_thinking",
|
|
5
|
+
"partial_tool_call",
|
|
6
|
+
"partial_tool_call_output"
|
|
7
|
+
];
|
|
8
|
+
function isPartialPayload(p) {
|
|
9
|
+
return PARTIAL_PAYLOAD_TYPES.includes(p.type ?? "");
|
|
10
|
+
}
|
|
11
|
+
function isModelMessage(msg) {
|
|
12
|
+
return msg.type === "model_msg";
|
|
13
|
+
}
|
|
14
|
+
function isEventMessage(msg) {
|
|
15
|
+
return msg.type === "event_msg";
|
|
16
|
+
}
|
|
17
|
+
function isSessionMeta(msg) {
|
|
18
|
+
return msg.type === "session_meta";
|
|
19
|
+
}
|
|
20
|
+
function isCompleteModelMessage(msg) {
|
|
21
|
+
return msg.type === "model_msg" && !isPartialPayload(msg.payload);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// src/omnimessage/builders.ts
|
|
25
|
+
function nowIso() {
|
|
26
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
27
|
+
}
|
|
28
|
+
function model(payload) {
|
|
29
|
+
return { timestamp: nowIso(), type: "model_msg", payload };
|
|
30
|
+
}
|
|
31
|
+
function event(payload) {
|
|
32
|
+
return { timestamp: nowIso(), type: "event_msg", payload };
|
|
33
|
+
}
|
|
34
|
+
function sessionMeta(payload) {
|
|
35
|
+
return { timestamp: nowIso(), type: "session_meta", payload };
|
|
36
|
+
}
|
|
37
|
+
function textMessage(role, text, stopReason = "completed", fidelity) {
|
|
38
|
+
return model({
|
|
39
|
+
type: "text",
|
|
40
|
+
role,
|
|
41
|
+
text,
|
|
42
|
+
stop_reason: stopReason,
|
|
43
|
+
...fidelity?.phase != null ? { phase: fidelity.phase } : {},
|
|
44
|
+
...fidelity?.signature !== void 0 ? { signature: fidelity.signature } : {}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
var userText = (text) => textMessage("user", text);
|
|
48
|
+
var assistantText = (text, stopReason = "completed", fidelity) => textMessage("assistant", text, stopReason, fidelity);
|
|
49
|
+
function imageUrlMessage(imageUrl) {
|
|
50
|
+
return model({
|
|
51
|
+
type: "image_url",
|
|
52
|
+
role: "user",
|
|
53
|
+
image_url: imageUrl,
|
|
54
|
+
stop_reason: "completed"
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function inlineData(role, data, mimeType, fidelity) {
|
|
58
|
+
return model({
|
|
59
|
+
type: "inline_data",
|
|
60
|
+
role,
|
|
61
|
+
data,
|
|
62
|
+
mime_type: mimeType,
|
|
63
|
+
stop_reason: "completed",
|
|
64
|
+
...fidelity?.signature !== void 0 ? { signature: fidelity.signature } : {}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function thinkingMessage(thinking, stopReason = "completed", fidelity) {
|
|
68
|
+
return model({
|
|
69
|
+
type: "thinking",
|
|
70
|
+
role: "assistant",
|
|
71
|
+
thinking,
|
|
72
|
+
stop_reason: stopReason,
|
|
73
|
+
...fidelity?.signature !== void 0 ? { signature: fidelity.signature } : {}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function inlineThinking(data, mimeType, fidelity) {
|
|
77
|
+
return model({
|
|
78
|
+
type: "inline_thinking",
|
|
79
|
+
role: "assistant",
|
|
80
|
+
data,
|
|
81
|
+
mime_type: mimeType,
|
|
82
|
+
stop_reason: "completed",
|
|
83
|
+
...fidelity?.signature !== void 0 ? { signature: fidelity.signature } : {}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function toolCall(args) {
|
|
87
|
+
return model({
|
|
88
|
+
type: "tool_call",
|
|
89
|
+
role: "assistant",
|
|
90
|
+
name: args.name,
|
|
91
|
+
arguments: args.arguments,
|
|
92
|
+
tool_call_id: args.toolCallId,
|
|
93
|
+
stop_reason: args.stopReason ?? "completed",
|
|
94
|
+
...args.signature !== void 0 ? { signature: args.signature } : {}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function toolCallOutput(args) {
|
|
98
|
+
return model({
|
|
99
|
+
type: "tool_call_output",
|
|
100
|
+
role: "user",
|
|
101
|
+
output: args.output,
|
|
102
|
+
...args.images !== void 0 && args.images.length > 0 ? { images: args.images } : {},
|
|
103
|
+
tool_call_id: args.toolCallId,
|
|
104
|
+
stop_reason: args.stopReason ?? "completed"
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
function partialText(eventType, text = "", stopReason = "completed") {
|
|
108
|
+
return model({
|
|
109
|
+
type: "partial_text",
|
|
110
|
+
role: "assistant",
|
|
111
|
+
event_type: eventType,
|
|
112
|
+
text,
|
|
113
|
+
stop_reason: stopReason
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
function partialThinking(eventType, thinking = "", stopReason = "completed") {
|
|
117
|
+
return model({
|
|
118
|
+
type: "partial_thinking",
|
|
119
|
+
role: "assistant",
|
|
120
|
+
event_type: eventType,
|
|
121
|
+
thinking,
|
|
122
|
+
stop_reason: stopReason
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function partialToolCall(args) {
|
|
126
|
+
return model({
|
|
127
|
+
type: "partial_tool_call",
|
|
128
|
+
role: "assistant",
|
|
129
|
+
event_type: args.eventType,
|
|
130
|
+
name: args.name,
|
|
131
|
+
arguments: args.arguments ?? "",
|
|
132
|
+
tool_call_id: args.toolCallId,
|
|
133
|
+
stop_reason: args.stopReason ?? "completed"
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function partialToolCallOutput(args) {
|
|
137
|
+
return model({
|
|
138
|
+
type: "partial_tool_call_output",
|
|
139
|
+
role: "user",
|
|
140
|
+
event_type: args.eventType,
|
|
141
|
+
output: args.output ?? "",
|
|
142
|
+
...args.images !== void 0 && args.images.length > 0 ? { images: args.images } : {},
|
|
143
|
+
tool_call_id: args.toolCallId,
|
|
144
|
+
stop_reason: args.stopReason ?? "completed"
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function approvalDecision(decision, toolCallId) {
|
|
148
|
+
return event({ type: "approval_decision", decision, tool_call_id: toolCallId });
|
|
149
|
+
}
|
|
150
|
+
function abortEvent(reason = null) {
|
|
151
|
+
return event({ type: "abort", reason });
|
|
152
|
+
}
|
|
153
|
+
function requestBegin() {
|
|
154
|
+
return event({ type: "request_begin" });
|
|
155
|
+
}
|
|
156
|
+
function requestEnd(status) {
|
|
157
|
+
return event({ type: "request_end", status });
|
|
158
|
+
}
|
|
159
|
+
function compactionBegin(args) {
|
|
160
|
+
return event({
|
|
161
|
+
type: "compaction_begin",
|
|
162
|
+
reason: args.reason,
|
|
163
|
+
mode: args.mode,
|
|
164
|
+
context: args.context,
|
|
165
|
+
turns: args.turns
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function compactionEnd(args) {
|
|
169
|
+
return event({
|
|
170
|
+
type: "compaction_end",
|
|
171
|
+
reason: args.reason,
|
|
172
|
+
mode: args.mode,
|
|
173
|
+
status: args.status
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
function subagentEvent(sessionId) {
|
|
177
|
+
return event({ type: "subagent", session_id: sessionId });
|
|
178
|
+
}
|
|
179
|
+
function emptyTokenCounts() {
|
|
180
|
+
return { cache_read: 0, cache_write: 0, output: 0, total: 0 };
|
|
181
|
+
}
|
|
182
|
+
function tokenUsage(session, request) {
|
|
183
|
+
return event({ type: "token_usage", session, request });
|
|
184
|
+
}
|
|
185
|
+
function addTokenCounts(a, b) {
|
|
186
|
+
return {
|
|
187
|
+
cache_read: a.cache_read + b.cache_read,
|
|
188
|
+
cache_write: a.cache_write + b.cache_write,
|
|
189
|
+
output: a.output + b.output,
|
|
190
|
+
total: a.total + b.total
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function withOrigin(msg, sessionId) {
|
|
194
|
+
return { ...msg, origin: [sessionId, ...msg.origin ?? []] };
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/omnimessage/aggregate.ts
|
|
198
|
+
function fragmentKey(p) {
|
|
199
|
+
const id = "tool_call_id" in p ? p.tool_call_id : "";
|
|
200
|
+
return `${p.type}::${id}`;
|
|
201
|
+
}
|
|
202
|
+
function finalize(frag) {
|
|
203
|
+
switch (frag.kind) {
|
|
204
|
+
case "partial_text":
|
|
205
|
+
return assistantText(frag.buffer, frag.lastStopReason);
|
|
206
|
+
case "partial_thinking":
|
|
207
|
+
return thinkingMessage(frag.buffer, frag.lastStopReason);
|
|
208
|
+
case "partial_tool_call":
|
|
209
|
+
return toolCall({
|
|
210
|
+
name: frag.name ?? "",
|
|
211
|
+
arguments: frag.buffer,
|
|
212
|
+
toolCallId: frag.toolCallId ?? "",
|
|
213
|
+
stopReason: frag.lastStopReason
|
|
214
|
+
});
|
|
215
|
+
case "partial_tool_call_output":
|
|
216
|
+
return toolCallOutput({
|
|
217
|
+
output: frag.buffer,
|
|
218
|
+
toolCallId: frag.toolCallId ?? "",
|
|
219
|
+
stopReason: frag.lastStopReason,
|
|
220
|
+
...frag.images !== void 0 ? { images: frag.images } : {}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function appendDelta(frag, p) {
|
|
225
|
+
switch (p.type) {
|
|
226
|
+
case "partial_text":
|
|
227
|
+
frag.buffer += p.text;
|
|
228
|
+
break;
|
|
229
|
+
case "partial_thinking":
|
|
230
|
+
frag.buffer += p.thinking;
|
|
231
|
+
break;
|
|
232
|
+
case "partial_tool_call":
|
|
233
|
+
frag.buffer += p.arguments;
|
|
234
|
+
if (p.name) frag.name = p.name;
|
|
235
|
+
frag.toolCallId = p.tool_call_id;
|
|
236
|
+
break;
|
|
237
|
+
case "partial_tool_call_output":
|
|
238
|
+
frag.buffer += p.output;
|
|
239
|
+
if (p.images && p.images.length > 0) frag.images = p.images;
|
|
240
|
+
frag.toolCallId = p.tool_call_id;
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
if (p.stop_reason !== void 0) frag.lastStopReason = p.stop_reason;
|
|
244
|
+
}
|
|
245
|
+
function newFragment(p) {
|
|
246
|
+
const frag = {
|
|
247
|
+
kind: p.type,
|
|
248
|
+
buffer: "",
|
|
249
|
+
lastStopReason: "completed"
|
|
250
|
+
};
|
|
251
|
+
if (p.type === "partial_tool_call") {
|
|
252
|
+
frag.name = p.name;
|
|
253
|
+
frag.toolCallId = p.tool_call_id;
|
|
254
|
+
} else if (p.type === "partial_tool_call_output") {
|
|
255
|
+
frag.toolCallId = p.tool_call_id;
|
|
256
|
+
}
|
|
257
|
+
return frag;
|
|
258
|
+
}
|
|
259
|
+
var PartialAggregator = class {
|
|
260
|
+
open = /* @__PURE__ */ new Map();
|
|
261
|
+
push(msg) {
|
|
262
|
+
if (!isPartialPayload(msg.payload)) {
|
|
263
|
+
return [msg];
|
|
264
|
+
}
|
|
265
|
+
const p = msg.payload;
|
|
266
|
+
const key = fragmentKey(p);
|
|
267
|
+
let frag = this.open.get(key);
|
|
268
|
+
if (p.event_type === "start") {
|
|
269
|
+
const out = [];
|
|
270
|
+
if (frag) out.push(finalize(frag));
|
|
271
|
+
frag = newFragment(p);
|
|
272
|
+
appendDelta(frag, p);
|
|
273
|
+
this.open.set(key, frag);
|
|
274
|
+
return out;
|
|
275
|
+
}
|
|
276
|
+
if (!frag) {
|
|
277
|
+
frag = newFragment(p);
|
|
278
|
+
this.open.set(key, frag);
|
|
279
|
+
}
|
|
280
|
+
appendDelta(frag, p);
|
|
281
|
+
if (p.event_type === "stop") {
|
|
282
|
+
this.open.delete(key);
|
|
283
|
+
return [finalize(frag)];
|
|
284
|
+
}
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
/** Finalizes: emits all still-open fragments (in the order they were opened). */
|
|
288
|
+
flush() {
|
|
289
|
+
const out = [...this.open.values()].map(finalize);
|
|
290
|
+
this.open.clear();
|
|
291
|
+
return out;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
function aggregateAll(messages) {
|
|
295
|
+
const agg = new PartialAggregator();
|
|
296
|
+
const out = [];
|
|
297
|
+
for (const msg of messages) out.push(...agg.push(msg));
|
|
298
|
+
out.push(...agg.flush());
|
|
299
|
+
return out;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export {
|
|
303
|
+
isPartialPayload,
|
|
304
|
+
isModelMessage,
|
|
305
|
+
isEventMessage,
|
|
306
|
+
isSessionMeta,
|
|
307
|
+
isCompleteModelMessage,
|
|
308
|
+
sessionMeta,
|
|
309
|
+
textMessage,
|
|
310
|
+
userText,
|
|
311
|
+
assistantText,
|
|
312
|
+
imageUrlMessage,
|
|
313
|
+
inlineData,
|
|
314
|
+
thinkingMessage,
|
|
315
|
+
inlineThinking,
|
|
316
|
+
toolCall,
|
|
317
|
+
toolCallOutput,
|
|
318
|
+
partialText,
|
|
319
|
+
partialThinking,
|
|
320
|
+
partialToolCall,
|
|
321
|
+
partialToolCallOutput,
|
|
322
|
+
approvalDecision,
|
|
323
|
+
abortEvent,
|
|
324
|
+
requestBegin,
|
|
325
|
+
requestEnd,
|
|
326
|
+
compactionBegin,
|
|
327
|
+
compactionEnd,
|
|
328
|
+
subagentEvent,
|
|
329
|
+
emptyTokenCounts,
|
|
330
|
+
tokenUsage,
|
|
331
|
+
addTokenCounts,
|
|
332
|
+
withOrigin,
|
|
333
|
+
PartialAggregator,
|
|
334
|
+
aggregateAll
|
|
335
|
+
};
|
|
336
|
+
//# sourceMappingURL=chunk-JC6SC6KF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/omnimessage/types.ts","../src/omnimessage/builders.ts","../src/omnimessage/aggregate.ts"],"sourcesContent":["/**\n * OmniMessage — PenguinHarness's primary message protocol.\n *\n * All messages share one envelope: `timestamp` (ISO 8601 UTC), `type`, and `payload`.\n * The outer `type` falls into three categories:\n * - `session_meta`: Session metadata;\n * - `model_msg`: model input/output messages (both complete messages and streaming\n * `partial_*` messages);\n * - `event_msg`: control/statistics events during execution.\n *\n * Trace records only: `session_meta`, complete `model_msg`, and all `event_msg`;\n * the Human interface communicates using: complete `model_msg`, streaming `partial_*`, and all\n * `event_msg`.\n *\n * Docs: packages/docs/content/omni-message.{zh,en}.md (site path /docs/omni-message) documents\n * this protocol payload-for-payload — keep the page in sync when changing types here.\n */\n\n/** The outer message category. */\nexport type OmniMessageType = \"session_meta\" | \"model_msg\" | \"event_msg\";\n\n/** The message's originating role. */\nexport type Role = \"user\" | \"assistant\";\n\n/**\n * The reason a model response or message generation ended. Only five protocol values are\n * allowed:\n * - `completed`: finished normally, including completed text, thinking, tool requests, or\n * tool output;\n * - `failed`: a non-retryable error or tool execution failure;\n * - `aborted`: user-initiated interruption or cancellation;\n * - `timeout`: LLM request timed out;\n * - `malformed`: the LLM response was malformed (e.g. AgentHub JSON parsing exception).\n * Only LLM timeout / malformed trigger a context_engine reconnect.\n * Docs: /docs/omni-message § \"stop_reason\".\n */\nexport type StopReason = \"completed\" | \"failed\" | \"aborted\" | \"timeout\" | \"malformed\";\n\n/** The event phase of a streaming fragment. `stop` marks the end of a fragment and usually carries no incremental content. */\nexport type StreamEventType = \"start\" | \"delta\" | \"stop\";\n\n/**\n * Nested-origin marker: a child Session id. The message envelope's `origin` is a chain of child\n * Session ids ordered **outer-to-inner**, identifying that the message comes from a nested child\n * session (e.g. a child Session derived by `run_subagent`); each layer of host-tool forwarding\n * prepends one more hop at the front. **An absent `origin` (the message carries no `origin`)\n * means the message comes from the main Session itself** (an empty array is never produced\n * either). Only session_id is recorded: the corresponding tool_call / agent info can be obtained\n * from the `run_subagent` tool_call in the parent session's stream and the child Session's own\n * Trace (session_meta).\n * Docs: /docs/omni-message § \"origin: the Subagent chain\".\n */\nexport type MessageOrigin = string;\n\n/** The approval decision for a tool call. */\nexport type ApprovalDecision = \"allow\" | \"deny\";\n\n/** Token counts (input/output/cache/total). */\nexport interface TokenCounts {\n cache_read: number;\n cache_write: number;\n output: number;\n total: number;\n}\n\n// ---------------------------------------------------------------------------\n// session_meta\n// ---------------------------------------------------------------------------\n// Docs: /docs/omni-message § \"session_meta\"\n\n/** Tool definition passed to the LLM (OpenAI/JSON Schema style). */\nexport interface ToolDefinition {\n name: string;\n description: string;\n parameters?: Record<string, unknown>;\n}\n\nexport interface SessionMetaPayload {\n session_id: string;\n /** The session model's provider group (paired with `model_id` to form a model reference). */\n provider: string;\n /** The session model's upstream model_id (the request id sent to AgentHub; paired with `provider`). */\n model_id: string;\n model_context_window: number | string;\n /** The system prompt actually used by this Session (the assembled result with environment placeholders already substituted). */\n system_prompt: string;\n /** The list of tool definitions this Session exposes to the model (full schema, matching what's sent to the LLM). */\n tools: ToolDefinition[];\n /** The model's thinking level (from system_config.model.thinking_level; \"default\" when unconfigured). */\n thinking_level: string;\n /** Absolute path to the Agent State. */\n agent_state: string;\n /** Absolute path to the Workspace. */\n workspace: string;\n}\n\n// ---------------------------------------------------------------------------\n// model_msg — complete messages\n// ---------------------------------------------------------------------------\n// Docs: /docs/omni-message § \"model_msg: complete payloads\"\n\nexport interface TextPayload {\n type: \"text\";\n role: Role;\n text: string;\n stop_reason?: StopReason;\n /** Provider fidelity field: text phase marker (e.g. GPT-5 segments by phase), kept as-is and restored verbatim. */\n phase?: string | null;\n /** Provider fidelity field: signature, kept as-is and restored verbatim. */\n signature?: string;\n}\n\nexport interface ImageUrlPayload {\n type: \"image_url\";\n role: \"user\";\n /** A web URL or a base64 data URL. */\n image_url: string;\n stop_reason?: StopReason;\n}\n\nexport interface InlineDataPayload {\n type: \"inline_data\";\n role: Role;\n /** Base64-encoded bytes. */\n data: string;\n mime_type: string;\n stop_reason?: StopReason;\n /** Provider fidelity field: signature, kept as-is and restored verbatim. */\n signature?: string;\n}\n\nexport interface ThinkingPayload {\n type: \"thinking\";\n role: \"assistant\";\n thinking: string;\n stop_reason?: StopReason;\n /**\n * Provider fidelity field: thinking-block signature (Claude thinking blocks / redacted\n * thinking, GPT-5 encrypted reasoning, etc. — **required** when some models replay history),\n * kept as-is and restored verbatim — losing it breaks Session resumption.\n */\n signature?: string;\n}\n\nexport interface InlineThinkingPayload {\n type: \"inline_thinking\";\n role: \"assistant\";\n /** Base64-encoded bytes. */\n data: string;\n mime_type: string;\n stop_reason?: StopReason;\n /** Provider fidelity field: signature, kept as-is and restored verbatim. */\n signature?: string;\n}\n\nexport interface ToolCallPayload {\n type: \"tool_call\";\n role: \"assistant\";\n name: string;\n /** Tool arguments as a JSON string. */\n arguments: string;\n tool_call_id: string;\n stop_reason?: StopReason;\n /** Provider fidelity field: signature, kept as-is and restored verbatim. */\n signature?: string;\n}\n\nexport interface ToolCallOutputPayload {\n type: \"tool_call_output\";\n role: \"user\";\n output: string;\n /**\n * Images carried by the tool output (optional): each is a `data:<mime>;base64,...` data URL,\n * fed back to the model alongside the text (e.g. images read by read_image). Images aren't\n * incremental: the streaming path carries the whole set once via a single delta (see\n * `PartialToolCallOutputPayload.images`), and the complete message carries them again — the\n * streamed-and-joined result equals the complete message.\n */\n images?: string[];\n tool_call_id: string;\n stop_reason?: StopReason;\n}\n\n// ---------------------------------------------------------------------------\n// model_msg — streaming partial_* messages\n// ---------------------------------------------------------------------------\n// Docs: /docs/omni-message § \"model_msg: streaming partials\"\n\nexport interface PartialTextPayload {\n type: \"partial_text\";\n role: \"assistant\";\n event_type: StreamEventType;\n text: string;\n stop_reason?: StopReason;\n}\n\nexport interface PartialThinkingPayload {\n type: \"partial_thinking\";\n role: \"assistant\";\n event_type: StreamEventType;\n thinking: string;\n stop_reason?: StopReason;\n}\n\nexport interface PartialToolCallPayload {\n type: \"partial_tool_call\";\n role: \"assistant\";\n event_type: StreamEventType;\n name: string;\n /** Incremental fragment of the arguments JSON. */\n arguments: string;\n tool_call_id: string;\n stop_reason?: StopReason;\n}\n\nexport interface PartialToolCallOutputPayload {\n type: \"partial_tool_call_output\";\n role: \"user\";\n event_type: StreamEventType;\n output: string;\n /** Images carried by the tool output (optional): images aren't incremental, carried as a whole by a single delta (consistent with the complete message). */\n images?: string[];\n tool_call_id: string;\n stop_reason?: StopReason;\n}\n\n// ---------------------------------------------------------------------------\n// event_msg\n// ---------------------------------------------------------------------------\n// Docs: /docs/omni-message § \"event_msg\"\n\nexport interface ApprovalDecisionPayload {\n type: \"approval_decision\";\n decision: ApprovalDecision;\n tool_call_id: string;\n}\n\nexport interface AbortPayload {\n type: \"abort\";\n reason?: string | null;\n}\n\nexport interface TokenUsagePayload {\n type: \"token_usage\";\n /** Current Session cumulative token usage. */\n session: TokenCounts;\n /** Token usage for the most recent Request. */\n request: TokenCounts;\n}\n\n/**\n * Request boundary event: the boundary of one LLM Request, produced **in pairs** by\n * `context_engine` and written to Trace. `request_end`\n * with `status` of `completed` means the turn has been committed by AgentHub — this is the\n * mechanical criterion Trace replay (Session resumption) uses to determine whether a turn was\n * committed, and it also gives performance analysis a basis for Request latency and turn counts.\n * A compaction request produces this same event pair too (written to Trace only, not streamed).\n */\nexport interface RequestBeginPayload {\n type: \"request_begin\";\n}\n\nexport interface RequestEndPayload {\n type: \"request_end\";\n /** Terminal state of this Request (reuses the five StopReason values, sharing its source with this turn's complete message's stop_reason / LLMOutcome). */\n status: StopReason;\n}\n\n/** Compaction trigger reason: context threshold / turn-count threshold / user-initiated request. */\nexport type CompactionReason = \"context\" | \"turns\" | \"manual\";\n\n/** Context compaction mode: summary relay / direct discard. */\nexport type CompactionMode = \"summarize\" | \"discard\";\n\n/**\n * Compaction boundary event: the compaction process exposes\n * only this event pair to Human, produced **in pairs** by `context_engine`. Both `reason` and\n * `mode` are carried on both events, for stateless frontend rendering; `status` reuses the\n * five-value `StopReason` protocol (compaction converges to a terminal state, taking\n * `completed` / `failed` / `aborted` in practice — `timeout` / `malformed` are handled internally\n * by the compaction request's existing retry mechanism, collapsing to `failed` once retries are\n * exhausted).\n */\nexport interface CompactionBeginPayload {\n type: \"compaction_begin\";\n reason: CompactionReason;\n mode: CompactionMode;\n /** Current context token usage (the most recent token_usage's request.total). */\n context: number;\n /** Session cumulative turn count. */\n turns: number;\n}\n\nexport interface CompactionEndPayload {\n type: \"compaction_end\";\n reason: CompactionReason;\n mode: CompactionMode;\n /** Compaction result; non-`completed` means compaction was abandoned and the original context was kept. */\n status: StopReason;\n}\n\n/**\n * Subagent pointer event: when the parent Session spawns a\n * **direct** child session, `context_engine` writes this to the parent Trace (not streamed),\n * recording only the child session's Session id — the child session's other details live in its\n * own Trace's `session_meta`. When the session is reopened, the server uses this to recursively\n * expand the child Trace and reconstruct the `origin` chain; a grandchild session's pointer is\n * recorded by the child Trace itself.\n */\nexport interface SubagentPayload {\n type: \"subagent\";\n /** The direct child session's Session id. */\n session_id: string;\n}\n\n// ---------------------------------------------------------------------------\n// Union types and the message envelope\n// ---------------------------------------------------------------------------\n\n/** Complete model_msg payload (written to Trace and exposed externally). */\nexport type CompleteModelPayload =\n | TextPayload\n | ImageUrlPayload\n | InlineDataPayload\n | ThinkingPayload\n | InlineThinkingPayload\n | ToolCallPayload\n | ToolCallOutputPayload;\n\n/** Streaming model_msg payload. */\nexport type PartialModelPayload =\n | PartialTextPayload\n | PartialThinkingPayload\n | PartialToolCallPayload\n | PartialToolCallOutputPayload;\n\nexport type ModelPayload = CompleteModelPayload | PartialModelPayload;\n\nexport type EventPayload =\n | ApprovalDecisionPayload\n | AbortPayload\n | RequestBeginPayload\n | RequestEndPayload\n | TokenUsagePayload\n | CompactionBeginPayload\n | CompactionEndPayload\n | SubagentPayload;\n\nexport type OmniPayload = SessionMetaPayload | ModelPayload | EventPayload;\n\n/** The unified message envelope. */\nexport interface OmniMessage<P extends OmniPayload = OmniPayload> {\n /** ISO 8601 UTC timestamp. */\n timestamp: string;\n type: OmniMessageType;\n payload: P;\n /** Nested-origin marker: the chain of child Session ids ordered outer-to-inner; absent = from the main Session (see MessageOrigin). */\n origin?: MessageOrigin[];\n}\n\n// Convenience aliases for concrete message types --------------------------------\n\nexport type SessionMetaMessage = OmniMessage<SessionMetaPayload>;\nexport type ModelMessage = OmniMessage<ModelPayload>;\nexport type EventMessage = OmniMessage<EventPayload>;\nexport type CompleteModelMessage = OmniMessage<CompleteModelPayload>;\nexport type PartialModelMessage = OmniMessage<PartialModelPayload>;\n\n// ---------------------------------------------------------------------------\n// Runtime discrimination helpers\n// ---------------------------------------------------------------------------\n\n/** The set of type values for streaming partial_* payloads. */\nconst PARTIAL_PAYLOAD_TYPES = [\n \"partial_text\",\n \"partial_thinking\",\n \"partial_tool_call\",\n \"partial_tool_call_output\",\n] as const;\n\nexport function isPartialPayload(p: OmniPayload): p is PartialModelPayload {\n return (PARTIAL_PAYLOAD_TYPES as readonly string[]).includes((p as { type?: string }).type ?? \"\");\n}\n\nexport function isModelMessage(msg: OmniMessage): msg is ModelMessage {\n return msg.type === \"model_msg\";\n}\n\nexport function isEventMessage(msg: OmniMessage): msg is EventMessage {\n return msg.type === \"event_msg\";\n}\n\nexport function isSessionMeta(msg: OmniMessage): msg is SessionMetaMessage {\n return msg.type === \"session_meta\";\n}\n\n/** A complete model_msg (not partial_*), i.e. a message that can be written to Trace. */\nexport function isCompleteModelMessage(msg: OmniMessage): msg is CompleteModelMessage {\n return msg.type === \"model_msg\" && !isPartialPayload(msg.payload);\n}\n","/**\n * OmniMessage builders. All modules create messages exclusively through these builders, avoiding\n * ad hoc protocol structures scattered across the codebase.\n * Every builder writes an ISO 8601 UTC timestamp.\n * Docs: /docs/omni-message § \"Builders and guards\".\n */\nimport type {\n AbortPayload,\n ApprovalDecision,\n ApprovalDecisionPayload,\n CompactionBeginPayload,\n CompactionEndPayload,\n CompactionMode,\n CompactionReason,\n EventMessage,\n ImageUrlPayload,\n InlineDataPayload,\n InlineThinkingPayload,\n MessageOrigin,\n ModelMessage,\n OmniMessage,\n PartialTextPayload,\n PartialThinkingPayload,\n PartialToolCallOutputPayload,\n PartialToolCallPayload,\n RequestBeginPayload,\n RequestEndPayload,\n Role,\n SessionMetaMessage,\n SessionMetaPayload,\n StopReason,\n StreamEventType,\n SubagentPayload,\n TextPayload,\n ThinkingPayload,\n TokenCounts,\n TokenUsagePayload,\n ToolCallOutputPayload,\n ToolCallPayload,\n} from \"./types.js\";\n\n/** The current moment's ISO 8601 UTC timestamp. */\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction model<P extends ModelMessage[\"payload\"]>(payload: P): OmniMessage<P> {\n return { timestamp: nowIso(), type: \"model_msg\", payload };\n}\n\nfunction event<P extends EventMessage[\"payload\"]>(payload: P): OmniMessage<P> {\n return { timestamp: nowIso(), type: \"event_msg\", payload };\n}\n\n// session_meta ---------------------------------------------------------------\n\nexport function sessionMeta(payload: SessionMetaPayload): SessionMetaMessage {\n return { timestamp: nowIso(), type: \"session_meta\", payload };\n}\n\n// Complete model_msg -----------------------------------------------------------\n\n/**\n * Provider fidelity fields: kept as-is and restored verbatim on replay.\n * Builder convention: positional-argument-style builders carry these in a trailing `fidelity`\n * object (narrowed via Pick per payload type — e.g. thinking only has signature); object-argument-\n * style builders (toolCall) flatten `fidelity` fields into the parameter object alongside\n * `stopReason`, mirroring the payload structure directly.\n */\nexport interface FidelityFields {\n phase?: string | null;\n signature?: string;\n}\n\nexport function textMessage(\n role: Role,\n text: string,\n stopReason: StopReason = \"completed\",\n fidelity?: FidelityFields,\n): OmniMessage<TextPayload> {\n return model({\n type: \"text\",\n role,\n text,\n stop_reason: stopReason,\n ...(fidelity?.phase != null ? { phase: fidelity.phase } : {}),\n ...(fidelity?.signature !== undefined ? { signature: fidelity.signature } : {}),\n });\n}\n\nexport const userText = (text: string): OmniMessage<TextPayload> => textMessage(\"user\", text);\n\nexport const assistantText = (\n text: string,\n stopReason: StopReason = \"completed\",\n fidelity?: FidelityFields,\n): OmniMessage<TextPayload> => textMessage(\"assistant\", text, stopReason, fidelity);\n\nexport function imageUrlMessage(imageUrl: string): OmniMessage<ImageUrlPayload> {\n return model({\n type: \"image_url\",\n role: \"user\",\n image_url: imageUrl,\n stop_reason: \"completed\",\n });\n}\n\nexport function inlineData(\n role: Role,\n data: string,\n mimeType: string,\n fidelity?: Pick<FidelityFields, \"signature\">,\n): OmniMessage<InlineDataPayload> {\n return model({\n type: \"inline_data\",\n role,\n data,\n mime_type: mimeType,\n stop_reason: \"completed\",\n ...(fidelity?.signature !== undefined ? { signature: fidelity.signature } : {}),\n });\n}\n\nexport function thinkingMessage(\n thinking: string,\n stopReason: StopReason = \"completed\",\n fidelity?: Pick<FidelityFields, \"signature\">,\n): OmniMessage<ThinkingPayload> {\n return model({\n type: \"thinking\",\n role: \"assistant\",\n thinking,\n stop_reason: stopReason,\n ...(fidelity?.signature !== undefined ? { signature: fidelity.signature } : {}),\n });\n}\n\nexport function inlineThinking(\n data: string,\n mimeType: string,\n fidelity?: Pick<FidelityFields, \"signature\">,\n): OmniMessage<InlineThinkingPayload> {\n return model({\n type: \"inline_thinking\",\n role: \"assistant\",\n data,\n mime_type: mimeType,\n stop_reason: \"completed\",\n ...(fidelity?.signature !== undefined ? { signature: fidelity.signature } : {}),\n });\n}\n\nexport function toolCall(args: {\n name: string;\n arguments: string;\n toolCallId: string;\n stopReason?: StopReason;\n signature?: string;\n}): OmniMessage<ToolCallPayload> {\n return model({\n type: \"tool_call\",\n role: \"assistant\",\n name: args.name,\n arguments: args.arguments,\n tool_call_id: args.toolCallId,\n stop_reason: args.stopReason ?? \"completed\",\n ...(args.signature !== undefined ? { signature: args.signature } : {}),\n });\n}\n\nexport function toolCallOutput(args: {\n output: string;\n toolCallId: string;\n stopReason?: StopReason;\n /** Images carried by the tool output (array of data URLs); images aren't incremental — a single delta carries the whole set in the streaming path, and the complete message carries them too. */\n images?: string[];\n}): OmniMessage<ToolCallOutputPayload> {\n return model({\n type: \"tool_call_output\",\n role: \"user\",\n output: args.output,\n ...(args.images !== undefined && args.images.length > 0 ? { images: args.images } : {}),\n tool_call_id: args.toolCallId,\n stop_reason: args.stopReason ?? \"completed\",\n });\n}\n\n// Streaming partial_* model_msg -------------------------------------------------\n\nexport function partialText(\n eventType: StreamEventType,\n text = \"\",\n stopReason: StopReason = \"completed\",\n): OmniMessage<PartialTextPayload> {\n return model({\n type: \"partial_text\",\n role: \"assistant\",\n event_type: eventType,\n text,\n stop_reason: stopReason,\n });\n}\n\nexport function partialThinking(\n eventType: StreamEventType,\n thinking = \"\",\n stopReason: StopReason = \"completed\",\n): OmniMessage<PartialThinkingPayload> {\n return model({\n type: \"partial_thinking\",\n role: \"assistant\",\n event_type: eventType,\n thinking,\n stop_reason: stopReason,\n });\n}\n\nexport function partialToolCall(args: {\n eventType: StreamEventType;\n name: string;\n arguments?: string;\n toolCallId: string;\n stopReason?: StopReason;\n}): OmniMessage<PartialToolCallPayload> {\n return model({\n type: \"partial_tool_call\",\n role: \"assistant\",\n event_type: args.eventType,\n name: args.name,\n arguments: args.arguments ?? \"\",\n tool_call_id: args.toolCallId,\n stop_reason: args.stopReason ?? \"completed\",\n });\n}\n\nexport function partialToolCallOutput(args: {\n eventType: StreamEventType;\n output?: string;\n toolCallId: string;\n stopReason?: StopReason;\n /** Images carried by the tool output (array of data URLs); images aren't incremental — a single delta carries the whole set. */\n images?: string[];\n}): OmniMessage<PartialToolCallOutputPayload> {\n return model({\n type: \"partial_tool_call_output\",\n role: \"user\",\n event_type: args.eventType,\n output: args.output ?? \"\",\n ...(args.images !== undefined && args.images.length > 0 ? { images: args.images } : {}),\n tool_call_id: args.toolCallId,\n stop_reason: args.stopReason ?? \"completed\",\n });\n}\n\n// event_msg -------------------------------------------------------------------\n\nexport function approvalDecision(\n decision: ApprovalDecision,\n toolCallId: string,\n): OmniMessage<ApprovalDecisionPayload> {\n return event({ type: \"approval_decision\", decision, tool_call_id: toolCallId });\n}\n\nexport function abortEvent(reason: string | null = null): OmniMessage<AbortPayload> {\n return event({ type: \"abort\", reason });\n}\n\n/** request begin event: marks the start of one LLM Request. */\nexport function requestBegin(): OmniMessage<RequestBeginPayload> {\n return event({ type: \"request_begin\" });\n}\n\n/** request end event: carries the terminal state (`completed` means this turn was already committed to AgentHub). */\nexport function requestEnd(status: StopReason): OmniMessage<RequestEndPayload> {\n return event({ type: \"request_end\", status });\n}\n\n/** compaction begin event: carries the trigger reason, mode, current context usage, and cumulative Session turn count. */\nexport function compactionBegin(args: {\n reason: CompactionReason;\n mode: CompactionMode;\n context: number;\n turns: number;\n}): OmniMessage<CompactionBeginPayload> {\n return event({\n type: \"compaction_begin\",\n reason: args.reason,\n mode: args.mode,\n context: args.context,\n turns: args.turns,\n });\n}\n\n/** compaction end event: carries the compaction result (non-`completed` means compaction was abandoned and the original context is kept). */\nexport function compactionEnd(args: {\n reason: CompactionReason;\n mode: CompactionMode;\n status: StopReason;\n}): OmniMessage<CompactionEndPayload> {\n return event({\n type: \"compaction_end\",\n reason: args.reason,\n mode: args.mode,\n status: args.status,\n });\n}\n\n/** subagent derivation pointer event: records only the direct child session's Session id (written to the parent Trace by context_engine). */\nexport function subagentEvent(sessionId: string): OmniMessage<SubagentPayload> {\n return event({ type: \"subagent\", session_id: sessionId });\n}\n\nexport function emptyTokenCounts(): TokenCounts {\n return { cache_read: 0, cache_write: 0, output: 0, total: 0 };\n}\n\nexport function tokenUsage(\n session: TokenCounts,\n request: TokenCounts,\n): OmniMessage<TokenUsagePayload> {\n return event({ type: \"token_usage\", session, request });\n}\n\n/** Adds two sets of Token counts together, used to maintain cumulative Session usage. */\nexport function addTokenCounts(a: TokenCounts, b: TokenCounts): TokenCounts {\n return {\n cache_read: a.cache_read + b.cache_read,\n cache_write: a.cache_write + b.cache_write,\n output: a.output + b.output,\n total: a.total + b.total,\n };\n}\n\n/**\n * Marks a message with a nested-origin tag: prepends one hop (a child Session id) to the front\n * of `origin`, outer-to-inner.\n * Used by host tools (e.g. run_subagent) when forwarding child-session messages; an absent\n * `origin` means the message comes from the main Session.\n */\nexport function withOrigin<M extends OmniMessage>(msg: M, sessionId: MessageOrigin): M {\n return { ...msg, origin: [sessionId, ...(msg.origin ?? [])] };\n}\n","/**\n * Aggregates streaming partial_* messages into a complete model_msg.\n *\n * When recording a Trace, streaming `partial_*` messages must first be joined into a complete\n * `model_msg` before writing. This module provides:\n * - `PartialAggregator`: a stateful aggregator, pushed one message at a time, producing a\n * complete message when a fragment ends with `stop`;\n * - `aggregateAll`: a one-shot pass that collapses `partial_*` messages in an array into\n * complete messages.\n *\n * Complete / event / session_meta messages pass through unchanged, preserving their original\n * order.\n * Docs: /docs/omni-message § \"The streaming discipline\".\n */\nimport { assistantText, thinkingMessage, toolCall, toolCallOutput } from \"./builders.js\";\nimport type { OmniMessage, PartialModelPayload, StopReason } from \"./types.js\";\nimport { isPartialPayload } from \"./types.js\";\n\ntype PartialKind = PartialModelPayload[\"type\"];\n\ninterface OpenFragment {\n kind: PartialKind;\n /** Accumulation buffer for text / thinking / tool_call arguments / tool_call_output. */\n buffer: string;\n name?: string;\n toolCallId?: string;\n /** Images carried by tool_call_output (images aren't incremental — a single delta carries the whole set; a later one overwrites). */\n images?: string[];\n lastStopReason: StopReason;\n}\n\n/** Merge key for partial fragments: same type + same tool_call_id counts as the same fragment. */\nfunction fragmentKey(p: PartialModelPayload): string {\n const id = \"tool_call_id\" in p ? p.tool_call_id : \"\";\n return `${p.type}::${id}`;\n}\n\nfunction finalize(frag: OpenFragment): OmniMessage {\n switch (frag.kind) {\n case \"partial_text\":\n return assistantText(frag.buffer, frag.lastStopReason);\n case \"partial_thinking\":\n return thinkingMessage(frag.buffer, frag.lastStopReason);\n case \"partial_tool_call\":\n return toolCall({\n name: frag.name ?? \"\",\n arguments: frag.buffer,\n toolCallId: frag.toolCallId ?? \"\",\n stopReason: frag.lastStopReason,\n });\n case \"partial_tool_call_output\":\n return toolCallOutput({\n output: frag.buffer,\n toolCallId: frag.toolCallId ?? \"\",\n stopReason: frag.lastStopReason,\n ...(frag.images !== undefined ? { images: frag.images } : {}),\n });\n }\n}\n\nfunction appendDelta(frag: OpenFragment, p: PartialModelPayload): void {\n switch (p.type) {\n case \"partial_text\":\n frag.buffer += p.text;\n break;\n case \"partial_thinking\":\n frag.buffer += p.thinking;\n break;\n case \"partial_tool_call\":\n frag.buffer += p.arguments;\n if (p.name) frag.name = p.name;\n frag.toolCallId = p.tool_call_id;\n break;\n case \"partial_tool_call_output\":\n frag.buffer += p.output;\n if (p.images && p.images.length > 0) frag.images = p.images;\n frag.toolCallId = p.tool_call_id;\n break;\n }\n if (p.stop_reason !== undefined) frag.lastStopReason = p.stop_reason;\n}\n\nfunction newFragment(p: PartialModelPayload): OpenFragment {\n const frag: OpenFragment = {\n kind: p.type,\n buffer: \"\",\n lastStopReason: \"completed\",\n };\n if (p.type === \"partial_tool_call\") {\n frag.name = p.name;\n frag.toolCallId = p.tool_call_id;\n } else if (p.type === \"partial_tool_call_output\") {\n frag.toolCallId = p.tool_call_id;\n }\n return frag;\n}\n\n/**\n * Stateful aggregator. Pushed one message at a time via `push`:\n * - complete / event / session_meta messages are returned unchanged;\n * - `partial_*` messages accumulate into an internal fragment, producing a complete message\n * when `event_type === \"stop\"`;\n * - `flush` forcibly emits any fragments that haven't yet received a stop.\n */\nexport class PartialAggregator {\n private open = new Map<string, OpenFragment>();\n\n push(msg: OmniMessage): OmniMessage[] {\n if (!isPartialPayload(msg.payload)) {\n return [msg];\n }\n const p = msg.payload;\n const key = fragmentKey(p);\n let frag = this.open.get(key);\n\n if (p.event_type === \"start\") {\n // start reopens a fragment; if a fragment with the same key already exists (out-of-order), finalize it first.\n const out: OmniMessage[] = [];\n if (frag) out.push(finalize(frag));\n frag = newFragment(p);\n appendDelta(frag, p);\n this.open.set(key, frag);\n return out;\n }\n\n if (!frag) {\n // delta/stop without a preceding start: handle leniently, creating a new fragment as needed.\n frag = newFragment(p);\n this.open.set(key, frag);\n }\n appendDelta(frag, p);\n\n if (p.event_type === \"stop\") {\n this.open.delete(key);\n return [finalize(frag)];\n }\n return [];\n }\n\n /** Finalizes: emits all still-open fragments (in the order they were opened). */\n flush(): OmniMessage[] {\n const out = [...this.open.values()].map(finalize);\n this.open.clear();\n return out;\n }\n}\n\n/** One-shot aggregation: keeps non-partial messages in their original order, collapsing partial ones into complete messages. */\nexport function aggregateAll(messages: OmniMessage[]): OmniMessage[] {\n const agg = new PartialAggregator();\n const out: OmniMessage[] = [];\n for (const msg of messages) out.push(...agg.push(msg));\n out.push(...agg.flush());\n return out;\n}\n"],"mappings":"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","names":[]}
|