github-actions[bot] commited on
Commit
db3a988
·
1 Parent(s): bae4297

Update from GitHub Actions

Browse files
Files changed (4) hide show
  1. api/handler.go +54 -200
  2. api/token_handler.go +35 -5
  3. config/config.go +1 -1
  4. templates/admin.html +13 -12
api/handler.go CHANGED
@@ -393,222 +393,76 @@ func detectLanguage(req OpenAIRequest) string {
393
  func getFullToolDefinitions() []ToolDefinition {
394
  return []ToolDefinition{
395
  {
396
- Name: "web-search",
397
- Description: "Search the web for information. Returns results in markdown format.\nEach result includes the URL, title, and a snippet from the page if available.\n\nThis tool uses Google's Custom Search API to find relevant web pages.",
398
- InputSchemaJSON: `{
399
- "description": "Input schema for the web search tool.",
400
- "properties": {
401
- "query": {
402
- "description": "The search query to send.",
403
- "title": "Query",
404
- "type": "string"
405
- },
406
- "num_results": {
407
- "default": 5,
408
- "description": "Number of results to return",
409
- "maximum": 10,
410
- "minimum": 1,
411
- "title": "Num Results",
412
- "type": "integer"
413
- }
414
- },
415
- "required": ["query"],
416
- "title": "WebSearchInput",
417
- "type": "object"
418
- }`,
419
- ToolSafety: 0,
420
  },
421
  {
422
- Name: "web-fetch",
423
- Description: "Fetches data from a webpage and converts it into Markdown.\n\n1. The tool takes in a URL and returns the content of the page in Markdown format;\n2. If the return is not valid Markdown, it means the tool cannot successfully parse this page.",
424
- InputSchemaJSON: `{
425
- "type": "object",
426
- "properties": {
427
- "url": {
428
- "type": "string",
429
- "description": "The URL to fetch."
430
- }
431
- },
432
- "required": ["url"]
433
- }`,
434
- ToolSafety: 0,
435
  },
436
  {
437
- Name: "codebase-retrieval",
438
- Description: "This tool is Augment's context engine, the world's best codebase context engine. It:\n1. Takes in a natural language description of the code you are looking for;\n2. Uses a proprietary retrieval/embedding model suite that produces the highest-quality recall of relevant code snippets from across the codebase;\n3. Maintains a real-time index of the codebase, so the results are always up-to-date and reflects the current state of the codebase;\n4. Can retrieve across different programming languages;\n5. Only reflects the current state of the codebase on the disk, and has no information on version control or code history.",
439
- InputSchemaJSON: `{
440
- "type": "object",
441
- "properties": {
442
- "information_request": {
443
- "type": "string",
444
- "description": "A description of the information you need."
445
- }
446
- },
447
- "required": ["information_request"]
448
- }`,
449
- ToolSafety: 1,
450
  },
451
  {
452
- Name: "shell",
453
- Description: "Execute a shell command.\n\n- You can use this tool to interact with the user's local version control system. Do not use the\nretrieval tool for that purpose.\n- If there is a more specific tool available that can perform the function, use that tool instead of\nthis one.\n\nThe OS is darwin. The shell is 'bash'.",
454
- InputSchemaJSON: `{
455
- "type": "object",
456
- "properties": {
457
- "command": {
458
- "type": "string",
459
- "description": "The shell command to execute."
460
- }
461
- },
462
- "required": ["command"]
463
- }`,
464
- ToolSafety: 2,
465
  },
466
  {
467
- Name: "str-replace-editor",
468
- Description: "Custom editing tool for viewing, creating and editing files\n* `path` is a file path relative to the workspace root\n* command `view` displays the result of applying `cat -n`.\n* If a `command` generates a long output, it will be truncated and marked with `<response clipped>`\n* `insert` and `str_replace` commands output a snippet of the edited section for each entry. This snippet reflects the final state of the file after all edits and IDE auto-formatting have been applied.\n\n\nNotes for using the `str_replace` command:\n* Use the `str_replace_entries` parameter with an array of objects\n* Each object should have `old_str`, `new_str`, `old_str_start_line_number` and `old_str_end_line_number` properties\n* The `old_str_start_line_number` and `old_str_end_line_number` parameters are 1-based line numbers\n* Both `old_str_start_line_number` and `old_str_end_line_number` are INCLUSIVE\n* The `old_str` parameter should match EXACTLY one or more consecutive lines from the original file. Be mindful of whitespace!\n* Empty `old_str` is allowed only when the file is empty or contains only whitespaces\n* It is important to specify `old_str_start_line_number` and `old_str_end_line_number` to disambiguate between multiple occurrences of `old_str` in the file\n* Make sure that `old_str_start_line_number` and `old_str_end_line_number` do not overlap with other entries in `str_replace_entries`\n* The `new_str` parameter should contain the edited lines that should replace the `old_str`. Can be an empty string to delete content\n\nNotes for using the `insert` command:\n* Use the `insert_line_entries` parameter with an array of objects\n* Each object should have `insert_line` and `new_str` properties\n* The `insert_line` parameter specifies the line number after which to insert the new string\n* The `insert_line` parameter is 1-based line number\n* To insert at the very beginning of the file, use `insert_line: 0`\n\nNotes for using the `view` command:\n* Strongly prefer to use larger ranges of at least 1000 lines when scanning through files. One call with large range is much more efficient than many calls with small ranges\n* Prefer to use grep instead of view when looking for a specific symbol in the file\n\nIMPORTANT:\n* This is the only tool you should use for editing files.\n* If it fails try your best to fix inputs and retry.\n* DO NOT fall back to removing the whole file and recreating it from scratch.\n* DO NOT use sed or any other command line tools for editing files.\n* Try to fit as many edits in one tool call as possible\n* Use view command to read the file before editing it.\n",
469
- InputSchemaJSON: `{
470
- "type": "object",
471
- "properties": {
472
- "command": {
473
- "type": "string",
474
- "enum": ["view", "str_replace", "insert"],
475
- "description": "The commands to run. Allowed options are: 'view', 'str_replace', 'insert'."
476
- },
477
- "path": {
478
- "description": "Full path to file relative to the workspace root, e.g. 'services/api_proxy/file.py' or 'services/api_proxy'.",
479
- "type": "string"
480
- },
481
- "view_range": {
482
- "description": "Optional parameter of 'view' command when 'path' points to a file. If none is given, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [11, 12] will show lines 11 and 12. Indexing at 1 to start. Setting '[start_line, -1]' shows all lines from 'start_line' to the end of the file.",
483
- "type": "array",
484
- "items": {
485
- "type": "integer"
486
- }
487
- },
488
- "insert_line_entries": {
489
- "description": "Required parameter of 'insert' command. A list of entries to insert. Each entry is a dictionary with keys 'insert_line' and 'new_str'.",
490
- "type": "array",
491
- "items": {
492
- "type": "object",
493
- "properties": {
494
- "insert_line": {
495
- "description": "The line number after which to insert the new string. This line number is relative to the state of the file before any insertions in the current tool call have been applied.",
496
- "type": "integer"
497
- },
498
- "new_str": {
499
- "description": "The string to insert. Can be an empty string.",
500
- "type": "string"
501
- }
502
- },
503
- "required": ["insert_line", "new_str"]
504
- }
505
- },
506
- "str_replace_entries": {
507
- "description": "Required parameter of 'str_replace' command. A list of entries to replace. Each entry is a dictionary with keys 'old_str', 'old_str_start_line_number', 'old_str_end_line_number' and 'new_str'. 'old_str' from different entries should not overlap.",
508
- "type": "array",
509
- "items": {
510
- "type": "object",
511
- "properties": {
512
- "old_str": {
513
- "description": "The string in 'path' to replace.",
514
- "type": "string"
515
- },
516
- "old_str_start_line_number": {
517
- "description": "The line number of the first line of 'old_str' in the file. This is used to disambiguate between multiple occurrences of 'old_str' in the file.",
518
- "type": "integer"
519
- },
520
- "old_str_end_line_number": {
521
- "description": "The line number of the last line of 'old_str' in the file. This is used to disambiguate between multiple occurrences of 'old_str' in the file.",
522
- "type": "integer"
523
- },
524
- "new_str": {
525
- "description": "The string to replace 'old_str' with. Can be an empty string to delete content.",
526
- "type": "string"
527
- }
528
- },
529
- "required": ["old_str", "new_str", "old_str_start_line_number", "old_str_end_line_number"]
530
- }
531
- }
532
- },
533
- "required": ["command", "path"]
534
- }`,
535
- ToolSafety: 1,
536
  },
537
  {
538
- Name: "save-file",
539
- Description: "Save a file.",
540
- InputSchemaJSON: `{
541
- "type": "object",
542
- "properties": {
543
- "file_path": {
544
- "type": "string",
545
- "description": "The path of the file to save."
546
- },
547
- "file_content": {
548
- "type": "string",
549
- "description": "The content of the file to save."
550
- },
551
- "add_last_line_newline": {
552
- "type": "boolean",
553
- "description": "Whether to add a newline at the end of the file (default: true)."
554
- }
555
- },
556
- "required": ["file_path", "file_content"]
557
- }`,
558
- ToolSafety: 1,
559
  },
560
  {
561
- Name: "launch-process",
562
- Description: "Launch a new process.\nIf wait is specified, waits up to that many seconds for the process to complete.\nIf the process completes within wait seconds, returns its output.\nIf it doesn't complete within wait seconds, returns partial output and process ID.\nIf wait is not specified, returns immediately with just the process ID.\nThe process's stdin is always enbled, so you can use write_process to send input if needed.",
563
- InputSchemaJSON: `{
564
- "type": "object",
565
- "properties": {
566
- "command": {
567
- "type": "string",
568
- "description": "The shell command to execute"
569
- },
570
- "wait": {
571
- "type": "number",
572
- "description": "Optional: number of seconds to wait for the command to complete."
573
- },
574
- "cwd": {
575
- "type": "string",
576
- "description": "Working directory for the command. If not supplied, uses the current working directory."
577
- }
578
- },
579
- "required": ["command"]
580
- }`,
581
- ToolSafety: 2,
582
  },
583
  {
584
- Name: "read-process",
585
- Description: "Read output from a terminal.",
586
- InputSchemaJSON: `{
587
- "type": "object",
588
- "properties": {
589
- "terminal_id": {
590
- "type": "number",
591
- "description": "Terminal ID to read from."
592
- }
593
- },
594
- "required": ["terminal_id"]
595
- }`,
596
- ToolSafety: 1,
597
  },
598
  {
599
- Name: "kill-process",
600
- Description: "Kill a process by its terminal ID.",
601
- InputSchemaJSON: `{
602
- "type": "object",
603
- "properties": {
604
- "terminal_id": {
605
- "type": "number",
606
- "description": "Terminal ID to kill."
607
- }
608
- },
609
- "required": ["terminal_id"]
610
- }`,
611
- ToolSafety: 1,
 
 
 
 
 
 
 
 
 
612
  },
613
  }
614
  }
 
393
  func getFullToolDefinitions() []ToolDefinition {
394
  return []ToolDefinition{
395
  {
396
+ Name: "save-file",
397
+ Description: "Save a new file. Use this tool to write new files with the attached content. It CANNOT modify existing files. Do NOT use this tool to edit an existing file by overwriting it entirely. Use the str-replace-editor tool to edit existing files instead.",
398
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"file_path\":{\"type\":\"string\",\"description\":\"The path of the file to save.\"},\"file_content\":{\"type\":\"string\",\"description\":\"The content of the file.\"},\"add_last_line_newline\":{\"type\":\"boolean\",\"description\":\"Whether to add a newline at the end of the file (default: true).\"}},\"required\":[\"file_path\",\"file_content\"]}",
399
+ ToolSafety: 1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
  },
401
  {
402
+ Name: "launch-process",
403
+ Description: "Launch a new process with a shell command. A process can be waiting (`wait=true`) or non-waiting (`wait=false`).\n\nIf `wait=true`, launches the process in an interactive terminal, and waits for the process to complete up to\n`max_wait_seconds` seconds. If the process ends during this period, the tool call returns. If the timeout\nexpires, the process will continue running in the background but the tool call will return. You can then\ninteract with the process using the other process tools.\n\nNote: Only one waiting process can be running at a time. If you try to launch a process with `wait=true`\nwhile another is running, the tool will return an error.\n\nIf `wait=false`, launches a background process in a separate terminal. This returns immediately, while the\nprocess keeps running in the background.\n\nNotes:\n- Use `wait=true` processes when the command is expected to be short, or when you can't\nproceed with your task until the process is complete. Use `wait=false` for processes that are\nexpected to run in the background, such as starting a server you'll need to interact with, or a\nlong-running process that does not need to complete before proceeding with the task.\n- If this tool returns while the process is still running, you can continue to interact with the process\nusing the other available tools. You can wait for the process, read from it, write to it, kill it, etc.\n- You can use this tool to interact with the user's local version control system. Do not use the\nretrieval tool for that purpose.\n- If there is a more specific tool available that can perform the function, use that tool instead of\nthis one.\n\nThe OS is darwin.",
404
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"The shell command to execute.\"},\"wait\":{\"type\":\"boolean\",\"description\":\"Whether to wait for the command to complete.\"},\"max_wait_seconds\":{\"type\":\"number\",\"description\":\"Number of seconds to wait for the command to complete. Only relevant when wait=true. 10 minutes may be a good default: increase from there if needed.\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the command. If not supplied, uses the current working directory.\"}},\"required\":[\"command\",\"wait\",\"max_wait_seconds\"]}",
405
+ ToolSafety: 2,
 
 
 
 
 
 
 
 
 
406
  },
407
  {
408
+ Name: "read-process",
409
+ Description: "Read output from a terminal.\n\nIf `wait=true` and the process has not yet completed, waits for the terminal to complete up to `max_wait_seconds` seconds before returning its output.\n\nIf `wait=false` or the process has already completed, returns immediately with the current output.",
410
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"terminal_id\":{\"type\":\"integer\",\"description\":\"Terminal ID to read from.\"},\"wait\":{\"type\":\"boolean\",\"description\":\"Whether to wait for the command to complete.\"},\"max_wait_seconds\":{\"type\":\"number\",\"description\":\"Number of seconds to wait for the command to complete. Only relevant when wait=true. 1 minute may be a good default: increase from there if needed.\"}},\"required\":[\"terminal_id\",\"wait\",\"max_wait_seconds\"]}",
411
+ ToolSafety: 1,
 
 
 
 
 
 
 
 
 
412
  },
413
  {
414
+ Name: "kill-process",
415
+ Description: "Kill a process by its process ID.",
416
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"terminal_id\":{\"type\":\"integer\",\"description\":\"Process ID to kill.\"}},\"required\":[\"terminal_id\"]}",
417
+ ToolSafety: 1,
 
 
 
 
 
 
 
 
 
418
  },
419
  {
420
+ Name: "write-process",
421
+ Description: "Write input to a process's stdin.",
422
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"terminal_id\":{\"type\":\"integer\",\"description\":\"Process ID to write to.\"},\"input_text\":{\"type\":\"string\",\"description\":\"Text to write to the process's stdin.\"}},\"required\":[\"terminal_id\",\"input_text\"]}",
423
+ ToolSafety: 1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
  },
425
  {
426
+ Name: "list-processes",
427
+ Description: "List all known processes and their states.",
428
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{},\"required\":[]}",
429
+ ToolSafety: 1,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  },
431
  {
432
+ Name: "web-search",
433
+ Description: "Search the web for information. Returns results in markdown format.\nEach result includes the URL, title, and a snippet from the page if available.\n\nThis tool uses Google's Custom Search API to find relevant web pages.",
434
+ InputSchemaJSON: "{\"description\": \"Input schema for the web search tool.\", \"properties\": {\"query\": {\"description\": \"The search query to send.\", \"title\": \"Query\", \"type\": \"string\"}, \"num_results\": {\"default\": 5, \"description\": \"Number of results to return\", \"maximum\": 10, \"minimum\": 1, \"title\": \"Num Results\", \"type\": \"integer\"}}, \"required\": [\"query\"], \"title\": \"WebSearchInput\", \"type\": \"object\"}",
435
+ ToolSafety: 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  },
437
  {
438
+ Name: "web-fetch",
439
+ Description: "Fetches data from a webpage and converts it into Markdown.\n\n1. The tool takes in a URL and returns the content of the page in Markdown format;\n2. If the return is not valid Markdown, it means the tool cannot successfully parse this page.",
440
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"url\":{\"type\":\"string\",\"description\":\"The URL to fetch.\"}},\"required\":[\"url\"]}",
441
+ ToolSafety: 0,
 
 
 
 
 
 
 
 
 
442
  },
443
  {
444
+ Name: "codebase-retrieval",
445
+ Description: "This tool is Augment's context engine, the world's best codebase context engine. It:\n1. Takes in a natural language description of the code you are looking for;\n2. Uses a proprietary retrieval/embedding model suite that produces the highest-quality recall of relevant code snippets from across the codebase;\n3. Maintains a real-time index of the codebase, so the results are always up-to-date and reflects the current state of the codebase;\n4. Can retrieve across different programming languages;\n5. Only reflects the current state of the codebase on the disk, and has no information on version control or code history.",
446
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"information_request\":{\"type\":\"string\",\"description\":\"A description of the information you need.\"}},\"required\":[\"information_request\"]}",
447
+ ToolSafety: 1,
448
+ },
449
+ {
450
+ Name: "remove-files",
451
+ Description: "Remove files. ONLY use this tool to delete files in the user's workspace. This is the only safe tool to delete files in a way that the user can undo the change. Do NOT use the shell or launch-process tools to remove files.",
452
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"file_paths\":{\"type\":\"array\",\"description\":\"The paths of the files to remove.\",\"items\":{\"type\":\"string\"}}},\"required\":[\"file_paths\"]}",
453
+ ToolSafety: 1,
454
+ },
455
+ {
456
+ Name: "remember",
457
+ Description: "Call this tool when user asks you:\n- to remember something\n- to create memory/memories\n\nUse this tool only with information that can be useful in the long-term.\nDo not use this tool for temporary information.\n",
458
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"memory\":{\"type\":\"string\",\"description\":\"The concise (1 sentence) memory to remember.\"}},\"required\":[\"memory\"]}",
459
+ ToolSafety: 1,
460
+ },
461
+ {
462
+ Name: "str-replace-editor",
463
+ Description: "Custom editing tool for viewing, creating and editing files\n* `path` is a file path relative to the workspace root\n* command `view` displays the result of applying `cat -n`.\n* If a `command` generates a long output, it will be truncated and marked with `<response clipped>`\n* `insert` and `str_replace` commands output a snippet of the edited section for each entry. This snippet reflects the final state of the file after all edits and IDE auto-formatting have been applied.\n\n\nNotes for using the `str_replace` command:\n* Use the `str_replace_entries` parameter with an array of objects\n* Each object should have `old_str`, `new_str`, `old_str_start_line_number` and `old_str_end_line_number` properties\n* The `old_str_start_line_number` and `old_str_end_line_number` parameters are 1-based line numbers\n* Both `old_str_start_line_number` and `old_str_end_line_number` are INCLUSIVE\n* The `old_str` parameter should match EXACTLY one or more consecutive lines from the original file. Be mindful of whitespace!\n* Empty `old_str` is allowed only when the file is empty or contains only whitespaces\n* It is important to specify `old_str_start_line_number` and `old_str_end_line_number` to disambiguate between multiple occurrences of `old_str` in the file\n* Make sure that `old_str_start_line_number` and `old_str_end_line_number` do not overlap with other entries in `str_replace_entries`\n* The `new_str` parameter should contain the edited lines that should replace the `old_str`. Can be an empty string to delete content\n\nNotes for using the `insert` command:\n* Use the `insert_line_entries` parameter with an array of objects\n* Each object should have `insert_line` and `new_str` properties\n* The `insert_line` parameter specifies the line number after which to insert the new string\n* The `insert_line` parameter is 1-based line number\n* To insert at the very beginning of the file, use `insert_line: 0`\n\nNotes for using the `view` command:\n* Strongly prefer to use larger ranges of at least 500 lines when scanning through files. One call with large range is much more efficient than many calls with small ranges\n\nIMPORTANT:\n* This is the only tool you should use for editing files.\n* If it fails try your best to fix inputs and retry.\n* DO NOT fall back to removing the whole file and recreating it from scratch.\n* DO NOT use sed or any other command line tools for editing files.\n* Try to fit as many edits in one tool call as possible\n* Use view command to read the file before editing it.\n",
464
+ InputSchemaJSON: "{\"type\":\"object\",\"properties\":{\"command\":{\"type\":\"string\",\"enum\":[\"view\",\"str_replace\",\"insert\"],\"description\":\"The commands to run. Allowed options are: 'view', 'str_replace', 'insert'.\"},\"path\":{\"description\":\"Full path to file relative to the workspace root, e.g. 'services/api_proxy/file.py' or 'services/api_proxy'.\",\"type\":\"string\"},\"view_range\":{\"description\":\"Optional parameter of `view` command when `path` points to a file. If none is given, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [501, 1000] will show lines from 501 to 1000. Indices are 1-based and inclusive. Setting `[start_line, -1]` shows all lines from `start_line` to the end of the file.\",\"type\":\"array\",\"items\":{\"type\":\"integer\"}},\"insert_line_entries\":{\"description\":\"Required parameter of `insert` command. A list of entries to insert. Each entry is a dictionary with keys `insert_line` and `new_str`.\",\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"insert_line\":{\"description\":\"The line number after which to insert the new string. This line number is relative to the state of the file before any insertions in the current tool call have been applied.\",\"type\":\"integer\"},\"new_str\":{\"description\":\"The string to insert. Can be an empty string.\",\"type\":\"string\"}},\"required\":[\"insert_line\",\"new_str\"]}},\"str_replace_entries\":{\"description\":\"Required parameter of `str_replace` command. A list of entries to replace. Each entry is a dictionary with keys `old_str`, `old_str_start_line_number`, `old_str_end_line_number` and `new_str`. `old_str` from different entries should not overlap.\",\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"old_str\":{\"description\":\"The string in `path` to replace.\",\"type\":\"string\"},\"old_str_start_line_number\":{\"description\":\"The line number of the first line of `old_str` in the file. This is used to disambiguate between multiple occurrences of `old_str` in the file.\",\"type\":\"integer\"},\"old_str_end_line_number\":{\"description\":\"The line number of the last line of `old_str` in the file. This is used to disambiguate between multiple occurrences of `old_str` in the file.\",\"type\":\"integer\"},\"new_str\":{\"description\":\"The string to replace `old_str` with. Can be an empty string to delete content.\",\"type\":\"string\"}},\"required\":[\"old_str\",\"new_str\",\"old_str_start_line_number\",\"old_str_end_line_number\"]}}},\"required\":[\"command\",\"path\"]}",
465
+ ToolSafety: 1,
466
  },
467
  }
468
  }
api/token_handler.go CHANGED
@@ -9,6 +9,7 @@ import (
9
  "fmt"
10
  "math/rand"
11
  "net/http"
 
12
  "strconv"
13
  "sync"
14
  "time"
@@ -85,6 +86,9 @@ func GetRedisTokenHandler(c *gin.Context) {
85
  return
86
  }
87
 
 
 
 
88
  // 使用并发方式批量获取token信息
89
  var wg sync.WaitGroup
90
  tokenList := make([]TokenInfo, 0, len(keys))
@@ -157,6 +161,11 @@ func GetRedisTokenHandler(c *gin.Context) {
157
  tokenList = append(tokenList, info)
158
  }
159
 
 
 
 
 
 
160
  // 计算总页数和分页数据
161
  totalItems := len(tokenList)
162
  totalPages := 1
@@ -398,12 +407,29 @@ func CheckTokenTenantURL(token string) (string, error) {
398
  tenantURLsToTest = append(tenantURLsToTest, currentTenantURL)
399
  }
400
 
 
 
 
 
 
 
401
  // 添加其他租户地址
402
- for i := 20; i >= 1; i-- {
 
403
  newTenantURL := fmt.Sprintf("https://d%d.api.augmentcode.com/", i)
404
  // 避免重复测试已有的租户地址
405
- if newTenantURL != currentTenantURL {
 
 
 
 
 
 
 
 
 
406
  tenantURLsToTest = append(tenantURLsToTest, newTenantURL)
 
407
  }
408
  }
409
 
@@ -526,16 +552,20 @@ func CheckAllTokensHandler(c *gin.Context) {
526
  var mu sync.Mutex
527
  var updatedCount int
528
  var disabledCount int
 
529
 
530
  for _, key := range keys {
531
  // 获取token状态,跳过已标记为不可用的token
532
  status, err := config.RedisHGet(key, "status")
533
  if err == nil && status == "disabled" {
534
- mu.Lock()
535
- mu.Unlock()
536
  continue // 跳过此token
537
  }
538
 
 
 
 
 
 
539
  wg.Add(1)
540
  go func(key string) {
541
  defer wg.Done()
@@ -568,7 +598,7 @@ func CheckAllTokensHandler(c *gin.Context) {
568
 
569
  c.JSON(http.StatusOK, gin.H{
570
  "status": "success",
571
- "total": len(keys),
572
  "updated": updatedCount,
573
  "disabled": disabledCount,
574
  })
 
9
  "fmt"
10
  "math/rand"
11
  "net/http"
12
+ "sort"
13
  "strconv"
14
  "sync"
15
  "time"
 
86
  return
87
  }
88
 
89
+ // 对keys进行排序,确保顺序稳定
90
+ sort.Sort(sort.Reverse(sort.StringSlice(keys)))
91
+
92
  // 使用并发方式批量获取token信息
93
  var wg sync.WaitGroup
94
  tokenList := make([]TokenInfo, 0, len(keys))
 
161
  tokenList = append(tokenList, info)
162
  }
163
 
164
+ // 对token列表按照token字符串进行排序,确保每次刷新结果顺序一致
165
+ sort.Slice(tokenList, func(i, j int) bool {
166
+ return tokenList[i].Token > tokenList[j].Token // 降序排序
167
+ })
168
+
169
  // 计算总页数和分页数据
170
  totalItems := len(tokenList)
171
  totalPages := 1
 
407
  tenantURLsToTest = append(tenantURLsToTest, currentTenantURL)
408
  }
409
 
410
+ // 创建一个map来跟踪已添加的URL,避免重复
411
+ uniqueTenantURLs := make(map[string]bool)
412
+ if currentTenantURL != "" {
413
+ uniqueTenantURLs[currentTenantURL] = true
414
+ }
415
+
416
  // 添加其他租户地址
417
+ // 添加 d1-d20 地址
418
+ for i := 20; i >= 0; i-- {
419
  newTenantURL := fmt.Sprintf("https://d%d.api.augmentcode.com/", i)
420
  // 避免重复测试已有的租户地址
421
+ if !uniqueTenantURLs[newTenantURL] {
422
+ tenantURLsToTest = append(tenantURLsToTest, newTenantURL)
423
+ uniqueTenantURLs[newTenantURL] = true
424
+ }
425
+ }
426
+
427
+ // 添加 i0-i5 地址
428
+ for i := 5; i >= 0; i-- {
429
+ newTenantURL := fmt.Sprintf("https://i%d.api.augmentcode.com/", i)
430
+ if !uniqueTenantURLs[newTenantURL] {
431
  tenantURLsToTest = append(tenantURLsToTest, newTenantURL)
432
+ uniqueTenantURLs[newTenantURL] = true
433
  }
434
  }
435
 
 
552
  var mu sync.Mutex
553
  var updatedCount int
554
  var disabledCount int
555
+ var validTokenCount int
556
 
557
  for _, key := range keys {
558
  // 获取token状态,跳过已标记为不可用的token
559
  status, err := config.RedisHGet(key, "status")
560
  if err == nil && status == "disabled" {
 
 
561
  continue // 跳过此token
562
  }
563
 
564
+ // 计算有效token数量
565
+ mu.Lock()
566
+ validTokenCount++
567
+ mu.Unlock()
568
+
569
  wg.Add(1)
570
  go func(key string) {
571
  defer wg.Done()
 
598
 
599
  c.JSON(http.StatusOK, gin.H{
600
  "status": "success",
601
+ "total": validTokenCount,
602
  "updated": updatedCount,
603
  "disabled": disabledCount,
604
  })
config/config.go CHANGED
@@ -16,7 +16,7 @@ type Config struct {
16
  ProxyURL string
17
  }
18
 
19
- const version = "v1.0.2"
20
 
21
  var AppConfig Config
22
 
 
16
  ProxyURL string
17
  }
18
 
19
+ const version = "v1.0.6"
20
 
21
  var AppConfig Config
22
 
templates/admin.html CHANGED
@@ -828,7 +828,7 @@
828
  <div class="container">
829
  <header>
830
  <div class="header-content">
831
- <h1>Augment面板|v1.0.2</h1>
832
  <button id="logout-btn" class="logout-btn">
833
  <i class="bi bi-box-arrow-right"></i> 登出
834
  </button>
@@ -1322,17 +1322,6 @@
1322
  // 使用事件委托处理所有点击事件
1323
  if (!document.querySelector('.token-list').hasEventListener) {
1324
  document.querySelector('.token-list').addEventListener('click', function(e) {
1325
- // 处理折叠/展开
1326
- const headerElement = e.target.closest('.token-header');
1327
- if (headerElement) {
1328
- const tokenItem = headerElement.closest('.token-item');
1329
- const details = tokenItem.querySelector('.token-details');
1330
- const toggle = tokenItem.querySelector('.token-toggle');
1331
-
1332
- details.classList.toggle('open');
1333
- toggle.classList.toggle('open');
1334
- }
1335
-
1336
  // 处理备注点击
1337
  const remarkElement = e.target.closest('.token-remark');
1338
  if (remarkElement) {
@@ -1414,6 +1403,18 @@
1414
  alert('请求失败: ' + error.message);
1415
  }
1416
  });
 
 
 
 
 
 
 
 
 
 
 
 
1417
  }
1418
  });
1419
 
 
828
  <div class="container">
829
  <header>
830
  <div class="header-content">
831
+ <h1>Augment面板|v1.0.6</h1>
832
  <button id="logout-btn" class="logout-btn">
833
  <i class="bi bi-box-arrow-right"></i> 登出
834
  </button>
 
1322
  // 使用事件委托处理所有点击事件
1323
  if (!document.querySelector('.token-list').hasEventListener) {
1324
  document.querySelector('.token-list').addEventListener('click', function(e) {
 
 
 
 
 
 
 
 
 
 
 
1325
  // 处理备注点击
1326
  const remarkElement = e.target.closest('.token-remark');
1327
  if (remarkElement) {
 
1403
  alert('请求失败: ' + error.message);
1404
  }
1405
  });
1406
+ return; // 阻止后续处理
1407
+ }
1408
+
1409
+ // 处理折叠/展开
1410
+ const headerElement = e.target.closest('.token-header');
1411
+ if (headerElement && !e.target.closest('.token-remark')) {
1412
+ const tokenItem = headerElement.closest('.token-item');
1413
+ const details = tokenItem.querySelector('.token-details');
1414
+ const toggle = tokenItem.querySelector('.token-toggle');
1415
+
1416
+ details.classList.toggle('open');
1417
+ toggle.classList.toggle('open');
1418
  }
1419
  });
1420