Project

notilens

0.0
The project is in a healthy, maintained state
Send task started/progress/complete/failed notifications from AI agents, Sidekiq workers, and any Ruby application.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

NotiLens Ruby SDK

Ruby SDK and CLI for NotiLens — task lifecycle notifications for AI agents, Sidekiq workers, and any Ruby application.

Installation

gem install notilens

Or in your Gemfile:

gem "notilens"

Quick Start

require "notilens"

nl  = NotiLens.init("my-agent")
run = nl.task("report")
run.start
run.progress("Processing...")
run.complete("Done!")

Credentials

Resolved in order:

  1. token: / secret: keyword args to init
  2. NOTILENS_TOKEN / NOTILENS_SECRET env vars
  3. Saved CLI config (notilens init --agent ...)
nl = NotiLens.init("my-agent",
  token:     "your-token",
  secret:    "your-secret",
  state_ttl: 86400  # optional — orphaned state TTL in seconds (default: 86400)
)

SDK Reference

Task Lifecycle

nl.task(label) creates a Run — an isolated execution context. Multiple concurrent runs of the same label never conflict.

run = nl.task("email")   # create a run for the "email" task
run.queue                # optional — pre-start signal
run.start                # begin the run

run.progress("Fetching data...")
run.loop("Processing item 42")
run.retry
run.pause("Waiting for rate limit")
run.resume("Resuming work")
run.wait("Waiting for tool response")
run.stop
run.error("Quota exceeded")  # non-fatal, run continues

# Terminal — pick one
run.complete("All done!")
run.fail("Unrecoverable error")
run.timeout("Timed out after 5m")
run.cancel("Cancelled by user")
run.terminate("Force-killed")

Output & Input Events

run.output_generated("Report ready")
run.output_failed("Rendering failed")

run.input_required("Approve deployment?")
run.input_approved("Approved")
run.input_rejected("Rejected")

Metrics

Numeric values accumulate; strings are replaced.

run.metric("tokens", 512)
run.metric("tokens", 128)    # now 640
run.metric("cost", 0.003)

run.reset_metrics("tokens")  # reset one key
run.reset_metrics            # reset all

Automatic Timing

NotiLens automatically tracks task timing. These fields are included in every notification's meta payload when non-zero:

Field Description
total_duration_ms Wall-clock time since start
queue_ms Time between queue and start
pause_ms Cumulative time spent paused
wait_ms Cumulative time spent waiting
active_ms Active time (total − pause − wait)

Generic Events

nl.track("custom.event", "Something happened")
nl.track("custom.event", "With meta", meta: { "key" => "value" })

run.track("custom.event", "Run-level event")
run.track("custom.event", "With meta", meta: { "key" => "value" })

Full Example

require "notilens"

nl  = NotiLens.init("summarizer", token: "TOKEN", secret: "SECRET")
run = nl.task("report")
run.start

begin
  result = llm.complete(prompt)
  run.metric("tokens", result.usage.total_tokens)
  run.output_generated("Summary ready")
  run.complete("All done!")
rescue => e
  run.fail(e.message)
end

CLI

Install

gem install notilens

Configure

notilens init --agent my-agent --token TOKEN --secret SECRET
notilens agents
notilens remove-agent my-agent

Commands

--task is a semantic label (e.g. email, report). Each task.start creates an isolated run internally — concurrent executions of the same label never conflict.

notilens queue                      --agent my-agent --task email
notilens start                      --agent my-agent --task email
notilens progress  "Fetching data"  --agent my-agent --task email
notilens loop      "Item 5/100"     --agent my-agent --task email
notilens retry                      --agent my-agent --task email
notilens pause     "Rate limited"   --agent my-agent --task email
notilens resume    "Resuming"       --agent my-agent --task email
notilens wait      "Awaiting tool"  --agent my-agent --task email
notilens stop                       --agent my-agent --task email
notilens error     "Quota hit"      --agent my-agent --task email
notilens fail      "Fatal error"    --agent my-agent --task email
notilens timeout   "Timed out"      --agent my-agent --task email
notilens cancel    "Cancelled"      --agent my-agent --task email
notilens terminate "Force stop"     --agent my-agent --task email
notilens complete  "Done!"          --agent my-agent --task email

notilens output.generate "Report ready"  --agent my-agent --task email
notilens output.fail     "Render failed" --agent my-agent --task email
notilens input.required  "Approve?"      --agent my-agent --task email
notilens input.approve   "Approved"      --agent my-agent --task email
notilens input.reject    "Rejected"      --agent my-agent --task email

notilens metric       tokens=512 cost=0.003 --agent my-agent --task email
notilens metric.reset tokens               --agent my-agent --task email
notilens metric.reset                      --agent my-agent --task email

notilens track my.event "Something happened" --agent my-agent
notilens version

task.start prints the internal run_id to stdout.

Requirements

  • Ruby 2.7+
  • No external dependencies (uses stdlib net/http and json)