mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 07:03:25 +00:00
Add timestamp to messages
This commit is contained in:
parent
ef09efaac9
commit
55dc0b6e08
24 changed files with 388 additions and 220 deletions
|
|
@ -9,6 +9,7 @@ async function testAbortSignal<TApi extends Api>(llm: Model<TApi>, options: Opti
|
|||
{
|
||||
role: "user",
|
||||
content: "What is 15 + 27? Think step by step. Then list 50 first names.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -29,7 +30,11 @@ async function testAbortSignal<TApi extends Api>(llm: Model<TApi>, options: Opti
|
|||
expect(msg.content.length).toBeGreaterThan(0);
|
||||
|
||||
context.messages.push(msg);
|
||||
context.messages.push({ role: "user", content: "Please continue, but only generate 5 names." });
|
||||
context.messages.push({
|
||||
role: "user",
|
||||
content: "Please continue, but only generate 5 names.",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
const followUp = await complete(llm, context, options);
|
||||
expect(followUp.stopReason).toBe("stop");
|
||||
|
|
@ -42,7 +47,7 @@ async function testImmediateAbort<TApi extends Api>(llm: Model<TApi>, options: O
|
|||
controller.abort();
|
||||
|
||||
const context: Context = {
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }],
|
||||
};
|
||||
|
||||
const response = await complete(llm, context, { ...options, signal: controller.signal });
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ async function calculateTest<TApi extends Api>(model: Model<TApi>, options: Opti
|
|||
1. Calculate 3485 * 4234 and 88823 * 3482 in parallel
|
||||
2. Calculate the sum of the two results using the calculator tool
|
||||
3. Output ONLY the final sum as a single integer number, nothing else.`,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
// Calculate expected results (using integers)
|
||||
|
|
@ -176,6 +177,7 @@ async function abortTest<TApi extends Api>(model: Model<TApi>, options: OptionsF
|
|||
const userPrompt: UserMessage = {
|
||||
role: "user",
|
||||
content: "Calculate 100 * 200, then 300 * 400, then 500 * 600, then sum all three results.",
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
// Create abort controller
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ async function testEmptyMessage<TApi extends Api>(llm: Model<TApi>, options: Opt
|
|||
const emptyMessage: UserMessage = {
|
||||
role: "user",
|
||||
content: [],
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
const context: Context = {
|
||||
|
|
@ -34,6 +35,7 @@ async function testEmptyStringMessage<TApi extends Api>(llm: Model<TApi>, option
|
|||
{
|
||||
role: "user",
|
||||
content: "",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -58,6 +60,7 @@ async function testWhitespaceOnlyMessage<TApi extends Api>(llm: Model<TApi>, opt
|
|||
{
|
||||
role: "user",
|
||||
content: " \n\t ",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -92,6 +95,7 @@ async function testEmptyAssistantMessage<TApi extends Api>(llm: Model<TApi>, opt
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "stop",
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
const context: Context = {
|
||||
|
|
@ -99,11 +103,13 @@ async function testEmptyAssistantMessage<TApi extends Api>(llm: Model<TApi>, opt
|
|||
{
|
||||
role: "user",
|
||||
content: "Hello, how are you?",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
emptyAssistant,
|
||||
{
|
||||
role: "user",
|
||||
content: "Please respond this time.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ const providerContexts = {
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
} satisfies AssistantMessage,
|
||||
toolResult: {
|
||||
role: "toolResult" as const,
|
||||
|
|
@ -56,6 +57,7 @@ const providerContexts = {
|
|||
toolName: "get_weather",
|
||||
output: "Weather in Tokyo: 18°C, partly cloudy",
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
} satisfies ToolResultMessage,
|
||||
facts: {
|
||||
calculation: 391,
|
||||
|
|
@ -98,6 +100,7 @@ const providerContexts = {
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
} satisfies AssistantMessage,
|
||||
toolResult: {
|
||||
role: "toolResult" as const,
|
||||
|
|
@ -105,6 +108,7 @@ const providerContexts = {
|
|||
toolName: "get_weather",
|
||||
output: "Weather in Berlin: 22°C, sunny",
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
} satisfies ToolResultMessage,
|
||||
facts: {
|
||||
calculation: 456,
|
||||
|
|
@ -146,6 +150,7 @@ const providerContexts = {
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
} satisfies AssistantMessage,
|
||||
toolResult: {
|
||||
role: "toolResult" as const,
|
||||
|
|
@ -153,6 +158,7 @@ const providerContexts = {
|
|||
toolName: "get_weather",
|
||||
output: "Weather in London: 15°C, rainy",
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
} satisfies ToolResultMessage,
|
||||
facts: {
|
||||
calculation: 525,
|
||||
|
|
@ -196,6 +202,7 @@ const providerContexts = {
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
} satisfies AssistantMessage,
|
||||
toolResult: {
|
||||
role: "toolResult" as const,
|
||||
|
|
@ -203,6 +210,7 @@ const providerContexts = {
|
|||
toolName: "get_weather",
|
||||
output: "Weather in Sydney: 25°C, clear",
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
} satisfies ToolResultMessage,
|
||||
facts: {
|
||||
calculation: 486,
|
||||
|
|
@ -239,6 +247,7 @@ const providerContexts = {
|
|||
},
|
||||
stopReason: "error",
|
||||
errorMessage: "Request was aborted",
|
||||
timestamp: Date.now(),
|
||||
} satisfies AssistantMessage,
|
||||
toolResult: null,
|
||||
facts: {
|
||||
|
|
@ -263,6 +272,7 @@ async function testProviderHandoff<TApi extends Api>(
|
|||
{
|
||||
role: "user",
|
||||
content: "Please do some calculations, tell me about capitals, and check the weather.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
sourceContext.message,
|
||||
];
|
||||
|
|
@ -281,6 +291,7 @@ async function testProviderHandoff<TApi extends Api>(
|
|||
3) What was the temperature?
|
||||
4) What capital city was mentioned?
|
||||
Please include the specific numbers and names.`,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
const context: Context = {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const calculatorTool: Tool<typeof calculatorSchema> = {
|
|||
async function basicTextGeneration<TApi extends Api>(model: Model<TApi>, options?: OptionsForApi<TApi>) {
|
||||
const context: Context = {
|
||||
systemPrompt: "You are a helpful assistant. Be concise.",
|
||||
messages: [{ role: "user", content: "Reply with exactly: 'Hello test successful'" }],
|
||||
messages: [{ role: "user", content: "Reply with exactly: 'Hello test successful'", timestamp: Date.now() }],
|
||||
};
|
||||
const response = await complete(model, context, options);
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ async function basicTextGeneration<TApi extends Api>(model: Model<TApi>, options
|
|||
expect(response.content.map((b) => (b.type === "text" ? b.text : "")).join("")).toContain("Hello test successful");
|
||||
|
||||
context.messages.push(response);
|
||||
context.messages.push({ role: "user", content: "Now say 'Goodbye test successful'" });
|
||||
context.messages.push({ role: "user", content: "Now say 'Goodbye test successful'", timestamp: Date.now() });
|
||||
|
||||
const secondResponse = await complete(model, context, options);
|
||||
|
||||
|
|
@ -65,6 +65,7 @@ async function handleToolCall<TApi extends Api>(model: Model<TApi>, options?: Op
|
|||
{
|
||||
role: "user",
|
||||
content: "Calculate 15 + 27 using the calculator tool.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
tools: [calculatorTool],
|
||||
|
|
@ -141,7 +142,7 @@ async function handleStreaming<TApi extends Api>(model: Model<TApi>, options?: O
|
|||
let textCompleted = false;
|
||||
|
||||
const context: Context = {
|
||||
messages: [{ role: "user", content: "Count from 1 to 3" }],
|
||||
messages: [{ role: "user", content: "Count from 1 to 3", timestamp: Date.now() }],
|
||||
};
|
||||
|
||||
const s = stream(model, context, options);
|
||||
|
|
@ -174,6 +175,7 @@ async function handleThinking<TApi extends Api>(model: Model<TApi>, options?: Op
|
|||
{
|
||||
role: "user",
|
||||
content: `Think long and hard about ${(Math.random() * 255) | 0} + 27. Think step by step. Then output the result.`,
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -228,6 +230,7 @@ async function handleImage<TApi extends Api>(model: Model<TApi>, options?: Optio
|
|||
},
|
||||
imageContent,
|
||||
],
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -251,6 +254,7 @@ async function multiTurn<TApi extends Api>(model: Model<TApi>, options?: Options
|
|||
{
|
||||
role: "user",
|
||||
content: "Think about this briefly, then calculate 42 * 17 and 453 + 434 using the calculator tool.",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
tools: [calculatorTool],
|
||||
|
|
@ -303,6 +307,7 @@ async function multiTurn<TApi extends Api>(model: Model<TApi>, options?: Options
|
|||
toolName: block.name,
|
||||
output: `${result}`,
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ describe("Tool Call Without Result Tests", () => {
|
|||
context.messages.push({
|
||||
role: "user",
|
||||
content: "Please calculate 25 * 18 using the calculate tool.",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// Step 3: Get the assistant's response (should contain a tool call)
|
||||
|
|
@ -54,6 +55,7 @@ describe("Tool Call Without Result Tests", () => {
|
|||
context.messages.push({
|
||||
role: "user",
|
||||
content: "Never mind, just tell me what is 2+2?",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// Step 5: The fix should filter out the orphaned tool call, and the request should succeed
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ async function testEmojiInToolResults<TApi extends Api>(llm: Model<TApi>, option
|
|||
{
|
||||
role: "user",
|
||||
content: "Use the test tool",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
|
|
@ -44,6 +45,7 @@ async function testEmojiInToolResults<TApi extends Api>(llm: Model<TApi>, option
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
tools: [
|
||||
|
|
@ -72,6 +74,7 @@ async function testEmojiInToolResults<TApi extends Api>(llm: Model<TApi>, option
|
|||
- Mathematical symbols: ∑∫∂√
|
||||
- Special quotes: "curly" 'quotes'`,
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
context.messages.push(toolResult);
|
||||
|
|
@ -80,6 +83,7 @@ async function testEmojiInToolResults<TApi extends Api>(llm: Model<TApi>, option
|
|||
context.messages.push({
|
||||
role: "user",
|
||||
content: "Summarize the tool result briefly.",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// This should not throw a surrogate pair error
|
||||
|
|
@ -97,6 +101,7 @@ async function testRealWorldLinkedInData<TApi extends Api>(llm: Model<TApi>, opt
|
|||
{
|
||||
role: "user",
|
||||
content: "Use the linkedin tool to get comments",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
|
|
@ -119,6 +124,7 @@ async function testRealWorldLinkedInData<TApi extends Api>(llm: Model<TApi>, opt
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
tools: [
|
||||
|
|
@ -151,6 +157,7 @@ Unanswered Comments: 2
|
|||
]
|
||||
}`,
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
context.messages.push(toolResult);
|
||||
|
|
@ -158,6 +165,7 @@ Unanswered Comments: 2
|
|||
context.messages.push({
|
||||
role: "user",
|
||||
content: "How many comments are there?",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// This should not throw a surrogate pair error
|
||||
|
|
@ -175,6 +183,7 @@ async function testUnpairedHighSurrogate<TApi extends Api>(llm: Model<TApi>, opt
|
|||
{
|
||||
role: "user",
|
||||
content: "Use the test tool",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
|
|
@ -197,6 +206,7 @@ async function testUnpairedHighSurrogate<TApi extends Api>(llm: Model<TApi>, opt
|
|||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
||||
},
|
||||
stopReason: "toolUse",
|
||||
timestamp: Date.now(),
|
||||
},
|
||||
],
|
||||
tools: [
|
||||
|
|
@ -218,6 +228,7 @@ async function testUnpairedHighSurrogate<TApi extends Api>(llm: Model<TApi>, opt
|
|||
toolName: "test_tool",
|
||||
output: `Text with unpaired surrogate: ${unpairedSurrogate} <- should be sanitized`,
|
||||
isError: false,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
|
||||
context.messages.push(toolResult);
|
||||
|
|
@ -225,6 +236,7 @@ async function testUnpairedHighSurrogate<TApi extends Api>(llm: Model<TApi>, opt
|
|||
context.messages.push({
|
||||
role: "user",
|
||||
content: "What did the tool return?",
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
// This should not throw a surrogate pair error
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue