All files / kernel-agents/src/strategies/json prepare-attempt.ts

87.5% Statements 14/16
60% Branches 3/5
100% Functions 2/2
87.5% Lines 14/16

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                                          1x                           4x   4x   4x       4x         4x     2x 2x 2x     2x 2x             4x 4x   4x                      
import { mergeDisjointRecords } from '@metamask/kernel-utils';
import type { Logger } from '@metamask/logger';
 
import { makeEvaluator } from './evaluator.ts';
import { CapabilitySpecMessage, UserMessage } from './messages.ts';
import type { State, Action, Observation } from './messages.ts';
import { makePrinter } from './printer.ts';
import { makePrompter } from './prompter.ts';
import { makeReader } from './reader.ts';
import { extractCapabilitySchemas } from '../../capabilities/capability.ts';
import { makeEnd } from '../../capabilities/end.ts';
import type {
  CapabilityRecord,
  Context,
  Objective,
  PrepareAttempt,
  PREP,
  Progress,
} from '../../types.ts';
import { ifDefined } from '../../utils.ts';
 
export const prepareAttempt: PrepareAttempt<State, Action, Observation> = <
  Result,
>({
  objective: { intent, judgment },
  context,
  options = {},
}: {
  objective: Objective<Result>;
  context: Context;
  options?: {
    taskLogger?: Logger;
    printLogger?: Logger;
  };
}): [PREP<State, Action, Observation>, Progress<Result, State>] => {
  const { taskLogger, printLogger } = options;
 
  const [end, didEnd, getEnd] = makeEnd();
 
  const capabilities = mergeDisjointRecords(context.capabilities, {
    end,
  }) as CapabilityRecord;
 
  const history = [
    new CapabilitySpecMessage(extractCapabilitySchemas(capabilities)),
    new UserMessage(intent),
  ];
 
  const progress: Progress<Result, State> = {
    history,
    isDone: () => {
      Eif (didEnd()) {
        const result = getEnd();
        Iif (!judgment(result)) {
          throw new Error(`Invalid result: ${result as string}`);
        }
        Object.assign(progress, { result });
        return true;
      }
      return false;
    },
    // result: not defined until judgment is satisfied
  };
 
  const readLogger = taskLogger?.subLogger({ tags: ['read'] });
  const evalLogger = taskLogger?.subLogger({ tags: ['eval'] });
 
  return [
    [
      makePrompter(),
      makeReader(ifDefined({ logger: readLogger })),
      makeEvaluator(ifDefined({ capabilities, logger: evalLogger })),
      makePrinter({ history, ...ifDefined({ logger: printLogger }) }),
      // TODO: Fix these types
    ] as unknown as PREP<State, Action, Observation>,
    progress,
  ];
};