@agent-os-lab/agent-game-sdk 0.1.6 → 0.1.8
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/README.md +3 -2
- package/USAGE.md +4 -3
- package/package.json +1 -1
- package/src/office/core/projection.ts +12 -2
- package/src/office/renderers/three/mount.ts +11 -6
package/README.md
CHANGED
|
@@ -14,7 +14,6 @@ import { mountAgentGameOffice } from "@agent-os-lab/agent-game-sdk/office";
|
|
|
14
14
|
|
|
15
15
|
const client = new AgentGameRuntimeBrowserClient({
|
|
16
16
|
baseUrl: "",
|
|
17
|
-
tokenPath: "/api/agent-game-runtime-token",
|
|
18
17
|
accessToken: async () => getScopedToken(),
|
|
19
18
|
});
|
|
20
19
|
|
|
@@ -94,7 +93,9 @@ Built-in room types are `office`, `auditorium`, and `gym`. `capacity` is optiona
|
|
|
94
93
|
|
|
95
94
|
Runtime statuses stay unchanged. The SDK locally distributes `idle` and `resting` agents across ambient areas such as lounge, pantry, gym, and reading/bookcase anchors so inactive agents do not all gather at the sofa.
|
|
96
95
|
|
|
97
|
-
Browser clients should call an application BFF endpoint.
|
|
96
|
+
Browser clients should call an application BFF endpoint. By default the browser client requests `/api/agent-game-runtime-token` on the same origin. Configure `tokenPath` only if your application exposes that BFF route at a different path.
|
|
97
|
+
|
|
98
|
+
Keep the AgentOS service API key on the server; the SDK server client forwards it to Agent Game Runtime. The runtime token endpoint path is SDK-managed and defaults to Agent Game Runtime's `/api/v1/game-runtime-token`, so application code only needs `baseUrl` and `apiKey`:
|
|
98
99
|
|
|
99
100
|
```ts
|
|
100
101
|
import { AgentGameRuntimeServerClient } from "@agent-os-lab/agent-game-sdk";
|
package/USAGE.md
CHANGED
|
@@ -73,16 +73,16 @@ import { AgentGameRuntimeBrowserClient } from "@agent-os-lab/agent-game-sdk";
|
|
|
73
73
|
|
|
74
74
|
const browserClient = new AgentGameRuntimeBrowserClient({
|
|
75
75
|
baseUrl: "",
|
|
76
|
-
tokenPath: "/api/agent-game-runtime-token",
|
|
77
76
|
});
|
|
78
77
|
```
|
|
79
78
|
|
|
79
|
+
The default browser token path is `/api/agent-game-runtime-token`. Configure `tokenPath` only when your application exposes its BFF/proxy endpoint at a different same-origin path. This browser path is not the Agent Game Runtime service path.
|
|
80
|
+
|
|
80
81
|
If your application backend expects an application-scoped browser token, provide `accessToken`. This token is for your BFF/proxy, not for Agent Game Runtime directly.
|
|
81
82
|
|
|
82
83
|
```ts
|
|
83
84
|
const browserClient = new AgentGameRuntimeBrowserClient({
|
|
84
85
|
baseUrl: "",
|
|
85
|
-
tokenPath: "/api/agent-game-runtime-token",
|
|
86
86
|
accessToken: async () => getScopedApplicationToken(),
|
|
87
87
|
});
|
|
88
88
|
```
|
|
@@ -141,7 +141,6 @@ import { mountAgentGameOffice } from "@agent-os-lab/agent-game-sdk/office";
|
|
|
141
141
|
|
|
142
142
|
const client = new AgentGameRuntimeBrowserClient({
|
|
143
143
|
baseUrl: "",
|
|
144
|
-
tokenPath: "/api/agent-game-runtime-token",
|
|
145
144
|
});
|
|
146
145
|
|
|
147
146
|
const view = await mountAgentGameOffice(container, {
|
|
@@ -318,6 +317,8 @@ AGENT_GAME_RUNTIME_BASE_URL=http://localhost:3107 AGENTOS_API_KEY=... bun run de
|
|
|
318
317
|
|
|
319
318
|
Open `http://localhost:7357`.
|
|
320
319
|
|
|
320
|
+
The demo exposes the browser BFF route at `/api/agent-game-runtime-token`. It does not require `AGENT_GAME_RUNTIME_TOKEN_PATH`; the SDK server client owns the runtime token path and uses Agent Game Runtime's default `/api/v1/game-runtime-token`.
|
|
321
|
+
|
|
321
322
|
Set `PORT=7358` or another value to change the port.
|
|
322
323
|
|
|
323
324
|
## Publish
|
package/package.json
CHANGED
|
@@ -29,7 +29,7 @@ export function mapPresenceToOfficeAgents(
|
|
|
29
29
|
role: agent.scene ?? null,
|
|
30
30
|
statusLabel: statusLabels[agent.status],
|
|
31
31
|
activity: agent.activity,
|
|
32
|
-
activityLabel: sanitizeActivityLabel(agent.activity),
|
|
32
|
+
activityLabel: sanitizeActivityLabel(agent.activity, agent.status),
|
|
33
33
|
sceneState: mapStatusToSceneState(agent.status),
|
|
34
34
|
zoneId: mapStatusToZoneId(agent.status, agent.agentId),
|
|
35
35
|
updatedAt: agent.updatedAt,
|
|
@@ -68,7 +68,13 @@ function mapStatusToSceneState(status: AgentPresenceStatus): AgentGameOfficeScen
|
|
|
68
68
|
return status;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function sanitizeActivityLabel(
|
|
71
|
+
function sanitizeActivityLabel(
|
|
72
|
+
activity: AgentPresence["activity"],
|
|
73
|
+
status: AgentPresenceStatus,
|
|
74
|
+
): string | undefined {
|
|
75
|
+
if (!isActiveWorkStatus(status)) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
72
78
|
if (activity?.kind === "completed") {
|
|
73
79
|
return undefined;
|
|
74
80
|
}
|
|
@@ -108,6 +114,10 @@ function formatToolActivityLabel(label: string): string {
|
|
|
108
114
|
return label === "正在使用工具" ? "正在调用工具..." : label;
|
|
109
115
|
}
|
|
110
116
|
|
|
117
|
+
function isActiveWorkStatus(status: AgentPresenceStatus): boolean {
|
|
118
|
+
return status === "working" || status === "thinking";
|
|
119
|
+
}
|
|
120
|
+
|
|
111
121
|
function mapStatusToZoneId(status: AgentPresenceStatus, agentId: string): AgentGameOfficeZoneId {
|
|
112
122
|
switch (status) {
|
|
113
123
|
case "working":
|
|
@@ -44,6 +44,7 @@ const WORKING_FOLLOW_RESET_DELAY_MS = 30_000;
|
|
|
44
44
|
const WORK_EXIT_WAIT_MS = 30_000;
|
|
45
45
|
const WORKING_FOLLOW_CAMERA_OFFSET = new THREE.Vector3(9, 12, 12);
|
|
46
46
|
const OFFICE_CAMERA_TRANSITION_DURATION_MS = 600;
|
|
47
|
+
const OFFICE_CAMERA_UP = new THREE.Vector3(0, 1, 0);
|
|
47
48
|
|
|
48
49
|
export type WorkingAgentFollowState = {
|
|
49
50
|
selectedAgentId: string | null;
|
|
@@ -478,14 +479,14 @@ export function createFollowOfficeCameraView(agentPosition: THREE.Vector3): Offi
|
|
|
478
479
|
const target = new THREE.Vector3(agentPosition.x, 1, agentPosition.z);
|
|
479
480
|
const position = target.clone().add(WORKING_FOLLOW_CAMERA_OFFSET);
|
|
480
481
|
const rotation = new THREE.Euler();
|
|
481
|
-
const matrix = new THREE.Matrix4().lookAt(position, target,
|
|
482
|
+
const matrix = new THREE.Matrix4().lookAt(position, target, OFFICE_CAMERA_UP);
|
|
482
483
|
rotation.setFromRotationMatrix(matrix);
|
|
483
484
|
|
|
484
485
|
return {
|
|
485
486
|
position,
|
|
486
487
|
rotation,
|
|
487
488
|
target,
|
|
488
|
-
up:
|
|
489
|
+
up: OFFICE_CAMERA_UP.clone(),
|
|
489
490
|
distance: position.distanceTo(target),
|
|
490
491
|
};
|
|
491
492
|
}
|
|
@@ -502,16 +503,20 @@ export function createInitialOfficeCameraView(
|
|
|
502
503
|
);
|
|
503
504
|
const quaternion = new THREE.Quaternion().setFromEuler(rotation);
|
|
504
505
|
const forward = new THREE.Vector3(0, 0, -1).applyQuaternion(quaternion).normalize();
|
|
505
|
-
const up = new THREE.Vector3(0, 1, 0).applyQuaternion(quaternion).normalize();
|
|
506
506
|
const target = new THREE.Vector3(layout.scene.center.x, OFFICE_CAMERA_BOUNDS_HEIGHT / 2, layout.scene.center.z);
|
|
507
|
-
const
|
|
507
|
+
const preliminaryPosition = target.clone().sub(forward.clone());
|
|
508
|
+
const orbitRotation = new THREE.Euler();
|
|
509
|
+
const matrix = new THREE.Matrix4().lookAt(preliminaryPosition, target, OFFICE_CAMERA_UP);
|
|
510
|
+
orbitRotation.setFromRotationMatrix(matrix);
|
|
511
|
+
const orbitQuaternion = new THREE.Quaternion().setFromEuler(orbitRotation);
|
|
512
|
+
const distance = resolveOfficeCameraDistance(layout, target, orbitQuaternion, aspect, fovDegrees);
|
|
508
513
|
const position = target.clone().sub(forward.multiplyScalar(distance));
|
|
509
514
|
|
|
510
515
|
return {
|
|
511
516
|
position,
|
|
512
|
-
rotation,
|
|
517
|
+
rotation: orbitRotation,
|
|
513
518
|
target,
|
|
514
|
-
up,
|
|
519
|
+
up: OFFICE_CAMERA_UP.clone(),
|
|
515
520
|
distance,
|
|
516
521
|
};
|
|
517
522
|
}
|