@stigmer/react 3.6.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/billing/CreditLedgerTable.d.ts.map +1 -1
- package/billing/CreditLedgerTable.js +2 -7
- package/billing/CreditLedgerTable.js.map +1 -1
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +21 -2
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/channel/ChannelConversationsDialog.d.ts +12 -4
- package/channel/ChannelConversationsDialog.d.ts.map +1 -1
- package/channel/ChannelConversationsDialog.js +18 -24
- package/channel/ChannelConversationsDialog.js.map +1 -1
- package/channel/providers.d.ts +23 -0
- package/channel/providers.d.ts.map +1 -1
- package/channel/providers.js +4 -0
- package/channel/providers.js.map +1 -1
- package/channel/useSaveAgentChannel.d.ts +5 -4
- package/channel/useSaveAgentChannel.d.ts.map +1 -1
- package/channel/useSaveAgentChannel.js +18 -4
- package/channel/useSaveAgentChannel.js.map +1 -1
- package/composer/ComposerToolbar.d.ts +6 -1
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +2 -2
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/SessionComposer.d.ts +9 -0
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +13 -2
- package/composer/SessionComposer.js.map +1 -1
- package/conversation/ConversationAttentionBanner.d.ts +22 -0
- package/conversation/ConversationAttentionBanner.d.ts.map +1 -0
- package/conversation/ConversationAttentionBanner.js +25 -0
- package/conversation/ConversationAttentionBanner.js.map +1 -0
- package/conversation/ConversationComposer.d.ts +41 -0
- package/conversation/ConversationComposer.d.ts.map +1 -0
- package/conversation/ConversationComposer.js +57 -0
- package/conversation/ConversationComposer.js.map +1 -0
- package/conversation/ConversationControlBanner.d.ts +52 -0
- package/conversation/ConversationControlBanner.d.ts.map +1 -0
- package/conversation/ConversationControlBanner.js +59 -0
- package/conversation/ConversationControlBanner.js.map +1 -0
- package/conversation/ConversationListPane.d.ts +68 -0
- package/conversation/ConversationListPane.d.ts.map +1 -0
- package/conversation/ConversationListPane.js +120 -0
- package/conversation/ConversationListPane.js.map +1 -0
- package/conversation/ConversationTimelineView.d.ts +46 -0
- package/conversation/ConversationTimelineView.d.ts.map +1 -0
- package/conversation/ConversationTimelineView.js +166 -0
- package/conversation/ConversationTimelineView.js.map +1 -0
- package/conversation/ConversationsWorkbench.d.ts +63 -0
- package/conversation/ConversationsWorkbench.d.ts.map +1 -0
- package/conversation/ConversationsWorkbench.js +165 -0
- package/conversation/ConversationsWorkbench.js.map +1 -0
- package/conversation/conversationPresentation.d.ts +137 -0
- package/conversation/conversationPresentation.d.ts.map +1 -0
- package/conversation/conversationPresentation.js +230 -0
- package/conversation/conversationPresentation.js.map +1 -0
- package/conversation/index.d.ts +26 -0
- package/conversation/index.d.ts.map +1 -0
- package/conversation/index.js +14 -0
- package/conversation/index.js.map +1 -0
- package/conversation/polling.d.ts +39 -0
- package/conversation/polling.d.ts.map +1 -0
- package/conversation/polling.js +39 -0
- package/conversation/polling.js.map +1 -0
- package/conversation/useConversation.d.ts +61 -0
- package/conversation/useConversation.d.ts.map +1 -0
- package/conversation/useConversation.js +153 -0
- package/conversation/useConversation.js.map +1 -0
- package/conversation/useConversationList.d.ts +98 -0
- package/conversation/useConversationList.d.ts.map +1 -0
- package/conversation/useConversationList.js +200 -0
- package/conversation/useConversationList.js.map +1 -0
- package/conversation/useConversationParticipation.d.ts +63 -0
- package/conversation/useConversationParticipation.d.ts.map +1 -0
- package/conversation/useConversationParticipation.js +84 -0
- package/conversation/useConversationParticipation.js.map +1 -0
- package/conversation/useConversationTimeline.d.ts +71 -0
- package/conversation/useConversationTimeline.d.ts.map +1 -0
- package/conversation/useConversationTimeline.js +152 -0
- package/conversation/useConversationTimeline.js.map +1 -0
- package/conversation/useConversationsWantsHumanCount.d.ts +42 -0
- package/conversation/useConversationsWantsHumanCount.d.ts.map +1 -0
- package/conversation/useConversationsWantsHumanCount.js +40 -0
- package/conversation/useConversationsWantsHumanCount.js.map +1 -0
- package/execution/useCreateAgentExecution.d.ts +14 -0
- package/execution/useCreateAgentExecution.d.ts.map +1 -1
- package/execution/useCreateAgentExecution.js +5 -0
- package/execution/useCreateAgentExecution.js.map +1 -1
- package/index.d.ts +6 -2
- package/index.d.ts.map +1 -1
- package/index.js +14 -5
- package/index.js.map +1 -1
- package/internal/Pagination.d.ts +15 -0
- package/internal/Pagination.d.ts.map +1 -0
- package/internal/Pagination.js +20 -0
- package/internal/Pagination.js.map +1 -0
- package/internal/tooltip.d.ts.map +1 -1
- package/internal/tooltip.js +7 -1
- package/internal/tooltip.js.map +1 -1
- package/internal/useAutoScroll.d.ts +25 -4
- package/internal/useAutoScroll.d.ts.map +1 -1
- package/internal/useAutoScroll.js +55 -15
- package/internal/useAutoScroll.js.map +1 -1
- package/internal/useFetch.d.ts.map +1 -1
- package/internal/useFetch.js +14 -4
- package/internal/useFetch.js.map +1 -1
- package/models/ModelSelector.d.ts +45 -1
- package/models/ModelSelector.d.ts.map +1 -1
- package/models/ModelSelector.js +49 -6
- package/models/ModelSelector.js.map +1 -1
- package/models/index.d.ts +2 -0
- package/models/index.d.ts.map +1 -1
- package/models/index.js +1 -0
- package/models/index.js.map +1 -1
- package/models/registry.d.ts +11 -0
- package/models/registry.d.ts.map +1 -1
- package/models/registry.js +3 -0
- package/models/registry.js.map +1 -1
- package/models/service-tier.d.ts +27 -0
- package/models/service-tier.d.ts.map +1 -0
- package/models/service-tier.js +34 -0
- package/models/service-tier.js.map +1 -0
- package/package.json +4 -4
- package/schedule/ScheduleDetailView.d.ts +31 -8
- package/schedule/ScheduleDetailView.d.ts.map +1 -1
- package/schedule/ScheduleDetailView.js +441 -29
- package/schedule/ScheduleDetailView.js.map +1 -1
- package/schedule/ScheduleForm.d.ts +7 -4
- package/schedule/ScheduleForm.d.ts.map +1 -1
- package/schedule/ScheduleForm.js +94 -8
- package/schedule/ScheduleForm.js.map +1 -1
- package/schedule/ScheduleRunsTable.d.ts +72 -0
- package/schedule/ScheduleRunsTable.d.ts.map +1 -0
- package/schedule/ScheduleRunsTable.js +161 -0
- package/schedule/ScheduleRunsTable.js.map +1 -0
- package/schedule/index.d.ts +6 -0
- package/schedule/index.d.ts.map +1 -1
- package/schedule/index.js +3 -0
- package/schedule/index.js.map +1 -1
- package/schedule/useScheduleRuns.d.ts +44 -0
- package/schedule/useScheduleRuns.d.ts.map +1 -0
- package/schedule/useScheduleRuns.js +48 -0
- package/schedule/useScheduleRuns.js.map +1 -0
- package/schedule/useTriggerSchedule.d.ts +23 -10
- package/schedule/useTriggerSchedule.d.ts.map +1 -1
- package/schedule/useTriggerSchedule.js +28 -9
- package/schedule/useTriggerSchedule.js.map +1 -1
- package/schedule/useUpdateScheduleSpec.d.ts +49 -0
- package/schedule/useUpdateScheduleSpec.d.ts.map +1 -0
- package/schedule/useUpdateScheduleSpec.js +70 -0
- package/schedule/useUpdateScheduleSpec.js.map +1 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +1 -0
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/useSessionConversation.d.ts +11 -0
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +1 -0
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionPageFlow.d.ts.map +1 -1
- package/session/useSessionPageFlow.js +1 -0
- package/session/useSessionPageFlow.js.map +1 -1
- package/sharing/useSaveAgentShare.d.ts +10 -1
- package/sharing/useSaveAgentShare.d.ts.map +1 -1
- package/sharing/useSaveAgentShare.js +9 -0
- package/sharing/useSaveAgentShare.js.map +1 -1
- package/sidebar/WorkspaceSidebar.d.ts +12 -4
- package/sidebar/WorkspaceSidebar.d.ts.map +1 -1
- package/sidebar/WorkspaceSidebar.js +19 -7
- package/sidebar/WorkspaceSidebar.js.map +1 -1
- package/src/billing/CreditLedgerTable.tsx +3 -42
- package/src/channel/AgentChannelsPanel.tsx +33 -2
- package/src/channel/ChannelConversationsDialog.tsx +22 -25
- package/src/channel/__tests__/AgentChannelsPanel.test.tsx +36 -5
- package/src/channel/__tests__/ChannelConversationsDialog.test.tsx +38 -1
- package/src/channel/__tests__/useSaveAgentChannel.test.tsx +26 -0
- package/src/channel/providers.ts +27 -0
- package/src/channel/useSaveAgentChannel.ts +18 -4
- package/src/composer/ComposerToolbar.tsx +9 -0
- package/src/composer/SessionComposer.tsx +24 -1
- package/src/composer/__tests__/SessionComposer-serviceTier.test.tsx +157 -0
- package/src/conversation/ConversationAttentionBanner.tsx +77 -0
- package/src/conversation/ConversationComposer.tsx +156 -0
- package/src/conversation/ConversationControlBanner.tsx +193 -0
- package/src/conversation/ConversationListPane.tsx +459 -0
- package/src/conversation/ConversationTimelineView.tsx +435 -0
- package/src/conversation/ConversationsWorkbench.tsx +378 -0
- package/src/conversation/__tests__/ConversationAttentionBanner.test.tsx +82 -0
- package/src/conversation/__tests__/ConversationComposer.test.tsx +160 -0
- package/src/conversation/__tests__/ConversationControlBanner.test.tsx +190 -0
- package/src/conversation/__tests__/ConversationListPane.test.tsx +372 -0
- package/src/conversation/__tests__/ConversationTimelineView.layout.test.tsx +160 -0
- package/src/conversation/__tests__/ConversationTimelineView.test.tsx +405 -0
- package/src/conversation/__tests__/ConversationsWorkbench.test.tsx +860 -0
- package/src/conversation/__tests__/a11y/conversation-surfaces.a11y.test.tsx +235 -0
- package/src/conversation/__tests__/a11y/harness.tsx +100 -0
- package/src/conversation/__tests__/conversation-tooltips.layout.test.tsx +167 -0
- package/src/conversation/__tests__/conversationPollingComposition.test.tsx +138 -0
- package/src/conversation/__tests__/conversationPresentation.test.ts +289 -0
- package/src/conversation/__tests__/useConversation.test.tsx +243 -0
- package/src/conversation/__tests__/useConversationList.test.tsx +492 -0
- package/src/conversation/__tests__/useConversationParticipation.test.tsx +190 -0
- package/src/conversation/__tests__/useConversationTimeline.test.tsx +258 -0
- package/src/conversation/__tests__/useConversationsWantsHumanCount.test.tsx +102 -0
- package/src/conversation/conversationPresentation.ts +305 -0
- package/src/conversation/index.ts +80 -0
- package/src/conversation/polling.ts +41 -0
- package/src/conversation/useConversation.ts +221 -0
- package/src/conversation/useConversationList.ts +328 -0
- package/src/conversation/useConversationParticipation.ts +178 -0
- package/src/conversation/useConversationTimeline.ts +244 -0
- package/src/conversation/useConversationsWantsHumanCount.ts +86 -0
- package/src/execution/useCreateAgentExecution.ts +18 -0
- package/src/index.ts +76 -4
- package/src/internal/Pagination.tsx +72 -0
- package/src/internal/__tests__/fake-timer-slices.ts +29 -0
- package/src/internal/__tests__/useAutoScroll.layout.test.tsx +143 -0
- package/src/internal/__tests__/useAutoScroll.test.tsx +62 -5
- package/src/internal/__tests__/useFetch-poll-under-render-pressure.test.tsx +79 -0
- package/src/internal/tooltip.tsx +6 -1
- package/src/internal/useAutoScroll.ts +66 -20
- package/src/internal/useFetch.ts +15 -4
- package/src/models/ModelSelector.tsx +133 -4
- package/src/models/__tests__/ModelSelector-serviceTier.test.tsx +256 -0
- package/src/models/__tests__/useModelRegistry.test.tsx +15 -0
- package/src/models/index.ts +2 -0
- package/src/models/registry.ts +17 -0
- package/src/models/service-tier.ts +49 -0
- package/src/schedule/ScheduleDetailView.tsx +1179 -111
- package/src/schedule/ScheduleForm.tsx +218 -7
- package/src/schedule/ScheduleRunsTable.tsx +424 -0
- package/src/schedule/__tests__/ScheduleDetailView.test.tsx +431 -8
- package/src/schedule/__tests__/scheduleCreation.test.tsx +197 -0
- package/src/schedule/__tests__/scheduleHooks.test.tsx +94 -7
- package/src/schedule/index.ts +12 -0
- package/src/schedule/useScheduleRuns.ts +93 -0
- package/src/schedule/useTriggerSchedule.ts +39 -14
- package/src/schedule/useUpdateScheduleSpec.ts +108 -0
- package/src/session/useNewSessionFlow.ts +1 -0
- package/src/session/useSessionConversation.ts +12 -0
- package/src/session/useSessionPageFlow.ts +1 -0
- package/src/sharing/__tests__/useSaveAgentShare.test.tsx +55 -1
- package/src/sharing/__tests__/useShareToolReadiness.test.tsx +1 -0
- package/src/sharing/useSaveAgentShare.ts +19 -1
- package/src/sidebar/WorkspaceSidebar.tsx +62 -3
- package/src/sidebar/__tests__/WorkspaceSidebar.test.tsx +56 -1
- package/src/workflow/__tests__/inspector-forms.test.tsx +119 -2
- package/src/workflow/inspector/forms/AgentCallForm.tsx +260 -37
- package/src/workflow/inspector/tabs/RuntimeTab.tsx +72 -33
- package/src/workflow/starter-workflow-yaml.ts +2 -1
- package/styles.css +1 -1
- package/workflow/inspector/forms/AgentCallForm.d.ts +18 -2
- package/workflow/inspector/forms/AgentCallForm.d.ts.map +1 -1
- package/workflow/inspector/forms/AgentCallForm.js +87 -9
- package/workflow/inspector/forms/AgentCallForm.js.map +1 -1
- package/workflow/inspector/tabs/RuntimeTab.d.ts +2 -1
- package/workflow/inspector/tabs/RuntimeTab.d.ts.map +1 -1
- package/workflow/inspector/tabs/RuntimeTab.js +31 -5
- package/workflow/inspector/tabs/RuntimeTab.js.map +1 -1
- package/workflow/starter-workflow-yaml.d.ts +1 -1
- package/workflow/starter-workflow-yaml.d.ts.map +1 -1
- package/workflow/starter-workflow-yaml.js +2 -1
- package/workflow/starter-workflow-yaml.js.map +1 -1
|
@@ -2,12 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useState, type FormEvent } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
getUserMessage,
|
|
7
|
+
type ResourceRef,
|
|
8
|
+
type RunConfigInput,
|
|
9
|
+
} from "@stigmer/sdk";
|
|
6
10
|
import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
11
|
+
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
7
12
|
import { Popover } from "@base-ui/react/popover";
|
|
8
13
|
import { AgentPicker } from "../agent/AgentPicker.js";
|
|
14
|
+
import { EnvironmentPicker } from "../environment/EnvironmentPicker.js";
|
|
15
|
+
import { useGitHubConnection } from "../github/useGitHubConnection.js";
|
|
16
|
+
import { ModelSelector } from "../models/ModelSelector.js";
|
|
17
|
+
import { toProtoHarness, type HarnessOption } from "../models/harness.js";
|
|
18
|
+
import { toProtoServiceTier, type ServiceTierOption } from "../models/service-tier.js";
|
|
9
19
|
import { Switch } from "../switch/Switch.js";
|
|
10
20
|
import { useStigmerPortalContainer } from "../portal-container.js";
|
|
21
|
+
import { useWorkspaceEntries } from "../workspace/useWorkspaceEntries.js";
|
|
22
|
+
import { WorkspaceEditor } from "../workspace/WorkspaceEditor.js";
|
|
11
23
|
import { CadenceField } from "./CadenceField.js";
|
|
12
24
|
import { TimeZoneField, browserTimeZone } from "./TimeZoneField.js";
|
|
13
25
|
import { useCreateSchedule } from "./useCreateSchedule.js";
|
|
@@ -33,7 +45,7 @@ export interface ScheduleFormProps {
|
|
|
33
45
|
readonly className?: string;
|
|
34
46
|
}
|
|
35
47
|
|
|
36
|
-
/**
|
|
48
|
+
/** invocation.proto pins AgentInvocation.message to 8192 characters. */
|
|
37
49
|
const MESSAGE_MAX_LEN = 8192;
|
|
38
50
|
/** Show the remaining-characters counter once within this margin. */
|
|
39
51
|
const MESSAGE_COUNTER_THRESHOLD = 500;
|
|
@@ -41,10 +53,13 @@ const MESSAGE_COUNTER_THRESHOLD = 500;
|
|
|
41
53
|
/**
|
|
42
54
|
* Single-page form for creating a {@link Schedule}.
|
|
43
55
|
*
|
|
44
|
-
*
|
|
45
|
-
* agent, what message,
|
|
46
|
-
*
|
|
47
|
-
*
|
|
56
|
+
* The form speaks the composer's vocabulary (DD-018 D-5): a schedule is
|
|
57
|
+
* a saved run — which agent, what message, what workspace, which
|
|
58
|
+
* engine and model, what budget — plus a cadence. It reuses the
|
|
59
|
+
* composer's own pickers ({@link ModelSelector}, {@link WorkspaceEditor})
|
|
60
|
+
* so the interactive and scheduled surfaces cannot drift, minus only
|
|
61
|
+
* what unattended makes impossible (no local folders, no attachments,
|
|
62
|
+
* no approval-mode choice).
|
|
48
63
|
*
|
|
49
64
|
* Enabled defaults to OFF, deliberately: it matches the proto/YAML
|
|
50
65
|
* default (an omitted `enabled` is false) and the platform's
|
|
@@ -83,6 +98,33 @@ export function ScheduleForm({
|
|
|
83
98
|
const [timeZone, setTimeZone] = useState(browserTimeZone);
|
|
84
99
|
const [enabled, setEnabled] = useState(false);
|
|
85
100
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
101
|
+
const [environmentRefs, setEnvironmentRefs] = useState<ResourceRef[]>([]);
|
|
102
|
+
|
|
103
|
+
// Engine & model are one atomic choice: picking a model pins BOTH the
|
|
104
|
+
// harness and the model (the registry scopes models per harness, so a
|
|
105
|
+
// model without its harness is meaningless). Empty model = nothing
|
|
106
|
+
// pinned = the platform defaults apply to both. Browsing harnesses in
|
|
107
|
+
// the popover without picking a model pins nothing.
|
|
108
|
+
const [modelName, setModelName] = useState("");
|
|
109
|
+
const [modelHarness, setModelHarness] = useState<HarnessOption>("cursor");
|
|
110
|
+
// Service tier is scoped by the model choice (#357): the ModelSelector
|
|
111
|
+
// renders the fast-tier switch only while the selected model's registry
|
|
112
|
+
// entry prices a fast variant. An active fast tier survives switches
|
|
113
|
+
// between fast-capable models and resets only when a model without one
|
|
114
|
+
// is picked. No model pinned = no tier pinned (fast requires a model,
|
|
115
|
+
// and the form's reset button clears both).
|
|
116
|
+
const [serviceTier, setServiceTier] = useState<ServiceTierOption>("standard");
|
|
117
|
+
|
|
118
|
+
const [budgetUsd, setBudgetUsd] = useState("");
|
|
119
|
+
|
|
120
|
+
// Workspace the fresh per-fire session clones — git sources only
|
|
121
|
+
// (write-time validated server-side: no client is connected at fire
|
|
122
|
+
// time to serve a local folder). The GitHub repo picker lights up
|
|
123
|
+
// when the user already has a connection; otherwise the editor's
|
|
124
|
+
// manual URL+branch input applies, with no OAuth flow forced into
|
|
125
|
+
// this form.
|
|
126
|
+
const workspace = useWorkspaceEntries();
|
|
127
|
+
const gitHub = useGitHubConnection(org);
|
|
86
128
|
|
|
87
129
|
const trimmedName = name.trim();
|
|
88
130
|
const trimmedMessage = message.trim();
|
|
@@ -108,6 +150,7 @@ export function ScheduleForm({
|
|
|
108
150
|
if (!canSubmit || !agentRef) return;
|
|
109
151
|
|
|
110
152
|
clearError();
|
|
153
|
+
const runConfig = buildRunConfig(modelName, budgetUsd, serviceTier);
|
|
111
154
|
try {
|
|
112
155
|
const schedule = await create({
|
|
113
156
|
name: trimmedName,
|
|
@@ -115,7 +158,20 @@ export function ScheduleForm({
|
|
|
115
158
|
cron,
|
|
116
159
|
timeZone,
|
|
117
160
|
enabled,
|
|
118
|
-
agent: {
|
|
161
|
+
agent: {
|
|
162
|
+
agentRef,
|
|
163
|
+
message: trimmedMessage,
|
|
164
|
+
// The harness travels with the model it was picked under;
|
|
165
|
+
// no model means no harness — the platform defaults apply.
|
|
166
|
+
...(modelName !== ""
|
|
167
|
+
? { harness: toProtoHarness(modelHarness) }
|
|
168
|
+
: {}),
|
|
169
|
+
...(workspace.hasEntries
|
|
170
|
+
? { workspaceEntries: workspace.toInput() }
|
|
171
|
+
: {}),
|
|
172
|
+
...(environmentRefs.length > 0 ? { environmentRefs } : {}),
|
|
173
|
+
...(runConfig ? { runConfig } : {}),
|
|
174
|
+
},
|
|
119
175
|
});
|
|
120
176
|
onComplete?.(schedule);
|
|
121
177
|
} catch {
|
|
@@ -133,6 +189,12 @@ export function ScheduleForm({
|
|
|
133
189
|
timeZone,
|
|
134
190
|
enabled,
|
|
135
191
|
trimmedMessage,
|
|
192
|
+
environmentRefs,
|
|
193
|
+
modelName,
|
|
194
|
+
modelHarness,
|
|
195
|
+
serviceTier,
|
|
196
|
+
budgetUsd,
|
|
197
|
+
workspace,
|
|
136
198
|
onComplete,
|
|
137
199
|
],
|
|
138
200
|
);
|
|
@@ -224,6 +286,53 @@ export function ScheduleForm({
|
|
|
224
286
|
)}
|
|
225
287
|
</div>
|
|
226
288
|
|
|
289
|
+
{/* Workspace — what each fire's fresh session operates on
|
|
290
|
+
(DD-018 D-4). Git sources only; the server refuses local
|
|
291
|
+
folders at write time because no client is connected when a
|
|
292
|
+
schedule fires. */}
|
|
293
|
+
<div className="space-y-1">
|
|
294
|
+
<span className={labelClasses}>
|
|
295
|
+
Workspace{" "}
|
|
296
|
+
<span className="font-normal text-muted-foreground">(optional)</span>
|
|
297
|
+
</span>
|
|
298
|
+
<WorkspaceEditor
|
|
299
|
+
workspace={workspace}
|
|
300
|
+
gitHubConnection={gitHub.isConnected ? gitHub : undefined}
|
|
301
|
+
enableGitHub
|
|
302
|
+
enableLocal={false}
|
|
303
|
+
disabled={isCreating}
|
|
304
|
+
/>
|
|
305
|
+
<p className={hintClasses}>
|
|
306
|
+
Each run clones these repositories fresh. Private repositories need
|
|
307
|
+
a <code className="font-mono">GITHUB_TOKEN</code> in one of this
|
|
308
|
+
schedule’s environments; public ones need nothing.
|
|
309
|
+
</p>
|
|
310
|
+
</div>
|
|
311
|
+
|
|
312
|
+
{/* Environments — how a tool-using agent becomes schedulable
|
|
313
|
+
(DD-017 D-2). Only org-shared environments resolve for a
|
|
314
|
+
schedule fire, so the picker is filtered to visibility_org —
|
|
315
|
+
the same credential surface a channel binding uses. */}
|
|
316
|
+
<div className="space-y-1">
|
|
317
|
+
<span id="stgm-new-schedule-env-label" className={labelClasses}>
|
|
318
|
+
Environments <span className="font-normal text-muted-foreground">(optional)</span>
|
|
319
|
+
</span>
|
|
320
|
+
<EnvironmentPicker
|
|
321
|
+
org={org}
|
|
322
|
+
value={environmentRefs}
|
|
323
|
+
onChange={setEnvironmentRefs}
|
|
324
|
+
disabled={isCreating}
|
|
325
|
+
filterEnvironment={(env) =>
|
|
326
|
+
env.metadata?.visibility === ApiResourceVisibility.visibility_org
|
|
327
|
+
}
|
|
328
|
+
/>
|
|
329
|
+
<p className={hintClasses}>
|
|
330
|
+
Bind org-shared credentials (for example an MCP server’s secret)
|
|
331
|
+
so the agent’s tools work on an unattended fire. Without this, an
|
|
332
|
+
agent whose tools need credentials will be refused every run.
|
|
333
|
+
</p>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
227
336
|
{/* Cadence */}
|
|
228
337
|
<div className="space-y-1">
|
|
229
338
|
<span className={labelClasses}>Runs</span>
|
|
@@ -235,6 +344,75 @@ export function ScheduleForm({
|
|
|
235
344
|
/>
|
|
236
345
|
</div>
|
|
237
346
|
|
|
347
|
+
{/* Engine & model — the composer's own picker (DD-018 D-5),
|
|
348
|
+
replacing the free-text model box whose typos surfaced as
|
|
349
|
+
fire-time failures. Nothing is pinned until a model is picked. */}
|
|
350
|
+
<div className="space-y-1">
|
|
351
|
+
<span className={labelClasses}>
|
|
352
|
+
Engine & model{" "}
|
|
353
|
+
<span className="font-normal text-muted-foreground">(optional)</span>
|
|
354
|
+
</span>
|
|
355
|
+
<div className="flex items-center gap-2">
|
|
356
|
+
<ModelSelector
|
|
357
|
+
value={modelName}
|
|
358
|
+
onValueChange={setModelName}
|
|
359
|
+
initialHarness={modelHarness}
|
|
360
|
+
onHarnessChange={setModelHarness}
|
|
361
|
+
serviceTier={serviceTier}
|
|
362
|
+
onServiceTierChange={setServiceTier}
|
|
363
|
+
placeholderLabel="Platform default"
|
|
364
|
+
disabled={isCreating}
|
|
365
|
+
/>
|
|
366
|
+
{modelName !== "" && (
|
|
367
|
+
<button
|
|
368
|
+
type="button"
|
|
369
|
+
onClick={() => {
|
|
370
|
+
setModelName("");
|
|
371
|
+
setServiceTier("standard");
|
|
372
|
+
}}
|
|
373
|
+
disabled={isCreating}
|
|
374
|
+
className={cn(
|
|
375
|
+
"rounded-md px-2 py-1 text-[0.65rem] text-muted-foreground",
|
|
376
|
+
"hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
377
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
378
|
+
)}
|
|
379
|
+
>
|
|
380
|
+
Reset to platform default
|
|
381
|
+
</button>
|
|
382
|
+
)}
|
|
383
|
+
</div>
|
|
384
|
+
<p className={hintClasses}>
|
|
385
|
+
Runs use the platform’s default engine and model unless you
|
|
386
|
+
pick one here. Picking a model pins the engine it belongs to.
|
|
387
|
+
</p>
|
|
388
|
+
</div>
|
|
389
|
+
|
|
390
|
+
{/* Budget — the one run bound that matters for an unattended
|
|
391
|
+
surface: nobody is watching a 3 AM fire (DD-018 D-5). Clamped
|
|
392
|
+
by the platform profile; tool-round bounds stay API-only. */}
|
|
393
|
+
<div className="space-y-1">
|
|
394
|
+
<label htmlFor="stgm-new-schedule-budget" className={labelClasses}>
|
|
395
|
+
Budget per run (USD){" "}
|
|
396
|
+
<span className="font-normal text-muted-foreground">(optional)</span>
|
|
397
|
+
</label>
|
|
398
|
+
<input
|
|
399
|
+
id="stgm-new-schedule-budget"
|
|
400
|
+
type="number"
|
|
401
|
+
min="0"
|
|
402
|
+
step="any"
|
|
403
|
+
value={budgetUsd}
|
|
404
|
+
onChange={(e) => setBudgetUsd(e.target.value)}
|
|
405
|
+
placeholder="platform default"
|
|
406
|
+
disabled={isCreating}
|
|
407
|
+
className={cn(inputClasses, "sm:max-w-48")}
|
|
408
|
+
/>
|
|
409
|
+
<p className={hintClasses}>
|
|
410
|
+
Each run stops when it reaches this spend. You can lower the
|
|
411
|
+
platform’s per-run cap, never raise it past the
|
|
412
|
+
platform’s ceiling.
|
|
413
|
+
</p>
|
|
414
|
+
</div>
|
|
415
|
+
|
|
238
416
|
{/* Time zone */}
|
|
239
417
|
<div className="space-y-1">
|
|
240
418
|
<label htmlFor="stgm-new-schedule-tz" className={labelClasses}>
|
|
@@ -318,6 +496,39 @@ export function ScheduleForm({
|
|
|
318
496
|
|
|
319
497
|
const labelClasses = "block text-xs font-medium text-foreground";
|
|
320
498
|
const hintClasses = "text-[0.65rem] text-muted-foreground";
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Assemble a {@link RunConfigInput} from the model choice and budget, or
|
|
502
|
+
* `undefined` when both are unset — an all-empty run_config carries no
|
|
503
|
+
* meaning, and omitting it keeps the schedule on the platform defaults
|
|
504
|
+
* (the server's own "empty = inherit" contract, DD-017 D-3 as carried
|
|
505
|
+
* into DD-018 D-2). Non-numeric or negative budgets are dropped rather
|
|
506
|
+
* than sent; the proto's `gte = 0` constraint would reject them anyway,
|
|
507
|
+
* and a blank field must not become a zero override. `max_tool_rounds`
|
|
508
|
+
* is deliberately not collected here — an implementation knob, not a
|
|
509
|
+
* user concept; API-reachable for operators (DD-018 D-5).
|
|
510
|
+
*/
|
|
511
|
+
function buildRunConfig(
|
|
512
|
+
modelName: string,
|
|
513
|
+
budgetUsd: string,
|
|
514
|
+
serviceTier: ServiceTierOption,
|
|
515
|
+
): RunConfigInput | undefined {
|
|
516
|
+
const model = modelName.trim();
|
|
517
|
+
const cost = Number.parseFloat(budgetUsd);
|
|
518
|
+
|
|
519
|
+
const config: RunConfigInput = {};
|
|
520
|
+
if (model !== "") config.modelName = model;
|
|
521
|
+
if (Number.isFinite(cost) && cost > 0) config.maxCostUsd = cost;
|
|
522
|
+
// Carried only when the user actively chose fast AND pinned a model
|
|
523
|
+
// (fast is a per-model price; the server refuses it without one). An
|
|
524
|
+
// untouched tier stays absent — unspecified-vs-explicit is a
|
|
525
|
+
// load-bearing ledger distinction (#357).
|
|
526
|
+
if (serviceTier === "fast" && model !== "") {
|
|
527
|
+
config.serviceTier = toProtoServiceTier(serviceTier);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return Object.keys(config).length > 0 ? config : undefined;
|
|
531
|
+
}
|
|
321
532
|
const inputClasses = cn(
|
|
322
533
|
"w-full rounded-md border border-input bg-background px-2.5 py-1.5 text-xs text-foreground",
|
|
323
534
|
"placeholder:text-muted-foreground",
|