ask-coding-providers 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1b9421ae222addaf585ea8b26333306078843d0574a4b71a34cecaa3fc4ff79
4
- data.tar.gz: 8c7d16435c702703f0f661474077389c28d4fc796aafe196bfce4ccd1f7019b2
3
+ metadata.gz: 5af7db1f38c3b4d11a223269116e1b7c83da716a6e5c4ef0120f321a9f566241
4
+ data.tar.gz: af4be91462e45a4b5fc07119976d098b439daae44714cdcfe302902bd4db5f64
5
5
  SHA512:
6
- metadata.gz: 76cbfb82c26608b1d73a44673b09ab6a299a7c604e80566fa8e9555acd4c2443239d28fafafdee6e29589aa9062cef5e4c4bab465bdb103e41db66560e91b2fe
7
- data.tar.gz: 4a704264075d1c25ce32bf4ae73106050c3ffd7aa52f34ed042f8e98c4132d0f150aca5fe88af3114ca4d0b8c066a83c9f545b44ca267b6abf34d7e802f5c829
6
+ metadata.gz: 06be52e4d472be0c6456842884cb3ccdeb07da10322683de138de6a638cb14e8ba198c5649f57eca1e17e142e752382234bdba8e971cacf664c96f49e821d3fb
7
+ data.tar.gz: 81beeba55e7d5b6cdd197d615f0f3926bf44ee36a87a781aba9197fe301e22ac7e7e72520fa6635f239fe266a9b13cdedc33450653ff47b8a1d3afcaa6d89215
@@ -64,7 +64,7 @@ module Ask
64
64
  @client&.running? || false
65
65
  end
66
66
 
67
- def create_session(workspace_path, mode: nil)
67
+ def create_session(workspace_path, mode: nil, system_prompt: nil, **)
68
68
  ensure_running
69
69
  params = { cwd: workspace_path || @cwd }
70
70
  session = @client.session_new(**params)
@@ -14,7 +14,7 @@ module Ask
14
14
  # @param workspace_path [String] the working directory
15
15
  # @param mode [String, nil] permission mode
16
16
  # @return [String] the session ID
17
- def create_session(workspace_path, mode: nil)
17
+ def create_session(workspace_path, mode: nil, system_prompt: nil, **)
18
18
  raise NotImplementedError, "#{self.class} must implement #create_session"
19
19
  end
20
20
 
@@ -147,7 +147,15 @@ module Ask
147
147
  # @param workspace_path [String] working directory
148
148
  # @param mode [String, nil] permission mode
149
149
  # @param model [String, nil] model override for this session
150
- def create_session(workspace_path, mode: nil, model: nil)
150
+ # @param system_prompt [String, nil] system prompt override for this
151
+ # session (takes precedence over any system_prompt in session_opts)
152
+ # @param agent [String, nil] declarative agent name (ask-agent
153
+ # convention: agents/<name>/agent.rb + instructions.md, discovered
154
+ # from the workspace's working directory). When given, the session
155
+ # is built via Ask::Agent.new so the definition's tools, skills,
156
+ # and instructions apply; the harness-level options (model,
157
+ # system_prompt, approval, plan mode, todos) still win.
158
+ def create_session(workspace_path, mode: nil, model: nil, system_prompt: nil, agent: nil)
151
159
  ensure_started
152
160
  sid = "sess_#{SecureRandom.uuid}"
153
161
  @mutex.synchronize do
@@ -155,6 +163,8 @@ module Ask
155
163
  workspace: workspace_path,
156
164
  mode: mode,
157
165
  model: model || @model_id,
166
+ system_prompt: system_prompt,
167
+ agent: agent,
158
168
  created_at: Time.now,
159
169
  session: nil,
160
170
  subscribers: [],
@@ -364,41 +374,78 @@ module Ask
364
374
  # ── Session construction ──
365
375
 
366
376
  def build_session(entry)
367
- chat = build_chat(entry[:model])
377
+ session = entry[:agent] ? build_agent_session(entry) : build_plain_session(entry)
378
+ session.on_event { |event| translate_event(entry, session, event) }
379
+ session
380
+ end
368
381
 
369
- queue = EmittingApprovalQueue.new(
370
- on_submit: ->(a) { emit_approval(entry, a, :pending) },
371
- on_status: ->(a) { emit_approval(entry, a, a.status) }
372
- )
382
+ # Build a session from a declarative agent definition (ask-agent
383
+ # convention). The definition's tools, skills (agent_dir), and
384
+ # instructions apply; harness-level options win where set. Agents
385
+ # are discovered from the working directory (the harness runs the
386
+ # session inside its workspace).
387
+ #
388
+ # The emitting approval queue is passed through Ask::Agent.new's
389
+ # opts, so Session#build_approval wires it with the session's
390
+ # apply/reject/register callbacks — approval events stream exactly
391
+ # like the plain path.
392
+ def build_agent_session(entry)
393
+ queue = emitting_queue(entry)
394
+ opts = {
395
+ approval: approval_config(queue),
396
+ plan_mode: @plan_mode,
397
+ todos: @todos,
398
+ max_turns: @max_turns,
399
+ # Caller options win over the definition; a nil model lets the
400
+ # definition's own model apply.
401
+ model: (entry[:model] unless entry[:model] == @model_id)
402
+ }.compact
403
+ opts[:system_prompt] = entry[:system_prompt] if entry[:system_prompt]
404
+ Ask::Agent.new(entry[:agent], **opts)
405
+ end
373
406
 
374
- approval_cfg =
375
- case @approval
376
- when APPROVAL_REQUIRE then { queue: queue, require_approval: @approval_required }
377
- when APPROVAL_AUTO then { queue: queue }
378
- when APPROVAL_OFF then nil
379
- else
380
- raise ArgumentError, "approval must be one of #{APPROVAL_MODES.inspect}, got #{@approval.inspect}"
381
- end
407
+ # Build the default session (no declarative agent).
408
+ def build_plain_session(entry)
409
+ prompt = entry[:system_prompt] || @session_opts[:system_prompt]
410
+ chat = build_chat(entry[:model], prompt)
382
411
 
383
412
  Ask::Agent::Session.new(
384
413
  model: chat,
385
414
  tools: @tools,
386
415
  max_turns: @max_turns,
387
- approval: approval_cfg,
416
+ approval: approval_config(emitting_queue(entry)),
388
417
  plan_mode: @plan_mode,
389
418
  todos: @todos,
390
419
  **@session_opts
391
- ).tap do |session|
392
- session.on_event { |event| translate_event(entry, session, event) }
420
+ )
421
+ end
422
+
423
+ def emitting_queue(entry)
424
+ EmittingApprovalQueue.new(
425
+ on_submit: ->(a) { emit_approval(entry, a, :pending) },
426
+ on_status: ->(a) { emit_approval(entry, a, a.status) }
427
+ )
428
+ end
429
+
430
+ def approval_config(queue)
431
+ case @approval
432
+ when APPROVAL_REQUIRE then { queue: queue, require_approval: @approval_required }
433
+ when APPROVAL_AUTO then { queue: queue }
434
+ when APPROVAL_OFF then nil
435
+ else
436
+ raise ArgumentError, "approval must be one of #{APPROVAL_MODES.inspect}, got #{@approval.inspect}"
393
437
  end
394
438
  end
395
439
 
396
- def build_chat(model_id)
440
+
441
+
442
+ def build_chat(model_id, system_prompt = nil)
397
443
  chat = Ask::Agent::Chat.new(
398
444
  model: model_id,
399
445
  provider: @provider_slug,
400
446
  tools: @tools
401
447
  )
448
+ chat.with_instructions(system_prompt) if system_prompt
402
449
  # Inject pre-configured provider to bypass Ask::Auth.resolve
403
450
  chat.instance_variable_set(:@provider, @provider)
404
451
  chat
@@ -38,7 +38,7 @@ module Ask
38
38
  @started
39
39
  end
40
40
 
41
- def create_session(workspace_path, mode: nil)
41
+ def create_session(workspace_path, mode: nil, system_prompt: nil, **)
42
42
  ensure_started
43
43
  sid = "sess_#{SecureRandom.uuid}"
44
44
  @sessions[sid] = { workspace: workspace_path, mode: mode, created_at: Time.now }
@@ -42,7 +42,7 @@ module Ask
42
42
  @client&.running? || false
43
43
  end
44
44
 
45
- def create_session(workspace_path, mode: nil)
45
+ def create_session(workspace_path, mode: nil, system_prompt: nil, **)
46
46
  ensure_running
47
47
  thread = @client.thread_start(cwd: workspace_path)
48
48
  tid = thread["id"] || thread[:id]
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ask
4
4
  module CodingProviders
5
- VERSION = "0.3.0"
5
+ VERSION = "0.3.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-coding-providers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto