1- import type { KartonContract , ChatMessage } from '@stagewise/karton-contract' ;
2- import type { KartonServer } from '@stagewise/karton/server' ;
1+ import type { ChatMessage } from '@stagewise/karton-contract' ;
32import type { ToolCallProcessingResult } from './tool-call-utils.js' ;
43import type { InferUIMessageChunk , ToolUIPart } from 'ai' ;
4+ import type { AgentCallbacks } from '../types/agent-callbacks.js' ;
55
66/**
77 * Checks if a message with the given ID exists in the active chat
8- * @param karton - The Karton server instance containing chat state
8+ * @param callbacks - The agent callbacks for state access
99 * @param messageId - The unique identifier of the message to check
1010 * @returns True if the message exists in the active chat, false otherwise
1111 */
12- function messageExists (
13- karton : KartonServer < KartonContract > ,
14- messageId : string ,
15- ) : boolean {
16- return karton . state . chats [ karton . state . activeChatId ! ] ! . messages . some (
17- ( m ) => m . id === messageId ,
12+ function messageExists ( callbacks : AgentCallbacks , messageId : string ) : boolean {
13+ const state = callbacks . getState ( ) ;
14+ return state . chats [ state . activeChatId ! ] ! . messages . some (
15+ ( m : ChatMessage ) => m . id === messageId ,
1816 ) ;
1917}
2018
2119/**
2220 * Creates a new chat with a timestamped title and sets it as the active chat
23- * @param karton - The Karton server instance to modify
21+ * @param callbacks - The agent callbacks for state modification
2422 * @returns The unique ID of the newly created chat
2523 */
26- export function createAndActivateNewChat ( karton : KartonServer < KartonContract > ) {
24+ export function createAndActivateNewChat ( callbacks : AgentCallbacks ) {
2725 const chatId = crypto . randomUUID ( ) ;
2826 const title = `New Chat - ${ new Date ( ) . toLocaleString ( 'en-US' , {
2927 month : 'short' ,
@@ -32,7 +30,7 @@ export function createAndActivateNewChat(karton: KartonServer<KartonContract>) {
3230 minute : '2-digit' ,
3331 hour12 : true ,
3432 } ) } `;
35- karton . setState ( ( draft ) => {
33+ callbacks . setState ( ( draft ) => {
3634 draft . chats [ chatId ] = {
3735 title,
3836 createdAt : new Date ( ) ,
@@ -46,21 +44,22 @@ export function createAndActivateNewChat(karton: KartonServer<KartonContract>) {
4644/**
4745 * Appends text content to a message, creating the message if it doesn't exist
4846 * or creating/appending to a text part at the specified index
49- * @param karton - The Karton server instance to modify
47+ * @param callbacks - The agent callbacks for state modification
5048 * @param messageId - The unique identifier of the message to append to
5149 * @param delta - The text content to append
5250 * @param partIndex - The index of the message part to append to
5351 */
5452export function appendTextDeltaToMessage (
55- karton : KartonServer < KartonContract > ,
53+ callbacks : AgentCallbacks ,
5654 messageId : string ,
5755 delta : string ,
5856 partIndex : number ,
5957) {
6058 // If the message doesn't exist, create it
61- if ( ! messageExists ( karton , messageId ) ) {
62- karton . setState ( ( draft ) => {
63- draft . chats [ karton . state . activeChatId ! ] ! . messages . push ( {
59+ if ( ! messageExists ( callbacks , messageId ) ) {
60+ callbacks . setState ( ( draft ) => {
61+ const state = callbacks . getState ( ) ;
62+ draft . chats [ state . activeChatId ! ] ! . messages . push ( {
6463 role : 'assistant' ,
6564 id : messageId ,
6665 parts : [ { type : 'text' , text : delta } ] ,
@@ -71,9 +70,10 @@ export function appendTextDeltaToMessage(
7170 } ) ;
7271 } else {
7372 // If the message exists, create a text part or append to the existing one
74- karton . setState ( ( draft ) => {
75- const message = draft . chats [ karton . state . activeChatId ! ] ! . messages . find (
76- ( m ) => m . id === messageId ,
73+ callbacks . setState ( ( draft ) => {
74+ const state = callbacks . getState ( ) ;
75+ const message = draft . chats [ state . activeChatId ! ] ! . messages . find (
76+ ( m : ChatMessage ) => m . id === messageId ,
7777 ) ! ;
7878
7979 // Create a new part if it's a new one
@@ -96,28 +96,29 @@ export function appendTextDeltaToMessage(
9696/**
9797 * Appends tool input information to a message, creating the message if it doesn't exist
9898 * or updating the tool part at the specified index
99- * @param karton - The Karton server instance to modify
99+ * @param callbacks - The agent callbacks for state modification
100100 * @param messageId - The unique identifier of the message to append to
101101 * @param chunk - The tool input chunk containing tool call details
102102 * @param partIndex - The index of the message part to update
103103 */
104104export function appendToolInputToMessage (
105- karton : KartonServer < KartonContract > ,
105+ callbacks : AgentCallbacks ,
106106 messageId : string ,
107107 chunk : Extract <
108108 InferUIMessageChunk < ChatMessage > ,
109109 { type : 'tool-input-available' }
110110 > ,
111111 partIndex : number ,
112112) {
113- karton . setState ( ( draft ) => {
114- const message = draft . chats [ karton . state . activeChatId ! ] ! . messages . find (
115- ( m ) => m . id === messageId ,
113+ callbacks . setState ( ( draft ) => {
114+ const state = callbacks . getState ( ) ;
115+ const message = draft . chats [ state . activeChatId ! ] ! . messages . find (
116+ ( m : ChatMessage ) => m . id === messageId ,
116117 ) ;
117118
118119 if ( ! message ) {
119120 // If the message doesn't exist, create it
120- draft . chats [ karton . state . activeChatId ! ] ! . messages . push ( {
121+ draft . chats [ state . activeChatId ! ] ! . messages . push ( {
121122 role : 'assistant' ,
122123 id : messageId ,
123124 parts : [
@@ -159,23 +160,24 @@ export function appendToolInputToMessage(
159160/**
160161 * Attaches tool execution results to the corresponding tool parts in a message
161162 * Updates the tool part state to reflect success or error outcomes
162- * @param karton - The Karton server instance to modify
163+ * @param callbacks - The agent callbacks for state modification
163164 * @param toolResults - Array of tool execution results to attach
164165 * @param messageId - The unique identifier of the message containing the tool parts
165166 */
166167export function attachToolOutputToMessage (
167- karton : KartonServer < KartonContract > ,
168+ callbacks : AgentCallbacks ,
168169 toolResults : ToolCallProcessingResult [ ] ,
169170 messageId : string ,
170171) {
171- karton . setState ( ( draft ) => {
172- const message = draft . chats [ karton . state . activeChatId ! ] ! . messages . find (
173- ( m ) => m . id === messageId ,
172+ callbacks . setState ( ( draft ) => {
173+ const state = callbacks . getState ( ) ;
174+ const message = draft . chats [ state . activeChatId ! ] ! . messages . find (
175+ ( m : ChatMessage ) => m . id === messageId ,
174176 ) ;
175177 if ( ! message ) return ;
176178 for ( const result of toolResults ) {
177179 const part = message . parts . find (
178- ( p ) => 'toolCallId' in p && p . toolCallId === result . toolCallId ,
180+ ( p : any ) => 'toolCallId' in p && p . toolCallId === result . toolCallId ,
179181 ) ;
180182 if ( ! part ) continue ;
181183 if ( part . type !== 'dynamic-tool' && ! part . type . startsWith ( 'tool-' ) )
@@ -196,14 +198,16 @@ export function attachToolOutputToMessage(
196198
197199/**
198200 * Finds tool calls in the last assistant message that don't have corresponding results
201+ * @param callbacks - The agent callbacks for state access
199202 * @param chatId - The chat ID to check
200203 * @returns Array of pending tool call IDs and their names
201204 */
202205export function findPendingToolCalls (
203- karton : KartonServer < KartonContract > ,
206+ callbacks : AgentCallbacks ,
204207 chatId : string ,
205208) : Array < { toolCallId : string } > {
206- const chat = karton . state . chats [ chatId ] ;
209+ const state = callbacks . getState ( ) ;
210+ const chat = state . chats [ chatId ] ;
207211 if ( ! chat ) return [ ] ;
208212
209213 const messages = chat . messages ;
0 commit comments