fix: read prompt and tools from the normalized transcript
pi 0.86.0 hands custom providers a TranscriptContext: `systemPrompt` and `tools` are gone, and tool declarations live in the transcript's system messages. Reading `context.tools` therefore sent zero tools to Devin, so every Devin model answered that it cannot run commands, and the system prompt was dropped with it. Collapse the system messages first, then take the prompt and the current tool set from the replayed transcript. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e4d4ec3aae
commit
8cf221e13f
+17
-6
@@ -1,4 +1,11 @@
|
|||||||
import type { Context, Message, Tool } from "@earendil-works/pi-ai";
|
import {
|
||||||
|
collapseSystemMessages,
|
||||||
|
getCurrentSystemPrompt,
|
||||||
|
getCurrentTools,
|
||||||
|
type Message,
|
||||||
|
type Tool,
|
||||||
|
type TranscriptContext,
|
||||||
|
} from "@earendil-works/pi-ai";
|
||||||
|
|
||||||
export interface ContentPart {
|
export interface ContentPart {
|
||||||
type: "text" | "image";
|
type: "text" | "image";
|
||||||
@@ -39,13 +46,17 @@ function userContent(content: Message["content"]): string | ContentPart[] {
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapContextToChat(context: Context): MappedChat {
|
export function mapContextToChat(context: TranscriptContext): MappedChat {
|
||||||
|
// Devin takes one leading system message and knows no mid-conversation system
|
||||||
|
// message, so replay the transcript deltas into the leading one first.
|
||||||
|
const transcript = collapseSystemMessages(context);
|
||||||
|
const systemPrompt = getCurrentSystemPrompt(transcript.messages);
|
||||||
const messages: ChatHistoryItem[] = [];
|
const messages: ChatHistoryItem[] = [];
|
||||||
if (context.systemPrompt) {
|
if (systemPrompt) {
|
||||||
messages.push({ role: "system", content: context.systemPrompt });
|
messages.push({ role: "system", content: systemPrompt });
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const message of context.messages) {
|
for (const message of transcript.messages) {
|
||||||
if (message.role === "user") {
|
if (message.role === "user") {
|
||||||
messages.push({ role: "user", content: userContent(message.content) });
|
messages.push({ role: "user", content: userContent(message.content) });
|
||||||
continue;
|
continue;
|
||||||
@@ -86,7 +97,7 @@ export function mapContextToChat(context: Context): MappedChat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tools: ToolDef[] = (context.tools ?? []).map((tool: Tool) => ({
|
const tools: ToolDef[] = getCurrentTools(transcript.messages).map((tool: Tool) => ({
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
description: tool.description,
|
description: tool.description,
|
||||||
parameters: tool.parameters,
|
parameters: tool.parameters,
|
||||||
|
|||||||
+2
-2
@@ -4,9 +4,9 @@ import {
|
|||||||
type Api,
|
type Api,
|
||||||
type AssistantMessage,
|
type AssistantMessage,
|
||||||
type AssistantMessageEventStream,
|
type AssistantMessageEventStream,
|
||||||
type Context,
|
|
||||||
type Model,
|
type Model,
|
||||||
type SimpleStreamOptions,
|
type SimpleStreamOptions,
|
||||||
|
type TranscriptContext,
|
||||||
calculateCost,
|
calculateCost,
|
||||||
createAssistantMessageEventStream,
|
createAssistantMessageEventStream,
|
||||||
} from "@earendil-works/pi-ai";
|
} from "@earendil-works/pi-ai";
|
||||||
@@ -402,7 +402,7 @@ async function* streamChatEvents(args: {
|
|||||||
|
|
||||||
export function streamDevin(
|
export function streamDevin(
|
||||||
model: Model<Api>,
|
model: Model<Api>,
|
||||||
context: Context,
|
context: TranscriptContext,
|
||||||
options?: SimpleStreamOptions,
|
options?: SimpleStreamOptions,
|
||||||
): AssistantMessageEventStream {
|
): AssistantMessageEventStream {
|
||||||
const stream = createAssistantMessageEventStream();
|
const stream = createAssistantMessageEventStream();
|
||||||
|
|||||||
Reference in New Issue
Block a user