Skip to content

feat(agent-world): add TinyPlace world and GraphQL reads#3867

Merged
senamakel merged 10 commits into
tinyhumansai:mainfrom
senamakel:feat/tinyplace-world-graphql
Jun 21, 2026
Merged

feat(agent-world): add TinyPlace world and GraphQL reads#3867
senamakel merged 10 commits into
tinyhumansai:mainfrom
senamakel:feat/tinyplace-world-graphql

Conversation

@senamakel

@senamakel senamakel commented Jun 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds a TinyPlace World sidebar page that mounts the Pixi isometric city renderer inside Agent World.
  • Updates the Rust tinyplace SDK dependency to 1.0.1.
  • Adds internal OpenHuman GraphQL controllers for agents, products, identity listings, bids, offers, and sales.
  • Moves high-volume Agent World reads for directory, explore, marketplace, and identities onto GraphQL-backed requests to reduce REST fan-out and 429 pressure.
  • Updates focused page unit tests and locale coverage for the new World sidebar entry.

Problem

Agent World's TinyPlace sidebar needed the new city rendering page from tiny.place, and several pages still used REST list calls or per-card follow/stat requests that could fan out into many backend requests and trigger 429s. The tinyplace Rust SDK API shape also changed in 1.0.1, so OpenHuman's bridge needed to compile and operate against that newer contract.

Solution

  • Ported the Pixi isometric world renderer into app/src/agentworld/iso and mounted it from a new WorldSection route.
  • Added agentWorld.world translations across locale files and made /agent-world default to the world page.
  • Exposed new GraphQL tinyplace controllers in Rust and normalized richer GraphQL response shapes at the renderer API boundary.
  • Switched Directory, Explore, Marketplace, and Identities read paths to GraphQL where the tiny.place website does the same.
  • Removed Directory per-card follow stats/list fan-out and uses server-resolved viewerIsFollowing edges when available.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/pr-ci.yml. Local full coverage not run; CI will enforce this gate.
  • Coverage matrix updated — N/A: existing Agent World/TinyPlace surfaces were extended; focused page/unit coverage updated without adding a new matrix-owned feature row.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related: N/A, no new/renamed feature ID.
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces: N/A, no release manual smoke checklist change required for this Agent World sidebar/internal bridge update.
  • Linked issue closed via Closes #NNN in the ## Related section: N/A, no linked issue provided.

Impact

  • Desktop renderer: adds a new TinyPlace World page under Agent World.
  • Rust core/Tauri bridge: uses tinyplace crate 1.0.1 and exposes additional internal GraphQL read controllers.
  • Backend request behavior: list/read pages now batch through GraphQL for directory/products/jobs/bounties/identity listings, reducing request fan-out.
  • Compatibility: writes remain on existing REST/x402 flows; GraphQL read responses are normalized for existing UI consumers.

Related

  • Closes: N/A
  • Follow-up PR(s)/TODOs: Add broader E2E smoke coverage for the Agent World World page once the web/Tauri E2E harness has a stable TinyPlace mock flow for Pixi canvas assertions.

AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/tinyplace-world-graphql
  • Commit SHA: 0ef340a

Validation Run

  • pnpm --filter openhuman-app format:check via pnpm format:check
  • pnpm typecheck
  • Focused tests: pnpm debug unit src/agentworld/pages/DirectorySection.test.tsx src/agentworld/pages/ExploreSection/ExploreSection.test.tsx src/agentworld/pages/MarketplaceSection.test.tsx; pnpm debug unit src/agentworld/pages/IdentitiesSection.test.tsx
  • Rust fmt/check (if changed): cargo fmt --manifest-path Cargo.toml; cargo check --manifest-path Cargo.toml
  • Tauri fmt/check (if changed): pre-push pnpm rust:check / cargo check --manifest-path app/src-tauri/Cargo.toml
  • Additional: pnpm lint, pnpm i18n:check, pnpm build during implementation

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: TinyPlace sidebar opens to a Pixi world view and high-volume Agent World reads use GraphQL bridge requests.
  • User-visible effect: Users can enter the TinyPlace world page from Agent World; directory/marketplace/explore/identity pages should make fewer backend requests.

Parity Contract

  • Legacy behavior preserved: Existing write flows, x402 buy/register/bid/offer flows, and REST-backed write endpoints remain unchanged.
  • Guard/fallback/dispatch parity checks: GraphQL bridge normalizes product/listing people fields back to current UI-facing string shapes; tests cover happy/error/payment/empty branches for moved pages.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): None found for senamakel:feat/tinyplace-world-graphql.
  • Canonical PR: This PR.
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

Release Notes

  • New Features

    • Added an interactive isometric World simulation with selectable agents, path routing, furniture seating, and animated speech bubbles.
    • Added multiple rooms (poker, court, office, home, outside) with modular furniture and seat/interaction points.
    • Outside room now includes moving street traffic and avoids collisions with standing humans.
  • Documentation

    • Added new multilingual translations for the World navigation, booting status, and room descriptions.
  • Tests / Chores

    • Updated GraphQL-backed UI/API loading and corresponding test coverage; updated the tinyplace dependency.

@senamakel senamakel requested a review from a team June 21, 2026 04:44
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a complete PixiJS isometric agent world engine (app/src/agentworld/iso/) with geometry, procedural textures, furniture, five room definitions, BFS pathfinding, animated agents, and a GameWorld orchestrator. Integrates it as a new "World" default section in AgentWorld. Simultaneously migrates Directory, Explore, Identities, and Marketplace sections from REST-style to GraphQL endpoints, adding matching Rust backend handlers, TypeScript client methods, and normalization helpers. Consolidates wallet test setup utilities.

Changes

Isometric World Engine and React Integration

Layer / File(s) Summary
Geometry, types, and color utilities
app/src/agentworld/iso/geometry.ts, app/src/agentworld/iso/types.ts, app/src/agentworld/iso/color.ts
Isometric tile/screen projection math, layer depth constants, all shared TypeScript types (TileCode, Facing, AgentAction, WalkNode, AgentState, RoomDefinition, etc.), and RGB color mixing/shading helpers.
Procedural texture generation
app/src/agentworld/iso/textures.ts
TextureFactory bakes and caches all greyscale Pixi textures (floor, road, cuboid, wall, building detail, chair, agent body/face/shadow/accessories, chat bubble background/tail) using nearest-sampled Graphics rendered once.
Furniture data model and rendering
app/src/agentworld/iso/furniture.ts
FurniturePart/FurnitureBlueprint data model, FURNITURE_BLUEPRINTS registry for all furniture kinds, and FurnitureSprite class that instantiates per-kind sprites and exposes footprint/seat/station tile queries.
BaseRoom: tile construction and BFS pathfinding
app/src/agentworld/iso/BaseRoom.ts
Abstract BaseRoom converts RoomDefinition tile matrices into Pixi layers, populates walkability/seat/station maps, records DepthObstacle regions, computes pixel bounds, and implements constrained BFS pathfinding with diagonal-cut and elevation rules.
Room definitions and registry
app/src/agentworld/iso/rooms.ts
Matrix authoring utilities, five RoomPalette constants, five concrete room definitions (Poker, Court, Office, Home, OutsideWorld with deterministic procedural city generation), five BaseRoom subclasses, and ROOM_REGISTRY.
Agent entity and ChatBubble
app/src/agentworld/iso/Agent.ts, app/src/agentworld/iso/ChatBubble.ts
Agent composes shadow/body/face/accessory/nameplate sprites, queues walkPath segments, interpolates movement per tick, and applies pose/depth. ChatBubble runs a pop-in → hold → fade-out phase state machine with dismiss() support.
GameWorld orchestrator
app/src/agentworld/iso/GameWorld.ts
Top-level PixiJS controller: WebGPU init, room management with depth-sorted rendering, authoritative agent reconciliation via updateAgentState with pathfinding, chat bubble lifecycle, road traffic simulation, tap-to-select/tap-to-route pointer handling, and resize/scale management.
React integration, routing, i18n, and config
app/src/agentworld/pages/WorldSection.tsx, app/src/agentworld/pages/AgentWorld.tsx, app/src/agentworld/pages/AgentWorld.test.tsx, app/src/agentworld/iso/index.ts, app/src/lib/i18n/*, app/test/vitest.config.ts
WorldSection mounts GameWorld with room-switching and agent-spawning UI; AgentWorld adds world as default section with frameless layout and updated routing; i18n key agentWorld.world added in 13 locales; iso paths excluded from jsdom coverage.

GraphQL API Surface Expansion

Layer / File(s) Summary
TypeScript GraphQL interfaces and normalization helpers
app/src/lib/agentworld/invokeApiClient.ts
Adds GqlAgentCardListResult, GqlProduct, GqlIdentityListing, GqlIdentityOffer, GqlIdentitySale and list-result wrappers, plus normalization helpers that rewrite GraphQL author objects into REST-like seller/sellerCryptoId/buyer fields.
GraphQL client methods and tests
app/src/lib/agentworld/invokeApiClient.ts, app/src/lib/agentworld/invokeApiClient.test.ts
Adds graphql.agents; updates graphql.products/product to normalize results; adds graphql.identityListings, identityListing, identityBids, identityOffers, identitySales. Tests cover routing, seller normalization, nullable detail handling, and buyer/seller party shapes.
Rust GraphQL handlers, schemas, and Cargo version bump
src/openhuman/tinyplace/manifest.rs, src/openhuman/tinyplace/schemas.rs, Cargo.toml
Adds eight Rust RPC handler functions for GraphQL agents/products/identity-marketplace endpoints with params parsing and degrade helpers; registers all new schemas; fixes public_key/viewer_is_following/actor_type fields in agent card construction; bumps tinyplace crate to 1.0.1.
Frontend section migrations to GraphQL
app/src/agentworld/pages/DirectorySection.*, app/src/agentworld/pages/ExploreSection/*, app/src/agentworld/pages/IdentitiesSection.*, app/src/agentworld/pages/MarketplaceSection.*
Migrates DirectorySection (per-card viewerIsFollowing instead of batched followingSet), ExploreSection (bounties and agents), IdentitiesSection (listings and floor price), and MarketplaceSection (products and jobs) to GraphQL endpoints, with all matching test updates.

Wallet Test Infrastructure Cleanup

Layer / File(s) Summary
Wallet test consolidation and env lock guards
src/openhuman/wallet/execution_tests.rs, src/openhuman/wallet/ops.rs
Removes local setup_wallet_in and TEST_LOCK from execution_tests.rs, importing from shared test_support; adds TEST_ENV_LOCK guards to two reveal_recovery_phrase tests to prevent parallel interference.

Sequence Diagram(s)

sequenceDiagram
  participant WorldSection
  participant GameWorld
  participant BaseRoom
  participant Agent
  participant TextureFactory

  WorldSection->>GameWorld: init(containerElement)
  GameWorld->>TextureFactory: new TextureFactory(renderer)
  WorldSection->>GameWorld: setRoom("outside")
  GameWorld->>BaseRoom: new OutsideWorldRoom(factory)
  BaseRoom->>TextureFactory: floorTile(), cuboid(), wallBlock(), buildingDetail()
  BaseRoom-->>GameWorld: view, depthObstacles(), findPath()
  WorldSection->>GameWorld: spawnAgents(count)
  GameWorld->>Agent: new Agent(options)
  Agent->>TextureFactory: agentBody(), agentFace(), accessory(), agentShadow()
  GameWorld->>Agent: teleportTo(spawnNode)
  loop Ticker
    GameWorld->>Agent: tick(deltaSeconds)
    Agent->>Agent: advanceMovement / applyPose / syncPosition
    GameWorld->>GameWorld: depth-sort agents vs depthObstacles
  end
  WorldSection->>GameWorld: updateAgentState(state)
  GameWorld->>BaseRoom: findPath(current, target)
  BaseRoom-->>GameWorld: Array<WalkNode>
  GameWorld->>Agent: walkPath(path, arrivalAction, facing, seatDropY)
Loading
sequenceDiagram
  participant FrontendSection
  participant invokeApiClient
  participant RustHandler
  participant TinyplaceGraphQL

  FrontendSection->>invokeApiClient: graphql.agents(params)
  invokeApiClient->>RustHandler: openhuman.tinyplace_graphql_agents({params})
  RustHandler->>TinyplaceGraphQL: GraphQL query
  TinyplaceGraphQL-->>RustHandler: agent list JSON
  RustHandler-->>invokeApiClient: GqlAgentCardListResult
  invokeApiClient-->>FrontendSection: typed agent list

  FrontendSection->>invokeApiClient: graphql.identityListings({limit:50})
  invokeApiClient->>RustHandler: openhuman.tinyplace_graphql_identity_listings
  RustHandler->>TinyplaceGraphQL: identity listings query
  TinyplaceGraphQL-->>RustHandler: listings JSON
  RustHandler-->>invokeApiClient: raw listings
  invokeApiClient->>invokeApiClient: normalizeGraphqlIdentityListing(each)
  invokeApiClient-->>FrontendSection: GqlIdentityListingListResult
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • tinyhumansai/openhuman#3780: Established the native tiny.place Agent World GraphQL integration that this PR's section migrations (Directory, Explore, Marketplace) build directly upon.
  • tinyhumansai/openhuman#3839: Both PRs modify app/src/agentworld/pages/ExploreSection (Featured Bounties/New Agents live subsections and data-fetching + filtering logic).

Suggested reviewers

  • graycyrus
  • sanil-23

Poem

🐇 Hop, hop through isometric tiles,
The rabbit builds rooms across pixel miles.
GraphQL queries now zip through the air,
REST endpoints fade — no longer there.
Agents walk paths with a bounce and a bow,
The world section blooms — watch the garden grow! 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 49.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary changes: adding a TinyPlace World page and implementing GraphQL reads for backend optimization.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ebd8ff3a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/lib/agentworld/invokeApiClient.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 313c04644e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/DirectorySection.tsx
Comment thread app/src/agentworld/pages/WorldSection.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
app/src/agentworld/iso/types.ts (1)

113-113: Extract spawnTile into a named interface.

Line 113 uses an inline object shape; this violates the repo TypeScript rule requiring interfaces for object-shape declarations.

♻️ Proposed fix
+export interface SpawnTile {
+  x: number;
+  y: number;
+}
+
 export interface RoomDefinition {
   key: string;
   name: string;
   description: string;
@@
-  spawnTile: { x: number; y: number };
+  spawnTile: SpawnTile;
   /** Extra vertical clearance above the floor for tall props (buildings). */
   topMargin?: number;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/iso/types.ts` at line 113, The spawnTile property on line
113 uses an inline object type definition ({ x: number; y: number }) which
violates the repo's TypeScript rule requiring named interfaces for object
shapes. Create a new named interface for the coordinate/position type that
defines the x and y number properties, then replace the inline object type in
the spawnTile declaration with a reference to this new interface.

Sources: Coding guidelines, Learnings

app/src/agentworld/iso/BaseRoom.ts (1)

76-77: ⚡ Quick win

Use named interfaces instead of inline object-shape types.

These ranges introduce inline object-shape annotations (e.g., size/bounds/queue node). Please extract named interfaces to align with the TypeScript style contract and keep types reusable.

As per coding guidelines, **/*.{ts,tsx} requires interface for defining object shapes.

Also applies to: 264-265, 305-306, 378-380

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/iso/BaseRoom.ts` around lines 76 - 77, The BaseRoom class
contains inline object-shape type annotations (such as the size property with {
width: number; height: number }) that should be extracted into named interfaces
for reusability and alignment with TypeScript style guidelines. Create named
interfaces for each distinct object shape (like for size, bounds, and queue node
types), and then replace all inline type annotations with references to these
newly created interfaces throughout the BaseRoom class, including at the
properties around lines 264-265, 305-306, and 378-380.

Source: Coding guidelines

app/src/agentworld/iso/furniture.ts (2)

64-74: ⚡ Quick win

Replace inline object-shape type annotations with named interfaces.

Lines in these ranges define object shapes inline (options: { ... }, Array<{ x: number; y: number }>). Please promote these to named interfaces for consistency with the repo’s TypeScript rules.

♻️ Suggested direction
+interface BuildingBlueprintOptions {
+  footprintWidth: number;
+  footprintHeight: number;
+  height: number;
+  bodyTint: number;
+  windowRows: number;
+  windowColumns: number;
+  windowColor: number;
+  roofColor: number;
+  doorColor: number;
+}
+
+interface TableBlueprintOptions {
+  footprintWidth: number;
+  footprintHeight: number;
+  height: number;
+  bodyTint: number;
+  topTint: number;
+  extraParts?: Array<FurniturePart>;
+}
+
+interface TileCoord {
+  x: number;
+  y: number;
+}
-
-function buildingBlueprint(options: { ... }): FurnitureBlueprint {
+function buildingBlueprint(options: BuildingBlueprintOptions): FurnitureBlueprint {
   ...
 }
-
-function tableBlueprint(options: { ... }): FurnitureBlueprint {
+function tableBlueprint(options: TableBlueprintOptions): FurnitureBlueprint {
   ...
 }
-
-public footprintTiles(): Array<{ x: number; y: number }> {
+public footprintTiles(): Array<TileCoord> {
   ...
 }

As per coding guidelines, **/*.{ts,tsx} should use interface for defining object shapes.

Also applies to: 105-112, 869-893

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/iso/furniture.ts` around lines 64 - 74, The
buildingBlueprint function and other functions in the specified ranges (105-112
and 869-893) are using inline object type annotations instead of named
interfaces. Create separate named interfaces for each of these object shapes
(the options parameter for buildingBlueprint and any other inline object types
in the mentioned ranges), then replace the inline type definitions with
references to these new interfaces. This ensures consistency with the
repository's TypeScript coding guidelines.

Source: Coding guidelines


1-900: 🏗️ Heavy lift

Split furniture.ts; it exceeds the frontend file-size limit.

This file is ~900 lines, which is well above the frontend size cap and is now mixing blueprint catalog + rendering logic in one module. Please split it (for example: blueprints.ts, blueprintBuilders.ts, FurnitureSprite.ts) to keep module boundaries maintainable.

As per coding guidelines, frontend files under app/src/**/*.{ts,tsx} should stay at or below ~500 lines and be broken into smaller focused modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/iso/furniture.ts` around lines 1 - 900, The furniture.ts
file is approximately 900 lines, exceeding the 500-line frontend file-size limit
and mixing blueprint catalog definitions with rendering logic. Split the file
into focused modules: move the FURNITURE_BLUEPRINTS record and constant
definitions (WOOD_DARK, WOOD_MID, FELT_GREEN) into a blueprints.ts file; move
the blueprint builder helper functions (buildingBlueprint, tableBlueprint, sit)
into a blueprintBuilders.ts file; keep the FurnitureSprite class,
FurnitureStation interface, and related types (FurniturePart,
FurnitureBlueprint) in the main furniture.ts or a separate FurnitureSprite.ts
file. Update all import statements in these new modules to reference each other
correctly and ensure they are properly exported for use by other modules that
depend on them.

Source: Coding guidelines

app/src/agentworld/pages/MarketplaceSection.test.tsx (1)

145-145: ⚡ Quick win

Assert the jobs-query payload, not just invocation.

This currently misses regressions where { limit: 50 } is dropped/changed. Assert the call args to lock the frontend↔client contract.

Proposed test hardening
-    expect(apiClient.graphql.jobs).toHaveBeenCalled();
+    expect(apiClient.graphql.jobs).toHaveBeenCalledWith({ limit: 50 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/pages/MarketplaceSection.test.tsx` at line 145, The test
currently only asserts that apiClient.graphql.jobs was called but does not
verify the arguments passed to it. Replace the toHaveBeenCalled() assertion on
apiClient.graphql.jobs with toHaveBeenCalledWith() and pass the expected query
payload (specifically { limit: 50 }) as the argument to ensure the
frontend↔client contract is properly locked and regressions where the limit
parameter is dropped or modified are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/agentworld/iso/BaseRoom.ts`:
- Around line 377-423: The BFS pathfinding algorithm is performing avoidable
quadratic work through two inefficiencies: queue.shift() is O(n) per operation,
and the path array is being cloned for each neighbor expansion with
[...current.path, next]. Replace the array-based queue with an index-based
approach using a pointer variable to track the current position instead of
calling shift(). Additionally, create a predecessor map that tracks which
node/position led to each visited tile, then construct the final path only once
when reaching the terminal destination by walking backwards through the
predecessor map instead of cloning the path array at each step.

In `@app/src/agentworld/iso/GameWorld.ts`:
- Around line 545-560: The arrival check at line 558 comparing startX ===
state.x and startY === state.y uses rounded coordinates, which causes the agent
to stop prematurely during interpolation before reaching the tile center. Remove
the rounding operations on start.x and start.y when creating the comparison
values, or alternatively modify the comparison logic to use a threshold-based
approach that checks if the agent is sufficiently close to the actual target
coordinates rather than exact matches. Apply the same fix to the similar arrival
checks mentioned in lines 562-565.
- Around line 177-1004: The GameWorld class exceeds the project guideline of
~500 lines for frontend files. Extract traffic management, pointer input
handling, and resize management into separate dedicated modules. Create
TrafficController to handle clearTraffic, spawnTraffic, addCar,
spawnReplacementCar, positionCar, carBlocked, updateTraffic and related fields
(cars, lanes, trafficLength). Create PointerController to handle onPointerDown,
onPointerMove, onPointerUp, handleTap and related pointer state fields
(pointerActive, pointerMoved, lastPointerX, lastPointerY). Create
ResizeController to handle observeResize, applySize and related fields
(resizeObserver, fillMode, panRangeX, panRangeY). Have GameWorld instantiate and
delegate to these controllers, passing necessary dependencies like the room,
agents, camera, and world containers to each controller.

In `@app/src/agentworld/iso/textures.ts`:
- Around line 57-63: The texture generation is using antialias: true which bakes
smoothing into the pixel rasterization, and setting texture.source.scaleMode =
'nearest' afterward cannot undo this smoothing. To achieve the crisp/chunky
pixel rendering intended by the code, change the antialias property from true to
false in the renderer.generateTexture() call to disable antialiasing at
generation time rather than attempting to compensate with scale mode adjustments
afterward.

In `@app/src/agentworld/pages/IdentitiesSection.tsx`:
- Around line 145-150: The identityListings API call in the floor-price lookup
is missing a status filter constraint, allowing inactive listings to be returned
and causing incorrect floor price calculations. Modify the parameters passed to
apiClient.graphql.identityListings to add a status constraint that filters for
only active listings. This will ensure the floor price lookup only considers
tradable listings when determining the minimum price.

In `@src/openhuman/tinyplace/schemas.rs`:
- Around line 2441-2442: The schema documentation for AgentQueryParams near the
string starting with "Optional AgentQueryParams..." lists pagination parameters
(`offset`) that don't match the frontend's actual pagination contract, which
uses `cursor`. Update this schema documentation string to replace `offset` with
`cursor` to accurately reflect the expected parameters that schema-discovery
clients should use when generating pagination calls.

---

Nitpick comments:
In `@app/src/agentworld/iso/BaseRoom.ts`:
- Around line 76-77: The BaseRoom class contains inline object-shape type
annotations (such as the size property with { width: number; height: number })
that should be extracted into named interfaces for reusability and alignment
with TypeScript style guidelines. Create named interfaces for each distinct
object shape (like for size, bounds, and queue node types), and then replace all
inline type annotations with references to these newly created interfaces
throughout the BaseRoom class, including at the properties around lines 264-265,
305-306, and 378-380.

In `@app/src/agentworld/iso/furniture.ts`:
- Around line 64-74: The buildingBlueprint function and other functions in the
specified ranges (105-112 and 869-893) are using inline object type annotations
instead of named interfaces. Create separate named interfaces for each of these
object shapes (the options parameter for buildingBlueprint and any other inline
object types in the mentioned ranges), then replace the inline type definitions
with references to these new interfaces. This ensures consistency with the
repository's TypeScript coding guidelines.
- Around line 1-900: The furniture.ts file is approximately 900 lines, exceeding
the 500-line frontend file-size limit and mixing blueprint catalog definitions
with rendering logic. Split the file into focused modules: move the
FURNITURE_BLUEPRINTS record and constant definitions (WOOD_DARK, WOOD_MID,
FELT_GREEN) into a blueprints.ts file; move the blueprint builder helper
functions (buildingBlueprint, tableBlueprint, sit) into a blueprintBuilders.ts
file; keep the FurnitureSprite class, FurnitureStation interface, and related
types (FurniturePart, FurnitureBlueprint) in the main furniture.ts or a separate
FurnitureSprite.ts file. Update all import statements in these new modules to
reference each other correctly and ensure they are properly exported for use by
other modules that depend on them.

In `@app/src/agentworld/iso/types.ts`:
- Line 113: The spawnTile property on line 113 uses an inline object type
definition ({ x: number; y: number }) which violates the repo's TypeScript rule
requiring named interfaces for object shapes. Create a new named interface for
the coordinate/position type that defines the x and y number properties, then
replace the inline object type in the spawnTile declaration with a reference to
this new interface.

In `@app/src/agentworld/pages/MarketplaceSection.test.tsx`:
- Line 145: The test currently only asserts that apiClient.graphql.jobs was
called but does not verify the arguments passed to it. Replace the
toHaveBeenCalled() assertion on apiClient.graphql.jobs with
toHaveBeenCalledWith() and pass the expected query payload (specifically {
limit: 50 }) as the argument to ensure the frontend↔client contract is properly
locked and regressions where the limit parameter is dropped or modified are
caught.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e632f46e-5113-44c1-a9a5-3f5540e0dc4b

📥 Commits

Reviewing files that changed from the base of the PR and between 35b7073 and 8111690.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • app/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (44)
  • Cargo.toml
  • app/src/agentworld/iso/Agent.ts
  • app/src/agentworld/iso/BaseRoom.ts
  • app/src/agentworld/iso/ChatBubble.ts
  • app/src/agentworld/iso/GameWorld.ts
  • app/src/agentworld/iso/color.ts
  • app/src/agentworld/iso/furniture.ts
  • app/src/agentworld/iso/geometry.ts
  • app/src/agentworld/iso/index.ts
  • app/src/agentworld/iso/rooms.ts
  • app/src/agentworld/iso/textures.ts
  • app/src/agentworld/iso/types.ts
  • app/src/agentworld/pages/AgentWorld.test.tsx
  • app/src/agentworld/pages/AgentWorld.tsx
  • app/src/agentworld/pages/DirectorySection.test.tsx
  • app/src/agentworld/pages/DirectorySection.tsx
  • app/src/agentworld/pages/ExploreSection/ExploreSection.test.tsx
  • app/src/agentworld/pages/ExploreSection/index.tsx
  • app/src/agentworld/pages/IdentitiesSection.test.tsx
  • app/src/agentworld/pages/IdentitiesSection.tsx
  • app/src/agentworld/pages/MarketplaceSection.test.tsx
  • app/src/agentworld/pages/MarketplaceSection.tsx
  • app/src/agentworld/pages/WorldSection.tsx
  • app/src/lib/agentworld/invokeApiClient.test.ts
  • app/src/lib/agentworld/invokeApiClient.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • app/test/vitest.config.ts
  • src/openhuman/tinyplace/manifest.rs
  • src/openhuman/tinyplace/schemas.rs
  • src/openhuman/wallet/execution_tests.rs
  • src/openhuman/wallet/ops.rs

Comment thread app/src/agentworld/iso/BaseRoom.ts Outdated
Comment thread app/src/agentworld/iso/GameWorld.ts
Comment thread app/src/agentworld/iso/GameWorld.ts Outdated
Comment thread app/src/agentworld/iso/textures.ts
Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated
Comment thread src/openhuman/tinyplace/schemas.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35253662c6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89558ed24d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated
Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a4e463c2b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
app/src/agentworld/pages/IdentitiesSection.tsx (1)

146-151: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Constrain floor lookup to active listings at query time.

Line 146 limits results before status filtering (Lines 149-151), so inactive entries can crowd out the actual active floor and produce a wrong price.

Suggested fix
-    void apiClient.graphql
-      .identityListings({ length, limit: 20, sortBy: 'price_asc' })
+    void apiClient.graphql
+      .identityListings({ length, limit: 1, sortBy: 'price_asc', status: 'active' })
       .then(data => {
         if (cancelled) return;
-        const listing = data.identities?.find(
-          identity => identity.status == null || identity.status === 'active'
-        );
+        const listing = data.identities?.[0];
         setState({ status: 'ok', data: { length, price: listing?.price } });
       })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/pages/IdentitiesSection.tsx` around lines 146 - 151, The
identityListings method query applies a limit of 20 results before filtering by
status, which means inactive listings can be included in the limited result set
and prevent finding the actual active floor price. Move the status filtering
logic (checking for identity.status == null or identity.status === 'active')
from the client-side find operation into the query parameters passed to
identityListings, so the server returns only active listings sorted by price and
the first result will be the true floor price.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@app/src/agentworld/pages/IdentitiesSection.tsx`:
- Around line 146-151: The identityListings method query applies a limit of 20
results before filtering by status, which means inactive listings can be
included in the limited result set and prevent finding the actual active floor
price. Move the status filtering logic (checking for identity.status == null or
identity.status === 'active') from the client-side find operation into the query
parameters passed to identityListings, so the server returns only active
listings sorted by price and the first result will be the true floor price.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c14ae330-649f-476f-8bd9-421651c1f428

📥 Commits

Reviewing files that changed from the base of the PR and between 8111690 and df7d295.

📒 Files selected for processing (27)
  • app/src/agentworld/iso/Agent.ts
  • app/src/agentworld/iso/BaseRoom.ts
  • app/src/agentworld/iso/GameWorld.ts
  • app/src/agentworld/iso/textures.ts
  • app/src/agentworld/iso/types.ts
  • app/src/agentworld/pages/DirectorySection.test.tsx
  • app/src/agentworld/pages/DirectorySection.tsx
  • app/src/agentworld/pages/IdentitiesSection.test.tsx
  • app/src/agentworld/pages/IdentitiesSection.tsx
  • app/src/agentworld/pages/MarketplaceSection.test.tsx
  • app/src/lib/agentworld/invokeApiClient.test.ts
  • app/src/lib/agentworld/invokeApiClient.ts
  • app/src/lib/i18n/ar.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/de.ts
  • app/src/lib/i18n/en.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/fr.ts
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/id.ts
  • app/src/lib/i18n/it.ts
  • app/src/lib/i18n/ko.ts
  • app/src/lib/i18n/pl.ts
  • app/src/lib/i18n/pt.ts
  • app/src/lib/i18n/ru.ts
  • app/src/lib/i18n/zh-CN.ts
  • src/openhuman/tinyplace/schemas.rs
✅ Files skipped from review due to trivial changes (4)
  • app/src/lib/i18n/hi.ts
  • app/src/lib/i18n/es.ts
  • app/src/lib/i18n/bn.ts
  • app/src/lib/i18n/id.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • app/src/agentworld/iso/types.ts
  • app/src/agentworld/pages/DirectorySection.test.tsx
  • app/src/agentworld/pages/IdentitiesSection.test.tsx
  • app/src/agentworld/iso/Agent.ts
  • app/src/agentworld/pages/DirectorySection.tsx
  • app/src/lib/agentworld/invokeApiClient.test.ts
  • app/src/lib/agentworld/invokeApiClient.ts
  • app/src/agentworld/pages/MarketplaceSection.test.tsx
  • app/src/agentworld/iso/textures.ts
  • app/src/agentworld/iso/GameWorld.ts
  • src/openhuman/tinyplace/schemas.rs
  • app/src/agentworld/iso/BaseRoom.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df7d295467

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/ExploreSection/index.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
app/src/agentworld/pages/IdentitiesSection.tsx (1)

172-179: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Constrain floor-price query to active listings at source (Line 173).

Filtering after limit: 20 can miss the real active floor when cheaper inactive rows fill the page. Query only active listings (or paginate until first active) before taking the minimum.

Suggested fix
     void apiClient.graphql
-      .identityListings({ length, limit: 20, sortBy: 'price_asc' })
+      .identityListings({ length, limit: 20, sortBy: 'price_asc', status: 'active' })
       .then(data => {
         if (cancelled) return;
-        const listing = data.identities?.find(
-          identity => identity.status == null || identity.status === 'active'
-        );
+        const listing = data.identities?.[0];
         setState({ status: 'ok', data: { length, price: listing?.price } });
       })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/agentworld/pages/IdentitiesSection.tsx` around lines 172 - 179, The
identityListings API call applies a limit of 20 results before filtering for
active listings in the JavaScript code, which can cause the actual cheapest
active listing to be missed if inactive listings fill the page. Modify the
identityListings API call to constrain the query at the source by adding a
filter or status parameter that ensures only active listings (where status is
null or 'active') are returned from the API before the limit is applied, so the
first result returned is guaranteed to be the true floor price of active
listings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@app/src/agentworld/pages/IdentitiesSection.tsx`:
- Around line 172-179: The identityListings API call applies a limit of 20
results before filtering for active listings in the JavaScript code, which can
cause the actual cheapest active listing to be missed if inactive listings fill
the page. Modify the identityListings API call to constrain the query at the
source by adding a filter or status parameter that ensures only active listings
(where status is null or 'active') are returned from the API before the limit is
applied, so the first result returned is guaranteed to be the true floor price
of active listings.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 75f8a1fa-aac1-45f0-b0d0-f1fc13a4af55

📥 Commits

Reviewing files that changed from the base of the PR and between df7d295 and fcfcd5f.

📒 Files selected for processing (4)
  • app/src/agentworld/pages/ExploreSection/ExploreSection.test.tsx
  • app/src/agentworld/pages/ExploreSection/index.tsx
  • app/src/agentworld/pages/IdentitiesSection.test.tsx
  • app/src/agentworld/pages/IdentitiesSection.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/src/agentworld/pages/ExploreSection/index.tsx
  • app/src/agentworld/pages/ExploreSection/ExploreSection.test.tsx
  • app/src/agentworld/pages/IdentitiesSection.test.tsx

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 21, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fcfcd5f6e7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/agentworld/pages/IdentitiesSection.tsx Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ef340a724

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


for (
let page = 0;
page < MARKETPLACE_MAX_PAGES && active.length < MARKETPLACE_TARGET_ACTIVE;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep paging marketplace listings until active rows are found

Fresh evidence: this version now pages, but the loop still stops after MARKETPLACE_MAX_PAGES (five pages/250 unfiltered rows) even when the server keeps returning full pages. If sold/expired listings occupy those first pages and active listings start at a later offset, the Trading tab shows an empty or truncated sale list; either use a real active-status filter in the core/GraphQL query or continue paging until the server is exhausted or enough active listings are collected.

Useful? React with 👍 / 👎.

}

async function fetchActiveFloorPrice(length: number): Promise<IdentityFloor> {
for (let page = 0; page < FLOOR_MAX_PAGES; page++) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep paging floor listings past the fixed cap

Fresh evidence: this version still hard-stops after FLOOR_MAX_PAGES (10 pages/200 price-sorted listings) before returning { price: undefined }. When a length bucket has more than 200 sold/expired listings cheaper than the first active listing, the floor card reports “No floor” even though a buyable listing exists; continue paging until an active row is found or add a real server-side active-status filter.

Useful? React with 👍 / 👎.

@senamakel senamakel merged commit db7f6d8 into tinyhumansai:main Jun 21, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant