Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ A cockpit is the user-facing control surface for coding-agent work. In JCode thi

The cockpit coordinates local tools and provider runtimes; it should not leak raw provider protocol details directly into ordinary user-facing concepts.

### OpenClaw Gateway Provider

The OpenClaw Gateway Provider is a first-class JCode Provider that connects to a user-configured OpenClaw Gateway URL and presents OpenClaw chat inside normal JCode Threads.

Its first version should treat the OpenClaw Gateway as a provider runtime rather than a separate external chat launcher. JCode owns the Settings configuration, provider health, thread-to-session mapping, and runtime-event translation while keeping OpenClaw protocol details behind the Provider boundary.

### Skill Library

The Skill Library is the settings-native surface for discovering and managing coding-agent skills across providers such as OpenCode and Codex.
Expand Down
35 changes: 24 additions & 11 deletions apps/server/integration/orchestrationEngine.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ const APPROVAL_REQUEST_ID = asApprovalRequestId("req-approval-1");
const itLiveUnlessCi = (process.env.CI ? it.skip : it.live) as typeof it.live;
type IntegrationProvider = ProviderKind;

function defaultModelSelectionFor(
provider: Exclude<ProviderKind, "openclaw" | "pi">,
): ModelSelection {
switch (provider) {
case "codex":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.codex };
case "claudeAgent":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.claudeAgent };
case "cursor":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.cursor };
case "gemini":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.gemini };
case "kilo":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.kilo };
case "opencode":
return { provider, model: DEFAULT_MODEL_BY_PROVIDER.opencode };
}
}

function nowIso() {
return new Date().toISOString();
}
Expand Down Expand Up @@ -109,21 +128,18 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
Effect.gen(function* () {
const createdAt = nowIso();
const provider = harness.adapterHarness?.provider ?? "codex";
if (provider === "pi") {
throw new Error("Pi integration tests require an explicit model selection.");
if (provider === "openclaw" || provider === "pi") {
throw new Error("OpenClaw and Pi integration tests require an explicit model selection.");
}
const defaultModel = DEFAULT_MODEL_BY_PROVIDER[provider];
const defaultModelSelection = defaultModelSelectionFor(provider);

yield* harness.engine.dispatch({
type: "project.create",
commandId: CommandId.makeUnsafe("cmd-project-create"),
projectId: PROJECT_ID,
title: "Integration Project",
workspaceRoot: harness.workspaceDir,
defaultModelSelection: {
provider,
model: defaultModel,
},
defaultModelSelection,
createdAt,
});

Expand All @@ -133,10 +149,7 @@ const seedProjectAndThread = (harness: OrchestrationIntegrationHarness) =>
threadId: THREAD_ID,
projectId: PROJECT_ID,
title: "Integration Thread",
modelSelection: {
provider,
model: defaultModel,
},
modelSelection: defaultModelSelection,
interactionMode: DEFAULT_PROVIDER_INTERACTION_MODE,
runtimeMode: "approval-required",
branch: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ const make = Effect.gen(function* () {
input.modelSelection ?? threadModelSelections.get(input.threadId) ?? thread.modelSelection;
const modelForTurn =
sessionModelSwitch === "unsupported"
? activeSession?.model !== undefined
? activeSession?.model !== undefined && requestedModelSelection.provider !== "openclaw"
? {
...requestedModelSelection,
model: activeSession.model,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1715,9 +1715,11 @@ const make = Effect.gen(function* () {
(entry) => entry.id === childThreadId,
);
const resolvedModelSelection =
identity?.model && identity.modelIsRequestedHint !== true
identity?.model &&
identity.modelIsRequestedHint !== true &&
parentThread.modelSelection.provider !== "openclaw"
? {
provider: parentThread.modelSelection.provider,
...parentThread.modelSelection,
model: identity.model,
}
: undefined;
Expand Down
Loading
Loading