All files / src/llm-orchestration/action-handlers new-session.handler.ts

95.23% Statements 20/21
57.14% Branches 4/7
83.33% Functions 5/6
94.73% Lines 18/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 997x           7x 7x 7x 7x     7x 8x                                                       2x           2x                 2x                         2x       3x 3x 3x 1x 1x   1x                     2x                
import { Injectable } from '@nestjs/common';
import { ActionHandler } from './action-handler.interface';
import {
  ActionExecutionResult,
  ToolMetadata,
} from '../llm-orchestration.interfaces';
import { NewSessionArgsDto } from './dto/new-session.args.dto';
import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator';
import { generateToolCall, generateToolCallJson } from '../../utils';
 
@Injectable()
export class NewSessionHandler implements ActionHandler {
  readonly toolName = 'new_session';
 
  getMetadata(): ToolMetadata {
    return {
      name: this.toolName,
      description: this.getDefinition(true),
      arguments: [
        {
          name: 'handover_string',
          type: 'string',
          description:
            'A clear instruction or prompt for the new session to execute.',
          required: true,
        },
      ],
    };
  }
 
  /**
   * Generates a tool call example in the specified format.
   * @param toolCall - The tool call object to format
   * @param useJson - If true, uses JSON format; otherwise uses XML-style format
   * @returns Formatted tool call string
   */
  private generateExample(
    toolCall: Record<string, any>,
    useJson: boolean = false,
  ): string {
    return useJson
      ? generateToolCallJson(toolCall)
      : generateToolCall(toolCall);
  }
 
  getDefinition(useJsonFormat: boolean = false): string {
    const example = this.generateExample(
      {
        tool_name: this.toolName,
        handover_string:
          'The component has been created. Now, create a new set of unit tests for the component located at `src/components/NewComponent.tsx`. Ensure all props are tested.',
      },
      useJsonFormat,
    );
 
    const definition = `
::<${this.toolName}>
  Used to break down a complex task into a smaller, separate task. It halts the current plan and creates a new session with the provided instructions.
 
  Parameters:
  - "handover_string": (string) A clear instruction or prompt for the new session to execute.
 
  <example>
    Explanation: After completing a large refactor, this creates a follow-up task to add documentation.
:${example}
  </example>
::</${this.toolName}>
`;
    return definition.trim();
  }
 
  async execute(args: { [key: string]: any }): Promise<ActionExecutionResult> {
    const validatedArgs = plainToClass(NewSessionArgsDto, args);
    const errors = await validate(validatedArgs);
    if (errors.length > 0) {
      const errorMessages = errors
        .map((err) => Object.values(err.constraints || {}).join(', '))
        .join('; ');
      return {
        status: 'FAILURE',
        summary: `Invalid arguments for ${this.toolName}.`,
        error_message: errorMessages,
        persisted_args: args,
        execution_log: { output: '', error_message: errorMessages },
      };
    }
 
    // Session handover will be handled separately
    // Just return success with empty execution_log
    return {
      status: 'SUCCESS',
      summary: `Session handover prepared: ${validatedArgs.handover_string}`,
      persisted_args: validatedArgs,
      execution_log: { output: 'New session prepared.', error_message: '' },
    };
  }
}