Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion packages/app/src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,8 @@ function AmicodeNavigateBridge() {
if (url.pathname === "/new-session") {
const prompt = url.searchParams.get("prompt") || undefined
const autoSend = url.searchParams.get("autoSend") === "1"
if (autoSend) setPendingAutoSend(true)
await tabs.newDraft({ server: server.key, directory: server.projects.list()[0]?.worktree ?? "" }, prompt)
if (autoSend) setPendingAutoSend(true)
} else {
// Navigate to an existing session by path (e.g. /session/:id)
const sessionMatch = url.pathname.match(/^\/session\/([^/?]+)/)
Expand Down
36 changes: 21 additions & 15 deletions packages/app/src/pages/new-session/new-session-draft-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,30 @@ export function createNewSessionDraftController(workspace: { worktree: () => str
prompt.set([{ type: "text", content: text, start: 0, end: text.length }], text.length)
setSearchParams({ ...searchParams, prompt: undefined, autoSend: undefined })
}
// amicode#363: auto-submit when the navigate bridge flagged it
if (pendingAutoSend()) {
setPendingAutoSend(false)
// Retry until model selection is ready and submit succeeds.
// After restart, providers may take a moment to load.
const trySubmit = (attempts = 0) => {
if (attempts > 20) return // give up after ~10s
if (model.ready() && model.current()) {
input.view.submit.onSubmit()
} else {
setTimeout(() => trySubmit(attempts + 1), 500)
}
}
setTimeout(() => trySubmit(), 500)
}
})
})

// amicode#363: auto-submit when the navigate bridge flagged it.
// Separated from the text-fill effect so it works even when the draft
// controller is already mounted (no sessions open → already on /new-session).
createEffect(() => {
if (!pendingAutoSend()) return
if (!prompt.ready()) return
setPendingAutoSend(false)
// Retry until model selection is ready and the prompt has content.
const trySubmit = (attempts = 0) => {
if (attempts > 20) return // give up after ~10s
const parts = prompt.current()
const hasContent = Array.isArray(parts) && parts.some((p: any) => p.content && p.content.length > 0)
if (model.ready() && model.current() && hasContent) {
input.view.submit.onSubmit()
} else {
setTimeout(() => trySubmit(attempts + 1), 500)
}
}
setTimeout(() => trySubmit(), 500)
})

return {
input,
prompt: {
Expand Down
7 changes: 4 additions & 3 deletions packages/opencode/src/server/amicode/widgets-src/about-you.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export default {
}).join('') + '</div>'
: '') +
'</div>' +
'<input data-f-focus placeholder="focus (e.g. transmon pulse design)" value="' + esc(draft.focus) + '" style="font-size:12px;padding:4px 8px;border:1px solid var(--amc-border);border-radius:8px;background:var(--amc-bg);color:var(--amc-text)">' +
'<input data-f-focus placeholder="research area (e.g. optimal control, ML, materials science)" value="' + esc(draft.focus) + '" style="font-size:12px;padding:4px 8px;border:1px solid var(--amc-border);border-radius:8px;background:var(--amc-bg);color:var(--amc-text)">' +
'<input data-f-scholar placeholder="Google Scholar URL" value="' + esc(draft.scholar) + '" style="font-size:12px;padding:4px 8px;border:1px solid var(--amc-border);border-radius:8px;background:var(--amc-bg);color:var(--amc-text)">' +
'<div style="display:flex;gap:8px">' +
'<button type="button" data-save ' + (saving ? 'disabled' : '') + ' style="font-size:12px;padding:4px 12px;border:1px solid var(--amc-accent);border-radius:8px;background:var(--amc-layer2);color:var(--amc-text);cursor:pointer">' + (saving ? 'Saving\\u2026' : 'Save') + '</button>' +
Expand All @@ -114,14 +114,15 @@ export default {
? editForm
: '<div style="font-size:12px;line-height:16px;color:var(--amc-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' +
esc(you.focus || you.affiliation || 'tell Amico about your work') + '</div>' +
(you.description ? '<div style="font-size:11px;line-height:15px;color:var(--amc-text-muted);margin-top:3px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical">' + esc(you.description) + '</div>' : '') +
(platforms ? '<div style="font-size:11px;color:var(--amc-text-faint);margin-top:1px">' + platforms + '</div>' : '')) +
'</div></div>'

var body
if (fresh && !editing) {
body =
'<div style="height:1px;background:var(--amc-border);margin:12px 0"></div>' +
'<div style="font-size:12px;color:var(--amc-text-muted);margin-bottom:8px">No solves yet \\u2014 tell Amico what you&#39;re working on and it&#39;ll start remembering.</div>' +
'<div style="font-size:12px;color:var(--amc-text-muted);margin-bottom:8px">No experiments yet \\u2014 tell Amico what you&#39;re working on and it&#39;ll start remembering.</div>' +
'<button type="button" data-firstrun style="align-self:flex-start;border:1px solid var(--amc-accent);border-radius:8px;background:var(--amc-layer2);color:var(--amc-text);padding:5px 12px;font-size:12px;cursor:pointer">Get started &#8594;</button>'
} else if (!editing) {
var cells = chosen.map(function (k) {
Expand Down Expand Up @@ -169,7 +170,7 @@ export default {
amico.action('open-external', { url: you.scholar })
})
on('[data-firstrun]', 'click', function () {
amico.prompt('help me set up my first pulse-design problem')
amico.prompt('help me get started with my first project')
})
on('[data-cancel]', 'click', function () {
editing = false
Expand Down
16 changes: 8 additions & 8 deletions packages/ui/src/amicode/getting-started.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ import { AmicodeTagline } from "./tagline"
// BE the recommendation, so we honor it verbatim and let the row wrap.
export const AMICODE_STARTERS: readonly { label: string; prompt: string }[] = [
{
label: "Design a pulse — walk me through it",
prompt: "walk me through designing a pulse",
label: "Walk me through my first experiment",
prompt: "walk me through setting up my first experiment",
},
{
label: "Optimize an X gate on my transmon",
prompt: "optimize an X gate on my transmon — use what you know from my history",
label: "Help me with a coding task",
prompt: "I have a coding task — let's get started",
},
// NOTE(spec B): the static "Resume my pulse design" chip was replaced by the
// conditional resumeName-driven chip below — Resume renders only when a
// problem workspace actually exists (no empty chrome).
{
label: "Warm-start from my pulse bank",
prompt: "warm-start a new solve from my pulse bank",
label: "Warm-start from a previous result",
prompt: "warm-start a new experiment from my previous results",
},
{
label: "Go fast with Veloce",
Expand All @@ -45,8 +45,8 @@ export const AMICODE_STARTERS: readonly { label: string; prompt: string }[] = [
},
]

// The three-beat arc of a pulse-design session, from setup to hardware.
const STEPS = ["① Define your system and problem", "② Optimize and iterate", "③ Execute and tune on hardware"]
// The three-beat arc of a research session, from setup to results.
const STEPS = ["① Define your system and problem", "② Optimize and iterate", "③ Analyze and refine"]

/** amicode chat-redesign (Kate): chips-only row for the composer-as-hero start
* screen — no tagline, no byline, no steps. Quiet neutral pills (Kimi-style):
Expand Down
24 changes: 21 additions & 3 deletions packages/ui/src/amicode/home-cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface ProfileYou {
scholar: string | null
affiliation_logo: string | null
focus: string | null
description: string | null
avatar: string | null
platforms: string[]
stats: ProfileStats
Expand All @@ -57,6 +58,7 @@ export function parseProfileResponse(raw: unknown): ProfileView {
scholar: typeof you.scholar === "string" ? you.scholar : null,
affiliation_logo: typeof you.affiliation_logo === "string" ? you.affiliation_logo : null,
focus: typeof you.focus === "string" ? you.focus : null,
description: typeof you.description === "string" ? you.description : null,
avatar: typeof you.avatar === "string" ? you.avatar : null,
platforms: Array.isArray(you.platforms) ? you.platforms.filter((p: unknown) => typeof p === "string") : [],
stats: {
Expand Down Expand Up @@ -924,8 +926,8 @@ function AboutYouCard(props: {
data-amc-clipboard="self"
class="amc-input amc-input--compact"
value={draft().focus}
placeholder="What you work on"
aria-label="Research focus"
placeholder="Research area"
aria-label="Research area"
onInput={(e) => setDraft({ ...draft(), focus: e.currentTarget.value })}
onKeyDown={pasteFallback((v) => setDraft({ ...draft(), focus: v }))}
/>
Expand Down Expand Up @@ -989,6 +991,22 @@ function AboutYouCard(props: {
</For>
</div>
</Show>
<Show when={y().description}>
<div
style={{
"font-size": "11px",
"line-height": "15px",
color: "var(--v2-text-text-muted)",
"margin-top": "3px",
overflow: "hidden",
display: "-webkit-box",
"-webkit-line-clamp": "2",
"-webkit-box-orient": "vertical",
}}
>
{y().description}
</div>
</Show>
</div>
</div>

Expand All @@ -998,7 +1016,7 @@ function AboutYouCard(props: {
<>
<div style={DIVIDER} />
<div style={{ "font-size": "12px", color: "var(--v2-text-text-muted)", "margin-bottom": "8px" }}>
No solves yet — tell Amico what you're working on and it'll start remembering.
No experiments yet — tell Amico what you're working on and it'll start remembering.
</div>
<PrimaryButton
slot="amicode-card-you-firstrun"
Expand Down
10 changes: 5 additions & 5 deletions packages/ui/src/amicode/onboarding-wizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ export function AmicodeOnboardingWizard(props: {
"max-width": "380px",
}}
>
Amico is your quantum-computing agent — it designs pulses from a conversation, warm-starts from your
pulse bank, and tunes on real hardware. Thirty seconds of setup makes it yours.
Amico is your research and coding companion — it runs experiments from a conversation, remembers your
results, and adapts to your workflow. Thirty seconds of setup makes it yours.
</div>
</div>
<div
Expand Down Expand Up @@ -393,12 +393,12 @@ export function AmicodeOnboardingWizard(props: {
</Show>
</div>
<div>
<div style={LABEL}>What you work on</div>
<div style={LABEL}>Research area</div>
<input
class="amc-input"
value={fields().focus}
onInput={(e) => setFields({ ...fields(), focus: e.currentTarget.value })}
placeholder="e.g. high-fidelity gates on transmons"
placeholder="e.g. optimal control, ML research, materials science"
/>
</div>
<div>
Expand Down Expand Up @@ -544,7 +544,7 @@ export function AmicodeOnboardingWizard(props: {
</div>
</div>
<div style={{ "font-size": "13px", color: "var(--v2-text-text-muted)", "max-width": "360px" }}>
You're set — a personal vault is ready. Amico will remember this; say hi and design your first pulse.
You're set — a personal vault is ready. Amico will remember your context across sessions.
</div>
{/* attach-your-own-vault: quiet by default so it never crowds the payoff shot */}
<Show when={props.onAttachVault}>
Expand Down
9 changes: 4 additions & 5 deletions packages/ui/src/amicode/tagline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { createSignal, onCleanup, onMount } from "solid-js"
// v2-token styling (dark/light correct); timings tuned to read, not distract.

export const TAGLINE_PHRASES = [
"Your friendly Quantum Computing Agent",
"designs pulses from a conversation",
"warm-starts from your pulse bank",
"tunes & calibrates on real hardware",
"powered by the Piccolo engine",
"your research copilot",
"runs experiments from a conversation",
"remembers your results and context",
"adapts to your workflow",
"Andiamo.",
]

Expand Down
Loading