Economy item lookup
SkillDev toolsHow to look up economy items by user-provided text (name/id/alias/plural) and compute their worth in this codebase, centered on selectItem() and calcItemValue() in src/utils/functions/economy/inventory.ts and getItems() in economy/utils.ts. Use whenever a command, tool, or feature needs to resolve a search string to an Item or needs an item's current value.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Economy item lookup skill
What this skill tells your AI
The instructions your AI receives, as published by mxz7/nypsi in .agents/skills/economy-items/SKILL.md and read by ahel’s review.
- All item data comes from
getItems()insrc/utils/functions/economy/utils.ts— returns{ [id: string]: Item }parsed fromdata/items.json. Don't re-read the JSON file yourself. - The
Itemtype is defined insrc/types/Economy.ts. Notable fields:id,name,plural,article,aliases?,hidden?(excluded from user-facing search),sell?/buy?,role.
Exact lookup — selectItem(search: string)
src/utils/functions/economy/inventory.ts exports selectItem, the established helper for resolving a single user-typed search string to one Item. It's already used by buy, sell, give, offer, etc. — reuse it instead of writing new matching logic.
- Lowercases the input and filters out
hiddenitems first. - Matches (in order) against:
item.id,item.name,item.idwith underscores stripped, any ofitem.aliases,item.namewith spaces stripped,item.plural. - Returns
undefinedif nothing matches — always check for that.
Note: several older commands (help.ts, autosell.ts, buy.ts, karmashop.ts, top.ts, crateall.ts) have their own hand-rolled inline copies of similar matching logic predating selectItem — don't copy those; use selectItem for new code.
Computing worth — calcItemValue(itemId: string)
src/utils/functions/economy/inventory.ts exports calcItemValue(item: string): Promise<number | undefined>. It's cached (RedisCache, 1hr TTL). Logic: if the item has a fixed buy/sell price (or is cookie/bitcoin/ethereum/prey/fish/sellable/ore), it uses item.sell; otherwise it averages market + offer prices. Can resolve to undefined if there's no sell price and no market/offer data.
After calculating a cache miss, it asynchronously records one global item-value-<itemId> GraphMetrics row per day for historic graphs. An atomic Redis SET NX EX gate limits each item to one database existence check every 7–12 hours, and a shared RedisMutex serializes these checks across all processes. This history write is not awaited by the caller.
Use hasItemValueData(itemId) when an action must only be available with a history-supported value. It returns true only when completed market or offer history provides a value, avoiding the $1,000 fallback that can be retained in the value cache when no history exists.
Recording item acquisition sources
addItemSourceStat(itemId, source, amount) in src/utils/functions/economy/inventory.ts increments the global ItemSourceStats row identified by (itemId, source). Call it explicitly and without await after a successful addInventoryItem() whenever an item is newly generated. The function handles and logs its own database errors. The season reset deletes all source-stat rows.
Do not record transfers, trades, market/offer fulfillment, refunds, or inventory restoration. Rewards obtained from a crate or scratch card use item:<containerItemId> as their source; giveLootPoolResult() and openCrate() already propagate this attribution.
Click rewards use giveLootPoolResult(member, result, "click") inside rollClickLoot(), so item
source stats are recorded automatically under click. Do not add another source-stat increment in
the click interaction or it will double-count generated items.
getItemSourceStats(itemId) returns the current season's rows ordered by amount. The item command's obtaining tab uses it for the optional view source stats alternate view; items without recorded rows do not show the toggle.
Fuzzy/substring search (multiple results)
selectItem only returns a single exact match. If you need to find candidate items from a partial/fuzzy query (e.g. an AI tool letting a model discover an item id first), filter getItems() yourself with substring checks against the relevant searchable fields, still excluding hidden items. The AI search_items tool in src/utils/functions/ai/tools/items.ts searches id/name/aliases/role, allowing category searches through the same query input.
Odds of obtaining an item — getObtainingData(item: Item)
src/utils/functions/economy/item_info.ts exports getObtainingData, a synchronous function that computes all the ways an item can be obtained, already used by the item/help command's "obtaining" tab. Don't recompute loot pool weights/chances by hand — reuse this. Returns ObtainingData:
sources: string[]— human-facing summary strings (shop, crafting, karma shop, mining, fishing, hunting, voting, streaks, etc).workers: string[]/farm: string[]— which workers produce it as a byproduct / which plants grow it.obtaining: { itemId, chance }[]— other items (crates/pools) that can drop this item, with the average % chance.pools: { poolName, count, breakdown: { chance, itemId?, amount? }[] }[]— if the item itself is a container (e.g. a crate), the full odds breakdown of everything inside it, per pool.
getItems()/getLootPools()/getBaseWorkers()/getPlantsData() are all read synchronously under the hood — no DB calls, safe to call from anywhere (including AI tool executors) without extra caching.
Signals
- GitHub stars
- 69
- Forks
- 31
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
economy-items- Source
- github.com/mxz7/nypsi