Computational affect + a curiosity layer for AI: mix emotions, rank valuable unanswered questions, and decompose them into investigable steps
Project description
๐ Artificial Emotions
Every AI tool races to answer. This one refuses.
A curiosity engine that ranks what we don't yet know โ then decomposes it into something you can actually go and test.
Quickstart ยท Discover ยท The loop ยท Go deeper ยท Affect ยท Surfaces ยท Docs
The problem nobody automated
We have built extraordinary machines for answering questions.
We have built almost nothing for choosing which question deserves the next decade of a career, a grant, or a lab. That choice is still made by intuition, prestige, and whatever happens to be trending โ and it is the highest-leverage decision in all of research.
Artificial Emotions is a curiosity layer. Give it a domain, a topic, and an explicit statement of what you value; get back ranked unknowns with gap evidence, uncertainty bands, and an investigation plan.
[!IMPORTANT] It will not answer them. That isn't a limitation we're working around โ it's the product. A tool that ranked unknowns and invented answers for them would quietly become the thing it was built to protect you from.
The 60-second demo
git clone https://github.com/KanakMalpani/Artificial-Emotions.git
cd Artificial-Emotions
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
pip install -e ".[dev]"
emotions spark --domain ai --n 5 --json
No API key. No network. No LLM. Curated seeds and heuristic scoring, entirely on your machine. Here is a real result, unedited:
{
"question": "Which training interventions most increase honest uncertainty
reporting under incentive pressure to appear confident?",
"curiosity_score": 0.8648,
"score_band": [0.578, 1.151], // evidence envelope, NOT a confidence interval
"confidence": 0.242, // low โ and it says so
"gap_status": "unknown_with_caveat",
"axes": { "impact": 0.40, "neglectedness": 1.00, "tractability": 0.70,
"surprise": 0.30, "answerability": 0.78, "risk": 0.15 },
"flags": ["heuristic_scoring", "no_literature"],
"epistemic_cues": ["information_gap", "curiosity_target", "confusion_risk"]
}
Look at what it volunteered about itself: confidence 0.242, flagged heuristic_scoring, flagged no_literature, gap status hedged to unknown_with_caveat. It tells you how much to trust it before you think to ask.
๐ญ It generates questions nobody wrote โ and can show the method works
Ranking a list someone typed cannot surprise you. So the engine also generates candidates from literature itself, using Swanson ABC linking: if one body of work ties A to B, and another ties B to C, but A and C are essentially never studied together, then "does A affect C via B?" is an open question with the bridge and the papers as evidence.
Swanson used exactly this to propose fish oil for Raynaud's (1986) and magnesium for migraine (1988) โ both from disconnected literatures, both later supported.
emotions discover "Fish oil" --corpus examples/discovery_corpus_demo.json
Fish oil --[Blood viscosity]--> Raynaud disease
co-occurrence: 0 works gap: 0.141421
Q: Does Fish oil influence Raynaud disease, and is Blood viscosity the mechanism?
evidence A-B: Dietary fish oil reduces blood viscosity in healthy volunteers
evidence B-C: Blood viscosity abnormalities in Raynaud's syndrome
No provider lock-in, no network required. DiscoveryClient is a Protocol โ
run it against a corpus you supply (reading list, BibTeX export, proceedings
dump) with zero API calls. OpenAlex is one optional backend, with caching.
Then prove it, don't assert it
Hide everything after a cutoff year, discover from the past alone, and check which proposals show up in the held-out future:
emotions validate --corpus examples/discovery_corpus_timesplit_demo.json \
--cutoff 1986 --seeds "Fish oil"
cutoff 1986: 14 past docs โ 3 proposals, 2 confirmed in 6 held-out docs
hit_rate=0.67 | baseline=0.20 | lift=3.33x
[CONFIRMED] Fish oil --[Blood viscosity]--> Raynaud disease
[ โ ] Fish oil --[Plasma lipids]--> Dietary fibre
[CONFIRMED] Fish oil --[Blood viscosity]--> Vasospasm
[!IMPORTANT] A hit rate alone would be the vanity metric this repo forbids. With a dense corpus you could "confirm" most random pairs and look brilliant. So every run also pairs A against randomly drawn concepts and measures how often those land. Lift is the honest number; lift near 1.0 means the method is doing nothing that shuffling would not โ and there is a test asserting exactly that collapse happens when the future confirms everything.
The random pool isn't filtered to exclude concepts the method also proposed, so the control can score its own hits. That makes lift a floor, not a ceiling.
This is one corpus at one cutoff, at small N โ evidence, not a benchmark, and the report says so. But it is a falsifiable claim about the method working, which is more than this field usually offers.
How it thinks
flowchart LR
A["๐ฏ Domain + Topic<br/>+ ValueProfile"] --> B["Generate<br/>seeds ยท packs ยท LLM"]
B --> C["Verify Gap<br/>OpenAlex ยท S2"]
C --> D["Score<br/>6 axes"]
D --> E["Gate<br/>risk ยท answerability"]
E --> F["Diversify<br/>near-dup suppression"]
F --> G["๐ Ranked Unknowns<br/>+ briefs + bands"]
G --> H["๐ฌ Decompose<br/>one step further"]
style A fill:#7c3aed,stroke:#5b21b6,color:#fff
style G fill:#059669,stroke:#047857,color:#fff
style H fill:#dc2626,stroke:#b91c1c,color:#fff
The critical edge is Verify Gap โ Score: finding related literature does not mean a question is answered. Most tools collapse that distinction. This one gates on it โ and an LLM gap-reader that cites a paper absent from the retrieved set gets its verdict rejected, not merged.
๐ The loop: curiosity with causes and consequences
Most "AI emotion" projects hand the model a mood and print it. Here affect is derived from what the run actually found, and it changes what happens next.
emotions explore --domain ai --steps 4
step 1 [ai] 4 new
acted: curiosity 0.69, hope 0.30, determination 0.25
observed: humility 0.35, clarity 0.30, uncertainty 0.29, insight 0.26
ยท n_candidates: 16 โ 22
because curiosity โ Open, neglected gaps are worth casting wider for.
ยท stay_the_course: False โ True
because hope โ A live, reachable thread is running.
ยท force_decompose: False โ True
because determination โ A workable high-value target is live.
โ Determination called for the ladder rather than more breadth.
step 2 [ai] 0 new
feels: boredom 0.93, curiosity 0.69, humility 0.35
ยท diversity_threshold: 0.82 โ 0.764
because boredom โ Ground already covered.
ยท domain: ai โ <caller picks a new one>
because boredom โ This vein is mined out; the honest move is to change ground.
โ Boredom pushed a change of ground.
step 3 [biology] 4 new
feels: curiosity 0.71, humility 0.35, insight 0.26
Nothing told it to be bored. It looked at the same ground twice, found nothing new, and boredom is what that situation produces โ so it moved. Nothing told it to be humble either: thin evidence met by correspondingly low confidence is humility, and the system appraises itself for that before you have to.
flowchart LR
R["Rank"] -->|"what did we find?"| A["Appraise"]
A -->|"so this is what<br/>it feels like"| F["Affective state"]
F -->|"so search<br/>differently"| M["Modulate"]
M --> T["Remember"]
T --> R
style A fill:#7c3aed,stroke:#5b21b6,color:#fff
style F fill:#dc2626,stroke:#b91c1c,color:#fff
37 of the 54 catalogued emotions are derivable, and 22 of those change what the engine does. The rest are declared observation-only โ surfaced for the reader, deliberately not acted on.
| Feeling | Fires when | Changes |
|---|---|---|
| curiosity | Open gaps, neglected, high stakes | Widens the candidate pool |
| confusion | Judges disagree, or answerability is low | Narrows, forces decomposition |
| boredom | This ground is already mined | Suppresses duplicates, changes domain |
| hubris | Confidence outran the evidence | Makes the system go get literature |
| anxiety | Dual-use material in the set | Tightens the risk ceiling, demands review |
| skepticism | An LLM cited work that wasn't retrieved | Forces the soundness pass |
| absorption / hope | A live, reachable thread is running | Vetoes the stop, holds the ground |
| disappointment | Gaps closed before we got there | Records the nulls and moves |
| triumph | A result that holds up | Turns it into a concrete plan |
| frustration | Repeated effort ruled nothing out | Stops the loop and records the dead end |
| elegance, respect, envy | Aesthetic pull, prior work, competition | Nothing โ real drivers and known biases, so they are shown, not obeyed |
Runs print acted: and observed: separately, so you can see which feelings
actually moved something:
step 1 [ai] 4 new
acted: curiosity 0.69, hope 0.30, determination 0.25
observed: humility 0.35, clarity 0.30, uncertainty 0.29, insight 0.26
ยท stay_the_course: False โ True
because hope โ A live, reachable thread is running.
[!NOTE] Affect is allowed to make a safety gate stricter, never looser.
anxietylowersmax_risk; nothing raises it. Andtests/test_appraisal_coverage.pyasserts every rule is firable and that each one either changes behaviour or is explicitly declared observation-only โ the catalog cannot quietly rot back into decoration.
[!IMPORTANT] Affect moves search behaviour โ never your scoring weights. Ranking stays a pure function of the
ValueProfileyou stated. Weight modulation exists but is opt-in (--affect-weights), capped at ยฑ0.08, and every delta is listed in the output. Otherwise this tool would be smuggling hidden values into the one thing built to refuse them.Every signal ships with its evidence. Affect you cannot audit is affect you cannot trust.
Three things it does
๐งญ Curiosity is not the only useful feeling
Curiosity asks "what is worth investigating?" โ and for a long time that was the only question this repo could ask. Every other emotion was a modifier on how curiosity searched.
But researchers don't only feel curious. Before committing a quarter to something they feel doubt. Before touching a risky area, anxiety. Looking at a pile of half-finished threads, resignation โ and the good ones act on it.
Stances make those the point instead of the side-effect. Same ranked set, seven different questions:
flowchart LR
R["๐ One ranked set<br/><i>ordered by your ValueProfile</i>"]
R --> D["๐ <b>doubt</b><br/>which am I most likely<br/>to be wrong about?"]
R --> S["๐ก๏ธ <b>safety</b><br/>which could hurt someone,<br/>and who reviews it?"]
R --> F["๐ฏ <b>focus</b><br/>if only one, what<br/>exactly would I do first?"]
R --> C["๐ช <b>close</b><br/>what do we stop doing,<br/>and what do we write down?"]
R --> T["โ๏ธ <b>taste</b><br/>which are badly posed,<br/>whether or not they matter?"]
R --> W["โจ <b>wonder</b><br/>what's most surprising,<br/>whether or not it's valuable?"]
R --> V["๐บ๏ธ <b>survey</b><br/>who already owns<br/>this ground?"]
emotions stance doubt --domain ai --n 5
[doubt] Which of these am I most likely to be wrong about?
driven by: skepticism, suspicion, hubris, humility
ยท What measurable internal signals most reliably predict goal-misgeneralizationโฆ
doubt_score: 0.84
- scored heuristically โ no judge looked at it
- no literature was consulted, so the gap is unverified
- confidence is low (0.24)
- score band is wide (0.57) โ weakly pinned
- gap status is hedged, not established
- no related work was found to argue against
Not claimed: a re-ranking โ the ValueProfile ordering you were given is unchanged.
A stance is a view, never a verdict. It cannot rescore anything, and every payload says so. wonder is the sharpest example: it deliberately ignores your ValueProfile and ranks on surprise alone, then reports where it disagrees with your values โ because a profile that never surprises you is a profile that is filtering something out.
emotions stance list # what each one asks, and when to reach for it
emotions stance safety --domain medicine
curl "localhost:8000/v1/stances/close?domain=ai"
This is what stops the catalog from being decoration. A test in tests/test_appraisal_coverage.py asserts that every appraisable emotion either steers the search or drives a stance โ 37 of 37, no exceptions, enforced in CI. Being named and disclaimed is not a use.
๐ฐ๏ธ Continuity โ and imagination under quarantine
Affect that dies when the process exits cannot surprise you twice. Alive adds continuity and generative lenses without claiming phenomenal feeling.
Memory defaults (privacy-first)
| Surface | Persistent memory |
|---|---|
CLI emotions explore |
On โ local JSON at ~/.artificial_emotions/memory.json |
Library explore(...) |
Off (persist_memory=False) |
| MCP / HTTP | Off by default |
Opt out everywhere with CURIOSITY_NO_MEMORY=1 (or explore --no-memory).
Inspect, edit, or wipe: emotions memory show|forget|reset.
Scars, costs, temperament, and avoidance bias search from that history โ
disclosed, capped behavioral biases, not motives. Avoidance reports
questions seen often and never picked (pattern_not_motive); it cannot tell
avoidance from judgment. emotions dream is explicit offline reanalysis of
the same file โ never a background loop, never labeled as dream-evidence.
emotions memory avoiding
Six encounters of ai-04, zero selections โ the pattern is checkable; the
motive is not. Re-render: python scripts/render_avoidance_svg.py.
Imagination โ sealed, then optional
emotions imagine list
emotions imagine premortem --domain ai --n 5
emotions imagine transfer --seed "Fish oil" --corpus examples/discovery_corpus_timesplit_demo.json
Imagined material travels only under the imagined key with
honesty: "imagined_not_retrieved" and never shares a list with ranked
unknowns. Wired today: premortem, reformulation, counterfactual.
Registered stubs (generators next): harm_scenario, rehearsal, eulogy.
Transfer is corpus-gated on purpose (not apply_imagination over a ranking)
and cleared the same validate lift bar as discovery โ โ5ร over random
pairing on the bundled timesplit corpus; a dense-corpus control collapses lift
to chance.
๐ฌ Going deeper: decompose
Ranking tells you what to investigate. This takes one unknown a step further toward a solution โ without becoming an answer engine.
emotions decompose \
"Which evaluation protocols most reduce sandbagging when models detect testing?" \
--ops "Capability gap <= 5% versus hidden probes." --depth 2
flowchart TD
Q["โ The unknown"] --> M["๐ Measurement<br/>what makes this observable?"]
Q --> B["โ๏ธ Baseline<br/>what does nothing look like?"]
Q --> X["โ๏ธ Mechanism<br/>what would have to hold?"]
Q --> C["๐ญ Confound<br/>what else explains it?"]
Q --> D["๐ง Boundary<br/>where does it stop holding?"]
X --> X1["distinguish the<br/>candidate mechanisms"]
X --> X2["where would a<br/>mechanism fail?"]
C --> C1["separate effect<br/>from confound"]
C --> C2["where do they<br/>look identical?"]
style Q fill:#dc2626,stroke:#b91c1c,color:#fff
style X fill:#7c3aed,stroke:#5b21b6,color:#fff
style C fill:#7c3aed,stroke:#5b21b6,color:#fff
Alongside the tree you get three things that turn a question into a plan:
| Output | What it gives you |
|---|---|
| The first observation | Chosen from your stated criteria and the score axes. No usable measurement? Start there. Shaky question? Probe its boundary. Well-posed? Go kill the rival explanations. |
| Falsifiers | Derived from your own operationalization. Capability gap <= 5% becomes refuted if Capability gap > 5%. |
| Stop rules | Including a review gate that fires automatically when the risk axis is elevated. |
[!NOTE] Every string it emits is a question, a test, or a criterion โ enforced, not intended.
assert_free()scans the whole payload for assertion language, and results ship withassertion_free: true. A decomposition that concluded something would be a bug. There's also a test that the checker itself still catches assertions, so the guarantee can't quietly go hollow.Even a complete decomposition signs off by telling you the original gap is not thereby closed.
๐ Computational affect
Not decoration. The catalog is a vocabulary for investigative states โ and it names the ones that actually govern research decisions.
mindmap
root((54 emotions))
Epistemic
curiosity
doubt
insight
perplexity
humility
hubris
Aesthetic
elegance
parsimony
dissonance
Volitional
determination
impatience
persistence
Achievement
triumph
disappointment
resignation
Social
compassion
respect
envy
Basic
joy
fear
trust
humility and hubris are both in there on purpose. This project exists to keep confidence proportionate to evidence. The failure mode needs a name as much as the discipline does.
Mixing past pairs
Most affect models stop at two-component blends. This returns three structural readings:
| Field | What it reports |
|---|---|
plutchik_dyad_hint |
Named 2-component compound โ joy + trust โ love |
blend_triad_hint |
Named 3-component blend โ curiosity + skepticism + humility โ disciplined_inquiry |
ambivalence |
Opposing entries held at once, scored across 13 opposition axes |
Ambivalence is the one that matters. Hold conviction beside live doubt and the simulation doesn't average them into mush โ it reports the tension and tells you what to do with it:
emotions mix conviction=45 doubt=40 urgency=15 --json
{
"ambivalence": {
"score": 0.756,
"pairs": [{ "components": ["conviction", "doubt"], "axis": "epistemic" }]
},
"pad": { "P": 0.113, "A": 0.510, "D": 0.305 },
"felt_simulation": {
"intensity": 0.483,
"inner_monologue":
"Simulated affect: I register primarily conviction, blended with Doubt (40%)
and Urgency (15%) โ mood reads ambivalent, mid-arousal, empowered.
I am pulled two ways โ conviction against doubt. Do not resolve that by
picking a side: name the observation that would settle it."
}
}
Sustained ambivalence is reported as an honest state, not an error to resolve.
[!WARNING] This is
computational_affect, and every payload says so. Not biological feeling. Not consciousness. Not biometric emotion recognition, and not measurement of anyone's affect โ which matters under the EU AI Act. It is a PAD blend simulating a stance for framing. Nothing more, and it never claims more.
๐ Use it from anywhere
flowchart LR
CLI["โจ๏ธ CLI<br/>emotions"] --> E(("Engine"))
PY["๐ Python<br/>CuriosityEngine"] --> E
MCP["๐ MCP stdio<br/>imagination + tiers"] --> E
HTTP["๐ HTTP<br/>/v1 discovery"] --> E
OAI["๐ค OpenAI tools<br/>function calling"] --> E
style E fill:#059669,stroke:#047857,color:#fff
โจ๏ธ CLI โ shell workflows and quick inspection
emotions discover "Fish oil" --corpus corpus.json # generate new questions
emotions validate --corpus corpus.json --cutoff 1986 --seeds "Fish oil" # prove the method
emotions explore --domain ai --steps 5 # the curiosity loop
emotions spark --domain biology --profile alignment_lab --json # fast offline pack
emotions run --domain ai --n 5 --no-literature --json # full pipeline
emotions decompose "Which mechanism explains X?" --depth 2 # go deeper
emotions imagine premortem --domain ai # quarantined imagination
emotions memory show # local CLI continuity
emotions dream # explicit history reanalysis
emotions compare-profiles --a humanity_default --b alignment_lab # whose values?
emotions mix curiosity=40 confusion=30 awe=30 --json # affect
emotions profiles # list presets
Domains: ai ยท biology ยท physics ยท climate ยท medicine ยท materials ยท social ยท energy ยท general
(curiosity and curiosity-mcp still work as pre-rename aliases.)
๐ Python โ libraries and notebooks
from artificial_emotions import CuriosityConfig, CuriosityEngine, provoke
from artificial_emotions.decompose import decompose_ranked
from artificial_emotions.emotions import mix_emotions
from artificial_emotions.explore import explore
pack = provoke(domain="ai", n=5, fast=True, profile_name="alignment_lab")
print(pack["inject"]) # paste into any model's context
results = CuriosityEngine(
CuriosityConfig(domain="climate", n_return=5, use_literature=False)
).run()
plan = decompose_ranked(results[0], depth=2)
assert plan["assertion_free"] is True # it never answered anything
mood = mix_emotions({"curiosity": 60, "doubt": 40})
print(mood["felt_simulation"]["inner_monologue"])
trail = explore(domain="ai", steps=5) # curiosity with a history
for step in trail["trajectory"]["steps"]:
print(step["step"], step["primary_feeling"], "โ", step["note"])
๐ MCP โ Cursor, Claude Desktop, Claude Code, Copilot, Continue, Windsurf
emotions-mcp # or: python -m artificial_emotions.mcp_server
{
"mcpServers": {
"artificial-emotions": {
"command": "/path/to/Artificial-Emotions/.venv/bin/python",
"args": ["-m", "artificial_emotions.mcp_server"]
}
}
}
Tools include ranking, stances, and imagination (list_imagination_kinds,
apply_imagination). Memory / dream / transfer tools are being exposed on the
same registry in parallel โ treat
agent_tools_pkg/registry.py
as the source of truth rather than a frozen count here. Set
CURIOSITY_MCP_TIER=core|investigate|affect|research to shrink the surface.
Host-by-host setup in docs/PLUGINS.md. Persistence stays
off on MCP by default.
๐ HTTP + OpenAI tools โ agent backends and function calling
emotions serve # 127.0.0.1:8000 โ interactive docs at /docs
| Route | Purpose |
|---|---|
GET|POST /v1/curiosity/provoke |
Fast investigation pack |
POST /v1/curiosity/run |
Full ranking pipeline |
POST /v1/curiosity/decompose |
Sub-questions, first step, falsifiers |
POST /v1/curiosity/explore |
The full loop: appraise โ feel โ modulate โ remember |
GET /v1/stances, /v1/stances/{stance} |
Non-curiosity views over a ranking |
POST /v1/emotions/mix |
Affect blend + felt simulation |
GET /v1/agent |
Machine-readable capability and honesty guide |
GET /v1/agent/tools |
OpenAI-compatible function schemas |
GET /health, /ready |
Liveness, config summary, offline readiness |
Imagination / memory / dream / transfer HTTP routes mirror the CLI and land via
/v1 discovery as they ship โ check GET /v1/agent rather than assuming a
fixed path list. Auth is opt-in: set CURIOSITY_API_KEY and every route outside
the open list requires a bearer token. Unset, it stays open for local demos.
How the ranking works
(Impact^ฮฑ ยท Neglectedness^ฮฒ ยท Tractability^ฮณ ยท Surprise^ฮด) ยท Answerability ยท (1 โ Risk)
curiosity = โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
cost + ฮต
A geometric mean, deliberately. It preserves weak-link behaviour: a near-zero tractability collapses the whole score instead of being averaged away by a flattering impact number.
| Axis | Asks | Guardrail |
|---|---|---|
| Impact | What changes if this is answered? | Stake language only โ citation counts never inflate it |
| Neglectedness | Is anyone already on this? | Literature density and answer pressure push it down |
| Tractability | Could we make progress now? | โ |
| Surprise | Would the answer shift beliefs? | Not EVSI, and never claimed to be |
| Answerability | Is it posed sharply enough? | Multi-clause research programmes get penalised |
| Risk | Dual-use / harm proxy | Heuristic filter, not a biosecurity authority |
The exponents come from your ValueProfile โ one of 7 presets, or your own. There is no value-free ranking, and the tool refuses to pretend otherwise.
Why you can trust the numbers
This is the part most tools skip. Here it's load-bearing โ and enforced in code rather than promised in prose.
|
๐ซ Hallucinated citations are rejected An LLM gap-reader citing a paper absent from the retrieved set has its verdict thrown out and the heuristic gap kept โ annotated with why. ๐ซ No vanity accuracy metric
๐ซ Tool descriptions are linted
|
๐ซ No silent consensus
๐ซ Reproducible by construction
Identical input yields byte-identical JSON โ verified across three ๐ซ Decomposition cannot conclude
|
Scores are decision aids, not oracles. The [lowโhigh] band is an evidence-strength envelope, not a statistical confidence interval. A literature neighborhood is evidence to inspect, not proof of anything. Read docs/LIMITS.md before treating any rank as truth.
Verify it yourself
pip install -e ".[dev]"
pytest -q --cov --cov-report=term-missing # ~680 tests ยท 88% ยท floor enforced
ruff check src tests && ruff format --check src tests
CI runs lint, tests, and the coverage gate on Python 3.11, 3.12 and 3.13 โ then builds the wheel, installs it into a clean environment, and exercises the data files and console scripts from outside the checkout. A package that only works inside its own source tree is a broken package.
Install: pip install artificial-emotions (or editable pip install -e ".[dev]" from a clone).
Documentation
| docs/INDEX.md | Everything, organised |
| docs/ARCHITECTURE.md | Module map, Alive continuity/imagination, trust boundaries |
| docs/LIMITS.md | Verified capabilities and honest bounds |
| docs/EMOTIONS.md | Catalog, mixing, affect safety |
| docs/PLAN_ALIVE.md | Continuity + imagination (Track C / web/ historical) |
| docs/PLUGINS.md | Host-by-host MCP setup |
| docs/PROOFS.md | Reproducible behaviour demos |
| CHANGELOG.md | [0.4.1] release notes |
| examples/ | Payloads, protocols, tool schemas |
Contributing
Domain packs, seed questions, eval fixtures, and honesty patches are all welcome โ start with CONTRIBUTING.md. Changes to ranking, gap logic, tools, or public claims should ship with tests and updates to the relevant limits docs.
One rule above the rest: don't add a claim the code can't back. If a feature needs a caveat, the caveat ships inside the response payload โ not in a footnote nobody reads.
Security. Keep credentials in local env files; never commit .env, keys, or tokens. Before exposing HTTP beyond localhost set CURIOSITY_API_KEY, and don't bind 0.0.0.0 without auth. Report vulnerabilities privately to the maintainer rather than in a public issue.
MIT licensed ยท LICENSE
The best question is worth more than a fast answer.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file artificial_emotions-0.4.1.tar.gz.
File metadata
- Download URL: artificial_emotions-0.4.1.tar.gz
- Upload date:
- Size: 447.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2dc3af0027a7fa2692207b1b44a78646caffdcfdca6007d3063051181e86c141
|
|
| MD5 |
6f1923ae849d3e2ed7deee978210888e
|
|
| BLAKE2b-256 |
5ce999c41c07f7d37d87ca83f64e627f69a91fe413eb87c34ca4a324ddaf1021
|
File details
Details for the file artificial_emotions-0.4.1-py3-none-any.whl.
File metadata
- Download URL: artificial_emotions-0.4.1-py3-none-any.whl
- Upload date:
- Size: 306.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a862015a954aff18e1f6ade8553a18db29e735fb0384d6220b79e80134a58b2d
|
|
| MD5 |
c5b454710e58e7c6994aeeed82001b61
|
|
| BLAKE2b-256 |
d6182ac4cb174752e90138667686d479a0ca7fe2ce8ebaf3d5fc5bfe2e74d401
|