Skip to content

Commit 36fdc68

Browse files
authored
Merge pull request #41 from zzz-creator/main
Refractor logic, GEMINI and CONTRIBUITNG
2 parents c3fd872 + da843ff commit 36fdc68

5 files changed

Lines changed: 59 additions & 74 deletions

File tree

.clinerules/GEMINI.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Cline Gemini Rules
2+
> [!IMPORTANT]
3+
> This file extends the core guidelines defined in the root [gemini.md](../gemini.md). Always cross-reference both documents.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#### **Do you intend to add a new feature or change an existing one?**
1818

19-
* Suggest your change in the [GitHub Discussions Ideas](https://github.com/orgs/WarMatrixAI/discussions/categories/ideas) before writing extensive code.
19+
* Suggest your change in [GitHub Discussions Ideas](https://github.com/orgs/WarMatrixAI/discussions/categories/ideas) before writing extensive code.
2020

2121
* Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes. When you do submit a PR for a feature, make sure to select the [✨ New Feature Template](https://github.com/WarMatrixAI/WarMatrix/tree/main/.github/PULL_REQUEST_TEMPLATE/feature.md).
2222

GEMINI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
- Always follow existing patterns found in the codebase.
1515
- Do not run terminal command lines containing `cd`. Execute all scripts and commands from the project workspace root directory.
1616
- Preserve existing comments and docstrings when modifying files.
17-
- Resolve active TypeScript compilation errors before finishing tasks. Reference [errors.txt](file:///c:/Users/FIDO/GitHub/WarMatrix/errors.txt) and [compile_errors.txt](file:///c:/Users/FIDO/GitHub/WarMatrix/compile_errors.txt) to verify type safety.
17+
- Resolve active TypeScript compilation errors before finishing tasks.
1818
- Keep the continuous coordinate system as floating-point numbers. Never regress coordinates back to discrete integer grids.
1919
- Ensure all API endpoints conform strictly to the specified data models and JSON payload formats.
2020

src/app/api/sitrep/route.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ function clamp(val: number | undefined, min: number, max: number, def: number):
6464
return Math.max(min, Math.min(max, Number(val)));
6565
}
6666

67+
/** Validates that a schema is a non-null, non-array object. */
68+
function isValidSchema(schema: any): boolean {
69+
return typeof schema === 'object' && schema !== null && !Array.isArray(schema);
70+
}
71+
6772
async function getGeminiApiKey(): Promise<string> {
6873
const cookieStore = await cookies();
6974
const cookieKey = cookieStore.get(GEMINI_API_KEY_COOKIE)?.value?.trim() ?? '';
@@ -120,6 +125,14 @@ export async function GET() {
120125
const res = await fetch(`${AI_SERVER_BASE}/health`, {
121126
signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS),
122127
});
128+
129+
if (!res.ok) {
130+
return NextResponse.json(
131+
{ ok: false, error: 'ai_server_error', details: `Server returned status ${res.status}` },
132+
{ status: res.status }
133+
);
134+
}
135+
123136
const data = await res.json();
124137
let model = 'Local Model';
125138
if (data.use_lm_studio) {
@@ -341,7 +354,7 @@ export async function POST(req: Request) {
341354
maxOutputTokens: payload.max_new_tokens,
342355
topP: payload.top_p,
343356
...(isJsonRequested ? { responseMimeType: "application/json" } : {}),
344-
...(raw.response_schema ? { responseSchema: raw.response_schema } : {})
357+
...(isValidSchema(raw.response_schema) ? { responseSchema: raw.response_schema } : {})
345358
}
346359
});
347360

@@ -389,18 +402,20 @@ export async function POST(req: Request) {
389402
signal: AbortSignal.timeout(INFERENCE_TIMEOUT_MS),
390403
});
391404

392-
const data = await res.json();
393-
394405
if (!res.ok) {
406+
const text = await res.text();
407+
console.error(`ai_sitrep fallback response failed with status ${res.status}:`, text.slice(0, 500));
395408
return NextResponse.json(
396409
{
397410
error: 'ai_inference_error',
398-
details: data?.details ?? data?.error ?? 'Inference failed on the AI server.',
411+
details: text.slice(0, 500) || `Inference failed on the AI server with status ${res.status}`,
399412
},
400413
{ status: res.status }
401414
);
402415
}
403416

417+
const data = await res.json();
418+
404419
// Normalize response for frontend consistency
405420
if (data.response && !data.ai_narrative_output) {
406421
data.ai_narrative_output = data.response;

src/app/login/page.tsx

Lines changed: 35 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -210,76 +210,43 @@ export default function LoginPage() {
210210
}
211211

212212
setError("");
213-
setStatus("UPLINKING");
214-
let p = 0;
213+
214+
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
215215

216-
// Step 1: Uplinking (2 seconds)
217-
const uplinkInterval = setInterval(() => {
218-
p += 5;
219-
setProgress(p);
220-
if (p >= 100) {
221-
clearInterval(uplinkInterval);
222-
setStatus("DECRYPTING_KEY");
223-
p = 0;
224-
setProgress(0);
225-
226-
// Step 2: Decrypting (2 seconds)
227-
const decryptInterval = setInterval(() => {
228-
p += 5;
229-
setProgress(p);
230-
if (p >= 100) {
231-
clearInterval(decryptInterval);
232-
setStatus("SYNCING_NODES");
233-
p = 0;
234-
setProgress(0);
235-
236-
// Step 3: Syncing Nodes (2 seconds)
237-
const syncInterval = setInterval(() => {
238-
p += 5;
239-
setProgress(p);
240-
if (p >= 100) {
241-
clearInterval(syncInterval);
242-
setStatus("SCANNING");
243-
p = 0;
244-
setProgress(0);
245-
246-
// Step 4: Scanning (2 seconds)
247-
const scanInterval = setInterval(() => {
248-
p += 5;
249-
setProgress(p);
250-
if (p >= 100) {
251-
clearInterval(scanInterval);
252-
setStatus("VERIFYING");
253-
setTimeout(() => {
254-
setStatus("SUCCESS");
255-
localStorage.setItem("warmatrix_auth", "true");
256-
localStorage.setItem("warmatrix_auth_expires", (Date.now() + 1000 * 60 * 60 * 24).toString()); // Expires in 24 hours
257-
258-
// Save Gemini API key & model to cookie
259-
const secureFlag = window.location.protocol === "https:" ? "; Secure" : "";
260-
if (trimmedKey) {
261-
document.cookie = `${GEMINI_API_KEY_COOKIE}=${encodeURIComponent(trimmedKey)}; Path=/; Max-Age=${GEMINI_API_KEY_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`;
262-
document.cookie = `${GEMINI_MODEL_COOKIE}=${encodeURIComponent(geminiModel)}; Path=/; Max-Age=${GEMINI_API_KEY_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`;
263-
} else {
264-
// Clear cookie if left empty
265-
document.cookie = `${GEMINI_API_KEY_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax`;
266-
document.cookie = `${GEMINI_MODEL_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax`;
267-
}
268-
269-
setTimeout(() => {
270-
const params = new URLSearchParams(window.location.search);
271-
const next = params.get('next');
272-
router.push(next && next.startsWith('/') ? next : "/console");
273-
}, 800);
274-
}, 1000);
275-
}
276-
}, 100);
277-
}
278-
}, 100);
279-
}
280-
}, 100);
216+
const animatePhase = async (statusValue: "UPLINKING" | "DECRYPTING_KEY" | "SYNCING_NODES" | "SCANNING") => {
217+
setStatus(statusValue);
218+
setProgress(0);
219+
for (let p = 5; p <= 100; p += 5) {
220+
setProgress(p);
221+
await sleep(100);
281222
}
282-
}, 100);
223+
};
224+
225+
await animatePhase("UPLINKING");
226+
await animatePhase("DECRYPTING_KEY");
227+
await animatePhase("SYNCING_NODES");
228+
await animatePhase("SCANNING");
229+
230+
setStatus("VERIFYING");
231+
await sleep(1000);
232+
233+
setStatus("SUCCESS");
234+
localStorage.setItem("warmatrix_auth", "true");
235+
localStorage.setItem("warmatrix_auth_expires", (Date.now() + 1000 * 60 * 60 * 24).toString());
236+
237+
const secureFlag = window.location.protocol === "https:" ? "; Secure" : "";
238+
if (trimmedKey) {
239+
document.cookie = `${GEMINI_API_KEY_COOKIE}=${encodeURIComponent(trimmedKey)}; Path=/; Max-Age=${GEMINI_API_KEY_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`;
240+
document.cookie = `${GEMINI_MODEL_COOKIE}=${encodeURIComponent(geminiModel)}; Path=/; Max-Age=${GEMINI_API_KEY_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secureFlag}`;
241+
} else {
242+
document.cookie = `${GEMINI_API_KEY_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax`;
243+
document.cookie = `${GEMINI_MODEL_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax`;
244+
}
245+
246+
await sleep(800);
247+
const params = new URLSearchParams(window.location.search);
248+
const next = params.get('next');
249+
router.push(next && next.startsWith('/') ? next : "/console");
283250
};
284251

285252
return (

0 commit comments

Comments
 (0)