mirror of
https://github.com/harivansh-afk/clanker-agent.git
synced 2026-04-17 07:03:28 +00:00
mime
This commit is contained in:
parent
9115d5647f
commit
e19f575229
2 changed files with 114 additions and 66 deletions
|
|
@ -62,6 +62,7 @@ export type { HistoryPart } from "./types.js";
|
||||||
let activeGatewayRuntime: GatewayRuntime | null = null;
|
let activeGatewayRuntime: GatewayRuntime | null = null;
|
||||||
|
|
||||||
type JsonRecord = Record<string, unknown>;
|
type JsonRecord = Record<string, unknown>;
|
||||||
|
type AssistantAgentMessage = Extract<AgentMessage, { role: "assistant" }>;
|
||||||
|
|
||||||
type CompanionChannelsSettings = JsonRecord & {
|
type CompanionChannelsSettings = JsonRecord & {
|
||||||
adapters?: Record<string, JsonRecord>;
|
adapters?: Record<string, JsonRecord>;
|
||||||
|
|
@ -659,14 +660,15 @@ export class GatewayRuntime {
|
||||||
|
|
||||||
private emitStructuredParts(
|
private emitStructuredParts(
|
||||||
managedSession: ManagedGatewaySession,
|
managedSession: ManagedGatewaySession,
|
||||||
message: AgentMessage,
|
message: AssistantAgentMessage,
|
||||||
): void {
|
): void {
|
||||||
const content = message.content;
|
const content = message.content;
|
||||||
if (!Array.isArray(content)) return;
|
if (!Array.isArray(content)) return;
|
||||||
|
|
||||||
for (const part of content) {
|
for (const part of content) {
|
||||||
if (typeof part !== "object" || part === null) continue;
|
const rawPart: unknown = part;
|
||||||
const p = part as Record<string, unknown>;
|
if (!isRecord(rawPart)) continue;
|
||||||
|
const p = rawPart;
|
||||||
|
|
||||||
if (p.type === "teamActivity") {
|
if (p.type === "teamActivity") {
|
||||||
const teamId = typeof p.teamId === "string" ? p.teamId : "";
|
const teamId = typeof p.teamId === "string" ? p.teamId : "";
|
||||||
|
|
@ -722,7 +724,6 @@ export class GatewayRuntime {
|
||||||
message: errorMessage,
|
message: errorMessage,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,47 @@ export interface GatewayTransientToolResult {
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TeamActivityMember = Extract<
|
||||||
|
HistoryPart,
|
||||||
|
{ type: "teamActivity" }
|
||||||
|
>["members"][number];
|
||||||
|
|
||||||
function isSupportedHistoryRole(
|
function isSupportedHistoryRole(
|
||||||
role: AgentMessage["role"],
|
role: AgentMessage["role"],
|
||||||
): role is "user" | "assistant" | "toolResult" {
|
): role is "user" | "assistant" | "toolResult" {
|
||||||
return role === "user" || role === "assistant" || role === "toolResult";
|
return role === "user" || role === "assistant" || role === "toolResult";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
|
return typeof value === "object" && value !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeTeamActivityMembers(value: unknown): TeamActivityMember[] {
|
||||||
|
if (!Array.isArray(value)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
.filter(isRecord)
|
||||||
|
.map((member) => {
|
||||||
|
const id = typeof member.id === "string" ? member.id : "";
|
||||||
|
if (!id) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
name: typeof member.name === "string" ? member.name : "Teammate",
|
||||||
|
...(typeof member.role === "string" ? { role: member.role } : {}),
|
||||||
|
status: typeof member.status === "string" ? member.status : "running",
|
||||||
|
...(typeof member.message === "string"
|
||||||
|
? { message: member.message }
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter((member): member is TeamActivityMember => member !== null);
|
||||||
|
}
|
||||||
|
|
||||||
function historyMessageId(message: AgentMessage, index: number): string {
|
function historyMessageId(message: AgentMessage, index: number): string {
|
||||||
return `${message.timestamp}-${message.role}-${index}`;
|
return `${message.timestamp}-${message.role}-${index}`;
|
||||||
}
|
}
|
||||||
|
|
@ -53,73 +88,85 @@ export function messageContentToHistoryParts(msg: AgentMessage): HistoryPart[] {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.role === "assistant") {
|
if (msg.role === "assistant") {
|
||||||
const content = msg.content;
|
const content: unknown = msg.content;
|
||||||
if (!Array.isArray(content)) return [];
|
if (!Array.isArray(content)) return [];
|
||||||
const parts: HistoryPart[] = [];
|
const parts: HistoryPart[] = [];
|
||||||
for (const contentPart of content) {
|
for (const contentPart of content) {
|
||||||
if (typeof contentPart !== "object" || contentPart === null) {
|
if (!isRecord(contentPart) || typeof contentPart.type !== "string") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (contentPart.type === "text") {
|
|
||||||
parts.push({
|
switch (contentPart.type) {
|
||||||
type: "text",
|
case "text":
|
||||||
text: (contentPart as { type: "text"; text: string }).text,
|
if (typeof contentPart.text === "string") {
|
||||||
});
|
parts.push({
|
||||||
} else if (contentPart.type === "thinking") {
|
type: "text",
|
||||||
parts.push({
|
text: contentPart.text,
|
||||||
type: "reasoning",
|
});
|
||||||
text: (contentPart as { type: "thinking"; thinking: string })
|
}
|
||||||
.thinking,
|
break;
|
||||||
});
|
case "thinking":
|
||||||
} else if (contentPart.type === "toolCall") {
|
if (typeof contentPart.thinking === "string") {
|
||||||
const toolCall = contentPart as {
|
parts.push({
|
||||||
type: "toolCall";
|
type: "reasoning",
|
||||||
id: string;
|
text: contentPart.thinking,
|
||||||
name: string;
|
});
|
||||||
arguments: unknown;
|
}
|
||||||
};
|
break;
|
||||||
parts.push({
|
case "toolCall":
|
||||||
type: "tool-invocation",
|
if (
|
||||||
toolCallId: toolCall.id,
|
typeof contentPart.id === "string" &&
|
||||||
toolName: toolCall.name,
|
typeof contentPart.name === "string"
|
||||||
args: toolCall.arguments,
|
) {
|
||||||
state: "call",
|
parts.push({
|
||||||
});
|
type: "tool-invocation",
|
||||||
} else if (contentPart.type === "teamActivity") {
|
toolCallId: contentPart.id,
|
||||||
const activity = contentPart as {
|
toolName: contentPart.name,
|
||||||
type: "teamActivity";
|
args: contentPart.arguments,
|
||||||
teamId: string;
|
state: "call",
|
||||||
status: string;
|
});
|
||||||
members?: Array<{ id: string; name: string; role?: string; status: string; message?: string }>;
|
}
|
||||||
};
|
break;
|
||||||
parts.push({
|
case "teamActivity": {
|
||||||
type: "teamActivity",
|
const teamId =
|
||||||
teamId: activity.teamId,
|
typeof contentPart.teamId === "string" ? contentPart.teamId : "";
|
||||||
status: activity.status,
|
if (!teamId) {
|
||||||
members: Array.isArray(activity.members) ? activity.members : [],
|
break;
|
||||||
});
|
}
|
||||||
} else if (contentPart.type === "image") {
|
parts.push({
|
||||||
const image = contentPart as {
|
type: "teamActivity",
|
||||||
type: "image";
|
teamId,
|
||||||
url: string;
|
status:
|
||||||
mimeType?: string;
|
typeof contentPart.status === "string"
|
||||||
};
|
? contentPart.status
|
||||||
parts.push({
|
: "running",
|
||||||
type: "media",
|
members: normalizeTeamActivityMembers(contentPart.members),
|
||||||
url: image.url,
|
});
|
||||||
mimeType: image.mimeType,
|
break;
|
||||||
});
|
}
|
||||||
} else if (contentPart.type === "error") {
|
case "image":
|
||||||
const error = contentPart as {
|
if (typeof contentPart.url === "string") {
|
||||||
type: "error";
|
parts.push({
|
||||||
code?: string;
|
type: "media",
|
||||||
message: string;
|
url: contentPart.url,
|
||||||
};
|
...(typeof contentPart.mimeType === "string"
|
||||||
parts.push({
|
? { mimeType: contentPart.mimeType }
|
||||||
type: "error",
|
: {}),
|
||||||
code: typeof error.code === "string" ? error.code : "unknown",
|
});
|
||||||
message: error.message,
|
}
|
||||||
});
|
break;
|
||||||
|
case "error":
|
||||||
|
if (typeof contentPart.message === "string") {
|
||||||
|
parts.push({
|
||||||
|
type: "error",
|
||||||
|
code:
|
||||||
|
typeof contentPart.code === "string"
|
||||||
|
? contentPart.code
|
||||||
|
: "unknown",
|
||||||
|
message: contentPart.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parts;
|
return parts;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue