Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
0edf2b9
Add OpenRouter gateway and truthful hot bot AI
pmbstyle Aug 1, 2026
a536950
Persist hot bot conversations and arbitrate dialogue
pmbstyle Aug 1, 2026
a06e317
Bound hot bot context and summarize activity
pmbstyle Aug 1, 2026
bed36a0
Register auditable hot bot tools
pmbstyle Aug 1, 2026
5c48663
Add hot bot policy and equipment controls
pmbstyle Aug 1, 2026
e8add70
Add symmetric native bot trade
pmbstyle Aug 1, 2026
596752a
Add bounded hot bot price negotiation
pmbstyle Aug 2, 2026
fff3bf4
Add ambient hot bot scene director
pmbstyle Aug 2, 2026
fc55792
Add per-bot hot inference budgets
pmbstyle Aug 2, 2026
2fb3966
Trigger bounded hot decisions on state changes
pmbstyle Aug 2, 2026
773c869
Journal hot bot inference outcomes
pmbstyle Aug 2, 2026
41261af
Fix hot bot AI review findings
pmbstyle Aug 2, 2026
741aa6c
Make hot bot chat mandatory and add Langfuse telemetry
pmbstyle Aug 2, 2026
7b888c4
Route player chat through hot and cold bot dialogue
pmbstyle Aug 2, 2026
4bd5f30
Bound bot dialogue context and trace tool outcomes
pmbstyle Aug 2, 2026
7726741
Refresh queued dialogue context before inference
pmbstyle Aug 2, 2026
e205727
Include dialogue regressions in the test suite
pmbstyle Aug 2, 2026
07ca94e
Always route explicit hot tells to the LLM
pmbstyle Aug 2, 2026
50ced5c
Fix LLM trace roots and outcome statuses
pmbstyle Aug 2, 2026
3ffda3a
Preserve FIFO order in queued bot dialogue
pmbstyle Aug 2, 2026
6dcf16f
Relax freshness checks for safe bot dialogue actions
pmbstyle Aug 2, 2026
4ceb773
Repair truncated structured bot responses
pmbstyle Aug 2, 2026
70749cf
Account mandatory chat usage and refresh ambient state
pmbstyle Aug 2, 2026
3b6b84f
Add dialogue stages and deterministic party replies
pmbstyle Aug 2, 2026
0b4f195
Classify stale actions as warning telemetry
pmbstyle Aug 2, 2026
fd98107
Enable structured response repair for hot dialogue
pmbstyle Aug 3, 2026
b8e3b34
Preserve canonical bot conversation turn order
pmbstyle Aug 3, 2026
07a5e04
Align queued dialogue with prepared world revision
pmbstyle Aug 3, 2026
ced2f91
Arbitrate one LLM responder per chat message
pmbstyle Aug 3, 2026
ff6b396
Separate hot dialogue Langfuse stages
pmbstyle Aug 3, 2026
a5e5b63
Trace cold chat context validation and delivery
pmbstyle Aug 3, 2026
ada81f0
Bound LLM traffic with global inference admission
pmbstyle Aug 3, 2026
5cbd0de
Cover cold chat global admission
pmbstyle Aug 3, 2026
f056978
Fix legacy SQLite conversation migration startup
pmbstyle Aug 3, 2026
b59361c
Allow reasoning-aware interactive bot completions
pmbstyle Aug 3, 2026
a45d3ea
Keep interactive inference ahead of soft quotas
pmbstyle Aug 3, 2026
65e8d2d
Recover truncated structured bot responses
pmbstyle Aug 3, 2026
b44b2bd
Make chat item context and arrival actions truthful
pmbstyle Aug 3, 2026
2e8dc3a
Render truthful bot replies after tool execution
pmbstyle Aug 3, 2026
9cfb559
Align bot response tests with delivery metadata
pmbstyle Aug 3, 2026
3bb1a13
Fix reasoning recovery and cold chat delivery
pmbstyle Aug 3, 2026
a263337
Preserve truthful bot replies across chat failures
pmbstyle Aug 3, 2026
7b1300a
Trace pre-provider bot dialogue failures
pmbstyle Aug 3, 2026
67b9a99
Harden hot bot LLM gateway and summarization
pmbstyle Aug 3, 2026
ae185fc
Make hot bot tools truthful and atomic
pmbstyle Aug 3, 2026
c2f0631
Fix hot bot dialogue truthfulness gaps
pmbstyle Aug 3, 2026
8909861
Add deterministic party chat address resolver
pmbstyle Aug 3, 2026
be84649
Route party chat through deterministic roster
pmbstyle Aug 3, 2026
e6e8b2c
Track party dialogue focus and in-flight ownership
pmbstyle Aug 3, 2026
0cc1828
Route party messages to role and interaction owners
pmbstyle Aug 3, 2026
35da1ef
Add bounded LLM router for ambiguous party chat
pmbstyle Aug 4, 2026
1bdc783
Add party routing telemetry and dispatch guardrails
pmbstyle Aug 4, 2026
6978229
Fix party LLM routing and companion errands
pmbstyle Aug 4, 2026
96f5196
Implement hot companion supply and party AI fixes
pmbstyle Aug 4, 2026
a6d924d
Fix companion supply workflows and AI policy edges
pmbstyle Aug 4, 2026
6b7ac25
Fix supply errand atomicity and lifecycle
pmbstyle Aug 5, 2026
74082a9
Implement LLM merchant price negotiation
pmbstyle Aug 5, 2026
d34cc82
Harden AI admission and trade concurrency
pmbstyle Aug 5, 2026
af082e3
Strengthen stale-price purchase regression
pmbstyle Aug 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions config/default.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,26 @@ showMonsterLevel = true
[OpenRouter]
enabled = false
apiKey =
model = google/gemini-2.5-flash-lite
model = openai/gpt-5.6-luna
partyRouterModel = openai/gpt-5.6-luna
temperature = 0.35
maxTokens = 160
timeoutMs = 3500
cooldownMs = 45000
chatCooldownMs = 12000
visibilityRadius = 6000
maxPromptPrice = 0.15
maxCompletionPrice = 0.60
reasoningEffort = low
maxConcurrentRequests = 32
debug = false

[Langfuse]
enabled = false
envFile =
baseUrl = http://localhost:3000
capturePayloads = true
debug = false

[BotPopulation]
enabled = true
ambientScenesEnabled = true
ambientSceneCooldownMs = 180000
ambientPairCooldownMs = 90000
ambientSceneTtlMs = 8000
backgroundResolverEnabled = true
backgroundPartyEnabled = true
phasePolicyEnabled = true
Expand Down
11 changes: 10 additions & 1 deletion config/local.example.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
[OpenRouter]
enabled = true
apiKey = sk-or-v1-your-key-here
model = google/gemini-2.5-flash-lite
model = openai/gpt-5.6-luna
# Optional cheap model for ambiguous party-chat routing; empty keeps deterministic routing only.
partyRouterModel =
debug = true

[Langfuse]
enabled = false
envFile =
baseUrl = http://localhost:3000
capturePayloads = true
debug = true
115 changes: 115 additions & 0 deletions database/sql/sqlite.sql
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,121 @@ CREATE TABLE IF NOT EXISTS bot_social_memory (
PRIMARY KEY(playerId, botId)
);

CREATE TABLE IF NOT EXISTS bot_conversations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
playerId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
summary TEXT NOT NULL DEFAULT '',
summaryThroughId INTEGER NOT NULL DEFAULT 0,
summaryThroughOrdinal INTEGER NOT NULL DEFAULT 0,
nextTurnOrdinal INTEGER NOT NULL DEFAULT 0,
version INTEGER NOT NULL DEFAULT 0,
createdAt INTEGER NOT NULL DEFAULT 0,
updatedAt INTEGER NOT NULL DEFAULT 0,
UNIQUE(playerId, botId)
);
CREATE INDEX IF NOT EXISTS bot_conversations_bot_updated ON bot_conversations(botId, updatedAt DESC);

CREATE TABLE IF NOT EXISTS bot_conversation_messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
conversationId INTEGER NOT NULL REFERENCES bot_conversations(id) ON DELETE CASCADE,
turnId TEXT NOT NULL,
role TEXT NOT NULL CHECK(role IN ('player', 'bot', 'system')),
channel TEXT NOT NULL DEFAULT 'local',
text TEXT NOT NULL DEFAULT '',
requestId TEXT,
delivered INTEGER NOT NULL DEFAULT 1,
createdAt INTEGER NOT NULL DEFAULT 0,
metaJson TEXT,
turnOrdinal INTEGER NOT NULL DEFAULT 0,
messageOrder INTEGER NOT NULL DEFAULT 0,
compacted INTEGER NOT NULL DEFAULT 0,
UNIQUE(conversationId, turnId, role)
);
CREATE INDEX IF NOT EXISTS bot_conversation_messages_recent ON bot_conversation_messages(conversationId, id DESC);
CREATE INDEX IF NOT EXISTS bot_conversation_messages_turn ON bot_conversation_messages(conversationId, turnId, role);

CREATE TABLE IF NOT EXISTS bot_activity_journal (
id INTEGER PRIMARY KEY AUTOINCREMENT,
playerId INTEGER REFERENCES characters(id) ON DELETE CASCADE,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
eventType TEXT NOT NULL,
summary TEXT NOT NULL DEFAULT '',
weight INTEGER NOT NULL DEFAULT 1,
dedupeKey TEXT,
count INTEGER NOT NULL DEFAULT 1,
createdAt INTEGER NOT NULL DEFAULT 0,
updatedAt INTEGER NOT NULL DEFAULT 0,
metaJson TEXT
);
CREATE INDEX IF NOT EXISTS bot_activity_journal_pair_recent ON bot_activity_journal(playerId, botId, updatedAt DESC);
CREATE INDEX IF NOT EXISTS bot_activity_journal_bot_recent ON bot_activity_journal(botId, updatedAt DESC);
CREATE INDEX IF NOT EXISTS bot_activity_journal_coalesce ON bot_activity_journal(playerId, botId, eventType, dedupeKey, updatedAt);

CREATE TABLE IF NOT EXISTS bot_tool_outcomes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
playerId INTEGER REFERENCES characters(id) ON DELETE SET NULL,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
turnId TEXT,
toolName TEXT NOT NULL,
outcome TEXT NOT NULL,
reason TEXT NOT NULL DEFAULT '',
worldRevision TEXT,
createdAt INTEGER NOT NULL DEFAULT 0,
metaJson TEXT
);
CREATE INDEX IF NOT EXISTS bot_tool_outcomes_bot_recent ON bot_tool_outcomes(botId, createdAt DESC);
CREATE INDEX IF NOT EXISTS bot_tool_outcomes_turn ON bot_tool_outcomes(botId, turnId, toolName, createdAt DESC);

CREATE TABLE IF NOT EXISTS bot_llm_turns (
id INTEGER PRIMARY KEY AUTOINCREMENT,
turnId TEXT NOT NULL UNIQUE,
playerId INTEGER REFERENCES characters(id) ON DELETE SET NULL,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
eventType TEXT NOT NULL,
channel TEXT NOT NULL DEFAULT '',
state TEXT NOT NULL DEFAULT 'queued',
requestId TEXT,
traceId TEXT,
startedAt INTEGER,
finishedAt INTEGER,
outcome TEXT,
model TEXT,
promptTokens INTEGER NOT NULL DEFAULT 0,
completionTokens INTEGER NOT NULL DEFAULT 0,
totalTokens INTEGER NOT NULL DEFAULT 0,
cost REAL,
error TEXT NOT NULL DEFAULT '',
metaJson TEXT
);
CREATE INDEX IF NOT EXISTS bot_llm_turns_bot_recent ON bot_llm_turns(botId, id DESC);
CREATE INDEX IF NOT EXISTS bot_llm_turns_player_recent ON bot_llm_turns(playerId, id DESC);
CREATE INDEX IF NOT EXISTS bot_llm_turns_state_recent ON bot_llm_turns(state, id DESC);

CREATE TABLE IF NOT EXISTS bot_negotiations (
id TEXT PRIMARY KEY,
playerId INTEGER REFERENCES characters(id) ON DELETE SET NULL,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
itemObjectId INTEGER NOT NULL,
itemSelfId INTEGER NOT NULL,
amount INTEGER NOT NULL,
referenceUnitPrice INTEGER NOT NULL,
desiredUnitPrice INTEGER NOT NULL,
minimumUnitPrice INTEGER NOT NULL,
maximumUnitPrice INTEGER NOT NULL,
currentUnitPrice INTEGER NOT NULL,
agreedTotalPrice INTEGER,
round INTEGER NOT NULL DEFAULT 0,
state TEXT NOT NULL,
createdAt INTEGER NOT NULL,
expiresAt INTEGER NOT NULL,
updatedAt INTEGER NOT NULL,
reason TEXT NOT NULL DEFAULT '',
metaJson TEXT
);
CREATE INDEX IF NOT EXISTS bot_negotiations_pair_recent ON bot_negotiations(playerId, botId, updatedAt DESC);
CREATE INDEX IF NOT EXISTS bot_negotiations_bot_recent ON bot_negotiations(botId, updatedAt DESC);

CREATE TABLE IF NOT EXISTS bot_friendships (
playerId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
botId INTEGER NOT NULL REFERENCES characters(id) ON DELETE CASCADE,
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
"wipe:bots": "node scripts/wipe-bots.js"
},
"dependencies": {
"@langfuse/otel": "^5.10.0",
"@langfuse/tracing": "^5.10.0",
"@opentelemetry/sdk-node": "^0.221.0",
"blowfish-ecb": "^1.0.2",
"eslint": "^8.36.0",
"explicit-json": "^1.0.5",
Expand Down
49 changes: 49 additions & 0 deletions scripts/run-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,59 @@ const tests = [
'tests/test_attack_hit_flags.js',
'tests/test_armor_stats.js',
'tests/test_bot_ai_visibility.js',
'tests/test_openrouter_gateway.js',
'tests/test_ai_config_surface.js',
'tests/test_langfuse_tracing.js',
'tests/test_bot_inference_budget.js',
'tests/test_bot_inference_interactive_queue.js',
'tests/test_chat_arrival_state.js',
'tests/test_bot_brain_state_change.js',
'tests/test_bot_llm_party_policy.js',
'tests/test_party_address_resolver.js',
'tests/test_party_dialogue_router.js',
'tests/test_party_dialogue_state.js',
'tests/test_party_llm_router.js',
'tests/test_party_chat_routing_integration.js',
'tests/test_bot_tool_pending_audit.js',
'tests/test_bot_conversation_store.js',
'tests/test_bot_dialogue_arbiter.js',
'tests/test_hot_bot_conversation_flow.js',
'tests/test_hot_bot_schema_repair.js',
'tests/test_hot_conversation_history_queue.js',
'tests/test_hot_bot_queue_failure.js',
'tests/test_bot_activity_journal.js',
'tests/test_bot_context_assembler.js',
'tests/test_bot_conversation_summary.js',
'tests/test_bot_tool_registry.js',
'tests/test_bot_tool_authorization.js',
'tests/test_hot_bot_policy_overlay.js',
'tests/test_llm_pull_policy_tools.js',
'tests/test_llm_party_regroup.js',
'tests/test_llm_supply_errand.js',
'tests/test_llm_configured_supply_store.js',
'tests/test_trade_store_atomicity.js',
'tests/test_supply_trade_lifecycle.js',
'tests/test_llm_skill_priority_tools.js',
'tests/test_llm_equipment_tools.js',
'tests/test_llm_trade_tools.js',
'tests/test_llm_negotiation_tools.js',
'tests/test_bot_merchant_store_negotiation.js',
'tests/test_bot_negotiation_policy.js',
'tests/test_bot_negotiation_flow.js',
'tests/test_bot_negotiation_database.js',
'tests/test_bot_outbound_trade.js',
'tests/test_bot_trade_reservations.js',
'tests/test_bot_trade_atomicity.js',
'tests/test_bot_trade_database.js',
'tests/test_bot_availability.js',
'tests/test_bot_chat_commands.js',
'tests/test_bot_chat_text.js',
'tests/test_bot_name_suggestion.js',
'tests/test_bot_party_chat.js',
'tests/test_bot_agent_support_confirmation.js',
'tests/test_bot_combat_skill_selection.js',
'tests/test_bot_conversation.js',
'tests/test_bot_ambient_director.js',
'tests/test_bot_death_respawn.js',
'tests/test_bot_gear.js',
'tests/test_bot_economy_pricing.js',
Expand All @@ -30,6 +77,7 @@ const tests = [
'tests/test_bot_spot_risk_baseline.js',
'tests/test_bot_persona_party_decision.js',
'tests/test_bot_remote_chat_persona.js',
'tests/test_cold_bot_chat.js',
'tests/test_bot_friendship.js',
'tests/test_bot_goal_planner.js',
'tests/test_bot_goal_market_priority.js',
Expand Down Expand Up @@ -81,6 +129,7 @@ const tests = [
'tests/test_cast_interrupt.js',
'tests/test_character_write_queue.js',
'tests/test_hot_bot_load_test.js',
'tests/test_sqlite_bot_conversation_migration.js',
'tests/test_sqlite_account_casefold.js',
'tests/test_character_status_persistence.js',
'tests/test_change_class.js',
Expand Down
Loading
Loading