Added some extra features to M365 Copilot2API

The author might be a bit busy and unable to address these features for now.

In my own experience, using the chat endpoint tends to get more refusals to reply, whereas using the message endpoint delivers answers and tool calls more reliably. Occasionally, refusals or repeating still happen — in those cases, try adjusting the “thinking level” setting and it should help.

The main issue I actually wanted to solve was this: I previously used it once and noticed that tool calls were limited to 16 rounds. Then when I tried it again today, I was forced to reset my password, but the reset interface didn’t pop up, so I couldn’t use any of the features at all. That’s why I created this fork, intending it as a temporary tool. It logs only for up to 2 hours, and any logs beyond that period won’t be recorded anymore.


# Changelog

## 2026-08-14 (b61c76a → bff8088)

### Added

  • Usage Log Retention and Trimming: Added M365_USAGE_RETENTION_HOURS environment variable. Usage records are automatically trimmed by time window (default 2 hours; set to 0 to disable time-based trimming, retaining logs only by entry count).

  • Optimized Usage Log Storage: Changed from append-only to atomic file rewrite, preventing usage.jsonl from growing indefinitely. Old files with too much data will be marked as dirty and compressed during the first rewrite after startup.

  • Linked Deletion Cleanup: When deleting an API Key, all usage history corresponding to its prefix is now cleaned up simultaneously (purgePrefix).

  • Unified Token Estimation: Added countTokens (for gpt-* models uses offline tiktoken, others use character-based heuristics). CacheStats and all usage endpoints now use the same estimator.

  • Cache Hit Reporting: OpenAI /v1/chat/completions now reports prompt_tokens_details.cached_tokens; /v1/responses reports cache_read_input_tokens; cached tokens are included for historical messages.

  • Anthropic Usage Fix: /v1/messages now shows locally estimated input_tokens / output_tokens instead of always 0, and separates them per SSE spec (message_start for input, message_delta for output).

  • Avoid Duplicate Counting: Adapter now marks reused paths to skip additional usage records; Responses / Anthropic API calls no longer trigger duplicate recording in /v1/chat/completions.

  • Test Coverage: Added unit tests for usage retention/trimming/deletion linkage, and a scripts/test_api.py script to verify batch endpoint usage.

### Fixed

  • keys.go: Fixed indentation and curly brace nesting for rollback blocks when saving create fails.

  • server.go: Aligned oaiReq struct fields with M365 metadata format.

  • Removed leftover merge conflict markers from account_health_test.go and fixed TMPDIR contamination in auto_cleanup_test.go.

### Build and Repository

  • Included m365-copilot2api.exe (Windows executable) in version control for easy direct distribution.

  • Added M365-Copilot2API.code-workspace for workspace configuration.

  • Updated .gitignore to include rules to ignore .zcode directory.

13 Likes

Change the node from AI to M365 Copilot

Absolutely! Thanks for your hard work :xhj16:

Actually, I solved some of the issues myself yesterday (in the latest commit).

Also, I don’t really want to do container deployment anymore. I’m planning to remove Docker deployment tomorrow.

Hope you can take over the project from here, awesome dev! :ac01:

2 Likes

That’s giving me too much credit.

I don’t know the first thing about reverse engineering or programming.

2 Likes

Have you been knocked down by difficulties?

1 Like

Awesome

2 Likes

Don’t, please, don’t delete the Docker deployment, I really need it.

1 Like

Isn’t this screenshot from a different program?

2 Likes

Hey, did you add the change password feature in the admin panel?

2 Likes

Yeah, not using Docker actually raises the entry barrier, which means the pull requests and feedback I get will be of higher quality.

And is Go configuration really that hard?

1 Like

You can do it yourself, right?

If I have to work with Docker again, all those weird problems will drive me nuts.

1 Like

Come on, man—wouldn’t deploying updates without Docker be a lot more hassle? :ac01:

But updating it myself without removing it is way too much trouble. Let’s wait for some other community experts, awa.

1 Like

I’ve been happily using it on Codex; it’s just a little slow. Is that because of my internet connection?

I sent two images, but neither of them are related to this program—they’re from a different gateway.

The response body now includes usage.

This way, when you use other programs, they can reflect their estimated context.

Once the context exceeds one million, the response time goes up to about 2 minutes and the error rate increases significantly.

In previous versions, the upstream would track usage but it wasn’t returned, so the client always saw 0 for both input and output. That meant context estimation wasn’t usable at all.

If you want to stop updating Docker, could you publish the already built binary files in Releases?

1 Like

It’s not because of the network — it’s just slow to begin with.