code-program.client.spec.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /** Recorded PTC argument validation and historical language selection. */
  2. import { describe, expect, it } from 'vitest'
  3. import { codeProgram } from '../src/client/code-program.ts'
  4. import type { TrajectoryCellProps } from '../src/client/trajectory-record.ts'
  5. const CELL: TrajectoryCellProps = {
  6. index: 1, kind: 'tool', text: 'run_code · {}', timeSeconds: 1,
  7. inputDetail: JSON.stringify({ code: 'return 42\n', description: 'Compute the answer' }),
  8. }
  9. describe('recorded code programs', () => {
  10. it('keeps the program and arguments verbatim', () => {
  11. expect(codeProgram(CELL)).toEqual({
  12. source: 'return 42\n', description: 'Compute the answer',
  13. arguments: { code: 'return 42\n', description: 'Compute the answer' }, language: undefined,
  14. })
  15. })
  16. it.each([
  17. ['The program: the body of an async TypeScript function.', 'typescript'],
  18. ['The program: the body of an async Python function.', 'python'],
  19. ['A TypeScript or Python program.', undefined],
  20. ['An executable program.', undefined],
  21. ])('uses the recorded parameter description %s', (description, language) => {
  22. const schemaDetail = JSON.stringify({ parameters: { properties: { code: { description } } } })
  23. expect(codeProgram({ ...CELL, schemaDetail })?.language).toBe(language)
  24. })
  25. it.each([undefined, '{', '{}', 'null', '[]'])('keeps missing or unusable schemas plain: %s', (schemaDetail) => {
  26. expect(codeProgram({ ...CELL, ...(schemaDetail === undefined ? {} : { schemaDetail }) })?.language).toBeUndefined()
  27. })
  28. it('uses the first nonempty source line when a description is unavailable', () => {
  29. const source = '\n const x = 1\nreturn x\n'
  30. for (const description of [undefined, '', ' ']) {
  31. expect(codeProgram({ ...CELL, inputDetail: JSON.stringify({ code: source, description }) }))
  32. .toMatchObject({ source, description: 'const x = 1' })
  33. }
  34. })
  35. it('retains empty source and unknown argument fields for JSON inspection', () => {
  36. expect(codeProgram({ ...CELL, inputDetail: '{"code":"","extra":true}' }))
  37. .toMatchObject({ source: '', description: '', arguments: { code: '', extra: true } })
  38. })
  39. it.each([undefined, '{', '[]', 'null', '42', '{}', '{"code":42}', '{"code":"x","description":[]}' ])(
  40. 'declines incomplete or unsupported arguments: %s', (inputDetail) => {
  41. const cell = { ...CELL }
  42. if (inputDetail === undefined) delete cell.inputDetail
  43. else cell.inputDetail = inputDetail
  44. expect(codeProgram(cell)).toBeUndefined()
  45. },
  46. )
  47. it('does not specialize other tools or non-tool records', () => {
  48. expect(codeProgram({ ...CELL, kind: 'message' })).toBeUndefined()
  49. expect(codeProgram({ ...CELL, text: 'run_code_extra · {}' })).toBeUndefined()
  50. expect(codeProgram({ ...CELL, kind: 'subtool' })?.source).toBe('return 42\n')
  51. })
  52. })