Class: SignalWire::Contexts::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/signalwire/contexts/context_builder.rb

Overview

Represents a single context containing multiple steps.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Context

Returns a new instance of Context.



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/signalwire/contexts/context_builder.rb', line 345

def initialize(name)
  @name = name
  @steps      = {}   # name => Step
  @step_order = []

  # Navigation
  @valid_contexts = nil
  @valid_steps    = nil
  @initial_step   = nil

  # Context entry parameters
  @post_prompt     = nil
  @system_prompt   = nil
  @system_prompt_sections = []
  @consolidate     = false
  @full_reset      = false
  @user_prompt     = nil
  @isolated        = false

  # Context prompt
  @prompt_text     = nil
  @prompt_sections = []

  # Fillers
  @enter_fillers = nil
  @exit_fillers  = nil
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



343
344
345
# File 'lib/signalwire/contexts/context_builder.rb', line 343

def name
  @name
end

Instance Method Details

#_initial_stepObject



601
# File 'lib/signalwire/contexts/context_builder.rb', line 601

def _initial_step; @initial_step; end

#_step_orderObject



600
# File 'lib/signalwire/contexts/context_builder.rb', line 600

def _step_order;   @step_order;   end

#_stepsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Expose internal state for validation



599
# File 'lib/signalwire/contexts/context_builder.rb', line 599

def _steps;        @steps;        end

#add_bullets(title, bullets) ⇒ Object

Add a POM section with bullets to the context prompt.

Raises:

  • (ArgumentError)


516
517
518
519
520
521
# File 'lib/signalwire/contexts/context_builder.rb', line 516

def add_bullets(title, bullets)
  raise ArgumentError, "Cannot add POM sections when set_prompt has been used" unless @prompt_text.nil?

  @prompt_sections << { "title" => title, "bullets" => bullets }
  self
end

#add_enter_filler(lang_code, fillers) ⇒ Object



549
550
551
552
553
554
555
# File 'lib/signalwire/contexts/context_builder.rb', line 549

def add_enter_filler(lang_code, fillers)
  if lang_code && fillers.is_a?(Array) && fillers.any?
    @enter_fillers ||= {}
    @enter_fillers[lang_code] = fillers
  end
  self
end

#add_exit_filler(lang_code, fillers) ⇒ Object



557
558
559
560
561
562
563
# File 'lib/signalwire/contexts/context_builder.rb', line 557

def add_exit_filler(lang_code, fillers)
  if lang_code && fillers.is_a?(Array) && fillers.any?
    @exit_fillers ||= {}
    @exit_fillers[lang_code] = fillers
  end
  self
end

#add_section(title, body) ⇒ Object

Add a POM section to the context prompt.

Raises:

  • (ArgumentError)


508
509
510
511
512
513
# File 'lib/signalwire/contexts/context_builder.rb', line 508

def add_section(title, body)
  raise ArgumentError, "Cannot add POM sections when set_prompt has been used" unless @prompt_text.nil?

  @prompt_sections << { "title" => title, "body" => body }
  self
end

#add_step(name, task: nil, bullets: nil, criteria: nil, functions: nil, valid_steps: nil) ⇒ Object

Add a new step. Returns the new Step object (not self).

Python parity: “Context.add_step(name, *, task=None, bullets=None, criteria=None, functions=None, valid_steps=None)“. The optional keyword arguments give a one-call configuration shortcut:

ctx.add_step("greet",
  task: "Greet the caller",
  bullets: ["Say hi", "Ask how can I help"],
  criteria: "User has been greeted",
  functions: ["weather"],
  valid_steps: ["help"])

Without the optional args this stays the bare “add_step(“greet”)“ form that returns a Step for further fluent configuration.

Raises:

  • (ArgumentError)


388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/signalwire/contexts/context_builder.rb', line 388

def add_step(name, task: nil, bullets: nil, criteria: nil,
             functions: nil, valid_steps: nil)
  raise ArgumentError, "Step '#{name}' already exists in context '#{@name}'" if @steps.key?(name)
  raise ArgumentError, "Maximum steps per context (#{MAX_STEPS_PER_CONTEXT}) exceeded" if @steps.size >= MAX_STEPS_PER_CONTEXT

  step = Step.new(name)
  @steps[name] = step
  @step_order << name

  step.add_section('Task', task)        unless task.nil?
  step.add_bullets('Process', bullets)  unless bullets.nil?
  step.set_step_criteria(criteria)      unless criteria.nil?
  step.set_functions(functions)         unless functions.nil?
  step.set_valid_steps(valid_steps)     unless valid_steps.nil?

  step
end

#add_system_bullets(title, bullets) ⇒ Object

Add a POM section with bullets to the system prompt.

Raises:

  • (ArgumentError)


532
533
534
535
536
537
# File 'lib/signalwire/contexts/context_builder.rb', line 532

def add_system_bullets(title, bullets)
  raise ArgumentError, "Cannot add POM system sections when set_system_prompt has been used" unless @system_prompt.nil?

  @system_prompt_sections << { "title" => title, "bullets" => bullets }
  self
end

#add_system_section(title, body) ⇒ Object

Add a POM section to the system prompt.

Raises:

  • (ArgumentError)


524
525
526
527
528
529
# File 'lib/signalwire/contexts/context_builder.rb', line 524

def add_system_section(title, body)
  raise ArgumentError, "Cannot add POM system sections when set_system_prompt has been used" unless @system_prompt.nil?

  @system_prompt_sections << { "title" => title, "body" => body }
  self
end

#get_step(name) ⇒ Object

Get an existing step by name. Returns Step or nil.



407
408
409
# File 'lib/signalwire/contexts/context_builder.rb', line 407

def get_step(name)
  @steps[name]
end

#move_step(name, position) ⇒ Object

Move an existing step to a specific position. Returns self.

Raises:

  • (ArgumentError)


421
422
423
424
425
426
427
# File 'lib/signalwire/contexts/context_builder.rb', line 421

def move_step(name, position)
  raise ArgumentError, "Step '#{name}' not found in context '#{@name}'" unless @steps.key?(name)

  @step_order.delete(name)
  @step_order.insert(position, name)
  self
end

#remove_step(name) ⇒ Object

Remove a step by name. Returns self.



412
413
414
415
416
417
418
# File 'lib/signalwire/contexts/context_builder.rb', line 412

def remove_step(name)
  if @steps.key?(name)
    @steps.delete(name)
    @step_order.delete(name)
  end
  self
end

#set_consolidate(val) ⇒ Object



469
470
471
472
# File 'lib/signalwire/contexts/context_builder.rb', line 469

def set_consolidate(val)
  @consolidate = val
  self
end

#set_enter_fillers(fillers) ⇒ Object



539
540
541
542
# File 'lib/signalwire/contexts/context_builder.rb', line 539

def set_enter_fillers(fillers)
  @enter_fillers = fillers if fillers.is_a?(Hash) && fillers.any?
  self
end

#set_exit_fillers(fillers) ⇒ Object



544
545
546
547
# File 'lib/signalwire/contexts/context_builder.rb', line 544

def set_exit_fillers(fillers)
  @exit_fillers = fillers if fillers.is_a?(Hash) && fillers.any?
  self
end

#set_full_reset(val) ⇒ Object



474
475
476
477
# File 'lib/signalwire/contexts/context_builder.rb', line 474

def set_full_reset(val)
  @full_reset = val
  self
end

#set_initial_step(step_name) ⇒ Object

Set which step the context starts on when entered.

By default, a context starts on its first step (index 0). Use this to skip a preamble step on re-entry via change_context.

Parameters:

  • step_name (String)

    name of the step to start on.



435
436
437
438
# File 'lib/signalwire/contexts/context_builder.rb', line 435

def set_initial_step(step_name)
  @initial_step = step_name
  self
end

#set_isolated(val) ⇒ Object

Mark this context as isolated — entering it wipes conversation history.

When val = true and the context is entered via change_context, the runtime wipes the conversation array. The model starts fresh with only the new context’s system_prompt + step instructions, with no memory of prior turns.

EXCEPTION — reset overrides the wipe:

If the context also has a reset configuration (via
+set_consolidate+ or +set_full_reset+), the wipe is skipped in
favor of the reset behavior. Use reset with consolidate=true
to summarize prior history into a single message instead of
dropping it entirely.

Use cases: switching to a sensitive billing flow that should not see prior small-talk; handing off to a different agent persona; resetting after a long off-topic detour.



502
503
504
505
# File 'lib/signalwire/contexts/context_builder.rb', line 502

def set_isolated(val)
  @isolated = val
  self
end

#set_post_prompt(prompt) ⇒ Object



450
451
452
453
# File 'lib/signalwire/contexts/context_builder.rb', line 450

def set_post_prompt(prompt)
  @post_prompt = prompt
  self
end

#set_prompt(prompt) ⇒ Object

Raises:

  • (ArgumentError)


462
463
464
465
466
467
# File 'lib/signalwire/contexts/context_builder.rb', line 462

def set_prompt(prompt)
  raise ArgumentError, "Cannot use set_prompt when POM prompt sections exist" if @prompt_sections.any?

  @prompt_text = prompt
  self
end

#set_system_prompt(prompt) ⇒ Object

Raises:

  • (ArgumentError)


455
456
457
458
459
460
# File 'lib/signalwire/contexts/context_builder.rb', line 455

def set_system_prompt(prompt)
  raise ArgumentError, "Cannot use set_system_prompt when POM system sections exist" if @system_prompt_sections.any?

  @system_prompt = prompt
  self
end

#set_user_prompt(prompt) ⇒ Object



479
480
481
482
# File 'lib/signalwire/contexts/context_builder.rb', line 479

def set_user_prompt(prompt)
  @user_prompt = prompt
  self
end

#set_valid_contexts(contexts) ⇒ Object



440
441
442
443
# File 'lib/signalwire/contexts/context_builder.rb', line 440

def set_valid_contexts(contexts)
  @valid_contexts = contexts
  self
end

#set_valid_steps(steps) ⇒ Object



445
446
447
448
# File 'lib/signalwire/contexts/context_builder.rb', line 445

def set_valid_steps(steps)
  @valid_steps = steps
  self
end

#to_hObject

Raises:

  • (ArgumentError)


565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# File 'lib/signalwire/contexts/context_builder.rb', line 565

def to_h
  raise ArgumentError, "Context '#{@name}' has no steps defined" if @steps.empty?

  ctx = {
    "steps" => @step_order.map { |n| @steps[n].to_h }
  }

  ctx["valid_contexts"] = @valid_contexts if @valid_contexts
  ctx["valid_steps"]    = @valid_steps    if @valid_steps
  ctx["initial_step"]   = @initial_step   if @initial_step
  ctx["post_prompt"]    = @post_prompt    if @post_prompt

  sys = render_system_prompt
  ctx["system_prompt"] = sys if sys

  ctx["consolidate"]  = @consolidate  if @consolidate
  ctx["full_reset"]   = @full_reset   if @full_reset
  ctx["user_prompt"]  = @user_prompt  if @user_prompt
  ctx["isolated"]     = @isolated     if @isolated

  if @prompt_sections.any?
    ctx["pom"] = @prompt_sections
  elsif @prompt_text
    ctx["prompt"] = @prompt_text
  end

  ctx["enter_fillers"] = @enter_fillers if @enter_fillers
  ctx["exit_fillers"]  = @exit_fillers  if @exit_fillers

  ctx
end