Sentiment
sentiment.bucket_events
sentiment.bucket_events=ConversationBucketer.bucket_events
sentiment.ConversationEvent
The conversational subset of the event spine that sentiment scoring consumes.
sentiment.ConversationEvent=UserEvent | AssistantEvent
sentiment.ConversationBucket
A session’s conversational events grouped into one fixed-width time window — the unit that gets scored.
Usage
sentiment.ConversationBucket()sentiment.ConversationBucketer
Groups conversational transcript events into per-session, time-aligned buckets worth scoring.
Usage
sentiment.ConversationBucketer()User and assistant events are selected from the stream; system, mode, and other events are ignored, and user turns that are protocol noise (JUNK_USER_MESSAGE_RE — slash-command wrappers, interrupt markers, stop-hook feedback, bash-mode echoes) are dropped before counting so they neither reach the model nor pad bucket eligibility. Sessions below MIN_USER_TURNS_PER_SESSION and windows lacking a substantive user turn or any assistant turn are dropped. The bucketing runs in the Rust core over borrowed event views; this facade rehydrates each window back into the caller’s own events.
Methods
| Name | Description |
|---|---|
| bucket_events() | Lifts the conversational events in events into scorable ConversationBucket windows. |
bucket_events()
Lifts the conversational events in events into scorable ConversationBucket windows.
Usage
bucket_events(events)Example
>>> bucket_events(parse_events_from_bytes(raw))[ConversationBucket(session_id=‘s’, bucket_index=0, …)]
sentiment.BucketKey
Stable identity of a ConversationBucket: its session and bucket index.
Usage
sentiment.BucketKey()sentiment.BucketIndex
sentiment.BucketIndex=NewType("BucketIndex", int)
sentiment.BUCKET_MINUTES
sentiment.BUCKET_MINUTES=3
sentiment.extract_bucket_keys()
Usage
sentiment.extract_bucket_keys(events)sentiment.SentimentScore
sentiment.SentimentScore=NewType("SentimentScore", int)
sentiment.InferenceEngine
Usage
sentiment.InferenceEngine()sentiment.FilteredEngine
Wraps an InferenceEngine with a ScoreSpec: short-circuit
Usage
sentiment.FilteredEngine(inner, spec)stages pre-empt inference, post-process stages adjust the model score. Every deterministic stage runs in Rust; only inference stays Python-side.
Parameter Attributes
inner: InferenceEnginespec: ScoreSpec
sentiment.ScoreSpec
An ordered list of ScoreStage applied around model inference.
Usage
sentiment.ScoreSpec(stages)Parameter Attributes
stages: tuple[ScoreStage, …]
sentiment.ScoreStage
sentiment.ScoreStage=FrustrationShortCircuit | PositiveClamp | MildIrritationDemote | ResumeClamp
sentiment.build_score_spec()
Assembles stages into a ScoreSpec for the engine to apply around inference.
Usage
sentiment.build_score_spec(*stages)sentiment.flag_frustration()
Composes the short-circuit stage that pins a frustrated message to score before inference.
Usage
sentiment.flag_frustration(*, score=1)sentiment.clamp_positive()
Composes the post-process stage that lowers a top score on a short message lacking positive lexicon.
Usage
sentiment.clamp_positive(*, max_words=SHORT_MESSAGE_MAX_WORDS)sentiment.clamp_resume()
Composes the post-process stage that neutralizes a bare resume phrase to a middling score.
Usage
sentiment.clamp_resume()sentiment.demote_mild_irritation()
Composes the post-process stage that softens a non-hostile mild-impatience message off the floor score.
Usage
sentiment.demote_mild_irritation()sentiment.Lexicon
Surface-form token polarity: coding-domain overrides layered over AFINN.
Usage
sentiment.Lexicon()Polarity is looked up on the token surface — never a lemma — so inflected forms AFINN scores directly (lost, broken) keep their signal instead of collapsing to a neutral base. DOMAIN_OVERRIDES (the cc_transcript/sentiment/data/domain_overrides.tsv snapshot) pins context-specific terms AFINN mis-scores; AFINN magnitudes below MIN_MAGNITUDE collapse to neutral. Backs the lexicon-bearing score stages through has_hit().
Methods
| Name | Description |
|---|---|
| has_hit() |
Whether any token in text reaches the polarity FLOOR.
|
| polarity() |
The signed polarity of token.
|
has_hit()
Whether any token in text reaches the polarity FLOOR.
Usage
has_hit(text, *, want_negative)<= -FLOOR when want_negative else >= FLOOR. Surface polarity with negation sign-flip and no POS gate: every token’s surface polarity counts, and a negated token’s polarity is sign-flipped — so isn't great reaches the negative floor, not the positive one. POS-based suppression is a highlighter concern, not a scoring one. Executes in Rust over the UDPipe substrate.
polarity()
The signed polarity of token.
Usage
polarity(token)A domain override when present, else its AFINN score zeroed below MIN_MAGNITUDE. token is a tokenizer surface: already lowercased and alphabetic. Executes in Rust.