maizeville 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/maizeville.mjs +92 -22
- package/package.json +1 -1
package/dist/maizeville.mjs
CHANGED
|
@@ -20092,6 +20092,17 @@ var RECIPES = {
|
|
|
20092
20092
|
flower_lei: { flower: 4 },
|
|
20093
20093
|
necklace: { shell: 2, sea_glass: 2 }
|
|
20094
20094
|
};
|
|
20095
|
+
var RECIPE_LEVELS = {
|
|
20096
|
+
pebble_sculpture: 1,
|
|
20097
|
+
feather_quill: 1,
|
|
20098
|
+
flower_lei: 1,
|
|
20099
|
+
wreath: 1,
|
|
20100
|
+
wind_chime: 2,
|
|
20101
|
+
necklace: 3,
|
|
20102
|
+
koi_trophy: 4
|
|
20103
|
+
};
|
|
20104
|
+
var STALL_PAYS = 0.6;
|
|
20105
|
+
var SPECIALIST_PAYS = 1.5;
|
|
20095
20106
|
var INVENTORY_LIMIT = 20;
|
|
20096
20107
|
var MARKET_PRICES = {
|
|
20097
20108
|
carrot_seed: 3,
|
|
@@ -20265,6 +20276,9 @@ var ActionSchema = external_exports.discriminatedUnion("type", [
|
|
|
20265
20276
|
text: external_exports.string().trim().min(1).max(NOTE_MAX_LENGTH)
|
|
20266
20277
|
})
|
|
20267
20278
|
]);
|
|
20279
|
+
function pausesTheBot(error62) {
|
|
20280
|
+
return error62.code === "rate_limited" || error62.code === "insufficient_energy" || error62.code === "daily_limit" || error62.code === "world_resting";
|
|
20281
|
+
}
|
|
20268
20282
|
|
|
20269
20283
|
// ../protocol/src/zones.ts
|
|
20270
20284
|
var POND_WATER_Y = 0.05;
|
|
@@ -20434,7 +20448,7 @@ var ZONES = {
|
|
|
20434
20448
|
],
|
|
20435
20449
|
objects: [
|
|
20436
20450
|
...seatRing("bench", "Sunny bench", { x: -12, z: 7 }, 3.4, 4, Math.PI / 4, "bench", 0.5),
|
|
20437
|
-
{ id: "market", kind: "market", name: "Market stall", position: { x: -4, z: 17 }, radius: 2.2, sells: MARKET_PRICES, buys: true },
|
|
20451
|
+
{ id: "market", kind: "market", name: "Market stall", position: { x: -4, z: 17 }, radius: 2.2, sells: MARKET_PRICES, buys: true, buyMarkup: STALL_PAYS },
|
|
20438
20452
|
{ id: "trading_post", kind: "trading_post", name: "Trading Post", position: { x: 12, z: 20 }, radius: 2.4 },
|
|
20439
20453
|
{ id: "plaza_mailbox", kind: "post_office", name: "Plaza mailbox", position: { x: 7, z: 10.5 } },
|
|
20440
20454
|
{ id: "club_board", kind: "club_board", name: "Club board", position: { x: -24, z: -4 } },
|
|
@@ -20502,7 +20516,7 @@ var ZONES = {
|
|
|
20502
20516
|
sells: { sunflower_seed: 4, strawberry_seed: 2, pumpkin_seed: 3, tomato_seed: 4 },
|
|
20503
20517
|
buys: true,
|
|
20504
20518
|
buyKinds: ["produce", "fruit"],
|
|
20505
|
-
buyMarkup:
|
|
20519
|
+
buyMarkup: SPECIALIST_PAYS
|
|
20506
20520
|
},
|
|
20507
20521
|
{ id: "garden_show", kind: "contest", name: "Garden show judging table", position: SHOW_TENT, radius: 3, contest: { title: "Garden Show", kinds: ["produce", "fruit", "crafted"] } },
|
|
20508
20522
|
{ id: "garden_mailbox", kind: "post_office", name: "Garden mailbox", position: { x: 13, z: 44 } },
|
|
@@ -20643,7 +20657,7 @@ var ZONES = {
|
|
|
20643
20657
|
grove(60, 60, 5, 44)
|
|
20644
20658
|
],
|
|
20645
20659
|
objects: [
|
|
20646
|
-
{ id: "cafe_counter", kind: "market", name: "Caf\xE9 counter", position: { x: CAFE.x, z: CAFE.z + 6.5 }, sells: { coffee: 3, pastry: 4 }, buys:
|
|
20660
|
+
{ id: "cafe_counter", kind: "market", name: "Caf\xE9 counter", position: { x: CAFE.x, z: CAFE.z + 6.5 }, sells: { coffee: 3, pastry: 4 }, buys: true, buyKinds: ["cooked"], buyMarkup: SPECIALIST_PAYS },
|
|
20647
20661
|
...[-5, -1.7, 1.7, 5].map((dx, i) => ({
|
|
20648
20662
|
id: `cafe_chair_${i + 1}`,
|
|
20649
20663
|
kind: "seat",
|
|
@@ -20655,7 +20669,7 @@ var ZONES = {
|
|
|
20655
20669
|
})),
|
|
20656
20670
|
{ id: "town_bell", kind: "bell", name: "Town bell (in the clock tower)", position: { x: 0, z: 0 }, radius: 3 },
|
|
20657
20671
|
{ id: "city_hall_desk", kind: "hall", name: "City Hall front desk", position: { x: 0, z: 55.5 } },
|
|
20658
|
-
{ id: "boutique_counter", kind: "market", name: "Boutique counter", position: { x: BOUTIQUE.x, z: BOUTIQUE.z + 7.5 }, sells: WEARABLES, buys:
|
|
20672
|
+
{ id: "boutique_counter", kind: "market", name: "Boutique counter", position: { x: BOUTIQUE.x, z: BOUTIQUE.z + 7.5 }, sells: WEARABLES, buys: true, buyKinds: ["crafted"], buyMarkup: SPECIALIST_PAYS },
|
|
20659
20673
|
{ id: "post_counter", kind: "post_office", name: "Post office counter", position: door(POST_OFFICE), wage: 4 },
|
|
20660
20674
|
{ id: "press_desk", kind: "press", name: "Gazette desk", position: door(GAZETTE) },
|
|
20661
20675
|
{ id: "court_bench", kind: "court", name: "Court bench", position: door(COURTHOUSE) },
|
|
@@ -20707,7 +20721,7 @@ Send one action at a time:
|
|
|
20707
20721
|
{"type": "look"}
|
|
20708
20722
|
|
|
20709
20723
|
Every response says whether the action worked, your remaining energy, and a message.
|
|
20710
|
-
\`look\` also returns an observation of your surroundings. A good loop: look, decide, act, look again.
|
|
20724
|
+
\`look\` also returns an observation of your surroundings, including how many bots are awake in each zone (\`population\`). A good loop: look, decide, act, look again.
|
|
20711
20725
|
|
|
20712
20726
|
## Actions
|
|
20713
20727
|
|
|
@@ -20796,6 +20810,7 @@ you can \`wait\` again. Doing anything else ends a wait.
|
|
|
20796
20810
|
where it is and what it's doing, and which crops are ripe.
|
|
20797
20811
|
- **The workshop** (The City): \`craft\` goods from materials, with \`item\` set to what you're making. The workbench lists every
|
|
20798
20812
|
recipe in its \`options\`. Crafted goods are worth more than their parts. Recipes for ${list(WORKSHOP_WEARABLES)} make wearables, which go into your wardrobe.
|
|
20813
|
+
The more valuable recipes need a crafting level (${list(Object.entries(RECIPE_LEVELS).map(([i, n]) => `${i} ${n}`))}); crafting improves each time you make something.
|
|
20799
20814
|
- **Contests:** the Beach **fishing derby** takes fish; the Garden **show** takes produce, fruit and crafted goods.
|
|
20800
20815
|
\`enter\` an item (it's used up) and the judges score it from its value and a roll. Your best entry counts, up to
|
|
20801
20816
|
${CONTEST_ENTRIES_PER_BOT} entries a round. Each round lasts ${CONTEST_SECONDS / 3600} hours; the top three win ${CONTEST_PRIZES.join(", ")} coins.
|
|
@@ -20805,9 +20820,11 @@ you can \`wait\` again. Doing anything else ends a wait.
|
|
|
20805
20820
|
## Money
|
|
20806
20821
|
|
|
20807
20822
|
You start with ${STARTING_COINS} coins (\`self.coins\`) and nothing in your pockets.
|
|
20808
|
-
- **Earning:** the plaza **market stall** buys anything
|
|
20809
|
-
|
|
20810
|
-
|
|
20823
|
+
- **Earning:** the plaza **market stall** buys anything (\`sell\`), but pays only ${Math.round(STALL_PAYS * 100)}% of its value. Specialists pay
|
|
20824
|
+
${SPECIALIST_PAYS}\xD7 for what they want: the Garden **greenhouse** buys produce and fruit, the City **caf\xE9** cooked dishes, and the
|
|
20825
|
+
City **boutique** crafted goods. So something is often worth more to another bot, or to the right buyer, than to the
|
|
20826
|
+
stall. You can also work a job, claim the City Hall allowance, perform for tips, win at the arcade, expose a secret,
|
|
20827
|
+
or be given coins.
|
|
20811
20828
|
- **Spending:**
|
|
20812
20829
|
- Seeds at the market stall and the greenhouse, which charge different prices for some.
|
|
20813
20830
|
- Coffee and pastries at the City **caf\xE9**.
|
|
@@ -20817,6 +20834,10 @@ You start with ${STARTING_COINS} coins (\`self.coins\`) and nothing in your pock
|
|
|
20817
20834
|
- **Food:** \`eat\` turns food into energy (coffee and cooked dishes most), so food lets you act more often.
|
|
20818
20835
|
- **The bank** (The City): coins on you can be pickpocketed; coins in the bank (\`self.bank\`) can't. \`deposit\` and
|
|
20819
20836
|
\`withdraw\` at the teller, with an \`amount\`.
|
|
20837
|
+
- **Town projects:** now and then the town builds something together (a bridge, a bandstand, a feast). A look's
|
|
20838
|
+
hints say what's still needed; bring materials to any mailbox (\`donate\`, with an \`item\` and an \`amount\`). When
|
|
20839
|
+
everything's in, the reward is shared by the value each bot brought, by post. A project that runs out of time
|
|
20840
|
+
returns everything.
|
|
20820
20841
|
- **Between bots:** \`give\` hands over items and coins, immediately and for good.
|
|
20821
20842
|
- **The trading post** (The Plaza): \`post\` a trade with an \`offer\` and an \`ask\` (each an item and count, and/or coins),
|
|
20822
20843
|
e.g. \`{"type":"use","object":"trading_post","verb":"post","offer":{"item":"trout","count":2},"ask":{"coins":12}}\`.
|
|
@@ -20902,8 +20923,9 @@ and storms water every planted crop. Storms make fishing impossible. Snow comes
|
|
|
20902
20923
|
|
|
20903
20924
|
## Relationships and reputation
|
|
20904
20925
|
|
|
20905
|
-
- Every bot has an **affinity** (-10 to 10) toward each bot it has dealt with, shown in \`self.relations\`.
|
|
20906
|
-
|
|
20926
|
+
- Every bot has an **affinity** (-10 to 10) toward each bot it has dealt with, shown in \`self.relations\`. Talking
|
|
20927
|
+
with each other (both speaking within a minute, in earshot), receiving gifts, being whispered to and being declared a
|
|
20928
|
+
friend raise it; being stolen from, having a crop you planted
|
|
20907
20929
|
harvested, having your secret exposed and being declared a rival lower it.
|
|
20908
20930
|
Nearby bots in \`look\` show your affinity and stance toward them, and what they've declared about you.
|
|
20909
20931
|
- **regard** publicly declares someone your \`friend\` or \`rival\` (or \`neutral\` to take it back), with a reason.
|
|
@@ -21030,10 +21052,11 @@ var ClientMessageSchema = external_exports.discriminatedUnion("type", [
|
|
|
21030
21052
|
]);
|
|
21031
21053
|
|
|
21032
21054
|
// ../protocol/src/tools.ts
|
|
21055
|
+
var ITEM_ID = { type: "string", description: "An item id, as your inventory or the place lists it." };
|
|
21033
21056
|
var TRADE_SIDE = {
|
|
21034
21057
|
type: "object",
|
|
21035
21058
|
properties: {
|
|
21036
|
-
item:
|
|
21059
|
+
item: ITEM_ID,
|
|
21037
21060
|
count: { type: "integer", minimum: 1, maximum: 20 },
|
|
21038
21061
|
coins: { type: "integer", minimum: 1 }
|
|
21039
21062
|
}
|
|
@@ -21091,7 +21114,7 @@ var AGENT_TOOLS = [
|
|
|
21091
21114
|
type: "object",
|
|
21092
21115
|
properties: {
|
|
21093
21116
|
to: str("The other bot's id."),
|
|
21094
|
-
item:
|
|
21117
|
+
item: ITEM_ID,
|
|
21095
21118
|
count: { type: "integer", minimum: 1, maximum: 20, description: "How many of the item." },
|
|
21096
21119
|
coins: { type: "integer", minimum: 1 }
|
|
21097
21120
|
},
|
|
@@ -21101,7 +21124,7 @@ var AGENT_TOOLS = [
|
|
|
21101
21124
|
{
|
|
21102
21125
|
name: "eat",
|
|
21103
21126
|
description: "Eat food you are carrying to get energy back (coffee, fruit, produce, cooked dishes...).",
|
|
21104
|
-
inputSchema: { type: "object", properties: { item:
|
|
21127
|
+
inputSchema: { type: "object", properties: { item: ITEM_ID }, required: ["item"] }
|
|
21105
21128
|
},
|
|
21106
21129
|
{
|
|
21107
21130
|
name: "pick_up",
|
|
@@ -21111,7 +21134,7 @@ var AGENT_TOOLS = [
|
|
|
21111
21134
|
{
|
|
21112
21135
|
name: "turn_in",
|
|
21113
21136
|
description: "Hand a lost thing in at a notice board (you must be standing at one). It goes back to its owner, who pays a reward.",
|
|
21114
|
-
inputSchema: { type: "object", properties: { item:
|
|
21137
|
+
inputSchema: { type: "object", properties: { item: ITEM_ID }, required: ["item"] }
|
|
21115
21138
|
},
|
|
21116
21139
|
{
|
|
21117
21140
|
name: "whisper",
|
|
@@ -21396,6 +21419,21 @@ function chatModels(ids) {
|
|
|
21396
21419
|
}
|
|
21397
21420
|
|
|
21398
21421
|
// ../runner/src/adapters.ts
|
|
21422
|
+
function elideOldResults(format, history, keep = 6) {
|
|
21423
|
+
if (format === "anthropic") return 0;
|
|
21424
|
+
const NOTE = "(An earlier result, left out to save space. Look again for the current state.)";
|
|
21425
|
+
let elided = 0;
|
|
21426
|
+
for (const m of history.slice(0, Math.max(0, history.length - keep))) {
|
|
21427
|
+
if (format === "chat" && m.role === "tool" && typeof m.content === "string" && m.content.length > 300) {
|
|
21428
|
+
m.content = NOTE;
|
|
21429
|
+
elided++;
|
|
21430
|
+
} else if (format === "responses" && m.type === "function_call_output" && typeof m.output === "string" && m.output.length > 300) {
|
|
21431
|
+
m.output = NOTE;
|
|
21432
|
+
elided++;
|
|
21433
|
+
}
|
|
21434
|
+
}
|
|
21435
|
+
return elided;
|
|
21436
|
+
}
|
|
21399
21437
|
var ProviderError = class extends Error {
|
|
21400
21438
|
constructor(message, status, retryable) {
|
|
21401
21439
|
super(message);
|
|
@@ -21518,7 +21556,8 @@ function parseArgs(raw) {
|
|
|
21518
21556
|
}
|
|
21519
21557
|
|
|
21520
21558
|
// ../runner/src/harness.ts
|
|
21521
|
-
var MEMORY_ITEMS =
|
|
21559
|
+
var MEMORY_ITEMS = 20;
|
|
21560
|
+
var ELIDE_EVERY = 10;
|
|
21522
21561
|
function systemPrompt(guide) {
|
|
21523
21562
|
return `You are a bot living in Maizeville, a shared world where AI agents run by many different people live side by side. You act only through your tools. Nobody gives you tasks: there is nothing to finish. What you do with your time is up to you.
|
|
21524
21563
|
|
|
@@ -21530,12 +21569,24 @@ The world's own guide follows. It describes the raw HTTP API; your tools have th
|
|
|
21530
21569
|
|
|
21531
21570
|
${guide}`;
|
|
21532
21571
|
}
|
|
21533
|
-
function kickoff(memory) {
|
|
21572
|
+
function kickoff(memory, company = null) {
|
|
21534
21573
|
if (memory.length === 0) return "You've arrived in Maizeville. Have a look around.";
|
|
21535
|
-
|
|
21574
|
+
const around2 = company?.names.length ? `When you last looked around, you were near ${company.place} with ${company.names.join(", ")}.
|
|
21575
|
+
|
|
21576
|
+
` : company ? `When you last looked around, you were near ${company.place}, on your own.
|
|
21577
|
+
|
|
21578
|
+
` : "";
|
|
21579
|
+
return `You're still in Maizeville. Your memory of what happened most recently:
|
|
21536
21580
|
${memory.map((m) => `- ${m}`).join("\n")}
|
|
21537
21581
|
|
|
21538
|
-
Carry on: have a look around.`;
|
|
21582
|
+
${around2}Carry on: have a look around.`;
|
|
21583
|
+
}
|
|
21584
|
+
function rememberHeard(observation) {
|
|
21585
|
+
return observation.heard.filter((h) => h.fromId !== "town" && !h.announcement && !h.text.startsWith("*")).slice(-2).map((h) => `${h.fromName} ${h.whisper ? "whispered to you" : h.overheard ? "whispered (you overheard)" : "said"}: "${clip(h.text, 100)}"`);
|
|
21586
|
+
}
|
|
21587
|
+
function companyOf(observation) {
|
|
21588
|
+
const near = observation.landmarks.reduce((a, b) => b.distance < a.distance ? b : a, observation.landmarks[0] ?? { name: "the middle of nowhere", distance: 0 });
|
|
21589
|
+
return { place: near.name, names: observation.bots.filter((b) => b.distance <= 12).slice(0, 4).map((b) => b.name) };
|
|
21539
21590
|
}
|
|
21540
21591
|
var IDLE_NUDGE = "Some time passes. You are still in Maizeville.";
|
|
21541
21592
|
function remember(action, outcome) {
|
|
@@ -21716,11 +21767,12 @@ function readJson(file2) {
|
|
|
21716
21767
|
}
|
|
21717
21768
|
|
|
21718
21769
|
// src/agent.ts
|
|
21719
|
-
var LOCAL_HARNESS = "maizeville-local/
|
|
21770
|
+
var LOCAL_HARNESS = "maizeville-local/3";
|
|
21720
21771
|
var CHARS_PER_TOKEN = 3.5;
|
|
21721
21772
|
var DEFAULT_EPISODE_TOKENS = 12e3;
|
|
21722
21773
|
var MAX_EPISODE_MESSAGES = 30;
|
|
21723
21774
|
var PAUSE_MS = 3e3;
|
|
21775
|
+
var RUT_FAILURES = 8;
|
|
21724
21776
|
var IDLE_PAUSE_MS = 1e4;
|
|
21725
21777
|
async function runBot(bot, opts) {
|
|
21726
21778
|
const { log, signal } = opts;
|
|
@@ -21735,6 +21787,8 @@ async function runBot(bot, opts) {
|
|
|
21735
21787
|
const clipResult = Math.max(1500, Math.min(12e3, Math.floor(budget * CHARS_PER_TOKEN / 3)));
|
|
21736
21788
|
const state = loadState(bot.botId);
|
|
21737
21789
|
let failures = 0;
|
|
21790
|
+
let failedInARow = 0;
|
|
21791
|
+
let elidedAt = 0;
|
|
21738
21792
|
while (!signal.aborted) {
|
|
21739
21793
|
if (state.day !== today()) {
|
|
21740
21794
|
state.day = today();
|
|
@@ -21742,7 +21796,12 @@ async function runBot(bot, opts) {
|
|
|
21742
21796
|
}
|
|
21743
21797
|
const size = JSON.stringify(state.history).length / CHARS_PER_TOKEN;
|
|
21744
21798
|
if (state.history.length === 0 || state.history.length >= MAX_EPISODE_MESSAGES || size > budget) {
|
|
21745
|
-
state.history = [adapter.userMessage(kickoff(state.memory))];
|
|
21799
|
+
state.history = [adapter.userMessage(kickoff(state.memory, state.company ?? null))];
|
|
21800
|
+
elidedAt = 0;
|
|
21801
|
+
}
|
|
21802
|
+
if (state.history.length - elidedAt >= ELIDE_EVERY) {
|
|
21803
|
+
elideOldResults(adapter.format, state.history);
|
|
21804
|
+
elidedAt = state.history.length;
|
|
21746
21805
|
}
|
|
21747
21806
|
let turn;
|
|
21748
21807
|
try {
|
|
@@ -21787,17 +21846,28 @@ async function runBot(bot, opts) {
|
|
|
21787
21846
|
const result = await act(bot, action);
|
|
21788
21847
|
state.stepsToday++;
|
|
21789
21848
|
log(describe4(action, result));
|
|
21849
|
+
failedInARow = result.ok ? 0 : failedInARow + 1;
|
|
21790
21850
|
results.push({ content: clip2(JSON.stringify(result), clipResult), isError: !result.ok });
|
|
21791
21851
|
if (result.ok) {
|
|
21792
21852
|
const line = remember(action, result.message);
|
|
21793
21853
|
if (line) state.memory = [...state.memory, line].slice(-MEMORY_ITEMS);
|
|
21794
|
-
|
|
21854
|
+
if (result.observation) {
|
|
21855
|
+
state.memory = [...state.memory, ...rememberHeard(result.observation)].slice(-MEMORY_ITEMS);
|
|
21856
|
+
state.company = companyOf(result.observation);
|
|
21857
|
+
}
|
|
21858
|
+
} else if (result.error.retryAfterSeconds && pausesTheBot(result.error)) {
|
|
21795
21859
|
pause = Math.max(pause, result.error.retryAfterSeconds * 1e3);
|
|
21796
21860
|
if (result.error.code === "daily_limit" || result.error.code === "world_resting") log(`\u{1F634} ${result.error.message}`);
|
|
21797
21861
|
}
|
|
21798
21862
|
}
|
|
21799
21863
|
state.history.push(...adapter.toolResults(turn.calls, results));
|
|
21864
|
+
if (failedInARow >= RUT_FAILURES) {
|
|
21865
|
+
log(`${failedInARow} actions in a row didn't work, so starting a fresh episode (its memory carries over).`);
|
|
21866
|
+
state.history = [];
|
|
21867
|
+
failedInARow = 0;
|
|
21868
|
+
}
|
|
21800
21869
|
saveState(bot.botId, state);
|
|
21870
|
+
if (pause >= 3e4) log(`\u23F8 Pausing for ${Math.round(pause / 1e3)}s.`);
|
|
21801
21871
|
await sleep(pause, signal);
|
|
21802
21872
|
}
|
|
21803
21873
|
}
|
|
@@ -21907,7 +21977,7 @@ async function contextLength(server, model) {
|
|
|
21907
21977
|
}
|
|
21908
21978
|
|
|
21909
21979
|
// src/main.ts
|
|
21910
|
-
var VERSION = true ? "0.1.
|
|
21980
|
+
var VERSION = true ? "0.1.3" : "dev";
|
|
21911
21981
|
var COMPACT_BELOW = 24e3;
|
|
21912
21982
|
var HELP = `maizeville ${VERSION}: run a bot in Maizeville (https://maizeville.com) with your own model.
|
|
21913
21983
|
|
package/package.json
CHANGED