generated from nhcarrigan/template
feat: initial prototype
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 47s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 47s
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import type { CharacterState } from "$lib/types/states";
|
||||
import type { ClaudeStreamMessage, ToolUseContentBlock } from "$lib/types/messages";
|
||||
|
||||
const SEARCH_TOOLS = ["Read", "Glob", "Grep", "WebSearch", "WebFetch"];
|
||||
const CODING_TOOLS = ["Edit", "Write", "NotebookEdit"];
|
||||
|
||||
function getToolCategory(toolName: string): CharacterState {
|
||||
if (SEARCH_TOOLS.includes(toolName)) {
|
||||
return "searching";
|
||||
}
|
||||
|
||||
if (CODING_TOOLS.includes(toolName)) {
|
||||
return "coding";
|
||||
}
|
||||
|
||||
if (toolName.startsWith("mcp__")) {
|
||||
return "mcp";
|
||||
}
|
||||
|
||||
if (toolName === "Task") {
|
||||
return "thinking";
|
||||
}
|
||||
|
||||
return "typing";
|
||||
}
|
||||
|
||||
export function mapMessageToState(message: ClaudeStreamMessage): CharacterState | null {
|
||||
switch (message.type) {
|
||||
case "system":
|
||||
if (message.subtype === "init") {
|
||||
return "idle";
|
||||
}
|
||||
return null;
|
||||
|
||||
case "assistant": {
|
||||
const toolUses = message.message.content.filter(
|
||||
(block): block is ToolUseContentBlock => block.type === "tool_use"
|
||||
);
|
||||
|
||||
if (toolUses.length > 0) {
|
||||
const lastTool = toolUses[toolUses.length - 1];
|
||||
return getToolCategory(lastTool.name);
|
||||
}
|
||||
|
||||
const hasText = message.message.content.some((block) => block.type === "text");
|
||||
if (hasText) {
|
||||
return "typing";
|
||||
}
|
||||
|
||||
const hasThinking = message.message.content.some((block) => block.type === "thinking");
|
||||
if (hasThinking) {
|
||||
return "thinking";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
case "stream_event": {
|
||||
const event = message.event;
|
||||
|
||||
if (event.type === "content_block_start") {
|
||||
if (event.content_block?.type === "thinking") {
|
||||
return "thinking";
|
||||
}
|
||||
if (event.content_block?.type === "text") {
|
||||
return "typing";
|
||||
}
|
||||
if (event.content_block?.type === "tool_use") {
|
||||
const toolBlock = event.content_block as ToolUseContentBlock;
|
||||
return getToolCategory(toolBlock.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type === "content_block_delta") {
|
||||
if (event.delta?.type === "thinking_delta") {
|
||||
return "thinking";
|
||||
}
|
||||
if (event.delta?.type === "text_delta") {
|
||||
return "typing";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
case "result":
|
||||
if (message.subtype === "success") {
|
||||
return "success";
|
||||
}
|
||||
if (message.subtype.startsWith("error")) {
|
||||
return "error";
|
||||
}
|
||||
return null;
|
||||
|
||||
case "user":
|
||||
return null;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function extractTextFromMessage(message: ClaudeStreamMessage): string | null {
|
||||
if (message.type === "assistant") {
|
||||
const textBlocks = message.message.content
|
||||
.filter((block) => block.type === "text")
|
||||
.map((block) => (block as { type: "text"; text: string }).text);
|
||||
|
||||
return textBlocks.length > 0 ? textBlocks.join("\n") : null;
|
||||
}
|
||||
|
||||
if (message.type === "stream_event" && message.event.delta?.text) {
|
||||
return message.event.delta.text;
|
||||
}
|
||||
|
||||
if (message.type === "result" && message.result) {
|
||||
return message.result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function extractToolInfo(
|
||||
message: ClaudeStreamMessage
|
||||
): { name: string; input: Record<string, unknown> }[] {
|
||||
if (message.type !== "assistant") {
|
||||
return [];
|
||||
}
|
||||
|
||||
return message.message.content
|
||||
.filter((block): block is ToolUseContentBlock => block.type === "tool_use")
|
||||
.map((block) => ({
|
||||
name: block.name,
|
||||
input: block.input,
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user