Class: Pikuri::Tasks::Create

Inherits:
Pikuri::Tool
  • Object
show all
Defined in:
lib/pikuri/tasks/create.rb

Overview

The task_create tool: mass-create pending items in a single call from a JSON array of strings — a native items array parameter, the shape every mainstream harness’s task tool uses and therefore the shape the model’s training prior produces unprompted. (An earlier newline-separated-string design tried to spare small models the bracket-balancing; in practice models sent JSON arrays anyway — the prior beats the parameter description — and the splitter turned ‘[`, `“foo”,`, `]` into garbage tasks. Match the prior instead of fighting it.)

Each element is whitespace-stripped; a blank element aborts the call (it is always an LLM mistake, never intent). If any input is a duplicate (within the batch, or already in the list), the whole call likewise aborts with an “Error: …” string and nothing is added — the LLM resends a corrected batch on the next turn. Atomic semantics keep the list in a coherent state the LLM doesn’t have to reconcile.

On success returns the rendered current list via List#render —including each new item’s #id, which the three mutation tools address items by — so the LLM always sees fresh state without a separate read tool.

Constant Summary collapse

DESCRIPTION =

Returns static description shown to the LLM, opencode-shape (summary + Usage: bullets).

Returns:

  • (String)

    static description shown to the LLM, opencode-shape (summary + Usage: bullets).

<<~DESC
  Create one or more new task items in a single call. All items start as `pending`.

  Usage:
  - Use at the start of a multi-step task to capture the plan.
  - `items` is a JSON array of strings — one task per element.
  - A blank element, a duplicate (within the batch or already on the list), or an empty array aborts the whole call with `Error: ...` and adds nothing — resend a corrected batch.
  - On success the full current list is returned, with each task's `#id` — use that id with `task_in_progress` / `task_completed` / `task_delete`.
DESC

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(list:) ⇒ Create

Parameters:

  • list (List)

    the shared per-Agent list, captured by closure so every tool in the Extension‘s set mutates the same instance.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/pikuri/tasks/create.rb', line 44

def initialize(list:)
  super(
    name: 'task_create',
    description: DESCRIPTION,
    parameters: Pikuri::Tool::Parameters.build { |p|
      p.required_string_array :items,
                              'Task contents, one task per array element, e.g. ' \
                              '["Add dark mode toggle", "Write unit tests", "Update README"].'
    },
    execute: lambda { |items:|
      Create.execute(list: list, items: items)
    }
  )
end

Class Method Details

.execute(list:, items:) ⇒ String

Validate and apply the batch. Public so specs can drive it without constructing a tool instance.

Parameters:

  • list (List)
  • items (Array<String>)

    raw items argument from the LLM (already type-validated by Pikuri::Tool::Parameters).

Returns:

  • (String)

    either List#render on success or an “Error: …” string the LLM can react to.



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/pikuri/tasks/create.rb', line 67

def self.execute(list:, items:)
  return 'Error: task_create requires at least one item' if items.empty?

  cleaned = items.map(&:strip)
  blank = cleaned.index('')
  return "Error: blank item at index #{blank} — every element must be non-blank task text" if blank

  seen_in_batch = {}
  cleaned.each do |c|
    return "Error: duplicate item in batch: '#{c}'" if seen_in_batch[c]

    seen_in_batch[c] = true
  end

  existing = list.items.map(&:content)
  clash = cleaned.find { |c| existing.include?(c) }
  return "Error: task already exists: '#{clash}'" if clash

  cleaned.each { |c| list.add(c) }
  list.render
end