feat: improve Droid provider implementation and configuration

- Add --skip-permissions-unsafe flag to droid exec commands for non-interactive execution
- Improve error handling to accept output from both stdout and stderr
- Map droid protocol to claude in getProtocolPrefix for proper request conversion
- Add DROID_AUTH_FILE and DROID_COMMAND to config.json.example
- Add droid-factory-oauth provider pool example to provider_pools.json.example

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
bee4come 2025-10-15 13:26:58 +08:00
parent 3111119f93
commit 66b6363ad4
5 changed files with 32 additions and 8 deletions

View file

@ -13,6 +13,8 @@
"KIRO_OAUTH_CREDS_BASE64": null,
"KIRO_OAUTH_CREDS_FILE_PATH": null,
"QWEN_OAUTH_CREDS_FILE_PATH": null,
"DROID_AUTH_FILE": null,
"DROID_COMMAND": "droid",
"SYSTEM_PROMPT_FILE_PATH": "input_system_prompt.txt",
"SYSTEM_PROMPT_MODE": "overwrite",
"PROMPT_LOG_BASE_NAME": "prompt_log",

2
package-lock.json generated
View file

@ -1,5 +1,5 @@
{
"name": "AIClient2API",
"name": "AIClient-2-API",
"lockfileVersion": 3,
"requires": true,
"packages": {

View file

@ -104,5 +104,18 @@
"errorCount": 0,
"lastErrorTime": null
}
],
"droid-factory-oauth": [
{
"DROID_AUTH_FILE": "~/.factory/auth.json",
"DROID_COMMAND": "droid",
"uuid": "9d8e7f6a-5c4b-3a2d-1e0f-9a8b7c6d5e4f",
"checkModelName": null,
"isHealthy": true,
"lastUsed": null,
"usageCount": 0,
"errorCount": 0,
"lastErrorTime": null
}
]
}

View file

@ -37,10 +37,17 @@ export const MODEL_PROVIDER = {
*/
export function getProtocolPrefix(provider) {
const hyphenIndex = provider.indexOf('-');
let prefix = provider;
if (hyphenIndex !== -1) {
return provider.substring(0, hyphenIndex);
prefix = provider.substring(0, hyphenIndex);
}
return provider; // Return original if no hyphen is found
// Map droid protocol to claude (since droid uses Claude API)
if (prefix === 'droid') {
return 'claude';
}
return prefix;
}
export const ENDPOINT_TYPE = {

View file

@ -53,10 +53,12 @@ export class DroidApiService {
});
droid.on('close', (code) => {
if (code !== 0) {
reject(new Error(`Droid command failed: ${stderr || stdout}`));
// Droid CLI may output to stderr even on success
const output = stdout || stderr;
if (code !== 0 && !output) {
reject(new Error(`Droid command failed with code ${code}: ${stderr || stdout}`));
} else {
resolve(stdout);
resolve(output);
}
});
@ -97,7 +99,7 @@ export class DroidApiService {
try {
const prompt = this.messagesToPrompt(requestBody.messages);
const output = await this.executeDroidCommand(['exec', prompt]);
const output = await this.executeDroidCommand(['exec', '--skip-permissions-unsafe', prompt]);
return {
id: `msg_${Date.now()}`,
@ -149,7 +151,7 @@ export class DroidApiService {
content_block: { type: 'text', text: '' }
};
const droid = spawn(this.droidCommand, ['exec', prompt]);
const droid = spawn(this.droidCommand, ['exec', '--skip-permissions-unsafe', prompt]);
let buffer = '';
for await (const chunk of droid.stdout) {