Skip to content

Commit 7885f95

Browse files
authored
Merge pull request #282 from unifyai/staging
Phase B + Phase C staging promotion + parallel scheduler/docs work
2 parents b245820 + 7327b1b commit 7885f95

139 files changed

Lines changed: 23567 additions & 601 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

β€Ž.env.exampleβ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ ANTHROPIC_API_KEY=
1414
ORCHESTRA_URL="https://api.unify.ai/v0"
1515

1616
# Auto-shutdown timeout for local Orchestra started by `unity setup`.
17-
ORCHESTRA_INACTIVITY_TIMEOUT_SECONDS=600
17+
# Default 0 = no auto-shutdown (install-and-live: Orchestra stays up so the
18+
# Assistants workspace is always reachable on the next `unity` invocation).
19+
# Set to a positive number of seconds to enable the legacy idle-shutdown.
20+
ORCHESTRA_INACTIVITY_TIMEOUT_SECONDS=0
1821

1922
# Validate that an LLM provider key is present on startup.
2023
UNITY_VALIDATE_LLM_PROVIDERS=true

β€Ž.gitignoreβ€Ž

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ Thumbs.db
1111

1212
# Secrets / env
1313
.env
14-
.env.deprecated*
14+
.env.*
15+
!.env.example
16+
!.env.advanced.example
1517
*.env
1618
.secrets.json
1719
.sensitive_data
@@ -27,10 +29,6 @@ log.txt
2729
.logs.txt
2830
logs.txt
2931
test.py
30-
.env.latest
31-
.env.old
32-
.env.temp
33-
.env.clean
3432
dump.rdb
3533
*venv/
3634
.venv
@@ -39,6 +37,7 @@ dump.rdb
3937
.unity_plans
4038
*.txt
4139
!requirements.txt
40+
!requirements-gateway.txt
4241
parsed_results_output/
4342
evals/
4443
magnitude/
@@ -52,7 +51,12 @@ intranet/logs/
5251
# diagrams below. (Use 'assets/*' rather than 'assets/' so the exceptions take
5352
# effect β€” git can't un-ignore a file inside a fully-ignored directory.)
5453
assets/*
55-
!assets/hero-architecture.svg
54+
!assets/hero-architecture.png
55+
!assets/architecture-flow.png
56+
!assets/nested-steering-sequence.png
57+
!assets/openclaw-architecture.png
58+
!assets/hermes-architecture.png
59+
!assets/unity-architecture.png
5660
discord_messages.md
5761
.cursor/debug.log
5862
# ConversationManager sandbox persistent config (project-local)

β€ŽREADME.mdβ€Ž

Lines changed: 144 additions & 253 deletions
Large diffs are not rendered by default.

β€Žagent-service/src/index.tsβ€Ž

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,62 @@ const getLaunchOptions = (headless: boolean, downloadsPath: string | null = null
646646
}}
647647
};
648648

649+
// LLM config resolution with graceful fallbacks. Default route is the
650+
// Unity Comms unillm proxy (when UNITY_COMMS_URL is set). When that
651+
// proxy isn't available (e.g. running agent-service standalone outside
652+
// a full Unity stack), fall back to Anthropic or OpenAI direct using
653+
// the corresponding API key from env.
654+
const getLlmConfig = (): any => {
655+
if (process.env.UNITY_COMMS_URL) {
656+
return {
657+
provider: 'openai-generic' as const,
658+
options: {
659+
model: 'claude-4.6-sonnet@anthropic',
660+
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
661+
headers: {
662+
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
663+
},
664+
temperature: 0.2,
665+
}
666+
};
667+
}
668+
// Prefer Anthropic for computer-use: Claude is significantly more
669+
// accurate at vision-grounded action planning than GPT-4o.
670+
if (process.env.ANTHROPIC_API_KEY) {
671+
// Anthropic ships an OpenAI-compatible endpoint that speaks the
672+
// same Chat Completions wire format, so we keep provider as
673+
// 'openai-generic' and point at the compat path.
674+
return {
675+
provider: 'openai-generic' as const,
676+
options: {
677+
model: 'claude-sonnet-4-5',
678+
baseUrl: 'https://api.anthropic.com/v1',
679+
headers: {
680+
'Authorization': `Bearer ${process.env.ANTHROPIC_API_KEY}`,
681+
},
682+
temperature: 0.2,
683+
}
684+
};
685+
}
686+
if (process.env.OPENAI_API_KEY) {
687+
return {
688+
provider: 'openai-generic' as const,
689+
options: {
690+
model: 'gpt-4o',
691+
baseUrl: 'https://api.openai.com/v1',
692+
headers: {
693+
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
694+
},
695+
temperature: 0.2,
696+
}
697+
};
698+
}
699+
throw new Error(
700+
'No LLM provider configured: set UNITY_COMMS_URL (preferred), or ' +
701+
'ANTHROPIC_API_KEY or OPENAI_API_KEY for direct provider fallback.'
702+
);
703+
};
704+
649705
const startDesktop = async (): Promise<BrowserAgent> => {
650706
try {
651707
const encodedPassword = encodeURIComponent(process.env.UNIFY_KEY || '');
@@ -656,18 +712,9 @@ const startDesktop = async (): Promise<BrowserAgent> => {
656712
browser: getLaunchOptions(true),
657713
prompt: "You're controlling a noVNC virtual desktop page. Do not navigate to other page and use mouse and keyboard to control the browser and apps within the virtual desktop. There may be a terminal (xterm) app launched in the desktop for use.",
658714
narrate: true,
659-
// Route LLM calls through Orchestra/UniLLM proxy for billing and caching
660-
llm: {
661-
provider: 'openai-generic',
662-
options: {
663-
model: 'claude-4.6-sonnet@anthropic',
664-
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
665-
headers: {
666-
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
667-
},
668-
temperature: 0.2,
669-
}
670-
}
715+
// Route LLM calls through Orchestra/UniLLM proxy for billing/caching,
716+
// with fallback to direct OpenAI/Anthropic when UNITY_COMMS_URL is unset.
717+
llm: getLlmConfig()
671718
});
672719
agent.context.setDefaultNavigationTimeout(90000);
673720
// Auto-grant clipboard permissions so the noVNC "Share clipboard?" popup is suppressed
@@ -690,18 +737,9 @@ const startBrowser = async (headless: boolean, urlMappings?: Record<string, stri
690737
browser: getLaunchOptions(headless, defaultBrowserPaths.downloadsPath, defaultBrowserPaths.tracesDir),
691738
narrate: true,
692739
urlMappings,
693-
// Route LLM calls through Orchestra/UniLLM proxy for billing and caching
694-
llm: {
695-
provider: 'openai-generic',
696-
options: {
697-
model: 'claude-4.6-sonnet@anthropic',
698-
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
699-
headers: {
700-
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
701-
},
702-
temperature: 0.2,
703-
}
704-
}
740+
// Route LLM calls through Orchestra/UniLLM proxy for billing/caching,
741+
// with fallback to direct OpenAI/Anthropic when UNITY_COMMS_URL is unset.
742+
llm: getLlmConfig()
705743
});
706744
agent.context.setDefaultNavigationTimeout(90000);
707745
console.log("βœ… BrowserAgent started successfully.");
@@ -731,17 +769,7 @@ const startBrowserOnVm = async (urlMappings?: Record<string, string>): Promise<B
731769
},
732770
narrate: true,
733771
urlMappings,
734-
llm: {
735-
provider: 'openai-generic',
736-
options: {
737-
model: 'claude-4.6-sonnet@anthropic',
738-
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
739-
headers: {
740-
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
741-
},
742-
temperature: 0.2,
743-
}
744-
}
772+
llm: getLlmConfig()
745773
});
746774
agent.context.setDefaultNavigationTimeout(90000);
747775
console.log("βœ… Web-VM BrowserAgent started successfully.");
@@ -781,17 +809,7 @@ const startGoogleMeetBrowser = async (meetUrl: string): Promise<BrowserAgent> =>
781809
},
782810
},
783811
narrate: true,
784-
llm: {
785-
provider: 'openai-generic',
786-
options: {
787-
model: 'claude-4.6-sonnet@anthropic',
788-
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
789-
headers: {
790-
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
791-
},
792-
temperature: 0.2,
793-
}
794-
}
812+
llm: getLlmConfig()
795813
});
796814
agent.context.setDefaultNavigationTimeout(90000);
797815
console.log("βœ… Google Meet BrowserAgent started successfully.");
@@ -2264,17 +2282,7 @@ const startTeamsMeetBrowser = async (meetUrl: string): Promise<BrowserAgent> =>
22642282
},
22652283
},
22662284
narrate: true,
2267-
llm: {
2268-
provider: 'openai-generic',
2269-
options: {
2270-
model: 'claude-4.6-sonnet@anthropic',
2271-
baseUrl: `${process.env.UNITY_COMMS_URL}/unillm`,
2272-
headers: {
2273-
'Authorization': `Bearer ${process.env.UNIFY_KEY}`,
2274-
},
2275-
temperature: 0.2,
2276-
}
2277-
}
2285+
llm: getLlmConfig()
22782286
});
22792287
agent.context.setDefaultNavigationTimeout(90000);
22802288
console.log("βœ… Teams Meet BrowserAgent started successfully.");

β€Žassets/architecture-flow.pngβ€Ž

1.15 MB
Loading
1.13 MB
Loading

β€Žassets/hero-architecture.pngβ€Ž

1.06 MB
Loading

β€Žassets/hero-architecture.svgβ€Ž

Lines changed: 0 additions & 109 deletions
This file was deleted.
1.16 MB
Loading
1.18 MB
Loading

0 commit comments

Comments
Β (0)